From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Sat, 24 Jun 2023 14:29:42 +0200 Subject: Khadas KBI cmd Taken from - https://raw.githubusercontent.com/khadas/khadas-uboot/master/packages/u-boot-mainline/patches/v2021.07-rc1/0002-Edge-add-kbi-support-WiP.patch - https://raw.githubusercontent.com/khadas/khadas-uboot/master/packages/u-boot-mainline/patches/v2021.07-rc1/0003-VIMs-add-kbi-cmd-support.patch - made it 'default y' so no need to change defconfig --- cmd/Kconfig | 7 + cmd/Makefile | 2 + cmd/kbi.c | 1065 ++++++++++ 3 files changed, 1074 insertions(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index 365371fb51..baa4143b88 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2847,4 +2847,11 @@ config CMD_MESON default y help Enable useful commands for the Meson Soc family developed by Amlogic Inc. + +config CMD_KHADAS_KBI + bool "Khadas Bootloader Instructions" + default y + help + Khadas Bootloader Instructions + endmenu diff --git a/cmd/Makefile b/cmd/Makefile index 6c37521b4e..54a93980f7 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -218,6 +218,8 @@ obj-$(CONFIG_CMD_REGULATOR) += regulator.o obj-$(CONFIG_CMD_BLOB) += blob.o +obj-$(CONFIG_CMD_KHADAS_KBI) += kbi.o + # Android Verified Boot 2.0 obj-$(CONFIG_CMD_AVB) += avb.o diff --git a/cmd/kbi.c b/cmd/kbi.c new file mode 100644 index 0000000000..d38611ca90 --- /dev/null +++ b/cmd/kbi.c @@ -0,0 +1,1065 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHIP_ADDR 0x18 +#define CHIP_ADDR_CHAR "0x18" +#define I2C_SPEED 100000 +#if defined (CONFIG_ARCH_ROCKCHIP) + #define MCU_I2C_BUS_NUM 8 +#else + #if defined (CONFIG_MESON_GXM) || defined (CONFIG_MESON_GXL) + #define MCU_I2C_BUS_NUM 1 + #elif defined (CONFIG_MESON_G12A) + #define MCU_I2C_BUS_NUM 0 + #endif +#endif + +#define REG_PASSWD_VENDOR 0x00 +#define REG_MAC 0x06 +#define REG_USID 0x0c +#define REG_VERSION 0x12 + +#define REG_BOOT_MODE 0x20 +#define REG_BOOT_EN_WOL 0x21 +#define REG_BOOT_EN_RTC 0x22 +#define REG_BOOT_EN_IR 0x24 +#define REG_BOOT_EN_DCIN 0x25 +#define REG_BOOT_EN_KEY 0x26 +#define REG_BOOT_EN_GPIO 0x23 +#define REG_LED_SYSTEM_ON_MODE 0x28 +#define REG_LED_SYSTEM_OFF_MODE 0x29 +#define REG_ADC 0x2a +#define REG_MAC_SWITCH 0x2d + +#if defined(CONFIG_MESON_G12A) +#define REG_PORT_MODE 0x33 +#endif + +#define REG_PASSWD_CUSTOM 0x40 + +#define REG_POWER_OFF 0x80 +#define REG_PASSWD_CHECK_STATE 0x81 +#define REG_PASSWD_CHECK_VENDOR 0x82 +#define REG_PASSWD_CHECK_CUSTOM 0x83 +#define REG_POWER_STATE 0x86 + +#define BOOT_EN_WOL 0 +#define BOOT_EN_RTC 1 +#define BOOT_EN_IR 2 +#define BOOT_EN_DCIN 3 +#define BOOT_EN_KEY 4 +#define BOOT_EN_GPIO 5 + +#define LED_OFF_MODE 0 +#define LED_ON_MODE 1 +#define LED_BREATHE_MODE 2 +#define LED_HEARTBEAT_MODE 3 + +#define LED_SYSTEM_OFF 0 +#define LED_SYSTEM_ON 1 + +#define BOOT_MODE_SPI 0 +#define BOOT_MODE_EMMC 1 + +#define FORCERESET_WOL 0 +#define FORCERESET_GPIO 1 + +#define VERSION_LENGHT 2 +#define USID_LENGHT 6 +#define MAC_LENGHT 6 +#define ADC_LENGHT 2 +#define PASSWD_CUSTOM_LENGHT 6 +#define PASSWD_VENDOR_LENGHT 6 + +#if defined (CONFIG_ARCH_ROCKCHIP) + // Board Detect + #define BOARD_DETECT_ADC_DEVIATION 10 + #define BOARD_DETECT_ADC_VALUE_EDGE 1024 + #define BOARD_DETECT_ADC_VALUE_EDGEV 204 + #define BOARD_DETECT_ADC_VALUE_CAPTAIN 170 + + #define BOARD_TYPE_EDGE 1 /* Single Edge Board */ + #define BOARD_TYPE_EDGEV 2 /* Single Edge V Board */ + #define BOARD_TYPE_CAPTAIN 3 /* Edge with Captain */ + #define BOARD_TYPE_UNKNOW 0 /* Unknow board */ +#else + #define HW_VERSION_ADC_VALUE_TOLERANCE 0x28 + #define HW_VERSION_ADC_VAL_VIM1_V12 0x7FE + #define HW_VERSION_ADC_VAL_VIM1_V14 0xA1E + #define HW_VERSION_ADC_VAL_VIM2_V12 0x805 + #define HW_VERSION_ADC_VAL_VIM2_V14 0xA20 + #define HW_VERSION_ADC_VAL_VIM3_V11 0x200 + #define HW_VERSION_ADC_VAL_VIM3_V12 0x288 + #define HW_VERSION_UNKNOW 0x00 + #define HW_VERSION_VIM1_V12 0x12 + #define HW_VERSION_VIM1_V14 0x14 + #define HW_VERSION_VIM2_V12 0x22 + #define HW_VERSION_VIM2_V14 0x24 + #define HW_VERSION_VIM3_V11 0x31 + #define HW_VERSION_VIM3_V12 0x32 +#endif + +static char* LED_MODE_STR[] = { "off", "on", "breathe", "heartbeat"}; + +#ifdef CONFIG_DM_I2C +static struct udevice *i2c_cur_bus; + +static int cmd_i2c_set_bus_num(unsigned int busnum) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus); + if (ret) { + printf("%s: No bus %d\n", __func__, busnum); + return ret; + } + i2c_cur_bus = bus; + + return 0; +} + +static int i2c_get_cur_bus(struct udevice **busp) +{ + if (!i2c_cur_bus) { + if (cmd_i2c_set_bus_num(MCU_I2C_BUS_NUM)) { + printf("Default I2C bus %d not found\n", + MCU_I2C_BUS_NUM); + return -ENODEV; + } + } + + if (!i2c_cur_bus) { + puts("No I2C bus selected\n"); + return -ENODEV; + } + *busp = i2c_cur_bus; + + return 0; +} + +static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) +{ + struct udevice *bus; + int ret; + + ret = i2c_get_cur_bus(&bus); + if (ret) + return ret; + + return i2c_get_chip(bus, chip_addr, 1, devp); +} +#endif + +static int kbi_i2c_read(uint reg) +{ + int ret; + char val[64]; + uchar linebuf[1]; + uchar chip; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif + + + chip = simple_strtoul(CHIP_ADDR_CHAR, NULL, 16); + +#ifdef CONFIG_DM_I2C + ret = i2c_get_cur_bus_chip(chip, &dev); + if (!ret) + ret = dm_i2c_read(dev, reg, (uint8_t *)linebuf, 1); +#else + ret = i2c_read(chip, reg, 1, linebuf, 1); +#endif + + if (ret) + printf("Error reading the chip: %d\n",ret); + else { + sprintf(val, "%d", linebuf[0]); + ret = simple_strtoul(val, NULL, 10); + + } + return ret; +} + +static void kbi_i2c_read_block(uint start_reg, int count, char val[]) +{ + uint addr; + int nbytes; + int ret; + uchar chip; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif + + chip = simple_strtoul(CHIP_ADDR_CHAR, NULL, 16); + + nbytes = count; + addr = start_reg; + do { + unsigned char linebuf[1]; +#ifdef CONFIG_DM_I2C + ret = i2c_get_cur_bus_chip(chip, &dev); + if (!ret) + ret = dm_i2c_read(dev, addr, (uint8_t *)linebuf, 1); +#else + ret = i2c_read(chip, addr, 1, linebuf, 1); +#endif + if (ret) + printf("Error reading the chip: %d\n",ret); + else + val[count-nbytes] = linebuf[0]; + + addr++; + nbytes--; + + } while (nbytes > 0); +} + +static void get_version(void) +{ + char version[VERSION_LENGHT] = {}; + int i; + + kbi_i2c_read_block(REG_VERSION, VERSION_LENGHT, version); + printf("version: "); + for (i=0; i< VERSION_LENGHT; i++) { + printf("%02x ",version[i]); + } + printf("\n"); +} + +static void get_mac(void) +{ + char mac[64]; + char mac_addr[MAC_LENGHT] = {0}; + int i, mode; + + mode = kbi_i2c_read(REG_MAC_SWITCH); + + if (mode == 1) { + kbi_i2c_read_block(REG_MAC, MAC_LENGHT, mac_addr); + } else { + ;; +// int ret; +// ret = vendor_storage_init(); +// if (ret) { +// printf("KBI: vendor_storage_init failed %d\n", ret); +// return; +// } + +// ret = vendor_storage_read(VENDOR_LAN_MAC_ID, mac_addr, MAC_LENGHT); +// if (MAC_LENGHT == ret && !is_zero_ethaddr((const u8 *)mac_addr)) { +// debug("read mac from vendor successfully!\n"); +// } else { +// kbi_i2c_read_block(REG_MAC, MAC_LENGHT, mac_addr); +// } + + } + printf("mac address: "); + for (i=0; i= (BOARD_DETECT_ADC_VALUE_EDGEV - BOARD_DETECT_ADC_DEVIATION) && val <= (BOARD_DETECT_ADC_VALUE_EDGEV + BOARD_DETECT_ADC_DEVIATION)) { + board_type = BOARD_TYPE_EDGEV; + } else if (val >= (BOARD_DETECT_ADC_VALUE_CAPTAIN - BOARD_DETECT_ADC_DEVIATION) && val <= (BOARD_DETECT_ADC_VALUE_CAPTAIN + BOARD_DETECT_ADC_DEVIATION)) { + board_type = BOARD_TYPE_CAPTAIN; + } else if (val >= (BOARD_DETECT_ADC_VALUE_EDGE - BOARD_DETECT_ADC_DEVIATION) && val <= (BOARD_DETECT_ADC_VALUE_EDGE + BOARD_DETECT_ADC_DEVIATION)) { + board_type = BOARD_TYPE_EDGE; + } else { + board_type = BOARD_TYPE_UNKNOW; + } + + printf("board type = %s (%d)\n", board_type_to_string(board_type), board_type); + + sprintf(str, "%d", board_type); + env_set("board_type", str); + env_set("board_type_name", board_type_to_string(board_type)); + + return board_type; +} +#else +static int get_hw_version(void) +{ + unsigned int val = 0; + int hw_ver = 0; + +#if defined (CONFIG_MESON_GXM) + int ret = adc_channel_single_shot("adc@8680", 1, &val); + if (ret) { + printf("%s adc_channel_single_shot fail! ret=%ud\n", __func__, ret); + return -1; + } + + debug("%s SARADC: %ud\n", __func__, val); + + if ((val >= HW_VERSION_ADC_VAL_VIM2_V12 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM2_V12 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM2_V12; + } else if ((val >= HW_VERSION_ADC_VAL_VIM2_V14 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM2_V14 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM2_V14; + } else { + hw_ver = HW_VERSION_UNKNOW; + } +#elif defined (CONFIG_MESON_GXL) + int ret = adc_channel_single_shot("adc@8680", 1, &val); + if (ret) { + printf("%s adc_channel_single_shot fail! ret=%ud\n", __func__, ret); + return -1; + } + + debug("%s SARADC: %ud\n", __func__, val); + + if ((val >= HW_VERSION_ADC_VAL_VIM1_V14 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM1_V14 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM1_V14; + } else if ((val >= HW_VERSION_ADC_VAL_VIM1_V12 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM1_V12 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM1_V12; + } else { + hw_ver = HW_VERSION_UNKNOW; + } +#elif defined (CONFIG_MESON_G12A) +// if ((val >= HW_VERSION_ADC_VAL_VIM3_V11 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM3_V11 + HW_VERSION_ADC_VALUE_TOLERANCE)) { +// hw_ver = HW_VERSION_VIM3_V11; +// } else if ((val >= HW_VERSION_ADC_VAL_VIM3_V12 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM3_V12 + HW_VERSION_ADC_VALUE_TOLERANCE)) { +// hw_ver = HW_VERSION_VIM3_V12; +// } else { +// hw_ver = HW_VERSION_UNKNOW; +// } + // force set to V12 + hw_ver = HW_VERSION_VIM3_V12; +#endif + printf("saradc: 0x%x, hw_ver: 0x%x (%s)\n", val, hw_ver, hw_version_str(hw_ver)); + + env_set("hwver", hw_version_str(hw_ver)); + + return 0; +} +#endif + +static void get_usid(void) +{ + char serial[64]; + char usid[USID_LENGHT] = {}; + int i; +#ifdef CONFIG_USID_FROM_ETH_MAC + int mode; + mode = kbi_i2c_read(REG_MAC_SWITCH); + + if (mode == 1) { + kbi_i2c_read_block(REG_MAC, MAC_LENGHT, usid); + } else { + run_command("efuse mac", 0); + char *s = getenv("eth_mac"); + if ((s != NULL) && (strcmp(s, "00:00:00:00:00:00") != 0)) { + for (i = 0; i < 6 && s[0] != '\0' && s[1] != '\0'; i++) { + usid[i] = chartonum(s[0]) << 4 | chartonum(s[1]); + s +=3; + } + } else { + kbi_i2c_read_block(REG_MAC, MAC_LENGHT, usid); + } + } +#else + kbi_i2c_read_block(REG_USID, USID_LENGHT, usid); +#endif + printf("usid: "); + for (i=0; i< USID_LENGHT; i++) { + printf("%x",usid[i]); + } + printf("\n"); + sprintf(serial, "%02x%02x%02x%02x%02x%02x",usid[0],usid[1],usid[2],usid[3],usid[4],usid[5]); + env_set("usid", serial); +} + +static void get_adc(void) +{ + char adc[ADC_LENGHT] = {}; + kbi_i2c_read_block(REG_ADC, ADC_LENGHT, adc); + printf("adc: 0x%x\n",(adc[0] << 8) | adc[1]); + +} + + +static void get_power_state(void) +{ + int val; + val = kbi_i2c_read(REG_POWER_STATE); + if (val == 0) { + printf("normal power on\n"); + env_set("power_state","0"); + } else if (val == 1) { + printf("abort power off\n"); + env_set("power_state","1"); + } else if (val == 2) { + printf("normal power off\n"); + env_set("power_state","2"); + } else { + printf("state err\n"); + env_set("power_state","f"); + } +} + +static void set_poweroff(void) +{ + char cmd[64]; + sprintf(cmd, "i2c mw 0x18 0x80 0x1"); + run_command(cmd, 0); +} + +static void set_bootmode(int mode) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_MODE, mode); + run_command(cmd, 0); + +} + +static void get_bootmode(void) +{ + int mode; + mode = kbi_i2c_read(REG_BOOT_MODE); + + if (mode == BOOT_MODE_EMMC) { + printf("bootmode: emmc\n"); + } else if (mode == BOOT_MODE_SPI) { + printf("bootmode: spi\n"); + } else { + printf("bootmode err: %d\n",mode); + } +} + +static void get_rtc(void) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_RTC); + printf("boot rtc: %s\n", enable==1 ? "enable" : "disable" ); +} + +static void set_rtc(int enable) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_EN_RTC, enable); + run_command(cmd, 0); + +} + +static void get_dcin(void) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_DCIN); + printf("boot dcin: %s\n", enable==1 ? "enable" : "disable" ); +} + +static void set_dcin(int enable) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_EN_DCIN, enable); + run_command(cmd, 0); +} + +static void get_ir(void) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_IR); + printf("boot ir: %s\n", enable==1 ? "enable" : "disable" ); +} + +static void set_ir(int enable) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_EN_IR, enable); + run_command(cmd, 0); +} + +#if defined(CONFIG_MESON_G12A) +static void get_port_mode(void) +{ + int mode; + mode = kbi_i2c_read(REG_PORT_MODE); + printf("port mode is %s\n", mode==0 ? "usb3.0" : "pcie"); + env_set("port_mode", mode==0 ? "0" : "1"); +} + +static void set_port_mode(int mode) +{ + char cmd[64]; + if ((mode < 0) && (mode > 1)) { + printf("the mode is invalid, you can set 0 and 1"); + return; + } + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_PORT_MODE, mode); + printf("set port mode to :%s\n", mode==0 ? "usb3.0" : "pcie"); + run_command(cmd, 0); + env_set("port_mode", mode==0 ? "0" : "1"); +} +#endif + +static void get_switch_mac(void) +{ + int mode; + mode = kbi_i2c_read(REG_MAC_SWITCH); + printf("switch mac from %d\n", mode); + env_set("switch_mac", mode==1 ? "1" : "0"); +} + +static void set_switch_mac(int mode) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_MAC_SWITCH, mode); + printf("set_switch_mac :%d\n", mode); + run_command(cmd, 0); + env_set("switch_mac", mode==1 ? "1" : "0"); +} + +static void get_key(void) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_KEY); + printf("boot key: %s\n", enable==1 ? "enable" : "disable" ); +} +static void set_key(int enable) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_EN_KEY, enable); + run_command(cmd, 0); +} + +/* +static int get_forcereset_gpio(bool is_print) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_GPIO); + if (is_print) + printf("gpio forcereset: %s\n", enable&0x02 ? "enable" : "disable" ); + return enable; +} +*/ + +static int get_gpio(bool is_print) +{ + int enable; + enable = kbi_i2c_read(REG_BOOT_EN_GPIO); + if (is_print) + printf("boot gpio: %s\n", enable&0x01 ? "enable" : "disable" ); + return enable; +} + +static void set_gpio(int enable) +{ + char cmd[64]; + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_BOOT_EN_GPIO, enable); + run_command(cmd, 0); +} + +static void get_boot_enable(int type) +{ + if (type == BOOT_EN_RTC) + get_rtc(); + else if (type == BOOT_EN_IR) + get_ir(); + else if (type == BOOT_EN_DCIN) + get_dcin(); + else if (type == BOOT_EN_KEY) + get_key(); + else + get_gpio(true); +} + +static void set_boot_enable(int type, int enable) +{ + int state = 0; + if (type == BOOT_EN_RTC) + set_rtc(enable); + else if (type == BOOT_EN_IR) + set_ir(enable); + else if (type == BOOT_EN_DCIN) + set_dcin(enable); + else if (type == BOOT_EN_KEY) + set_key(enable); + else { + state = get_gpio(false); + set_gpio(enable|(state&0x02)); + } +} + +static void get_blue_led_mode(int type) +{ + int mode; + if (type == LED_SYSTEM_OFF) { + mode = kbi_i2c_read(REG_LED_SYSTEM_OFF_MODE); + if ((mode >= 0) && (mode <=3) ) + printf("led mode: %s [systemoff]\n",LED_MODE_STR[mode]); + else + printf("read led mode err\n"); + } + else { + mode = kbi_i2c_read(REG_LED_SYSTEM_ON_MODE); + if ((mode >= LED_OFF_MODE) && (mode <= LED_HEARTBEAT_MODE)) + printf("led mode: %s [systemon]\n",LED_MODE_STR[mode]); + else + printf("read led mode err\n"); + } +} + +static int set_blue_led_mode(int type, int mode) +{ + char cmd[64]; + if (type == LED_SYSTEM_OFF) { + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_LED_SYSTEM_OFF_MODE, mode); + } else if (type == LED_SYSTEM_ON) { + sprintf(cmd, "i2c mw %x %x %d 1",CHIP_ADDR, REG_LED_SYSTEM_ON_MODE, mode); + } else { + return CMD_RET_USAGE; + } + + run_command(cmd, 0); + return 0; +} + +static int do_kbi_init(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + char cmd[64]; + sprintf(cmd, "i2c dev %d", MCU_I2C_BUS_NUM); + run_command(cmd, 0); + return 0; +} + +static int do_kbi_resetflag(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) + return CMD_RET_USAGE; + + if (strcmp(argv[1], "1") == 0) { + run_command("i2c mw 0x18 0x87 1 1", 0); + } else if (strcmp(argv[1], "0") == 0) { + run_command("i2c mw 0x18 0x87 0 1", 0); + } else { + return CMD_RET_USAGE; + } + return 0; +} + +static int do_kbi_version(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + get_version(); + return 0; + +} + +static int do_kbi_usid(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + get_usid(); + return 0; +} + +static int do_kbi_adc(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + get_adc(); + return 0; +} + +static int do_kbi_powerstate(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + get_power_state(); + return 0; + +} + +static int do_kbi_ethmac(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + get_mac(); + return 0; +} + +#if defined (CONFIG_ARCH_ROCKCHIP) +static int do_kbi_boarddetect(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + detect_board(); + return 0; +} +#else +static int do_kbi_hwver(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + return get_hw_version(); +} +#endif + +static int do_kbi_switchmac(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + + if (argc < 2) + return CMD_RET_USAGE; + + if (strcmp(argv[1], "w") == 0) { + if (argc < 3) + return CMD_RET_USAGE; + + if (strcmp(argv[2], "0") == 0) { + set_switch_mac(0); + } else if (strcmp(argv[2], "1") == 0) { + set_switch_mac(1); + } else { + return CMD_RET_USAGE; + } + } else if (strcmp(argv[1], "r") == 0) { + get_switch_mac(); + } else { + return CMD_RET_USAGE; + } + return 0; +} + +#if defined (CONFIG_MESON_G12A) +static int do_kbi_portmode(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + + if (argc < 2) + return CMD_RET_USAGE; + + if (strcmp(argv[1], "w") == 0) { + if (argc < 3) + return CMD_RET_USAGE; + + if (strcmp(argv[2], "0") == 0) { + set_port_mode(0); + } else if (strcmp(argv[2], "1") == 0) { + set_port_mode(1); + } else { + return CMD_RET_USAGE; + } + } else if (strcmp(argv[1], "r") == 0) { + get_port_mode(); + } else { + return CMD_RET_USAGE; + } + return 0; +} +#endif + +static int do_kbi_led(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + int ret = 0; + if (argc < 3) + return CMD_RET_USAGE; + + if (strcmp(argv[1], "systemoff") ==0) { + if (strcmp(argv[2], "r") == 0) { + get_blue_led_mode(LED_SYSTEM_OFF); + } else if (strcmp(argv[2], "w") == 0) { + if (argc < 4) + return CMD_RET_USAGE; + if (strcmp(argv[3], "breathe") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_OFF, LED_BREATHE_MODE); + } else if (strcmp(argv[3], "heartbeat") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_OFF, LED_HEARTBEAT_MODE); + } else if (strcmp(argv[3], "on") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_OFF, LED_ON_MODE); + } else if (strcmp(argv[3], "off") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_OFF, LED_OFF_MODE); + } else { + ret = CMD_RET_USAGE; + } + } + } else if (strcmp(argv[1], "systemon") ==0) { + + if (strcmp(argv[2], "r") == 0) { + get_blue_led_mode(LED_SYSTEM_ON); + } else if (strcmp(argv[2], "w") == 0) { + if (argc <4) + return CMD_RET_USAGE; + if (strcmp(argv[3], "breathe") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_ON, LED_BREATHE_MODE); + } else if (strcmp(argv[3], "heartbeat") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_ON, LED_HEARTBEAT_MODE); + } else if (strcmp(argv[3], "on") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_ON, LED_ON_MODE); + } else if (strcmp(argv[3], "off") == 0) { + ret = set_blue_led_mode(LED_SYSTEM_ON, LED_OFF_MODE); + } else { + ret = CMD_RET_USAGE; + } + } + + } else { + return CMD_RET_USAGE; + } + return ret; +} + +static int do_kbi_poweroff(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + printf("System poweroff\n"); + set_poweroff(); + return 0; +} + +static int do_kbi_trigger(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 3) + return CMD_RET_USAGE; + + if (strcmp(argv[2], "r") == 0) { + + if (strcmp(argv[1], "rtc") == 0) + get_boot_enable(BOOT_EN_RTC); + else if (strcmp(argv[1], "ir") == 0) + get_boot_enable(BOOT_EN_IR); + else if (strcmp(argv[1], "dcin") == 0) + get_boot_enable(BOOT_EN_DCIN); + else if (strcmp(argv[1], "key") == 0) + get_boot_enable(BOOT_EN_KEY); + else if (strcmp(argv[1], "gpio") == 0) + get_boot_enable(BOOT_EN_GPIO); + else + return CMD_RET_USAGE; + } else if (strcmp(argv[2], "w") == 0) { + if (argc < 4) + return CMD_RET_USAGE; + if ((strcmp(argv[3], "1") != 0) && (strcmp(argv[3], "0") != 0)) + return CMD_RET_USAGE; + + if (strcmp(argv[1], "rtc") == 0) { + + if (strcmp(argv[3], "1") == 0) + set_boot_enable(BOOT_EN_RTC, 1); + else + set_boot_enable(BOOT_EN_RTC, 0); + + } else if (strcmp(argv[1], "ir") == 0) { + + if (strcmp(argv[3], "1") == 0) + set_boot_enable(BOOT_EN_IR, 1); + else + set_boot_enable(BOOT_EN_IR, 0); + + } else if (strcmp(argv[1], "dcin") == 0) { + + if (strcmp(argv[3], "1") == 0) + set_boot_enable(BOOT_EN_DCIN, 1); + else + set_boot_enable(BOOT_EN_DCIN, 0); + + } else if (strcmp(argv[1], "key") == 0) { + + if (strcmp(argv[3], "1") == 0) + set_boot_enable(BOOT_EN_KEY, 1); + else + set_boot_enable(BOOT_EN_KEY, 0); + + } else if (strcmp(argv[1], "gpio") == 0) { + + if (strcmp(argv[3], "1") == 0) + set_boot_enable(BOOT_EN_GPIO, 1); + else + set_boot_enable(BOOT_EN_GPIO, 0); + + } else { + return CMD_RET_USAGE; + + } + } else { + + return CMD_RET_USAGE; + } + + return 0; +} + + +static int do_kbi_bootmode(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) + return CMD_RET_USAGE; + if (strcmp(argv[1], "w") == 0) { + if (argc < 3) + return CMD_RET_USAGE; + if (strcmp(argv[2], "emmc") == 0) { + set_bootmode(BOOT_MODE_EMMC); + } else if (strcmp(argv[2], "spi") == 0) { + set_bootmode(BOOT_MODE_SPI); + } else { + return CMD_RET_USAGE; + } + } else if (strcmp(argv[1], "r") == 0) { + + get_bootmode(); + + } else { + return CMD_RET_USAGE; + } + + return 0; +} +static struct cmd_tbl cmd_kbi_sub[] = { + U_BOOT_CMD_MKENT(init, 1, 1, do_kbi_init, "", ""), + U_BOOT_CMD_MKENT(resetflag, 2, 1, do_kbi_resetflag, "", ""), + U_BOOT_CMD_MKENT(usid, 1, 1, do_kbi_usid, "", ""), + U_BOOT_CMD_MKENT(version, 1, 1, do_kbi_version, "", ""), + U_BOOT_CMD_MKENT(adc, 1, 1, do_kbi_adc, "", ""), + U_BOOT_CMD_MKENT(powerstate, 1, 1, do_kbi_powerstate, "", ""), + U_BOOT_CMD_MKENT(ethmac, 1, 1, do_kbi_ethmac, "", ""), +#if defined (CONFIG_ARCH_ROCKCHIP) + U_BOOT_CMD_MKENT(boarddetect, 1, 1, do_kbi_boarddetect, "", ""), +#else + U_BOOT_CMD_MKENT(hwver, 1, 1, do_kbi_hwver, "", ""), +#endif + U_BOOT_CMD_MKENT(poweroff, 1, 1, do_kbi_poweroff, "", ""), + U_BOOT_CMD_MKENT(switchmac, 3, 1, do_kbi_switchmac, "", ""), + U_BOOT_CMD_MKENT(led, 4, 1, do_kbi_led, "", ""), + U_BOOT_CMD_MKENT(trigger, 4, 1, do_kbi_trigger, "", ""), + U_BOOT_CMD_MKENT(bootmode, 3, 1, do_kbi_bootmode, "", ""), +#if defined(CONFIG_MESON_G12A) + U_BOOT_CMD_MKENT(portmode, 1, 1, do_kbi_portmode, "", ""), +#endif +}; + +static int do_kbi(struct cmd_tbl * cmdtp, int flag, int argc, char * const argv[]) +{ + struct cmd_tbl *c; + +#if defined (CONFIG_MESON_GXL) + int hw_ver = 0; + unsigned int val = 0; + int ret = 0; + + ret = adc_channel_single_shot("adc@8680", 1, &val); + if (ret) { + printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret); + return -1; + } + + if ((val >= HW_VERSION_ADC_VAL_VIM1_V14 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM1_V14 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM1_V14; + } else if ((val >= HW_VERSION_ADC_VAL_VIM1_V12 - HW_VERSION_ADC_VALUE_TOLERANCE) && (val <= HW_VERSION_ADC_VAL_VIM1_V12 + HW_VERSION_ADC_VALUE_TOLERANCE)) { + hw_ver = HW_VERSION_VIM1_V12; + } else { + hw_ver = HW_VERSION_UNKNOW; + } + if ((hw_ver == HW_VERSION_UNKNOW) || (hw_ver == HW_VERSION_VIM1_V12)) { + printf("The Board don't support KBI interface\n"); + env_set("hwver", hw_version_str(hw_ver)); + return CMD_RET_FAILURE; + } +#endif + + if (argc < 2) + return CMD_RET_USAGE; + + /* Strip off leading 'kbi' command argument */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], &cmd_kbi_sub[0], ARRAY_SIZE(cmd_kbi_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; + +} +static char kbi_help_text[] = + "[function] [mode] [write|read] \n" + "\n" + "kbi version - read version information\n" + "kbi usid - read usid information\n" + "kbi adc - read adc value\n" + "kbi powerstate - read power on state\n" + "kbi poweroff - power off device\n" + "kbi ethmac - read ethernet mac address\n" +#if defined (CONFIG_ARCH_ROCKCHIP) + "kbi boarddetect - detect board type\n" +#else + "kbi hwver - read board hardware version\n" +#endif + "\n" + "kbi led [systemoff|systemon] w - set blue led mode\n" + "kbi led [systemoff|systemon] r - read blue led mode\n" + "\n" + "kbi bootmode w - set bootmode to emmc or spi\n" + "kbi bootmode r - read current bootmode\n" + "\n" +#if defined(CONFIG_MESON_G12A) + "kbi portmode w <0|1> - set port as usb3.0 or pcie\n" + "kbi portmode r - read current port mode\n" + "\n" +#endif + "kbi trigger [rtc|ir|dcin|key|gpio] w <0|1> - disable/enable boot trigger\n" + "kbi trigger [rtc|ir|dcin|key|gpio] r - read mode of a boot trigger"; + + +U_BOOT_CMD( + kbi, 6, 1, do_kbi, + "Khadas Bootloader Instructions sub-system", + kbi_help_text +); -- Armbian