#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) import argparse # When adding new devices to the list please keep them in alphabetical order # board-name should contain 'dashes' (-) not 'underscores' (_) and shouldn't contain capitals # you can check the formating using an online tool such as https://codebeautify.org/python-formatter-beautifier # 'project' : { # 'device' : { # 'board-name' : { # 'dtb' : 'board-name.dtb', # 'config' : 'board_name_defconfig' # }, # }, # }, devices = \ { 'Allwinner': { 'A64': { 'orangepi-win': { 'dtb': 'sun50i-a64-orangepi-win.dtb', 'config': 'orangepi_win_defconfig', 'crust_config': 'orangepi_win_defconfig', }, 'pine64': { 'dtb': 'sun50i-a64-pine64.dtb', 'config': 'pine64_plus_defconfig', 'crust_config': 'pine64_plus_defconfig' }, 'pine64-lts': { 'dtb': 'sun50i-a64-pine64-lts.dtb', 'config': 'pine64-lts_defconfig', 'crust_config': 'pine64_plus_defconfig' }, 'pine64-plus': { 'dtb': 'sun50i-a64-pine64-plus.dtb', 'config': 'pine64_plus_defconfig', 'crust_config': 'pine64_plus_defconfig', }, }, 'H2-plus': { 'bananapi-m2-zero': { 'dtb': 'sun8i-h2-plus-bananapi-m2-zero.dtb', 'config': 'bananapi_m2_zero_defconfig', 'crust_config': 'orangepi_one_defconfig' }, }, 'H3': { 'bananapi-m2p': { 'dtb': 'sun8i-h3-bananapi-m2-plus.dtb', 'config': 'bananapi_m2_plus_h3_defconfig', 'crust_config': 'bananapi_m2_plus_h3_defconfig' }, 'beelink-x2': { 'dtb': 'sun8i-h3-beelink-x2.dtb', 'config': 'beelink_x2_defconfig', 'crust_config': 'beelink_x2_defconfig' }, 'capcom-home-arcade': { 'dtb': 'sun8i-h3-libretech-all-h3-cc.dtb', 'config': 'libretech_all_h3_cc_h3_defconfig', 'crust_config': 'libretech_all_h3_cc_h3_defconfig', }, 'libretech-h3': { 'dtb': 'sun8i-h3-libretech-all-h3-cc.dtb', 'config': 'libretech_all_h3_cc_h3_defconfig', 'crust_config': 'libretech_all_h3_cc_h3_defconfig', }, 'nanopi-m1': { 'dtb': 'sun8i-h3-nanopi-m1.dtb', 'config': 'nanopi_m1_defconfig', 'crust_config': 'nanopi_m1_defconfig' }, 'orangepi-2': { 'dtb': 'sun8i-h3-orangepi-2.dtb', 'config': 'orangepi_2_defconfig', 'crust_config': 'orangepi_2_defconfig', }, 'orangepi-pc': { 'dtb': 'sun8i-h3-orangepi-pc.dtb', 'config': 'orangepi_pc_defconfig', 'crust_config': 'orangepi_pc_defconfig', }, 'orangepi-pc-plus': { 'dtb': 'sun8i-h3-orangepi-pc-plus.dtb', 'config': 'orangepi_pc_plus_defconfig', 'crust_config': 'orangepi_pc_plus_defconfig', }, 'orangepi-plus2e': { 'dtb': 'sun8i-h3-orangepi-plus2e.dtb', 'config': 'orangepi_plus2e_defconfig', 'crust_config': 'orangepi_plus2e_defconfig', }, 'orangepi-plus': { 'dtb': 'sun8i-h3-orangepi-plus.dtb', 'config': 'orangepi_plus_defconfig', 'crust_config': 'orangepi_plus_defconfig', }, }, 'H5' : { 'orangepi-pc2': { 'dtb': 'sun50i-h5-orangepi-pc2.dtb', 'config': 'orangepi_pc2_defconfig', 'crust_config': 'orangepi_pc2_defconfig', }, 'tritium-h5': { 'dtb': 'sun50i-h5-libretech-all-h3-cc.dtb', 'config': 'libretech_all_h3_cc_h5_defconfig', 'crust_config': 'libretech_all_h3_cc_h5_defconfig' }, }, 'H6': { 'beelink-gs1' : { 'dtb' : 'sun50i-h6-beelink-gs1.dtb', 'config' : 'beelink_gs1_defconfig', 'crust_config' : 'beelink_gs1_defconfig' }, 'orangepi-3': { 'dtb': 'sun50i-h6-orangepi-3.dtb', 'config': 'orangepi_3_defconfig', 'crust_config': 'orangepi_3_defconfig' }, 'orangepi-3-lts': { 'dtb': 'sun50i-h6-orangepi-3-lts.dtb', 'config': 'orangepi_3_lts_defconfig', 'crust_config': 'pine_h64_defconfig' }, 'orangepi-lite2': { 'dtb': 'sun50i-h6-orangepi-lite2.dtb', 'config': 'orangepi_lite2_defconfig', 'crust_config': 'orangepi_3_defconfig' }, 'orangepi-one-plus': { 'dtb': 'sun50i-h6-orangepi-one-plus.dtb', 'config': 'orangepi_one_plus_defconfig', 'crust_config': 'orangepi_3_defconfig' }, 'pine-h64': { 'dtb': 'sun50i-h6-pine-h64.dtb', 'config': 'pine_h64_defconfig', 'crust_config': 'pine_h64_defconfig', }, 'pine-h64-model-b': { 'dtb': 'sun50i-h6-pine-h64-model-b.dtb', 'config': 'pine_h64_defconfig', 'crust_config': 'pine_h64_defconfig' }, 'tanix-tx6' : { 'dtb' : 'sun50i-h6-tanix-tx6.dtb', 'config' : 'tanix_tx6_defconfig', 'crust_config' : 'tanix_tx6_defconfig' }, }, 'R40' : { 'bananapi-m2u' : { 'dtb' : 'sun8i-r40-bananapi-m2-ultra.dtb', 'config' : 'Bananapi_M2_Ultra_defconfig' }, }, 'H616' : { 'orangepi-zero2': { 'dtb': 'sun50i-h616-orangepi-zero2.dtb', 'config': 'orangepi_zero2_defconfig', 'crust_config': 'orangepi_zero2_defconfig', }, }, }, 'Amlogic': { 'AMLGX': { 'box': { 'dtb': '', 'config': 'p212_defconfig' }, 'bananapi-cm4io': { 'dtb': 'meson-g12b-bananapi-cm4-cm4io.dtb', 'config': 'bananapi-cm4io_defconfig' }, 'bananapi-m2s': { 'dtb': 'meson-g12b-a311d-bananapi-m2s.dtb', 'config': 'bananapi-m2s_defconfig' }, 'bananapi-m2-pro': { 'dtb': 'meson-sm1-bananapi-m2-pro.dtb', 'config': 'bananapi-m2-pro_defconfig' }, 'bananapi-m5': { 'dtb': 'meson-sm1-bananapi-m5.dtb', 'config': 'bananapi-m5_defconfig' }, 'khadas-vim': { 'dtb': 'meson-gxl-s905x-khadas-vim.dtb', 'config': 'khadas-vim_defconfig' }, 'khadas-vim2': { 'dtb': 'meson-gxm-khadas-vim2.dtb', 'config': 'khadas-vim2_defconfig' }, 'khadas-vim3': { 'dtb': 'meson-g12b-a311d-khadas-vim3.dtb', 'config': 'khadas-vim3_defconfig' }, 'khadas-vim3l': { 'dtb': 'meson-sm1-khadas-vim3l.dtb', 'config': 'khadas-vim3l_defconfig' }, 'lafrite': { 'dtb': 'meson-gxl-s805x-libretech-ac.dtb', 'config': 'libretech-ac_defconfig' }, 'lepotato': { 'dtb': 'meson-gxl-s905x-libretech-cc.dtb', 'config': 'libretech-cc_defconfig' }, 'nanopi-k2': { 'dtb': 'meson-gxbb-nanopi-k2.dtb', 'config': 'nanopi-k2_defconfig' }, 'odroid-c2': { 'dtb': 'meson-gxbb-odroidc2.dtb', 'config': 'odroid-c2_defconfig' }, 'odroid-c4': { 'dtb': 'meson-sm1-odroid-c4.dtb', 'config': 'odroid-c4_defconfig' }, 'odroid-hc4': { 'dtb': 'meson-sm1-odroid-hc4.dtb', 'config': 'odroid-hc4_defconfig' }, 'odroid-n2': { 'dtb': 'meson-g12b-odroid-n2.dtb', 'config': 'odroid-n2_defconfig' }, 'radxa-zero': { 'dtb': 'meson-g12a-radxa-zero.dtb', 'config': 'radxa-zero_defconfig' }, 'radxa-zero2': { 'dtb': 'meson-g12b-radxa-zero2.dtb', 'config': 'radxa-zero2_defconfig' }, 'wetek-core2': { 'dtb': 'meson-gxm-wetek-core2.dtb', 'config': 'wetek-core2_defconfig' }, 'wetek-hub': { 'dtb': 'meson-gxbb-wetek-hub.dtb', 'config': 'wetek-hub_defconfig' }, 'wetek-play2': { 'dtb': 'meson-gxbb-wetek-play2.dtb', 'config': 'wetek-play2_defconfig' }, }, }, 'NXP': { 'iMX6': { 'cubox': { 'dtb': '', 'config': 'mx6cuboxi_defconfig' }, 'udoo': { 'dtb': '', 'config': 'udoo_defconfig' }, 'wandboard': { 'dtb': '', 'config': 'wandboard_defconfig' }, }, 'iMX8' : { 'mq-evk' : { 'dtb' : 'imx8mq-evk.dtb', 'config' : 'imx8mq_evk_defconfig' }, 'pico-mq' : { 'dtb' : 'imx8mq-pico-pi.dtb', 'config' : 'pico-imx8mq_defconfig' }, }, }, 'Qualcomm': { 'Dragonboard': { '410c': { 'dtb': 'apq8016-sbc.dtb', 'config': 'dragonboard410c_defconfig' }, }, }, 'Rockchip': { 'RK3288': { 'miqi': { 'dtb': 'rk3288-miqi.dtb', 'config': 'miqi-rk3288_defconfig' }, 'tinker': { 'dtb': 'rk3288-tinker-s.dtb', 'config': 'tinker-s-rk3288_defconfig' }, }, 'RK3328': { 'a1': { 'dtb': 'rk3328-a1.dtb', 'config': 'evb-rk3328_defconfig', 'rockchip_legacy_boot': '1' }, 'roc-cc': { 'dtb': 'rk3328-roc-cc.dtb', 'config': 'roc-cc-rk3328_defconfig' }, 'rock64': { 'dtb': 'rk3328-rock64.dtb', 'config': 'rock64-rk3328_defconfig' }, }, 'RK3399': { 'hugsun-x99': { 'dtb': 'rk3399-hugsun-x99.dtb', 'config': 'evb-rk3399_defconfig', 'rockchip_legacy_boot': '1' }, 'khadas-edge': { 'dtb': 'rk3399-khadas-edge.dtb', 'config': 'khadas-edge-rk3399_defconfig' }, 'nanopc-t4': { 'dtb': 'rk3399-nanopc-t4.dtb', 'config': 'nanopc-t4-rk3399_defconfig' }, 'nanopi-m4': { 'dtb': 'rk3399-nanopi-m4.dtb', 'config': 'nanopi-m4-rk3399_defconfig' }, 'orangepi': { 'dtb': 'rk3399-orangepi.dtb', 'config': 'orangepi-rk3399_defconfig' }, 'orangepi-4-lts': { 'dtb': 'rk3399-orangepi-4-lts.dtb', 'config': 'orangepi-rk3399_defconfig', }, 'rock960': { 'dtb': 'rk3399-rock960.dtb', 'config': 'rock960-rk3399_defconfig' }, 'rock-pi-4': { 'dtb': 'rk3399-rock-pi-4b.dtb', 'config': 'rock-pi-4-rk3399_defconfig' }, 'rock-pi-4-plus': { 'dtb': 'rk3399-rock-pi-4b-plus.dtb', 'config': 'rock-pi-4-rk3399_defconfig' }, 'rock-pi-4c-plus': { 'dtb': 'rk3399-rock-4c-plus.dtb', 'config': 'rock-pi-4-rk3399_defconfig' }, 'rock-pi-n10': { 'dtb': 'rk3399pro-rock-pi-n10.dtb', 'config': 'rock-pi-n10-rk3399pro_defconfig' }, 'rockpro64': { 'dtb': 'rk3399-rockpro64.dtb', 'config': 'rockpro64-rk3399_defconfig' }, 'roc-pc': { 'dtb': 'rk3399-roc-pc-mezzanine.dtb', 'config': 'roc-pc-mezzanine-rk3399_defconfig' }, 'roc-pc-plus': { 'dtb': 'rk3399-roc-pc-plus.dtb', 'config': 'roc-pc-rk3399_defconfig' }, 'sapphire': { 'dtb': 'rk3399-sapphire.dtb', 'config': 'evb-rk3399_defconfig', 'rockchip_legacy_boot': '1' }, }, }, 'Samsung': { 'Exynos': { 'odroid-xu3': { 'dtb': 'exynos5422-odroidxu3.dtb', 'config': 'odroid-xu3_defconfig' }, 'odroid-xu4': { 'dtb': 'exynos5422-odroidxu4.dtb', 'config': 'odroid-xu4_defconfig' }, }, }, } class OptionsAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): message = None if self.dest == 'project': if values is None: print(' '.join(project for project in sorted(devices))) parser.exit() if values not in devices.keys(): message = "invalid choice: {0!r} (choose from {1})".format(values, ', '.join([repr(project) for project in devices])) if self.dest == 'soc': project = getattr(namespace, 'project') if values is None: print(' '.join(soc for soc in sorted(devices[project]))) parser.exit() if values not in devices[project].keys(): message = "invalid choice: {0!r} (choose from {1})".format(values, ', '.join([repr(soc) for soc in devices[project]])) if self.dest == 'board': project = getattr(namespace, 'project') soc = getattr(namespace, 'soc') if values is None: print(' '.join(board for board in sorted(devices[project][soc]))) parser.exit() if values not in devices[project][soc].keys(): message = "invalid choice: {0!r} (choose from {1})".format(values, ', '.join([repr(board) for board in devices[project][soc]])) if self.dest == 'value': project = getattr(namespace, 'project') soc = getattr(namespace, 'soc') board = getattr(namespace, 'board') if values is None: print(' '.join(value for value in sorted(devices[project][soc][board].keys()))) parser.exit() if values not in devices[project][soc][board].keys(): parser.exit() if message is not None: raise argparse.ArgumentError(self, message) setattr(namespace, self.dest, values) parser = argparse.ArgumentParser(description='Script to help with u-boot configuration') parser.add_argument('project', nargs='?', action=OptionsAction) parser.add_argument('soc', nargs='?', action=OptionsAction) parser.add_argument('board', nargs='?', action=OptionsAction) parser.add_argument('value', nargs='?', action=OptionsAction) options = parser.parse_args() print(devices[options.project][options.soc][options.board][options.value]) parser.exit()