From: Jan Kiszka <jan.kis...@siemens.com> This adds support for the IOT2050 Basic and Advanced devices. The Basic used the dual-core AM6528 GP processor, the Advanced one the AM6548 HS quad-core version.
Both variants are booted via a Siemens-provided FSBL that runs on the R5 cores. Consequently, U-Boot support is targeting the A53 cores. U-Boot SPL, ATF and TEE have to reside in SPI flash. Full integration into a bootable image can be found on https://github.com/siemens/meta-iot2050 Based on original board support by Le Jin, Gao Nian and Chao Zeng. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- arch/arm/mach-k3/Kconfig | 1 + board/siemens/iot2050/Kconfig | 32 ++++ board/siemens/iot2050/MAINTAINERS | 8 + board/siemens/iot2050/Makefile | 10 ++ board/siemens/iot2050/README | 65 +++++++ board/siemens/iot2050/board.c | 284 ++++++++++++++++++++++++++++++ board/siemens/iot2050/config.mk | 8 + configs/iot2050_defconfig | 132 ++++++++++++++ include/configs/iot2050.h | 67 +++++++ 9 files changed, 607 insertions(+) create mode 100644 board/siemens/iot2050/Kconfig create mode 100644 board/siemens/iot2050/MAINTAINERS create mode 100644 board/siemens/iot2050/Makefile create mode 100644 board/siemens/iot2050/README create mode 100644 board/siemens/iot2050/board.c create mode 100644 board/siemens/iot2050/config.mk create mode 100644 configs/iot2050_defconfig create mode 100644 include/configs/iot2050.h diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig index fa8d134b42..526f5f8b76 100644 --- a/arch/arm/mach-k3/Kconfig +++ b/arch/arm/mach-k3/Kconfig @@ -168,4 +168,5 @@ config K3_DM_FW source "board/ti/am65x/Kconfig" source "board/ti/am64x/Kconfig" source "board/ti/j721e/Kconfig" +source "board/siemens/iot2050/Kconfig" endif diff --git a/board/siemens/iot2050/Kconfig b/board/siemens/iot2050/Kconfig new file mode 100644 index 0000000000..8f634c172c --- /dev/null +++ b/board/siemens/iot2050/Kconfig @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) Siemens AG, 2018-2021 +# +# Authors: +# Le Jin <le....@siemens.com> +# Jan Kiszka <jan.kis...@siemens.com> + +config TARGET_IOT2050_A53 + bool "IOT2050 running on A53" + select ARM64 + select SOC_K3_AM6 + select BOARD_LATE_INIT + select SYS_DISABLE_DCACHE_OPS + select BINMAN + +if TARGET_IOT2050_A53 + +config SYS_BOARD + default "iot2050" + +config SYS_VENDOR + default "siemens" + +config SYS_CONFIG_NAME + default "iot2050" + +config IOT2050_BOOT_SWITCH + bool "Disable eMMC boot via USER button (Advanced version only)" + default y + +endif diff --git a/board/siemens/iot2050/MAINTAINERS b/board/siemens/iot2050/MAINTAINERS new file mode 100644 index 0000000000..028fd22960 --- /dev/null +++ b/board/siemens/iot2050/MAINTAINERS @@ -0,0 +1,8 @@ +IOT2050 BOARD +M: Le Jin <le....@siemens.com> +M: Jan Kiszka <jan.kis...@siemens.com> +S: Maintained +F: board/siemens/iot2050/ +F: include/configs/iot2050.h +F: configs/iot2050_defconfig +F: arch/arm/dts/iot2050-* diff --git a/board/siemens/iot2050/Makefile b/board/siemens/iot2050/Makefile new file mode 100644 index 0000000000..619594ab8e --- /dev/null +++ b/board/siemens/iot2050/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Makefile for Siemens IOT2050 board +# Copyright (c) Siemens AG, 2018-2021 +# +# Authors: +# Le Jin <le....@siemens.com> +# + +obj-y += board.o diff --git a/board/siemens/iot2050/README b/board/siemens/iot2050/README new file mode 100644 index 0000000000..b63f05b5cf --- /dev/null +++ b/board/siemens/iot2050/README @@ -0,0 +1,65 @@ +SIMATIC IOT2050 BASIC and ADVANCED +================================== + +The SIMATIC IOT2050 is an open industrial IoT gateway that is using the TI +AM6528 GP (Basic variant) or the AM6548 HS (Advanced variant). The Advanced +variant is prepared for secure boot. + +The IOT2050 starts only from OSPI. It loads a Siemens-provided bootloader +called SE-Boot for the MCU domain (R5F cores), then hands over to ATF and +OP-TEE, before booting U-Boot on the A53 cores. This describes how to build all +open artifacts into a flashable image for the OSPI flash. The flash image will +work on both variants. + + +Dependencies +------------ + +ATF: Upstream release 2.4 or newer +OP-TEE: Upstream release 3.10.0 or newer + +Binary dependencies can be found in +https://github.com/siemens/meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild. +The following binaries from that source need to be present in the build folder: + + - tiboot3.bin + - sysfw.itb + - sysfw.itb_HS + + +Building +-------- + +Make sure that CROSS_COMPILE is set appropriately: + + export CROSS_COMPILE=aarch64-linux-gnu- + +ATF: + + make PLAT=k3 SPD=opteed K3_USART=1 + +OP-TEE: + + make PLATFORM=k3-am65x CFG_ARM64_core=y \ + CFG_TEE_CORE_LOG_LEVEL=2 CFG_CONSOLE_UART=1 + +U-Boot: + + export ATF=/path/to/bl31.bin + export TEE=/path/to/tee-pager_v2.bin + make iot2050_defconfig + make + + +Flashing +-------- + +Via U-Boot: + + sf probe + load mmc 0:1 $loadaddr /path/to/flash.bin + sf update $loadaddr 0x0 $filesize + +Via external programmer Dediprog SF100 or SF600: + + dpcmd --vcc 2 -v -u flash.bin diff --git a/board/siemens/iot2050/board.c b/board/siemens/iot2050/board.c new file mode 100644 index 0000000000..cc84081296 --- /dev/null +++ b/board/siemens/iot2050/board.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Board specific initialization for IOT2050 + * Copyright (c) Siemens AG, 2018-2021 + * + * Authors: + * Le Jin <le....@siemens.com> + * Jan Kiszka <jan.kis...@siemens.com> + */ + +#include <common.h> +#include <bootstage.h> +#include <dm.h> +#include <i2c.h> +#include <led.h> +#include <malloc.h> +#include <net.h> +#include <phy.h> +#include <spl.h> +#include <version.h> +#include <linux/delay.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/hardware.h> +#include <asm/gpio.h> +#include <asm/io.h> + +#define IOT2050_INFO_MAGIC 0x20502050 + +struct iot2050_info { + u32 magic; + u16 size; + char name[20 + 1]; + char serial[16 + 1]; + char mlfb[18 + 1]; + char uuid[32 + 1]; + char a5e[18 + 1]; + u8 mac_addr_cnt; + u8 mac_addr[8][ARP_HLEN]; + char seboot_version[40 + 1]; +} __packed; + +/* + * Scratch SRAM (available before DDR RAM) contains extracted EEPROM data. + */ +#define IOT2050_INFO_DATA ((struct iot2050_info *) \ + TI_SRAM_SCRATCH_BOARD_EEPROM_START) + +DECLARE_GLOBAL_DATA_PTR; + +static bool board_is_advanced(void) +{ + struct iot2050_info *info = IOT2050_INFO_DATA; + + return info->magic == IOT2050_INFO_MAGIC && + !strcmp((char *)info->name, "IOT2050-ADVANCED"); +} + +static void remove_mmc1_target(void) +{ + char *boot_targets = strdup(env_get("boot_targets")); + char *mmc1 = strstr(boot_targets, "mmc1"); + + if (mmc1) { + memmove(mmc1, mmc1 + 4, strlen(mmc1 + 4) + 1); + env_set("boot_targets", boot_targets); + } + + free(boot_targets); +} + +void set_board_info_env(void) +{ + struct iot2050_info *info = IOT2050_INFO_DATA; + u8 __maybe_unused mac_cnt; + + if (info->magic != IOT2050_INFO_MAGIC) { + pr_err("IOT2050: Board info parsing error!\n"); + return; + } + + if (env_get("board_uuid")) + return; + + env_set("board_name", info->name); + env_set("board_serial", info->serial); + env_set("mlfb", info->mlfb); + env_set("board_uuid", info->uuid); + env_set("board_a5e", info->a5e); + env_set("fw_version", PLAIN_VERSION); + env_set("seboot_version", info->seboot_version); + + if (IS_ENABLED(CONFIG_NET)) { + /* MAC address */ + for (mac_cnt = 0; mac_cnt < info->mac_addr_cnt; mac_cnt++) { + if (is_valid_ethaddr(info->mac_addr[mac_cnt])) + eth_env_set_enetaddr_by_index("eth", + mac_cnt + 1, + info->mac_addr[mac_cnt]); + } + + /* + * Set the MAC address environment variable that ICSSG0-PRU eth0 will + * use in u-boot + */ + env_set("ethaddr", env_get("eth1addr")); + } + + if (board_is_advanced()) { + env_set("fdtfile", "ti/k3-am6548-iot2050-advanced.dtb"); + } else { + env_set("fdtfile", "ti/k3-am6528-iot2050-basic.dtb"); + /* remove the unavailable eMMC (mmc1) from the list */ + remove_mmc1_target(); + } + + env_save(); +} + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + if (board_is_advanced()) + gd->ram_size = SZ_2G; + else + gd->ram_size = SZ_1G; + + return 0; +} + +int dram_init_banksize(void) +{ + dram_init(); + + /* Bank 0 declares the memory available in the DDR low region */ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; + + /* Bank 1 declares the memory available in the DDR high region */ + gd->bd->bi_dram[1].start = 0; + gd->bd->bi_dram[1].size = 0; + + return 0; +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + struct iot2050_info *info = IOT2050_INFO_DATA; + char upper_name[32]; + + if (info->magic != IOT2050_INFO_MAGIC || + strlen(name) >= sizeof(upper_name)) + return -1; + + str_to_upper(name, upper_name, sizeof(upper_name)); + if (!strcmp(upper_name, (char *)info->name)) + return 0; + + return -1; +} +#endif + +int do_board_detect(void) +{ + return 0; +} + +#ifdef CONFIG_IOT2050_BOOT_SWITCH +static bool user_button_pressed(void) +{ + struct udevice *red_led = NULL; + unsigned long count = 0; + struct gpio_desc gpio; + + memset(&gpio, 0, sizeof(gpio)); + + if (dm_gpio_lookup_name("25", &gpio) < 0 || + dm_gpio_request(&gpio, "USER button") < 0 || + dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN) < 0) + return false; + + if (dm_gpio_get_value(&gpio) == 1) + return false; + + printf("USER button pressed - booting from external media only\n"); + + led_get_by_label("status-led-red", &red_led); + + if (red_led) + led_set_state(red_led, LEDST_ON); + + while (dm_gpio_get_value(&gpio) == 0 && count++ < 10000) + mdelay(1); + + if (red_led) + led_set_state(red_led, LEDST_OFF); + + return true; +} +#endif + +#define SERDES0_LANE_SELECT 0x00104080 + +int board_late_init(void) +{ + /* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */ + writel(0x3, SERDES0_LANE_SELECT); + + set_board_info_env(); + + /* remove the eMMC if requested via button */ + if (IS_ENABLED(CONFIG_IOT2050_BOOT_SWITCH) && board_is_advanced() && + user_button_pressed()) + remove_mmc1_target(); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + int ret; + + ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000"); + if (ret < 0) + ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000", + "sram@70000000"); + if (ret) + pr_err("%s: fixing up msmc ram failed %d\n", __func__, ret); + + return ret; +} +#endif + +void spl_board_init(void) +{ +} + +/* RJ45 LED configuration */ +#define DP83867_DEVADDR 0x1f + +#define DP83867_LEDCR_1 0x0018 + +#define DP83867_LED_1000_BT_LINK 0x5 +#define DP83867_LED_100_BTX_LINK 0x6 +#define DP83867_LED_LINK_BLINK_ACTIVE 0xb +#define DP83867_LED_SET(n, v) ((v) << ((n) * 4)) + +#define DP83867_LED_SETTINGS \ + (DP83867_LED_SET(0, DP83867_LED_LINK_BLINK_ACTIVE) | \ + DP83867_LED_SET(1, DP83867_LED_1000_BT_LINK) | \ + DP83867_LED_SET(2, DP83867_LED_100_BTX_LINK) | \ + DP83867_LED_SET(3, DP83867_LED_100_BTX_LINK)) + +int board_phy_config(struct phy_device *phydev) +{ + return phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_LEDCR_1, + DP83867_LED_SETTINGS); +} + +#if CONFIG_IS_ENABLED(LED) && CONFIG_IS_ENABLED(BOOTSTAGE) +/* + * Indicate any error or (accidental?) entering of CLI via the red status LED. + */ +void show_boot_progress(int progress) +{ + struct udevice *dev; + int ret; + + if (progress < 0 || progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) { + ret = led_get_by_label("status-led-green", &dev); + if (ret == 0) + led_set_state(dev, LEDST_OFF); + + ret = led_get_by_label("status-led-red", &dev); + if (ret == 0) + led_set_state(dev, LEDST_ON); + } +} +#endif diff --git a/board/siemens/iot2050/config.mk b/board/siemens/iot2050/config.mk new file mode 100644 index 0000000000..267ec76c4e --- /dev/null +++ b/board/siemens/iot2050/config.mk @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) Siemens AG, 2020-2021 +# +# Authors: +# Jan Kiszka <jan.kis...@siemens.com> + +flash.bin: all diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig new file mode 100644 index 0000000000..6af8971aa5 --- /dev/null +++ b/configs/iot2050_defconfig @@ -0,0 +1,132 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_SOC_K3_AM6=y +CONFIG_TARGET_IOT2050_A53=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0x680000 +CONFIG_ENV_SECT_SIZE=0x20000 +CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-am6528-iot2050-basic" +CONFIG_SPL_TEXT_BASE=0x80080000 +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_ENV_OFFSET_REDUND=0x6a0000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTSTAGE=y +CONFIG_CONSOLE_MUX=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_PROMPT="IOT2050> " +CONFIG_CMD_ASKENV=y +CONFIG_CMD_DFU=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +# CONFIG_ISO_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIST="k3-am6528-iot2050-basic k3-am6548-iot2050-advanced" +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_OF_LIST="k3-am65-iot2050-spl" +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +# CONFIG_NET is not set +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_REGMAP=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_TI_SCI=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_LED=y +CONFIG_SPL_LED=y +CONFIG_LED_GPIO=y +CONFIG_SPL_LED_GPIO=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_DM_ETH=y +CONFIG_PCI=y +CONFIG_PCI_KEYSTONE=y +CONFIG_PHY=y +CONFIG_AM654_PHY=y +CONFIG_OMAP_USB2_PHY=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_REMOTEPROC_TI_K3_R5F=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_KEYBOARD=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/iot2050.h b/include/configs/iot2050.h new file mode 100644 index 0000000000..e95442d6aa --- /dev/null +++ b/include/configs/iot2050.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Configuration header file for IOT2050 + * Copyright (c) Siemens AG, 2018-2021 + * + * Authors: + * Le Jin <le....@siemens.com> + * Jan Kiszka <jan.ki...@siemens.com> + */ + +#ifndef __CONFIG_IOT2050_H +#define __CONFIG_IOT2050_H + +#include <linux/sizes.h> + +/* SPL Loader Configuration */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SPL_TEXT_BASE + \ + CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE) + +#define CONFIG_SKIP_LOWLEVEL_INIT + +#define CONFIG_SPL_MAX_SIZE CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE + +#define CONFIG_SYS_BOOTM_LEN SZ_64M + +/* U-Boot general configuration */ +#define EXTRA_ENV_IOT2050_BOARD_SETTINGS \ + "loadaddr=0x80080000\0" \ + "scriptaddr=0x83000000\0" \ + "kernel_addr_r=0x80080000\0" \ + "ramdisk_addr_r=0x81000000\0" \ + "fdt_addr_r=0x82000000\0" \ + "overlay_addr_r=0x83000000\0" \ + "usb_pgood_delay=900\0" + +#ifndef CONFIG_SPL_BUILD + +#if CONFIG_IS_ENABLED(CMD_USB) +# define BOOT_TARGET_USB(func) \ + func(USB, usb, 0) \ + func(USB, usb, 1) \ + func(USB, usb, 2) +#else +# define BOOT_TARGET_USB(func) +#endif + +/* + * This defines all MMC devices, even if the basic variant has no mmc1. + * The non-supported device will be removed from the boot targets during + * runtime, when that board was detected. + */ +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 1) \ + func(MMC, mmc, 0) \ + BOOT_TARGET_USB(func) + +#include <config_distro_bootcmd.h> + +#endif + +#define CONFIG_EXTRA_ENV_SETTINGS \ + BOOTENV \ + EXTRA_ENV_IOT2050_BOARD_SETTINGS + +#include <configs/ti_armv7_common.h> + +#endif /* __CONFIG_IOT2050_H */ -- 2.31.1