diff options
author | Shou-Chieh Hsu <shouchieh@google.com> | 2023-04-24 02:25:20 +0000 |
---|---|---|
committer | Shou-Chieh Hsu <shouchieh@google.com> | 2023-04-24 02:25:20 +0000 |
commit | a510225252d6f70c5b78c30c704dd6d7256fe2c4 (patch) | |
tree | f7f30b9ac00c04a1ec4aaa0a3028a9a6a1ca9e12 | |
parent | cb9e2e815903093411c5f00bf3328331046252fb (diff) | |
parent | de9944a9e66695f94916aa040d654a299198bf72 (diff) | |
download | chrome-ec-a510225252d6f70c5b78c30c704dd6d7256fe2c4.tar.gz |
Merge remote-tracking branch cros/main into firmware-dedede-13606.B-master
Generated by: util/update_release_branch.py -r --baseboard dedede
--relevant_paths_file util/dedede-relevant-paths.txt firmware-
dedede-13606.B-master
Relevant changes:
git log --oneline cb9e2e8159..de9944a9e6 -- baseboard/dedede
board/beadrix board/beetley board/blipper board/boten board/bugzzy
board/corori2 board/cret board/dibbi board/drawcia board/drawcia_riscv
board/galtic board/kracko board/lantis board/madoo board/magolor
board/metaknight board/pirika board/sasuke board/sasukette board/shotzo
board/storo board/taranza board/waddledee board/waddledoo board/wheelie
chip/it83xx common/charge_state_v2.c common/fpsensor/build.mk
common/mkbp_* common/ocpc.c common/usbc/usb_tc_drp_acc_trysrc_sm.c
common/usbc/usb_sm.c common/usbc/*_pd_* common/usbc/dp_alt_mode.c
common/usbc/usb_prl_sm.c common/usbc/usb_pe_drp_sm.c
common/usb_charger.c common/usb_common.c common/usbc_ocp.c
driver/charger/sm5803.* driver/charger/isl923x.* driver/tcpm/raa489000.*
driver/tcpm/it83* include/power/icelake.h include/intel_x86.h
power/icelake.c power/intel_x86.c util/getversion.sh
cb17c1f2eb ec: Add another #line directive for usb_common.c
f97df4fc01 beadrix: Support POW-TECH battery
b5e2ea8b0d zephyr: test: Set up OCPC test project and check console commands
7380b56e8c Taranza: Create initial EC image
312f806c07 Reland "zephyr/tests: emulator and tests for sm5803"
5d015bc961 Dibbi: Add CONFIG_EMULATED_SYSRQ
f91109844b Revert "zephyr/tests: emulator and tests for sm5803"
fd2415cda6 zephyr/tests: emulator and tests for sm5803
af177eb7ec clock: Remove the weak definition clock_enable_module
1ab21afba9 power/icelake: Wait for enough power before booting the AP
2ed86ebbcb zephyr: Eliminate pointer from SYS_INIT functions
74108a6ab3 USB-PD: Make sink automatically enter EPR mode
1366a27d9b USB-PD: Update pd console command for EPR
c3d56ca023 TCPMv2: Disable PE during ErrorRecovery
BRANCH=None
BUG=b:273720621 b:272518464 b:242544165 b:273842037 b:277664211
BUG=b:248508087 b:272188485 b:257320026 b:276805061 b:276837557
BUG=b:242544165 b:278890420 b:257320026 b:274929940 b:278595739
TEST=`make -j buildall`
Force-Relevant-Builds: all
Change-Id: I4b90aac0df3186b89ad95ca992dde886c637ea9e
Signed-off-by: Shou-Chieh Hsu <shouchieh@google.com>
329 files changed, 9520 insertions, 2303 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7e78e150c3..bc8b4c3f37 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,6 +23,7 @@ workflow: # | |_ hal_stm32/ # | |_ nanopb/ # | |_ cryptoc/ +# | |_ boringssl/ # |_ zephyr/ # |_ main/ - Zephyr repo (${ZEPHYR_BASE}) # @@ -38,6 +39,9 @@ before_script: - export EC_DIR="${CI_PROJECT_DIR}/ec_dir" - export MODULES_DIR="$CI_PROJECT_DIR/modules" - export ZEPHYR_BASE="${CI_PROJECT_DIR}/zephyr/main" + - export REPO_BASE="${CI_PROJECT_DIR}/repo" + - git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git + - export PATH="${CI_PROJECT_DIR}/depot_tools:$PATH" - git config --global --add safe.directory '*' # Get Zephyr repo and modules - checkout_at_date() { @@ -67,12 +71,38 @@ before_script: done ; git checkout -d "${rev}" ; } + - repo_clone_at_data() { + local repo="$1" ; + local branch="$2" ; + local path="$3" ; + local date="$4" ; + + mkdir -p "${REPO_BASE}" ; + cd "${REPO_BASE}" ; + repo init -u https://chromium.googlesource.com/chromiumos/manifest -b main ; + repo sync "${repo}" ; + + mkdir -p "${path}" ; + cp -rTLf "${repo}" "${path}" ; + + cd "${path}" ; + rev="$(git rev-list -n 1 --before="${date}" "${branch}")" ; + depth=1 ; + while [ -z "${rev}" ] ; do + depth="$(( ${depth} + 100 ))" ; + git fetch --depth="${depth}" ; + rev="$(git rev-list -n 1 --before="${date}" "${branch}")" ; + done ; + git checkout -d "${rev}" ; + rev="$(git rev-list -n 1 --before="${date}" "${branch}")" ; + } - ec_commit_date="$(cd ${EC_DIR} ; git log -1 HEAD --format=%cd --date=iso)" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr" "main" "${ZEPHYR_BASE}" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr/cmsis" "chromeos-main" "${MODULES_DIR}/cmsis" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr/hal_stm32" "chromeos-main" "${MODULES_DIR}/hal_stm32" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr/nanopb" "main" "${MODULES_DIR}/nanopb" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/cryptoc" "main" "${MODULES_DIR}/cryptoc" "${ec_commit_date}" + - repo_clone_at_data "src/third_party/boringssl" "m/main" "${MODULES_DIR}/boringssl" "${ec_commit_date}" # Add a symlink so the ec appears in modules directory (hack to make zmake work) - ln -s "${EC_DIR}" "${MODULES_DIR}/ec" # Install Python and packages @@ -322,12 +352,23 @@ geralt_coverage: PROJECT: "geralt" <<: *coverage_template +myst: + variables: + PROJECT: "myst" + <<: *build_template + +myst_coverage: + variables: + PROJECT: "myst" + <<: *coverage_template + ec_coverage: stage: test needs: [] script: - cd ${EC_DIR} - - make -j$(nproc) CRYPTOC_DIR="${MODULES_DIR}/cryptoc" + - make -j$(nproc) BORINGSSL_DIR="${MODULES_DIR}/boringssl" + CRYPTOC_DIR="${MODULES_DIR}/cryptoc" CROSS_COMPILE_arm=/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi- CROSS_COMPILE_host=/usr/bin/ test-coverage diff --git a/baseboard/dedede/variant_ec_it8320.c b/baseboard/dedede/variant_ec_it8320.c index 5e5590d60c..9668911978 100644 --- a/baseboard/dedede/variant_ec_it8320.c +++ b/baseboard/dedede/variant_ec_it8320.c @@ -73,7 +73,7 @@ const struct vcmp_t vcmp_list[] = { BUILD_ASSERT(ARRAY_SIZE(vcmp_list) <= CHIP_VCMP_COUNT); BUILD_ASSERT(ARRAY_SIZE(vcmp_list) == VCMP_COUNT); -#ifndef BOARD_DIBBI +#if !defined(BOARD_DIBBI) && !defined(BOARD_TARANZA) /* I2C Ports */ const struct i2c_port_t i2c_ports[] = { { .name = "eeprom", diff --git a/board/beadrix/battery.c b/board/beadrix/battery.c index 48defc0481..ba6f295e53 100644 --- a/board/beadrix/battery.c +++ b/board/beadrix/battery.c @@ -60,6 +60,35 @@ const struct board_batt_params board_battery_info[] = { .discharging_max_c = 60, }, }, + /* Pow-Tech SG20JL1C2S5900-P1P1 Battery Information */ + [BATTERY_POWTECH_SG20JL1C] = { + .fuel_gauge = { + .manuf_name = "POW-TECH", + .device_name = "SG20", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .mfgacc_support = 1, + .reg_addr = 0x54, + .reg_mask = 0x0006, + .disconnect_val = 0x0000, + } + }, + .batt_info = { + .voltage_max = 8800, /* mV */ + .voltage_normal = 7700, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 350, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 55, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); diff --git a/board/beadrix/board.h b/board/beadrix/board.h index 82a7802445..09ef205ee1 100644 --- a/board/beadrix/board.h +++ b/board/beadrix/board.h @@ -117,6 +117,7 @@ enum temp_sensor_id { TEMP_SENSOR_1, TEMP_SENSOR_2, TEMP_SENSOR_COUNT }; /* List of possible batteries */ enum battery_type { BATTERY_GANFENG, + BATTERY_POWTECH_SG20JL1C, BATTERY_TYPE_COUNT, }; diff --git a/board/dibbi/board.h b/board/dibbi/board.h index 6cfc9ea472..d2d384691b 100644 --- a/board/dibbi/board.h +++ b/board/dibbi/board.h @@ -96,6 +96,7 @@ #define CONFIG_POWER_BUTTON #define CONFIG_POWER_BUTTON_IGNORE_LID #define CONFIG_POWER_BUTTON_X86 +#define CONFIG_EMULATED_SYSRQ /* No Keyboard */ #undef CONFIG_KEYBOARD_COL2_INVERTED diff --git a/board/hades/board.h b/board/hades/board.h index cb6463c86d..14cd16bf2e 100644 --- a/board/hades/board.h +++ b/board/hades/board.h @@ -109,13 +109,13 @@ #define I2C_PORT_SENSOR NPCX_I2C_PORT0_0 #define I2C_PORT_USB_C0_TCPC NPCX_I2C_PORT1_0 -#define I2C_PORT_USB_C2_TCPC NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C1_TCPC NPCX_I2C_PORT2_0 #define I2C_PORT_USB_C0_PPC NPCX_I2C_PORT1_0 -#define I2C_PORT_USB_C2_PPC NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C1_PPC NPCX_I2C_PORT2_0 #define I2C_PORT_USB_C0_BC12 NPCX_I2C_PORT1_0 -#define I2C_PORT_USB_C2_BC12 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C1_BC12 NPCX_I2C_PORT2_0 #define I2C_PORT_USBA1_RT NPCX_I2C_PORT6_1 diff --git a/board/hades/gpio.inc b/board/hades/gpio.inc index d2b10fce5d..c9c53d7dfe 100644 --- a/board/hades/gpio.inc +++ b/board/hades/gpio.inc @@ -9,7 +9,7 @@ /* INTERRUPT GPIOs: */ GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) -GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO_INT(EC_PROCHOT_IN_L, PIN(A, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(GSC_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW, power_button_interrupt) GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) @@ -23,9 +23,9 @@ GPIO_INT(USB_C0_BC12_INT_ODL, PIN(C, 6), GPIO_INT_FALLING, bc12_inter GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, tcpc_alert_event) GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, ppc_interrupt) GPIO_INT(PG_PP3300_S5_OD, PIN(B, 4), GPIO_INT_BOTH | GPIO_PULL_UP, board_power_interrupt) -GPIO_INT(USB_C2_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt) -GPIO_INT(USB_C2_TCPC_INT_ODL, PIN(A, 7), GPIO_INT_FALLING, tcpc_alert_event) -GPIO_INT(USB_C2_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C1_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt) +GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 7), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(USB_C1_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt) GPIO_INT(BJ_ADP_PRESENT_ODL, PIN(9, 5), GPIO_INT_BOTH | GPIO_PULL_UP, bj_present_interrupt) GPIO_INT(GPU_OVERT_ODL, PIN(5, 0), GPIO_INT_BOTH, gpu_overt_interrupt) @@ -40,8 +40,8 @@ GPIO(EC_I2C_BAT_SCL, PIN(3, 3), GPIO_INPUT) GPIO(EC_I2C_BAT_SDA, PIN(3, 6), GPIO_INPUT) GPIO(EC_I2C_MISC_SCL_R, PIN(B, 3), GPIO_INPUT) GPIO(EC_I2C_MISC_SDA_R, PIN(B, 2), GPIO_INPUT) -GPIO(EC_I2C_USB_C2_SCL, PIN(9, 2), GPIO_INPUT) -GPIO(EC_I2C_USB_C2_SDA, PIN(9, 1), GPIO_INPUT) +GPIO(EC_I2C_USB_C1_SCL, PIN(9, 2), GPIO_INPUT) +GPIO(EC_I2C_USB_C1_SDA, PIN(9, 1), GPIO_INPUT) GPIO(EC_I2C_USB_C0_SCL, PIN(9, 0), GPIO_INPUT) GPIO(EC_I2C_USB_C0_SDA, PIN(8, 7), GPIO_INPUT) GPIO(EC_I2C_USBA_RT_SCL, PIN(E, 4), GPIO_INPUT) @@ -64,12 +64,13 @@ GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW) GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(EC_USB_PCH_C0_OC_ODL, PIN(9, 4), GPIO_ODR_HIGH) GPIO(EC_USB_PCH_C2_OC_ODL, PIN(9, 7), GPIO_ODR_HIGH) -GPIO(USB_C0_FRS_EN, PIN(A, 0), GPIO_OUT_LOW) GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) GPIO(EN_USB_A_LOW_POWER, PIN(9, 3), GPIO_OUT_LOW) GPIO(PG_PP3300_S5_EC_SEQ_OD, PIN(B, 5), GPIO_OUT_LOW) -GPIO(USB_C2_FRS_EN, PIN(D, 4), GPIO_OUT_LOW) +GPIO(USB_C1_FRS_EN, PIN(D, 4), GPIO_OUT_LOW) GPIO(NVIDIA_GPU_ACOFF_ODL, PIN(5, 6), GPIO_ODR_HIGH) +GPIO(LED_4_L, PIN(6, 0), GPIO_OUT_LOW) +GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_LOW) GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_LOW) GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_LOW) @@ -108,6 +109,7 @@ ALTERNATE(PIN_MASK(B, 0xC0), 0, MODULE_PWM, 0) /* GPIOB7/PWM5, GPI /* ADC alternate functions */ ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ ALTERNATE(PIN_MASK(4, 0x36), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1, GPIO41/ADC4 */ +/* TODO: GPIOF0/ADC9 for USB_C1_VBUSM */ /* KB alternate functions */ ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */ @@ -130,6 +132,4 @@ UNUSED(PIN(0, 2)) /* GPIO02 */ UNUSED(PIN(6, 6)) /* GPIO66 */ UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ UNUSED(PIN(8, 1)) /* GPIO81 */ -UNUSED(PIN(6, 0)) /* GPIO60 */ -UNUSED(PIN(C, 2)) /* GPIOC2 */ UNUSED(PIN(E, 1)) /* GPIOE1 */ diff --git a/board/hades/i2c.c b/board/hades/i2c.c index bf8c88b211..6bdbfda2f2 100644 --- a/board/hades/i2c.c +++ b/board/hades/i2c.c @@ -22,11 +22,11 @@ const struct i2c_port_t i2c_ports[] = { }, { /* I2C2 */ - .name = "tcpc2", - .port = I2C_PORT_USB_C2_TCPC, + .name = "tcpc1", + .port = I2C_PORT_USB_C1_TCPC, .kbps = 400, - .scl = GPIO_EC_I2C_USB_C2_SCL, - .sda = GPIO_EC_I2C_USB_C2_SDA, + .scl = GPIO_EC_I2C_USB_C1_SCL, + .sda = GPIO_EC_I2C_USB_C1_SDA, }, { /* I2C5 */ diff --git a/board/hades/keyboard.c b/board/hades/keyboard.c index a63feae5c2..a420ec8a4a 100644 --- a/board/hades/keyboard.c +++ b/board/hades/keyboard.c @@ -19,27 +19,24 @@ __override struct keyboard_scan_config keyscan_config = { .min_post_scan_delay_us = 1000, .poll_timeout_us = 100 * MSEC, .actual_key_mask = { - 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x1c, 0xfe, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xa4, 0xff, 0xf6, 0x55, 0xfe, 0xff, 0xff, 0xff, /* full set */ }, }; static const struct ec_response_keybd_config keybd = { - .num_top_row_keys = 13, + .num_top_row_keys = 10, .action_keys = { TK_BACK, /* T1 */ - TK_REFRESH, /* T2 */ - TK_FULLSCREEN, /* T3 */ - TK_OVERVIEW, /* T4 */ - TK_SNAPSHOT, /* T5 */ + TK_FORWARD, /* T2 */ + TK_REFRESH, /* T3 */ + TK_FULLSCREEN, /* T4 */ + TK_OVERVIEW, /* T5 */ TK_BRIGHTNESS_DOWN, /* T6 */ TK_BRIGHTNESS_UP, /* T7 */ - TK_KBD_BKLIGHT_TOGGLE, /* T8 */ - TK_PLAY_PAUSE, /* T9 */ - TK_MICMUTE, /* T10 */ - TK_VOL_MUTE, /* T11 */ - TK_VOL_DOWN, /* T12 */ - TK_VOL_UP, /* T13 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ }, /* There's no screen lock key on hades */ .capabilities = KEYBD_CAP_NUMERIC_KEYPAD, @@ -50,3 +47,19 @@ board_vivaldi_keybd_config(void) { return &keybd; } + +/* + * We have total 30 pins for keyboard connecter {-1, -1} mean + * the N/A pin that don't consider it and reserve index 0 area + * that we don't have pin 0. + */ +const int keyboard_factory_scan_pins[][2] = { + { -1, -1 }, { 0, 5 }, { 1, 1 }, { 1, 0 }, { 0, 6 }, { 0, 7 }, + { -1, -1 }, { -1, -1 }, { 1, 4 }, { 1, 3 }, { -1, -1 }, { 1, 6 }, + { 1, 7 }, { 3, 1 }, { 2, 0 }, { 1, 5 }, { 2, 6 }, { 2, 7 }, + { 2, 1 }, { 2, 4 }, { 2, 5 }, { 1, 2 }, { 2, 3 }, { 2, 2 }, + { 3, 0 }, { -1, -1 }, { 0, 4 }, { -1, -1 }, { 8, 2 }, { -1, -1 }, + { -1, -1 }, +}; +const int keyboard_factory_scan_pins_used = + ARRAY_SIZE(keyboard_factory_scan_pins); diff --git a/board/hades/led.c b/board/hades/led.c index 2781842e79..580c8e1679 100644 --- a/board/hades/led.c +++ b/board/hades/led.c @@ -41,23 +41,31 @@ enum led_color { static void led_set_color_battery(enum led_color color) { - enum gpio_signal amber_led, white_led; + enum gpio_signal amber_led1, white_led1, amber_led2, white_led2; - amber_led = GPIO_LED_1_L; - white_led = GPIO_LED_2_L; + amber_led1 = GPIO_LED_1_L; + white_led1 = GPIO_LED_2_L; + amber_led2 = GPIO_LED_3_L; + white_led2 = GPIO_LED_4_L; switch (color) { case LED_WHITE: - gpio_set_level(white_led, BAT_LED_ON); - gpio_set_level(amber_led, BAT_LED_OFF); + gpio_set_level(white_led1, BAT_LED_ON); + gpio_set_level(amber_led1, BAT_LED_OFF); + gpio_set_level(white_led2, BAT_LED_ON); + gpio_set_level(amber_led2, BAT_LED_OFF); break; case LED_AMBER: - gpio_set_level(white_led, BAT_LED_OFF); - gpio_set_level(amber_led, BAT_LED_ON); + gpio_set_level(white_led1, BAT_LED_OFF); + gpio_set_level(amber_led1, BAT_LED_ON); + gpio_set_level(white_led2, BAT_LED_OFF); + gpio_set_level(amber_led2, BAT_LED_ON); break; case LED_OFF: - gpio_set_level(white_led, BAT_LED_OFF); - gpio_set_level(amber_led, BAT_LED_OFF); + gpio_set_level(white_led1, BAT_LED_OFF); + gpio_set_level(amber_led1, BAT_LED_OFF); + gpio_set_level(white_led2, BAT_LED_OFF); + gpio_set_level(amber_led2, BAT_LED_OFF); break; default: break; diff --git a/board/hades/usbc_config.c b/board/hades/usbc_config.c index 7511773cc8..7448204aa2 100644 --- a/board/hades/usbc_config.c +++ b/board/hades/usbc_config.c @@ -46,10 +46,10 @@ const struct tcpc_config_t tcpc_config[] = { }, .drv = &rt1715_tcpm_drv, }, - [USBC_PORT_C2] = { + [USBC_PORT_C1] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { - .port = I2C_PORT_USB_C2_TCPC, + .port = I2C_PORT_USB_C1_TCPC, .addr_flags = RT1715_I2C_ADDR_FLAGS, }, .drv = &rt1715_tcpm_drv, @@ -73,14 +73,13 @@ struct ppc_config_t ppc_chips[] = { [USBC_PORT_C0] = { .i2c_port = I2C_PORT_USB_C0_PPC, .i2c_addr_flags = SYV682X_ADDR0_FLAGS, - .frs_en = GPIO_USB_C0_FRS_EN, .drv = &syv682x_drv, }, - [USBC_PORT_C2] = { - .i2c_port = I2C_PORT_USB_C2_PPC, + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_USB_C1_PPC, .i2c_addr_flags = SYV682X_ADDR2_FLAGS, - .frs_en = GPIO_USB_C2_FRS_EN, .drv = &syv682x_drv, + .frs_en = GPIO_USB_C1_FRS_EN, }, }; @@ -147,8 +146,8 @@ int board_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state) const static struct usb_mux_chain usbc2_ps8818 = { .mux = &(const struct usb_mux){ - .usb_port = USBC_PORT_C2, - .i2c_port = I2C_PORT_USB_C2_TCPC, + .usb_port = USBC_PORT_C1, + .i2c_port = I2C_PORT_USB_C1_TCPC, .i2c_addr_flags = PS8818_I2C_ADDR0_FLAGS, .driver = &ps8818_usb_retimer_driver, .board_set = &board_ps8818_mux_set, @@ -164,9 +163,9 @@ const struct usb_mux_chain usb_muxes[] = { .hpd_update = &virtual_hpd_update, }, }, - [USBC_PORT_C2] = { + [USBC_PORT_C1] = { .mux = &(const struct usb_mux) { - .usb_port = USBC_PORT_C2, + .usb_port = USBC_PORT_C1, .driver = &virtual_usb_mux_driver, .hpd_update = &virtual_hpd_update, }, @@ -181,8 +180,8 @@ const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { .i2c_port = I2C_PORT_USB_C0_BC12, .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, }, - [USBC_PORT_C2] = { - .i2c_port = I2C_PORT_USB_C2_BC12, + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_USB_C1_BC12, .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, }, }; @@ -231,15 +230,15 @@ static void board_tcpc_init(void) /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); - gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); /* Enable TCPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL); - gpio_enable_interrupt(GPIO_USB_C2_TCPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL); /* Enable BC1.2 interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); - gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL); } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET); @@ -250,7 +249,7 @@ uint16_t tcpc_get_alert_status(void) if (gpio_get_level(GPIO_USB_C0_TCPC_INT_ODL) == 0) status |= PD_STATUS_TCPC_ALERT_0; - if (gpio_get_level(GPIO_USB_C2_TCPC_INT_ODL) == 0) + if (gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0) status |= PD_STATUS_TCPC_ALERT_1; return status; @@ -261,8 +260,8 @@ int ppc_get_alert_status(int port) if (port == USBC_PORT_C0) return gpio_get_level(GPIO_USB_C0_PPC_INT_ODL) == 0; - if (port == USBC_PORT_C2) - return gpio_get_level(GPIO_USB_C2_PPC_INT_ODL) == 0; + if (port == USBC_PORT_C1) + return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0; return 0; } @@ -273,8 +272,8 @@ void tcpc_alert_event(enum gpio_signal signal) case GPIO_USB_C0_TCPC_INT_ODL: schedule_deferred_pd_interrupt(USBC_PORT_C0); break; - case GPIO_USB_C2_TCPC_INT_ODL: - schedule_deferred_pd_interrupt(USBC_PORT_C2); + case GPIO_USB_C1_TCPC_INT_ODL: + schedule_deferred_pd_interrupt(USBC_PORT_C1); break; default: break; @@ -287,7 +286,7 @@ void bc12_interrupt(enum gpio_signal signal) case GPIO_USB_C0_BC12_INT_ODL: usb_charger_task_set_event(0, USB_CHG_EVENT_BC12); break; - case GPIO_USB_C2_BC12_INT_ODL: + case GPIO_USB_C1_BC12_INT_ODL: usb_charger_task_set_event(1, USB_CHG_EVENT_BC12); break; default: @@ -301,8 +300,8 @@ void ppc_interrupt(enum gpio_signal signal) case GPIO_USB_C0_PPC_INT_ODL: syv682x_interrupt(USBC_PORT_C0); break; - case GPIO_USB_C2_PPC_INT_ODL: - syv682x_interrupt(USBC_PORT_C2); + case GPIO_USB_C1_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C1); break; default: break; diff --git a/board/hades/usbc_config.h b/board/hades/usbc_config.h index 831dcc1a9f..fa3c5d241b 100644 --- a/board/hades/usbc_config.h +++ b/board/hades/usbc_config.h @@ -10,7 +10,7 @@ #define CONFIG_USB_PD_PORT_MAX_COUNT 2 -enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C2, USBC_PORT_COUNT }; +enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; struct ps8818_reg_val { uint8_t reg; diff --git a/board/hammer/variants.h b/board/hammer/variants.h index 06dbe3d0f7..f649f27982 100644 --- a/board/hammer/variants.h +++ b/board/hammer/variants.h @@ -25,6 +25,8 @@ #define CONFIG_USB_PID 0x5057 #elif defined(BOARD_GELATIN) #define CONFIG_USB_PID 0x505D +#elif defined(BOARD_JEWEL) +#define CONFIG_USB_PID 0x5061 #elif defined(BOARD_MAGNEMITE) #define CONFIG_USB_PID 0x503d #elif defined(BOARD_MASTERBALL) @@ -105,6 +107,14 @@ #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 1060 /* tenth of mm */ #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 575 /* tenth of mm */ #define CONFIG_TOUCHPAD_VIRTUAL_SIZE (64 * 1024) +#elif defined(BOARD_JEWEL) +#define HAS_I2C_TOUCHPAD +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X 2925 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y 1440 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_PRESSURE 511 +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 929 /* tenth of mm */ +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 457 /* tenth of mm */ +#define CONFIG_TOUCHPAD_VIRTUAL_SIZE (56 * 1024) #elif defined(BOARD_MAGNEMITE) #define HAS_NO_TOUCHPAD #elif defined(BOARD_MASTERBALL) diff --git a/board/hyperdebug/board.c b/board/hyperdebug/board.c index 1c08e5f57d..d685c37964 100644 --- a/board/hyperdebug/board.c +++ b/board/hyperdebug/board.c @@ -10,6 +10,7 @@ #include "queue_policies.h" #include "registers.h" #include "spi.h" +#include "stm32-dma.h" #include "timer.h" #include "usart-stm32l5.h" #include "usb-stream.h" @@ -266,8 +267,9 @@ static void board_init(void) STM32_OCTOSPI_DCR1_DEVSIZE_MSK; /* Clock prescaler (max value 255) */ STM32_OCTOSPI_DCR2 = spi_devices[1].div; - /* Zero dummy cycles */ - STM32_OCTOSPI_TCR = 0; + + /* Select DMA channel */ + dma_select_channel(STM32_DMAC_CH13, DMAMUX_REQ_OCTOSPI1); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); diff --git a/board/hyperdebug/board.h b/board/hyperdebug/board.h index 8271f81e63..d341a6e570 100644 --- a/board/hyperdebug/board.h +++ b/board/hyperdebug/board.h @@ -144,6 +144,7 @@ /* Enable control of SPI over USB */ #define CONFIG_USB_SPI #define CONFIG_USB_SPI_BUFFER_SIZE 2048 +#define CONFIG_USB_SPI_FLASH_EXTENSIONS #define CONFIG_SPI_CONTROLLER #define CONFIG_STM32_SPI1_CONTROLLER #define CONFIG_SPI_MUTABLE_DEVICE_LIST diff --git a/board/hyperdebug/spi.c b/board/hyperdebug/spi.c index 4b549120a5..eee1626281 100644 --- a/board/hyperdebug/spi.c +++ b/board/hyperdebug/spi.c @@ -6,9 +6,11 @@ #include "common.h" #include "console.h" +#include "dma.h" #include "gpio.h" #include "registers.h" #include "spi.h" +#include "stm32-dma.h" #include "timer.h" #include "usb_spi.h" #include "util.h" @@ -28,8 +30,8 @@ struct spi_device_t spi_devices[] = { .div = 255, .gpio_cs = GPIO_CN10_6, .usb_flags = USB_SPI_ENABLED | USB_SPI_CUSTOM_SPI_DEVICE | - USB_SPI_FLASH_DUAL_SUPPORT | - USB_SPI_FLASH_QUAD_SUPPORT }, + USB_SPI_FLASH_DUAL_SUPPORT | USB_SPI_FLASH_QUAD_SUPPORT | + USB_SPI_FLASH_DTR_SUPPORT }, }; const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices); @@ -196,234 +198,282 @@ static int octospi_wait_for(uint32_t flags, timestamp_t deadline) } /* - * Write transaction: Write a number of bytes on the OCTOSPI bus. + * Board-specific SPI driver entry point, called by usb_spi.c. */ -static int octospi_indirect_write(const uint8_t *txdata, int txlen) +void usb_spi_board_enable(void) { - timestamp_t deadline; - /* Deadline on the entire SPI transaction. */ - deadline.val = get_time().val + OCTOSPI_TRANSACTION_TIMEOUT_US; - - /* Enable OCTOSPI, indirect write mode. */ - STM32_OCTOSPI_CR = STM32_OCTOSPI_CR_FMODE_IND_WRITE | - STM32_OCTOSPI_CR_EN; - /* Clear completion flag from last transaction. */ - STM32_OCTOSPI_FCR = STM32_OCTOSPI_FCR_CTCF; + /* All initialization already done in board_init(). */ +} - /* Data length. */ - STM32_OCTOSPI_DLR = txlen - 1; - /* No instruction or address, only data. */ - STM32_OCTOSPI_CCR = - STM32_OCTOSPI_CCR_IMODE_NONE | STM32_OCTOSPI_CCR_ADMODE_NONE | - STM32_OCTOSPI_CCR_ABMODE_NONE | STM32_OCTOSPI_CCR_DMODE_1WIRE; - - /* Transmit data, four bytes at a time. */ - for (int i = 0; i < txlen; i += 4) { - uint32_t value = 0; - int rv; - for (int j = 0; j < 4; j++) { - if (i + j < txlen) - value |= txdata[i + j] << (j * 8); - } - /* Wait for room in the FIFO. */ - if ((rv = octospi_wait_for(STM32_OCTOSPI_SR_FTF, deadline))) - return rv; - STM32_OCTOSPI_DR = value; - } - /* Wait for transaction completion flag. */ - return octospi_wait_for(STM32_OCTOSPI_SR_TCF, deadline); +void usb_spi_board_disable(void) +{ } +static const struct dma_option dma_octospi_option = { + .channel = STM32_DMAC_CH13, + .periph = (void *)&STM32_OCTOSPI_DR, + .flags = STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT, +}; + +static bool previous_cs; +static timestamp_t deadline; + /* - * Read transaction: Optionally write a few bytes, before reading a number of - * bytes on the OCTOSPI bus. + * Board-specific SPI driver entry point, called by usb_spi.c. On this board, + * the only spi device declared as requiring board specific driver is OCTOSPI. + * + * Actually, there is nothing board-specific in the code below, as it merely + * implements the serial flash USB protocol extensions on the OctoSPI hardware + * found on STM32L5 chips (and probably others). For now, however, HyperDebug + * is the only board that uses a chip with such an OctoSPI controller, so until + * we have seen this code being generally useful, it will live in + * board/hyperdebug. */ -static int octospi_indirect_read(const uint8_t *control_data, int control_len, - uint8_t *rxdata, int rxlen) +int usb_spi_board_transaction_async(const struct spi_device_t *spi_device, + uint32_t flash_flags, const uint8_t *txdata, + int txlen, uint8_t *rxdata, int rxlen) { - uint32_t instruction = 0, address = 0; - timestamp_t deadline; + uint32_t opcode = 0, address = 0; + const uint32_t mode = flash_flags & FLASH_FLAG_MODE_MSK; + const uint8_t width = (flash_flags & FLASH_FLAG_WIDTH_MSK) >> + FLASH_FLAG_WIDTH_POS; + uint8_t opcode_len = (flash_flags & FLASH_FLAG_OPCODE_LEN_MSK) >> + FLASH_FLAG_OPCODE_LEN_POS; + uint8_t addr_len = (flash_flags & FLASH_FLAG_ADDR_LEN_MSK) >> + FLASH_FLAG_ADDR_LEN_POS; + const uint8_t dummy_cycles = + (flash_flags & FLASH_FLAG_DUMMY_CYCLES_MSK) >> + FLASH_FLAG_DUMMY_CYCLES_POS; + uint32_t data_len; + uint32_t control_value = 0; + + if (!flash_flags) { + /* + * This is a request does not use the extended format with SPI + * flash flags, but is for doing plain write-then-read of single + * lane (COPI/CIPO) SPI data. + */ + if (rxlen == SPI_READBACK_ALL) { + cprints(CC_SPI, + "Full duplex not supported by OctoSPI hardware"); + return EC_ERROR_UNIMPLEMENTED; + } else if (!rxlen && !txlen) { + /* No operation requested, done. */ + return EC_SUCCESS; + } else if (!rxlen) { + /* + * Transmit-only transaction. This is implemented by + * not using any of the up to 12 bytes of instructions, + * but as all "data". + */ + flash_flags |= FLASH_FLAG_READ_WRITE_WRITE; + } else if (txlen <= 12) { + /* + * Sending of up to 12 bytes, followed by reading a + * possibly large number of bytes. This is implemented + * by a "read" transaction using the instruction and + * address feature of OctoSPI. + */ + if (txlen <= 4) { + opcode_len = txlen; + } else { + opcode_len = 4; + addr_len = txlen - 4; + } + } else { + /* + * Sending many bytes, followed by reading. This would + * have to be implemented as two separate OctoSPI + * transactions. + */ + cprints(CC_SPI, + "General write-then-read not supported by OctoSPI hardware"); + return EC_ERROR_UNIMPLEMENTED; + } + } + + previous_cs = gpio_get_level(spi_device->gpio_cs); + + /* Drive chip select low */ + gpio_set_level(spi_device->gpio_cs, 0); /* Deadline on the entire SPI transaction. */ deadline.val = get_time().val + OCTOSPI_TRANSACTION_TIMEOUT_US; - /* Enable OCTOSPI, indirect read mode. */ - STM32_OCTOSPI_CR = STM32_OCTOSPI_CR_FMODE_IND_READ | - STM32_OCTOSPI_CR_EN; + if ((flash_flags & FLASH_FLAG_READ_WRITE_MSK) == + FLASH_FLAG_READ_WRITE_WRITE) { + data_len = txlen - opcode_len - addr_len; + /* Enable OCTOSPI, indirect write mode. */ + STM32_OCTOSPI_CR = STM32_OCTOSPI_CR_FMODE_IND_WRITE | + STM32_OCTOSPI_CR_DMAEN | STM32_OCTOSPI_CR_EN; + } else { + data_len = rxlen; + /* Enable OCTOSPI, indirect read mode. */ + STM32_OCTOSPI_CR = STM32_OCTOSPI_CR_FMODE_IND_READ | + STM32_OCTOSPI_CR_DMAEN | STM32_OCTOSPI_CR_EN; + } + /* Clear completion flag from last transaction. */ STM32_OCTOSPI_FCR = STM32_OCTOSPI_FCR_CTCF; - /* Data length (receive). */ - STM32_OCTOSPI_DLR = rxlen - 1; - if (control_len == 0) { - /* - * Set up OCTOSPI for: No instruction, no address, then read - * data. - */ - STM32_OCTOSPI_CCR = STM32_OCTOSPI_CCR_IMODE_NONE | - STM32_OCTOSPI_CCR_ADMODE_NONE | - STM32_OCTOSPI_CCR_ABMODE_NONE | - STM32_OCTOSPI_CCR_DMODE_1WIRE; - } else if (control_len <= 4) { - /* - * Set up OCTOSPI for: One to four bytes of instruction, no - * address, then read data. - */ - STM32_OCTOSPI_CCR = STM32_OCTOSPI_CCR_IMODE_1WIRE | - (control_len - 1) - << STM32_OCTOSPI_CCR_ISIZE_POS | - STM32_OCTOSPI_CCR_ADMODE_NONE | - STM32_OCTOSPI_CCR_ABMODE_NONE | - STM32_OCTOSPI_CCR_DMODE_1WIRE; - for (int i = 0; i < control_len; i++) { - instruction <<= 8; - instruction |= control_data[i]; + /* Data length. */ + STM32_OCTOSPI_DLR = data_len - 1; + + /* + * Set up the number of bytes and data width of each of the opcode, + * address, and "alternate" stages of the initial command bytes. + */ + if (opcode_len == 0) { + control_value |= STM32_OCTOSPI_CCR_IMODE_NONE; + } else { + control_value |= (opcode_len - 1) + << STM32_OCTOSPI_CCR_ISIZE_POS; + if (mode < FLASH_FLAG_MODE_NNN) { + // Opcode phase is single-lane + control_value |= 1 << STM32_OCTOSPI_CCR_IMODE_POS; + } else { + // Opcode phase is multi-lane + control_value |= (width + 1) + << STM32_OCTOSPI_CCR_IMODE_POS; + if (flash_flags & FLASH_FLAG_DTR) + control_value |= STM32_OCTOSPI_CCR_IDTR; } - } else if (control_len <= 8) { - /* - * Set up OCTOSPI for: One to four bytes of instruction, four - * bytes of address, then read data. - */ - STM32_OCTOSPI_CCR = STM32_OCTOSPI_CCR_IMODE_1WIRE | - (control_len - 1) - << STM32_OCTOSPI_CCR_ISIZE_POS | - STM32_OCTOSPI_CCR_ADMODE_1WIRE | - STM32_OCTOSPI_CCR_ADSIZE_4BYTES | - STM32_OCTOSPI_CCR_ABMODE_NONE | - STM32_OCTOSPI_CCR_DMODE_1WIRE; - for (int i = 0; i < control_len - 4; i++) { - instruction <<= 8; - instruction |= control_data[i]; + for (int i = 0; i < opcode_len; i++) { + opcode <<= 8; + opcode |= *txdata++; + txlen--; } - for (int i = 0; i < 4; i++) { + } + if (addr_len == 0) { + control_value |= STM32_OCTOSPI_CCR_ADMODE_NONE; + control_value |= STM32_OCTOSPI_CCR_ABMODE_NONE; + } else if (addr_len <= 4) { + control_value |= (addr_len - 1) << STM32_OCTOSPI_CCR_ADSIZE_POS; + if (mode < FLASH_FLAG_MODE_1NN) { + // Address phase is single-lane + control_value |= 1 << STM32_OCTOSPI_CCR_ADMODE_POS; + } else { + // Address phase is multi-lane + control_value |= (width + 1) + << STM32_OCTOSPI_CCR_ADMODE_POS; + if (flash_flags & FLASH_FLAG_DTR) + control_value |= STM32_OCTOSPI_CCR_ADDTR; + } + for (int i = 0; i < addr_len; i++) { address <<= 8; - address |= control_data[control_len - 4 + i]; + address |= *txdata++; + txlen--; } - } else if (control_len <= 12) { + control_value |= STM32_OCTOSPI_CCR_ABMODE_NONE; + } else { uint32_t alternate = 0; - /* - * Set up OCTOSPI for: One to four bytes of instruction, four - * bytes of address, four "alternate" bytes, then read data. - */ - STM32_OCTOSPI_CCR = STM32_OCTOSPI_CCR_IMODE_1WIRE | - (control_len - 1) - << STM32_OCTOSPI_CCR_ISIZE_POS | - STM32_OCTOSPI_CCR_ADMODE_1WIRE | - STM32_OCTOSPI_CCR_ADSIZE_4BYTES | - STM32_OCTOSPI_CCR_ABMODE_1WIRE | - STM32_OCTOSPI_CCR_ABSIZE_4BYTES | - STM32_OCTOSPI_CCR_DMODE_1WIRE; - for (int i = 0; i < control_len - 8; i++) { - instruction <<= 8; - instruction |= control_data[i]; + control_value |= 3 << STM32_OCTOSPI_CCR_ADSIZE_POS; + control_value |= (addr_len - 5) << STM32_OCTOSPI_CCR_ABSIZE_POS; + if (mode < FLASH_FLAG_MODE_1NN) { + // Address phase is single-lane + control_value |= 1 << STM32_OCTOSPI_CCR_ADMODE_POS; + control_value |= 1 << STM32_OCTOSPI_CCR_ABMODE_POS; + } else { + // Address phase is multi-lane + control_value |= (width + 1) + << STM32_OCTOSPI_CCR_ADMODE_POS; + control_value |= (width + 1) + << STM32_OCTOSPI_CCR_ABMODE_POS; + if (flash_flags & FLASH_FLAG_DTR) + control_value |= STM32_OCTOSPI_CCR_ADDTR | + STM32_OCTOSPI_CCR_ABDTR; } for (int i = 0; i < 4; i++) { address <<= 8; - address |= control_data[control_len - 8 + i]; + address |= *txdata++; + txlen--; } - for (int i = 0; i < 4; i++) { + for (int i = 0; i < addr_len - 4; i++) { alternate <<= 8; - alternate |= control_data[control_len - 4 + i]; + alternate |= *txdata++; + txlen--; } STM32_OCTOSPI_ABR = alternate; + } + /* Set up how many bytes to read/write after the initial command. */ + if (data_len == 0) { + control_value |= STM32_OCTOSPI_CCR_DMODE_NONE; } else { - return EC_ERROR_UNIMPLEMENTED; + if (mode < FLASH_FLAG_MODE_11N) { + // Data phase is single-lane + control_value |= 1 << STM32_OCTOSPI_CCR_DMODE_POS; + } else { + // Data phase is multi-lane + control_value |= (width + 1) + << STM32_OCTOSPI_CCR_DMODE_POS; + if (flash_flags & FLASH_FLAG_DTR) + control_value |= STM32_OCTOSPI_CCR_DDTR; + } } + + /* Dummy cycles. */ + STM32_OCTOSPI_TCR = dummy_cycles << STM32_OCTOSPI_TCR_DCYC_POS; + + STM32_OCTOSPI_CCR = control_value; + /* Set instruction and address registers, triggering the start of the * write+read transaction. */ - STM32_OCTOSPI_IR = instruction; + STM32_OCTOSPI_IR = opcode; STM32_OCTOSPI_AR = address; - /* Receive data, four bytes at a time. */ - for (int i = 0; i < rxlen; i += 4) { - int rv; - uint32_t value; - /* Wait for data available in the FIFO. */ - if ((rv = octospi_wait_for(STM32_OCTOSPI_SR_FTF, deadline))) - return rv; - value = STM32_OCTOSPI_DR; - for (int j = 0; j < 4; j++) { - if (i + j < rxlen) - rxdata[i + j] = value >> (j * 8); + if ((flash_flags & FLASH_FLAG_READ_WRITE_MSK) == + FLASH_FLAG_READ_WRITE_WRITE) { + if (txlen > 0) { + dma_chan_t *txdma = dma_get_channel(STM32_DMAC_CH13); + dma_prepare_tx(&dma_octospi_option, txlen, txdata); + dma_go(txdma); + } + } else { + if (rxlen > 0) { + dma_start_rx(&dma_octospi_option, rxlen, rxdata); } } - /* Wait for transaction completion flag. */ - return octospi_wait_for(STM32_OCTOSPI_SR_TCF, deadline); -} -/* - * Board-specific SPI driver entry point, called by usb_spi.c. - */ -void usb_spi_board_enable(void) -{ - /* All initialization already done in board_init(). */ + return EC_SUCCESS; } -void usb_spi_board_disable(void) +int usb_spi_board_transaction_is_complete(const struct spi_device_t *spi_device) { + /* Query the "transaction complete flag" of the status register. */ + return STM32_OCTOSPI_SR & STM32_OCTOSPI_SR_TCF; } -/* - * Board-specific SPI driver entry point, called by usb_spi.c. On this board, - * the only spi device declared as requiring board specific driver is OCTOSPI. - */ -int usb_spi_board_transaction(const struct spi_device_t *spi_device, - uint32_t flash_flags, const uint8_t *txdata, - int txlen, uint8_t *rxdata, int rxlen) +int usb_spi_board_transaction_flush(const struct spi_device_t *spi_device) { - int rv = EC_SUCCESS; - bool previous_cs; - - if (flash_flags & FLASH_FLAGS_REQUIRING_SUPPORT) - return EC_ERROR_UNIMPLEMENTED; - - previous_cs = gpio_get_level(spi_device->gpio_cs); - - /* Drive chip select low */ - gpio_set_level(spi_device->gpio_cs, 0); - /* - * STM32L5 OctoSPI in "indirect mode" supports two types of SPI - * operations, "read" and "write", in addition to the main data, each - * type of operation can be preceded by up to 12 bytes of - * "instructions", (which are always written from HyperDebug to the SPI - * device). We can use the above features to support some combination - * of write-followed-by-read in a single OctoSPI transaction. + * Wait until DMA transfer is complete (no-op if DMA not started because + * of zero-length transfer). */ + int rv = dma_wait(STM32_DMAC_CH13); + dma_disable(STM32_DMAC_CH13); + if (rv != EC_SUCCESS) + return rv; - if (rxlen == SPI_READBACK_ALL) { - cprints(CC_SPI, - "Full duplex not supported by OctoSPI hardware"); - rv = EC_ERROR_UNIMPLEMENTED; - } else if (!rxlen && !txlen) { - /* No operation requested, done. */ - } else if (!rxlen) { - /* - * Transmit-only transaction. This is implemented by not using - * any of the up to 12 bytes of instructions, but as all "data". - */ - rv = octospi_indirect_write(txdata, txlen); - } else if (txlen <= 12) { - /* - * Sending of up to 12 bytes, followed by reading a possibly - * large number of bytes. This is implemented by a "read" - * transaction using the instruction and address feature of - * OctoSPI. - */ - rv = octospi_indirect_read(txdata, txlen, rxdata, rxlen); - } else { - /* - * Sending many bytes, followed by reading. This is implemented - * as two separate OctoSPI transactions. (Chip select is kept - * asserted across both transactions, outside the control of the - * OctoSPI hardware.) - */ - rv = octospi_indirect_write(txdata, txlen); - if (rv == EC_SUCCESS) - rv = octospi_indirect_read(NULL, 0, rxdata, rxlen); - } + /* + * Ensure that all bits of the last byte has been shifted onto the SPI + * bus. + */ + rv = octospi_wait_for(STM32_OCTOSPI_SR_TCF, deadline); /* Return chip select to previous level. */ gpio_set_level(spi_device->gpio_cs, previous_cs); + + return rv; +} + +int usb_spi_board_transaction(const struct spi_device_t *spi_device, + uint32_t flash_flags, const uint8_t *txdata, + int txlen, uint8_t *rxdata, int rxlen) +{ + int rv = usb_spi_board_transaction_async(spi_device, flash_flags, + txdata, txlen, rxdata, rxlen); + if (rv == EC_SUCCESS) { + rv = usb_spi_board_transaction_flush(spi_device); + } return rv; } diff --git a/board/jewel b/board/jewel new file mode 120000 index 0000000000..7f4a914148 --- /dev/null +++ b/board/jewel @@ -0,0 +1 @@ +hammer
\ No newline at end of file diff --git a/board/kindred/board.c b/board/kindred/board.c index 99375e94c7..3358b86583 100644 --- a/board/kindred/board.c +++ b/board/kindred/board.c @@ -173,11 +173,35 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, }; +static int board_anx7447_mux_set_c0(const struct usb_mux *me, + mux_state_t mux_state) +{ + int port = me->usb_port; + int rv = EC_SUCCESS; + + if (port != USB_PD_PORT_TCPC_0) + return rv; + + if (gpio_get_level(GPIO_CCD_MODE_ODL)) + return rv; + + /* + * Expect to set AUX_SWITCH to 0, but 0xc isolates the DP_AUX + * signal from SBU. + */ + CPRINTS("C%d: AUX_SW_SEL=0x%x", port, 0xc); + if (tcpc_write(port, ANX7447_REG_TCPC_AUX_SWITCH, 0xc)) + CPRINTS("C%d: Setting AUX_SW_SEL failed", port); + + return rv; +} + const struct usb_mux_chain usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { [USB_PD_PORT_TCPC_0] = { .mux = &(const struct usb_mux) { .usb_port = USB_PD_PORT_TCPC_0, .driver = &anx7447_usb_mux_driver, + .board_set = &board_anx7447_mux_set_c0, .hpd_update = &anx7447_tcpc_update_hpd_status, }, }, @@ -528,39 +552,12 @@ static void board_update_sensor_config_from_sku(void) } } -static void anx7447_set_aux_switch(void) -{ - const int port = USB_PD_PORT_TCPC_0; - - /* Debounce */ - if (gpio_get_level(GPIO_CCD_MODE_ODL)) - return; - - /* - * Expect to set AUX_SWITCH to 0, but 0xc isolates the DP_AUX - * signal from SBU. - */ - CPRINTS("C%d: AUX_SW_SEL=0x%x", port, 0xc); - if (tcpc_write(port, ANX7447_REG_TCPC_AUX_SWITCH, 0xc)) - CPRINTS("C%d: Setting AUX_SW_SEL failed", port); -} -DECLARE_DEFERRED(anx7447_set_aux_switch); - -void ccd_mode_isr(enum gpio_signal signal) -{ - /* Wait 2 seconds until all mux setting is done by PD task */ - hook_call_deferred(&anx7447_set_aux_switch_data, 2 * SECOND); -} - static void board_init(void) { /* Initialize Fans */ setup_fans(); /* Enable HDMI HPD interrupt. */ gpio_enable_interrupt(GPIO_HDMI_CONN_HPD); - /* Trigger once to set mux in case CCD cable is already connected. */ - ccd_mode_isr(GPIO_CCD_MODE_ODL); - gpio_enable_interrupt(GPIO_CCD_MODE_ODL); /* Select correct gpio signal for PP5000_A control */ board_gpio_set_pp5000(); /* Use sku_id to set motion sensor count */ diff --git a/board/kindred/gpio.inc b/board/kindred/gpio.inc index ec336c5542..cde4305f16 100644 --- a/board/kindred/gpio.inc +++ b/board/kindred/gpio.inc @@ -38,7 +38,7 @@ GPIO_INT(USB_C0_BC12_INT_ODL, PIN(9, 5), GPIO_INT_FALLING, bc12_interrupt) GPIO_INT(USB_C1_BC12_INT_ODL, PIN(E, 4), GPIO_INT_FALLING, bc12_interrupt) /* CCD mode line*/ -GPIO_INT(CCD_MODE_ODL, PIN(E, 5), GPIO_INT_FALLING, ccd_mode_isr) +GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) GPIO_INT(HDMI_CONN_HPD, PIN(7, 2), GPIO_INT_BOTH, hdmi_hpd_interrupt) diff --git a/board/taranza/board.c b/board/taranza/board.c new file mode 100644 index 0000000000..619f609b3c --- /dev/null +++ b/board/taranza/board.c @@ -0,0 +1,410 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taranza board-specific configuration */ + +#include "adc_chip.h" +#include "board.h" +#include "button.h" +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "driver/ppc/syv682x_public.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/temp_sensor/thermistor.h" +#include "driver/usb_mux/it5205.h" +#include "gpio.h" +#include "hooks.h" +#include "intc.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "switch.h" +#include "system.h" +#include "tablet_mode.h" +#include "task.h" +#include "tcpm/tcpci.h" +#include "temp_sensor.h" +#include "uart.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" + +#define CPRINTUSB(format, args...) cprints(CC_USBCHARGE, format, ##args) + +/* ADC channels */ +const struct adc_t adc_channels[] = { + [ADC_VSNS_PP3300_A] = { .name = "PP3300_A_PGOOD", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH0 }, + [ADC_TEMP_SENSOR_1] = { .name = "TEMP_SENSOR1", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH2 }, + [ADC_TEMP_SENSOR_2] = { .name = "TEMP_SENSOR2", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH3 }, + [ADC_TEMP_SENSOR_3] = { .name = "TEMP_SENSOR3", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH13 }, + [ADC_PPVAR_PWR_IN_IMON] = { .name = "ADC_PPVAR_PWR_IN_IMON", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH15 }, + [ADC_SNS_PPVAR_PWR_IN] = { .name = "ADC_SNS_PPVAR_PWR_IN", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH16 }, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +/* TCPCs */ +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + .drv = &it83xx_tcpm_drv, + }, +}; + +/* PPCs */ +struct ppc_config_t ppc_chips[] = { + [USBC_PORT_C0] = { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .frs_en = GPIO_EC_USB_C0_FRS_EN, + .drv = &syv682x_drv, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT); + +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +/* USB Muxes */ +const struct usb_mux_chain usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .mux = + &(const struct usb_mux){ + .usb_port = 0, + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS, + .driver = &it5205_usb_mux_driver, + }, + }, +}; + +/* USB-A ports */ +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_USB_A0_VBUS, + GPIO_EN_USB_A1_VBUS, + GPIO_EN_USB_A2_VBUS, + GPIO_EN_USB_A3_VBUS, +}; + +/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ +const struct pwm_t pwm_channels[] = { + [PWM_CH_LED_RED] = { + .channel = 1, + .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, + .freq_hz = 2400, + }, + + [PWM_CH_LED_GREEN] = { + .channel = 2, + .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, + .freq_hz = 2400, + }, + + [PWM_CH_LED_BLUE] = { + .channel = 3, + .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, + .freq_hz = 2400, + } + +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +/* Thermistors */ +const struct temp_sensor_t temp_sensors[] = { + [TEMP_SENSOR_1] = { .name = "Memory", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_1 }, + [TEMP_SENSOR_2] = { .name = "SoC power", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_2 }, + [TEMP_SENSOR_3] = { .name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_3 }, +}; +BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +void board_init(void) +{ + gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT); + + /* Enable PPC interrupt */ + gpio_enable_interrupt(GPIO_USB_C0_FAULT_L); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +void board_reset_pd_mcu(void) +{ + /* + * Nothing to do. TCPC C0 is internal. + */ +} + +__override void board_power_5v_enable(int enable) +{ + /* + * Nothing to do. 5V should always be enabled while in Z1 or above. + */ +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, + int charge_mv) +{ + int insufficient_power = + (charge_ma * charge_mv) < + (CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON * 1000); + /* TODO(b/259467280) blink LED on error */ + (void)insufficient_power; +} + +int board_vbus_source_enabled(int port) +{ + if (port != CHARGE_PORT_TYPEC0) + return 0; + + return ppc_is_sourcing_vbus(port); +} + +/* Vconn control for integrated ITE TCPC */ +void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) +{ + /* + * We ignore the cc_pin and PPC vconn because polarity and PPC vconn + * should already be set correctly in the PPC driver via the pd + * state machine. + */ +} + +/******************************************************************************/ +/* + * Since taranza has no battery, it must source all of its power from either + * USB-C or the barrel jack (preferred). Fizz operates in continuous safe + * mode (charge_manager_leave_safe_mode() will never be called), which + * modifies port selection as follows: + * + * - Dual-role / dedicated capability of the port partner is ignored. + * - Charge ceiling on PD voltage transition is ignored. + * - CHARGE_PORT_NONE will never be selected. + */ + +/* List of BJ adapters */ +enum bj_adapter { + BJ_NONE, + BJ_65W_19V, +}; + +/* Barrel-jack power adapter ratings. */ +static const struct charge_port_info bj_adapters[] = { + [BJ_NONE] = { .current = 0, .voltage = 0 }, + [BJ_65W_19V] = { .current = 3420, .voltage = 19000 }, +}; +#define BJ_ADP_RATING_DEFAULT BJ_65W_19V /* BJ power ratings default */ +#define ADP_DEBOUNCE_MS 1000 /* Debounce time for BJ plug/unplug */ + +/* Debounced connection state of the barrel jack */ +static int8_t bj_adp_connected = -1; +static void adp_connect_deferred(void) +{ + const struct charge_port_info *pi; + int connected = gpio_get_level(GPIO_BJ_ADP_PRESENT); + + /* Debounce */ + if (connected == bj_adp_connected) + return; + + if (connected) { + pi = &bj_adapters[BJ_ADP_RATING_DEFAULT]; + } else { + /* No barrel-jack, zero out this power supply */ + pi = &bj_adapters[BJ_NONE]; + } + /* This will result in a call to board_set_active_charge_port */ + charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED, + DEDICATED_CHARGE_PORT, pi); + bj_adp_connected = connected; +} +DECLARE_DEFERRED(adp_connect_deferred); + +/* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */ +void adp_connect_interrupt(enum gpio_signal signal) +{ + hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC); +} + +int board_set_active_charge_port(int port) +{ + const int active_port = charge_manager_get_active_charge_port(); + + CPRINTUSB("Requested charge port change to %d", port); + + if (port < 0 || CHARGE_PORT_COUNT <= port) + return EC_ERROR_INVAL; + + if (port == active_port) + return EC_SUCCESS; + + /* Don't sink from a source port */ + if (board_vbus_source_enabled(port)) + return EC_ERROR_INVAL; + + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + int bj_requested; + + if (charge_manager_get_active_charge_port() != CHARGE_PORT_NONE) + /* Change is only permitted while the system is off */ + return EC_ERROR_INVAL; + + /* + * Current setting is no charge port but the AP is on, so the + * charge manager is out of sync (probably because we're + * reinitializing after sysjump). Reject requests that aren't + * in sync with our outputs. + */ + bj_requested = port == CHARGE_PORT_BARRELJACK; + if (bj_adp_connected != bj_requested) + return EC_ERROR_INVAL; + } + + CPRINTUSB("New charger p%d", port); + + switch (port) { + case CHARGE_PORT_TYPEC0: + ppc_vbus_sink_enable(USBC_PORT_C0, 1); + gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_OD, 0); + break; + case CHARGE_PORT_BARRELJACK: + /* Make sure BJ adapter is sourcing power */ + if (!gpio_get_level(GPIO_BJ_ADP_PRESENT)) + return EC_ERROR_INVAL; + gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_OD, 1); + ppc_vbus_sink_enable(USBC_PORT_C0, 1); + break; + default: + return EC_ERROR_INVAL; + } + + return EC_SUCCESS; +} + +static void board_charge_manager_init(void) +{ + enum charge_port port; + + /* + * Initialize all charge suppliers to 0. The charge manager waits until + * all ports have reported in before doing anything. + */ + for (int i = 0; i < CHARGE_PORT_COUNT; i++) { + for (int j = 0; j < CHARGE_SUPPLIER_COUNT; j++) + charge_manager_update_charge(j, i, NULL); + } + + port = gpio_get_level(GPIO_BJ_ADP_PRESENT) ? CHARGE_PORT_BARRELJACK : + CHARGE_PORT_TYPEC0; + CPRINTUSB("Power source is p%d (%s)", port, + port == CHARGE_PORT_TYPEC0 ? "USB-C" : "BJ"); + + /* Initialize the power source supplier */ + switch (port) { + case CHARGE_PORT_TYPEC0: + typec_set_input_current_limit(port, 3000, 5000); + break; + case CHARGE_PORT_BARRELJACK: + charge_manager_update_charge( + CHARGE_SUPPLIER_DEDICATED, DEDICATED_CHARGE_PORT, + &bj_adapters[BJ_ADP_RATING_DEFAULT]); + break; + } + + /* Report charge state from the barrel jack. */ + adp_connect_deferred(); +} +DECLARE_HOOK(HOOK_INIT, board_charge_manager_init, + HOOK_PRIO_INIT_CHARGE_MANAGER + 1); + +__override int extpower_is_present(void) +{ + /* + * There's no battery, so running this method implies we have power. + */ + return 1; +} + +void ppc_interrupt(enum gpio_signal signal) +{ + if (signal == GPIO_USB_C0_FAULT_L) + syv682x_interrupt(USBC_PORT_C0); +} + +/* I2C Ports */ +const struct i2c_port_t i2c_ports[] = { + { .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA }, + + { .name = "hdmi2_edid", + .port = I2C_PORT_HDMI2_EDID, + .kbps = 100, + .scl = GPIO_EC_I2C_HDMI2_EDID_SCL, + .sda = GPIO_EC_I2C_HDMI2_EDID_SDA }, + + { .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_SCL, + .sda = GPIO_EC_I2C_USB_C0_SDA }, + + { .name = "hdmi2_src_ddc", + .port = I2C_PORT_HDMI2_SRC_DDC, + .kbps = 100, + .scl = GPIO_EC_I2C_HDMI2_SRC_DDC_SCL, + .sda = GPIO_EC_I2C_HDMI2_SRC_DDC_SDA }, + + { .name = "hdmi1_edid", + .port = I2C_PORT_HDMI1_EDID, + .kbps = 100, + .scl = GPIO_EC_I2C_HDMI1_EDID_SCL, + .sda = GPIO_EC_I2C_HDMI1_EDID_SDA }, + + { .name = "hdmi1_src_ddc", + .port = I2C_PORT_HDMI1_SRC_DDC, + .kbps = 100, + .scl = GPIO_EC_I2C_HDMI1_SRC_DDC_SCL, + .sda = GPIO_EC_I2C_HDMI1_SRC_DDC_SDA }, +}; + +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); +/* Must come after other header files and interrupt handler declarations */ +#include "gpio_list.h" diff --git a/board/taranza/board.h b/board/taranza/board.h new file mode 100644 index 0000000000..bb394f7056 --- /dev/null +++ b/board/taranza/board.h @@ -0,0 +1,167 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taranza board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* Select Baseboard features */ +#define VARIANT_DEDEDE_EC_IT8320 +#include "baseboard.h" + +/* System unlocked in early development */ +#define CONFIG_SYSTEM_UNLOCKED + +#define CONFIG_CMD_CHARGER_DUMP + +/* I2C Bus Configuration */ +#define I2C_PORT_HDMI2_EDID IT83XX_I2C_CH_B +#undef I2C_PORT_USB_C0 +#define I2C_PORT_USB_C0 IT83XX_I2C_CH_C +#define I2C_PORT_HDMI2_SRC_DDC IT83XX_I2C_CH_D +#define I2C_PORT_HDMI1_EDID IT83XX_I2C_CH_E +#define I2C_PORT_HDMI1_SRC_DDC IT83XX_I2C_CH_F + +/* Power */ +#undef CONFIG_CHARGER +#undef CONFIG_CHARGER_DISCHARGE_ON_AC +#undef CONFIG_USB_PD_VBUS_MEASURE_CHARGER +#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 16000 +#define PD_MAX_VOLTAGE_MV 20000 +#undef PD_MAX_CURRENT_MA +#define PD_MAX_CURRENT_MA 3250 +#undef PD_MAX_POWER_MW +#define PD_MAX_POWER_MW 65000 +#define CONFIG_USB_PD_VBUS_DETECT_GPIO +/* ADC sensors could measure VBUS on this board, but components are DNS */ +#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT + +/* Override macro for C0 only */ +#define PORT_TO_HPD(port) (GPIO_USB_C0_DP_HPD) + +/* Power: Dedicated barreljack charger port */ +#undef CONFIG_DEDICATED_CHARGE_PORT_COUNT +#define CONFIG_DEDICATED_CHARGE_PORT_COUNT 1 +#define DEDICATED_CHARGE_PORT 1 + +/* USB Type-C */ +#undef CONFIG_USB_CHARGER +#undef CONFIG_USB_MUX_PI3USB31532 + +/* TCPC */ +#define CONFIG_USB_PD_PORT_MAX_COUNT 1 +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP /* C0: ITE EC TCPC */ +#define CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT 1 + +/* PPC */ +#define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USB_PD_VBUS_DETECT_PPC +#define CONFIG_USBC_PPC +#define CONFIG_USBC_PPC_SYV682X + +/* USB Mux and Retimer */ +#define CONFIG_USB_MUX_IT5205 /* C0: ITE Mux */ +#define I2C_PORT_USB_MUX I2C_PORT_USB_C0 /* Required for ITE Mux */ + +/* USB Type A Features */ +#define CONFIG_USB_PORT_POWER_DUMB +#define USB_PORT_COUNT 4 /* Type A ports */ + +/* No battery */ +#undef CONFIG_BATTERY_CUT_OFF +#undef CONFIG_BATTERY_PRESENT_GPIO +#undef CONFIG_BATTERY_REQUESTS_NIL_WHEN_DEAD +#undef CONFIG_BATTERY_REVIVE_DISCONNECT +#undef CONFIG_BATTERY_SMART + +/* LED */ +#define CONFIG_LED_PWM +#define CONFIG_LED_PWM_COUNT 1 + +/* PWM */ +#define CONFIG_PWM + +/* Thermistors */ +#define CONFIG_TEMP_SENSOR +#define CONFIG_THERMISTOR +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B + +/* Buttons */ +#define CONFIG_DEDICATED_RECOVERY_BUTTON +#define CONFIG_DEDICATED_RECOVERY_BUTTON_2 +#define CONFIG_DEDICATED_RECOVERY_BUTTON_FLAGS BUTTON_FLAG_ACTIVE_HIGH +#define CONFIG_POWER_BUTTON +#define CONFIG_POWER_BUTTON_IGNORE_LID +#define CONFIG_POWER_BUTTON_X86 + +/* No Keyboard */ +#undef CONFIG_KEYBOARD_COL2_INVERTED +#undef CONFIG_KEYBOARD_PROTOCOL_8042 +#undef CONFIG_CMD_KEYBOARD +#undef CONFIG_KEYBOARD_BOOT_KEYS +#undef CONFIG_KEYBOARD_RUNTIME_KEYS + +/* No backlight */ +#undef CONFIG_BACKLIGHT_LID +#undef GPIO_ENABLE_BACKLIGHT + +/* Unused features - Misc */ +#undef CONFIG_HIBERNATE +#undef CONFIG_VOLUME_BUTTONS +#undef CONFIG_LID_SWITCH +#undef CONFIG_TABLET_MODE +#undef CONFIG_TABLET_MODE_SWITCH +#undef CONFIG_GMR_TABLET_MODE +#undef GPIO_TABLET_MODE_L + +/* Unused GPIOs */ +#undef GPIO_USB_C1_DP_HPD + +/* Pin renaming */ +#define GPIO_RECOVERY_L GPIO_EC_RECOVERY_BTN_OD +#define GPIO_RECOVERY_L_2 GPIO_H1_EC_RECOVERY_BTN_ODL +#define GPIO_POWER_BUTTON_L GPIO_H1_EC_PWR_BTN_ODL + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +enum charge_port { + CHARGE_PORT_TYPEC0, + CHARGE_PORT_BARRELJACK, +}; + +enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_COUNT }; + +enum pwm_channel { + PWM_CH_LED_RED, + PWM_CH_LED_GREEN, + PWM_CH_LED_BLUE, + PWM_CH_COUNT, +}; + +/* ADC channels */ +enum adc_channel { + ADC_VSNS_PP3300_A, /* ADC0 */ + ADC_TEMP_SENSOR_1, /* ADC2 */ + ADC_TEMP_SENSOR_2, /* ADC3 */ + ADC_TEMP_SENSOR_3, /* ADC13 */ + ADC_PPVAR_PWR_IN_IMON, /* ADC15 */ + ADC_SNS_PPVAR_PWR_IN, /* ADC16 */ + ADC_CH_COUNT +}; + +enum temp_sensor_id { + TEMP_SENSOR_1, + TEMP_SENSOR_2, + TEMP_SENSOR_3, + TEMP_SENSOR_COUNT +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/taranza/build.mk b/board/taranza/build.mk new file mode 100644 index 0000000000..9bbf403060 --- /dev/null +++ b/board/taranza/build.mk @@ -0,0 +1,15 @@ +# -*- makefile -*- +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Board specific files build +# + +CHIP:=it83xx +CHIP_FAMILY:=it8320 +CHIP_VARIANT:=it8320dx +BASEBOARD:=dedede +BOARD:=taranza + +board-y=board.o led.o usb_pd_policy.o diff --git a/board/taranza/ec.tasklist b/board/taranza/ec.tasklist new file mode 100644 index 0000000000..4aad682d14 --- /dev/null +++ b/board/taranza/ec.tasklist @@ -0,0 +1,16 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * See CONFIG_TASK_LIST in config.h for details. + */ + +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, ULTRA_TASK_STACK_SIZE) diff --git a/board/taranza/gpio.inc b/board/taranza/gpio.inc new file mode 100644 index 0000000000..5cd0ef6a8e --- /dev/null +++ b/board/taranza/gpio.inc @@ -0,0 +1,179 @@ +/* -*- mode:c -*- + * + * Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Declare symbolic names for all the GPIOs that we care about. + * Note: Those with interrupt handlers must be declared first. */ + +/* Power State interrupts */ +GPIO_INT(SLP_S4_L, PIN(I, 5), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SLP_S3_L, PIN(H, 3), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt) +GPIO_INT(SLP_S0_L, PIN(E, 4), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SLP_SUS_L, PIN(G, 2), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(VCCIN_AUX_VID0, PIN(D, 0), GPIO_INT_BOTH | GPIO_SEL_1P8V, + power_signal_interrupt) +GPIO_INT(VCCIN_AUX_VID1, PIN(K, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, + power_signal_interrupt) +GPIO_INT(RSMRST_PWRGD_L, PIN(E, 1), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(G, 1), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_DRAM_OD, PIN(D, 3), GPIO_INT_BOTH, + baseboard_all_sys_pgood_interrupt) +GPIO_INT(PG_PP1050_ST_OD, PIN(L, 1), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(EC_VSNS_PP3300_S5, PIN(I, 0), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_VCCIO_EXT_OD, PIN(D, 7), GPIO_INT_BOTH, + baseboard_all_sys_pgood_interrupt) +GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, + espi_reset_pin_asserted_interrupt) + +GPIO_INT(H1_EC_PWR_BTN_ODL, PIN(E, 2), GPIO_INT_BOTH | GPIO_PULL_UP, + power_button_interrupt) +#ifdef CONFIG_LOW_POWER_IDLE +/* Used to wake up the EC from Deep Doze mode when writing to console */ +GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_BOTH, + uart_deepsleep_interrupt) /* UART_DBG_TX_EC_RX + */ +#endif + +/* Other interrupts */ +GPIO_INT(EC_WP_OD, PIN(A, 6), GPIO_INT_BOTH, switch_interrupt) +/* Directly connected recovery button */ +GPIO_INT(EC_RECOVERY_BTN_OD, PIN(K, 7), GPIO_INT_BOTH, button_interrupt) +/* Recovery button input from H1 */ +GPIO_INT(H1_EC_RECOVERY_BTN_ODL, PIN(K, 4), GPIO_INT_BOTH, button_interrupt) +GPIO_INT(BJ_ADP_PRESENT, PIN(A, 7), GPIO_INT_BOTH, adp_connect_interrupt) +GPIO_INT(USB_C0_FAULT_L, PIN(K, 0), GPIO_INT_FALLING, ppc_interrupt) + +/* Power sequence GPIOs */ +GPIO(EC_AP_PSYS, PIN(J, 2), GPIO_OUT_LOW) +GPIO(EC_AP_RTCRST, PIN(K, 2), GPIO_OUT_LOW) +GPIO(EC_AP_PWR_BTN_ODL, PIN(B, 6), GPIO_ODR_HIGH) +GPIO(EC_AP_DPWROK, PIN(L, 7), GPIO_OUT_LOW) +GPIO(EC_AP_RSMRST_L, PIN(H, 0), GPIO_OUT_LOW) +GPIO(EC_AP_WAKE_ODL, PIN(D, 5), GPIO_ODR_HIGH) +GPIO(SYS_RST_ODL, PIN(D, 1), GPIO_ODR_HIGH) +GPIO(EC_AP_SYS_PWROK, PIN(F, 2), GPIO_OUT_LOW) +GPIO(PG_PP5000_U_OD, PIN(J, 0), GPIO_INPUT) +GPIO(EN_PP5000_U, PIN(K, 5), GPIO_OUT_HIGH) +GPIO(PG_PP3300_A, PIN(B, 5), GPIO_INPUT) +GPIO(EN_PP3300_A, PIN(C, 5), GPIO_OUT_LOW) +GPIO(EC_AP_PCH_PWROK_OD, PIN(D, 6), GPIO_ODR_LOW) +/* TODO(b:149775160) - Modify if needed if we ever use this signal. */ +GPIO(EN_VCCST, PIN(D, 4), GPIO_INPUT) +GPIO(EN_VCCIO_EXT, PIN(B, 2), GPIO_OUT_LOW) +GPIO(EC_PROCHOT_ODL, PIN(I, 1), GPIO_ODR_HIGH | GPIO_SEL_1P8V) +GPIO(EC_AP_VCCST_PWRGD_OD, PIN(E, 5), GPIO_ODR_LOW) +GPIO(ALL_SYS_PWRGD, PIN(B, 7), GPIO_OUT_LOW) +GPIO(EN_PPVAR_BJ_ADP_OD, PIN(E, 3), GPIO_ODR_HIGH) +GPIO(ACK_PPVAR_BJ_ADP_ODL, PIN(A, 0), GPIO_INPUT) + +/* Required for icelake chipset code, but implemented through other means for + * dedede */ +UNIMPLEMENTED(AC_PRESENT) +UNIMPLEMENTED(PG_EC_DSW_PWROK) +UNIMPLEMENTED(PG_EC_ALL_SYS_PWRGD) + +/* Required for dedede baseboard but not used in taranza */ +UNIMPLEMENTED(USB_C0_INT_ODL) +UNIMPLEMENTED(EN_SLP_Z) +UNIMPLEMENTED(EC_BATTERY_PRES_ODL) + +/* I2C pins - Alternate function below configures I2C module on these pins */ +GPIO(EC_I2C_EEPROM_SCL, PIN(B, 3), GPIO_INPUT) +GPIO(EC_I2C_EEPROM_SDA, PIN(B, 4), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SCL, PIN(F, 6), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SDA, PIN(F, 7), GPIO_INPUT) +GPIO(EC_I2C_HDMI1_EDID_SCL, PIN(E, 0), GPIO_INPUT) +GPIO(EC_I2C_HDMI1_EDID_SDA, PIN(E, 7), GPIO_INPUT) +GPIO(EC_I2C_HDMI2_EDID_SCL, PIN(C, 1), GPIO_INPUT) +GPIO(EC_I2C_HDMI2_EDID_SDA, PIN(C, 2), GPIO_INPUT) +GPIO(EC_I2C_HDMI1_SRC_DDC_SCL, PIN(A, 4), GPIO_INPUT) +GPIO(EC_I2C_HDMI1_SRC_DDC_SDA, PIN(A, 5), GPIO_INPUT) +GPIO(EC_I2C_HDMI2_SRC_DDC_SCL, PIN(H, 1), GPIO_INPUT) +GPIO(EC_I2C_HDMI2_SRC_DDC_SDA, PIN(H, 2), GPIO_INPUT) + +/* USB pins */ +GPIO(EC_AP_USB_C0_HPD, PIN(L, 4), GPIO_OUT_LOW) +GPIO(EN_USB_A0_VBUS, PIN(L, 6), GPIO_OUT_LOW) +GPIO(EN_USB_A1_VBUS, PIN(C, 6), GPIO_OUT_LOW) +GPIO(EN_USB_A2_VBUS, PIN(C, 4), GPIO_OUT_LOW) +GPIO(EN_USB_A3_VBUS, PIN(J, 5), GPIO_OUT_LOW) +GPIO(EC_USB_C0_FRS_EN, PIN(K, 6), GPIO_OUT_LOW) +GPIO(USB_C0_SBU_MUX_FAULT, PIN(I, 7), GPIO_INPUT) + +/* MKBP event synchronization */ +/* TODO(b/257833880) Check whether this pin is needed */ +GPIO(EC_AP_MKBP_INT_L, PIN(L, 5), GPIO_ODR_HIGH) + +/* HDMI */ +GPIO(HDMI1_CEC, PIN(F, 0), GPIO_OUT_LOW) +GPIO(HDMI2_CEC_IN, PIN(J, 3), GPIO_INPUT) +GPIO(HDMI2_CEC, PIN(F, 1), GPIO_OUT_LOW) +GPIO(HDMI1_SRC_HPD, PIN(F, 3), GPIO_INPUT) +GPIO(HDMI2_SRC_HPD, PIN(KSO_L, 3), GPIO_INPUT) +GPIO(EC_HDMI1_SRC_HPD_OUT, PIN(I, 6), GPIO_OUT_LOW) +GPIO(EC_HDMI2_SRC_HPD_OUT, PIN(KSO_L, 4), GPIO_OUT_LOW) +GPIO(HDMI1_EDID_SEL, PIN(J, 1), GPIO_OUT_LOW) +GPIO(HDMI2_EDID_SEL, PIN(KSO_L, 5), GPIO_OUT_LOW) +GPIO(EDID_BTN_ODL, PIN(C, 3), GPIO_INPUT) +GPIO(EC_EN_PP5000_HDMI1, PIN(KSO_L, 6), GPIO_OUT_LOW) +GPIO(EC_EN_PP5000_HDMI2, PIN(KSO_L, 7), GPIO_OUT_LOW) + +/* Misc */ +GPIO(EC_ENTERING_RW, PIN(C, 7), GPIO_OUT_LOW) +GPIO(CCD_MODE_ODL, PIN(H, 5), GPIO_ODR_HIGH) +GPIO(ECH1_PACKET_MODE, PIN(C, 0), GPIO_OUT_LOW) +GPIO(EN_RS232_X, PIN(E, 6), GPIO_OUT_LOW) +GPIO(UART0_RX, PIN(B, 1), GPIO_OUT_LOW) /* UART_EC_TX_DBG_RX */ + +/* NC pins, enable internal pull-down to avoid floating state. */ +GPIO(GPIOG0_NC, PIN(G, 0), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOG3_NC, PIN(G, 3), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOG4_NC, PIN(G, 4), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOG5_NC, PIN(G, 5), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOG6_NC, PIN(G, 6), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOG7_NC, PIN(G, 7), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOH4_NC, PIN(H, 4), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOH6_NC, PIN(H, 6), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOI4_NC, PIN(I, 4), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOJ4_NC, PIN(J, 4), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOJ6_NC, PIN(J, 6), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOK3_NC, PIN(K, 3), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOM6_NC, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) + +/* Alternate functions GPIO definitions */ +/* UART */ +ALTERNATE(PIN_MASK(B, BIT(0) | BIT(1)), 0, MODULE_UART, 0) /* UART for debug */ + +/* I2C */ +ALTERNATE(PIN_MASK(B, BIT(3) | BIT(4)), 0, MODULE_I2C, 0) /* I2C0 - EEPROM */ +ALTERNATE(PIN_MASK(C, BIT(1) | BIT(2)), 0, MODULE_I2C, 0) /* I2C1 - HDMI2_EDID + */ +ALTERNATE(PIN_MASK(F, BIT(6) | BIT(7)), 0, MODULE_I2C, 0) /* I2C2 - USB_C0 */ +ALTERNATE(PIN_MASK(E, BIT(0) | BIT(7)), 0, MODULE_I2C, 0) /* I2C4 - HDMI1_EDID + */ +ALTERNATE(PIN_MASK(A, BIT(4) | BIT(5)), 0, MODULE_I2C, 0) /* I2C5 - + HDMI1_SRC_DDC */ +ALTERNATE(PIN_MASK(H, BIT(1) | BIT(2)), 0, MODULE_I2C, 0) /* I2C3 - + HDMI2_SRC_DDC */ + +/* ADC */ +ALTERNATE(PIN_MASK(I, BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC2: + TEMP_SENSOR_1, + ADC3: TEMP_SENSOR_2 + */ +ALTERNATE(PIN_MASK(L, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, + 0) /* ADC13: + TEMP_SENSOR_3, + ADC15: + ANALOG_PPVAR_PWR_IN_IMON, + ADC16: + SNS_PPVAR_PWR_IN + */ + +/* PWM */ +ALTERNATE(PIN_MASK(A, BIT(1) | BIT(2) | BIT(3)), 0, MODULE_PWM, + 0) /* LED_[R,G,B]_ODL + */ diff --git a/board/taranza/led.c b/board/taranza/led.c new file mode 100644 index 0000000000..31ab932829 --- /dev/null +++ b/board/taranza/led.c @@ -0,0 +1,80 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taranza specific PWM LED settings. */ + +#include "common.h" +#include "ec_commands.h" +#include "led_pwm.h" +#include "pwm.h" +#include "util.h" + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_POWER_LED, +}; +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +/* One physical LED with red, green, and blue. */ +struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { + /* Red, Green, Blue */ + [EC_LED_COLOR_RED] = { 100, 0, 0 }, + [EC_LED_COLOR_GREEN] = { 0, 100, 0 }, + [EC_LED_COLOR_BLUE] = { 0, 0, 100 }, + [EC_LED_COLOR_YELLOW] = { 50, 50, 0 }, + [EC_LED_COLOR_WHITE] = { 50, 50, 50 }, + [EC_LED_COLOR_AMBER] = { 70, 30, 0 }, +}; + +/* One logical LED with red, green, and blue channels. */ +struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { + { + .ch0 = PWM_CH_LED_RED, + .ch1 = PWM_CH_LED_GREEN, + .ch2 = PWM_CH_LED_BLUE, + .enable = &pwm_enable, + .set_duty = &pwm_set_duty, + }, +}; + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + memset(brightness_range, '\0', + sizeof(*brightness_range) * EC_LED_COLOR_COUNT); + brightness_range[EC_LED_COLOR_RED] = 100; + brightness_range[EC_LED_COLOR_GREEN] = 100; + brightness_range[EC_LED_COLOR_BLUE] = 100; + brightness_range[EC_LED_COLOR_YELLOW] = 100; + brightness_range[EC_LED_COLOR_WHITE] = 100; + brightness_range[EC_LED_COLOR_AMBER] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + enum pwm_led_id pwm_id; + + /* Convert ec_led_id to pwm_led_id. */ + if (led_id == EC_LED_ID_POWER_LED) + pwm_id = PWM_LED0; + else + return EC_ERROR_UNKNOWN; + + if (brightness[EC_LED_COLOR_RED]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_RED); + else if (brightness[EC_LED_COLOR_GREEN]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_GREEN); + else if (brightness[EC_LED_COLOR_BLUE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_BLUE); + else if (brightness[EC_LED_COLOR_YELLOW]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_YELLOW); + else if (brightness[EC_LED_COLOR_WHITE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); + else + /* Otherwise, the "color" is "off". */ + set_pwm_led_color(pwm_id, -1); + + return EC_SUCCESS; +} diff --git a/board/taranza/usb_pd_policy.c b/board/taranza/usb_pd_policy.c new file mode 100644 index 0000000000..e95e5f7a85 --- /dev/null +++ b/board/taranza/usb_pd_policy.c @@ -0,0 +1,85 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_manager.h" +#include "charger.h" +#include "chipset.h" +#include "common.h" +#include "console.h" +#include "gpio.h" +#include "usb_pd.h" +#include "usbc_ppc.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) + +__override int pd_check_power_swap(int port) +{ + /* If type-c port is supplying power, we never swap PR (to source) */ + if (port == charge_manager_get_active_charge_port()) + return 0; + /* + * Allow power swap as long as we are acting as a dual role device, + * otherwise assume our role is fixed (not in S0 or console command + * to fix our role). + */ + return (pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ? 1 : 0); +} + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on */ + return gpio_get_level(GPIO_EN_PP5000_U); +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= board_get_usb_pd_port_count()) + return; + + prev_en = ppc_is_sourcing_vbus(port); + + /* Disable VBUS source */ + ppc_vbus_source_enable(port, 0); + + /* Enable discharge if we were previously sourcing 5V */ + if (prev_en) + pd_set_vbus_discharge(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + /* Disable charging */ + rv = ppc_vbus_sink_enable(port, 0); + if (rv) + return rv; + + pd_set_vbus_discharge(port, 0); + + /* Enable VBUS source */ + rv = ppc_vbus_source_enable(port, 1); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +__override int pd_snk_is_vbus_provided(int port) +{ + if (port != CHARGE_PORT_TYPEC0) + return 0; + + return ppc_is_vbus_present(port); +} diff --git a/board/taranza/vif_override.xml b/board/taranza/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/taranza/vif_override.xml @@ -0,0 +1,3 @@ +<!-- Add VIF field overrides here. See genvif.c and the Vendor Info File + Definition from the USB-IF. +--> diff --git a/chip/host/clock.c b/chip/host/clock.c index 4f90067f3a..defb12f4f0 100644 --- a/chip/host/clock.c +++ b/chip/host/clock.c @@ -11,3 +11,7 @@ int clock_get_freq(void) { return 16000000; } + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/ish/clock.c b/chip/ish/clock.c index f9fec0b7d2..2fefa11c2f 100644 --- a/chip/ish/clock.c +++ b/chip/ish/clock.c @@ -29,3 +29,7 @@ void clock_refresh_console_in_use(void) */ ish_pm_refresh_console_in_use(); } + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/it83xx/clock.c b/chip/it83xx/clock.c index fccc62eee7..abbbcf3b58 100644 --- a/chip/it83xx/clock.c +++ b/chip/it83xx/clock.c @@ -701,3 +701,7 @@ DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats, "", #endif /* CONFIG_CMD_IDLE_STATS */ #endif /* CONFIG_LOW_POWER_IDLE */ + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/max32660/clock_chip.c b/chip/max32660/clock_chip.c index 26225401ba..8e497c846b 100644 --- a/chip/max32660/clock_chip.c +++ b/chip/max32660/clock_chip.c @@ -139,3 +139,7 @@ void clock_init(void) } } } + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c index 0323d16f8f..8732e21117 100644 --- a/chip/mchp/clock.c +++ b/chip/mchp/clock.c @@ -750,3 +750,7 @@ DECLARE_CONSOLE_COMMAND( "Give a timeout value for the console in use timeout.\n" "See also 'sleep mask'."); #endif /* CONFIG_LOW_POWER_IDLE */ + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/mt_scp/mt818x/clock_mt8183.c b/chip/mt_scp/mt818x/clock_mt8183.c index fca89cd2a5..a48eee952a 100644 --- a/chip/mt_scp/mt818x/clock_mt8183.c +++ b/chip/mt_scp/mt818x/clock_mt8183.c @@ -370,3 +370,7 @@ static int command_ulposc(int argc, const char *argv[]) } DECLARE_CONSOLE_COMMAND(ulposc, command_ulposc, "[calibrate]", "Calibrate ULPOSC frequency"); + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/mt_scp/mt818x/clock_mt8186.c b/chip/mt_scp/mt818x/clock_mt8186.c index cb0d339b5f..eafc5992fd 100644 --- a/chip/mt_scp/mt818x/clock_mt8186.c +++ b/chip/mt_scp/mt818x/clock_mt8186.c @@ -376,3 +376,7 @@ static int command_ulposc(int argc, const char *argv[]) } DECLARE_CONSOLE_COMMAND(ulposc, command_ulposc, "[calibrate]", "Calibrate ULPOSC frequency"); + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/mt_scp/mt8192/clock.c b/chip/mt_scp/mt8192/clock.c index 21d07d410a..ec6e3f2537 100644 --- a/chip/mt_scp/mt8192/clock.c +++ b/chip/mt_scp/mt8192/clock.c @@ -381,3 +381,7 @@ int command_ulposc(int argc, const char *argv[]) DECLARE_CONSOLE_COMMAND(ulposc, command_ulposc, "[ulposc]", "Measure ULPOSC frequency"); #endif + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/mt_scp/mt8195/clock.c b/chip/mt_scp/mt8195/clock.c index 779f356bab..e41a360ae8 100644 --- a/chip/mt_scp/mt8195/clock.c +++ b/chip/mt_scp/mt8195/clock.c @@ -501,3 +501,7 @@ int command_ulposc(int argc, const char *argv[]) DECLARE_CONSOLE_COMMAND(ulposc, command_ulposc, "[ulposc]", "Measure ULPOSC frequency"); #endif + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/chip/npcx/clock.c b/chip/npcx/clock.c index 1ab4d1063a..992fc1b628 100644 --- a/chip/npcx/clock.c +++ b/chip/npcx/clock.c @@ -162,6 +162,11 @@ void clock_turbo(void) */ NPCX_HFCBCD = NPCX_HFCBCD & 0xF3; } + +void clock_enable_module(enum module_id module, int enable) +{ +} + #elif NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7 void clock_turbo(void) { @@ -200,6 +205,12 @@ void clock_enable_module(enum module_id module, int enable) } } +#else + +void clock_enable_module(enum module_id module, int enable) +{ +} + #endif /** diff --git a/chip/stm32/trng.c b/chip/stm32/trng.c index aafc0e89c1..67d3700cf1 100644 --- a/chip/stm32/trng.c +++ b/chip/stm32/trng.c @@ -16,7 +16,7 @@ #include "trng.h" #include "util.h" -uint32_t trng_rand(void) +static uint32_t trng_rand(void) { int tries = 300; /* Wait for a valid random number */ diff --git a/chip/stm32/usb_spi.c b/chip/stm32/usb_spi.c index c45ea3520d..0ddde1b0d8 100644 --- a/chip/stm32/usb_spi.c +++ b/chip/stm32/usb_spi.c @@ -8,11 +8,18 @@ #include "link_defs.h" #include "registers.h" #include "spi.h" +#include "timer.h" #include "usb_descriptor.h" #include "usb_hw.h" #include "usb_spi.h" #include "util.h" +/* How long to wait for a flash page programming. */ +#define FLASH_BUSY_POLL_TIMEOUT_USEC (1000 * MSEC) + +const uint8_t JEDEC_READ_STATUS = 0x05; +const uint8_t JEDEC_STATUS_BUSY = 0x01; + /* Forward declare platform specific functions. */ static bool usb_spi_received_packet(void); static bool usb_spi_transmitted_packet(void); @@ -164,6 +171,9 @@ static void setup_transfer_response(uint16_t status_code) */ static void create_spi_config_response(struct usb_spi_packet_ctx *packet) { + const struct spi_device_t *current_device = + &spi_devices[usb_spi_state.current_spi_device_idx]; + /* Construct the response packet. */ packet->rsp_config.packet_id = USB_SPI_PKT_ID_RSP_USB_SPI_CONFIG; packet->rsp_config.max_write_count = USB_SPI_MAX_WRITE_COUNT; @@ -174,6 +184,23 @@ static void create_spi_config_response(struct usb_spi_packet_ctx *packet) packet->rsp_config.feature_bitmap |= USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED; #endif +#ifdef CONFIG_USB_SPI_FLASH_EXTENSIONS + packet->rsp_config.feature_bitmap |= USB_SPI_FEATURE_FLASH_EXTENSIONS; + if (current_device->usb_flags & USB_SPI_FLASH_DUAL_SUPPORT) + packet->rsp_config.feature_bitmap |= + USB_SPI_FEATURE_DUAL_MODE_SUPPORTED; + if (current_device->usb_flags & USB_SPI_FLASH_QUAD_SUPPORT) + packet->rsp_config.feature_bitmap |= + USB_SPI_FEATURE_QUAD_MODE_SUPPORTED; + if (current_device->usb_flags & USB_SPI_FLASH_OCTO_SUPPORT) + packet->rsp_config.feature_bitmap |= + USB_SPI_FEATURE_OCTO_MODE_SUPPORTED; + if (current_device->usb_flags & USB_SPI_FLASH_DTR_SUPPORT) + packet->rsp_config.feature_bitmap |= + USB_SPI_FEATURE_DTR_SUPPORTED; +#else + (void)current_device; /* Avoid warning about unused variable. */ +#endif packet->packet_size = sizeof(struct usb_spi_response_configuration_v2); } @@ -231,6 +258,45 @@ usb_spi_create_spi_transfer_response(struct usb_spi_packet_ctx *transmit_packet) } } +#ifdef CONFIG_USB_SPI_FLASH_EXTENSIONS +/* + * Decodes the header fields of a Flash Command Start Packet, and sets up the + * transaction depending on if it is read or write. + */ +static void setup_flash_transfer(struct usb_spi_packet_ctx *packet) +{ + const uint32_t flags = packet->cmd_flash_start.flags; + usb_spi_state.flash_flags = flags; + const uint8_t opcode_count = (flags & FLASH_FLAG_OPCODE_LEN_MSK) >> + FLASH_FLAG_OPCODE_LEN_POS; + const uint8_t addr_count = (flags & FLASH_FLAG_ADDR_LEN_MSK) >> + FLASH_FLAG_ADDR_LEN_POS; + const bool write_enable = !!(flags & FLASH_FLAG_WRITE_ENABLE); + if ((packet->cmd_flash_start.flags & FLASH_FLAG_READ_WRITE_MSK) == + FLASH_FLAG_READ_WRITE_WRITE) { + size_t write_count = packet->cmd_flash_start.count; + if (write_count > USB_SPI_MAX_WRITE_COUNT) { + usb_spi_state.status_code = USB_SPI_WRITE_COUNT_INVALID; + return; + } + usb_spi_setup_transfer(write_enable + opcode_count + + addr_count + write_count, + 0); + } else { + size_t read_count = packet->cmd_flash_start.count; + if (read_count > USB_SPI_MAX_READ_COUNT) { + usb_spi_state.status_code = USB_SPI_WRITE_COUNT_INVALID; + return; + } + usb_spi_setup_transfer(write_enable + opcode_count + addr_count, + read_count); + } + packet->header_size = offsetof(struct usb_spi_flash_command, data); + usb_spi_state.status_code = + usb_spi_read_usb_packet(&usb_spi_state.spi_write_ctx, packet); +} +#endif + /* * Process the rx packet. * @@ -266,6 +332,7 @@ static void usb_spi_process_rx_packet(struct usb_spi_packet_ctx *packet) /* The host started a new USB SPI transfer */ size_t write_count = packet->cmd_start.write_count; size_t read_count = packet->cmd_start.read_count; + usb_spi_state.flash_flags = 0; if (!usb_spi_state.enabled) { setup_transfer_response(USB_SPI_DISABLED); @@ -302,6 +369,30 @@ static void usb_spi_process_rx_packet(struct usb_spi_packet_ctx *packet) break; } +#ifdef CONFIG_USB_SPI_FLASH_EXTENSIONS + case USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START: { + /* The host started a new USB serial flash SPI transfer */ + if (!usb_spi_state.enabled) { + setup_transfer_response(USB_SPI_DISABLED); + } else { + setup_flash_transfer(packet); + } + + /* Send responses if we encountered an error. */ + if (usb_spi_state.status_code != USB_SPI_SUCCESS) { + setup_transfer_response(usb_spi_state.status_code); + break; + } + + /* Start the SPI transfer when we've read all data. */ + if (usb_spi_state.spi_write_ctx.transfer_index == + usb_spi_state.spi_write_ctx.transfer_size) { + usb_spi_state.mode = USB_SPI_MODE_START_SPI; + } + + break; + } +#endif case USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE: { /* * The host has sent a continue packet for the SPI transfer @@ -355,6 +446,107 @@ static void usb_spi_process_rx_packet(struct usb_spi_packet_ctx *packet) } } +/* + * Perform a SPI write-then-read transaction, optionally preceded by a single + * byte "write enable" (separated by deasserting chip select), and optionally + * followed by polling the "busy bit" until clear. + */ +static uint16_t do_spi_transfer(void) +{ + const struct spi_device_t *current_device = + &spi_devices[usb_spi_state.current_spi_device_idx]; + bool custom_board_driver = current_device->usb_flags & + USB_SPI_CUSTOM_SPI_DEVICE; + /* + * If CONFIG_USB_SPI_FLASH_EXTENSIONS is not enabled, then the below + * value being zero will allow the compiler to optimize away several + * large if-blocks in this function. + */ + const uint32_t flash_flags = + IS_ENABLED(CONFIG_USB_SPI_FLASH_EXTENSIONS) ? + usb_spi_state.flash_flags : + 0; + uint16_t status_code = EC_SUCCESS; + int read_count = usb_spi_state.spi_read_ctx.transfer_size; + const char *write_data_ptr = usb_spi_state.spi_write_ctx.buffer; + int write_count = usb_spi_state.spi_write_ctx.transfer_size; +#ifndef CONFIG_SPI_HALFDUPLEX + /* + * Handle the full duplex mode on supported platforms. + * The read count is equal to the write count. + */ + if (read_count == USB_SPI_FULL_DUPLEX_ENABLED) { + usb_spi_state.spi_read_ctx.transfer_size = + usb_spi_state.spi_write_ctx.transfer_size; + read_count = SPI_READBACK_ALL; + } +#endif + + if (!custom_board_driver && + (flash_flags & FLASH_FLAGS_REQUIRING_SUPPORT)) { + /* + * The standard spi_transaction() does not support + * any multi-lane modes. + */ + return USB_SPI_UNSUPPORTED_FLASH_MODE; + } + + if (status_code == EC_SUCCESS && + flash_flags & FLASH_FLAG_WRITE_ENABLE) { + /* Precede main transaction with one-byte "write enable". */ + if (custom_board_driver) { + status_code = usb_spi_board_transaction( + current_device, 0, write_data_ptr, 1, NULL, 0); + } else { + status_code = spi_transaction( + current_device, write_data_ptr, 1, NULL, 0); + } + write_data_ptr += 1; + write_count -= 1; + } + + if (status_code == EC_SUCCESS) { + if (custom_board_driver) { + status_code = usb_spi_board_transaction( + current_device, flash_flags, write_data_ptr, + write_count, usb_spi_state.spi_read_ctx.buffer, + read_count); + } else { + status_code = spi_transaction( + current_device, write_data_ptr, write_count, + usb_spi_state.spi_read_ctx.buffer, read_count); + } + } + + if (flash_flags & FLASH_FLAG_POLL) { + /* After main transaction, poll until no longer "busy". */ + static timestamp_t deadline; + deadline.val = get_time().val + FLASH_BUSY_POLL_TIMEOUT_USEC; + + while (status_code == EC_SUCCESS) { + timestamp_t now; + uint8_t status_byte; + if (custom_board_driver) { + status_code = usb_spi_board_transaction( + current_device, 0, &JEDEC_READ_STATUS, + 1, &status_byte, 1); + } else { + status_code = spi_transaction( + current_device, &JEDEC_READ_STATUS, 1, + &status_byte, 1); + } + if ((status_byte & JEDEC_STATUS_BUSY) == 0) + break; + now = get_time(); + if (timestamp_expired(deadline, &now)) { + status_code = EC_ERROR_TIMEOUT; + break; + } + } + } + return usb_spi_map_error(status_code); +} + /* Deferred function to handle state changes, process USB SPI packets, * and construct responses. * @@ -412,40 +604,7 @@ void usb_spi_deferred(void) /* Start a new SPI transfer. */ if (usb_spi_state.mode == USB_SPI_MODE_START_SPI) { - const struct spi_device_t *current_device = - &spi_devices[usb_spi_state.current_spi_device_idx]; - bool custom_board_driver = current_device->usb_flags & - USB_SPI_CUSTOM_SPI_DEVICE; - uint16_t status_code; - int read_count = usb_spi_state.spi_read_ctx.transfer_size; -#ifndef CONFIG_SPI_HALFDUPLEX - /* - * Handle the full duplex mode on supported platforms. - * The read count is equal to the write count. - */ - if (read_count == USB_SPI_FULL_DUPLEX_ENABLED) { - usb_spi_state.spi_read_ctx.transfer_size = - usb_spi_state.spi_write_ctx.transfer_size; - read_count = SPI_READBACK_ALL; - } -#endif - - if (custom_board_driver) { - status_code = usb_spi_board_transaction( - current_device, 0 /* flash_flags */, - usb_spi_state.spi_write_ctx.buffer, - usb_spi_state.spi_write_ctx.transfer_size, - usb_spi_state.spi_read_ctx.buffer, read_count); - } else { - status_code = spi_transaction( - current_device, - usb_spi_state.spi_write_ctx.buffer, - usb_spi_state.spi_write_ctx.transfer_size, - usb_spi_state.spi_read_ctx.buffer, read_count); - } - - /* Cast the EC status code to USB SPI and start the response. */ - status_code = usb_spi_map_error(status_code); + uint16_t status_code = do_spi_transfer(); setup_transfer_response(status_code); } diff --git a/chip/stm32/usb_spi.h b/chip/stm32/usb_spi.h index 385aaaf730..e0dfd34b18 100644 --- a/chip/stm32/usb_spi.h +++ b/chip/stm32/usb_spi.h @@ -146,6 +146,7 @@ * 0x0008: An unexpected packet arrived that the device could not * process. * 0x0009: The device does not support full duplex mode. + * 0x000A: Requested serial flash mode not supported * 0x8000: Unknown error mask * The bottom 15 bits will contain the bottom 15 bits from the EC * error code. @@ -218,7 +219,12 @@ * * feature bitmap: Bitmap of supported features. * BIT(0): Full duplex SPI mode is supported - * BIT(1:15): Reserved for future use + * BIT(1): Serial flash extensions are supported + * BIT(2): Dual mode flash supported + * BIT(3): Quad mode flash supported + * BIT(4): Octo mode flash supported + * BIT(5): Double transfer rate supported + * BIT(6:15): Reserved for future use * * Command Restart Response Packet (Host to Device): * @@ -256,6 +262,64 @@ * 0x0000: Success * others: Error * + * Flash Command Start Packet (Host to Device): + * + * Start of the USB serial flash SPI command, contains the number of + * bytes to write or read on SPI and up to the first 58 bytes of write + * payload. Longer writes will use the continue packets with packet id + * USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data. + * + * The reading or writing of the "main" data will be preceded by an + * short sequence of opcode, optional address, optional "alternate data", + * and optional 'dummy cycles" on the SPI bus. Flags indicate how many + * bytes of each stage to send, and whether to use advanced features such + * as dual or quad signal lanes for each stage of the transfer". + * + * The indicated number of opcode, address and alternate bytes will be + * the first in the "write payload". The "count" field will contain the + * number of data bytes to be written/read after the opcode, address and + * alternate bytes. + * + * This request is only supported if bit 1 of the "feature bitmap" + * indicates that serial flash extensions are supported. Implementations + * will further advertise whether they support dual, quad or octo modes, if + * none of these are supported, then support for "dummy cycles" is not + * guaranteed either, and callers should use one or two bytes of "extra + * address data" for dummy cycles, address length can be up to 7 bytes for + * this reason. + * + * +----------------+------------+------------+---------------+ + * | packet id : 2B | count : 2B | flags : 4B | w.p. : <= 56B | + * +----------------+------------+------------+---------------+ + * + * packet id: 2 byte enum defined by packet_id_type + * Valid values packet id = + * USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START + * + * count: 2 byte, zero based count of bytes to read or write + * + * flags: 4 byte, flags + * bits 0:1 opcode length in bytes (0-3) + * bits 2:4 address length in bytes (0-7) + * bits 5:6 mode (0: 1-1-1, 1: 1-1-N, 2: 1-N-N, 3: N-N-N) + * bits 7:8 width (0: N=1, 1: N=2, 2: N=4, 3: N=8) + * bit 9 double transfer rate (in phases marked as N) + * bits 10:14 number of dummy cycles (0-31) + * bits 15:27 reserved, must be zero + * bit 28 write to be preceded by "write enable" + * bit 29 write to be followed by polling of JEDEC "busy bit" + * bit 30 reserved, must be zero + * bit 31 read (0) / write (1) + * + * write payload: Up to 56 bytes of data to write to SPI, the total length + * of all TX packets must match: write enable length (zero or + * one, depending on bit 27) + opcode length + address length + * + count, (the last one only if bit 31 indicates a write + * operation). Due to data alignment constraints, this must + * be an even number of bytes unless this is the final + * packet. + * + * * USB Error Codes: * * send_command return codes have the following format: @@ -278,6 +342,8 @@ #define USB_SPI_PAYLOAD_SIZE_V2_ERROR (60) +#define USB_SPI_PAYLOAD_SIZE_FLASH_START (56) + #define USB_SPI_MIN_PACKET_SIZE (2) /* @@ -294,6 +360,8 @@ #define USB_SPI_FLASH_QUAD_SUPPORT BIT(3) /* This SPI device supports eight lane mode. */ #define USB_SPI_FLASH_OCTO_SUPPORT BIT(4) +/* This SPI device supports double transfer rate (data on both clock edges). */ +#define USB_SPI_FLASH_DTR_SUPPORT BIT(5) enum packet_id_type { /* Request USB SPI configuration data from device. */ @@ -325,11 +393,34 @@ enum packet_id_type { USB_SPI_PKT_ID_CMD_CHIP_SELECT = 7, /* Response to above request. */ USB_SPI_PKT_ID_RSP_CHIP_SELECT = 8, + /* + * Start a USB serial flash SPI transfer. + */ + USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START = 9, }; enum feature_bitmap { /* Indicates the platform supports full duplex mode. */ - USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = BIT(0) + USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = BIT(0), + /* Indicates support for USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START. */ + USB_SPI_FEATURE_FLASH_EXTENSIONS = BIT(1), + /* + * Indicates that chip and any MUXes support bidirectional data on the + * two SPI data lines. + */ + USB_SPI_FEATURE_DUAL_MODE_SUPPORTED = BIT(2), + /* + * Indicates that chip and any MUXes support bidirectional data on the + * "hold" and "write protect" lines. + */ + USB_SPI_FEATURE_QUAD_MODE_SUPPORTED = BIT(3), + /* Indicates support for eight-line bidirectional data. */ + USB_SPI_FEATURE_OCTO_MODE_SUPPORTED = BIT(4), + /* + * Indicates support for double transfer rate, i.e. data bit shift on + * both rising and falling clock edges. + */ + USB_SPI_FEATURE_DTR_SUPPORTED = BIT(5), }; struct usb_spi_response_configuration_v2 { @@ -374,11 +465,36 @@ struct usb_spi_chip_select_response { uint16_t status_code; } __packed; +struct usb_spi_flash_command { + uint16_t packet_id; + uint16_t count; + uint32_t flags; + uint8_t data[USB_SPI_PAYLOAD_SIZE_FLASH_START]; +} __packed; + +/* + * Mask of the flags that are handled by logic in sub_spi.c, and not passed to + * SPI drivers through usb_spi_board_transaction(). + */ +#define FLASH_FLAGS_NONBOARD 0xF0000000UL + +#define FLASH_FLAG_WRITE_ENABLE_POS 28U +#define FLASH_FLAG_WRITE_ENABLE (0x1UL << FLASH_FLAG_WRITE_ENABLE_POS) + +#define FLASH_FLAG_POLL_POS 29U +#define FLASH_FLAG_POLL (0x1UL << FLASH_FLAG_POLL_POS) + +#define FLASH_FLAG_READ_WRITE_POS 31U +#define FLASH_FLAG_READ_WRITE_MSK (0x1UL << FLASH_FLAG_READ_WRITE_POS) +#define FLASH_FLAG_READ_WRITE_READ 0 +#define FLASH_FLAG_READ_WRITE_WRITE (0x1UL << FLASH_FLAG_READ_WRITE_POS) + struct usb_spi_packet_ctx { union { uint8_t bytes[USB_MAX_PACKET_SIZE]; uint16_t packet_id; struct usb_spi_command_v2 cmd_start; + struct usb_spi_flash_command cmd_flash_start; struct usb_spi_continue_v2 cmd_continue; struct usb_spi_response_configuration_v2 rsp_config; struct usb_spi_response_v2 rsp_start; @@ -412,6 +528,8 @@ enum usb_spi_error { USB_SPI_RX_UNEXPECTED_PACKET = 0x0008, /* The device does not support full duplex mode. */ USB_SPI_UNSUPPORTED_FULL_DUPLEX = 0x0009, + /* The device does not support dual/quad wire mode. */ + USB_SPI_UNSUPPORTED_FLASH_MODE = 0x000A, USB_SPI_UNKNOWN_ERROR = 0x8000, }; @@ -508,6 +626,12 @@ struct usb_spi_state { struct usb_spi_packet_ctx transmit_packet; /* + * Flags describing if and how multi-lane (dual/quad), double transfer + * rate, and other advanced flash protocol features are to be used. + */ + uint32_t flash_flags; + + /* * Context structures representing the progress receiving the SPI * write data and transmitting the SPI read data. */ @@ -666,70 +790,38 @@ int usb_spi_board_transaction(const struct spi_device_t *spi_device, * communication, when supported. */ -/* Data width during the opcode stage. */ -#define FLASH_FLAG_OPCODE_WIDTH_POS 0 -#define FLASH_FLAG_OPCODE_WIDTH_MSK (0x3U << FLASH_FLAG_OPCODE_WIDTH_POS) -#define FLASH_FLAG_OPCODE_WIDTH_1WIRE (0x0U << FLASH_FLAG_OPCODE_WIDTH_POS) -#define FLASH_FLAG_OPCODE_WIDTH_2WIRE (0x1U << FLASH_FLAG_OPCODE_WIDTH_POS) -#define FLASH_FLAG_OPCODE_WIDTH_4WIRE (0x2U << FLASH_FLAG_OPCODE_WIDTH_POS) -#define FLASH_FLAG_OPCODE_WIDTH_8WIRE (0x3U << FLASH_FLAG_OPCODE_WIDTH_POS) - -/* Transmit opcode bits at both rising and falling clock edges. */ -#define FLASH_FLAG_OPCODE_DTR_POS 2 -#define FLASH_FLAG_OPCODE_DTR (0x1U << FLASH_FLAG_OPCODE_DTR_POS) - -/* Number of bytes of opcode (0-4). */ -#define FLASH_FLAG_OPCODE_LEN_POS 3 -#define FLASH_FLAG_OPCODE_LEN_MSK (0x7U << FLASH_FLAG_OPCODE_LEN_POS) - -/* Data width during the address stage. */ -#define FLASH_FLAG_ADDR_WIDTH_POS 6 -#define FLASH_FLAG_ADDR_WIDTH_MSK (0x3U << FLASH_FLAG_ADDR_WIDTH_POS) -#define FLASH_FLAG_ADDR_WIDTH_1WIRE (0x0U << FLASH_FLAG_ADDR_WIDTH_POS) -#define FLASH_FLAG_ADDR_WIDTH_2WIRE (0x1U << FLASH_FLAG_ADDR_WIDTH_POS) -#define FLASH_FLAG_ADDR_WIDTH_4WIRE (0x2U << FLASH_FLAG_ADDR_WIDTH_POS) -#define FLASH_FLAG_ADDR_WIDTH_8WIRE (0x3U << FLASH_FLAG_ADDR_WIDTH_POS) - -/* Transmit address bits at both rising and falling clock edges. */ -#define FLASH_FLAG_ADDR_DTR_POS 8 -#define FLASH_FLAG_ADDR_DTR (0x1U << FLASH_FLAG_ADDR_DTR_POS) - -/* Number of bytes of address (0-4). */ -#define FLASH_FLAG_ADDR_LEN_POS 9 -#define FLASH_FLAG_ADDR_LEN_MSK (0x7U << FLASH_FLAG_ADDR_LEN_POS) - -/* Data width during the "alternate bytes" stage. */ -#define FLASH_FLAG_ALT_WIDTH_POS 12 -#define FLASH_FLAG_ALT_WIDTH_MSK (0x3U << FLASH_FLAG_ALT_WIDTH_POS) -#define FLASH_FLAG_ALT_WIDTH_1WIRE (0x0U << FLASH_FLAG_ALT_WIDTH_POS) -#define FLASH_FLAG_ALT_WIDTH_2WIRE (0x1U << FLASH_FLAG_ALT_WIDTH_POS) -#define FLASH_FLAG_ALT_WIDTH_4WIRE (0x2U << FLASH_FLAG_ALT_WIDTH_POS) -#define FLASH_FLAG_ALT_WIDTH_8WIRE (0x3U << FLASH_FLAG_ALT_WIDTH_POS) +/* Number of bytes of opcode (0-3). */ +#define FLASH_FLAG_OPCODE_LEN_POS 0 +#define FLASH_FLAG_OPCODE_LEN_MSK (0x3U << FLASH_FLAG_OPCODE_LEN_POS) -/* Transmit alternate bits at both rising and falling clock edges. */ -#define FLASH_FLAG_ALT_DTR_POS 14 -#define FLASH_FLAG_ALT_DTR (0x1U << FLASH_FLAG_ALT_DTR_POS) +/* Number of bytes of address plus additional data bytes (0-7). */ +#define FLASH_FLAG_ADDR_LEN_POS 2 +#define FLASH_FLAG_ADDR_LEN_MSK (0x7U << FLASH_FLAG_ADDR_LEN_POS) -/* Number of bytes of alternate data (0-4). */ -#define FLASH_FLAG_ALT_LEN_POS 15 -#define FLASH_FLAG_ALT_LEN_MSK (0x7U << FLASH_FLAG_ALT_LEN_POS) +/* At what stage to switch to multi-lane mode (if any). */ +#define FLASH_FLAG_MODE_POS 5 +#define FLASH_FLAG_MODE_MSK (0x3U << FLASH_FLAG_MODE_POS) +#define FLASH_FLAG_MODE_111 (0x0U << FLASH_FLAG_MODE_POS) +#define FLASH_FLAG_MODE_11N (0x1U << FLASH_FLAG_MODE_POS) +#define FLASH_FLAG_MODE_1NN (0x2U << FLASH_FLAG_MODE_POS) +#define FLASH_FLAG_MODE_NNN (0x3U << FLASH_FLAG_MODE_POS) + +/* Data width during the later stages (value of N, above). */ +#define FLASH_FLAG_WIDTH_POS 7 +#define FLASH_FLAG_WIDTH_MSK (0x3U << FLASH_FLAG_WIDTH_POS) +#define FLASH_FLAG_WIDTH_1WIRE (0x0U << FLASH_FLAG_WIDTH_POS) +#define FLASH_FLAG_WIDTH_2WIRE (0x1U << FLASH_FLAG_WIDTH_POS) +#define FLASH_FLAG_WIDTH_4WIRE (0x2U << FLASH_FLAG_WIDTH_POS) +#define FLASH_FLAG_WIDTH_8WIRE (0x3U << FLASH_FLAG_WIDTH_POS) + +/* Transmit opcode bits at both clock edges in later stages. */ +#define FLASH_FLAG_DTR_POS 9 +#define FLASH_FLAG_DTR (0x1U << FLASH_FLAG_DTR_POS) /* Number of dummy clock cycles (0-31). */ -#define FLASH_FLAG_DUMMY_CYCLES_POS 18 +#define FLASH_FLAG_DUMMY_CYCLES_POS 10 #define FLASH_FLAG_DUMMY_CYCLES_MSK (0x1FU << FLASH_FLAG_DUMMY_CYCLES_POS) -/* Data width during the data stage. */ -#define FLASH_FLAG_DATA_WIDTH_POS 23 -#define FLASH_FLAG_DATA_WIDTH_MSK (0x3U << FLASH_FLAG_DATA_WIDTH_POS) -#define FLASH_FLAG_DATA_WIDTH_1WIRE (0x0U << FLASH_FLAG_DATA_WIDTH_POS) -#define FLASH_FLAG_DATA_WIDTH_2WIRE (0x1U << FLASH_FLAG_DATA_WIDTH_POS) -#define FLASH_FLAG_DATA_WIDTH_4WIRE (0x2U << FLASH_FLAG_DATA_WIDTH_POS) -#define FLASH_FLAG_DATA_WIDTH_8WIRE (0x3U << FLASH_FLAG_DATA_WIDTH_POS) - -/* Transmit data bits at both rising and falling clock edges. */ -#define FLASH_FLAG_DATA_DTR_POS 25 -#define FLASH_FLAG_DATA_DTR (0x1U << FLASH_FLAG_DATA_DTR_POS) - /* * Mask of the flags that cannot be ignored. This is basically any flags * which call for wires to switch direction, or data being clocked on both @@ -739,11 +831,7 @@ int usb_spi_board_transaction(const struct spi_device_t *spi_device, * the controller knowing which parts are to be interpreted as * opcode/address/data. */ -#define FLASH_FLAGS_REQUIRING_SUPPORT \ - (FLASH_FLAG_OPCODE_WIDTH_MSK | FLASH_FLAG_OPCODE_DTR | \ - FLASH_FLAG_ADDR_WIDTH_MSK | FLASH_FLAG_ADDR_DTR | \ - FLASH_FLAG_ALT_WIDTH_MSK | FLASH_FLAG_ALT_DTR | \ - FLASH_FLAG_DUMMY_CYCLES_MSK | FLASH_FLAG_DATA_WIDTH_MSK | \ - FLASH_FLAG_DATA_DTR) +#define FLASH_FLAGS_REQUIRING_SUPPORT \ + (FLASH_FLAG_MODE_MSK | FLASH_FLAG_DTR | FLASH_FLAG_DUMMY_CYCLES_MSK) #endif /* __CROS_EC_USB_SPI_H */ diff --git a/cmake/toolchain-armv7m.cmake b/cmake/toolchain-armv7m.cmake index 38d8f761d8..dacb265879 100644 --- a/cmake/toolchain-armv7m.cmake +++ b/cmake/toolchain-armv7m.cmake @@ -5,9 +5,13 @@ set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) -set(PREFIX armv7m-cros-eabi-) +set(CROSS_COMPILE armv7m-cros-eabi-) set(CMAKE_SYSROOT /usr/armv7m-cros-eabi/) +set(CC_NAME clang) +set(CXX_NAME clang++) + +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CROSS_COMPILE CC_NAME CXX_NAME) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/toolchain-common.cmake") add_link_options(-lclang_rt.builtins-armv7m) diff --git a/cmake/toolchain-common.cmake b/cmake/toolchain-common.cmake index 059c604235..765487267f 100644 --- a/cmake/toolchain-common.cmake +++ b/cmake/toolchain-common.cmake @@ -2,21 +2,49 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -set(CMAKE_C_COMPILER ${PREFIX}clang) -set(CMAKE_CXX_COMPILER ${PREFIX}clang++) -set(CMAKE_LINKER ${PREFIX}ld.lld) -set(CMAKE_AR ${PREFIX}ar) -set(CMAKE_NM ${PREFIX}nm) -set(CMAKE_OBJCOPY ${PREFIX}objcopy) -set(CMAKE_OBJDUMP ${PREFIX}objdump) -set(CMAKE_RANLIB ${PREFIX}ranlib) -set(CMAKE_READELF ${PREFIX}readelf) +# Input variables: +# CROSS_COMPILE: the prefix of the cross compiler. +# CC_NAME: the name of the C compiler. +# CXX_NAME: the name of the C++ compiler. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER "${CROSS_COMPILE}${CC_NAME}") +set(CMAKE_CXX_COMPILER "${CROSS_COMPILE}${CXX_NAME}") +set(CMAKE_OBJCOPY "${CROSS_COMPILE}objcopy") +set(CMAKE_OBJDUMP "${CROSS_COMPILE}objdump") +set(CMAKE_READELF "${CROSS_COMPILE}readelf") + +if ("${CC_NAME}" STREQUAL "gcc") +set(CMAKE_LINKER "${CROSS_COMPILE}ld") +else() +set(CMAKE_LINKER "${CROSS_COMPILE}ld.lld") +endif() + +# This is only for host unittests build. +if ("${CC_NAME}" STREQUAL gcc AND "${CMAKE_SYSROOT}" STREQUAL "") +set(CMAKE_AR "${CROSS_COMPILE}gcc-ar") +set(CMAKE_NM "${CROSS_COMPILE}gcc-nm") +set(CMAKE_RANLIB "${CROSS_COMPILE}gcc-ranlib") +else() +set(CMAKE_AR "${CROSS_COMPILE}ar") +set(CMAKE_NM "${CROSS_COMPILE}nm") +set(CMAKE_RANLIB "${CROSS_COMPILE}ranlib") +endif() + +if ("${CC_NAME}" STREQUAL gcc) +add_compile_options(-Os) +else() add_compile_options(-Oz) +endif() +# Enable Link Time Optimization. add_compile_options(-flto) add_link_options(-flto) +# See https://www.chromium.org/chromium-os/build/c-exception-support +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables") + set(CMAKE_POSITION_INDEPENDENT_CODE OFF) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) diff --git a/common/charger.c b/common/charger.c index 3c0dbb6226..a9cee0decf 100644 --- a/common/charger.c +++ b/common/charger.c @@ -163,30 +163,34 @@ void print_charger_debug(int chgnum) if (check_print_error(charger_device_id(&d))) ccprintf("0x%04x\n", d); + /* dptf current limit */ + print_item_name("I_dptf:"); + if (dptf_limit_ma >= 0) + ccprintf("%5d\n", dptf_limit_ma); + else + ccputs("disabled\n"); + + /* Limits */ + ccprintf("Limits\t\t\t ( min max step)\n"); + /* charge voltage limit */ - print_item_name("V_batt:"); + print_item_name("chg_voltage:"); if (check_print_error(charger_get_voltage(chgnum, &d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, info->voltage_min, + ccprintf("\t%5d mV (%4d - %5d, %3d)\n", d, info->voltage_min, info->voltage_max, info->voltage_step); /* charge current limit */ - print_item_name("I_batt:"); + print_item_name("chg_current:"); if (check_print_error(charger_get_current(chgnum, &d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, info->current_min, + ccprintf("\t%5d mA (%4d - %5d, %3d)\n", d, info->current_min, info->current_max, info->current_step); /* input current limit */ - print_item_name("I_in:"); + print_item_name("input_current:"); if (check_print_error(charger_get_input_current_limit(chgnum, &d))) - ccprintf("%5d (%4d - %5d, %3d)\n", d, info->input_current_min, - info->input_current_max, info->input_current_step); - - /* dptf current limit */ - print_item_name("I_dptf:"); - if (dptf_limit_ma >= 0) - ccprintf("%5d\n", dptf_limit_ma); - else - ccputs("disabled\n"); + ccprintf("\t%5d mA (%4d - %5d, %3d)\n", d, + info->input_current_min, info->input_current_max, + info->input_current_step); } void print_charger_prochot(int chgnum) diff --git a/common/flash.c b/common/flash.c index 8b1ca25089..05eceaedd0 100644 --- a/common/flash.c +++ b/common/flash.c @@ -6,6 +6,9 @@ /* Flash memory module for Chrome EC - common functions */ #include "builtin/assert.h" +#ifdef CONFIG_ZEPHYR +#include "cbi_flash.h" +#endif /* CONFIG_ZEPHYR */ #include "common.h" #include "console.h" #include "cros_board_info.h" @@ -666,7 +669,45 @@ int crec_flash_is_erased(uint32_t offset, int size) return 1; } -test_mockable int crec_flash_read(int offset, int size, char *data) +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH) +/** + * Check if the passed section overlaps with CBI section on EC flash. + * + * @param offset Flash offset. + * @param size Length of section in bytes. + * @return true if there is overlap, or false if there is no overlap. + */ +static bool check_cbi_section_overlap(int offset, int size) +{ + int cbi_start = CBI_FLASH_OFFSET; + int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE; + int sec_start = offset; + int sec_end = offset + size; + + return !((sec_end <= cbi_start) || (sec_start >= cbi_end)); +} + +/** + * Hide the information related to CBI(EC flash) if data contains any. + * + * @param offset Flash offset. + * @param size Length of section in bytes. + * @param data Flash data. Must be 32-bit aligned. + */ +static void protect_cbi_overlapped_section(int offset, int size, char *data) +{ + if (check_cbi_section_overlap(offset, size)) { + int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE; + int sec_end = offset + size; + int cbi_fill_start = MAX(CBI_FLASH_OFFSET, offset); + int cbi_fill_size = MIN(cbi_end, sec_end) - cbi_fill_start; + + memset(data + (cbi_fill_start - offset), 0xff, cbi_fill_size); + } +} +#endif + +test_mockable int crec_flash_unprotected_read(int offset, int size, char *data) { #ifdef CONFIG_MAPPED_STORAGE const char *src; @@ -683,6 +724,15 @@ test_mockable int crec_flash_read(int offset, int size, char *data) #endif } +int crec_flash_read(int offset, int size, char *data) +{ + RETURN_ERROR(crec_flash_unprotected_read(offset, size, data)); +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH) + protect_cbi_overlapped_section(offset, size, data); +#endif + return EC_SUCCESS; +} + static void flash_abort_or_invalidate_hash(int offset, int size) { #ifdef CONFIG_VBOOT_HASH @@ -728,6 +778,23 @@ int crec_flash_write(int offset, int size, const char *data) flash_abort_or_invalidate_hash(offset, size); +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH) + if (check_cbi_section_overlap(offset, size)) { + int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE; + int sec_end = offset + size; + + if (offset < CBI_FLASH_OFFSET) { + RETURN_ERROR(crec_flash_physical_write( + offset, CBI_FLASH_OFFSET - offset, data)); + } + if (sec_end > cbi_end) { + RETURN_ERROR(crec_flash_physical_write( + cbi_end, sec_end - cbi_end, + data + cbi_end - offset)); + } + return EC_SUCCESS; + } +#endif return crec_flash_physical_write(offset, size, data); } @@ -740,6 +807,22 @@ int crec_flash_erase(int offset, int size) flash_abort_or_invalidate_hash(offset, size); +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_PLATFORM_EC_CBI_FLASH) + if (check_cbi_section_overlap(offset, size)) { + int cbi_end = CBI_FLASH_OFFSET + CBI_IMAGE_SIZE; + int sec_end = offset + size; + + if (offset < CBI_FLASH_OFFSET) { + RETURN_ERROR(crec_flash_physical_erase( + offset, CBI_FLASH_OFFSET - offset)); + } + if (sec_end > cbi_end) { + RETURN_ERROR(crec_flash_physical_erase( + cbi_end, sec_end - cbi_end)); + } + return EC_SUCCESS; + } +#endif return crec_flash_physical_erase(offset, size); } diff --git a/common/fpsensor/fpsensor.cc b/common/fpsensor/fpsensor.cc index 19b917dea0..cb013363f1 100644 --- a/common/fpsensor/fpsensor.cc +++ b/common/fpsensor/fpsensor.cc @@ -412,7 +412,7 @@ static enum ec_status fp_command_frame(struct host_cmd_handler_args *args) const auto *params = static_cast<const struct ec_params_fp_frame *>(args->params); void *out = args->response; - uint32_t idx = FP_FRAME_GET_BUFFER_INDEX(params->offset); + uint16_t idx = FP_FRAME_GET_BUFFER_INDEX(params->offset); uint32_t offset = params->offset & FP_FRAME_OFFSET_MASK; uint32_t size = params->size; uint16_t fgr; @@ -579,7 +579,7 @@ static enum ec_status fp_command_template(struct host_cmd_handler_args *args) uint32_t size = params->size & ~FP_TEMPLATE_COMMIT; bool xfer_complete = params->size & FP_TEMPLATE_COMMIT; uint32_t offset = params->offset; - uint32_t idx = templ_valid; + uint16_t idx = templ_valid; uint8_t key[SBP_ENC_KEY_LEN]; struct ec_fp_template_encryption_metadata *enc_info; int ret; diff --git a/common/fpsensor/fpsensor_state.cc b/common/fpsensor/fpsensor_state.cc index e516563dc9..7a2c9b6347 100644 --- a/common/fpsensor/fpsensor_state.cc +++ b/common/fpsensor/fpsensor_state.cc @@ -69,7 +69,7 @@ void fp_task_simulate(void) task_wait_event(timeout_us); } -void fp_clear_finger_context(int idx) +void fp_clear_finger_context(uint16_t idx) { always_memset(fp_template[idx], 0, sizeof(fp_template[0])); always_memset(fp_positive_match_salt[idx], 0, @@ -83,15 +83,13 @@ void fp_clear_finger_context(int idx) */ static void _fp_clear_context(void) { - int idx; - templ_valid = 0; templ_dirty = 0; always_memset(fp_buffer, 0, sizeof(fp_buffer)); always_memset(fp_enc_buffer, 0, sizeof(fp_enc_buffer)); always_memset(user_id, 0, sizeof(user_id)); fp_disable_positive_match_secret(&positive_match_secret_state); - for (idx = 0; idx < FP_MAX_FINGER_COUNT; idx++) + for (uint16_t idx = 0; idx < FP_MAX_FINGER_COUNT; idx++) fp_clear_finger_context(idx); } diff --git a/common/host_command.c b/common/host_command.c index 3693941476..37715b793f 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -13,6 +13,7 @@ #include "host_command.h" #include "link_defs.h" #include "lpc.h" +#include "power.h" #include "printf.h" #include "shared_mem.h" #include "system.h" @@ -916,3 +917,24 @@ DECLARE_CONSOLE_COMMAND(hcdebug, command_hcdebug, "hcdebug [off | normal | every | params]", "Set host command debug output mode"); #endif /* CONFIG_CMD_HCDEBUG */ + +#if defined(CONFIG_AP_PWRSEQ_S0IX_COUNTER) || \ + defined(CONFIG_POWERSEQ_S0IX_COUNTER) +static enum ec_status +host_command_get_s0ix_cnt(struct host_cmd_handler_args *args) +{ + const struct ec_params_s0ix_cnt *p = args->params; + struct ec_response_s0ix_cnt *r = args->response; + + if (p->flags & EC_S0IX_COUNTER_RESET) { + atomic_clear(&s0ix_counter); + } + + r->s0ix_counter = atomic_get(&s0ix_counter); + + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_GET_S0IX_COUNTER, host_command_get_s0ix_cnt, + EC_VER_MASK(0)); +#endif diff --git a/common/i2c_controller.c b/common/i2c_controller.c index 3332f771f6..f84b329d8d 100644 --- a/common/i2c_controller.c +++ b/common/i2c_controller.c @@ -52,10 +52,8 @@ BUILD_ASSERT(ARRAY_SIZE(port_mutex) < 32); static uint8_t port_protected[I2C_PORT_COUNT + I2C_BITBANG_PORT_COUNT]; #ifdef CONFIG_ZEPHYR -static int init_port_mutex(const struct device *dev) +static int init_port_mutex(void) { - ARG_UNUSED(dev); - for (int i = 0; i < ARRAY_SIZE(port_mutex); ++i) k_mutex_init(port_mutex + i); diff --git a/common/mkbp_event.c b/common/mkbp_event.c index 3b26ad48bf..f36f455ee6 100644 --- a/common/mkbp_event.c +++ b/common/mkbp_event.c @@ -80,10 +80,8 @@ static uint32_t mkbp_host_event_wake_mask = CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK; #endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */ #ifdef CONFIG_ZEPHYR -static int init_mkbp_mutex(const struct device *dev) +static int init_mkbp_mutex(void) { - ARG_UNUSED(dev); - k_mutex_init(&state.lock); return 0; diff --git a/common/motion_sense.c b/common/motion_sense.c index d2a51fc2a4..546034c7e2 100644 --- a/common/motion_sense.c +++ b/common/motion_sense.c @@ -76,10 +76,8 @@ static atomic_t odr_event_required; __maybe_unused static int fifo_int_enabled; #ifdef CONFIG_ZEPHYR -static int init_sensor_mutex(const struct device *dev) +static int init_sensor_mutex(void) { - ARG_UNUSED(dev); - k_mutex_init(&g_sensor_mutex); return 0; diff --git a/common/ocpc.c b/common/ocpc.c index a176eea075..6ed15b1b1b 100644 --- a/common/ocpc.c +++ b/common/ocpc.c @@ -701,7 +701,7 @@ void ocpc_reset(struct ocpc_data *ocpc) ocpc_precharge_enable(false); } -static void ocpc_set_pid_constants(void) +test_export_static void ocpc_set_pid_constants(void) { ocpc_get_pid_constants(&k_p, &k_p_div, &k_i, &k_i_div, &k_d, &k_d_div); } @@ -800,3 +800,14 @@ static int command_ocpcdrvlmt(int argc, const char **argv) } DECLARE_SAFE_CONSOLE_COMMAND(ocpcdrvlmt, command_ocpcdrvlmt, "[<drive_limit>]", "Show/Set drive limit for OCPC PID loop"); + +#ifdef TEST_BUILD +int test_ocpc_get_viz_output(void) +{ + return viz_output; +} +int test_ocpc_get_debug_output(void) +{ + return debug_output; +} +#endif diff --git a/common/rollback.c b/common/rollback.c index 23ac9df1d4..e2860f86f7 100644 --- a/common/rollback.c +++ b/common/rollback.c @@ -373,16 +373,28 @@ DECLARE_CONSOLE_COMMAND(rollbackupdate, command_rollback_update, "min_version", #ifdef CONFIG_ROLLBACK_SECRET_SIZE static int command_rollback_add_entropy(int argc, const char **argv) { + uint8_t rand[CONFIG_ROLLBACK_SECRET_SIZE]; + const uint8_t *data; int len; - if (argc < 2) - return EC_ERROR_PARAM_COUNT; + if (argc < 2) { + if (!IS_ENABLED(CONFIG_RNG)) + return EC_ERROR_PARAM_COUNT; - len = strlen(argv[1]); + trng_init(); + trng_rand_bytes(rand, sizeof(rand)); + trng_exit(); + + data = rand; + len = sizeof(rand); + } else { + data = argv[1]; + len = strlen(argv[1]); + } - return rollback_add_entropy(argv[1], len); + return rollback_add_entropy(data, len); } -DECLARE_CONSOLE_COMMAND(rollbackaddent, command_rollback_add_entropy, "data", +DECLARE_CONSOLE_COMMAND(rollbackaddent, command_rollback_add_entropy, "[data]", "Add entropy to rollback block"); #ifdef CONFIG_RNG diff --git a/common/system.c b/common/system.c index f598fb36c9..adb8c665c3 100644 --- a/common/system.c +++ b/common/system.c @@ -903,9 +903,17 @@ void system_common_pre_init(void) uint32_t reason; uint32_t info; uint8_t exception; + struct panic_data *pdata; panic_get_reason(&reason, &info, &exception); - if (reason != PANIC_SW_WATCHDOG) + pdata = panic_get_data(); + /* The watchdog panic info may have already been initialized by + * the watchdog handler, so only set it here if the panic reason + * is not a watchdog or the panic info has already been read, + * i.e. an old watchdog panic. + */ + if (reason != PANIC_SW_WATCHDOG || !pdata || + pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD) panic_set_reason(PANIC_SW_WATCHDOG, 0, 0); } @@ -1835,15 +1843,6 @@ __overridable int board_write_mac_addr(const char *mac_addr) } #endif /* CONFIG_MAC_ADDR_LEN */ -__attribute__((weak)) void clock_enable_module(enum module_id module, - int enable) -{ - /* - * Default weak implementation - for chips that don't support this - * function. - */ -} - __test_only void system_common_reset_state(void) { jdata = 0; diff --git a/common/system_safe_mode.c b/common/system_safe_mode.c index 889c67f799..e49e206b4f 100644 --- a/common/system_safe_mode.c +++ b/common/system_safe_mode.c @@ -22,10 +22,17 @@ static bool in_safe_mode; static const int safe_mode_allowed_hostcmds[] = { - EC_CMD_SYSINFO, EC_CMD_GET_PROTOCOL_INFO, - EC_CMD_GET_VERSION, EC_CMD_CONSOLE_SNAPSHOT, - EC_CMD_CONSOLE_READ, EC_CMD_GET_NEXT_EVENT, - EC_CMD_GET_UPTIME_INFO, EC_CMD_GET_PANIC_INFO + EC_CMD_CONSOLE_READ, + EC_CMD_CONSOLE_SNAPSHOT, + EC_CMD_GET_NEXT_EVENT, + EC_CMD_GET_PANIC_INFO, + EC_CMD_GET_PROTOCOL_INFO, + EC_CMD_GET_UPTIME_INFO, + EC_CMD_GET_VERSION, + EC_CMD_MEMORY_DUMP_GET_ENTRY_INFO, + EC_CMD_MEMORY_DUMP_GET_METADATA, + EC_CMD_MEMORY_DUMP_READ_MEMORY, + EC_CMD_SYSINFO, }; bool is_task_safe_mode_critical(task_id_t task_id) diff --git a/common/usb_common.c b/common/usb_common.c index 32d9d82e74..429bc8be8b 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -35,6 +35,12 @@ #include "usbc_ppc.h" #include "util.h" +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 43 + #ifdef CONFIG_COMMON_RUNTIME #define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) diff --git a/common/usbc/ap_vdm_control.c b/common/usbc/ap_vdm_control.c index b2786a58dd..08b8f727d6 100644 --- a/common/usbc/ap_vdm_control.c +++ b/common/usbc/ap_vdm_control.c @@ -57,12 +57,10 @@ static struct { } ap_storage[CONFIG_USB_PD_PORT_MAX_COUNT]; #ifdef CONFIG_ZEPHYR -static int init_ap_vdm_mutexes(const struct device *dev) +static int init_ap_vdm_mutexes(void) { int port; - ARG_UNUSED(dev); - for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) { k_mutex_init(&ap_storage[port].queue_lock); } diff --git a/common/usbc/usb_pd_console.c b/common/usbc/usb_pd_console.c index 20ddbff7d8..ae6527b601 100644 --- a/common/usbc/usb_pd_console.c +++ b/common/usbc/usb_pd_console.c @@ -192,18 +192,49 @@ static ccprintf("TC State: %s, Flags: 0x%04x", tc_get_current_state(port), tc_get_flags(port)); - if (IS_ENABLED(CONFIG_USB_PE_SM)) - ccprintf(" PE State: %s, Flags: 0x%04x\n", + if (IS_ENABLED(CONFIG_USB_PE_SM)) { + ccprintf(" PE State: %s, Flags: 0x%04x", pe_get_current_state(port), pe_get_flags(port)); - else - ccprintf("\n"); + if (pe_is_explicit_contract(port)) { + if (pe_snk_in_epr_mode(port)) + ccprintf(" EPR"); + else + ccprintf(" SPR"); + } + } + ccprintf("\n"); cflush(); } else if (!strcasecmp(argv[2], "srccaps")) { pd_srccaps_dump(port); } else if (!strcasecmp(argv[2], "cc")) { ccprintf("Port C%d CC%d\n", port, pd_get_task_cc_state(port)); +#ifdef CONFIG_USB_PD_EPR + } else if (!strcasecmp(argv[2], "epr")) { + enum pd_dpm_request req; + + if (argc < 4) { + return EC_ERROR_PARAM_COUNT; + } + if (pd_get_power_role(port) != PD_ROLE_SINK) { + ccprintf("EPR is currently supported only for sink\n"); + /* Suppress (long) help message */ + return EC_SUCCESS; + } + if (!strcasecmp(argv[3], "enter")) { + req = DPM_REQUEST_EPR_MODE_ENTRY; + } else if (!strcasecmp(argv[3], "exit")) { + req = DPM_REQUEST_EPR_MODE_EXIT; + /* Prevent snk_ready from repeatedly entering EPR. */ + pe_snk_epr_explicit_exit(port); + } else { + return EC_ERROR_PARAM3; + } + pd_dpm_request(port, req); + ccprintf("EPR %s requested\n", argv[3]); + return EC_SUCCESS; +#endif } if (IS_ENABLED(CONFIG_CMD_PD_TIMER) && !strcasecmp(argv[2], "timer")) { @@ -232,6 +263,9 @@ DECLARE_CONSOLE_COMMAND(pd, command_pd, "\n\t<port> suspend|resume" "\n\t<port> dualrole [on|off|freeze|sink|source]" "\n\t<port> swap [power|data|vconn]" +#ifdef CONFIG_USB_PD_EPR + "\n\t<port> epr [enter|exit]" +#endif #endif /* CONFIG_USB_PD_DUAL_ROLE */ , "USB PD"); diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 9a9e102b6e..0324132ac2 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -142,12 +142,10 @@ static void print_current_state(const int port) } #ifdef CONFIG_ZEPHYR -static int init_dpm_mutexes(const struct device *dev) +static int init_dpm_mutexes(void) { int port; - ARG_UNUSED(dev); - for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) { k_mutex_init(&dpm[port].vdm_req_mutex); } diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 767fed302b..dba06dfbfb 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -1159,6 +1159,11 @@ bool pe_snk_in_epr_mode(int port) return PE_CHK_FLAG(port, PE_FLAGS_IN_EPR); } +void pe_snk_epr_explicit_exit(int port) +{ + PE_SET_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); +} + bool pe_snk_can_enter_epr_mode(int port) { /* @@ -3749,9 +3754,12 @@ static void pe_snk_ready_entry(int port) */ pe_update_wait_and_add_jitter_timer(port); - if (IS_ENABLED(CONFIG_USB_PD_EPR) && pe_snk_in_epr_mode(port)) { - pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE, - PD_T_SINK_EPR_KEEP_ALIVE); + if (IS_ENABLED(CONFIG_USB_PD_EPR)) { + if (pe_snk_in_epr_mode(port)) + pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE, + PD_T_SINK_EPR_KEEP_ALIVE); + else if (!PE_CHK_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT)) + pd_dpm_request(port, DPM_REQUEST_EPR_MODE_ENTRY); } } @@ -4138,6 +4146,7 @@ static void pe_send_soft_reset_entry(int port) print_current_state(port); PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); + PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); /* Reset Protocol Layer (softly) */ prl_reset_soft(port); @@ -7913,6 +7922,7 @@ static void pe_ddr_perform_data_reset_exit(int port) static void pe_enter_epr_mode(int port) { PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); + PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); PE_SET_FLAG(port, PE_FLAGS_IN_EPR); CPRINTS("C%d: Entered EPR", port); } diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h index 5eafb7befd..b71cfced86 100644 --- a/common/usbc/usb_pe_private.h +++ b/common/usbc/usb_pe_private.h @@ -92,6 +92,11 @@ enum { PE_FLAGS_ENTERING_EPR_FN, /* In EPR mode */ PE_FLAGS_IN_EPR_FN, + /* + * Indicate the port exited EPR mode explicitly. If this is set, the + * port wouldn't enter EPR mode automatically. + */ + PE_FLAGS_EPR_EXPLICIT_EXIT_FN, /* Discovery disabled due to UFP/PD 2.0 constraint. */ PE_FLAGS_DISCOVERY_DISABLED_FN, /* Last element */ diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 6690fff25b..a43a9ffa2a 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -731,6 +731,7 @@ static void tc_detached(int port) { TC_CLR_FLAG(port, TC_FLAGS_TS_DTS_PARTNER); hook_notify(HOOK_USB_PD_DISCONNECT); + tc_enable_pd(port, 0); tc_pd_connection(port, 0); tcpm_debug_accessory(port, 0); set_ccd_mode(port, 0); @@ -2255,7 +2256,6 @@ static void tc_unattached_snk_entry(const int port) #ifdef CONFIG_USB_PE_SM CLR_FLAGS_ON_DISCONNECT(port); - tc_enable_pd(port, 0); tc[port].ps_reset_state = PS_STATE0; #endif } @@ -2806,7 +2806,6 @@ static void tc_unattached_src_entry(const int port) #ifdef CONFIG_USB_PE_SM CLR_FLAGS_ON_DISCONNECT(port); - tc_enable_pd(port, 0); tc[port].ps_reset_state = PS_STATE0; #endif diff --git a/common/usbc_intr_task.c b/common/usbc_intr_task.c index d1d25c6b68..68190aff4b 100644 --- a/common/usbc_intr_task.c +++ b/common/usbc_intr_task.c @@ -5,6 +5,12 @@ /* High-priority interrupt tasks implementations */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 13 + #include "builtin/assert.h" #include "common.h" #include "compile_time_macros.h" diff --git a/docs/ap-ec-comm.md b/docs/ap-ec-comm.md index 4270fca5f8..6f1292bcaf 100644 --- a/docs/ap-ec-comm.md +++ b/docs/ap-ec-comm.md @@ -120,6 +120,27 @@ cat /sys/kernel/debug/tracing/trace 369.421383: cros_ec_request_done: version: 0, command: EC_CMD_USB_PD_DISCOVERY, ec result: EC_RES_SUCCESS, retval: 5 ``` +## API synchronization + +EC, coreboot, user space (`platform2)` and kernel needs to access the same +information contained in `ec_commands.h`. + +* Coreboot regularly update [ec_commands.h]. +* User space/depthcharge use `ec_commands.h` installed by + `chromeos-base/chromeos-ec-headers` package. +* Kernel `ec_commands.h` - named + `./include/linux/platform_data/cros_ec_commands.h` - is not a direct +copy. New commands and options are added on a need-to-know basis +alongside the kernel code that uses these commands. + +A copy of `ec_commands.h`, matching kernel standard is auto-generated at +`/build/kernel/include/linux/mfd/cros_ec_commands.h` when +`make build_cros_ec_commands` or `make buildall` is run. (It is far from +perfect, since the kernel include file has not been updated with `clang-format` as +`ec_commands.h` has been). Copy the necessary changes from that file to +`include/linux/platform_data/cros_ec_commands.h` and push the changes upstream +first following the [upstream instructions]. + ## Transport-specific details Although the command and response formats are the same across all transports, @@ -179,3 +200,5 @@ after receiving a host packet and before it has a response ready. [Industrial I/O]: https://www.kernel.org/doc/html/v4.14/driver-api/iio/index.html [host command task]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/common/host_command.c [Transport-specific details]: #Transport_specific-details +[ec_commands.h]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/coreboot/src/ec/google/chromeec/ec_commands.h +[upstream instructions]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/kernel_development.md#Upstream-development. diff --git a/docs/reducing_ec_image_size.md b/docs/reducing_ec_image_size.md index 85a15a3f3c..dc04605dda 100644 --- a/docs/reducing_ec_image_size.md +++ b/docs/reducing_ec_image_size.md @@ -244,7 +244,7 @@ prj.conf file to disable the console command. | | CONFIG_CMD_RAND | `rand` | Used only on STM32 | | | CONFIG_CMD_REGULATOR | `ir357x` | | | | CONFIG_CMD_RESET_FLAGS | `rflags` | | -| | CONFIG_CMD_RETIMER | `bb`<br>`kbxfer` | | +| | CONFIG_CMD_RETIMER | `retimer` | | | | CONFIG_CMD_RTC | `rtc` | | | | CONFIG_CMD_RTC_ALARM | `rtc_alarm` | | | | CONFIG_CMD_RW | `rw` | | diff --git a/docs/zephyr/ztest.md b/docs/zephyr/ztest.md index b5f40821fc..dc5f1bea3e 100644 --- a/docs/zephyr/ztest.md +++ b/docs/zephyr/ztest.md @@ -54,10 +54,18 @@ test cases, but the attributes are applied to all test cases in the file. See for more details. Some common attributes include: -- `extra_configs` which is a list of Kconfigs to add to the test. -- `extra_args` which is a string containing additional arguments to pass to - CMake - +- `extra_configs` - a list of Kconfigs to add to the test. +- `extra_conf_files` - specifies a YAML list of additional Kconfig files to + to apply to the build. Replaces the `CONF_FILE` field in extra_args. +- `extra_overlay_confs` - specifies a list of overlay Kconfig files. Replaces + the `OVERLAY_CONFIG` field in extra_args. +- `extra_dtc_overlay_files` - specifies a list of additional device tree files + to apply to the build. Replaces the `DTC_OVERLAY_FILE` field in extra_args. + +`extra_args` is a string field that allows injecting free-form CMake variables +into the build. It is rarely needed and the practice of specifying `CONF_FILE`, +`OVERLAY_CONFIG`, or `DTC_OVERLAY_FILE` here is deprecated. Please use the +above fields for these functions, as they are much more readable. ## Integration tests Integration tests build the full EC. They require devicetree and all Kconfigs to diff --git a/driver/accel_lis2dw12.c b/driver/accel_lis2dw12.c index f249f1896c..bdd3f2120d 100644 --- a/driver/accel_lis2dw12.c +++ b/driver/accel_lis2dw12.c @@ -360,7 +360,7 @@ static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd) * But lis2dw12 needs switch low power mode according to odr value. */ if (!IS_ENABLED(CONFIG_ACCEL_LIS2DWL)) { - if (reg_val > LIS2DW12_ODR_200HZ_VAL) + if (reg_val >= LIS2DW12_ODR_50HZ_VAL) ret = lis2dw12_set_power_mode(s, LIS2DW12_HIGH_PERF, 0); else ret = lis2dw12_set_power_mode( @@ -392,7 +392,7 @@ static int get_rms_noise(const struct motion_sensor_t *s) rate = INT_TO_FP(st_get_data_rate(s) / 1000); /* - * LIS2DW12: 90ug/sqrt(Hz) when ODR is over 200Hz + * LIS2DW12: 90ug/sqrt(Hz) when ODR is over 50Hz * When lower, we are in power mode 2, so the noise density does not * depend on frequency and the RMS at +/-2g is 2.4mg. * @@ -401,7 +401,7 @@ static int get_rms_noise(const struct motion_sensor_t *s) */ if (!IS_ENABLED(CONFIG_ACCEL_LIS2DWL)) { - if (rate < INT_TO_FP(200)) + if (rate < INT_TO_FP(50)) return 2400; noise_density_ug = INT_TO_FP(90); } else { diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index 57b1a0330f..ec7132fb35 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -44,7 +44,7 @@ #define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args) #define UNKNOWN_DEV_ID -1 -static int dev_id = UNKNOWN_DEV_ID; +test_export_static int dev_id = UNKNOWN_DEV_ID; static const struct charger_info sm5803_charger_info = { .name = CHARGER_NAME, @@ -435,7 +435,7 @@ enum ec_error_list sm5803_vbus_sink_enable(int chgnum, int enable) * Track and store whether we've initialized the charger chips already on this * boot. This should prevent us from re-running inits after sysjumps. */ -static bool chip_inited[CHARGER_NUM]; +test_export_static bool chip_inited[CHARGER_NUM]; #define SM5803_SYSJUMP_TAG 0x534D /* SM */ #define SM5803_HOOK_VERSION 1 @@ -734,15 +734,13 @@ static void sm5803_init(int chgnum) SM5803_TINT_MIN_LEVEL); /* - * Configure VBAT_SNSP high interrupt to fire after thresholds are set. + * Configure VBAT_SNSP high and TINT interrupts to fire after + * thresholds are set. */ rv |= main_read8(chgnum, SM5803_REG_INT2_EN, ®); - reg |= SM5803_INT2_VBATSNSP; + reg |= SM5803_INT2_VBATSNSP | SM5803_INT2_TINT; rv |= main_write8(chgnum, SM5803_REG_INT2_EN, reg); - /* Configure TINT interrupts to fire after thresholds are set */ - rv |= main_write8(chgnum, SM5803_REG_INT2_EN, SM5803_INT2_TINT); - /* * Configure CHG_ENABLE to only be set through I2C by setting * HOST_MODE_EN bit (all other register bits are 0 by default) diff --git a/driver/ppc/ktu1125.c b/driver/ppc/ktu1125.c index f90168adef..698c4f6cb1 100644 --- a/driver/ppc/ktu1125.c +++ b/driver/ppc/ktu1125.c @@ -96,11 +96,10 @@ static int ktu1125_dump(int port) /* helper */ static int ktu1125_power_path_control(int port, int enable) { - int status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, - KTU1125_SW_AB_EN) : - clr_flags(port, KTU1125_CTRL_SW_CFG, - KTU1125_SW_AB_EN | KTU1125_CC1S_VCONN | - KTU1125_CC2S_VCONN); + int status = + enable ? + set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_SW_AB_EN) : + clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_SW_AB_EN); if (status) { CPRINTS("ppc p%d: Failed to %s power path", port, @@ -260,7 +259,7 @@ static int ktu1125_is_vbus_present(int port) return 0; } - return regval & KTU1125_SYSA_OK; + return !!(regval & KTU1125_SYSA_OK); } #endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ @@ -275,7 +274,7 @@ static int ktu1125_is_sourcing_vbus(int port) return 0; } - return regval & KTU1125_VBUS_OK; + return !!(regval & KTU1125_VBUS_OK); } #ifdef CONFIG_USBC_PPC_POLARITY @@ -345,11 +344,19 @@ static int ktu1125_discharge_vbus(int port, int enable) #ifdef CONFIG_USBC_PPC_VCONN static int ktu1125_set_vconn(int port, int enable) { - int status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, - KTU1125_VCONN_EN) : - clr_flags(port, KTU1125_CTRL_SW_CFG, - KTU1125_VCONN_EN | KTU1125_CC1S_VCONN | - KTU1125_CC2S_VCONN); + int polarity; + int status; + int flags = KTU1125_VCONN_EN; + + polarity = polarity_rm_dts(pd_get_polarity(port)); + + if (enable) { + flags |= polarity ? KTU1125_CC2S_VCONN : KTU1125_CC1S_VCONN; + status = set_flags(port, KTU1125_SET_SW_CFG, flags); + } else { + flags |= KTU1125_CC1S_VCONN | KTU1125_CC2S_VCONN; + status = clr_flags(port, KTU1125_SET_SW_CFG, flags); + } return status; } @@ -378,6 +385,12 @@ static int ktu1125_set_frs_enable(int port, int enable) static int ktu1125_vbus_sink_enable(int port, int enable) { +#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC + /* Skip if VBUS SNK is already enabled/disabled */ + if (ktu1125_is_vbus_present(port) == enable) + return EC_SUCCESS; +#endif + /* Select active sink */ int rv = clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); @@ -391,6 +404,10 @@ static int ktu1125_vbus_sink_enable(int port, int enable) static int ktu1125_vbus_source_enable(int port, int enable) { + /* Skip if VBUS SRC is already enabled/disabled */ + if (ktu1125_is_sourcing_vbus(port) == enable) + return EC_SUCCESS; + /* Select active source */ int rv = set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); diff --git a/driver/retimer/anx7483.c b/driver/retimer/anx7483.c index 3cb840dfa5..4b07848b9e 100644 --- a/driver/retimer/anx7483.c +++ b/driver/retimer/anx7483.c @@ -25,13 +25,7 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ##args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ##args) -/* Tuning defaults */ -struct anx7483_tuning_set { - uint8_t addr; - uint8_t value; -}; - -const static struct anx7483_tuning_set anx7483_usb_enabled[] = { +const test_export_static struct anx7483_tuning_set anx7483_usb_enabled[] = { { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, { ANX7483_DRX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, @@ -68,7 +62,7 @@ const static struct anx7483_tuning_set anx7483_usb_enabled[] = { { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, }; -static struct anx7483_tuning_set anx7483_dp_enabled[] = { +const test_export_static struct anx7483_tuning_set anx7483_dp_enabled[] = { { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, @@ -105,7 +99,7 @@ static struct anx7483_tuning_set anx7483_dp_enabled[] = { { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, }; -static struct anx7483_tuning_set anx7483_dock_noflip[] = { +const test_export_static struct anx7483_tuning_set anx7483_dock_noflip[] = { { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, @@ -143,7 +137,7 @@ static struct anx7483_tuning_set anx7483_dock_noflip[] = { { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, }; -static struct anx7483_tuning_set anx7483_dock_flip[] = { +const test_export_static struct anx7483_tuning_set anx7483_dock_flip[] = { { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, @@ -181,6 +175,11 @@ static struct anx7483_tuning_set anx7483_dock_flip[] = { { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, }; +const size_t anx7483_usb_enabled_count = ARRAY_SIZE(anx7483_usb_enabled); +const size_t anx7483_dp_enabled_count = ARRAY_SIZE(anx7483_dp_enabled); +const size_t anx7483_dock_noflip_count = ARRAY_SIZE(anx7483_dock_noflip); +const size_t anx7483_dock_flip_count = ARRAY_SIZE(anx7483_dock_flip); + test_export_static int anx7483_read(const struct usb_mux *me, uint8_t reg, int *val) { diff --git a/driver/retimer/anx7483.h b/driver/retimer/anx7483.h index 3120e3c707..a478f5abf6 100644 --- a/driver/retimer/anx7483.h +++ b/driver/retimer/anx7483.h @@ -8,6 +8,14 @@ #ifndef __CROS_EC_USB_RETIMER_ANX7483_H #define __CROS_EC_USB_RETIMER_ANX7483_H +#include "common.h" + +/* Tuning defaults */ +struct anx7483_tuning_set { + uint8_t addr; + uint8_t value; +}; + /* * LFPS_TIMER register * diff --git a/driver/retimer/bb_retimer.c b/driver/retimer/bb_retimer.c index 88eb4835fc..5571b666d4 100644 --- a/driver/retimer/bb_retimer.c +++ b/driver/retimer/bb_retimer.c @@ -37,6 +37,7 @@ #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ##args) #define BB_RETIMER_I2C_RETRY 5 +#define BB_RETIMER_REG_OFFSET_MAX UINT8_MAX /* * Mutex for BB_RETIMER_REG_CONNECTION_STATE register, which can be @@ -51,12 +52,16 @@ static mux_state_t bb_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT]; /** * Utility functions */ -static int bb_retimer_read(const struct usb_mux *me, const uint8_t offset, +static int bb_retimer_read(const struct usb_mux *me, const uint32_t offset, uint32_t *data) { int rv, retry = 0; uint8_t buf[BB_RETIMER_READ_SIZE]; + /* Validate the register address */ + if (offset > BB_RETIMER_REG_OFFSET_MAX) + return EC_ERROR_INVAL; + /* * This I2C message will trigger retimer's internal read sequence * if its a NAK, sleep and resend same I2C @@ -69,7 +74,8 @@ static int bb_retimer_read(const struct usb_mux *me, const uint8_t offset, * byte[1:4] : Data [LSB -> MSB] * Stop */ - rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags, &offset, 1, buf, + rv = i2c_xfer(me->i2c_port, me->i2c_addr_flags, + (const uint8_t *)&offset, 1, buf, BB_RETIMER_READ_SIZE); if (rv == EC_SUCCESS) @@ -91,12 +97,16 @@ static int bb_retimer_read(const struct usb_mux *me, const uint8_t offset, return EC_SUCCESS; } -static int bb_retimer_write(const struct usb_mux *me, const uint8_t offset, +static int bb_retimer_write(const struct usb_mux *me, const uint32_t offset, uint32_t data) { int rv, retry = 0; uint8_t buf[BB_RETIMER_WRITE_SIZE]; + /* Validate the register address */ + if (offset > BB_RETIMER_REG_OFFSET_MAX) + return EC_ERROR_INVAL; + /* * Write sequence * Addr flags(w) @@ -105,7 +115,7 @@ static int bb_retimer_write(const struct usb_mux *me, const uint8_t offset, * byte[2:5] : Data [LSB -> MSB] * stop */ - buf[0] = offset; + buf[0] = (uint8_t)offset; buf[1] = BB_RETIMER_REG_SIZE; buf[2] = data & 0xFF; buf[3] = (data >> 8) & 0xFF; @@ -670,75 +680,8 @@ const struct usb_mux_driver bb_usb_retimer = { .set_idle_mode = bb_set_idle_mode, .enter_low_power_mode = retimer_low_power_mode, .is_retimer_fw_update_capable = is_retimer_fw_update_capable, -}; - #ifdef CONFIG_CMD_RETIMER -static int console_command_bb_retimer(int argc, const char **argv) -{ - char rw, *e; - int port, reg, data, val = 0; - int rv = EC_SUCCESS; - const struct usb_mux *mux; - const struct usb_mux_chain *mux_chain; - - if (argc < 4) - return EC_ERROR_PARAM_COUNT; - - /* Get port number */ - port = strtoi(argv[1], &e, 0); - if (*e || !board_is_usb_pd_port_present(port)) - return EC_ERROR_PARAM1; - - mux_chain = &usb_muxes[port]; - while (mux_chain) { - mux = mux_chain->mux; - if (mux->driver == &bb_usb_retimer) - break; - mux_chain = mux_chain->next; - } - - if (!mux_chain) - return EC_ERROR_PARAM1; - - /* Validate r/w selection */ - rw = argv[2][0]; - if (rw != 'w' && rw != 'r') - return EC_ERROR_PARAM2; - - /* Get register address */ - reg = strtoi(argv[3], &e, 0); - if (*e || reg < 0) - return EC_ERROR_PARAM3; - - /* Get value to be written */ - if (rw == 'w') { - val = strtoi(argv[4], &e, 0); - if (*e || val < 0) - return EC_ERROR_PARAM4; - } - - for (; mux_chain != NULL; mux_chain = mux_chain->next) { - mux = mux_chain->mux; - if (mux->driver == &bb_usb_retimer) { - if (rw == 'r') - rv = bb_retimer_read(mux, reg, &data); - else { - rv = bb_retimer_write(mux, reg, val); - if (rv == EC_SUCCESS) { - rv = bb_retimer_read(mux, reg, &data); - if (rv == EC_SUCCESS && data != val) - rv = EC_ERROR_UNKNOWN; - } - } - if (rv == EC_SUCCESS) - CPRINTS("Addr 0x%x register %d = 0x%x", - mux->i2c_addr_flags, reg, data); - } - } - - return rv; -} -DECLARE_CONSOLE_COMMAND(bb, console_command_bb_retimer, - "<port> <r/w> <reg> | <val>", - "Read or write to BB retimer register"); + .retimer_read = bb_retimer_read, + .retimer_write = bb_retimer_write, #endif /* CONFIG_CMD_RETIMER */ +}; diff --git a/driver/retimer/kb800x.c b/driver/retimer/kb800x.c index 35ab5b183d..2ca4b062bb 100644 --- a/driver/retimer/kb800x.c +++ b/driver/retimer/kb800x.c @@ -14,30 +14,44 @@ /* Time between load switch enable and the reset being de-asserted */ #define KB800X_POWER_ON_DELAY_MS 20 +#define KB800X_REG_OFFSET_MAX UINT16_MAX +#define KB800X_REG_DATA_MAX UINT8_MAX static mux_state_t cached_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT]; -static int kb800x_write(const struct usb_mux *me, uint16_t address, - uint8_t data) +static int kb800x_write(const struct usb_mux *me, uint32_t address, + uint32_t data) { uint8_t kb800x_config[3] = { 0x00, 0x00, 0x00 }; + /* Validate the register address */ + if (address > KB800X_REG_OFFSET_MAX) + return EC_ERROR_INVAL; + + /* Validate the writeable data */ + if (data > KB800X_REG_DATA_MAX) + return EC_ERROR_INVAL; + kb800x_config[0] = (address >> 8) & 0xff; kb800x_config[1] = address & 0xff; - kb800x_config[2] = data; + kb800x_config[2] = (uint8_t)data; return i2c_xfer(me->i2c_port, me->i2c_addr_flags, kb800x_config, sizeof(kb800x_config), NULL, 0); } -static int kb800x_read(const struct usb_mux *me, uint16_t address, - uint8_t *data) +static int kb800x_read(const struct usb_mux *me, uint32_t address, + uint32_t *data) { uint8_t kb800x_config[2] = { 0x00, 0x00 }; + /* Validate the register address */ + if (address > KB800X_REG_OFFSET_MAX) + return EC_ERROR_INVAL; + kb800x_config[0] = (address >> 8) & 0xff; kb800x_config[1] = address & 0xff; return i2c_xfer(me->i2c_port, me->i2c_addr_flags, kb800x_config, - sizeof(kb800x_config), data, 1); + sizeof(kb800x_config), (uint8_t *)data, 1); } #ifdef CONFIG_KB800X_CUSTOM_XBAR @@ -83,7 +97,7 @@ static int kb800x_assign_tx_to_eb(const struct usb_mux *me, enum kb800x_eb eb) { uint8_t field_value = 0; - uint8_t regval; + uint32_t regval; int rv; field_value = KB800X_PHY_IS_AB(phy_lane) ? tx_eb_to_field_ab[eb] : @@ -106,7 +120,7 @@ static int kb800x_assign_rx_to_eb(const struct usb_mux *me, { uint16_t address = 0; uint8_t field_value = 0; - uint8_t regval = 0; + uint32_t regval = 0; int rv; field_value = rx_phy_lane_to_field[phy_lane]; @@ -472,76 +486,12 @@ static int kb800x_enter_low_power_mode(const struct usb_mux *me) return EC_SUCCESS; } -#ifdef CONFIG_CMD_RETIMER - -static int console_command_kb800x_xfer(int argc, const char **argv) -{ - char rw, *e; - int rv, port, reg, val; - uint8_t data; - const struct usb_mux_chain *mux_chain; - const struct usb_mux *mux; - - if (argc < 4) - return EC_ERROR_PARAM_COUNT; - - /* Get port number */ - port = strtoi(argv[1], &e, 0); - if (*e || !board_is_usb_pd_port_present(port)) - return EC_ERROR_PARAM1; - - mux_chain = &usb_muxes[port]; - while (mux_chain) { - if (mux_chain->mux->driver == &kb800x_usb_mux_driver) - break; - mux_chain = mux_chain->next; - } - - if (!mux_chain) - return EC_ERROR_PARAM1; - - mux = mux_chain->mux; - - /* Validate r/w selection */ - rw = argv[2][0]; - if (rw != 'w' && rw != 'r') - return EC_ERROR_PARAM2; - - /* Get register address */ - reg = strtoi(argv[3], &e, 0); - if (*e || reg < 0) - return EC_ERROR_PARAM3; - rv = EC_SUCCESS; - if (rw == 'r') - rv = kb800x_read(mux, reg, &data); - else { - if (argc < 5) - return EC_ERROR_PARAM_COUNT; - /* Get value to be written */ - val = strtoi(argv[4], &e, 0); - if (*e || val < 0) - return EC_ERROR_PARAM4; - rv = kb800x_write(mux, reg, val); - if (rv == EC_SUCCESS) { - rv = kb800x_read(mux, reg, &data); - if (rv == EC_SUCCESS && data != val) - rv = EC_ERROR_UNKNOWN; - } - } - - if (rv == EC_SUCCESS) - ccprintf("register 0x%x [%d] = 0x%x [%d]\n", reg, reg, data, - data); - - return rv; -} -DECLARE_CONSOLE_COMMAND(kbxfer, console_command_kb800x_xfer, - "<port> <r/w> <reg> | <val>", - "Read or write to KB retimer register"); -#endif /* CONFIG_CMD_RETIMER */ - const struct usb_mux_driver kb800x_usb_mux_driver = { .init = kb800x_init, .set = kb800x_set_state, .enter_low_power_mode = kb800x_enter_low_power_mode, +#ifdef CONFIG_CMD_RETIMER + .retimer_read = kb800x_read, + .retimer_write = kb800x_write, +#endif /* CONFIG_CMD_RETIMER */ }; diff --git a/driver/tcpm/anx7406.c b/driver/tcpm/anx7406.c index d270be0099..52f73a9c2f 100644 --- a/driver/tcpm/anx7406.c +++ b/driver/tcpm/anx7406.c @@ -6,6 +6,7 @@ /* ANX7406 port manager */ #include "anx7406.h" +#include "assert.h" #include "common.h" #include "console.h" #include "hooks.h" @@ -15,7 +16,7 @@ #include "usb_pd.h" #include "util.h" -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, "ANX7406: " format, ##args) const struct anx7406_i2c_addr anx7406_i2c_addrs_flags[] = { { ANX7406_TCPC0_I2C_ADDR_FLAGS, ANX7406_TOP0_I2C_ADDR_FLAGS }, @@ -30,6 +31,21 @@ const struct anx7406_i2c_addr anx7406_i2c_addrs_flags[] = { static struct anx7406_i2c_addr i2c_peripheral[CONFIG_USB_PD_PORT_MAX_COUNT]; +enum ec_error_list anx7406_set_gpio(int port, uint8_t gpio, bool value) +{ + if (gpio != 0) { + CPRINTS("C%d: Setting GPIO%d not supported", port, gpio); + return EC_ERROR_INVAL; + } + + CPRINTS("C%d: Setting GPIO%u %s", port, gpio, value ? "high" : "low"); + + return i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + ANX7406_REG_GPIO0, + value ? GPIO0_OUTPUT_HIGH : GPIO0_OUTPUT_LOW); +} + static int anx7406_set_hpd(int port, int hpd_lvl) { int val; @@ -114,7 +130,7 @@ static int anx7406_init(int port) { int rv, i; - CPRINTS("C%d: %s", port, __func__); + CPRINTS("C%d: init", port); /* * find corresponding anx7406 TOP address according to * specified TCPC address @@ -131,7 +147,7 @@ static int anx7406_init(int port) } } if (!I2C_STRIP_FLAGS(i2c_peripheral[port].top_addr_flags)) { - CPRINTS("C%d: 0x%x is invalid for anx7406", port, + CPRINTS("C%d: 0x%x is invalid", port, i2c_peripheral[port].top_addr_flags); return EC_ERROR_UNKNOWN; } @@ -191,7 +207,7 @@ static int anx7406_init(int port) rv = anx7406_hpd_reset(port); - CPRINTS("C%d: TCPC anx7406 initial success", port); + CPRINTS("C%d: init success", port); return rv; } diff --git a/driver/tcpm/anx7406.h b/driver/tcpm/anx7406.h index 83651b9573..b32a657da9 100644 --- a/driver/tcpm/anx7406.h +++ b/driver/tcpm/anx7406.h @@ -6,6 +6,7 @@ #ifndef __CROS_EC_USB_PD_TCPM_ANX7406_H #define __CROS_EC_USB_PD_TCPM_ANX7406_H +#include "stdbool.h" #include "usb_mux.h" struct anx7406_i2c_addr { @@ -68,6 +69,10 @@ struct anx7406_i2c_addr { #define ANX7406_REG_HPD_OEN BIT(6) #define HPD_DEGLITCH_TIME 0x0D +#define ANX7406_REG_GPIO0 0xCA +#define GPIO0_OUTPUT_HIGH (BIT(0) | BIT(1)) +#define GPIO0_OUTPUT_LOW BIT(0) + #define EXT_I2C_OP_DELAY 1000 /* Internal I2C0 master */ /* External I2C0 address & offset */ @@ -132,4 +137,14 @@ int anx7406_hpd_reset(const int port); void anx7406_update_hpd_status(const struct usb_mux *mux, mux_state_t mux_state); +/** + * Set/clear GPIO + * + * @param port USB-C port + * @param gpio GPIO number + * @param value true:high false:low + * @return enum ec_error_list + */ +enum ec_error_list anx7406_set_gpio(int port, uint8_t gpio, bool value); + #endif /* __CROS_EC_USB_PD_TCPM_ANX7406_H */ diff --git a/driver/usb_mux/usb_mux.c b/driver/usb_mux/usb_mux.c index 8029fd6fe6..334b7f2f2d 100644 --- a/driver/usb_mux/usb_mux.c +++ b/driver/usb_mux/usb_mux.c @@ -120,11 +120,10 @@ extern mutex_t queue_lock[]; #endif #ifdef CONFIG_ZEPHYR -static int init_mux_mutex(const struct device *dev) +static int init_mux_mutex(void) { int port; - ARG_UNUSED(dev); for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) { k_mutex_init(&mux_lock[port]); @@ -852,3 +851,69 @@ static enum ec_status hc_usb_pd_mux_ack(struct host_cmd_handler_args *args) return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_ACK, hc_usb_pd_mux_ack, EC_VER_MASK(0)); + +#ifdef CONFIG_CMD_RETIMER +static int console_command_retimer(int argc, const char **argv) +{ + char rw, *e; + uint32_t reg, data, val = 0; + int port, rv = EC_ERROR_UNIMPLEMENTED; + const struct usb_mux *mux; + const struct usb_mux_chain *mux_chain; + + if (argc < 4 || argc > 5) + return EC_ERROR_PARAM_COUNT; + + /* Get port number */ + port = strtoi(argv[1], &e, 0); + if (*e || !board_is_usb_pd_port_present(port)) + return EC_ERROR_PARAM1; + + mux_chain = &usb_muxes[port]; + if (!mux_chain) + return EC_ERROR_PARAM1; + + /* Validate r/w selection */ + rw = argv[2][0]; + if (rw != 'w' && rw != 'r') + return EC_ERROR_PARAM2; + + /* Get register address */ + reg = strtoull(argv[3], &e, 0); + if (*e) + return EC_ERROR_PARAM3; + + /* Get value to be written */ + if (rw == 'w') { + val = strtoull(argv[4], &e, 0); + if (*e) + return EC_ERROR_PARAM4; + } + + /* + * It is assumed that similar chips are connected in chain and the + * same set of data is written to all the chained chips. + */ + for (; mux_chain != NULL; mux_chain = mux_chain->next) { + mux = mux_chain->mux; + if (mux->driver && mux->driver->retimer_read && + mux->driver->retimer_write) { + if (rw == 'r') { + rv = mux->driver->retimer_read(mux, reg, &data); + if (rv == EC_SUCCESS) { + CPRINTS("Addr 0x%x register %d = 0x%x", + mux->i2c_addr_flags, reg, data); + } + } else { + rv = mux->driver->retimer_write(mux, reg, val); + } + } + } + + return rv; +} +DECLARE_CONSOLE_COMMAND(retimer, console_command_retimer, + "<port> r <reg>" + "\n<port> w <reg> <val>", + "Read or write to retimer register"); +#endif /* CONFIG_CMD_RETIMER */ diff --git a/firmware_builder.py b/firmware_builder.py index a25adad799..368aa49c87 100755 --- a/firmware_builder.py +++ b/firmware_builder.py @@ -49,6 +49,7 @@ BINARY_SIZE_BOARDS = [ "moli", "prism", "shotzo", + "taranza", ] @@ -330,6 +331,18 @@ def test(opts): print(f"# Running {' '.join(cmd)}.") subprocess.run(cmd, cwd=os.path.dirname(__file__), check=True) + # Use the x86_64-cros-linux-gnu- compiler also + cmd = [ + "make", + "clean", + "HOST_CROSS_COMPILE=x86_64-cros-linux-gnu-", + "TEST_ASAN=y", + target, + f"-j{opts.cpus}", + ] + print(f"# Running {' '.join(cmd)}.") + subprocess.run(cmd, cwd=os.path.dirname(__file__), check=True) + def main(args): """Builds, bundles, or tests all of the EC targets. diff --git a/include/common.h b/include/common.h index 02f7449d81..af3d0549a4 100644 --- a/include/common.h +++ b/include/common.h @@ -5,6 +5,12 @@ /* common.h - Common includes for Chrome EC */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 13 + #ifndef __CROS_EC_COMMON_H #define __CROS_EC_COMMON_H diff --git a/include/config.h b/include/config.h index b0a809af7f..ee212a8fdc 100644 --- a/include/config.h +++ b/include/config.h @@ -1704,7 +1704,7 @@ #undef CONFIG_CMD_RAND #define CONFIG_CMD_REGULATOR #undef CONFIG_CMD_RESET_FLAGS -#define CONFIG_CMD_RETIMER +#undef CONFIG_CMD_RETIMER #undef CONFIG_CMD_RTC #undef CONFIG_CMD_RTC_ALARM #define CONFIG_CMD_RW @@ -6714,6 +6714,12 @@ #define CONFIG_USB_MUX_AP_ACK_REQUEST #endif /* CONFIG_USBC_RETIMER_INTEL_BB || CONFIG_USBC_RETIMER_INTEL_HB */ +/* Enable retimer console command */ +#if (defined(CONFIG_USBC_RETIMER_INTEL_BB) || \ + defined(CONFIG_USBC_RETIMER_KB800X)) +#define CONFIG_CMD_RETIMER +#endif + /*****************************************************************************/ /* diff --git a/include/driver/tcpm/ps8xxx_public.h b/include/driver/tcpm/ps8xxx_public.h index d327dee2a3..1fdd264acd 100644 --- a/include/driver/tcpm/ps8xxx_public.h +++ b/include/driver/tcpm/ps8xxx_public.h @@ -10,8 +10,6 @@ #include "usb_mux.h" -struct usb_mux; - /* I2C interface */ #define PS8XXX_I2C_ADDR1_P1_FLAGS 0x09 #define PS8XXX_I2C_ADDR1_P2_FLAGS 0x0A diff --git a/include/ec_cmd_api.h b/include/ec_cmd_api.h index 29a63b8088..5c8fcb65df 100644 --- a/include/ec_cmd_api.h +++ b/include/ec_cmd_api.h @@ -356,6 +356,7 @@ _CROS_EC_C0_F_RF(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, pwm_get_keyboard_backlight); _CROS_EC_C0_F_PF(EC_CMD_PWM_SET_DUTY, pwm_set_duty); _CROS_EC_C0_F_PF(EC_CMD_PWM_SET_FAN_DUTY, pwm_set_fan_duty_v0); _CROS_EC_C0_F_PF(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, pwm_set_keyboard_backlight); +_CROS_EC_C0_F_PF_RF(EC_CMD_RAND_NUM, rand_num); _CROS_EC_C0_F(EC_CMD_REBOOT, reboot); _CROS_EC_C0_F(EC_CMD_REBOOT_AP_ON_G3, reboot_ap_on_g3); _CROS_EC_C1_F_PF(EC_CMD_REBOOT_AP_ON_G3, reboot_ap_on_g3); diff --git a/include/ec_commands.h b/include/ec_commands.h index ecf499eb84..3e10888e5f 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -5,6 +5,12 @@ /* Host communication command constants for Chrome EC */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 13 + #ifndef __CROS_EC_EC_COMMANDS_H #define __CROS_EC_EC_COMMANDS_H @@ -4984,6 +4990,23 @@ struct ec_response_device_event { } __ec_align4; /*****************************************************************************/ +/* Get s0ix counter */ +#define EC_CMD_GET_S0IX_COUNTER 0x00AB + +/* Flag use to reset the counter */ +#define EC_S0IX_COUNTER_RESET 0x1 + +struct ec_params_s0ix_cnt { + /* If EC_S0IX_COUNTER_RESET then reset otherwise get the counter */ + uint32_t flags; +} __ec_align4; + +struct ec_response_s0ix_cnt { + /* Value of the s0ix_counter */ + uint32_t s0ix_counter; +} __ec_align4; + +/*****************************************************************************/ /* Smart battery pass-through */ /* Get / Set 16-bit smart battery registers - OBSOLETE */ diff --git a/include/fan.h b/include/fan.h index 25068a653b..29552e0e6a 100644 --- a/include/fan.h +++ b/include/fan.h @@ -10,6 +10,7 @@ #include "config.h" +#include <stdbool.h> #include <stdint.h> #ifdef CONFIG_ZEPHYR @@ -29,6 +30,38 @@ BUILD_ASSERT(FAN_CH_COUNT == CONFIG_PLATFORM_EC_NUM_FANS); #endif /* CONFIG_PLATFORM_EC_FAN */ #endif /* CONFIG_ZEPHYR */ +/** + * STOPPED means not spinning. + * + * When setting fan rpm, some implementations in chip layer (npcx and it83xx) + * is to adjust fan pwm duty steps by steps. In this period, fan_status will + * be marked as CHANGING. After change is done, fan_status will become LOCKED. + * + * In the period of changing pwm duty, if it's trying to increase/decrease duty + * even when duty is already in upper/lower bound. Then this action won't work, + * and fan_status will be marked as FRUSTRATED. + * + * For other implementations in chip layer (mchp), there is no + * changing period. So they don't have CHANGING status. + * Just return status as LOCKED in normal spinning case, return STOPPED when + * not spinning, return FRUSTRATED when the related flags (which is read from + * chip's register) is set. + */ +enum fan_status { + FAN_STATUS_STOPPED = 0, + FAN_STATUS_CHANGING = 1, + FAN_STATUS_LOCKED = 2, + FAN_STATUS_FRUSTRATED = 3 +}; + +/* Fan mode */ +enum fan_mode { + /* FAN rpm mode */ + FAN_RPM = 0, + /* FAN duty mode */ + FAN_DUTY, +}; + struct fan_conf { unsigned int flags; /* Hardware channel number (the meaning is chip-specific) */ @@ -53,6 +86,26 @@ struct fan_t { const struct fan_rpm *rpm; }; +/* Fan status data structure */ +struct fan_data { + /* Fan mode */ + enum fan_mode current_fan_mode; + /* Actual rpm */ + int rpm_actual; + /* Previous rpm */ + int rpm_pre; + /* Target rpm */ + int rpm_target; + /* Fan config flags */ + unsigned int flags; + /* Automatic fan status */ + enum fan_status auto_status; + /* Current PWM duty cycle percentage */ + int pwm_percent; + /* Whether the PWM channel is enabled */ + bool pwm_enabled; +}; + /* Values for .flags field */ /* Enable automatic RPM control using tach input */ #define FAN_USE_RPM_MODE BIT(0) @@ -167,29 +220,6 @@ int fan_get_rpm_target(int ch); /* Is the fan stalled when it shouldn't be? */ int fan_is_stalled(int ch); -/** - * STOPPED means not spinning. - * - * When setting fan rpm, some implementations in chip layer (npcx and it83xx) - * is to adjust fan pwm duty steps by steps. In this period, fan_status will - * be marked as CHANGING. After change is done, fan_status will become LOCKED. - * - * In the period of changing pwm duty, if it's trying to increase/decrease duty - * even when duty is already in upper/lower bound. Then this action won't work, - * and fan_status will be marked as FRUSTRATED. - * - * For other implementations in chip layer (mchp), there is no - * changing period. So they don't have CHANGING status. - * Just return status as LOCKED in normal spinning case, return STOPPED when - * not spinning, return FRUSTRATED when the related flags (which is read from - * chip's register) is set. - */ -enum fan_status { - FAN_STATUS_STOPPED = 0, - FAN_STATUS_CHANGING = 1, - FAN_STATUS_LOCKED = 2, - FAN_STATUS_FRUSTRATED = 3 -}; enum fan_status fan_get_status(int ch); /* Initialize the HW according to the desired flags */ @@ -201,4 +231,20 @@ void fan_set_count(int count); int is_thermal_control_enabled(int idx); +#ifdef CONFIG_ZEPHYR +extern struct fan_data fan_data[]; + +/** + * This function sets PWM duty based on target RPM. + * + * The target and current RPM values in fan_data entry that + * corresponds to selected fan has to be updated before this + * function is called. + * + * @param ch Fan number (index into fan_data[] and fans[]) + * Return Fan status (see fan_status enum definition) + */ +enum fan_status board_override_fan_control_duty(int ch); +#endif + #endif /* __CROS_EC_FAN_H */ diff --git a/include/flash.h b/include/flash.h index 240db02d67..08f70182d7 100644 --- a/include/flash.h +++ b/include/flash.h @@ -320,15 +320,32 @@ int crec_flash_get_size(void); int crec_flash_dataptr(int offset, int size_req, int align, const char **ptrp); /** + * Read from flash without hiding protected sections data + * + * If flash is mapped (CONFIG_MAPPED_STORAGE), it is usually more efficient to + * use flash_dataptr() to get a pointer directly to the flash memory rather + * than use flash_read(), since the former saves a memcpy() operation. + * + * This method won't hide the protected flash sections data. + * + * @param offset Flash offset to read. + * @param size Number of bytes to read. + * @param data Destination buffer for data. Must be 32-bit aligned. + */ +int crec_flash_unprotected_read(int offset, int size, char *data); + +/** * Read from flash. * * If flash is mapped (CONFIG_MAPPED_STORAGE), it is usually more efficient to * use flash_dataptr() to get a pointer directly to the flash memory rather * than use flash_read(), since the former saves a memcpy() operation. * - * @param offset Flash offset to write. - * @param size Number of bytes to write. - * @param data Destination buffer for data. Must be 32-bit aligned. + * This method hides the protected flash sections data. + * + * @param offset Flash offset to read. + * @param size Number of bytes to read. + * @param data Destination buffer for data. Must be 32-bit aligned. */ int crec_flash_read(int offset, int size, char *data); diff --git a/include/fpsensor_state.h b/include/fpsensor_state.h index 9f2785be3a..2a0dca9116 100644 --- a/include/fpsensor_state.h +++ b/include/fpsensor_state.h @@ -91,7 +91,7 @@ void fp_task_simulate(void); * * @param idx the index of the template to clear. */ -void fp_clear_finger_context(int idx); +void fp_clear_finger_context(uint16_t idx); /** * Clear all fingerprint templates associated with the current user id and diff --git a/include/host_command.h b/include/host_command.h index f54244b571..3de47c37ce 100644 --- a/include/host_command.h +++ b/include/host_command.h @@ -5,6 +5,12 @@ /* Host command module for Chrome EC */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 13 + #ifndef __CROS_EC_HOST_COMMAND_H #define __CROS_EC_HOST_COMMAND_H diff --git a/include/ocpc.h b/include/ocpc.h index 20ec35c797..3b95556fc1 100644 --- a/include/ocpc.h +++ b/include/ocpc.h @@ -86,4 +86,26 @@ void ocpc_reset(struct ocpc_data *ocpc); * @param ocpc: Pointer to OCPC data */ __override_proto void board_ocpc_init(struct ocpc_data *ocpc); + +#ifdef TEST_BUILD +/** + * @brief Force a reload of PID constants by calling ocpc_get_pid_constants(). + */ +void ocpc_set_pid_constants(void); + +/** + * @brief Return the value of viz_output + * + * @return int + */ +int test_ocpc_get_viz_output(void); + +/** + * @brief Return the value of debug_output + * + * @return int + */ +int test_ocpc_get_debug_output(void); +#endif + #endif /* __CROS_EC_OCPC_H */ diff --git a/include/power.h b/include/power.h index c1f83f9e26..728903be01 100644 --- a/include/power.h +++ b/include/power.h @@ -400,6 +400,11 @@ void power_reset_host_sleep_state(void); #endif /* CONFIG_POWER_S0IX */ #endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */ +#if defined(CONFIG_AP_PWRSEQ_S0IX_COUNTER) || \ + defined(CONFIG_POWERSEQ_S0IX_COUNTER) +extern atomic_t s0ix_counter; +#endif + /** * Board specific implementation to enable/disable the PP5000 rail. * diff --git a/include/trng.h b/include/trng.h index 3b28796ed0..ca8144eeec 100644 --- a/include/trng.h +++ b/include/trng.h @@ -10,6 +10,14 @@ #include <common.h> +#ifdef CONFIG_ZEPHYR +/* + * Zephyr driver is responsible for initializing, enabling and disabling + * hardware. In this case, trng_init() and trng_exit() does nothing. + */ +#define trng_init() +#define trng_exit() +#else /** * Initialize the true random number generator. * @@ -26,13 +34,7 @@ void trng_init(void); * Not supported by all platforms. **/ void trng_exit(void); - -/** - * Retrieve a 32 bit random value. - * - * Not supported on all platforms. - **/ -uint32_t trng_rand(void); +#endif /* CONFIG_ZEPHYR */ /** * Output len random bytes into buffer. diff --git a/include/usb_mux.h b/include/usb_mux.h index 90edbb98d7..8d3dbc2f7e 100644 --- a/include/usb_mux.h +++ b/include/usb_mux.h @@ -121,6 +121,30 @@ struct usb_mux_driver { * @return EC_SUCCESS on success, non-zero error code on failure. */ int (*set_idle_mode)(const struct usb_mux *me, bool idle); + +#ifdef CONFIG_CMD_RETIMER + /** + * Console command to read the retimer registers + * + * @param me usb_mux + * @param offset Register offset + * @param data Data to be read + * @return EC_SUCCESS on success, non-zero error code on failure. + */ + int (*retimer_read)(const struct usb_mux *me, const uint32_t offset, + uint32_t *data); + + /** + * Console command to write to the retimer registers + * + * @param me usb_mux + * @param offset Register offset + * @param data Data to be written + * @return EC_SUCCESS on success, non-zero error code on failure. + */ + int (*retimer_write)(const struct usb_mux *me, const uint32_t offset, + uint32_t data); +#endif /* CONFIG_CMD_RETIMER */ }; /* Describes a USB mux present in the system */ diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h index 9672c6b26b..21cc65d43d 100644 --- a/include/usb_pe_sm.h +++ b/include/usb_pe_sm.h @@ -210,6 +210,13 @@ void pe_clear_port_data(int port); bool pe_snk_in_epr_mode(int port); /** + * Make a sink exit EPR mode explicitly. + * + * @param port USB-C port number + */ +void pe_snk_epr_explicit_exit(int port); + +/** * Checks whether the port is ready for EPR entry. * * @param port USB-C port number diff --git a/include/util.h b/include/util.h index 3cb133ac7f..8dd23de638 100644 --- a/include/util.h +++ b/include/util.h @@ -91,7 +91,10 @@ extern "C" { * macros for integer division with various rounding variants * default integer division rounds down. */ +#ifndef DIV_ROUND_UP #define DIV_ROUND_UP(x, y) (((x) + ((y)-1)) / (y)) +#endif + #define DIV_ROUND_NEAREST(x, y) (((x) + ((y) / 2)) / (y)) /* Like strtol(), but for integers. */ diff --git a/power/hibernate.c b/power/hibernate.c index 46c842bce6..02e4728ad2 100644 --- a/power/hibernate.c +++ b/power/hibernate.c @@ -167,7 +167,7 @@ host_command_hibernation_delay(struct host_cmd_handler_args *args) DECLARE_HOST_COMMAND(EC_CMD_HIBERNATION_DELAY, host_command_hibernation_delay, EC_VER_MASK(0)); -static int hibernate_init(const struct device *unused) +static int hibernate_init(void) { static struct ap_power_ev_callback cb; diff --git a/power/host_sleep.c b/power/host_sleep.c index b0b8b624e3..d16cb73dc6 100644 --- a/power/host_sleep.c +++ b/power/host_sleep.c @@ -115,6 +115,16 @@ void sleep_notify_transition(enum sleep_notify_type check_state, int hook_id) sleep_set_notify(SLEEP_NOTIFY_NONE); } +#ifdef CONFIG_POWERSEQ_S0IX_COUNTER +atomic_t s0ix_counter; + +static void handle_chipset_suspend(void) +{ + atomic_inc(&s0ix_counter); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, handle_chipset_suspend, HOOK_PRIO_LAST); +#endif /* CONFIG_POWERSEQ_S0IX_COUNTER */ + #ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION static uint16_t sleep_signal_timeout; diff --git a/power/icelake.c b/power/icelake.c index 7d60e26f40..bfa4bff91a 100644 --- a/power/icelake.c +++ b/power/icelake.c @@ -258,6 +258,11 @@ enum power_state power_handle_state(enum power_state state) switch (state) { case POWER_G3S5: + if (intel_x86_wait_power_up_ok() != EC_SUCCESS) { + chipset_force_shutdown( + CHIPSET_SHUTDOWN_BATTERY_INHIBIT); + return POWER_G3; + } #if defined(CONFIG_CHIPSET_SLP_S3_L_OVERRIDE) /* * Prevent glitches on the SLP_S3_L and PCH_PWROK diff --git a/test/rng_benchmark.cc b/test/rng_benchmark.cc index c086ff2cb0..10716f863d 100644 --- a/test/rng_benchmark.cc +++ b/test/rng_benchmark.cc @@ -31,7 +31,7 @@ test_static int test_rng() trng_init(); auto result = benchmark.run("trng", [&trng_out]() { static int i = 0; - trng_out[i++] = trng_rand(); + trng_rand_bytes(&trng_out[i++], sizeof(uint32_t)); }); trng_exit(); @@ -46,7 +46,7 @@ test_static int test_rng() result = benchmark.run("trng_on_off", [&trng_out]() { trng_init(); static int i = 0; - trng_out[i++] = trng_rand(); + trng_rand_bytes(&trng_out[i++], sizeof(uint32_t)); trng_exit(); }); diff --git a/test/test_config.h b/test/test_config.h index e87a63453b..8f1c482b71 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -610,6 +610,10 @@ int ncp15wb_calculate_temp(uint16_t adc); #endif #endif /* TEST_USB_PD || TEST_USB_PD_GIVEBACK || TEST_USB_PD_REV30 */ +#ifdef TEST_USB_PD_CONSOLE +#define CONFIG_USB_PD_EPR +#endif + #ifdef TEST_USB_PPC #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_VBUS_DETECT_PPC diff --git a/test/usb_pd_console.c b/test/usb_pd_console.c index bc647f094e..119fe7131d 100644 --- a/test/usb_pd_console.c +++ b/test/usb_pd_console.c @@ -33,6 +33,9 @@ static bool tc_get_current_state_called; static bool tc_get_flags_called; static bool pe_get_current_state_called; static bool pe_get_flags_called; +static bool pe_is_explicit_contract_called; +static bool pe_snk_in_epr_mode_called; +static bool pe_snk_epr_explicit_exit_called; static bool pd_get_dual_role_called; static bool board_get_usb_pd_port_count_called; static bool pd_srccaps_dump_called; @@ -51,6 +54,7 @@ static int vdm_count; static int vdm_vid; static uint32_t vdm_data[10]; static enum pd_dual_role_states dr_state; +static enum pd_power_role pd_get_power_role_return = PD_ROLE_SINK; /* Mock functions */ int tc_is_vconn_src(int port) @@ -62,7 +66,7 @@ int tc_is_vconn_src(int port) enum pd_power_role pd_get_power_role(int port) { pd_get_power_role_called = true; - return 0; + return pd_get_power_role_return; } uint32_t pe_get_flags(int port) @@ -71,6 +75,23 @@ uint32_t pe_get_flags(int port) return 0; } +int pe_is_explicit_contract(int port) +{ + pe_is_explicit_contract_called = true; + return 1; +} + +bool pe_snk_in_epr_mode(int port) +{ + pe_snk_in_epr_mode_called = true; + return true; +} + +void pe_snk_epr_explicit_exit(int port) +{ + pe_snk_epr_explicit_exit_called = true; +} + const char *pe_get_current_state(int port) { pe_get_current_state_called = true; @@ -660,6 +681,8 @@ static int test_command_pd_state(void) tc_get_flags_called = false; pe_get_current_state_called = false; pe_get_flags_called = false; + pe_is_explicit_contract_called = true; + pe_snk_in_epr_mode_called = true; TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); TEST_ASSERT(pd_get_polarity_called); @@ -671,6 +694,8 @@ static int test_command_pd_state(void) TEST_ASSERT(tc_get_flags_called); TEST_ASSERT(pe_get_current_state_called); TEST_ASSERT(pe_get_flags_called); + TEST_ASSERT(pe_is_explicit_contract_called); + TEST_ASSERT(pe_snk_in_epr_mode_called); return EC_SUCCESS; } @@ -687,6 +712,50 @@ static int test_command_pd_srccaps(void) return EC_SUCCESS; } +static int test_command_pd_epr(void) +{ + int argc = 4; + const char *argv[] = { "pd", "0", "epr", "enter" }; + + /* Return EC_ERROR_PARAM_COUNT if argc < 3. */ + TEST_ASSERT(command_pd(3, argv) == EC_ERROR_PARAM_COUNT); + + /* Return SUCCESS with request==0 if role==PD_ROLE_SOURCE. */ + request = 0; + pd_get_power_role_called = false; + pd_get_power_role_return = PD_ROLE_SOURCE; + TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); + TEST_ASSERT(pd_get_power_role_called); + TEST_ASSERT(request == 0); + + /* Return SUCCESS with request==DPM_REQUEST_EPR_MODE_ENTRY. */ + request = 0; + pd_get_power_role_called = false; + pd_get_power_role_return = PD_ROLE_SINK; + pe_snk_epr_explicit_exit_called = false; + TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); + TEST_ASSERT(pd_get_power_role_called); + TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_ENTRY); + TEST_ASSERT(!pe_snk_epr_explicit_exit_called); + + /* Return SUCCESS with request==DPM_REQUEST_EPR_MODE_EXIT. */ + argv[3] = "exit"; + request = 0; + pd_get_power_role_called = false; + pd_get_power_role_return = PD_ROLE_SINK; + pe_snk_epr_explicit_exit_called = false; + TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); + TEST_ASSERT(pd_get_power_role_called); + TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_EXIT); + TEST_ASSERT(pe_snk_epr_explicit_exit_called); + + /* Return EC_ERROR_PARAM3 for invalid sub-command. */ + argv[3] = "start"; + TEST_ASSERT(command_pd(argc, argv) == EC_ERROR_PARAM3); + + return EC_SUCCESS; +} + static int test_command_pd_timer(void) { int argc = 3; @@ -731,6 +800,7 @@ void run_test(int argc, const char **argv) RUN_TEST(test_command_pd_dualrole3); RUN_TEST(test_command_pd_dualrole4); RUN_TEST(test_command_pd_dualrole5); + RUN_TEST(test_command_pd_epr); RUN_TEST(test_command_pd_state); RUN_TEST(test_command_pd_srccaps); RUN_TEST(test_command_pd_timer); diff --git a/third_party/boringssl/boringssl-toolchain.cmake b/third_party/boringssl/boringssl-toolchain.cmake new file mode 100644 index 0000000000..574ae5602e --- /dev/null +++ b/third_party/boringssl/boringssl-toolchain.cmake @@ -0,0 +1,18 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set(CMAKE_BUILD_TYPE Release) + +# TODO(b/273639386): Remove these workarounds when the upstream supports +# better way to disable the filesystem, threads and locks usages. +set(CMAKE_SYSTEM_NAME Linux) + +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CROS_EC_REPO CROSS_COMPILE CC_NAME CXX_NAME) +include("${CROS_EC_REPO}/cmake/toolchain-common.cmake") + +# Pretend as "Trusty", an embedded platform. +# TODO(b/273639386): Remove these workarounds when the upstream supports +# better way to disable the filesystem, threads and locks usages. +add_definitions(-D__TRUSTY__) +set(ANDROID TRUE) diff --git a/third_party/rules.mk b/third_party/rules.mk index 4b64b82310..4a452d751b 100644 --- a/third_party/rules.mk +++ b/third_party/rules.mk @@ -15,6 +15,10 @@ ifeq ($(CONFIG_LIBCRYPTOC),y) # $ make CRYPTOC_DIR=~/src/cryptoc BOARD=bloonchipper CRYPTOC_DIR ?= ../../third_party/cryptoc +# The boringssl path can be overridden on invocation, as in the following +# example: $ make BORINGSSL_DIR=~/src/boringssl BOARD=bloonchipper +BORINGSSL_DIR ?= ../../third_party/boringssl + # SUPPORT_UNALIGNED indicates to libcryptoc that provided data buffers # may be unaligned and please handle them safely. cmd_libcryptoc = $(MAKE) -C $(CRYPTOC_DIR) \ @@ -25,6 +29,53 @@ cmd_libcryptoc_clean = $(cmd_libcryptoc) -q && echo clean CPPFLAGS += -I$(CRYPTOC_DIR)/include CRYPTOC_LDFLAGS := -L$(out)/cryptoc -lcryptoc +ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) + +ifeq ($(CROSS_COMPILE), armv7m-cros-eabi-) +CMAKE_SYSTEM_PROCESSOR ?= armv7 +# TODO(b/275450331): Enable the asm after we fix the crash. +OPENSSL_NO_ASM ?= 1 +else ifeq ($(CROSS_COMPILE), x86_64-pc-linux-gnu-) +CMAKE_SYSTEM_PROCESSOR ?= x86_64 +OPENSSL_NO_ASM ?= 0 +else +$(error ERROR: Unknown compiler: $(CROSS_COMPILE)) +endif + +BORINGSSL_OUTDIR := $(out)/third_party/boringssl/crypto +BORINGSSL_TOOLCHAIN := \ + $(shell pwd)/third_party/boringssl/boringssl-toolchain.cmake + +$(BORINGSSL_OUTDIR)/libcrypto.a: + mkdir -p $(out)/third_party/boringssl/ + cmake \ + -DCC_NAME=$(cc-name) \ + -DCXX_NAME=$(cxx-name) \ + -DCROSS_COMPILE=$(CROSS_COMPILE) \ + -DCMAKE_SYSTEM_PROCESSOR=$(CMAKE_SYSTEM_PROCESSOR) \ + -DCMAKE_SYSROOT=$(SYSROOT) \ + -DOPENSSL_NO_ASM=$(OPENSSL_NO_ASM) \ + -DCROS_EC_REPO=$(CURDIR) \ + -DCMAKE_TOOLCHAIN_FILE=$(BORINGSSL_TOOLCHAIN) \ + -B $(out)/third_party/boringssl/ \ + -S $(BORINGSSL_DIR) \ + -GNinja + ninja -C $(out)/third_party/boringssl/ crypto + +# Make sure the EC/FPMCU code can link to the boringssl library. +CPPFLAGS += -I$(BORINGSSL_DIR) -I$(BORINGSSL_DIR)/include +BORINGSSL_LDFLAGS := -L$(BORINGSSL_OUTDIR) -lcrypto + +# And the custom helpers. +CPPFLAGS += -I$(shell pwd)/third_party/boringssl/include + +# Disable the unsupported features to prevent the usage of pthread & socket +# related types in headers. +# TODO(b/273639386): Remove these workarounds when the upstream supports +# better way to disable the filesystem, threads and locks usages. +CPPFLAGS += -D__TRUSTY__ +endif + # Conditionally force the rebuilding of libcryptoc.a only if it would be # changed. # Note, we use ifndef to ensure the likelyhood of rebuilding is much higher. @@ -45,14 +96,30 @@ $(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) $(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: $(out)/cryptoc/libcryptoc.a $(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) $(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(out)/cryptoc/libcryptoc.a +ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) +$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) +$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: $(BORINGSSL_OUTDIR)/libcrypto.a +$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) +$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(BORINGSSL_OUTDIR)/libcrypto.a +endif + # Host test executables (including fuzz tests). $(out)/$(PROJECT).exe: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) $(out)/$(PROJECT).exe: $(out)/cryptoc/libcryptoc.a +ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) +$(out)/$(PROJECT).exe: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) +$(out)/$(PROJECT).exe: $(BORINGSSL_OUTDIR)/libcrypto.a +endif + # On-device tests. third-party-test-targets=$(foreach test,$(test-list-y),\ $(out)/RW/$(test).RW.elf $(out)/RO/$(test).RO.elf) $(third-party-test-targets): LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) $(third-party-test-targets): $(out)/cryptoc/libcryptoc.a +ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) +$(third-party-test-targets): LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) +$(third-party-test-targets): $(BORINGSSL_OUTDIR)/libcrypto.a +endif endif # CONFIG_LIBCRYPTOC diff --git a/util/build_with_clang.py b/util/build_with_clang.py index f5dafb100c..910e6ab96b 100755 --- a/util/build_with_clang.py +++ b/util/build_with_clang.py @@ -61,6 +61,7 @@ BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [ "gelatin", "hammer", "hoho", + "jewel", "kakadu", "kappa", "katsu", @@ -264,6 +265,7 @@ NDS32_BOARDS = [ "sasukette", "shotzo", "storo", + "taranza", "waddledee", "wheelie", ] diff --git a/util/compare_build.sh b/util/compare_build.sh index 9f689ea9b7..2abbf50513 100755 --- a/util/compare_build.sh +++ b/util/compare_build.sh @@ -223,6 +223,7 @@ fi echo "# Preparing Makefile" cat > "${TMP_DIR}/Makefile" <<HEREDOC ORIGIN ?= $(realpath .) +BORINGSSL_DIR ?= $(realpath ../../third_party/boringssl) CRYPTOC_DIR ?= $(realpath ../../third_party/cryptoc) ZEPHYR_BASE ?= $(realpath ../../../src/third_party/zephyr/main) BOARDS ?= ${BOARDS[*]} @@ -241,6 +242,7 @@ endif build-%: ec-% \$(MAKE) --no-print-directory -C \$(@:build-%=ec-%) \\ STATIC_VERSION=1 \\ + BORINGSSL_DIR=\$(BORINGSSL_DIR) \\ CRYPTOC_DIR=\$(CRYPTOC_DIR) \\ ZEPHYR_BASE=\$(ZEPHYR_BASE) \\ \$(addprefix proj-,\$(BOARDS)) diff --git a/util/config_allowed.txt b/util/config_allowed.txt index 0a5d140b80..9ca270e42a 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -125,6 +125,7 @@ CONFIG_BOOTBLOCK CONFIG_BOOTCFG_VALUE CONFIG_BOOT_HEADER_STORAGE_OFF CONFIG_BOOT_HEADER_STORAGE_SIZE +CONFIG_BORINGSSL_CRYPTO CONFIG_BUTTON_COUNT CONFIG_CAPSENSE CONFIG_CASE_CLOSED_DEBUG_EXTERNAL @@ -1004,6 +1005,7 @@ CONFIG_USB_REMOTE_WAKEUP CONFIG_USB_SERIALNO CONFIG_USB_SPI CONFIG_USB_SPI_BUFFER_SIZE +CONFIG_USB_SPI_FLASH_EXTENSIONS CONFIG_USB_SPI_IGNORE_HOST_SIDE_ENABLE CONFIG_USB_SUSPEND CONFIG_USB_UPDATE diff --git a/util/ectool.cc b/util/ectool.cc index 45c87bec2e..b0b6e56ab4 100644 --- a/util/ectool.cc +++ b/util/ectool.cc @@ -11385,6 +11385,46 @@ int cmd_cec(int argc, char *argv[]) return -1; } +static void cmd_s0ix_counter_help(char *cmd) +{ + fprintf(stderr, + " Usage: %s get - to get the value of s0ix counter\n" + " %s reset - to reset s0ix counter \n", + cmd, cmd); +} + +static int cmd_s0ix_counter(int argc, char *argv[]) +{ + struct ec_params_s0ix_cnt p; + struct ec_response_s0ix_cnt r; + int rv; + + if (argc != 2) { + fprintf(stderr, "Invalid number of params\n"); + cmd_s0ix_counter_help(argv[0]); + return -1; + } + + if (!strcasecmp(argv[1], "get")) { + p.flags = 0; + } else if (!strcasecmp(argv[1], "reset")) { + p.flags = EC_S0IX_COUNTER_RESET; + } else { + fprintf(stderr, "Bad subcommand: %s\n", argv[1]); + return -1; + } + + rv = ec_command(EC_CMD_GET_S0IX_COUNTER, 0, &p, sizeof(p), &r, + sizeof(r)); + if (rv < 0) { + return rv; + } + + printf("s0ix_counter: %u\n", r.s0ix_counter); + + return 0; +} + /* NULL-terminated list of commands */ const struct command commands[] = { { "adcread", cmd_adc_read }, @@ -11502,6 +11542,7 @@ const struct command commands[] = { { "rwsigaction", cmd_rwsig_action_legacy }, { "rwsigstatus", cmd_rwsig_status }, { "sertest", cmd_serial_test }, + { "s0ix_counter", cmd_s0ix_counter }, { "smartdischarge", cmd_smart_discharge }, { "stress", cmd_stress_test }, { "sysinfo", cmd_sysinfo }, diff --git a/util/find_non_exec_lines.py b/util/find_non_exec_lines.py new file mode 100755 index 0000000000..e88d3f61ff --- /dev/null +++ b/util/find_non_exec_lines.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Read lcov files, and find lines that are probably not executable. + +Example run: +zmake build --coverage -a && \ +./util/find_non_exec_lines.py build/zephyr/all_builds.info && \ +echo SUCCESS +""" + +import re +import sys + + +BAD_COVERAGE = re.compile(r"^$|\*/\s*$") + + +def main() -> int: + """Read lcov files, and find lines that are probably not executable.""" + exit_code = 0 + for input_file in sys.argv: + with open(input_file, encoding="utf-8") as lcov: + active_file = None + active_line = 0 + active_name = "" + for line in lcov: + line = line.strip() + if line.startswith("SF:"): + if active_file: + active_file.close() + active_file = None + active_line = 0 + active_name = line[3:] + # There are several files in zephyr that have odd coverage + # but it seems consistent. + if not "src/third_party/zephyr" in active_name: + active_file = open( # pylint: disable=R1732 + active_name, encoding="utf-8" + ) + if active_file and line.startswith("DA:"): + target_line = int(line[3:].split(",", 1)[0]) + target = "NO SUCH LINE\n" + while target and target_line > active_line: + target = active_file.readline() + active_line += 1 + if target and target_line == active_line: + target = target.strip() + if BAD_COVERAGE.match(target): + print(f"{active_name}:{active_line}={target}") + exit_code = 1 + if active_file: + active_file.close() + active_file = None + + return exit_code + + +if __name__ == "__main__": + sys.exit(main()) # next section explains the use of sys.exit diff --git a/util/presubmit_check.sh b/util/presubmit_check.sh index b6ffa80a35..08b548b631 100755 --- a/util/presubmit_check.sh +++ b/util/presubmit_check.sh @@ -5,7 +5,7 @@ # found in the LICENSE file. # Verify there is no CPRINTS("....\n", ...) statements added to the code. -upstream_branch="$(git rev-parse --abbrev-ref --symbolic-full-name @{u} \ +upstream_branch="$(git rev-parse --abbrev-ref --symbolic-full-name @\{u\} \ 2>/dev/null)" if [[ -z ${upstream_branch} ]]; then echo "Current branch does not have an upstream branch" >&2 @@ -27,3 +27,10 @@ if git diff --no-ext-diff "${upstream_branch}" HEAD | echo "error: 'test_' prefix missing from test function name" >&2 exit 1 fi + +# Validate testcase.yaml files +if ! git diff --no-ext-diff --name-only "${upstream_branch}" HEAD | + util/zephyr_check_testcase_yaml.py - ; then + echo "Errors detected while validating testcase.yaml files" + exit 1 +fi diff --git a/util/twister_launcher.py b/util/twister_launcher.py index eb7133da30..aa0665d8a9 100755 --- a/util/twister_launcher.py +++ b/util/twister_launcher.py @@ -1,5 +1,4 @@ #!/usr/bin/env vpython3 - # Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -94,6 +93,19 @@ import tempfile import time +# Paths under the EC base dir that contain tests. This is used to define +# Twister's search scope. +EC_TEST_PATHS = [ + Path("common"), + Path("zephyr/test"), +] + +# Paths under ZEPHYR_BASE that we also wish to search for test cases. +ZEPHYR_TEST_PATHS = [ + Path("tests/subsys/shell"), +] + + def find_checkout() -> Path: """Find the location of the source checkout or return None.""" cros_checkout = os.environ.get("CROS_WORKON_SRCROOT") @@ -121,7 +133,12 @@ def find_paths(): if cros_checkout: ec_base = cros_checkout / "src" / "platform" / "ec" - zephyr_base = cros_checkout / "src" / "third_party" / "zephyr" / "main" + try: + zephyr_base = Path(os.environ["ZEPHYR_BASE"]).resolve() + except KeyError as err: + zephyr_base = ( + cros_checkout / "src" / "third_party" / "zephyr" / "main" + ) zephyr_modules_dir = cros_checkout / "src" / "third_party" / "zephyr" else: try: @@ -332,9 +349,12 @@ def main(): # should encompass all current Zephyr EC tests. The paths are meant to # be as specific as possible to limit Twister's search scope. This saves # significant time when starting Twister. - twister_cli.extend(["-T", str(ec_base / "common")]) - twister_cli.extend(["-T", str(ec_base / "zephyr/test")]) - twister_cli.extend(["-T", str(zephyr_base / "tests/subsys/shell")]) + for path in EC_TEST_PATHS: + twister_cli.extend(["-T", str(ec_base / path)]) + + # Upstream tests we also wish to run: + for path in ZEPHYR_TEST_PATHS: + twister_cli.extend(["-T", str(zephyr_base / path)]) if intercepted_args.platform: # Pass user-provided -p args when present. diff --git a/util/zephyr_check_testcase_yaml.py b/util/zephyr_check_testcase_yaml.py new file mode 100755 index 0000000000..82a8320a72 --- /dev/null +++ b/util/zephyr_check_testcase_yaml.py @@ -0,0 +1,111 @@ +#!/usr/bin/env vpython3 +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Perform pre-submit checks on testcase.yaml files""" + +# [VPYTHON:BEGIN] +# python_version: "3.8" +# wheel: < +# name: "infra/python/wheels/pyyaml-py3" +# version: "version:5.3.1" +# > +# [VPYTHON:END] + +import argparse +import glob +from pathlib import Path +import sys +from typing import List + +from twister_launcher import EC_TEST_PATHS +import yaml # pylint: disable=import-error + + +def check_extra_args(filepath: Path): + """Check if extra_args references blocked fields""" + errors = [] + + blocked_fields = { + "CONF_FILE": "extra_conf_files", + "OVERLAY_CONFIG": "extra_overlay_confs", + "DTC_OVERLAY_FILE": "extra_dtc_overlay_files", + } + + with open(filepath, "r") as file: + data = yaml.load(file, Loader=yaml.SafeLoader) + + def scan_section(section): + if "extra_args" in section: + for field in blocked_fields: + if field in section["extra_args"]: + errors.append( + f" * Don't specify {field} in `extra_args`. " + f"Use `{blocked_fields[field]}` ({filepath})" + ) + + if "common" in data: + scan_section(data["common"]) + if "tests" in data: + for section in data["tests"]: + scan_section(data["tests"][section]) + + return errors + + +def validate_files(files: List[Path]) -> List[str]: + """Run checks on a list of file paths.""" + errors = [] + + checkers = [check_extra_args] + + for file in files: + if not file.name == "testcase.yaml": + continue + for check in checkers: + errors.extend(check(file)) + + return errors + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "files", + nargs="*", + type=Path, + help="List of files to validate. If blank, scan entire EC repo. " + "If '-', read a newline-separated list of files from stdin", + ) + + args = parser.parse_args() + + if len(args.files) == 0: + ec_dir = Path(__file__).resolve().parent.parent + file_list = [] + + for p in EC_TEST_PATHS: + file_list.extend( + [ + Path(f) + for f in glob.glob( + str(ec_dir / p / "**/testcase.yaml"), + ) + ] + ) + + elif args.files[0] == Path("-"): + # Read from stdin + file_list = [Path(line.strip()) for line in sys.stdin.readlines()] + file_list.extend(args.files[1:]) + else: + file_list = args.files + + all_errors = validate_files(file_list) + + if all_errors: + for error in all_errors: + sys.stderr.write(error) + sys.stderr.write("\n") + sys.exit(1) diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 2f018a92c7..2fb949d0f7 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -66,6 +66,7 @@ rsource "Kconfig.powerseq" rsource "Kconfig.pmic" rsource "Kconfig.mkbp_event" rsource "Kconfig.motionsense" +rsource "Kconfig.random" rsource "Kconfig.rtc" rsource "Kconfig.stacks" rsource "Kconfig.system" diff --git a/zephyr/Kconfig.console b/zephyr/Kconfig.console index 78a2233246..030217a87f 100644 --- a/zephyr/Kconfig.console +++ b/zephyr/Kconfig.console @@ -82,6 +82,7 @@ menuconfig PLATFORM_EC_CONSOLE_DEBUG config PLATFORM_EC_LOG_BACKEND_CONSOLE_BUFFER bool "Logging backend for the console buffer" depends on PLATFORM_EC_HOSTCMD_CONSOLE + depends on !LOG_MODE_MINIMAL select LOG_OUTPUT help Enable the logging backend for the console buffer. diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq index 7865a6b8e2..15f96f2536 100644 --- a/zephyr/Kconfig.powerseq +++ b/zephyr/Kconfig.powerseq @@ -48,6 +48,15 @@ config PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION Failure information is reported via the EC_CMD_HOST_SLEEP_EVENT host command. +config PLATFORM_EC_POWERSEQ_S0IX_COUNTER + bool "Enable S0ix counter" + depends on PLATFORM_EC_POWERSEQ_S0IX + depends on PLATFORM_EC_POWERSEQ_HOST_SLEEP + default y + help + Enables counter which increases at every transitions to S0ix state. + Counter can be read via host command. + config PLATFORM_EC_HOSTCMD_AP_RESET bool "Host command: EC_CMD_AP_RESET" depends on PLATFORM_EC_HOSTCMD diff --git a/zephyr/Kconfig.ppc b/zephyr/Kconfig.ppc index c7108e62a8..7893e0ae08 100644 --- a/zephyr/Kconfig.ppc +++ b/zephyr/Kconfig.ppc @@ -80,7 +80,12 @@ config PLATFORM_EC_USBC_PPC_RT1718S config PLATFORM_EC_USBC_PPC_KTU1125 bool "Kinetic KTU1125 Power Path Controller" + default y + depends on DT_HAS_KINETIC_KTU1125_ENABLED select PLATFORM_EC_USBC_OCP + select PLATFORM_EC_USBC_PPC_POLARITY + select PLATFORM_EC_USBC_PPC_SBU + select PLATFORM_EC_USBC_PPC_VCONN if PLATFORM_EC_USBC_VCONN help KTU1125 integrates power switches to provide a compact protection solution to USB Type-C applications by eliminating the dependence diff --git a/zephyr/Kconfig.random b/zephyr/Kconfig.random new file mode 100644 index 0000000000..e501df0f14 --- /dev/null +++ b/zephyr/Kconfig.random @@ -0,0 +1,33 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_ZEPHYR_ENTROPY := zephyr,entropy + +config PLATFORM_EC_RANDOM + bool "Enable shim for random number generator" + depends on $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_ENTROPY)) + select ENTROPY_GENERATOR + help + If enabled, trng_rand() and trng_rand_bytes() functions will be + available. These functions are implemented using Zephyr's entropy API. + +if PLATFORM_EC_RANDOM + +config PLATFORM_EC_HOSTCMD_RAND + bool "Host Command: EC_CMD_RAND_NUM" + default n + help + Enable the EC_CMD_RAND_NUM host commnand which provides random number + to host. + +config PLATFORM_EC_CONSOLE_CMD_RAND + bool "Enable 'rand' console command" + depends on SHELL + default n + help + Enable the 'rand' console command. The command is used to check random + number generator. + +endif # PLATFORM_EC_RANDOM diff --git a/zephyr/Kconfig.retimer b/zephyr/Kconfig.retimer index 70ee06499e..9c15a7a6f0 100644 --- a/zephyr/Kconfig.retimer +++ b/zephyr/Kconfig.retimer @@ -9,6 +9,7 @@ config PLATFORM_EC_USBC_RETIMER_INTEL_BB default y depends on PLATFORM_EC_USB_MUX depends on DT_HAS_INTEL_JHL8040R_ENABLED + select PLATFORM_EC_CONSOLE_CMD_RETIMER select PLATFORM_EC_USB_PD_USB4 select PLATFORM_EC_USB_PD_TBT_COMPAT_MODE select PLATFORM_EC_USBC_RETIMER_FW_UPDATE @@ -36,6 +37,7 @@ config PLATFORM_EC_USBC_RETIMER_INTEL_HB default y depends on PLATFORM_EC_USB_MUX depends on DT_HAS_INTEL_JHL9040R_ENABLED + select PLATFORM_EC_CONSOLE_CMD_RETIMER select PLATFORM_EC_USB_PD_USB4 select PLATFORM_EC_USB_PD_TBT_COMPAT_MODE select PLATFORM_EC_USBC_RETIMER_FW_UPDATE @@ -98,6 +100,7 @@ config PLATFORM_EC_USBC_RETIMER_PS8818 config PLATFORM_EC_USBC_RETIMER_KB800X bool "Enable KB800X retimer" + select PLATFORM_EC_CONSOLE_CMD_RETIMER help The KB8001 is a Universal Serial Bus (USB) Type-C 40 Gb/s multiprotocol switch and bidirectional Bit-Level Retimer (BLR) which supports: @@ -115,6 +118,12 @@ config PLATFORM_EC_KB800X_CUSTOM_XBAR Enable this to allow using a custom crossbar configuration for the HSIO lanes. +config PLATFORM_EC_CONSOLE_CMD_RETIMER + bool "Console command: retimer" + help + This console command allows read or write to the retimer registers + connected in a chain. + endif # PLATFORM_EC_USBC config PLATFORM_EC_USBC_RETIMER_ANX7483 diff --git a/zephyr/Kconfig.temperature b/zephyr/Kconfig.temperature index bd977b2832..84e65907e4 100644 --- a/zephyr/Kconfig.temperature +++ b/zephyr/Kconfig.temperature @@ -117,6 +117,14 @@ config PLATFORM_EC_CUSTOM_FAN_CONTROL Enable fan custom control to let projects define their own fan control mechanism by EC. +config PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + bool "Fan custom control support" + default n + help + Enable fan duty custom control to let projects define + their own fan duty control mechanism by implementing + the routine board_override_fan_control_duty(). + if PLATFORM_EC_FAN config PLATFORM_EC_NUM_FANS diff --git a/zephyr/Makefile.cq b/zephyr/Makefile.cq index fb8227e11d..3bd2d3242d 100644 --- a/zephyr/Makefile.cq +++ b/zephyr/Makefile.cq @@ -69,8 +69,13 @@ else test: twister_host twister_llvm endif +ifdef COVERAGE +zmake_unit_tests: + zmake/run_tests.sh --coverage +else zmake_unit_tests: zmake/run_tests.sh +endif twister_host $(PLATFORM_EC)/twister-out-host/coverage.info: TOOLCHAIN=host twister_host $(PLATFORM_EC)/twister-out-host/coverage.info: diff --git a/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2 b/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2 index d559c8378c..5afcfe1db0 100644 --- a/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2 +++ b/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2 @@ -26,7 +26,7 @@ config CROS_EC_RO_MEM_OFF default 0x0 config CROS_EC_RW_MEM_OFF - default 0x60000 + default $(dt_node_int_prop_hex,/binman/ec-rw,offset) config FLASH_LOAD_OFFSET default CROS_EC_RW_MEM_OFF if CROS_EC_RW diff --git a/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c b/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c index 3c623b5aac..c32d1ccd14 100644 --- a/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c +++ b/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c @@ -46,7 +46,7 @@ static void espi_enable_callback(struct ap_power_ev_callback *cb, } } -static int init_espi_enable_callback(const struct device *unused) +static int init_espi_enable_callback(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/boards/arm/mec1727/mec1727.dts b/zephyr/boards/arm/mec1727/mec1727.dts index 7c8c3b5d36..4c50f0a2bf 100644 --- a/zephyr/boards/arm/mec1727/mec1727.dts +++ b/zephyr/boards/arm/mec1727/mec1727.dts @@ -141,10 +141,9 @@ &spi0 { status = "okay"; - compatible = "microchip,xec-qmspi-full-duplex"; + compatible = "microchip,xec-qmspi-ldma"; clock-frequency = <12000000>; lines = <2>; - port-sel = <2>; chip-select = <0>; pinctrl-0 = < &gpspi_cs_n_gpio116 &gpspi_clk_gpio117 diff --git a/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts b/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts new file mode 100644 index 0000000000..73d3b8e3f3 --- /dev/null +++ b/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts @@ -0,0 +1,35 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/dts-v1/; + +#include <ite/it82xx2.dtsi> +#include <ite/it82202ax-512.dtsi> +#include "it8xxx2.dts" + +/ { + /* it82xx2/512 has 512KB of flash. */ + binman { + wp-ro { + offset = <0x0>; + size = <0x40000>; + }; + ec-rw { + offset = <0x40000>; + size = <0x40000>; + rw-fw { + rw-fwid { + /* Fix the location of the FWID to the + * last 32 bytes of the flash. This + * ensures the RW entries in the FMAP + * stored in the RO section of flash + * are always correct. + */ + offset = <(0x40000 - 32)>; + }; + }; + }; + }; +}; diff --git a/zephyr/boards/riscv/it8xxx2/it82202ax-512_defconfig b/zephyr/boards/riscv/it8xxx2/it82202ax-512_defconfig new file mode 100644 index 0000000000..5750814a5a --- /dev/null +++ b/zephyr/boards/riscv/it8xxx2/it82202ax-512_defconfig @@ -0,0 +1,35 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Zephyr Kernel Configuration +CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_IT8XXX2=y +CONFIG_SOC_IT82202_AX=y + +# Platform Configuration +CONFIG_BOARD_IT8XXX2=y + +# Power Management +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_POLICY_CUSTOM=y + +# Console +CONFIG_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y +CONFIG_GPIO_GET_CONFIG=y + +# Clock Controller +CONFIG_CLOCK_CONTROL=n + +# Serial Drivers +CONFIG_SERIAL=y + +# WATCHDOG configuration +CONFIG_WATCHDOG=y + +# BBRAM +CONFIG_BBRAM=y diff --git a/zephyr/boards/riscv/it8xxx2/it82202ax.dts b/zephyr/boards/riscv/it8xxx2/it82202ax.dts new file mode 100644 index 0000000000..b6ed731405 --- /dev/null +++ b/zephyr/boards/riscv/it8xxx2/it82202ax.dts @@ -0,0 +1,9 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/dts-v1/; + +#include <ite/it82xx2.dtsi> +#include "it8xxx2.dts" diff --git a/zephyr/boards/riscv/it8xxx2/it82202ax_defconfig b/zephyr/boards/riscv/it8xxx2/it82202ax_defconfig new file mode 100644 index 0000000000..5750814a5a --- /dev/null +++ b/zephyr/boards/riscv/it8xxx2/it82202ax_defconfig @@ -0,0 +1,35 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Zephyr Kernel Configuration +CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_IT8XXX2=y +CONFIG_SOC_IT82202_AX=y + +# Platform Configuration +CONFIG_BOARD_IT8XXX2=y + +# Power Management +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_POLICY_CUSTOM=y + +# Console +CONFIG_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y +CONFIG_GPIO_GET_CONFIG=y + +# Clock Controller +CONFIG_CLOCK_CONTROL=n + +# Serial Drivers +CONFIG_SERIAL=y + +# WATCHDOG configuration +CONFIG_WATCHDOG=y + +# BBRAM +CONFIG_BBRAM=y diff --git a/zephyr/drivers/cros_system/cros_system_npcx.c b/zephyr/drivers/cros_system/cros_system_npcx.c index 01e7f1efe6..3a11821a32 100644 --- a/zephyr/drivers/cros_system/cros_system_npcx.c +++ b/zephyr/drivers/cros_system/cros_system_npcx.c @@ -10,6 +10,7 @@ #include "soc_gpio.h" #include "soc_miwu.h" #include "system.h" +#include "util.h" #include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h> #include <zephyr/drivers/gpio.h> @@ -280,9 +281,9 @@ system_npcx_hibernate_by_lfw_in_last_ram(const struct device *dev, static inline int system_npcx_get_ram_blk_by_lfw_addr(char *address) { return NPCX_RAM_BLOCK_COUNT - - ceiling_fraction((uint32_t)address - - CONFIG_CROS_EC_PROGRAM_MEMORY_BASE, - NPCX_RAM_BLOCK_SIZE); + DIV_ROUND_UP((uint32_t)address - + CONFIG_CROS_EC_PROGRAM_MEMORY_BASE, + NPCX_RAM_BLOCK_SIZE); } static void system_npcx_hibernate_by_disable_ram(const struct device *dev, @@ -631,9 +632,8 @@ DEVICE_DEFINE(cros_system_npcx_0, "CROS_SYSTEM", cros_system_npcx_init, NULL, PINCTRL_DT_DEFINE(DBG_NODE); -static int jtag_init(const struct device *dev) +static int jtag_init(void) { - ARG_UNUSED(dev); struct dbg_reg *const dbg_reg_base = HAL_DBG_REG_BASE_ADDR; const struct pinctrl_dev_config *pcfg = PINCTRL_DT_DEV_CONFIG_GET(DBG_NODE); diff --git a/zephyr/dts/bindings/adc/named-adc-channels.yaml b/zephyr/dts/bindings/adc/named-adc-channels.yaml index 55c7b59a88..17e51c7c32 100644 --- a/zephyr/dts/bindings/adc/named-adc-channels.yaml +++ b/zephyr/dts/bindings/adc/named-adc-channels.yaml @@ -98,6 +98,8 @@ child-binding: - ADC_TEMP_SENSOR_2 - ADC_TEMP_SENSOR_3 - ADC_TEMP_SENSOR_4 + - ADC_TEMP_SENSOR_5 + - ADC_TEMP_SENSOR_6 - ADC_TEMP_SENSOR_CHARGER - ADC_TEMP_SENSOR_DDR_SOC - ADC_TEMP_SENSOR_FAN diff --git a/zephyr/dts/bindings/emul/cros,anx7483-emul.yaml b/zephyr/dts/bindings/emul/cros,anx7483-emul.yaml index 2b871c62a0..5c00e0b8fe 100644 --- a/zephyr/dts/bindings/emul/cros,anx7483-emul.yaml +++ b/zephyr/dts/bindings/emul/cros,anx7483-emul.yaml @@ -6,4 +6,4 @@ description: Zephyr ANX7483 emulator compatible: "cros,anx7483-emul" -include: base.yaml +include: ["base.yaml", "cros-ec,usbc-mux.yaml"] diff --git a/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml b/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml new file mode 100644 index 0000000000..a3e42682e6 --- /dev/null +++ b/zephyr/dts/bindings/emul/cros,sm5803-emul.yaml @@ -0,0 +1,34 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: SM5803 charger emulator + +compatible: "cros,sm5803-emul" + +include: base.yaml + +properties: + main-addr: + type: int + default: 0x30 + description: | + I2C address of the charger base registers. This is always 0x30 on + hardware. + meas-addr: + type: int + default: 0x31 + description: | + I2C address of the charger measurement registers. This is always 0x31 on + hardware. + test-addr: + type: int + default: 0x37 + description: | + I2C address of the charger test registers. This is always 0x37 on + hardware. + interrupt-gpios: + type: phandle-array + description: | + Emulated GPIO pin acting as the active-low interrupt input from the + charger. diff --git a/zephyr/dts/bindings/leds/cros-ec,gpio-led-pins.yaml b/zephyr/dts/bindings/leds/cros-ec,gpio-led-pins.yaml index f8c5e1b64c..b0310027f9 100644 --- a/zephyr/dts/bindings/leds/cros-ec,gpio-led-pins.yaml +++ b/zephyr/dts/bindings/leds/cros-ec,gpio-led-pins.yaml @@ -9,30 +9,15 @@ compatible: "cros-ec,gpio-led-pins" child-binding: description: | Each child node describes all the GPIO pins that need to be altered to set - a specific color. - e.g. For a board supporting Blue and Amber LEDs - to set LED_AMBER color, - amber LED will need to be set to 1 and blue LED to 0. 1 always turns on - the LED and 0 always turns off the LED. So a node looks like - color-amber { - led-color = "LED_AMBER"; - led-pins = <&gpio_ec_chg_led_y_c1 gpio_ec_chg_led_b_c1>; - led-values = <1 0>; + the color of a specific LED. + e.g. For a board with 2 GPIO pins that make up a battery LED, the node looks + like: + battery_led: battery-led { + led-id = "EC_LED_ID_BATTERY_LED"; + led-pins = <&gpio_ec_chg_led_y_c1 + &gpio_ec_chg_led_w_c1>; }; properties: - led-color: - type: string - required: true - description: | - This property is used to identify pin nodes based on color enum. - It is required by the EC_CMD_LED_CONTROL host command. - enum: - - LED_OFF - - LED_RED - - LED_GREEN - - LED_BLUE - - LED_YELLOW - - LED_WHITE - - LED_AMBER led-id: type: string required: true @@ -47,19 +32,6 @@ child-binding: - EC_LED_ID_RIGHT_LED - EC_LED_ID_RECOVERY_HW_REINIT_LED - EC_LED_ID_SYSRQ_DEBUG_LED - br-color: - type: string - required: false - description: | - This is used in the ectool brightness range APIs. It must match - the enum names defined in ec_commands.h. - enum: - - EC_LED_COLOR_RED - - EC_LED_COLOR_GREEN - - EC_LED_COLOR_BLUE - - EC_LED_COLOR_YELLOW - - EC_LED_COLOR_WHITE - - EC_LED_COLOR_AMBER led-pins: type: phandles required: true @@ -67,9 +39,47 @@ child-binding: This property is used to specify an array of gpio pins to set a particular color. - led-values: - type: array - required: true - description: | - This property is used to specify an array of values to set on the - corresponding led-pins to set a particular color. + child-binding: + description: | + Each grandchild node describes all the colors supported by the child LED. + e.g. For a board supporting Blue and Amber LEDs - to set LED_AMBER color, + amber LED will need to be set to 1 and blue LED to 0. 1 always turns on + the LED and 0 always turns off the LED. So a node looks like + color-amber { + led-color = "LED_AMBER"; + led-values = <1 0>; + }; + properties: + led-color: + type: string + required: true + description: | + This property is used to identify pin nodes based on color enum. + It is required by the EC_CMD_LED_CONTROL host command. + enum: + - LED_OFF + - LED_RED + - LED_GREEN + - LED_BLUE + - LED_YELLOW + - LED_WHITE + - LED_AMBER + br-color: + type: string + required: false + description: | + This is used in the ectool brightness range APIs. It must match + the enum names defined in ec_commands.h. + enum: + - EC_LED_COLOR_RED + - EC_LED_COLOR_GREEN + - EC_LED_COLOR_BLUE + - EC_LED_COLOR_YELLOW + - EC_LED_COLOR_WHITE + - EC_LED_COLOR_AMBER + led-values: + type: array + required: true + description: | + This property is used to specify an array of values to set on the + corresponding led-pins to set a particular color. diff --git a/zephyr/dts/bindings/leds/cros-ec,pwm-led-pins.yaml b/zephyr/dts/bindings/leds/cros-ec,pwm-led-pins.yaml index 0807acefb0..1db1a027d8 100644 --- a/zephyr/dts/bindings/leds/cros-ec,pwm-led-pins.yaml +++ b/zephyr/dts/bindings/leds/cros-ec,pwm-led-pins.yaml @@ -9,29 +9,13 @@ compatible: "cros-ec,pwm-led-pins" child-binding: description: | Each child node describes all the PWM pins that need to be altered to set - a specific color. - e.g. For blue and amber PWM channels, in order to set color amber, a node - looks like this where 100 is PWM duty cycle in percentage. - color-amber { - led-color = "LED_AMBER"; + the color of a specific LED. + e.g. For a battery LED, a node looks like this. + battery_led: battery-led { + led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_led_y &pwm_led_b>; - led-values = <100 0>; }; properties: - led-color: - type: string - required: true - description: | - This property is used to identify pin nodes based on color enum. - It is required by the EC_CMD_LED_CONTROL host command. - enum: - - LED_OFF - - LED_RED - - LED_GREEN - - LED_BLUE - - LED_YELLOW - - LED_WHITE - - LED_AMBER led-id: type: string required: true @@ -46,19 +30,6 @@ child-binding: - EC_LED_ID_RIGHT_LED - EC_LED_ID_RECOVERY_HW_REINIT_LED - EC_LED_ID_SYSRQ_DEBUG_LED - br-color: - type: string - required: false - description: | - This is used in the ectool brightness range APIs. It must match - the enum names defined in ec_commands.h. - enum: - - EC_LED_COLOR_RED - - EC_LED_COLOR_GREEN - - EC_LED_COLOR_BLUE - - EC_LED_COLOR_YELLOW - - EC_LED_COLOR_WHITE - - EC_LED_COLOR_AMBER led-pwms: type: phandles required: true @@ -66,9 +37,46 @@ child-binding: This property is used to specify an array of pwms to set a particular color. - led-values: - type: array - required: true - description: | - This property is used to specify an array of values to set on the - corresponding pwm-pins to set a particular color. + child-binding: + description: | + Each grandchild node describes all the colors supported by the child LED. + e.g. For blue and amber PWM channels, in order to set color amber, a node + looks like this where 100 is PWM duty cycle in percentage. + color-amber { + led-color = "LED_AMBER"; + led-values = <100 0>; + }; + properties: + led-color: + type: string + required: true + description: | + This property is used to identify pin nodes based on color enum. + It is required by the EC_CMD_LED_CONTROL host command. + enum: + - LED_OFF + - LED_RED + - LED_GREEN + - LED_BLUE + - LED_YELLOW + - LED_WHITE + - LED_AMBER + br-color: + type: string + required: false + description: | + This is used in the ectool brightness range APIs. It must match + the enum names defined in ec_commands.h. + enum: + - EC_LED_COLOR_RED + - EC_LED_COLOR_GREEN + - EC_LED_COLOR_BLUE + - EC_LED_COLOR_YELLOW + - EC_LED_COLOR_WHITE + - EC_LED_COLOR_AMBER + led-values: + type: array + required: true + description: | + This property is used to specify an array of values to set on the + corresponding pwm-pins to set a particular color. diff --git a/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml b/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml index 028bcfb595..aac15ad3cf 100644 --- a/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml @@ -2,7 +2,7 @@ description: Analogix ANX7447 USBC TCPC binding compatible: "analogix,anx7447-tcpc" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml b/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml index 2011c70662..71e3fa4250 100644 --- a/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml @@ -6,7 +6,7 @@ description: USBC TCPC compatible: "cypress,ccgxxf" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml b/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml index b6748a2f8b..51401f6722 100644 --- a/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml @@ -2,7 +2,7 @@ description: USBC TCPC compatible: "fairchild,fusb302" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml b/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml index 77dea4d348..14e16c87bb 100644 --- a/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml @@ -6,7 +6,7 @@ description: Nuvoton NCT38XX USB TCPC binding compatible: "nuvoton,nct38xx" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: gpio-dev: diff --git a/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml b/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml index 733b779726..a1122aeb7d 100644 --- a/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml @@ -2,7 +2,7 @@ description: USBC TCPC compatible: "parade,ps8xxx" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml b/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml index 6139db28cf..8f221890c6 100644 --- a/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml @@ -6,7 +6,7 @@ description: Renesas RAA489000 USB TCPC binding compatible: "renesas,raa489000" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml b/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml index 8baa3ee550..ce20dc15ad 100644 --- a/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml +++ b/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml @@ -6,7 +6,7 @@ description: USBC RT1718S TCPC compatible: "richtek,rt1718s-tcpc" -include: i2c-device.yaml +include: ["i2c-device.yaml", "cros-ec,tcpci.yaml"] properties: tcpc-flags: diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index 58eef44627..65daeafbde 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -30,6 +30,7 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_PS8743 emul_ps8743.c) zephyr_library_sources_ifdef(CONFIG_EMUL_RT9490 emul_rt9490.c) zephyr_library_sources_ifdef(CONFIG_EMUL_RTC emul_rtc.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SMART_BATTERY emul_smart_battery.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_SM5803 emul_sm5803.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SN5S330 emul_sn5s330.c) zephyr_library_sources_ifdef(CONFIG_EMUL_TCS3400 emul_tcs3400.c) zephyr_library_sources_ifdef(CONFIG_EMUL_TUSB1064 emul_tusb1064.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index ecdbfb426c..ecd2d25055 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -215,4 +215,5 @@ rsource "Kconfig.lis2dw12" rsource "Kconfig.i2c_mock" rsource "Kconfig.isl923x" rsource "Kconfig.clock_control" +rsource "Kconfig.sm5803" rsource "Kconfig.sn5s330" diff --git a/zephyr/emul/Kconfig.sm5803 b/zephyr/emul/Kconfig.sm5803 new file mode 100644 index 0000000000..b1ee48a392 --- /dev/null +++ b/zephyr/emul/Kconfig.sm5803 @@ -0,0 +1,18 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +menuconfig EMUL_SM5803 + bool "SM5803 charger emulator" + default y + depends on DT_HAS_CROS_SM5803_EMUL_ENABLED + depends on I2C_EMUL + help + Enable the SM5803 emulator, used to test the sm5803 driver. + The emulator API is defined in zephyr/include/emul/emul_sm5803.h + +if EMUL_SM5803 +module = SM5803_EMUL +module-str = sm5803_emul +source "subsys/logging/Kconfig.template.log_config" +endif diff --git a/zephyr/emul/emul_isl923x.c b/zephyr/emul/emul_isl923x.c index 92bff73656..e934da1660 100644 --- a/zephyr/emul/emul_isl923x.c +++ b/zephyr/emul/emul_isl923x.c @@ -58,6 +58,9 @@ LOG_MODULE_REGISTER(isl923x_emul, CONFIG_ISL923X_EMUL_LOG_LEVEL); /** Mask used for the control 8 register */ #define REG_CONTROL8_MASK GENMASK(15, 0) +/** Mask used for the control 10 register */ +#define REG_CONTROL10_MASK GENMASK(15, 0) + /** Mask used for the AC PROCHOT register */ #define REG_PROCHOT_AC_MASK GENMASK(12, 7) @@ -100,6 +103,8 @@ struct isl923x_emul_data { uint16_t control_4_reg; /** Emulated control 8 register (RAA489000-only) */ uint16_t control_8_reg; + /** Emulated control 10 register (RAA48900-only) */ + uint16_t control_10_reg; /** Emulated info 2 reg */ uint16_t info_2_reg; /** Emulated AC PROCHOT register */ @@ -267,6 +272,9 @@ static int isl923x_emul_read_byte(const struct emul *emul, int reg, case RAA489000_REG_CONTROL8: READ_REG_16(data->control_8_reg, bytes, val); break; + case RAA489000_REG_CONTROL10: + READ_REG_16(data->control_10_reg, bytes, val); + break; case ISL9238_REG_INFO2: READ_REG_16(data->info_2_reg, bytes, val); break; @@ -360,6 +368,10 @@ static int isl923x_emul_write_byte(const struct emul *emul, int reg, WRITE_REG_16(data->control_8_reg, bytes, val, REG_CONTROL8_MASK); break; + case RAA489000_REG_CONTROL10: + WRITE_REG_16(data->control_10_reg, bytes, val, + REG_CONTROL10_MASK); + break; case ISL9238_REG_INFO2: __ASSERT(false, "Write to read-only reg ISL9238_REG_INFO2"); break; @@ -453,7 +465,7 @@ DT_INST_FOREACH_STATUS_OKAY(INIT_ISL923X) #ifdef CONFIG_ZTEST_NEW_API #define ISL923X_EMUL_RESET_RULE_AFTER(n) \ - isl923x_emul_reset(&isl923x_emul_data_##n) + isl923x_emul_reset(&isl923x_emul_data_##n); static void emul_isl923x_reset_before(const struct ztest_unit_test *test, void *data) @@ -461,7 +473,7 @@ static void emul_isl923x_reset_before(const struct ztest_unit_test *test, ARG_UNUSED(test); ARG_UNUSED(data); - DT_INST_FOREACH_STATUS_OKAY(ISL923X_EMUL_RESET_RULE_AFTER); + DT_INST_FOREACH_STATUS_OKAY(ISL923X_EMUL_RESET_RULE_AFTER) } ZTEST_RULE(emul_isl923x_reset, emul_isl923x_reset_before, NULL); #endif /* CONFIG_ZTEST_NEW_API */ diff --git a/zephyr/emul/emul_sm5803.c b/zephyr/emul/emul_sm5803.c new file mode 100644 index 0000000000..39dda70598 --- /dev/null +++ b/zephyr/emul/emul_sm5803.c @@ -0,0 +1,723 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "driver/charger/sm5803.h" +#include "emul/emul_common_i2c.h" +#include "emul/emul_sm5803.h" +#include "emul/emul_stub_device.h" + +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/logging/log.h> +#include <zephyr/ztest.h> + +#define DT_DRV_COMPAT cros_sm5803_emul + +LOG_MODULE_REGISTER(sm5803_emul, CONFIG_SM5803_EMUL_LOG_LEVEL); + +#define VBUS_GPADC_LSB_MV 23.4 +#define ADC_CURRENT_LSB_MA 7.32 +#define ICL_LSB_MA 100 +#define CHG_DET_THRESHOLD_MV 4000 + +struct sm5803_emul_data { + struct i2c_common_emul_data i2c_main; + struct i2c_common_emul_data i2c_chg; + struct i2c_common_emul_data i2c_meas; + struct i2c_common_emul_data i2c_test; + + /** Device ID register value */ + uint8_t device_id; + /** PLATFORM register value */ + uint8_t pmode; + /** Raw value of ISO_CL_REG1 */ + uint8_t input_current_limit; + uint8_t gpadc_conf1, gpadc_conf2; + /** Raw values of INT_EN{1..4} */ + uint8_t int_en[4]; + /** Raw values of INT_REQ_{1..4} */ + uint8_t irq1, irq2, irq3, irq4; + uint16_t vbus; + uint16_t ibus; + uint16_t ibat_avg; + bool clock_slowed; + uint8_t cc_conf1; + /** Raw values of FLOW_REG* */ + uint8_t flow1, flow2, flow3; + /** Raw value of SWITCHER_CONF register */ + uint8_t switcher_conf; + /** Bit 0 (PSYS_DAC_EN) of PSYS_REG1 */ + bool psys_dac_enabled; + /** PHOT_REG1 raw value. */ + uint8_t phot1; + /** Raw values of DISCH_CONF_REG* */ + uint8_t disch_conf5; + /** Raw values of PRE_FAST_CONF_REG{1..6} */ + uint8_t pre_fast_conf[6]; + /** Raw value of GPIO0_CTRL register */ + uint8_t gpio_ctrl; +}; + +struct sm5803_emul_cfg { + const struct i2c_common_emul_cfg i2c_main; + const struct i2c_common_emul_cfg i2c_chg; + const struct i2c_common_emul_cfg i2c_meas; + const struct i2c_common_emul_cfg i2c_test; + struct gpio_dt_spec interrupt_gpio; +}; + +const struct gpio_dt_spec * +sm5803_emul_get_interrupt_gpio(const struct emul *emul) +{ + const struct sm5803_emul_cfg *cfg = emul->cfg; + + return &cfg->interrupt_gpio; +} + +struct i2c_common_emul_data *sm5803_emul_get_i2c_main(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return &data->i2c_main; +} + +struct i2c_common_emul_data *sm5803_emul_get_i2c_chg(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return &data->i2c_chg; +} + +struct i2c_common_emul_data *sm5803_emul_get_i2c_meas(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return &data->i2c_meas; +} + +struct i2c_common_emul_data *sm5803_emul_get_i2c_test(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return &data->i2c_test; +} + +int sm5803_emul_read_chg_reg(const struct emul *emul, uint8_t reg) +{ + struct sm5803_emul_data *data = emul->data; + + switch (reg) { + case SM5803_REG_CHG_ILIM: + return data->input_current_limit; + } + return -ENOTSUP; +} + +int sm5803_emul_get_fast_charge_current_limit(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return data->pre_fast_conf[3] & GENMASK(5, 0); +} + +void sm5803_emul_set_vbus_voltage(const struct emul *emul, uint16_t mv) +{ + struct sm5803_emul_data *data = emul->data; + uint16_t old = (float)data->vbus * VBUS_GPADC_LSB_MV; + + data->vbus = (uint16_t)((float)mv / VBUS_GPADC_LSB_MV); + + if (MIN(mv, old) <= CHG_DET_THRESHOLD_MV && + MAX(mv, old) > CHG_DET_THRESHOLD_MV) { + /* CHG_DET changes state; trigger an interrupt. */ + sm5803_emul_set_irqs(emul, SM5803_INT1_CHG, 0, 0, 0); + } +} + +void sm5803_emul_set_input_current(const struct emul *emul, uint16_t mv) +{ + struct sm5803_emul_data *data = emul->data; + + data->ibus = (uint16_t)((float)mv / ADC_CURRENT_LSB_MA); +} + +void sm5803_emul_set_battery_current(const struct emul *emul, uint16_t ma) +{ + struct sm5803_emul_data *data = emul->data; + + data->ibat_avg = (uint16_t)((float)ma / ADC_CURRENT_LSB_MA); +} + +static void update_interrupt_pin(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + const struct sm5803_emul_cfg *cfg = emul->cfg; + + bool pending = data->irq1 || data->irq2 || data->irq3 || data->irq4; + + /* Pin goes low if any IRQ is pending. */ + gpio_emul_input_set(cfg->interrupt_gpio.port, cfg->interrupt_gpio.pin, + !pending); +} + +void sm5803_emul_set_irqs(const struct emul *emul, uint8_t irq1, uint8_t irq2, + uint8_t irq3, uint8_t irq4) +{ + struct sm5803_emul_data *data = emul->data; + + data->irq1 |= irq1; + data->irq2 |= irq2; + data->irq3 |= irq3; + data->irq4 |= irq4; + update_interrupt_pin(emul); +} + +static bool is_chg_det(struct sm5803_emul_data *data) +{ + /* Assume charger presence is cut off at 4V VBUS. */ + return data->vbus * VBUS_GPADC_LSB_MV > CHG_DET_THRESHOLD_MV; +} + +void sm5803_emul_set_gpadc_conf(const struct emul *emul, uint8_t conf1, + uint8_t conf2) +{ + struct sm5803_emul_data *data = emul->data; + + data->gpadc_conf1 = conf1; + data->gpadc_conf2 = conf2; +} + +void sm5803_emul_get_gpadc_conf(const struct emul *emul, uint8_t *conf1, + uint8_t *conf2) +{ + struct sm5803_emul_data *data = emul->data; + + *conf1 = data->gpadc_conf1; + *conf2 = data->gpadc_conf2; +} + +bool sm5803_emul_is_clock_slowed(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return data->clock_slowed; +} + +uint8_t sm5803_emul_get_cc_config(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return data->cc_conf1; +} + +void sm5803_emul_get_flow_regs(const struct emul *emul, uint8_t *flow1, + uint8_t *flow2, uint8_t *flow3) +{ + struct sm5803_emul_data *data = emul->data; + + *flow1 = data->flow1; + *flow2 = data->flow2; + *flow3 = data->flow3; +} + +void sm5803_emul_set_pmode(const struct emul *emul, uint8_t pmode) +{ + struct sm5803_emul_data *data = emul->data; + + data->pmode = pmode & GENMASK(4, 0); +} + +void sm5803_emul_set_device_id(const struct emul *emul, uint8_t id) +{ + struct sm5803_emul_data *data = emul->data; + + data->device_id = id; +} + +uint8_t sm5803_emul_get_gpio_ctrl(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + + return data->gpio_ctrl; +} + +static void sm5803_emul_reset(const struct emul *emul) +{ + struct sm5803_emul_data *data = emul->data; + const struct sm5803_emul_cfg *cfg = emul->cfg; + +#define RESET_I2C(page) \ + do { \ + struct i2c_common_emul_data *common = &data->i2c_##page; \ + \ + i2c_common_emul_set_read_func(common, NULL, NULL); \ + i2c_common_emul_set_write_func(common, NULL, NULL); \ + i2c_common_emul_set_read_fail_reg( \ + common, I2C_COMMON_EMUL_NO_FAIL_REG); \ + i2c_common_emul_set_write_fail_reg( \ + common, I2C_COMMON_EMUL_NO_FAIL_REG); \ + } while (0) + + RESET_I2C(main); + RESET_I2C(chg); + RESET_I2C(meas); + RESET_I2C(test); + + /* Registers set to chip reset values */ + data->device_id = 3; + data->pmode = 0x0b; + data->input_current_limit = 4; + data->gpadc_conf1 = 0xf3; + data->gpadc_conf2 = 0x01; + memset(data->int_en, 0, sizeof(data->int_en)); + data->irq1 = data->irq2 = data->irq3 = data->irq4 = 0; + data->vbus = 0; + data->ibus = 0; + data->ibat_avg = 0; + data->clock_slowed = false; + data->cc_conf1 = 0x09; + data->flow1 = 0x01; + data->flow2 = 0; + data->flow3 = 0; + data->switcher_conf = 1; + data->psys_dac_enabled = true; + data->phot1 = 0x20; + data->disch_conf5 = 0; + memset(data->pre_fast_conf, 0, sizeof(data->pre_fast_conf)); + data->gpio_ctrl = 0x04; + + /* Interrupt pin deasserted */ + gpio_emul_input_set(cfg->interrupt_gpio.port, cfg->interrupt_gpio.pin, + 1); +} + +static int sm5803_main_read_byte(const struct emul *target, int reg, + uint8_t *val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_CHIP_ID: + *val = data->device_id; + return 0; + case SM5803_REG_STATUS1: + *val = is_chg_det(data) ? SM5803_STATUS1_CHG_DET : 0; + return 0; + case SM5803_REG_INT1_REQ: + *val = data->irq1; + /* register clears on read */ + data->irq1 = 0; + update_interrupt_pin(target); + return 0; + case SM5803_REG_INT2_REQ: + *val = data->irq2; + /* register clears on read */ + data->irq2 = 0; + update_interrupt_pin(target); + return 0; + case SM5803_REG_INT3_REQ: + *val = data->irq3; + /* register clears on read */ + data->irq3 = 0; + update_interrupt_pin(target); + return 0; + case SM5803_REG_INT4_REQ: + *val = data->irq4; + /* register clears on read */ + data->irq4 = 0; + update_interrupt_pin(target); + return 0; + case SM5803_REG_INT1_EN: + case SM5803_REG_INT2_EN: + case SM5803_REG_INT3_EN: + case SM5803_REG_INT4_EN: + *val = data->int_en[reg - SM5803_REG_INT1_EN]; + return 0; + case SM5803_REG_PLATFORM: + *val = data->pmode; + return 0; + case SM5803_REG_REFERENCE: + /* Driver never actually uses LDO PGOOD bits. */ + *val = 0; + return 0; + case SM5803_REG_CLOCK_SEL: + *val = data->clock_slowed ? 1 : 0; + return 0; + case SM5803_REG_GPIO0_CTRL: + *val = data->gpio_ctrl; + return 0; + } + LOG_INF("SM5803 main page read of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_main_write_byte(const struct emul *target, int reg, + uint8_t val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_CLOCK_SEL: + data->clock_slowed = (val & 1) == 1; + return 0; + case SM5803_REG_GPIO0_CTRL: + data->gpio_ctrl = val & (GENMASK(7, 6) | GENMASK(2, 0)); + return 0; + } + LOG_INF("SM5803 main page write of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_chg_read_byte(const struct emul *target, int reg, + uint8_t *val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_CC_CONFIG1: + *val = data->cc_conf1; + return 0; + case SM5803_REG_INT1_EN: + case SM5803_REG_INT2_EN: + case SM5803_REG_INT3_EN: + case SM5803_REG_INT4_EN: + *val = data->int_en[reg - SM5803_REG_INT1_EN]; + return 0; + case SM5803_REG_FLOW1: + *val = data->flow1; + return 0; + case SM5803_REG_FLOW2: + *val = data->flow2; + return 0; + case SM5803_REG_FLOW3: + *val = data->flow3; + return 0; + case SM5803_REG_SWITCHER_CONF: + *val = data->switcher_conf; + return 0; + case SM5803_REG_CHG_ILIM: + *val = data->input_current_limit; + return 0; + case SM5803_REG_DISCH_CONF5: + *val = data->disch_conf5; + return 0; + case SM5803_REG_PRE_FAST_CONF_REG1: + case SM5803_REG_PRE_FAST_CONF_REG1 + 1: + case SM5803_REG_PRE_FAST_CONF_REG1 + 2: + case SM5803_REG_PRE_FAST_CONF_REG1 + 3: + case SM5803_REG_PRE_FAST_CONF_REG1 + 4: + case SM5803_REG_PRE_FAST_CONF_REG1 + 5: + *val = data->pre_fast_conf[reg - SM5803_REG_PRE_FAST_CONF_REG1]; + return 0; + case SM5803_REG_LOG2: + *val = ((data->ibus * ADC_CURRENT_LSB_MA) > + (data->input_current_limit * ICL_LSB_MA)) + << 1; + return 0; + case SM5803_REG_PHOT1: + *val = data->phot1; + return 0; + } + LOG_INF("SM5803 charger page read of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_chg_write_byte(const struct emul *target, int reg, + uint8_t val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_CC_CONFIG1: + data->cc_conf1 = val; + return 0; + case SM5803_REG_FLOW1: + data->flow1 = val & 0x8f; + return 0; + case SM5803_REG_FLOW2: + data->flow2 = val; + return 0; + case SM5803_REG_FLOW3: + data->flow3 = val & GENMASK(3, 0); + return 0; + case SM5803_REG_SWITCHER_CONF: + data->switcher_conf = val & 0xc1; + return 0; + case SM5803_REG_CHG_ILIM: + data->input_current_limit = val & GENMASK(4, 0); + return 0; + case SM5803_REG_PRE_FAST_CONF_REG1: + case SM5803_REG_PRE_FAST_CONF_REG1 + 1: + case SM5803_REG_PRE_FAST_CONF_REG1 + 2: + case SM5803_REG_PRE_FAST_CONF_REG1 + 3: + case SM5803_REG_PRE_FAST_CONF_REG1 + 4: + case SM5803_REG_PRE_FAST_CONF_REG1 + 5: + data->pre_fast_conf[reg - SM5803_REG_PRE_FAST_CONF_REG1] = val; + return 0; + case SM5803_REG_PHOT1: + data->phot1 = val; + return 0; + case SM5803_REG_DISCH_CONF5: + data->disch_conf5 = val; + return 0; + } + LOG_INF("SM5803 charger page write of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_meas_read_byte(const struct emul *target, int reg, + uint8_t *val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_GPADC_CONFIG1: + *val = data->gpadc_conf1; + return 0; + case SM5803_REG_GPADC_CONFIG2: + *val = data->gpadc_conf2; + return 0; + case SM5803_REG_PSYS1: + *val = 0x04 | data->psys_dac_enabled; + return 0; + case SM5803_REG_IBUS_CHG_MEAS_MSB: + *val = (data->ibus & GENMASK(9, 2)) >> 2; + return 0; + case SM5803_REG_IBUS_CHG_MEAS_LSB: + *val = data->ibus & GENMASK(1, 0); + return 0; + case SM5803_REG_VBUS_MEAS_MSB: + *val = (data->vbus & GENMASK(9, 2)) >> 2; + return 0; + case SM5803_REG_VBUS_MEAS_LSB: + *val = (is_chg_det(data) ? SM5803_VBUS_MEAS_CHG_DET : 0) | + (data->vbus & GENMASK(1, 0)); + return 0; + case SM5803_REG_IBAT_CHG_AVG_MEAS_MSB: + *val = (data->ibat_avg & GENMASK(9, 2)) >> 2; + return 0; + case SM5803_REG_IBAT_CHG_AVG_MEAS_LSB: + *val = data->ibat_avg & GENMASK(1, 0); + return 0; + } + LOG_INF("SM5803 meas page read of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_meas_write_byte(const struct emul *target, int reg, + uint8_t val, int bytes) +{ + struct sm5803_emul_data *data = target->data; + + switch (reg) { + case SM5803_REG_GPADC_CONFIG1: + data->gpadc_conf1 = val; + return 0; + case SM5803_REG_GPADC_CONFIG2: + data->gpadc_conf2 = val; + return 0; + } + + LOG_INF("SM5803 meas page write of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_test_read_byte(const struct emul *target, int reg, + uint8_t *val, int bytes) +{ + switch (reg) { + case 0x8e: /* Mystery register used for init on chip ID 2 */ + *val = 0; + return 0; + } + LOG_INF("SM5803 test page read of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_test_write_byte(const struct emul *target, int reg, + uint8_t val, int bytes) +{ + switch (reg) { + case 0x8e: /* Mystery register used for init on chip ID 2 */ + return 0; + } + LOG_INF("SM5803 test page write of register %#x unhandled", reg); + return -ENOTSUP; +} + +static int sm5803_emul_i2c_transfer(const struct emul *target, + struct i2c_msg *msgs, int num_msgs, + int addr) +{ + struct sm5803_emul_data *data = target->data; + const struct sm5803_emul_cfg *cfg = target->cfg; + + if (addr == cfg->i2c_main.addr) { + return i2c_common_emul_transfer_workhorse(target, + &data->i2c_main, + &cfg->i2c_main, msgs, + num_msgs, addr); + } else if (addr == cfg->i2c_chg.addr) { + return i2c_common_emul_transfer_workhorse(target, + &data->i2c_chg, + &cfg->i2c_chg, msgs, + num_msgs, addr); + } else if (addr == cfg->i2c_meas.addr) { + return i2c_common_emul_transfer_workhorse(target, + &data->i2c_meas, + &cfg->i2c_meas, msgs, + num_msgs, addr); + } else if (addr == cfg->i2c_test.addr) { + return i2c_common_emul_transfer_workhorse(target, + &data->i2c_test, + &cfg->i2c_test, msgs, + num_msgs, addr); + } + LOG_ERR("I2C transaction for address %#x not supported by SM5803", + addr); + return -ENOTSUP; +} + +const static struct i2c_emul_api sm5803_emul_api = { + .transfer = sm5803_emul_i2c_transfer, +}; + +static int sm5803_emul_init(const struct emul *emul, + const struct device *parent) +{ + struct sm5803_emul_data *data = emul->data; + struct i2c_common_emul_data *const i2c_pages[] = { + &data->i2c_chg, + &data->i2c_main, + &data->i2c_meas, + &data->i2c_test, + }; + + for (int i = 0; i < ARRAY_SIZE(i2c_pages); i++) { + int rv = i2c_emul_register(parent, &i2c_pages[i]->emul); + + if (rv != 0) { + k_oops(); + } + i2c_common_emul_init(i2c_pages[i]); + } + + sm5803_emul_reset(emul); + + return 0; +} + +#define INIT_SM5803(n) \ + const static struct sm5803_emul_cfg sm5803_emul_cfg_##n; \ + static struct sm5803_emul_data sm5803_emul_data_##n = { \ + .i2c_main = { \ + .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .emul = \ + (struct i2c_emul){ \ + .target = EMUL_DT_GET( \ + DT_DRV_INST(n)), \ + .api = &sm5803_emul_api, \ + .addr = DT_INST_PROP( \ + n, main_addr), \ + }, \ + .cfg = &sm5803_emul_cfg_##n.i2c_main, \ + .read_byte = &sm5803_main_read_byte, \ + .write_byte = &sm5803_main_write_byte, \ + }, \ + .i2c_chg = { \ + .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .emul = \ + (struct i2c_emul){ \ + .target = EMUL_DT_GET( \ + DT_DRV_INST(n)), \ + .api = &sm5803_emul_api, \ + .addr = DT_INST_REG_ADDR(n), \ + }, \ + .cfg = &sm5803_emul_cfg_##n.i2c_chg, \ + .read_byte = &sm5803_chg_read_byte, \ + .write_byte = &sm5803_chg_write_byte, \ + }, \ + .i2c_meas = { \ + .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .emul = \ + (struct i2c_emul){ \ + .target = EMUL_DT_GET( \ + DT_DRV_INST(n)), \ + .api = &sm5803_emul_api, \ + .addr = DT_INST_PROP( \ + n, meas_addr), \ + }, \ + .cfg = &sm5803_emul_cfg_##n.i2c_meas, \ + .read_byte = &sm5803_meas_read_byte, \ + .write_byte = &sm5803_meas_write_byte, \ + }, \ + .i2c_test = { \ + .i2c = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .emul = \ + (struct i2c_emul){ \ + .target = EMUL_DT_GET( \ + DT_DRV_INST(n)), \ + .api = &sm5803_emul_api, \ + .addr = DT_INST_PROP( \ + n, test_addr), \ + }, \ + .cfg = &sm5803_emul_cfg_##n.i2c_test, \ + .read_byte = &sm5803_test_read_byte, \ + .write_byte = &sm5803_test_write_byte, \ + }, \ + }; \ + const static struct sm5803_emul_cfg sm5803_emul_cfg_##n = { \ + .i2c_main = \ + (struct i2c_common_emul_cfg){ \ + .dev_label = \ + DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .addr = DT_INST_PROP(n, main_addr), \ + .data = &sm5803_emul_data_##n.i2c_main, \ + }, \ + .i2c_chg = \ + (struct i2c_common_emul_cfg){ \ + .dev_label = \ + DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .addr = DT_INST_REG_ADDR(n), \ + .data = &sm5803_emul_data_##n.i2c_chg, \ + }, \ + .i2c_meas = \ + (struct i2c_common_emul_cfg){ \ + .dev_label = \ + DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .addr = DT_INST_PROP(n, meas_addr), \ + .data = &sm5803_emul_data_##n.i2c_meas, \ + }, \ + .i2c_test = \ + (struct i2c_common_emul_cfg){ \ + .dev_label = \ + DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .addr = DT_INST_PROP(n, test_addr), \ + .data = &sm5803_emul_data_##n.i2c_test, \ + }, \ + .interrupt_gpio = { \ + .port = DEVICE_DT_GET(DT_GPIO_CTLR(DT_DRV_INST(n), \ + interrupt_gpios)), \ + .pin = DT_INST_GPIO_PIN(n, interrupt_gpios), \ + .dt_flags = (gpio_dt_flags_t) \ + DT_INST_GPIO_FLAGS(n, interrupt_gpios), \ + }, \ + }; \ + EMUL_DT_INST_DEFINE(n, sm5803_emul_init, &sm5803_emul_data_##n, \ + &sm5803_emul_cfg_##n, &sm5803_emul_api, NULL); + +DT_INST_FOREACH_STATUS_OKAY(INIT_SM5803) +DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE) + +static void sm5803_emul_reset_before(const struct ztest_unit_test *test, + void *data) +{ + ARG_UNUSED(test); + ARG_UNUSED(data); + +#define SM5803_EMUL_RESET_RULE_BEFORE(n) \ + sm5803_emul_reset(EMUL_DT_GET(DT_DRV_INST(n))); + + DT_INST_FOREACH_STATUS_OKAY(SM5803_EMUL_RESET_RULE_BEFORE); +} +ZTEST_RULE(sm5803_emul_reset, sm5803_emul_reset_before, NULL); diff --git a/zephyr/emul/retimer/emul_anx7483.c b/zephyr/emul/retimer/emul_anx7483.c index 37a34b25cf..13c6e39d43 100644 --- a/zephyr/emul/retimer/emul_anx7483.c +++ b/zephyr/emul/retimer/emul_anx7483.c @@ -292,6 +292,37 @@ int anx7483_emul_set_reg_reserved_mask(const struct emul *emul, int r, return 0; } +int anx7483_emul_get_eq(const struct emul *emul, enum anx7483_tune_pin pin, + enum anx7483_eq_setting *eq) +{ + int reg; + int rv; + + if (pin == ANX7483_PIN_UTX1) + reg = ANX7483_UTX1_PORT_CFG0_REG; + else if (pin == ANX7483_PIN_UTX2) + reg = ANX7483_UTX2_PORT_CFG0_REG; + else if (pin == ANX7483_PIN_URX1) + reg = ANX7483_URX1_PORT_CFG0_REG; + else if (pin == ANX7483_PIN_URX2) + reg = ANX7483_URX2_PORT_CFG0_REG; + else if (pin == ANX7483_PIN_DRX1) + reg = ANX7483_DRX1_PORT_CFG0_REG; + else if (pin == ANX7483_PIN_DRX2) + reg = ANX7483_DRX2_PORT_CFG0_REG; + else + return EC_ERROR_INVAL; + + rv = anx7483_emul_get_reg(emul, reg, (uint8_t *)eq); + if (rv) + return rv; + + *eq &= ANX7483_CFG0_EQ_MASK; + *eq >>= ANX7483_CFG0_EQ_SHIFT; + + return EC_SUCCESS; +} + void anx7483_emul_reset(const struct emul *emul) { struct anx7483_emul_data *anx7483 = emul->data; @@ -306,6 +337,25 @@ void anx7483_emul_reset(const struct emul *emul) anx7483->regs[i].def); } +int anx7483_emul_validate_tuning(const struct emul *emul, + const struct anx7483_tuning_set *tuning, + size_t tuning_count) +{ + uint8_t val; + int rv; + + for (size_t i = 0; i < tuning_count; i++) { + rv = anx7483_emul_get_reg(emul, tuning[i].addr, &val); + if (rv) + return rv; + + if (val != tuning[i].value) + return 1; + } + + return 0; +} + static int anx7483_emul_init(const struct emul *emul, const struct device *parent) { diff --git a/zephyr/firmware_builder.py b/zephyr/firmware_builder.py index a760855cc0..04f3fba650 100755 --- a/zephyr/firmware_builder.py +++ b/zephyr/firmware_builder.py @@ -34,6 +34,7 @@ SPECIAL_BOARDS = [ "kingler", "rex", "geralt", + "myst", # Nissa variants "nereid", "nivviks", diff --git a/zephyr/include/drivers/cros_kb_raw.h b/zephyr/include/drivers/cros_kb_raw.h index 7b9255bb9f..ba1434fb04 100644 --- a/zephyr/include/drivers/cros_kb_raw.h +++ b/zephyr/include/drivers/cros_kb_raw.h @@ -19,6 +19,12 @@ * the Zephyr kscan API. */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 27 + #ifndef ZEPHYR_INCLUDE_DRIVERS_CROS_KB_RAW_H_ #define ZEPHYR_INCLUDE_DRIVERS_CROS_KB_RAW_H_ diff --git a/zephyr/include/emul/emul_sm5803.h b/zephyr/include/emul/emul_sm5803.h new file mode 100644 index 0000000000..006fe1d0c7 --- /dev/null +++ b/zephyr/include/emul/emul_sm5803.h @@ -0,0 +1,77 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/drivers/emul.h> +#include <zephyr/drivers/gpio.h> + +const struct gpio_dt_spec * +sm5803_emul_get_interrupt_gpio(const struct emul *emul); +struct i2c_common_emul_data *sm5803_emul_get_i2c_main(const struct emul *emul); +struct i2c_common_emul_data *sm5803_emul_get_i2c_chg(const struct emul *emul); +struct i2c_common_emul_data *sm5803_emul_get_i2c_meas(const struct emul *emul); +struct i2c_common_emul_data *sm5803_emul_get_i2c_test(const struct emul *emul); + +/** + * Read the value of a charger page register, by address. + * + * This is useful to verify that a user has written an expected value to a + * register, without depending on the user's corresponding getter function. + * + * @return negative value on error, otherwise 8-bit register value. + */ +int sm5803_emul_read_chg_reg(const struct emul *emul, uint8_t reg); + +/** + * Set the reported VBUS voltage, in mV. + * + * If the VBUS voltage crosses the charger detection threshold as a result, + * a CHG_DET interrupt will automatically be triggered. + */ +void sm5803_emul_set_vbus_voltage(const struct emul *emul, uint16_t mv); + +/** Set the reported input current (from VBUS), in mA. */ +void sm5803_emul_set_input_current(const struct emul *emul, uint16_t mv); + +/** Set the reported battery charge current, in mA. */ +void sm5803_emul_set_battery_current(const struct emul *emul, uint16_t ma); + +/** Set the reported device ID (default 3). */ +void sm5803_emul_set_device_id(const struct emul *emul, uint8_t id); + +/** Set the platform ID as configured in hardware by the PMODE resistor. */ +void sm5803_emul_set_pmode(const struct emul *emul, uint8_t pmode); + +/** Get the register value of ICHG_FAST_SET; the fast charge current limit. */ +int sm5803_emul_get_fast_charge_current_limit(const struct emul *emul); + +/** Get the values of the GPADC_CONFIG_1 and GPADC_CONFIG_2 registers. */ +void sm5803_emul_get_gpadc_conf(const struct emul *emul, uint8_t *conf1, + uint8_t *conf2); + +/** Set the GPADC enable bits in GPADC_CONFIG_1 and GPADC_CONFIG_2 registers. */ +void sm5803_emul_set_gpadc_conf(const struct emul *emul, uint8_t conf1, + uint8_t conf2); + +/** Return whether the main clock is slowed (CLOCK_SEL:LOW_POWER_CLOCK_EN). */ +bool sm5803_emul_is_clock_slowed(const struct emul *emul); + +/** Get the value of the CC_CONFIG_1 register. */ +uint8_t sm5803_emul_get_cc_config(const struct emul *emul); + +/** Get the values of the FLOW1..FLOW3 registers. */ +void sm5803_emul_get_flow_regs(const struct emul *emul, uint8_t *flow1, + uint8_t *flow2, uint8_t *flow3); + +/** + * Set the INT_REQ_* registers to indicate pending interrupts. + * + * This does not clear pending IRQs; it only asserts them. IRQs are cleared only + * when the interrupt status registers are read. + */ +void sm5803_emul_set_irqs(const struct emul *emul, uint8_t irq1, uint8_t irq2, + uint8_t irq3, uint8_t irq4); + +/** Get the value of the GPIO_CTRL_1 register, which controls GPIO0. */ +uint8_t sm5803_emul_get_gpio_ctrl(const struct emul *emul); diff --git a/zephyr/include/emul/retimer/emul_anx7483.h b/zephyr/include/emul/retimer/emul_anx7483.h index fe528e2e97..f2b7fe32d4 100644 --- a/zephyr/include/emul/retimer/emul_anx7483.h +++ b/zephyr/include/emul/retimer/emul_anx7483.h @@ -7,6 +7,7 @@ #define __EMUL_ANX7483_H #include "driver/retimer/anx7483.h" +#include "driver/retimer/anx7483_public.h" #include "emul/emul_common_i2c.h" #include <zephyr/device.h> @@ -123,6 +124,13 @@ int anx7483_emul_set_reg(const struct emul *emul, int r, uint8_t val); int anx7483_emul_set_reg_reserved_mask(const struct emul *emul, int r, uint8_t mask, uint8_t def); +int anx7483_emul_get_eq(const struct emul *emul, enum anx7483_tune_pin pin, + enum anx7483_eq_setting *eq); + void anx7483_emul_reset(const struct emul *emul); +int anx7483_emul_validate_tuning(const struct emul *emul, + const struct anx7483_tuning_set *tuning, + size_t tuning_count); + #endif /* __EMUL_ANX7483_H */ diff --git a/zephyr/program/corsola/ite_led.dtsi b/zephyr/program/corsola/ite_led.dtsi index 582af0b092..5dd571008e 100644 --- a/zephyr/program/corsola/ite_led.dtsi +++ b/zephyr/program/corsola/ite_led.dtsi @@ -109,42 +109,42 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_power_off: color-power-off { - led-color = "LED_OFF"; + power_led: power-led { led-id = "EC_LED_ID_POWER_LED"; led-pwms = <&led_power_white>; - led-values = <0>; - }; - color_power_white: color-power-white { - led-color = "LED_WHITE"; - br-color = "EC_LED_COLOR_WHITE"; - led-id = "EC_LED_ID_POWER_LED"; - led-pwms = <&led_power_white>; - led-values = <100>; - }; + color_power_off: color-power-off { + led-color = "LED_OFF"; + led-values = <0>; + }; - color_battery_off: color-battery-off { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_BATTERY_LED"; - led-pwms = <&led_battery_amber &led_battery_white>; - led-values = <0 0>; + color_power_white: color-power-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <100>; + }; }; - color_battery_amber: color-battery-amber { - led-color = "LED_AMBER"; - br-color = "EC_LED_COLOR_AMBER"; + battery_led: batter-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&led_battery_amber &led_battery_white>; - led-values = <100 0>; - }; - color_battery_white: color-battery-white { - led-color = "LED_WHITE"; - br-color = "EC_LED_COLOR_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - led-pwms = <&led_battery_amber &led_battery_white>; - led-values = <0 100>; + color_battery_off: color-battery-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + + color_battery_amber: color-battery-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_battery_white: color-battery-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/corsola/magikarp/project.overlay b/zephyr/program/corsola/magikarp/project.overlay index 48c823fa0e..3628f6770d 100644 --- a/zephyr/program/corsola/magikarp/project.overlay +++ b/zephyr/program/corsola/magikarp/project.overlay @@ -338,12 +338,15 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - /* Overwrite Power LED white to off */ - color_power_white: color-power-white { - led-color = "LED_WHITE"; + power_led: power-led { led-id = "EC_LED_ID_POWER_LED"; led-pwms = <&led_power_white>; - led-values = <0>; + + /* Overwrite Power LED white to off */ + color_power_white: color-power-white { + led-color = "LED_WHITE"; + led-values = <0>; + }; }; }; diff --git a/zephyr/program/corsola/src/board_chipset.c b/zephyr/program/corsola/src/board_chipset.c index 54cc7116fd..6f4585c180 100644 --- a/zephyr/program/corsola/src/board_chipset.c +++ b/zephyr/program/corsola/src/board_chipset.c @@ -34,7 +34,7 @@ static void board_backlight_handler(struct ap_power_ev_callback *cb, gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_bl_en_od), value); } -static int install_backlight_handler(const struct device *unused) +static int install_backlight_handler(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/program/corsola/src/ite_hooks.c b/zephyr/program/corsola/src/ite_hooks.c index 5564ea1660..817c25c0dc 100644 --- a/zephyr/program/corsola/src/ite_hooks.c +++ b/zephyr/program/corsola/src/ite_hooks.c @@ -65,7 +65,7 @@ static void board_suspend_handler(struct ap_power_ev_callback *cb, gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_5v_usm), value); } -static int install_suspend_handler(const struct device *unused) +static int install_suspend_handler(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/program/corsola/src/ite_usb_pd_policy.c b/zephyr/program/corsola/src/ite_usb_pd_policy.c index 71ac98d14a..c4151f94f0 100644 --- a/zephyr/program/corsola/src/ite_usb_pd_policy.c +++ b/zephyr/program/corsola/src/ite_usb_pd_policy.c @@ -39,48 +39,6 @@ int pd_snk_is_vbus_provided(int port) return vbus; } -void pd_power_supply_reset(int port) -{ - int prev_en; - - prev_en = ppc_is_sourcing_vbus(port); - - /* Disable VBUS. */ - ppc_vbus_source_enable(port, 0); - - /* Enable discharge if we were previously sourcing 5V */ - if (prev_en) { - pd_set_vbus_discharge(port, 1); - } - - /* Notify host of power info change. */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); -} - -int pd_set_power_supply_ready(int port) -{ - int rv; - - /* Disable charging. */ - rv = ppc_vbus_sink_enable(port, 0); - if (rv) { - return rv; - } - - pd_set_vbus_discharge(port, 0); - - /* Provide Vbus. */ - rv = ppc_vbus_source_enable(port, 1); - if (rv) { - return rv; - } - - /* Notify host of power info change. */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); - - return EC_SUCCESS; -} - int board_vbus_source_enabled(int port) { return ppc_is_sourcing_vbus(port); diff --git a/zephyr/program/corsola/src/npcx_usb_pd_policy.c b/zephyr/program/corsola/src/npcx_usb_pd_policy.c index 65be43807b..39c780bddd 100644 --- a/zephyr/program/corsola/src/npcx_usb_pd_policy.c +++ b/zephyr/program/corsola/src/npcx_usb_pd_policy.c @@ -12,56 +12,6 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ##args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ##args) -void pd_power_supply_reset(int port) -{ - int prev_en; - - prev_en = ppc_is_sourcing_vbus(port); - - if (port == USBC_PORT_C1) { - rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 0); - } - - /* Disable VBUS. */ - ppc_vbus_source_enable(port, 0); - - /* Enable discharge if we were previously sourcing 5V */ - if (prev_en) { - pd_set_vbus_discharge(port, 1); - } - - /* Notify host of power info change. */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); -} - -int pd_set_power_supply_ready(int port) -{ - int rv; - - /* Disable charging. */ - rv = ppc_vbus_sink_enable(port, 0); - if (rv) { - return rv; - } - - pd_set_vbus_discharge(port, 0); - - /* Provide Vbus. */ - if (port == USBC_PORT_C1) { - rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 1); - } - - rv = ppc_vbus_source_enable(port, 1); - if (rv) { - return rv; - } - - /* Notify host of power info change. */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); - - return EC_SUCCESS; -} - int pd_snk_is_vbus_provided(int port) { /* TODO: use ADC? */ diff --git a/zephyr/program/corsola/src/usb_pd_policy.c b/zephyr/program/corsola/src/usb_pd_policy.c index a7fa22fa41..06750149b9 100644 --- a/zephyr/program/corsola/src/usb_pd_policy.c +++ b/zephyr/program/corsola/src/usb_pd_policy.c @@ -6,11 +6,13 @@ #include "baseboard_usbc_config.h" #include "chipset.h" #include "console.h" +#include "driver/tcpm/rt1718s.h" #include "hooks.h" #include "timer.h" #include "typec_control.h" #include "usb_mux.h" #include "usb_pd.h" +#include "usbc_ppc.h" #define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) @@ -220,3 +222,49 @@ __override int svdm_dp_attention(int port, uint32_t *payload) /* ack */ return 1; } + +void pd_power_supply_reset(int port) +{ + int prev_en; + + prev_en = ppc_is_sourcing_vbus(port); + +#ifdef CONFIG_USB_PD_TCPM_RT1718S + if (port == USBC_PORT_C1) { + rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 0); + } +#endif + + /* Disable VBUS. */ + ppc_vbus_source_enable(port, 0); + + /* Enable discharge if we were previously sourcing 5V */ + if (prev_en) { + pd_set_vbus_discharge(port, 1); + } + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + /* Disable charging. */ + RETURN_ERROR(ppc_vbus_sink_enable(port, 0)); + + pd_set_vbus_discharge(port, 0); + +#ifdef CONFIG_USB_PD_TCPM_RT1718S + /* Provide Vbus. */ + if (port == USBC_PORT_C1) { + rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 1); + } +#endif + + RETURN_ERROR(ppc_vbus_source_enable(port, 1)); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} diff --git a/zephyr/program/corsola/tentacruel/project.overlay b/zephyr/program/corsola/tentacruel/project.overlay index 370e16e8d1..79e8f4a05b 100644 --- a/zephyr/program/corsola/tentacruel/project.overlay +++ b/zephyr/program/corsola/tentacruel/project.overlay @@ -366,24 +366,15 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - /* Overwrite Power LED white to off */ - color_power_white: color-power-white { - led-color = "LED_WHITE"; + power_led: power-led { led-id = "EC_LED_ID_POWER_LED"; led-pwms = <&led_power_white>; - led-values = <0>; - }; - }; - - pwm-led-pins { - compatible = "cros-ec,pwm-led-pins"; - /* Overwrite Power LED white to off */ - color_power_white: color-power-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_POWER_LED"; - led-pwms = <&led_power_white>; - led-values = <0>; + /* Overwrite Power LED white to off */ + color_power_white: color-power-white { + led-color = "LED_WHITE"; + led-values = <0>; + }; }; }; diff --git a/zephyr/program/corsola/voltorb/project.overlay b/zephyr/program/corsola/voltorb/project.overlay index 3ab5badcb3..7ae230a47e 100644 --- a/zephyr/program/corsola/voltorb/project.overlay +++ b/zephyr/program/corsola/voltorb/project.overlay @@ -185,27 +185,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&led_amber &led_blue>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&led_amber &led_blue>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_blue: color_blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pwms = <&led_amber &led_blue>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_blue: color_blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 100>; + }; }; }; @@ -287,4 +286,3 @@ &adc0_chan3_gp42 &adc0_chan8_gpf1>; }; - diff --git a/zephyr/program/geralt/geralt/led.dtsi b/zephyr/program/geralt/geralt/led.dtsi index 905d5f13dd..f88fd99d76 100644 --- a/zephyr/program/geralt/geralt/led.dtsi +++ b/zephyr/program/geralt/geralt/led.dtsi @@ -66,30 +66,27 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_power_off: color-power-off { - led-color = "LED_OFF"; + power_led: power-led { led-id = "EC_LED_ID_POWER_LED"; led-pwms = <&led_power_red &led_power_green &led_power_blue>; - led-values = <0 0 0>; - }; - color_power_green: color-power-green { - led-color = "LED_GREEN"; - br-color = "EC_LED_COLOR_GREEN"; - led-id = "EC_LED_ID_POWER_LED"; - led-pwms = <&led_power_red &led_power_green - &led_power_blue>; - led-values = <0 100 0>; - }; + color_power_off: color-power-off { + led-color = "LED_OFF"; + led-values = <0 0 0>; + }; - color_power_blue: color-power-blue { - led-color = "LED_BLUE"; - br-color = "EC_LED_COLOR_BLUE"; - led-id = "EC_LED_ID_POWER_LED"; - led-pwms = <&led_power_red &led_power_green - &led_power_blue>; - led-values = <0 0 100>; + color_power_green: color-power-green { + led-color = "LED_GREEN"; + br-color = "EC_LED_COLOR_GREEN"; + led-values = <0 100 0>; + }; + + color_power_blue: color-power-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 0 100>; + }; }; }; }; diff --git a/zephyr/program/geralt/src/backlight.c b/zephyr/program/geralt/src/backlight.c index 8234191d22..cf03df4cd2 100644 --- a/zephyr/program/geralt/src/backlight.c +++ b/zephyr/program/geralt/src/backlight.c @@ -32,7 +32,7 @@ static void board_backlight_handler(struct ap_power_ev_callback *cb, gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_bl_en_od), value); } -static int install_backlight_handler(const struct device *unused) +static int install_backlight_handler(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/program/geralt/src/base_detect.c b/zephyr/program/geralt/src/base_detect.c index feb01337ce..205b79a695 100644 --- a/zephyr/program/geralt/src/base_detect.c +++ b/zephyr/program/geralt/src/base_detect.c @@ -87,7 +87,7 @@ static void base_startup_hook(struct ap_power_ev_callback *cb, } } -static int base_init(const struct device *unused) +static int base_init(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/program/geralt/src/hooks.c b/zephyr/program/geralt/src/hooks.c index fd106732ae..c5c769e8f9 100644 --- a/zephyr/program/geralt/src/hooks.c +++ b/zephyr/program/geralt/src/hooks.c @@ -74,7 +74,7 @@ static void board_suspend_handler(struct ap_power_ev_callback *cb, gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_en_5v_usm), value); } -static int install_suspend_handler(const struct device *unused) +static int install_suspend_handler(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/program/geralt/src/ppc.c b/zephyr/program/geralt/src/ppc.c index e69aa2171c..00efa23976 100644 --- a/zephyr/program/geralt/src/ppc.c +++ b/zephyr/program/geralt/src/ppc.c @@ -8,7 +8,7 @@ #include <zephyr/init.h> -static int board_usbc_init(const struct device *unused) +static int board_usbc_init(void) { /* Enable PPC interrupts. */ gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_ppc_bc12)); diff --git a/zephyr/program/herobrine/evoker/led_pins.dtsi b/zephyr/program/herobrine/evoker/led_pins.dtsi index 8365691f4d..3b739c4ce3 100644 --- a/zephyr/program/herobrine/evoker/led_pins.dtsi +++ b/zephyr/program/herobrine/evoker/led_pins.dtsi @@ -7,58 +7,50 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_power_off: color-power-off { - led-color = "LED_OFF"; + power_led: power-led { led-id = "EC_LED_ID_POWER_LED"; led-pins = <&gpio_ec_chg_led_w_c1>; - led-values = <0>; - }; - color_power_white: color-power-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_POWER_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_ec_chg_led_w_c1>; - led-values = <1>; - }; + color_power_off: color-power-off { + led-color = "LED_OFF"; + led-values = <0>; + }; - color_battery_off: color-battery-off { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_BATTERY_LED"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0 - &gpio_ec_chg_led_r_c0>; - led-values = <0 0 0>; + color_power_white: color-power-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <1>; + }; }; - color_battery_amber: color-battery-amber { - led-color = "LED_AMBER"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; led-pins = <&gpio_ec_chg_led_y_c0 &gpio_ec_chg_led_w_c0 &gpio_ec_chg_led_r_c0>; - led-values = <1 0 0>; - }; - color_battery_white: color-battery-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0 - &gpio_ec_chg_led_r_c0>; - led-values = <0 1 0>; - }; + color_battery_off: color-battery-off { + led-color = "LED_OFF"; + led-values = <0 0 0>; + }; - color_battery_red: color-battery-red { - led-color = "LED_RED"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_RED"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0 - &gpio_ec_chg_led_r_c0>; - led-values = <0 0 1>; + color_battery_amber: color-battery-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <1 0 0>; + }; + + color_battery_white: color-battery-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 1 0>; + }; + + color_battery_red: color-battery-red { + led-color = "LED_RED"; + br-color = "EC_LED_COLOR_RED"; + led-values = <0 0 1>; + }; }; }; }; diff --git a/zephyr/program/herobrine/herobrine/led_pins.dtsi b/zephyr/program/herobrine/herobrine/led_pins.dtsi index 23a0271e69..f3580fc491 100644 --- a/zephyr/program/herobrine/herobrine/led_pins.dtsi +++ b/zephyr/program/herobrine/herobrine/led_pins.dtsi @@ -7,56 +7,52 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off_left: color-off-left { - led-color = "LED_OFF"; + left_led: left-led { led-id = "EC_LED_ID_LEFT_LED"; led-pins = <&gpio_ec_chg_led_y_c1 &gpio_ec_chg_led_w_c1>; - led-values = <0 0>; - }; - color_off_right: color-off-right { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_RIGHT_LED"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0>; - led-values = <0 0>; - }; + color_off_left: color-off-left { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_amber_left: color-amber-left { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pins = <&gpio_ec_chg_led_y_c1 - &gpio_ec_chg_led_w_c1>; - led-values = <1 0>; + color_amber_left: color-amber-left { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <1 0>; + }; + + color_white_left: color-white-left { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 1>; + }; }; - color_amber_right: color-amber-right { - led-color = "LED_AMBER"; + right_led: right-led { led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_AMBER"; led-pins = <&gpio_ec_chg_led_y_c0 &gpio_ec_chg_led_w_c0>; - led-values = <1 0>; - }; - color_white_left: color-white-left { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_ec_chg_led_y_c1 - &gpio_ec_chg_led_w_c1>; - led-values = <0 1>; - }; + color_off_right: color-off-right { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_white_right: color-white-right { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0>; - led-values = <0 1>; + + color_amber_right: color-amber-right { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <1 0>; + }; + + + color_white_right: color-white-right { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 1>; + }; }; }; }; diff --git a/zephyr/program/herobrine/hoglin/led_pins.dtsi b/zephyr/program/herobrine/hoglin/led_pins.dtsi index b70c385b98..1f5d649215 100644 --- a/zephyr/program/herobrine/hoglin/led_pins.dtsi +++ b/zephyr/program/herobrine/hoglin/led_pins.dtsi @@ -7,30 +7,27 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pins = <&gpio_ec_chg_led_b_c0 &gpio_ec_chg_led_r_c0>; - led-values = <0 0>; - }; - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_b_c0 - &gpio_ec_chg_led_r_c0>; - led-values = <1 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_red: color-red { - led-color = "LED_RED"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_RED"; - led-pins = <&gpio_ec_chg_led_b_c0 - &gpio_ec_chg_led_r_c0>; - led-values = <0 1>; + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <1 0>; + }; + + color_red: color-red { + led-color = "LED_RED"; + br-color = "EC_LED_COLOR_RED"; + led-values = <0 1>; + }; }; }; }; diff --git a/zephyr/program/herobrine/villager/led_pins.dtsi b/zephyr/program/herobrine/villager/led_pins.dtsi index 2a74fce58c..f171b6f656 100644 --- a/zephyr/program/herobrine/villager/led_pins.dtsi +++ b/zephyr/program/herobrine/villager/led_pins.dtsi @@ -7,30 +7,27 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pins = <&gpio_ec_chg_led_y_c0 &gpio_ec_chg_led_b_c0>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_b_c0>; - led-values = <1 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_b_c0>; - led-values = <0 1>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <1 0>; + }; + + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 1>; + }; }; }; }; diff --git a/zephyr/program/herobrine/zombie/led_pins.dtsi b/zephyr/program/herobrine/zombie/led_pins.dtsi index 2a74fce58c..f171b6f656 100644 --- a/zephyr/program/herobrine/zombie/led_pins.dtsi +++ b/zephyr/program/herobrine/zombie/led_pins.dtsi @@ -7,30 +7,27 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pins = <&gpio_ec_chg_led_y_c0 &gpio_ec_chg_led_b_c0>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_b_c0>; - led-values = <1 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_b_c0>; - led-values = <0 1>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <1 0>; + }; + + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 1>; + }; }; }; }; diff --git a/zephyr/program/intelrvp/adlrvp/src/adlrvp.c b/zephyr/program/intelrvp/adlrvp/src/adlrvp.c index d7d192b1af..93a2dee0f6 100644 --- a/zephyr/program/intelrvp/adlrvp/src/adlrvp.c +++ b/zephyr/program/intelrvp/adlrvp/src/adlrvp.c @@ -405,10 +405,8 @@ __override bool board_is_tbt_usb4_port(int port) return tbt_usb4; } -static int board_pre_task_peripheral_init(const struct device *unused) +static int board_pre_task_peripheral_init(void) { - ARG_UNUSED(unused); - /* Initialized IOEX-0 to access IOEX-GPIOs needed pre-task */ ioex_init(IOEX_C0_PCA9675); diff --git a/zephyr/program/intelrvp/mtlrvp/src/mtlrvp.c b/zephyr/program/intelrvp/mtlrvp/src/mtlrvp.c index cb7e282f63..76982a81cf 100644 --- a/zephyr/program/intelrvp/mtlrvp/src/mtlrvp.c +++ b/zephyr/program/intelrvp/mtlrvp/src/mtlrvp.c @@ -342,10 +342,8 @@ __override enum tbt_compat_cable_speed board_get_max_tbt_speed(int port) return max_speed; } -static int board_pre_task_peripheral_init(const struct device *unused) +static int board_pre_task_peripheral_init(void) { - ARG_UNUSED(unused); - /* Only reset tcpc/pd if not sysjump */ if (!system_jumped_late()) { /* Initialize tcpc and all ioex */ diff --git a/zephyr/program/myst/myst/led_pins.dtsi b/zephyr/program/myst/myst/led_pins.dtsi index 29c33f7457..fa93f388a3 100644 --- a/zephyr/program/myst/myst/led_pins.dtsi +++ b/zephyr/program/myst/myst/led_pins.dtsi @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_w>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/myst/myst/project.overlay b/zephyr/program/myst/myst/project.overlay index 1bdcd595c7..d42138e176 100644 --- a/zephyr/program/myst/myst/project.overlay +++ b/zephyr/program/myst/myst/project.overlay @@ -182,6 +182,24 @@ value = <1>; }; }; + + storage { + enum-name = "STORAGE_TYPE"; + start = <11>; + size = <1>; + + storage-nvme { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "STORAGE_TYPE_NVME"; + value = <0>; + default; + }; + storage-mmc { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "STORAGE_TYPE_MMC"; + value = <1>; + }; + }; }; /* Rotation matrices for motion sensors. */ diff --git a/zephyr/program/nissa/CMakeLists.txt b/zephyr/program/nissa/CMakeLists.txt index 97b25e7e06..e2f85139bf 100644 --- a/zephyr/program/nissa/CMakeLists.txt +++ b/zephyr/program/nissa/CMakeLists.txt @@ -114,6 +114,8 @@ endif() if(DEFINED CONFIG_BOARD_ULDREN) project(uldren) zephyr_library_sources( + "uldren/src/form_factor.c" + "uldren/src/kb_backlight.c" "uldren/src/keyboard.c" ) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "uldren/src/fan.c") diff --git a/zephyr/program/nissa/joxer/src/usbc.c b/zephyr/program/nissa/joxer/src/usbc.c index 3ce489e357..e3e18e0f33 100644 --- a/zephyr/program/nissa/joxer/src/usbc.c +++ b/zephyr/program/nissa/joxer/src/usbc.c @@ -76,7 +76,7 @@ static void board_chargers_suspend(struct ap_power_ev_callback *const cb, fn(CHARGER_SECONDARY); } -static int board_chargers_suspend_init(const struct device *unused) +static int board_chargers_suspend_init(void) { static struct ap_power_ev_callback cb = { .handler = board_chargers_suspend, diff --git a/zephyr/program/nissa/nereid/src/usbc.c b/zephyr/program/nissa/nereid/src/usbc.c index 3ce489e357..e3e18e0f33 100644 --- a/zephyr/program/nissa/nereid/src/usbc.c +++ b/zephyr/program/nissa/nereid/src/usbc.c @@ -76,7 +76,7 @@ static void board_chargers_suspend(struct ap_power_ev_callback *const cb, fn(CHARGER_SECONDARY); } -static int board_chargers_suspend_init(const struct device *unused) +static int board_chargers_suspend_init(void) { static struct ap_power_ev_callback cb = { .handler = board_chargers_suspend, diff --git a/zephyr/program/nissa/src/common.c b/zephyr/program/nissa/src/common.c index 435ef95e29..def29ccd02 100644 --- a/zephyr/program/nissa/src/common.c +++ b/zephyr/program/nissa/src/common.c @@ -81,7 +81,7 @@ __override void ocpc_get_pid_constants(int *kp, int *kp_div, int *ki, static int battery_cells; -void board_get_battery_cells(void) +test_export_static void board_get_battery_cells(void) { if (charger_get_battery_cells(CHARGER_PRIMARY, &battery_cells) == EC_SUCCESS) { diff --git a/zephyr/program/nissa/uldren/cbi.dtsi b/zephyr/program/nissa/uldren/cbi.dtsi index 148a7d2e99..9d865a38bb 100644 --- a/zephyr/program/nissa/uldren/cbi.dtsi +++ b/zephyr/program/nissa/uldren/cbi.dtsi @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,5 +6,66 @@ / { /* Uldren-specific fw_config fields. */ nissa-fw-config { + /* + * FW_CONFIG field to enable KB back light or not. + */ + kb-bl { + enum-name = "FW_KB_BL"; + start = <4>; + size = <1>; + + no-kb-bl { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BL_NOT_PRESENT"; + value = <0>; + default; + }; + kb-bl-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_KB_BL_PRESENT"; + value = <1>; + }; + }; + + /* + * FW_CONFIG field to enable USB DB. + */ + db-usb { + enum-name = "FW_DB_USB"; + start = <6>; + size = <1>; + + no-db-usb { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_DB_USB_NOT_PRESENT"; + value = <0>; + }; + db-usb-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_DB_USB_PRESENT"; + value = <1>; + default; + }; + }; + + /* + * FW_CONFIG field for tablet present or not. + */ + tablet { + enum-name = "FW_TABLET"; + start = <7>; + size = <1>; + + no-tablet { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_TABLET_NOT_PRESENT"; + value = <0>; + }; + tablet-present { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_TABLET_PRESENT"; + value = <1>; + }; + }; }; }; diff --git a/zephyr/program/nissa/uldren/generated.dtsi b/zephyr/program/nissa/uldren/generated.dtsi index f02faec389..ab3b5264ae 100644 --- a/zephyr/program/nissa/uldren/generated.dtsi +++ b/zephyr/program/nissa/uldren/generated.dtsi @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -105,6 +105,10 @@ gpio_ec_wp_odl: ec_wp_odl { gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; gpio_en_pp3300_s5: en_pp3300_s5 { gpios = <&gpiob 6 GPIO_OUTPUT>; enum-name = "GPIO_TEMP_SENSOR_POWER"; diff --git a/zephyr/program/nissa/uldren/keyboard.dtsi b/zephyr/program/nissa/uldren/keyboard.dtsi index 5248c4aaff..f958ed9cea 100644 --- a/zephyr/program/nissa/uldren/keyboard.dtsi +++ b/zephyr/program/nissa/uldren/keyboard.dtsi @@ -1,8 +1,21 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +/ { + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 PWM_KHZ(10) PWM_POLARITY_NORMAL>; + }; +}; + +&pwm6 { + status = "okay"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + &cros_kb_raw { status = "okay"; /* No KSO2 (it's inverted and implemented by GPIO) */ diff --git a/zephyr/program/nissa/uldren/led_pins.dtsi b/zephyr/program/nissa/uldren/led_pins.dtsi index e9003ffc30..03f9d61df0 100644 --- a/zephyr/program/nissa/uldren/led_pins.dtsi +++ b/zephyr/program/nissa/uldren/led_pins.dtsi @@ -19,27 +19,25 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_led_y_c0 &pwm_led_w_c0>; - led-values = <0 0>; - }; - - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_led_y_c0 &pwm_led_w_c0>; - led-values = <100 0>; - }; - - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_led_y_c0 &pwm_led_w_c0>; - led-values = <0 100>; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; @@ -59,4 +57,3 @@ pinctrl-0 = <&pwm2_gpc4>; pinctrl-names = "default"; }; - diff --git a/zephyr/program/nissa/uldren/overlay.dtsi b/zephyr/program/nissa/uldren/overlay.dtsi index 50ba4c932e..7e6e823b37 100644 --- a/zephyr/program/nissa/uldren/overlay.dtsi +++ b/zephyr/program/nissa/uldren/overlay.dtsi @@ -1,4 +1,4 @@ -/* Copyright 2021 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -316,7 +316,6 @@ <&gpio8 3 0>, <&gpio8 5 0>, <&gpio8 6 0>, - <&gpioa 0 0>, <&gpiob 1 0>, <&gpiob 7 0>, <&gpioc 0 0>, diff --git a/zephyr/program/nissa/uldren/power_signals.dtsi b/zephyr/program/nissa/uldren/power_signals.dtsi index 1d2b23069d..99e64cc52f 100644 --- a/zephyr/program/nissa/uldren/power_signals.dtsi +++ b/zephyr/program/nissa/uldren/power_signals.dtsi @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/zephyr/program/nissa/uldren/project.conf b/zephyr/program/nissa/uldren/project.conf index 0c64e7ad3d..f65c304bd4 100644 --- a/zephyr/program/nissa/uldren/project.conf +++ b/zephyr/program/nissa/uldren/project.conf @@ -9,6 +9,7 @@ CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000 +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y # Both ports use a SLGC55545 smart switch with CTL1..3 fixed high, # for SDP2 or CDP only. @@ -17,5 +18,5 @@ CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_CDP_SDP_ONLY=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_DEFAULT_CDP=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_INVERTED=y -# Disable keyboard backlight -CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=n +# BTN +CONFIG_PLATFORM_EC_BUTTONS_RUNTIME_CONFIG=y diff --git a/zephyr/program/nissa/uldren/project.overlay b/zephyr/program/nissa/uldren/project.overlay index 10b76b0080..f56a20e235 100644 --- a/zephyr/program/nissa/uldren/project.overlay +++ b/zephyr/program/nissa/uldren/project.overlay @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/zephyr/program/nissa/uldren/src/form_factor.c b/zephyr/program/nissa/uldren/src/form_factor.c index 72c0ba04d3..2dcc61c590 100644 --- a/zephyr/program/nissa/uldren/src/form_factor.c +++ b/zephyr/program/nissa/uldren/src/form_factor.c @@ -4,42 +4,46 @@ */ #include "accelgyro.h" +#include "button.h" +#include "cros_board_info.h" #include "cros_cbi.h" +#include "driver/accel_bma4xx.h" +#include "driver/accelgyro_bmi323.h" +#include "gpio/gpio_int.h" #include "hooks.h" +#include "motion_sense.h" #include "motionsense_sensors.h" +#include "tablet_mode.h" #include <zephyr/devicetree.h> #include <zephyr/logging/log.h> LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); -/* - * Mainboard orientation support. - */ - -#define ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(base_rot_inverted)) -#define BASE_SENSOR SENSOR_ID(DT_NODELABEL(base_accel)) -#define BASE_GYRO SENSOR_ID(DT_NODELABEL(base_gyro)) - static void form_factor_init(void) { int ret; uint32_t val; - /* - * If the firmware config indicates - * an inverted form factor, use the alternative - * rotation matrix. - */ - ret = cros_cbi_get_fw_config(FW_BASE_INVERSION, &val); + + /*check tabletmode*/ + ret = cros_cbi_get_fw_config(FW_TABLET, &val); if (ret != 0) { - LOG_ERR("Error retrieving CBI FW_CONFIG field %d", - FW_BASE_INVERSION); + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_TABLET); return; } - if (val == FW_BASE_INVERTED) { - LOG_INF("Switching to inverted base"); - motion_sensors[BASE_SENSOR].rot_standard_ref = &ALT_MAT; - motion_sensors[BASE_GYRO].rot_standard_ref = &ALT_MAT; + if (val == FW_TABLET_NOT_PRESENT) { + LOG_INF("Clamshell: disable motionsense function."); + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + gpio_disable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_imu)); + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_imu_int_l), + GPIO_DISCONNECTED); + + LOG_INF("Clamshell: disable volume button function."); + button_disable_gpio(BUTTON_VOLUME_UP); + button_disable_gpio(BUTTON_VOLUME_DOWN); + } else { + LOG_INF("Tablet: Enable motionsense function."); } } DECLARE_HOOK(HOOK_INIT, form_factor_init, HOOK_PRIO_POST_I2C); diff --git a/zephyr/program/nissa/uldren/src/kb_backlight.c b/zephyr/program/nissa/uldren/src/kb_backlight.c new file mode 100644 index 0000000000..1f73d3e8be --- /dev/null +++ b/zephyr/program/nissa/uldren/src/kb_backlight.c @@ -0,0 +1,34 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "board_config.h" +#include "common.h" +#include "cros_board_info.h" +#include "cros_cbi.h" + +#include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> + +LOG_MODULE_DECLARE(uldren, CONFIG_NISSA_LOG_LEVEL); + +__override uint32_t board_override_feature_flags0(uint32_t flags0) +{ + int ret; + uint32_t val; + + /* + * Remove keyboard backlight feature for devices that don't support it. + */ + ret = cros_cbi_get_fw_config(FW_KB_BL, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_KB_BL); + return flags0; + } + + if (val == FW_KB_BL_NOT_PRESENT) + return (flags0 & ~EC_FEATURE_MASK_0(EC_FEATURE_PWM_KEYB)); + else + return flags0; +} diff --git a/zephyr/program/nissa/xivu/led_pins.dtsi b/zephyr/program/nissa/xivu/led_pins.dtsi index e7efa3e96c..40817eada7 100644 --- a/zephyr/program/nissa/xivu/led_pins.dtsi +++ b/zephyr/program/nissa/xivu/led_pins.dtsi @@ -23,30 +23,27 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_led_y_c0 &pwm_led_y_c1 &pwm_led_w_c0 &pwm_led_w_c1>; - led-values = <0 0 0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_led_y_c0 &pwm_led_y_c1 - &pwm_led_w_c0 &pwm_led_w_c1>; - led-values = <50 50 0 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0 0 0>; + }; - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_led_y_c0 &pwm_led_y_c1 - &pwm_led_w_c0 &pwm_led_w_c1>; - led-values = <0 0 50 50>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <50 50 0 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 0 50 50>; + }; }; }; }; diff --git a/zephyr/program/nissa/yaviks/src/usbc.c b/zephyr/program/nissa/yaviks/src/usbc.c index dcaa8221ff..c9950ae73b 100644 --- a/zephyr/program/nissa/yaviks/src/usbc.c +++ b/zephyr/program/nissa/yaviks/src/usbc.c @@ -77,7 +77,7 @@ static void board_chargers_suspend(struct ap_power_ev_callback *const cb, fn(CHARGER_SECONDARY); } -static int board_chargers_suspend_init(const struct device *unused) +static int board_chargers_suspend_init(void) { static struct ap_power_ev_callback cb = { .handler = board_chargers_suspend, diff --git a/zephyr/program/nissa/yavilla/src/usbc.c b/zephyr/program/nissa/yavilla/src/usbc.c index fa280615ee..c9950ae73b 100644 --- a/zephyr/program/nissa/yavilla/src/usbc.c +++ b/zephyr/program/nissa/yavilla/src/usbc.c @@ -12,6 +12,7 @@ #include "hooks.h" #include "system.h" #include "usb_mux.h" +#include "watchdog.h" #include <zephyr/logging/log.h> @@ -76,7 +77,7 @@ static void board_chargers_suspend(struct ap_power_ev_callback *const cb, fn(CHARGER_SECONDARY); } -static int board_chargers_suspend_init(const struct device *unused) +static int board_chargers_suspend_init(void) { static struct ap_power_ev_callback cb = { .handler = board_chargers_suspend, @@ -316,6 +317,15 @@ void board_process_pd_alert(int port) */ if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c1_int_odl))) schedule_deferred_pd_interrupt(port); + + /* + * b:273208597: There are some peripheral display docks will + * issue HPDs in the short time. TCPM must wake up pd_task + * continually to service the events. They may cause the + * watchdog to reset. This patch placates watchdog after + * receiving dp_attention. + */ + watchdog_reload(); } int pd_snk_is_vbus_provided(int port) diff --git a/zephyr/program/rex/BUILD.py b/zephyr/program/rex/BUILD.py index 89aee8b06d..1b0fe31509 100644 --- a/zephyr/program/rex/BUILD.py +++ b/zephyr/program/rex/BUILD.py @@ -44,3 +44,7 @@ register_rex_project( here / "rex-sans-sensors" / "project.conf", ], ) + +register_rex_project( + project_name="screebo", +) diff --git a/zephyr/program/rex/CMakeLists.txt b/zephyr/program/rex/CMakeLists.txt index 1962569692..2790a99146 100644 --- a/zephyr/program/rex/CMakeLists.txt +++ b/zephyr/program/rex/CMakeLists.txt @@ -13,4 +13,7 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/usb_pd_policy.c") if(DEFINED CONFIG_BOARD_REX) project(rex) add_subdirectory(rex) +elseif(DEFINED CONFIG_BOARD_SCREEBO) + project(screebo) + add_subdirectory(screebo) endif() diff --git a/zephyr/program/rex/Kconfig b/zephyr/program/rex/Kconfig index f61e27ad7d..723febc6d4 100644 --- a/zephyr/program/rex/Kconfig +++ b/zephyr/program/rex/Kconfig @@ -8,6 +8,12 @@ config BOARD_REX Build Google Rex reference board. The board uses Nuvoton NPCX9 chip as the EC. +config BOARD_SCREEBO + bool "Google Screebo Board" + help + Build Google Screebo variant board. The board uses Nuvoton + NPCX9 chip as the EC. + module = REX module-str = Rex board-specific code source "subsys/logging/Kconfig.template.log_config" diff --git a/zephyr/program/rex/generated.dtsi b/zephyr/program/rex/generated.dtsi index 5b6f9cd708..3a878f9bc7 100644 --- a/zephyr/program/rex/generated.dtsi +++ b/zephyr/program/rex/generated.dtsi @@ -1,13 +1,8 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * This file is auto-generated - do not edit! - * - * TODO(b:/244441996): There are some errors in the main Rex EC GPIO spreadsheet - * which is used as input to create this device tree file. Until that issue is - * resolved, there are some edits required to this file to support EC - * functionality. */ / { @@ -15,20 +10,20 @@ named-adc-channels { compatible = "named-adc-channels"; - adc_ddr_soc: ddr_soc { + adc_temp_sensor_1: temp_sensor_1 { enum-name = "ADC_TEMP_SENSOR_1_DDR_SOC"; io-channels = <&adc0 0>; }; - adc_ambient: ambient { - enum-name = "ADC_TEMP_SENSOR_2"; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2_AMBIENT"; io-channels = <&adc0 1>; }; - adc_charger: charger { - enum-name = "ADC_TEMP_SENSOR_3"; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3_CHARGER"; io-channels = <&adc0 8>; }; - adc_wwan: wwan { - enum-name = "ADC_TEMP_SENSOR_4"; + adc_temp_sensor_4: temp_sensor_4 { + enum-name = "ADC_TEMP_SENSOR_4_WWAN"; io-channels = <&adc0 7>; }; }; @@ -41,7 +36,7 @@ enum-name = "GPIO_AC_PRESENT"; }; gpio_ccd_mode_odl: ccd_mode_odl { - gpios = <&gpioe 5 GPIO_ODR_HIGH>; + gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_CCD_MODE_ODL"; }; gpio_cpu_c10_gate_l: cpu_c10_gate_l { @@ -61,7 +56,7 @@ gpios = <&gpio7 3 GPIO_OUTPUT>; }; gpio_ec_edp_bl_en: ec_edp_bl_en { - gpios = <&gpiod 3 GPIO_OUTPUT_LOW>; + gpios = <&gpiod 3 GPIO_OUTPUT>; enum-name = "GPIO_ENABLE_BACKLIGHT"; }; gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { @@ -71,15 +66,16 @@ gpio_ec_imu_int_r_l: ec_imu_int_r_l { gpios = <&gpio5 6 GPIO_INPUT_PULL_UP>; }; - gpio_ec_imvp92_en_smb: ec_imvp92_en_smb { - gpios = <&gpiob 1 GPIO_OUTPUT>; - }; gpio_ec_kb_bl_en_l: ec_kb_bl_en_l { gpios = <&gpio8 6 GPIO_OUTPUT>; }; gpio_ec_kso_02_inv: ec_kso_02_inv { gpios = <&gpio1 7 (GPIO_OUTPUT | GPIO_ACTIVE_LOW)>; }; + gpio_ec_mech_pwr_btn_l: ec_mech_pwr_btn_l { + gpios = <&gpio0 2 GPIO_INPUT>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; gpio_ec_prochot_in_l: ec_prochot_in_l { gpios = <&gpiof 0 GPIO_INPUT>; }; @@ -106,6 +102,9 @@ gpio_ec_soc_wake_r_odl: ec_soc_wake_r_odl { gpios = <&gpioc 0 GPIO_ODR_LOW>; }; + gpio_ec_spare_gpio01: ec_spare_gpio01 { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; gpio_ec_spare_gpio42: ec_spare_gpio42 { gpios = <&gpio4 2 GPIO_OUTPUT>; }; @@ -121,6 +120,9 @@ gpio_ec_spare_gpioa4: ec_spare_gpioa4 { gpios = <&gpioa 4 GPIO_OUTPUT>; }; + gpio_ec_spare_gpiob1: ec_spare_gpiob1 { + gpios = <&gpiob 1 GPIO_OUTPUT>; + }; gpio_ec_spare_gpioc7: ec_spare_gpioc7 { gpios = <&gpioc 7 GPIO_OUTPUT>; }; @@ -139,10 +141,10 @@ enum-name = "GPIO_VOLUME_UP_L"; }; gpio_ec_wp_l: ec_wp_l { - gpios = <&gpioa 1 GPIO_INPUT>; + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; }; gpio_en_pp5000_fan: en_pp5000_fan { - gpios = <&gpio6 1 GPIO_OUTPUT_LOW>; + gpios = <&gpio6 1 GPIO_OUTPUT>; }; gpio_en_pp5000_usba_r: en_pp5000_usba_r { gpios = <&gpiod 7 GPIO_OUTPUT>; @@ -154,9 +156,6 @@ gpio_en_z1_rails: en_z1_rails { gpios = <&gpio8 5 GPIO_OUTPUT>; }; - gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { - gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; - }; gpio_imvp92_vrrdy_od: imvp92_vrrdy_od { gpios = <&gpio4 3 GPIO_INPUT>; }; @@ -173,14 +172,10 @@ gpios = <&gpio6 0 GPIO_OUTPUT>; }; gpio_lid_open: lid_open { - gpios = <&gpiod 2 GPIO_INPUT_PULL_UP>; + gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; }; - gpio_mech_pwr_btn_odl: mech_pwr_btn_odl { - gpios = <&gpio0 2 GPIO_INPUT>; - enum-name = "GPIO_POWER_BUTTON_L"; - }; - gpio_seq_ec_all_sys_pg: seq_ec_all_sys_pg { + gpio_seq_ec_all_sys_pg_od: seq_ec_all_sys_pg_od { gpios = <&gpiof 4 GPIO_INPUT>; }; gpio_seq_ec_rsmrst_odl: seq_ec_rsmrst_odl { @@ -217,13 +212,13 @@ enum-name = "GPIO_USB_C0_PPC_INT_ODL"; }; gpio_usb_c0_rt_3p3_sx_en: usb_c0_rt_3p3_sx_en { - gpios = <&gpio0 3 GPIO_OUTPUT_LOW>; + gpios = <&gpio0 3 GPIO_ODR_LOW>; }; gpio_usb_c0_rt_int_odl: usb_c0_rt_int_odl { gpios = <&gpioa 0 GPIO_INPUT>; }; gpio_usb_c0_tcpc_int_odl: usb_c0_tcpc_int_odl { - gpios = <&gpioe 0 GPIO_INPUT>; + gpios = <&gpioe 0 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; }; gpio_usb_c0_tcpc_rst_odl: usb_c0_tcpc_rst_odl { @@ -250,7 +245,7 @@ gpios = <&gpio7 4 GPIO_ODR_HIGH>; }; gpio_usb_c1_tcpc_int_odl: usb_c1_tcpc_int_odl { - gpios = <&gpio3 4 GPIO_INPUT>; + gpios = <&gpio3 4 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; }; }; @@ -258,7 +253,7 @@ named-i2c-ports { compatible = "named-i2c-ports"; - i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c_ec_i2c_sensor_scl_r: ec_i2c_sensor_scl_r { i2c-port = <&i2c0_0>; enum-names = "I2C_PORT_SENSOR"; }; @@ -277,7 +272,6 @@ i2c_ec_i2c_usb_c1_tcp: ec_i2c_usb_c1_tcp { i2c-port = <&i2c4_1>; enum-names = "I2C_PORT_USB_C1_TCPC"; - dynamic-speed; }; i2c_ec_i2c_bat: ec_i2c_bat { i2c-port = <&i2c5_0>; diff --git a/zephyr/program/rex/gpio.csv b/zephyr/program/rex/gpio.csv index 5c20f6fb00..26f09181ee 100644 --- a/zephyr/program/rex/gpio.csv +++ b/zephyr/program/rex/gpio.csv @@ -1,44 +1,90 @@ Signal Name,Pin Number,Type,Enum -USB_C1_BC12_INT_ODL,G10,INPUT,GPIO_USB_C1_BC12_INT_ODL -ESPI_SOC_CS0_L,L2,OTHER, -ESPI_SOC_RESET_L,K3,OTHER, -ESPI_SOC_CLK,M1,OTHER, -EC_IMU_INT_R_L,M2,INPUT_PU, ESPI_SOC_IO0,H1,OTHER, ESPI_SOC_IO1,J1,OTHER, ESPI_SOC_IO2,K1,OTHER, ESPI_SOC_IO3,L1,OTHER, +ESPI_SOC_CS0_L,L2,OTHER, +ESPI_SOC_RESET_L,K3,OTHER, +ESPI_SOC_CLK,M1,OTHER, ESPI_SOC_ALERT_L_R,L3,OTHER, +USB_C1_BC12_INT_ODL,G10,INPUT,GPIO_USB_C1_BC12_INT_ODL +EC_IMU_INT_R_L,M2,INPUT_PU, EC_VOLDN_BTN_ODL,E11,INPUT_PU,GPIO_VOLUME_DOWN_L TABLET_MODE_L,M12,INPUT_PU,GPIO_TABLET_MODE_L SOCHOT_ODL,G12,INPUT, EC_VOLUP_BTN_ODL,L10,INPUT_PU,GPIO_VOLUME_UP_L USB_C0_RT_INT_ODL,G11,INPUT, -EC_WP_L,L12,INPUT, +EC_WP_L,L12,INPUT_L, EC_BATT_PRES_ODL,K12,INPUT,GPIO_BATT_PRES_ODL -CPU_C10_GATE_L,J11,INPUT, SOC_PWROK,K11,OUTPUT, EC_SOC_RSMRST_L,F11,OUTPUT, +CPU_C10_GATE_L,J11,INPUT, SYS_PWROK,L11,OUTPUT, EC_SPARE_GPIO94,M11,OUTPUT, EC_SPARE_GPIOA2,F12,OUTPUT, EC_SPARE_GPIOA4,H11,OUTPUT, EC_ACCEL_INT_R_L,M7,INPUT, +TEMP_SENSOR_2,E3,ADC,ADC_TEMP_SENSOR_2_AMBIENT +TEMP_SENSOR_1,F2,ADC,ADC_TEMP_SENSOR_1_DDR_SOC +TEMP_SENSOR_4,F3,ADC,ADC_TEMP_SENSOR_4_WWAN +TEMP_SENSOR_3,G3,ADC,ADC_TEMP_SENSOR_3_CHARGER SLP_S3_LS_L,C2,INPUT, IMVP92_VRRDY_OD,E2,INPUT, EC_PROCHOT_IN_L,D2,INPUT, EC_SPARE_GPIO42,D3,OUTPUT, -TEMP_SENSOR_2,E3,ADC,ADC_TEMP_SENSOR_2 -TEMP_SENSOR_1,F2,ADC,ADC_TEMP_SENSOR_1 -TEMP_SENSOR_4,F3,ADC,ADC_TEMP_SENSOR_4 -TEMP_SENSOR_3,G3,ADC,ADC_TEMP_SENSOR_3 -SYS_RST_ODL,H7,INPUT, -EC_SOC_WAKE_R_ODL,H8,OUTPUT_ODL, +USB_C0_RT_3P3_SX_EN,D9,OUTPUT_ODL, +USB_C1_RST_ODL,C1,OUTPUT_ODL, +EN_PP5000_FAN,K4,OUTPUT, EC_PROCHOT_ODL,J2,OUTPUT_ODR, +USB_C0_TCPC_RST_ODL,J3,OUTPUT_ODR, EC_SOC_INT_ODL,J4,OUTPUT_ODL,GPIO_EC_INT_L +USB_C1_RT_RST_R_ODL,H5,OUTPUT_ODR, +EC_GSC_PACKET_MODE,J6,OUTPUT,GPIO_PACKET_MODE_EN EC_SOC_RTCRST,J5,OUTPUT_ODR, +USB_C1_FRS_EN,D7,OUTPUT_ODR, +EN_S5_RAILS,L9,OUTPUT_ODR,GPIO_TEMP_SENSOR_POWER +EC_SOC_WAKE_R_ODL,H8,OUTPUT_ODL, EC_SOC_PWR_BTN_ODL,H9,OUTPUT_ODL,GPIO_PCH_PWRBTN_L -USB_C0_RT_3P3_SX_EN,D9,OUTPUT_ODR, +SYS_RST_ODL,H7,INPUT, +EC_EDP_BL_EN,E10,OUTPUT,GPIO_ENABLE_BACKLIGHT +SYS_SLP_S0IX_3V3_L,A10,INPUT, +SEQ_EC_RSMRST_ODL,A11,INPUT, +CCD_MODE_ODL,A12,INPUT,GPIO_CCD_MODE_ODL +EC_KB_BL_EN_L,J9,OUTPUT, +EC_SHDF_ESPI_L,H3,OTHER, +USB_C1_TCPC_INT_ODL,B2,INPUT_L,GPIO_USB_C1_TCPC_INT_ODL +EC_FAN_TACH,E5,TACH, +USB_C0_PPC_INT_ODL,H2,INPUT,GPIO_USB_C0_PPC_INT_ODL +USB_C1_RT_INT_ODL,M4,INPUT_PU, +USB_C0_BC12_INT_ODL,D10,INPUT,GPIO_USB_C0_BC12_INT_ODL +EC_ALS_RGB_INT_R_L,A9,INPUT_PU, +USB_C0_TCPC_INT_ODL,F4,INPUT_L,GPIO_USB_C0_TCPC_INT_ODL +SEQ_EC_ALL_SYS_PG_OD,E9,INPUT, +USB_C1_PPC_INT_ODL,E8,INPUT,GPIO_USB_C1_PPC_INT_ODL +EC_I2C_SENSOR_SDA_R,B12,I2C_DATA, +EC_I2C_SENSOR_SCL_R,C12,I2C_CLOCK,I2C_PORT_SENSOR +EC_I2C_USB_C0_TCPC_SDA,K7,I2C_DATA, +EC_I2C_USB_C0_TCPC_SCL,K8,I2C_CLOCK,I2C_PORT_USB_C0_TCPC +EC_I2C_USB_C0_PPC_BC_SDA,K9,I2C_DATA, +EC_I2C_USB_C0_PPC_BC_SCL,L8,I2C_CLOCK,I2C_PORT_PPC0 +EC_I2C_USB_C0_RT_SDA,F9,I2C_DATA, +EC_I2C_USB_C0_RT_SCL,F8,I2C_CLOCK,I2C_PORT_USB_C0_RT +EC_I2C_USB_C1_TCPC_SDA,F6,I2C_DATA, +EC_I2C_USB_C1_TCPC_SCL,F5,I2C_CLOCK,I2C_PORT_USB_C1_TCPC +EC_I2C_BAT_SCL,D5,I2C_CLOCK,I2C_PORT_BATTERY +EC_I2C_BAT_SDA,D4,I2C_DATA, +EC_I2C_USB_C1_MIX_SDA,L7,I2C_DATA, +EC_I2C_USB_C1_MIX_SCL,L6,I2C_CLOCK,I2C_PORT_USB_1_MIX +EC_I2C_MISC_SDA,K10,I2C_DATA, +EC_I2C_MISC_SCL,J10,I2C_CLOCK,I2C_PORT_EEPROM +KSI_07,C5,OTHER, +KSI_06,C4,OTHER, +KSI_05,C3,OTHER, +KSI_04,B4,OTHER, +EC_KSI_03,B3,OTHER, +EC_KSI_02,A4,OTHER, +KSI_01,A3,OTHER, +EC_KSI_00,A2,OTHER, KSO_13,D11,OTHER, KSO_12,C11,OTHER, KSO_11,B10,OTHER, @@ -51,72 +97,29 @@ KSO_03,B8,OTHER, EC_KSO_02_INV,B7,OUTPUT_L, KSO_01,B6,OTHER, KSO_00,B5,OTHER, -KSI_07,C5,OTHER, -KSI_06,C4,OTHER, -KSI_05,C3,OTHER, -KSI_04,B4,OTHER, -EC_KSI_03,B3,OTHER, -EC_KSI_02,A4,OTHER, -KSI_01,A3,OTHER, -EC_KSI_00,A2,OTHER, -EC_I2C_BAT_SCL,D5,I2C_CLOCK,I2C_PORT_BATTERY -USB_C1_TCPC_INT_ODL,B2,INPUT,GPIO_USB_C1_TCPC_INT_ODL -EC_I2C_BAT_SDA,D4,I2C_DATA, -USB_C1_RST_ODL,C1,OUTPUT_ODL, -EC_FAN_TACH,E5,TACH, +KSO_14,D6,OTHER, +EC_KSO_07_JEN_L,B9,OTHER, +EC_KSO_06_GP_SEL_L,C8,OTHER, LED_4_L,G6,OUTPUT, -EN_PP5000_FAN,K4,OUTPUT_ODR, -USB_C0_PPC_INT_ODL,H2,INPUT,GPIO_USB_C0_PPC_INT_ODL -UART_GSC_DBG_TX_EC_RX_R,G4,OTHER, -EC_SPARE_GPIO66,G2,OUTPUT, -USB_C0_TCPC_RST_ODL,J3,OUTPUT_ODL, -USB_C1_RT_INT_ODL,M4,INPUT_PU, -EC_CBI_WP,G5,OUTPUT, -USB_C1_RT_RST_R_ODL,H5,OUTPUT_ODL, -EC_GSC_PACKET_MODE,J6,OUTPUT_ODR,GPIO_PACKET_MODE_EN EC_KB_BL_PWM,K5,PWM,GPIO_EN_KEYBOARD_BACKLIGHT -KSO_14,D6,OTHER, -USB_C1_FRS_EN,D7,OUTPUT_ODR, -EC_I2C_USB_C0_TCPC_SDA,K7,I2C_DATA, -EC_I2C_USB_C0_TCPC_SCL,K8,I2C_CLOCK,I2C_PORT_USB_C0_TCPC -EC_I2C_USB_C0_PPC_BC_SDA,K9,I2C_DATA, -EC_I2C_USB_C0_PPC_BC_SCL,L8,I2C_CLOCK,I2C_PORT_PPC0 -EC_IMVP92_EN_SMB,D8,OUTPUT, -EC_I2C_MISC_SDA,K10,I2C_DATA, -EC_I2C_MISC_SCL,J10,I2C_CLOCK,I2C_PORT_EEPROM -EC_I2C_SENSOR_SDA,B12,I2C_DATA, -EC_I2C_SENSOR_SCL,C12,I2C_CLOCK,I2C_PORT_SENSOR -EN_S5_RAILS,L9,OUTPUT_ODR, FAN_PWM,J7,PWM, LED_3_L,H10,OUTPUT, LED_2_L,G9,OUTPUT, LED_1_L,G8,OUTPUT, -USB_C0_BC12_INT_ODL,D10,INPUT,GPIO_USB_C0_BC12_INT_ODL +EC_RST_R_ODL,K6,INPUT, +UART_GSC_DBG_TX_EC_RX_R,G4,OTHER, +UART_GSC_DBG_RX_EC_TX_R,H4,OTHER, +EC_SPARE_GPIO66,G2,OUTPUT, +EC_CBI_WP,G5,OUTPUT, +EC_SPARE_GPIOB1,D8,OUTPUT, EC_SPARE_GPIOC7,F10,OUTPUT, -EC_I2C_USB_C0_RT_SDA,F9,I2C_DATA, -EC_I2C_USB_C0_RT_SCL,F8,I2C_CLOCK,I2C_PORT_USB_C0_RT -EC_EDP_BL_EN,E10,OUTPUT_ODR,GPIO_ENABLE_BACKLIGHT -EC_ALS_RGB_INT_R_L,A9,INPUT_PU, -SYS_SLP_S0IX_3V3_L,A10,INPUT, -USB_C0_TCPC_INT_ODL,F4,INPUT,GPIO_USB_C0_TCPC_INT_ODL -SEQ_EC_RSMRST_ODL,A11,INPUT, -EC_I2C_USB_C1_MIX_SDA,L7,I2C_DATA, -EC_I2C_USB_C1_MIX_SCL,L6,I2C_CLOCK,I2C_PORT_USB_1_MIX -CCD_MODE_ODL,A12,OUTPUT_ODL,GPIO_CCD_MODE_ODL -EC_I2C_USB_C1_TCPC_SDA,F6,I2C_DATA, -EC_I2C_USB_C1_TCPC_SCL,F5,I2C_CLOCK,I2C_PORT_USB_C1_TCPC -SEQ_EC_ALL_SYS_PG,E9,INPUT, -USB_C1_PPC_INT_ODL,E8,INPUT,GPIO_USB_C1_PPC_INT_ODL -EC_KSO_07_JEN_L,B9,OTHER, -EC_KSO_06_GP_SEL_L,C8,OTHER, EC_SPARE_GPO32,E4,OUTPUT, EC_SPARE_GPO35,K2,OUTPUT, -UART_GSC_DBG_RX_EC_TX_R,H4,OTHER, -EC_RST_R_ODL,K6,INPUT, -EC_KB_BL_EN_L,J9,OUTPUT, +EC_32KXIN,L5,INPUT, +EC_32KXOUT,M5,OUTPUT, ACOK_OD,E7,INPUT,GPIO_AC_PRESENT -GSC_EC_PWR_BTN_ODL,E6,INPUT_PU,GPIO_POWER_BUTTON_L -MECH_PWR_BTN_ODL,F7,INPUT, -LID_OPEN,G7,INPUT_PU,GPIO_LID_OPEN +EC_SPARE_GPIO01,E6,INPUT_PU, +EC_MECH_PWR_BTN_L,F7,INPUT,GPIO_POWER_BUTTON_L +LID_OPEN,G7,INPUT,GPIO_LID_OPEN EN_Z1_RAILS,J8,OUTPUT, EN_PP5000_USBA_R,H6,OUTPUT, diff --git a/zephyr/program/rex/interrupts.dtsi b/zephyr/program/rex/interrupts.dtsi index f8cd156720..0f1100b18d 100644 --- a/zephyr/program/rex/interrupts.dtsi +++ b/zephyr/program/rex/interrupts.dtsi @@ -13,7 +13,7 @@ handler = "extpower_interrupt"; }; int_power_button: power_button { - irq-pin = <&gpio_mech_pwr_btn_odl>; + irq-pin = <&gpio_ec_mech_pwr_btn_l>; flags = <GPIO_INT_EDGE_BOTH>; handler = "power_button_interrupt"; }; diff --git a/zephyr/program/rex/motionsense.dtsi b/zephyr/program/rex/motionsense.dtsi index 6af7cd2b12..6d30209a12 100644 --- a/zephyr/program/rex/motionsense.dtsi +++ b/zephyr/program/rex/motionsense.dtsi @@ -153,7 +153,7 @@ active-mask = "SENSOR_ACTIVE_S0_S3"; location = "MOTIONSENSE_LOC_LID"; mutex = <&mutex_lis2dw12>; - port = <&i2c_ec_i2c_sensor>; + port = <&i2c_ec_i2c_sensor_scl_r>; rot-standard-ref = <&lid_rot_ref>; default-range = <2>; drv-data = <&lis2dw12_data>; @@ -177,7 +177,7 @@ active-mask = "SENSOR_ACTIVE_S0_S3"; location = "MOTIONSENSE_LOC_BASE"; mutex = <&mutex_lsm6dso>; - port = <&i2c_ec_i2c_sensor>; + port = <&i2c_ec_i2c_sensor_scl_r>; rot-standard-ref = <&base_rot_ref>; default-range = <4>; drv-data = <&lsm6dso_accel_data>; @@ -203,7 +203,7 @@ active-mask = "SENSOR_ACTIVE_S0_S3"; location = "MOTIONSENSE_LOC_BASE"; mutex = <&mutex_lsm6dso>; - port = <&i2c_ec_i2c_sensor>; + port = <&i2c_ec_i2c_sensor_scl_r>; rot-standard-ref = <&base_rot_ref>; default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ drv-data = <&lsm6dso_gyro_data>; @@ -216,7 +216,7 @@ active-mask = "SENSOR_ACTIVE_S0_S3"; location = "MOTIONSENSE_LOC_CAMERA"; - port = <&i2c_ec_i2c_sensor>; + port = <&i2c_ec_i2c_sensor_scl_r>; default-range = <0x10000>; drv-data = <&tcs_clear_data>; i2c-spi-addr-flags = "TCS3400_I2C_ADDR_FLAGS"; diff --git a/zephyr/program/rex/power_signals.dtsi b/zephyr/program/rex/power_signals.dtsi index 09c84b8558..448c233746 100644 --- a/zephyr/program/rex/power_signals.dtsi +++ b/zephyr/program/rex/power_signals.dtsi @@ -146,7 +146,7 @@ }; /* pwr-all-sys-pwrgd */ -&gpio_seq_ec_all_sys_pg { +&gpio_seq_ec_all_sys_pg_od { no-auto-init; }; diff --git a/zephyr/program/rex/program.conf b/zephyr/program/rex/program.conf index 75351088fe..0e572e373c 100644 --- a/zephyr/program/rex/program.conf +++ b/zephyr/program/rex/program.conf @@ -82,6 +82,7 @@ CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_PPC=y CONFIG_PLATFORM_EC_USB_PD_FRS=y CONFIG_PLATFORM_EC_USB_PD_FRS_PPC=y +CONFIG_PLATFORM_EC_USB_PD_LOGGING=y CONFIG_PLATFORM_EC_USB_PD_REV30=y CONFIG_PLATFORM_EC_USB_PD_TCPC_LOW_POWER=y CONFIG_PLATFORM_EC_USB_PD_TCPM_TCPCI=y diff --git a/zephyr/program/rex/rex-sans-sensors/project.overlay b/zephyr/program/rex/rex-sans-sensors/project.overlay index 59f3f5ae6d..d292714a25 100644 --- a/zephyr/program/rex/rex-sans-sensors/project.overlay +++ b/zephyr/program/rex/rex-sans-sensors/project.overlay @@ -9,7 +9,7 @@ &i2c0_0 { status = "disabled"; }; -&i2c_ec_i2c_sensor { +&i2c_ec_i2c_sensor_scl_r { status = "disabled"; }; &int_imu { diff --git a/zephyr/program/rex/rex.dtsi b/zephyr/program/rex/rex.dtsi index 83d10b95d1..52e5cfe1a5 100644 --- a/zephyr/program/rex/rex.dtsi +++ b/zephyr/program/rex/rex.dtsi @@ -44,30 +44,25 @@ gpios = <&gpiod 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; }; - /* - * The pinmap utility does not currently support ACTIVE_LOW - * flag. So it is set here. - */ - /delete-node/ usb_c0_tcpc_int_odl; - /delete-node/ usb_c1_tcpc_int_odl; - gpio_usb_c0_tcpc_int_odl: usb_c0_tcpc_int_odl { - gpios = <&gpioe 0 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; - enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; + /* Overrides for generated.dtsi */ + ec_edp_bl_en { + gpios = <&gpiod 3 GPIO_OUTPUT_LOW>; }; - gpio_usb_c1_tcpc_int_odl: usb_c1_tcpc_int_odl { - gpios = <&gpio3 4 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; - enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; + en_pp5000_fan { + gpios = <&gpio6 1 GPIO_OUTPUT_LOW>; }; - /delete-node/ usb_c0_tcpc_rst_odl; - /delete-node/ usb_c1_rt_rst_r_odl; - gpio_usb_c0_tcpc_rst_odl: usb_c0_tcpc_rst_odl { + usb_c0_tcpc_rst_odl { gpios = <&gpio6 7 (GPIO_ODR_HIGH | GPIO_ACTIVE_LOW)>; }; - gpio_usb_c1_rt_rst_r_odl: usb_c1_rt_rst_r_odl { + usb_c1_rt_rst_r_odl { gpios = <&gpio7 4 (GPIO_ODR_HIGH | GPIO_ACTIVE_LOW)>; }; - ec_wp_l { - gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + + /* Special I2C port attribute */ + named-i2c-ports { + ec_i2c_usb_c1_tcp { + dynamic-speed; }; }; diff --git a/zephyr/program/rex/rex/led_pins.dtsi b/zephyr/program/rex/rex/led_pins.dtsi index e1d08ab9d2..7a4ff16273 100644 --- a/zephyr/program/rex/rex/led_pins.dtsi +++ b/zephyr/program/rex/rex/led_pins.dtsi @@ -7,50 +7,49 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off_left: color-off-left { - led-color = "LED_OFF"; + left_led: left-led { led-id = "EC_LED_ID_LEFT_LED"; led-pins = <&gpio_led_1_l &gpio_led_2_l>; - led-values = <1 1>; - }; + color_off_left: color-off-left { + led-color = "LED_OFF"; + led-values = <1 1>; + }; - color_off_right: color-off-right { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_RIGHT_LED"; - led-pins = <&gpio_led_3_l &gpio_led_4_l>; - led-values = <1 1>; - }; + color_amber_left: color-amber-left { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <0 1>; + }; - color_amber_left: color-amber-left { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pins = <&gpio_led_1_l &gpio_led_2_l>; - led-values = <0 1>; + color_white_left: color-white-left { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <1 0>; + }; }; - color_amber_right: color-amber-right { - led-color = "LED_AMBER"; + right_led: right-led { led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_AMBER"; led-pins = <&gpio_led_3_l &gpio_led_4_l>; - led-values = <0 1>; - }; - color_white_left: color-white-left { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_led_1_l &gpio_led_2_l>; - led-values = <1 0>; - }; + color_off_right: color-off-right { + led-color = "LED_OFF"; + led-values = <1 1>; + }; - color_white_right: color-white-right { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_led_3_l &gpio_led_4_l>; - led-values = <1 0>; + + color_amber_right: color-amber-right { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <0 1>; + }; + + + color_white_right: color-white-right { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <1 0>; + }; }; }; }; diff --git a/zephyr/program/rex/screebo/CMakeLists.txt b/zephyr/program/rex/screebo/CMakeLists.txt new file mode 100644 index 0000000000..16a5240f3d --- /dev/null +++ b/zephyr/program/rex/screebo/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cros_ec_library_include_directories_ifdef(CONFIG_BOARD_SCREEBO include) +zephyr_library_sources("src/keyboard.c" "src/usb_config.c") diff --git a/zephyr/program/rex/screebo/project.conf b/zephyr/program/rex/screebo/project.conf new file mode 100644 index 0000000000..c3ee418874 --- /dev/null +++ b/zephyr/program/rex/screebo/project.conf @@ -0,0 +1,34 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Screebo-NPCX9 variant-board-specific Kconfig settings. +CONFIG_BOARD_SCREEBO=y + +# Battery Configuration +CONFIG_PLATFORM_EC_BATT_HOST_FULL_FACTOR=99 +CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT=10 +CONFIG_PLATFORM_EC_SMBUS_PEC=y + +# Buttons +CONFIG_PLATFORM_EC_VOLUME_BUTTONS=n + +# Keyboard +CONFIG_PLATFORM_EC_KEYBOARD_REFRESH_ROW3=y +CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI3=y + +# No sensors +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=n +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=n +CONFIG_PLATFORM_EC_ACCEL_FIFO=n +CONFIG_PLATFORM_EC_ALS_TCS3400=n +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=n +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=n +CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_SPEED=n +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=n +CONFIG_PLATFORM_EC_GMR_TABLET_MODE=n +CONFIG_PLATFORM_EC_LID_ANGLE=n +CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=n +CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=n +CONFIG_PLATFORM_EC_TABLET_MODE=n +CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=n diff --git a/zephyr/program/rex/screebo/project.overlay b/zephyr/program/rex/screebo/project.overlay new file mode 100644 index 0000000000..35156be4f4 --- /dev/null +++ b/zephyr/program/rex/screebo/project.overlay @@ -0,0 +1,191 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Rex program common DTSI includes */ +#include "../fan.dtsi" +#include "../generated.dtsi" +#include "../interrupts.dtsi" +#include "../keyboard.dtsi" +#include "../power_signals.dtsi" +#include "../rex.dtsi" +#include "../usbc.dtsi" + +/* Screebo project DTS includes */ +#include "temp_sensors.dtsi" + +/ { + named-gpios { + /delete-node/ led_3_l; + /delete-node/ led_4_l; + /delete-node/ ec-i2c-sensor-scl; + /delete-node/ ec-i2c-sensor-sda; + /delete-node/ ec_imu_int_r_l; + /delete-node/ ec_als_rgb_int_r_l; + /delete-node/ ec_accel_int_r_l; + /delete-node/ ec_volup_btn_odl; + /delete-node/ ec_voldn_btn_odl; + /delete-node/ tablet_mode_l; + /delete-node/ ec_spare_gpiob1; + /delete-node/ ec_spare_gpioa2; + /delete-node/ usb_c1_rst_odl; + + gpio_usb_c1_rt_3p3_sx_en: usb_c1_rt_3p3_sx_en { + gpios = <&gpiob 1 GPIO_OUTPUT_LOW>; + }; + gpio_usb_c1_rst_odl: usb_c1_rst_odl { + gpios = <&gpio3 7 (GPIO_ODR_HIGH | GPIO_ACTIVE_LOW)>; + }; + gpio_usb_c1_rt_int_odl: usb_c1_rt_int_odl { + gpios = <&gpio7 2 GPIO_INPUT>; + }; + gpio_usb_a1_oc_pu_en: usb_a1_oc_pu_en { + gpios = <&gpioc 2 GPIO_OUTPUT_LOW>; + }; + gpio_usb_a_low_pwr_od: usb_a_low_pwr_od { + gpios = <&gpioa 2 GPIO_OUTPUT_LOW>; + }; + ioex_usb_c1_rt_rst_ls_l: usb_c1_rt_rst_ls_l { + gpios = <&ioex_c1_port0 7 GPIO_OUTPUT>; + }; + ioex_usb_c1_frs_en: usb_c1_frs_en { + gpios = <&ioex_c1_port0 6 GPIO_OUTPUT_LOW>; + }; + + }; + + unused-pins { + compatible = "unused-gpios"; + + unused-gpios = + <&gpiob 4 0>, + <&gpiob 5 0>, + <&gpio5 6 0>, + <&gpiod 4 0>, + <&gpio8 1 0>, + <&gpio9 7 0>, + <&gpio9 3 0>, + <&gpio9 5 0>, + <&gpio6 0 0>; + }; + + gpio-interrupts { + /delete-node/ ec_imu; + /delete-node/ ec_als_rgb; + /delete-node/ ec_accel; + /delete-node/ volume_up; + /delete-node/ volume_down; + usb_c0_ppc { + handler = "screebo_ppc_interrupt"; + }; + usb_c1_ppc { + handler = "screebo_ppc_interrupt"; + }; + }; + + named-i2c-ports { + /delete-node/ ec_i2c_sensor_scl_r; + }; + + batteries { + default_battery: cdt_c340152 { + compatible = "cdt,c340152", "battery-smart"; + }; + }; +}; + +/* ADC and GPIO alt-function specifications */ +&adc0 { + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan3_gp42 + &adc0_chan7_gpe1 + &adc0_chan8_gpf1 + &adc0_chan11_gpc7>; + pinctrl-names = "default"; +}; + +&i2c0_0 { + status = "disabled"; +}; +&i2c_ctrl0 { + status = "disabled"; +}; + +&i2c3_0 { + usb_c1_hb_retimer: jhl9040r-c0@58 { + compatible = "intel,jhl9040r"; + reg = <0x58>; + ls-en-pin = <&gpio_usb_c1_rt_3p3_sx_en>; + int-pin = <&gpio_usb_c1_rt_int_odl>; + reset-pin = <&ioex_usb_c1_rt_rst_ls_l>; + }; +}; + +&i2c4_1 { + /delete-node/ ps8xxx@b; + + tcpc_port1: nct38xx@73 { + compatible = "nuvoton,nct38xx"; + gpio-dev = <&nct3807_C1>; + reg = <0x73>; + tcpc-flags = <( + TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V)>; + /* a duplicate of the <&gpio_usb_c1_tcpc_int_odl> node in + * "named-gpios". This is the Zephyr preferred style, + * the "named-gpios" node will be dealt with at a later date. + */ + irq-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + /* a duplicate of the <&gpio_usb_c1_rst_odl> node in + * "named-gpios". This is the Zephyr preferred style, + * the "named-gpios" node will be dealt with at a later date. + */ + rst-gpios = <&gpio3 7 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; + }; + + nct3807_C1: nct3807_C1@73 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,nct38xx-gpio"; + reg = <0x73>; + label = "NCT3807_C1"; + + ioex_c1_port0: gpio@0 { + compatible = "nuvoton,nct38xx-gpio-port"; + reg = <0x0>; + label = "NCT3807_C1_GPIO0"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin_mask = <0xff>; + pinmux_mask = <0xf7>; + }; + }; + + nct3808_alert_1 { + compatible = "nuvoton,nct38xx-gpio-alert"; + irq-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + nct38xx-dev = <&nct3807_C1>; + label = "NCT3807_ALERT_0"; + }; +}; + +&i2c6_1 { + /delete-node/ nx20p348x@72; + + ppc_port1_syv: ppc_syv@40 { + compatible = "silergy,syv682x"; + status = "okay"; + reg = <0x40>; + frs_en_gpio = <&ioex_usb_c1_frs_en>; + }; +}; + +&usbc_port1 { + ppc = <&ppc_port1_syv>; + usb-mux-chain-1 { + usb-muxes = <&usb_c1_hb_retimer &virtual_mux_c1>; + }; +}; diff --git a/zephyr/program/rex/screebo/src/keyboard.c b/zephyr/program/rex/screebo/src/keyboard.c new file mode 100644 index 0000000000..5a9818ba7a --- /dev/null +++ b/zephyr/program/rex/screebo/src/keyboard.c @@ -0,0 +1,28 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config screebo_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ + }, +}; + +__override const struct ec_response_keybd_config * +board_vivaldi_keybd_config(void) +{ + return &screebo_kb; +} diff --git a/zephyr/program/rex/screebo/src/usb_config.c b/zephyr/program/rex/screebo/src/usb_config.c new file mode 100644 index 0000000000..41653832bd --- /dev/null +++ b/zephyr/program/rex/screebo/src/usb_config.c @@ -0,0 +1,29 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Screebo board-specific USB-C configuration */ + +#include "ppc/syv682x_public.h" +#include "usbc_ppc.h" + +#include <zephyr/drivers/gpio.h> + +/* USB-C ports */ +enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; +BUILD_ASSERT(USBC_PORT_COUNT == CONFIG_USB_PD_PORT_MAX_COUNT); + +void screebo_ppc_interrupt(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_USB_C0_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C0); + break; + case GPIO_USB_C1_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C1); + break; + default: + break; + } +} diff --git a/zephyr/program/rex/screebo/temp_sensors.dtsi b/zephyr/program/rex/screebo/temp_sensors.dtsi new file mode 100644 index 0000000000..f4747b96a5 --- /dev/null +++ b/zephyr/program/rex/screebo/temp_sensors.dtsi @@ -0,0 +1,103 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + named-adc-channels { + /delete-node/ temp_sensor_1; + /delete-node/ temp_sensor_2; + /delete-node/ temp_sensor_3; + /delete-node/ temp_sensor_4; + + adc_ddr_soc: ddr_soc { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_vcc: vcc { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_ambient: ambient { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 8>; + }; + adc_charger: charger { + enum-name = "ADC_TEMP_SENSOR_4"; + io-channels = <&adc0 7>; + }; + adc_hw_shutdown: hw_shutdown { + enum-name = "ADC_TEMP_SENSOR_5"; + io-channels = <&adc0 3>; + }; + adc_typec: typec { + enum-name = "ADC_TEMP_SENSOR_6"; + io-channels = <&adc0 11>; + }; + }; + + temp_ddr_soc: ddr_soc { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_ddr_soc>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_ambient>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_charger>; + }; + temp_vcc: vcc { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_vcc>; + }; + temp_hw_shutdown: hw_shutdown { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_hw_shutdown>; + }; + temp_typec: typec { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + adc = <&adc_typec>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + ddr_soc { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <90>; + temp_host_halt = <95>; + temp_host_release_high = <85>; + sensor = <&temp_ddr_soc>; + }; + ambient { + temp_fan_off = <30>; + temp_fan_max = <50>; + temp_host_high = <65>; + temp_host_halt = <75>; + temp_host_release_high = <60>; + sensor = <&temp_ambient>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <85>; + temp_host_high = <100>; + temp_host_halt = <110>; + temp_host_release_high = <95>; + sensor = <&temp_charger>; + }; + }; +}; + +&thermistor_3V3_30K9_47K_4050B { + status = "okay"; +}; diff --git a/zephyr/program/rex/temp_sensors.dtsi b/zephyr/program/rex/temp_sensors.dtsi index 680ebc8954..3c90dc9d8d 100644 --- a/zephyr/program/rex/temp_sensors.dtsi +++ b/zephyr/program/rex/temp_sensors.dtsi @@ -9,22 +9,22 @@ temp_ddr_soc: ddr_soc { compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; - adc = <&adc_ddr_soc>; + adc = <&adc_temp_sensor_1>; }; temp_ambient: ambient { compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; - adc = <&adc_ambient>; + adc = <&adc_temp_sensor_2>; }; temp_charger: charger { compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; - adc = <&adc_charger>; + adc = <&adc_temp_sensor_3>; }; temp_wwan: wwan { compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; - adc = <&adc_wwan>; + adc = <&adc_temp_sensor_4>; }; named-temp-sensors { diff --git a/zephyr/program/skyrim/CMakeLists.txt b/zephyr/program/skyrim/CMakeLists.txt index 2468d1f44d..672a22a5bf 100644 --- a/zephyr/program/skyrim/CMakeLists.txt +++ b/zephyr/program/skyrim/CMakeLists.txt @@ -6,6 +6,8 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}") +zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") + zephyr_library_sources("src/common.c") zephyr_library_sources("src/power_signals.c") diff --git a/zephyr/program/skyrim/crystaldrift/led_pins.dtsi b/zephyr/program/skyrim/crystaldrift/led_pins.dtsi index b7c7325ded..ec0d93de8d 100644 --- a/zephyr/program/skyrim/crystaldrift/led_pins.dtsi +++ b/zephyr/program/skyrim/crystaldrift/led_pins.dtsi @@ -10,29 +10,26 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pins = <&gpio_ec_chg_led_r &gpio_ec_chg_led_b>; - led-values = <0 0>; - }; - color_red: color-red { - led-color = "LED_RED"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_RED"; - led-pins = <&gpio_ec_chg_led_r &gpio_ec_chg_led_b>; - led-values = <1 0>; - }; - - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_r &gpio_ec_chg_led_b>; - led-values = <0 1>; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + + color_red: color-red { + led-color = "LED_RED"; + br-color = "EC_LED_COLOR_RED"; + led-values = <1 0>; + }; + + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 1>; + }; }; }; }; - - diff --git a/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c b/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c index 4f875bc3ab..bc5b61279e 100644 --- a/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c +++ b/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c @@ -13,6 +13,7 @@ #include "ioexpander.h" #include "usb_mux.h" #include "usbc/usb_muxes.h" +#include "ztest/usb_mux_config.h" #include <zephyr/drivers/gpio.h> @@ -23,7 +24,7 @@ * USB C0 (general) and C1 (just ANX DB) use IOEX pins to * indicate flipped polarity to a protection switch. */ -static int ioex_set_flip(int port, mux_state_t mux_state) +test_export_static int ioex_set_flip(int port, mux_state_t mux_state) { if (port == 0) { if (mux_state & USB_PD_MUX_POLARITY_INVERTED) diff --git a/zephyr/program/skyrim/frostflow/led_pins.dtsi b/zephyr/program/skyrim/frostflow/led_pins.dtsi index 78b9a59c40..28766c5271 100644 --- a/zephyr/program/skyrim/frostflow/led_pins.dtsi +++ b/zephyr/program/skyrim/frostflow/led_pins.dtsi @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_w>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/skyrim/frostflow/project.conf b/zephyr/program/skyrim/frostflow/project.conf index a97a3e5989..9567aaf814 100644 --- a/zephyr/program/skyrim/frostflow/project.conf +++ b/zephyr/program/skyrim/frostflow/project.conf @@ -25,3 +25,5 @@ CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y # Fan CONFIG_PLATFORM_EC_CUSTOM_FAN_CONTROL=y + +CONFIG_PLATFORM_EC_USB_PD_STARTUP_DELAY_MS=150 diff --git a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c index d018ff12f3..b73c6370b8 100644 --- a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c +++ b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c @@ -11,19 +11,13 @@ #include "driver/retimer/ps8811.h" #include "hooks.h" #include "i2c.h" +#include "i2c/i2c.h" #include "ioexpander.h" #include "timer.h" #include "usb_mux.h" #include "usbc/usb_muxes.h" #include "util.h" -#ifdef CONFIG_ZTEST -/* Verify this is still needed for b/247151116. */ -#undef I2C_PORT_NODELABEL -#define I2C_PORT_NODELABEL(x) 0 - -#endif /* CONFIG_ZTEST */ - #define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ##args) #define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ##args) @@ -36,7 +30,7 @@ struct ps8811_reg_val { * USB C0 (general) and C1 (just ps8815 DB) use IOEX pins to * indicate flipped polarity to a protection switch. */ -static int ioex_set_flip(int port, mux_state_t mux_state) +test_export_static int ioex_set_flip(int port, mux_state_t mux_state) { if (port == 0) { if (mux_state & USB_PD_MUX_POLARITY_INVERTED) diff --git a/zephyr/program/skyrim/include/ztest/usb_mux_config.h b/zephyr/program/skyrim/include/ztest/usb_mux_config.h new file mode 100644 index 0000000000..727cdf0654 --- /dev/null +++ b/zephyr/program/skyrim/include/ztest/usb_mux_config.h @@ -0,0 +1,19 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef __SKYRIM_TEST_USB_MUX_CONFIG +#define __SKYRIM_TEST_USB_MUX_CONFIG + +#ifdef CONFIG_ZTEST + +#include <zephyr/fff.h> + +DECLARE_FAKE_VOID_FUNC(usb_mux_enable_alternative); + +#undef USB_MUX_ENABLE_ALTERNATIVE +#define USB_MUX_ENABLE_ALTERNATIVE(x) usb_mux_enable_alternative() + +#endif /* CONFIG_ZTEST */ + +#endif /* __SKYRIM_TEST_USB_MUX_CONFIG */ diff --git a/zephyr/program/skyrim/markarth/led_pins.dtsi b/zephyr/program/skyrim/markarth/led_pins.dtsi index c662dcc575..73a8b8c8fa 100644 --- a/zephyr/program/skyrim/markarth/led_pins.dtsi +++ b/zephyr/program/skyrim/markarth/led_pins.dtsi @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_w>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/skyrim/markarth/src/usb_mux_config.c b/zephyr/program/skyrim/markarth/src/usb_mux_config.c index b87174f35c..41015df680 100644 --- a/zephyr/program/skyrim/markarth/src/usb_mux_config.c +++ b/zephyr/program/skyrim/markarth/src/usb_mux_config.c @@ -13,6 +13,7 @@ #include "ioexpander.h" #include "usb_mux.h" #include "usbc/usb_muxes.h" +#include "ztest/usb_mux_config.h" #include <zephyr/drivers/gpio.h> @@ -23,7 +24,7 @@ * USB C0 (general) and C1 (just ANX DB) use IOEX pins to * indicate flipped polarity to a protection switch. */ -static int ioex_set_flip(int port, mux_state_t mux_state) +test_export_static int ioex_set_flip(int port, mux_state_t mux_state) { if (port == 0) { if (mux_state & USB_PD_MUX_POLARITY_INVERTED) diff --git a/zephyr/program/skyrim/skyrim/led_pins.dtsi b/zephyr/program/skyrim/skyrim/led_pins.dtsi index 78b9a59c40..28766c5271 100644 --- a/zephyr/program/skyrim/skyrim/led_pins.dtsi +++ b/zephyr/program/skyrim/skyrim/led_pins.dtsi @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_w>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/skyrim/skyrim/src/usb_mux_config.c b/zephyr/program/skyrim/skyrim/src/usb_mux_config.c index 17e452a778..2351144849 100644 --- a/zephyr/program/skyrim/skyrim/src/usb_mux_config.c +++ b/zephyr/program/skyrim/skyrim/src/usb_mux_config.c @@ -13,16 +13,10 @@ #include "ioexpander.h" #include "usb_mux.h" #include "usbc/usb_muxes.h" +#include "ztest/usb_mux_config.h" #include <zephyr/drivers/gpio.h> -#ifdef CONFIG_ZTEST - -#undef USB_MUX_ENABLE_ALTERNATIVE -#define USB_MUX_ENABLE_ALTERNATIVE(x) - -#endif /* CONFIG_ZTEST */ - #define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ##args) #define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ##args) @@ -30,7 +24,7 @@ * USB C0 (general) and C1 (just ANX DB) use IOEX pins to * indicate flipped polarity to a protection switch. */ -static int ioex_set_flip(int port, mux_state_t mux_state) +test_export_static int ioex_set_flip(int port, mux_state_t mux_state) { if (port == 0) { if (mux_state & USB_PD_MUX_POLARITY_INVERTED) @@ -129,7 +123,7 @@ int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state) return 0; } -static void setup_mux(void) +test_export_static void setup_mux(void) { uint32_t val; diff --git a/zephyr/program/skyrim/src/power_signals.c b/zephyr/program/skyrim/src/power_signals.c index b0919ae5f4..5814359606 100644 --- a/zephyr/program/skyrim/src/power_signals.c +++ b/zephyr/program/skyrim/src/power_signals.c @@ -3,6 +3,10 @@ * found in the LICENSE file. */ +#ifdef CONFIG_ZTEST +#define CHARGER_SOLO 0 +#endif + #include "ap_power/ap_power.h" #include "charger.h" #include "chipset.h" @@ -52,8 +56,9 @@ const struct prochot_cfg prochot_cfg = { }; /* Chipset hooks */ -static void baseboard_suspend_change(struct ap_power_ev_callback *cb, - struct ap_power_ev_data data) +test_export_static void +baseboard_suspend_change(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) { switch (data.event) { default: @@ -91,7 +96,7 @@ static void handle_prochot(bool asserted, void *data) ccprints("Charger prochot deasserted externally"); } -static void baseboard_init(void) +test_export_static void baseboard_init(void) { static struct ap_power_ev_callback cb; const struct gpio_dt_spec *gpio_ec_sfh_int_h = diff --git a/zephyr/program/skyrim/winterhold/led_pins.dtsi b/zephyr/program/skyrim/winterhold/led_pins.dtsi index 78b9a59c40..28766c5271 100644 --- a/zephyr/program/skyrim/winterhold/led_pins.dtsi +++ b/zephyr/program/skyrim/winterhold/led_pins.dtsi @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_w>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_white: color-white { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwm_y &pwm_w>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_white: color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/skyrim/winterhold/motionsense.dtsi b/zephyr/program/skyrim/winterhold/motionsense.dtsi index b66f6a34cc..03f30d44be 100644 --- a/zephyr/program/skyrim/winterhold/motionsense.dtsi +++ b/zephyr/program/skyrim/winterhold/motionsense.dtsi @@ -76,11 +76,12 @@ configs { compatible = "cros-ec,motionsense-sensor-config"; + /* 50 Hz to support body detection. */ ec-s0 { - odr = <(12500 | ROUND_UP_FLAG)>; + odr = <(50000 | ROUND_UP_FLAG)>; }; ec-s3 { - odr = <(12500 | ROUND_UP_FLAG)>; + odr = <(50000 | ROUND_UP_FLAG)>; }; }; }; diff --git a/zephyr/program/skyrim/winterhold/project.conf b/zephyr/program/skyrim/winterhold/project.conf index 27f1c60c88..3521417c68 100644 --- a/zephyr/program/skyrim/winterhold/project.conf +++ b/zephyr/program/skyrim/winterhold/project.conf @@ -51,3 +51,6 @@ CONFIG_PLATFORM_EC_GESTURE_HOST_DETECTION=y # GPIO configuration CONFIG_GPIO_GET_CONFIG=y + +# FAN +CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL=y diff --git a/zephyr/program/skyrim/winterhold/project.overlay b/zephyr/program/skyrim/winterhold/project.overlay index a348b0f55c..818c625fe9 100644 --- a/zephyr/program/skyrim/winterhold/project.overlay +++ b/zephyr/program/skyrim/winterhold/project.overlay @@ -197,6 +197,7 @@ rpm_min = <2100>; rpm_start = <2800>; rpm_max = <4800>; + rpm_deviation = <3>; }; /* temperature sensor overrides */ diff --git a/zephyr/program/skyrim/winterhold/src/thermal.c b/zephyr/program/skyrim/winterhold/src/thermal.c index 82b802f2ee..00e162e45a 100644 --- a/zephyr/program/skyrim/winterhold/src/thermal.c +++ b/zephyr/program/skyrim/winterhold/src/thermal.c @@ -4,9 +4,11 @@ */ #include "body_detection.h" +#include "fan.h" #include "hooks.h" #include "host_command.h" #include "lid_switch.h" +#include "math_util.h" #include "temp_sensor/temp_sensor.h" #include "thermal.h" @@ -138,7 +140,7 @@ __maybe_unused static const struct ec_thermal_config fan_soc_laptop = */ #define FAN_CPU_DESKTOP_LID_OPEN \ { \ - .temp_fan_off = C_TO_K(76), .temp_fan_max = C_TO_K(82), \ + .temp_fan_off = C_TO_K(72), .temp_fan_max = C_TO_K(82), \ } __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_open = FAN_CPU_DESKTOP_LID_OPEN; @@ -148,7 +150,7 @@ __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_open = */ #define FAN_CPU_DESKTOP_LID_CLOSE \ { \ - .temp_fan_off = C_TO_K(76), .temp_fan_max = C_TO_K(82), \ + .temp_fan_off = C_TO_K(72), .temp_fan_max = C_TO_K(82), \ } __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_close = FAN_CPU_DESKTOP_LID_CLOSE; @@ -158,7 +160,7 @@ __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_close = */ #define FAN_CPU_LAPTOP \ { \ - .temp_fan_off = C_TO_K(72), .temp_fan_max = C_TO_K(78), \ + .temp_fan_off = C_TO_K(68), .temp_fan_max = C_TO_K(78), \ } __maybe_unused static const struct ec_thermal_config fan_cpu_laptop = FAN_CPU_LAPTOP; @@ -209,3 +211,82 @@ static void detect_temp_change(void) } } DECLARE_HOOK(HOOK_SECOND, detect_temp_change, HOOK_PRIO_TEMP_SENSOR_DONE); + +#ifdef CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + +K_TIMER_DEFINE(grace_period_timer, NULL, NULL); + +enum fan_status board_override_fan_control_duty(int ch) +{ + int duty, rpm_diff, deviation, duty_step; + struct fan_data *data = &fan_data[ch]; + int rpm_actual = data->rpm_actual; + int rpm_target = data->rpm_target; + + /* This works with one fan only. */ + if (ch != 0) { + CPRINTS("Only FAN0 is supported!"); + return FAN_STATUS_FRUSTRATED; + } + + /* Wait for fan RPM to catch up after its duty has been changed. */ + if (k_timer_remaining_ticks(&grace_period_timer) != 0) + return FAN_STATUS_LOCKED; + + duty = fan_get_duty(ch); + if (duty == 0 && rpm_target == 0) + return FAN_STATUS_STOPPED; + + /* + * If the current RPM is close enough to the target just leave it. + * It's always going to fluctuate a bit anyway. + */ + deviation = fans[ch].rpm->rpm_deviation * rpm_target / 100; + rpm_diff = rpm_target - rpm_actual; + if (rpm_diff > deviation) { + /* Can't set duty higher than 100%... */ + if (duty == 100) + return FAN_STATUS_FRUSTRATED; + } else if (rpm_diff < -deviation) { + /* Can't set duty lower than 1%... */ + if (duty == 1 && rpm_target != 0) + return FAN_STATUS_FRUSTRATED; + } else { + return FAN_STATUS_LOCKED; + } + + /* + * The rpm_diff -> duty_step conversion is specific to a specific + * whiterun fan. + * It has been determined empirically. + */ + if (ABS(rpm_diff) >= 2500) { + duty_step = 35; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 2000) { + duty_step = 28; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 1000) { + duty_step = 14; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 500) { + duty_step = 6; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 250) { + duty_step = 3; + k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); + } else { + duty_step = 1; + k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); + } + + if (rpm_diff > 0) + duty = MIN(duty + duty_step, 100); + else + duty = MAX(duty - duty_step, 1); + + fan_set_duty(ch, duty); + + return FAN_STATUS_CHANGING; +} +#endif diff --git a/zephyr/program/skyrim/winterhold/src/usb_mux_config.c b/zephyr/program/skyrim/winterhold/src/usb_mux_config.c index 8a4bf861d1..b4a8bc2662 100644 --- a/zephyr/program/skyrim/winterhold/src/usb_mux_config.c +++ b/zephyr/program/skyrim/winterhold/src/usb_mux_config.c @@ -24,7 +24,7 @@ * USB C0 (general) and C1 (just ANX DB) use IOEX pins to * indicate flipped polarity to a protection switch. */ -static int ioex_set_flip(int port, mux_state_t mux_state) +test_export_static int ioex_set_flip(int port, mux_state_t mux_state) { if (port == 0) { if (mux_state & USB_PD_MUX_POLARITY_INVERTED) diff --git a/zephyr/program/trogdor/lazor/pwm_led.dts b/zephyr/program/trogdor/lazor/pwm_led.dts index f8375b3596..507019f4ef 100644 --- a/zephyr/program/trogdor/lazor/pwm_led.dts +++ b/zephyr/program/trogdor/lazor/pwm_led.dts @@ -17,27 +17,26 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color_off: color-off { - led-color = "LED_OFF"; + battery_led: battery-led { led-id = "EC_LED_ID_BATTERY_LED"; led-pwms = <&pwm_y &pwm_b>; - led-values = <0 0>; - }; - color_amber: color-amber { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwm_y &pwm_b>; - led-values = <100 0>; - }; + color_off: color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; - color_blue: color-blue { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_BATTERY_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pwms = <&pwm_y &pwm_b>; - led-values = <0 100>; + color_amber: color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + + color_blue: color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <0 100>; + }; }; }; }; diff --git a/zephyr/program/trogdor/lazor/src/power.c b/zephyr/program/trogdor/lazor/src/power.c index ee99c77196..5661fa8049 100644 --- a/zephyr/program/trogdor/lazor/src/power.c +++ b/zephyr/program/trogdor/lazor/src/power.c @@ -45,7 +45,7 @@ static void board_power_change(struct ap_power_ev_callback *cb, } } -static int board_power_handler_init(const struct device *unused) +static int board_power_handler_init(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/scripts/named_gpios.py b/zephyr/scripts/named_gpios.py index d71c2483f8..2eaf344e7f 100644 --- a/zephyr/scripts/named_gpios.py +++ b/zephyr/scripts/named_gpios.py @@ -9,13 +9,14 @@ import inspect import logging from pathlib import Path import pickle +import re import site import sys from typing import List, Optional -def verify_no_duplicates(zephyr_base, edt_pickle): - """Verify there are no duplicate GPIOs in the named-gpios node. +def _load_edt(zephyr_base, edt_pickle): + """Load an EDT object from a pickle file source. Args: zephyr_base: pathlib.Path pointing to the Zephyr OS repository. @@ -23,7 +24,12 @@ def verify_no_duplicates(zephyr_base, edt_pickle): file. Returns: - True if no duplicates found. Returns False otherwise. + A 3-field tuple: (edtlib, edt, project_name) + edtlib: module object for the edtlib + edt: EDT object of the devicetree + project_name: string containing the name of the project or test. + + Returns None if the edtlib pickle file doesn't exist. """ zephyr_devicetree_path = ( zephyr_base / "scripts" / "dts" / "python-devicetree" / "src" @@ -36,17 +42,171 @@ def verify_no_duplicates(zephyr_base, edt_pickle): with open(edt_pickle, "rb") as edt_file: edt = pickle.load(edt_file) except FileNotFoundError: - # Skip the GPIOs check if the edt_pickle file doesn't exist. - # UnpicklingErrors will generate a failure. + # Skip the all EC specific checks if the edt_pickle file doesn't exist. + # UnpicklingErrors will raise an exception and fail the build. + return None, None, None + + is_test = re.compile(r"twister-out") + + if is_test.search(edt_pickle.as_posix()): + # For tests built with twister, the edt.pickle file is located in a + # path ending <test_name>/zephyr/. + project_name = edt_pickle.parents[1].name + else: + # For Zephyr EC project, the edt.pickle file is located in a path + # ending <project>/build-[ro|rw|single-image]/zephyr/. + project_name = edt_pickle.parents[2].name + + edtlib = inspect.getmodule(edt) + + return edtlib, edt, project_name + + +def _detect_gpios_mismatches(node_name, prop_name, prop_gpios, board_gpios): + """Verify that all GPIO entries in a -gpios style property match the flags + specified in the named-gpios node. + + Args: + node_name - The name of the node containing the -gpios style property. + prop_name - The name of the -gpios style property. + prop_gpios - An edtlib.ControllerAndData class object containing + the GPIO tuples found in the property. + board_gpios - A dictionary that maps gpio port/pin tuples to the GPIO + flags. This dictionary is initialized from the children + found in the named-gpios devicetree node. + + Returns: + A tuple indicating how many GPIOs were checked, and how many GPIOs + had a mismatch. + """ + errors = 0 + count = 0 + + # The -gpios property may be an array of GPIO tuples + for gpio in prop_gpios: + count += 1 + gpio_pin = gpio.data["pin"] + + # The "flags" cell should be only 16-bits + dt_flags = gpio.data["flags"] & 0xFFFF + + if gpio.controller.labels[0] is not None: + nodelabel = gpio.controller.labels[0] + else: + nodelabel = gpio.controller.name + + if (nodelabel, gpio_pin) not in board_gpios.keys(): + # GPIO not specified in named-gpios + logging.debug( + "Warning: property %s/%s = <%s %s 0x%x> not found in named-gpios", + node_name, + prop_name, + nodelabel, + gpio_pin, + dt_flags, + ) + continue + + if dt_flags != board_gpios[(nodelabel, gpio_pin)]: + errors += 1 + logging.error( + "ERROR: property %s/%s = <%s %s 0x%x>. Flags don't match named-gpios 0x%x", + node_name, + prop_name, + nodelabel, + gpio_pin, + dt_flags, + board_gpios[(nodelabel, gpio_pin)], + ) + + return count, errors + + +def verify_gpios_flags_match(edtlib, edt, project_name): + """Check that GPIO flags used across devices matches. + + Until all drivers are upstream, the Zephyr EC devicetrees specify GPIOs + in multiple locations: the "named-gpios" node performs the configuration + of all GPIOs on the board, and individual drivers may also configure GPIOs. + + This routine finds all "*-gpios" style properties in the devicetree and + cross-checks the flags set by "named-gpios" and ensures they match. + + Args: + edtlib: Module object for the edtlib library. + edt: EDT object representation of a devicetree + project_name: A string containing the project/test name + + Returns: + True if no GPIO flag mismatches found. Returns False otherwise. + """ + try: + named_gpios = edt.get_node("/named-gpios") + except edtlib.EDTError: + # If the named-gpios node doesn't exist, return success. return True + # Dictionary using the gpio,pin tuple as the key. Value set to the flags + board_gpios = dict() + for node in named_gpios.children.values(): + if "gpios" not in node.props: + continue + + gpios = node.props["gpios"].val + + # edtlib converts a "-gpios" style property to a list of of + # ControllerAndData objects. However, the named-gpios node only + # supports a single GPIO per child, so no need to iterate over + # the list. + gpio = gpios[0] + gpio_pin = gpio.data["pin"] + + if gpio.controller.labels[0] is not None: + nodelabel = gpio.controller.labels[0] + else: + nodelabel = gpio.controller.name + + # The named-gpios stores a 32-bit flags, but Zephyr GPIO flags + # are limited to the lower 16-bits + board_gpios[(nodelabel, gpio_pin)] = gpio.data["flags"] & 0xFFFF + + errors = 0 + count = 0 + for node in edt.nodes: + for prop_name in node.props.keys(): + if prop_name.endswith("-gpios"): + gpios = node.props[prop_name].val + + prop_gpio_count, prop_gpio_errors = _detect_gpios_mismatches( + node.name, prop_name, gpios, board_gpios + ) + count += prop_gpio_count + errors += prop_gpio_errors + + if errors: + logging.error("%d GPIO mismatches found in %s.", errors, project_name) + return False + + logging.info("Verified %d '*-gpios' properties, all flags match", count) + return True + + +def verify_no_duplicates(edtlib, edt, project_name): + """Verify there are no duplicate GPIOs in the named-gpios node. + + Args: + edtlib: Module object for the edtlib library. + edt: EDT object representation of a devicetree + project_name: A string containing the project/test name + + Returns: + True if no duplicates found. Returns False otherwise. + """ # Dictionary of GPIO controllers, indexed by the GPIO controller nodelabel gpio_ctrls = dict() duplicates = 0 count = 0 - edtlib = inspect.getmodule(edt) - try: named_gpios = edt.get_node("/named-gpios") except edtlib.EDTError: @@ -91,7 +251,9 @@ def verify_no_duplicates(zephyr_base, edt_pickle): gpio_ctrls[nodelabel][gpio_pin] = node.name if duplicates: - logging.error("%d duplicate GPIOs found in %s", duplicates, edt_pickle) + logging.error( + "%d duplicate GPIOs found in %s", duplicates, project_name + ) return False logging.info("Verified %d GPIOs, no duplicates found", count) @@ -157,7 +319,15 @@ def main(argv: Optional[List[str]] = None) -> Optional[int]: logging.basicConfig(format=log_format, level=args.log_level) - if not verify_no_duplicates(args.zephyr_base, args.edt_pickle): + edtlib, edt, project_name = _load_edt(args.zephyr_base, args.edt_pickle) + + if edtlib is None: + return 0 + + if not verify_no_duplicates(edtlib, edt, project_name): + return 1 + + if not verify_gpios_flags_match(edtlib, edt, project_name): return 1 return 0 diff --git a/zephyr/shim/chip/CMakeLists.txt b/zephyr/shim/chip/CMakeLists.txt index 0236570ddd..a899a96070 100644 --- a/zephyr/shim/chip/CMakeLists.txt +++ b/zephyr/shim/chip/CMakeLists.txt @@ -10,5 +10,7 @@ elseif (DEFINED CONFIG_SOC_FAMILY_MEC) add_subdirectory(mchp) elseif (DEFINED CONFIG_SOC_FAMILY_STM32) add_subdirectory(stm32) +else () + add_subdirectory(stub) endif() diff --git a/zephyr/shim/chip/it8xxx2/clock.c b/zephyr/shim/chip/it8xxx2/clock.c index a4df87dc1d..ede854ac14 100644 --- a/zephyr/shim/chip/it8xxx2/clock.c +++ b/zephyr/shim/chip/it8xxx2/clock.c @@ -31,3 +31,7 @@ int clock_get_freq(void) return pll_reg_to_freq[reg_val]; } + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/zephyr/shim/chip/mchp/system.c b/zephyr/shim/chip/mchp/system.c index 517c928ad1..def53cdef9 100644 --- a/zephyr/shim/chip/mchp/system.c +++ b/zephyr/shim/chip/mchp/system.c @@ -52,10 +52,8 @@ void system_mpu_config(void) /* Reseve for future use */ } -static int chip_system_init(const struct device *unused) +static int chip_system_init(void) { - ARG_UNUSED(unused); - /* * Check BBRAM power status. */ diff --git a/zephyr/shim/chip/mchp/system_download_from_flash.c b/zephyr/shim/chip/mchp/system_download_from_flash.c index 8f6304274f..ae3d96fa4a 100644 --- a/zephyr/shim/chip/mchp/system_download_from_flash.c +++ b/zephyr/shim/chip/mchp/system_download_from_flash.c @@ -18,7 +18,7 @@ #define STRUCT_PCR_REG_BASE_ADDR \ ((struct pcr_regs *)DT_REG_ADDR_BY_IDX(PCR_NODE, 0)) -#define QSPI_NODE DT_INST(0, microchip_xec_qmspi_full_duplex) +#define QSPI_NODE DT_INST(0, microchip_xec_qmspi_ldma) #define STRUCT_QSPI_REG_BASE_ADDR \ ((struct qmspi_regs *)(DT_REG_ADDR(QSPI_NODE))) diff --git a/zephyr/shim/chip/npcx/system.c b/zephyr/shim/chip/npcx/system.c index 1fbdca0803..5c16d3bd40 100644 --- a/zephyr/shim/chip/npcx/system.c +++ b/zephyr/shim/chip/npcx/system.c @@ -73,10 +73,8 @@ void system_mpu_config(void) CPU_MPU_RASR = 0x03080013; } -static int chip_system_init(const struct device *unused) +static int chip_system_init(void) { - ARG_UNUSED(unused); - /* * Check BBRAM power status. */ diff --git a/zephyr/shim/chip/stm32/CMakeLists.txt b/zephyr/shim/chip/stm32/CMakeLists.txt index 52787ce656..8dfbcd5834 100644 --- a/zephyr/shim/chip/stm32/CMakeLists.txt +++ b/zephyr/shim/chip/stm32/CMakeLists.txt @@ -3,3 +3,5 @@ # found in the LICENSE file. cros_ec_library_include_directories(include) + +zephyr_library_sources(clock.c) diff --git a/zephyr/shim/chip/stm32/clock.c b/zephyr/shim/chip/stm32/clock.c new file mode 100644 index 0000000000..5adf7b2412 --- /dev/null +++ b/zephyr/shim/chip/stm32/clock.c @@ -0,0 +1,10 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "clock.h" + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/zephyr/shim/chip/stub/CMakeLists.txt b/zephyr/shim/chip/stub/CMakeLists.txt new file mode 100644 index 0000000000..8dfbcd5834 --- /dev/null +++ b/zephyr/shim/chip/stub/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cros_ec_library_include_directories(include) + +zephyr_library_sources(clock.c) diff --git a/zephyr/shim/chip/stub/clock.c b/zephyr/shim/chip/stub/clock.c new file mode 100644 index 0000000000..5adf7b2412 --- /dev/null +++ b/zephyr/shim/chip/stub/clock.c @@ -0,0 +1,10 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "clock.h" + +void clock_enable_module(enum module_id module, int enable) +{ +} diff --git a/zephyr/shim/core/cortex-m/mpu.c b/zephyr/shim/core/cortex-m/mpu.c index 601961225c..4f1e893d48 100644 --- a/zephyr/shim/core/cortex-m/mpu.c +++ b/zephyr/shim/core/cortex-m/mpu.c @@ -21,7 +21,7 @@ void mpu_enable(void) } } -static int mpu_disable_fixed_regions(const struct device *dev) +static int mpu_disable_fixed_regions(void) { /* MPU is configured and enabled by the Zephyr init code, disable the * fixed sections by default. diff --git a/zephyr/shim/include/cbi_flash.h b/zephyr/shim/include/cbi_flash.h new file mode 100644 index 0000000000..9f2fc26cc4 --- /dev/null +++ b/zephyr/shim/include/cbi_flash.h @@ -0,0 +1,28 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_CBI_FLASH_H +#define __CROS_EC_CBI_FLASH_H + +#include "cros_board_info.h" + +#include <zephyr/devicetree.h> + +#define DT_DRV_COMPAT cros_ec_flash_layout + +#define CBI_FLASH_NODE DT_NODELABEL(cbi_flash) +#define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset) +#define CBI_FLASH_PRESERVE DT_PROP(CBI_FLASH_NODE, preserve) + +#if CONFIG_PLATFORM_EC_CBI_FLASH +BUILD_ASSERT(DT_NODE_EXISTS(CBI_FLASH_NODE) == 1, + "CBI flash DT node label not found"); +BUILD_ASSERT((CBI_FLASH_OFFSET % CONFIG_FLASH_ERASE_SIZE) == 0, + "CBI flash offset is not erase-size aligned"); +BUILD_ASSERT((CBI_IMAGE_SIZE % CONFIG_FLASH_ERASE_SIZE) == 0, + "CBI flash size is not erase-size aligned"); +BUILD_ASSERT(CBI_IMAGE_SIZE > 0, "CBI flash size must be greater than zero"); +#endif /* CONFIG_PLATFORM_EC_CBI_FLASH */ +#endif /* __CROS_EC_CBI_FLASH_H */ diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 2659ac66ce..b46ca76cb1 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -972,6 +972,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_POWER_SLEEP_FAILURE_DETECTION #endif +#undef CONFIG_POWERSEQ_S0IX_COUNTER +#ifdef CONFIG_PLATFORM_EC_POWERSEQ_S0IX_COUNTER +#define CONFIG_POWERSEQ_S0IX_COUNTER +#endif + #undef CONFIG_HOSTCMD_AP_RESET #ifdef CONFIG_PLATFORM_EC_HOSTCMD_AP_RESET #define CONFIG_HOSTCMD_AP_RESET @@ -1852,6 +1857,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_USBC_RETIMER_ANX7452 #endif +#undef CONFIG_USBC_RETIMER_KB800X +#ifdef CONFIG_PLATFORM_EC_USBC_RETIMER_KB800X +#define CONFIG_USBC_RETIMER_KB800X +#endif + #undef CONFIG_USBC_RETIMER_PS8811 #ifdef CONFIG_PLATFORM_EC_USBC_RETIMER_PS8811 #define CONFIG_USBC_RETIMER_PS8811 @@ -1862,6 +1872,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_USBC_RETIMER_PS8818 #endif +#undef CONFIG_CMD_RETIMER +#ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_RETIMER +#define CONFIG_CMD_RETIMER +#endif + #undef CONFIG_USBC_SS_MUX #ifdef CONFIG_PLATFORM_EC_USBC_SS_MUX #define CONFIG_USBC_SS_MUX @@ -2368,6 +2383,11 @@ BUILD_ASSERT((DT_NUM_INST_STATUS_OKAY(maxim_max695x)) == 1, #define CONFIG_PANIC_CONSOLE_OUTPUT #endif +#undef CONFIG_RNG +#ifdef CONFIG_PLATFORM_EC_RANDOM +#define CONFIG_RNG +#endif + #undef CONFIG_CMD_CRASH #ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_CRASH #define CONFIG_CMD_CRASH diff --git a/zephyr/shim/include/usbc/tcpci.h b/zephyr/shim/include/usbc/tcpci.h index f106f441a6..f388f2eeeb 100644 --- a/zephyr/shim/include/usbc/tcpci.h +++ b/zephyr/shim/include/usbc/tcpci.h @@ -4,7 +4,18 @@ */ #include "driver/tcpm/tcpci.h" +#include "usbc/tcpc_anx7447.h" +#include "usbc/tcpc_anx7447_emul.h" +#include "usbc/tcpc_ccgxxf.h" +#include "usbc/tcpc_fusb302.h" +#include "usbc/tcpc_generic_emul.h" +#include "usbc/tcpc_nct38xx.h" +#include "usbc/tcpc_ps8xxx.h" +#include "usbc/tcpc_ps8xxx_emul.h" +#include "usbc/tcpc_raa489000.h" #include "usbc/tcpc_rt1715.h" +#include "usbc/tcpc_rt1718s.h" +#include "usbc/utils.h" #include <zephyr/devicetree.h> @@ -64,7 +75,21 @@ * Forward declare a struct tcpc_config_t for every TCPC node in the tree with * the "is-alt" property set. */ +DT_FOREACH_STATUS_OKAY(ANX7447_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(CCGXXF_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(FUSB302_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(PS8XXX_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(NCT38XX_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(RAA489000_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(RT1718S_TCPC_COMPAT, TCPC_ALT_DECLARE) DT_FOREACH_STATUS_OKAY(RT1715_TCPC_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(TCPCI_COMPAT, TCPC_ALT_DECLARE) + +#ifdef TEST_BUILD +DT_FOREACH_STATUS_OKAY(TCPCI_EMUL_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(PS8XXX_EMUL_COMPAT, TCPC_ALT_DECLARE) +DT_FOREACH_STATUS_OKAY(ANX7447_EMUL_COMPAT, TCPC_ALT_DECLARE) +#endif #define TCPC_ENABLE_ALTERNATE_BY_NODELABEL(usb_port_num, nodelabel) \ memcpy(&tcpc_config[usb_port_num], \ diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt index 17932540e4..a2d87f5571 100644 --- a/zephyr/shim/src/CMakeLists.txt +++ b/zephyr/shim/src/CMakeLists.txt @@ -55,6 +55,7 @@ zephyr_library_sources_ifdef(CONFIG_CROS_EC_POWER_SIGNAL_LIST power.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_PWM_HC pwm_hc.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_PWM pwm_led.c) +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_RANDOM random.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_RTC rtc.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_SWITCHCAP_GPIO switchcap_gpio.c) diff --git a/zephyr/shim/src/adc.c b/zephyr/shim/src/adc.c index 0041335662..661a3c40e1 100644 --- a/zephyr/shim/src/adc.c +++ b/zephyr/shim/src/adc.c @@ -40,10 +40,8 @@ const struct adc_t adc_channels[] = { DT_FOREACH_CHILD( DT_INST(0, named_adc_channels), ADC_CHANNEL_INIT) }; #endif -static int init_device_bindings(const struct device *device) +static int init_device_bindings(void) { - ARG_UNUSED(device); - for (int i = 0; i < ARRAY_SIZE(adc_channels); i++) { if (!device_is_ready(adc_channels[i].dev)) k_oops(); diff --git a/zephyr/shim/src/bc12.c b/zephyr/shim/src/bc12.c index 12b45d2197..ed5fe101b2 100644 --- a/zephyr/shim/src/bc12.c +++ b/zephyr/shim/src/bc12.c @@ -13,11 +13,6 @@ #include <zephyr/devicetree.h> -#if DT_HAS_COMPAT_STATUS_OKAY(RT1718S_BC12_COMPAT) || \ - DT_HAS_COMPAT_STATUS_OKAY(RT1739_BC12_COMPAT) || \ - DT_HAS_COMPAT_STATUS_OKAY(RT9490_BC12_COMPAT) || \ - DT_HAS_COMPAT_STATUS_OKAY(PI3USB9201_COMPAT) - /* Check RT1718S dependency. BC12 node must be dependent on TCPC node. */ #if DT_HAS_COMPAT_STATUS_OKAY(RT1718S_BC12_COMPAT) BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(RT1718S_TCPC_COMPAT)); @@ -43,5 +38,3 @@ BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(RT1718S_TCPC_COMPAT)); /* BC1.2 controllers */ struct bc12_config bc12_ports[CHARGE_PORT_COUNT] = { DT_FOREACH_STATUS_OKAY( named_usbc_port, BC12_CHIP) }; - -#endif /* #if DT_HAS_COMPAT_STATUS_OKAY */ diff --git a/zephyr/shim/src/cbi/cbi_flash.c b/zephyr/shim/src/cbi/cbi_flash.c index bb63f66c59..60dac33ad1 100644 --- a/zephyr/shim/src/cbi/cbi_flash.c +++ b/zephyr/shim/src/cbi/cbi_flash.c @@ -3,8 +3,7 @@ * found in the LICENSE file. */ -#define DT_DRV_COMPAT cros_ec_flash_layout - +#include "cbi_flash.h" #include "console.h" #include "cros_board_info.h" #include "flash.h" @@ -12,26 +11,13 @@ #include "write_protect.h" #include <zephyr/devicetree.h> -#include <zephyr/drivers/gpio.h> -#include <zephyr/logging/log.h> LOG_MODULE_REGISTER(cbi_flash, LOG_LEVEL_ERR); -#define CBI_FLASH_NODE DT_NODELABEL(cbi_flash) -#define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset) -#define CBI_FLASH_PRESERVE DT_PROP(CBI_FLASH_NODE, preserve) - -BUILD_ASSERT(DT_NODE_EXISTS(CBI_FLASH_NODE) == 1, - "CBI flash DT node label not found"); -BUILD_ASSERT((CBI_FLASH_OFFSET % CONFIG_FLASH_ERASE_SIZE) == 0, - "CBI flash offset is not erase-size aligned"); -BUILD_ASSERT((CBI_IMAGE_SIZE % CONFIG_FLASH_ERASE_SIZE) == 0, - "CBI flash size is not erase-size aligned"); -BUILD_ASSERT(CBI_IMAGE_SIZE > 0, "CBI flash size must be greater than zero"); - static int flash_load(uint8_t offset, uint8_t *data, int len) { - return crec_flash_read(CBI_FLASH_OFFSET, CBI_IMAGE_SIZE, (char *)data); + return crec_flash_unprotected_read(CBI_FLASH_OFFSET, CBI_IMAGE_SIZE, + (char *)data); } static int flash_is_write_protected(void) diff --git a/zephyr/shim/src/console.c b/zephyr/shim/src/console.c index 2a82571065..6df3511cd1 100644 --- a/zephyr/shim/src/console.c +++ b/zephyr/shim/src/console.c @@ -278,7 +278,7 @@ static const char *const disabled_channels[] = DT_PROP(EC_CONSOLE_NODE, disabled); static const size_t disabled_channel_count = DT_PROP_LEN(EC_CONSOLE_NODE, disabled); -static int init_ec_console(const struct device *unused) +static int init_ec_console(void) { for (size_t i = 0; i < disabled_channel_count; i++) console_channel_disable(disabled_channels[i]); @@ -288,7 +288,7 @@ static int init_ec_console(const struct device *unused) SYS_INIT(init_ec_console, PRE_KERNEL_1, 50); #endif /* CONFIG_PLATFORM_EC_CONSOLE_CHANNEL */ -static int init_ec_shell(const struct device *unused) +static int init_ec_shell(void) { #if defined(CONFIG_SHELL_BACKEND_SERIAL) shell_zephyr = shell_backend_uart_get_ptr(); diff --git a/zephyr/shim/src/espi.c b/zephyr/shim/src/espi.c index ac7074bfa0..0fc5d2c0cb 100644 --- a/zephyr/shim/src/espi.c +++ b/zephyr/shim/src/espi.c @@ -692,7 +692,7 @@ static void espi_peripheral_handler(const struct device *dev, } } -static int zephyr_shim_setup_espi(const struct device *unused) +static int zephyr_shim_setup_espi(void) { uint32_t enable = 1; static const struct { diff --git a/zephyr/shim/src/fan.c b/zephyr/shim/src/fan.c index 9978e6f4ca..69c23fa9fd 100644 --- a/zephyr/shim/src/fan.c +++ b/zephyr/shim/src/fan.c @@ -62,34 +62,6 @@ DT_INST_FOREACH_CHILD(0, FAN_CONFIGS) const struct fan_t fans[FAN_CH_COUNT] = { DT_INST_FOREACH_CHILD(0, FAN_INST) }; -/* Fan mode */ -enum fan_mode { - /* FAN rpm mode */ - FAN_RPM = 0, - /* FAN duty mode */ - FAN_DUTY, -}; - -/* Fan status data structure */ -struct fan_data { - /* Fan mode */ - enum fan_mode current_fan_mode; - /* Actual rpm */ - int rpm_actual; - /* Previous rpm */ - int rpm_pre; - /* Target rpm */ - int rpm_target; - /* Fan config flags */ - unsigned int flags; - /* Automatic fan status */ - enum fan_status auto_status; - /* Current PWM duty cycle percentage */ - int pwm_percent; - /* Whether the PWM channel is enabled */ - bool pwm_enabled; -}; - /* Data structure to define PWM and tachometer. */ struct fan_config { struct pwm_dt_spec pwm; @@ -97,7 +69,7 @@ struct fan_config { const struct device *tach; }; -static struct fan_data fan_data[FAN_CH_COUNT]; +struct fan_data fan_data[FAN_CH_COUNT]; static const struct fan_config fan_config[FAN_CH_COUNT] = { DT_INST_FOREACH_CHILD(0, FAN_CONTROL_INST) }; @@ -268,8 +240,13 @@ static void fan_tick_func_rpm(int ch) /* Get actual rpm */ data->rpm_actual = fan_rpm(ch); + /* TODO: b/279132492 */ +#ifdef CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + data->auto_status = board_override_fan_control_duty(ch); +#else /* Do smart fan stuff */ data->auto_status = fan_smart_control(ch); +#endif } static void fan_tick_func_duty(int ch) diff --git a/zephyr/shim/src/flash.c b/zephyr/shim/src/flash.c index e196166cdf..4cdd0f78f8 100644 --- a/zephyr/shim/src/flash.c +++ b/zephyr/shim/src/flash.c @@ -131,10 +131,8 @@ test_mockable int crec_flash_physical_read(int offset, int size, char *data) return rv; } -static int flash_dev_init(const struct device *unused) +static int flash_dev_init(void) { - ARG_UNUSED(unused); - if (!device_is_ready(cros_flash_dev) || !device_is_ready(flash_ctrl_dev)) k_oops(); diff --git a/zephyr/shim/src/gpio.c b/zephyr/shim/src/gpio.c index 142f106e02..ca2f4abc5d 100644 --- a/zephyr/shim/src/gpio.c +++ b/zephyr/shim/src/gpio.c @@ -263,13 +263,11 @@ const struct gpio_dt_spec *gpio_get_dt_spec(enum gpio_signal signal) /* Allow access to this function in tests so we can run it multiple times * without having to create a new binary for each run. */ -test_export_static int init_gpios(const struct device *unused) +test_export_static int init_gpios(void) { gpio_flags_t flags; bool is_sys_jumped = system_jumped_to_this_image(); - ARG_UNUSED(unused); - for (size_t i = 0; i < ARRAY_SIZE(configs); ++i) { int rv; diff --git a/zephyr/shim/src/hooks.c b/zephyr/shim/src/hooks.c index b8f9b917e4..8c49857c3e 100644 --- a/zephyr/shim/src/hooks.c +++ b/zephyr/shim/src/hooks.c @@ -95,7 +95,7 @@ static void check_hook_task_priority(void) } DECLARE_HOOK(HOOK_INIT, check_hook_task_priority, HOOK_PRIO_FIRST); -static int zephyr_shim_setup_hooks(const struct device *unused) +static int zephyr_shim_setup_hooks(void) { int rv; @@ -217,7 +217,7 @@ static void ev_handler(struct ap_power_ev_callback *cb, /* * Events are received from the AP power event system and sent to the hooks. */ -static int zephyr_shim_ap_power_event(const struct device *unused) +static int zephyr_shim_ap_power_event(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/shim/src/ioex.c b/zephyr/shim/src/ioex.c index afda051c8a..da8a1ea05a 100644 --- a/zephyr/shim/src/ioex.c +++ b/zephyr/shim/src/ioex.c @@ -34,13 +34,11 @@ int ioex_init(int ioex) return EC_SUCCESS; } -static int ioex_init_default(const struct device *unused) +static int ioex_init_default(void) { int ret; int i; - ARG_UNUSED(unused); - for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; i++) { /* IO Expander has been initialized, skip re-initializing */ if (ioex_config[i].flags & diff --git a/zephyr/shim/src/led_driver/led.c b/zephyr/shim/src/led_driver/led.c index 19324487e9..da648a4636 100644 --- a/zephyr/shim/src/led_driver/led.c +++ b/zephyr/shim/src/led_driver/led.c @@ -36,11 +36,13 @@ struct led_color_node_t { #define DECLARE_PINS_NODE(id) extern struct led_pins_node_t PINS_NODE(id); #if CONFIG_PLATFORM_EC_LED_DT_PWM -DT_FOREACH_CHILD(DT_COMPAT_GET_ANY_STATUS_OKAY(cros_ec_pwm_led_pins), - DECLARE_PINS_NODE) +DT_FOREACH_CHILD_STATUS_OKAY_VARGS( + DT_COMPAT_GET_ANY_STATUS_OKAY(cros_ec_pwm_led_pins), DT_FOREACH_CHILD, + DECLARE_PINS_NODE) #elif CONFIG_PLATFORM_EC_LED_DT_GPIO -DT_FOREACH_CHILD(DT_COMPAT_GET_ANY_STATUS_OKAY(cros_ec_gpio_led_pins), - DECLARE_PINS_NODE) +DT_FOREACH_CHILD_STATUS_OKAY_VARGS( + DT_COMPAT_GET_ANY_STATUS_OKAY(cros_ec_gpio_led_pins), DT_FOREACH_CHILD, + DECLARE_PINS_NODE) #endif /* @@ -235,7 +237,8 @@ static int match_node(int node_idx) /* Check if this node depends on battery level */ if (node_array[node_idx].batt_lvl[0] != -1) { - int curr_batt_lvl = charge_get_percent(); + int curr_batt_lvl = + DIV_ROUND_NEAREST(charge_get_display_charge(), 10); if ((curr_batt_lvl < node_array[node_idx].batt_lvl[0]) || (curr_batt_lvl > node_array[node_idx].batt_lvl[1])) diff --git a/zephyr/shim/src/led_driver/led_gpio.c b/zephyr/shim/src/led_driver/led_gpio.c index dba2571d9c..2419663859 100644 --- a/zephyr/shim/src/led_driver/led_gpio.c +++ b/zephyr/shim/src/led_driver/led_gpio.c @@ -20,23 +20,24 @@ LOG_MODULE_REGISTER(gpio_led, LOG_LEVEL_ERR); BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "Exactly one instance of cros-ec,gpio-led-pins should be defined."); -#define SET_PIN(node_id, prop, i) \ - { .signal = GPIO_SIGNAL(DT_PHANDLE_BY_IDX(node_id, prop, i)), \ - .val = DT_PROP_BY_IDX(node_id, led_values, i) }, +#define SET_PIN(node_id, prop, i) \ + { .signal = GPIO_SIGNAL( \ + DT_PHANDLE_BY_IDX(DT_PARENT(node_id), led_pins, i)), \ + .val = DT_PROP_BY_IDX(node_id, prop, i) }, #define SET_GPIO_PIN(node_id) \ - { DT_FOREACH_PROP_ELEM(node_id, led_pins, SET_PIN) }; + { DT_FOREACH_PROP_ELEM(node_id, led_values, SET_PIN) }; #define GEN_PINS_ARRAY(id) struct gpio_pin_t PINS_ARRAY(id)[] = SET_GPIO_PIN(id) -DT_INST_FOREACH_CHILD(0, GEN_PINS_ARRAY) +DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, GEN_PINS_ARRAY) #define SET_PIN_NODE(node_id) \ { .led_color = GET_PROP(node_id, led_color), \ - .led_id = GET_PROP(node_id, led_id), \ + .led_id = GET_PROP(DT_PARENT(node_id), led_id), \ .br_color = GET_COLOR_PROP_NVE(node_id, br_color), \ .gpio_pins = PINS_ARRAY(node_id), \ - .pins_count = DT_PROP_LEN(node_id, led_pins) }; + .pins_count = DT_PROP_LEN(node_id, led_values) }; /* * Initialize led_pins_node_t struct for each pin node defined @@ -44,14 +45,16 @@ DT_INST_FOREACH_CHILD(0, GEN_PINS_ARRAY) #define GEN_PINS_NODES(id) \ const struct led_pins_node_t PINS_NODE(id) = SET_PIN_NODE(id) -DT_INST_FOREACH_CHILD(0, GEN_PINS_NODES) +DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, GEN_PINS_NODES) /* * Array of pointers to each pin node */ #define PINS_NODE_PTR(id) &PINS_NODE(id), -const struct led_pins_node_t *pins_node[] = { DT_INST_FOREACH_CHILD( - 0, PINS_NODE_PTR) }; +const struct led_pins_node_t *pins_node[] = { + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, + PINS_NODE_PTR) +}; /* * Set all the GPIO pins defined in the node to the defined value, diff --git a/zephyr/shim/src/led_driver/led_pwm.c b/zephyr/shim/src/led_driver/led_pwm.c index bad887a86f..a747c3d3b9 100644 --- a/zephyr/shim/src/led_driver/led_pwm.c +++ b/zephyr/shim/src/led_driver/led_pwm.c @@ -31,28 +31,30 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, * duty_cycle = 50 %, pulse_ns = (2000000*50)/100 = 1000000ns */ -#define SET_PIN(node_id, prop, i) \ - { \ - .pwm = PWM_DT_SPEC_GET(DT_PHANDLE_BY_IDX(node_id, prop, i)), \ - .pulse_ns = DIV_ROUND_NEAREST( \ - DT_PWMS_PERIOD(DT_PHANDLE_BY_IDX(node_id, prop, i)) * \ - DT_PROP_BY_IDX(node_id, led_values, i), \ - 100), \ +#define SET_PIN(node_id, prop, i) \ + { \ + .pwm = PWM_DT_SPEC_GET( \ + DT_PHANDLE_BY_IDX(DT_PARENT(node_id), led_pwms, i)), \ + .pulse_ns = DIV_ROUND_NEAREST( \ + DT_PWMS_PERIOD(DT_PHANDLE_BY_IDX(DT_PARENT(node_id), \ + led_pwms, i)) * \ + DT_PROP_BY_IDX(node_id, prop, i), \ + 100), \ }, #define SET_PWM_PIN(node_id) \ - { DT_FOREACH_PROP_ELEM(node_id, led_pwms, SET_PIN) }; + { DT_FOREACH_PROP_ELEM(node_id, led_values, SET_PIN) }; #define GEN_PINS_ARRAY(id) struct pwm_pin_t PINS_ARRAY(id)[] = SET_PWM_PIN(id) -DT_INST_FOREACH_CHILD(0, GEN_PINS_ARRAY) +DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, GEN_PINS_ARRAY) #define SET_PIN_NODE(node_id) \ { .led_color = GET_PROP(node_id, led_color), \ - .led_id = GET_PROP(node_id, led_id), \ + .led_id = GET_PROP(DT_PARENT(node_id), led_id), \ .br_color = GET_COLOR_PROP_NVE(node_id, br_color), \ .pwm_pins = PINS_ARRAY(node_id), \ - .pins_count = DT_PROP_LEN(node_id, led_pwms) }; + .pins_count = DT_PROP_LEN(node_id, led_values) }; /* * Initialize led_pins_node_t struct for each pin node defined @@ -60,14 +62,17 @@ DT_INST_FOREACH_CHILD(0, GEN_PINS_ARRAY) #define GEN_PINS_NODES(id) \ const struct led_pins_node_t PINS_NODE(id) = SET_PIN_NODE(id) -DT_INST_FOREACH_CHILD(0, GEN_PINS_NODES) +DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, GEN_PINS_NODES) /* * Array of pointers to each pin node */ #define PINS_NODE_PTR(id) &PINS_NODE(id), -const struct led_pins_node_t *pins_node[] = { DT_INST_FOREACH_CHILD( - 0, PINS_NODE_PTR) }; + +const struct led_pins_node_t *pins_node[] = { + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(0, DT_FOREACH_CHILD, + PINS_NODE_PTR) +}; /* * Set all the PWM channels defined in the node to the defined value, diff --git a/zephyr/shim/src/random.c b/zephyr/shim/src/random.c new file mode 100644 index 0000000000..a18d83066e --- /dev/null +++ b/zephyr/shim/src/random.c @@ -0,0 +1,69 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "console.h" +#include "host_command.h" +#include "printf.h" +#include "system.h" + +#include <zephyr/drivers/entropy.h> +#include <zephyr/kernel.h> + +#define rng DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy)) + +void trng_rand_bytes(void *buffer, size_t len) +{ + /* + * In EC, we use size_t to represent buffer size, but Zephyr uses + * uint16_t. Crash the system if user requested more than UINT16_MAX + * bytes. + */ + if (!device_is_ready(rng) || len > UINT16_MAX) + k_oops(); + + if (entropy_get_entropy(rng, (uint8_t *)buffer, (uint16_t)len)) + k_oops(); +} + +#if defined(CONFIG_PLATFORM_EC_CONSOLE_CMD_RAND) +static int command_rand(const struct shell *shell, int argc, const char **argv) +{ + uint8_t data[32]; + char str_buf[hex_str_buf_size(sizeof(data))]; + + trng_rand_bytes(data, sizeof(data)); + + snprintf_hex_buffer(str_buf, sizeof(str_buf), + HEX_BUF(data, sizeof(data))); + shell_fprintf(shell, SHELL_NORMAL, "rand %s\n", str_buf); + + return EC_SUCCESS; +} +SHELL_CMD_REGISTER(rand, NULL, "Output random bytes to console.", command_rand); +#endif + +#if defined(CONFIG_PLATFORM_EC_HOSTCMD_RAND) +static enum ec_status host_command_rand(struct host_cmd_handler_args *args) +{ + const struct ec_params_rand_num *p = args->params; + struct ec_response_rand_num *r = args->response; + uint16_t num_rand_bytes = p->num_rand_bytes; + + if (system_is_locked()) + return EC_RES_ACCESS_DENIED; + + if (num_rand_bytes > args->response_max) + return EC_RES_OVERFLOW; + + trng_rand_bytes(r->rand, num_rand_bytes); + + args->response_size = num_rand_bytes; + + return EC_RES_SUCCESS; +} + +DECLARE_HOST_COMMAND(EC_CMD_RAND_NUM, host_command_rand, + EC_VER_MASK(EC_VER_RAND_NUM)); +#endif diff --git a/zephyr/shim/src/rtc.c b/zephyr/shim/src/rtc.c index 6e694d48e4..b3d2be1086 100644 --- a/zephyr/shim/src/rtc.c +++ b/zephyr/shim/src/rtc.c @@ -36,10 +36,8 @@ void rtc_callback(const struct device *dev) } /** Initialize the rtc. */ -static int system_init_rtc(const struct device *unused) +static int system_init_rtc(void) { - ARG_UNUSED(unused); - cros_rtc_dev = DEVICE_DT_GET(CROS_RTC_NODE); if (!cros_rtc_dev) { LOG_ERR("Error: device %s is not ready", cros_rtc_dev->name); diff --git a/zephyr/shim/src/sha256_hw.c b/zephyr/shim/src/sha256_hw.c index 017b2ea857..dd6b236c3c 100644 --- a/zephyr/shim/src/sha256_hw.c +++ b/zephyr/shim/src/sha256_hw.c @@ -125,10 +125,8 @@ void hmac_SHA256(uint8_t *output, const uint8_t *key, const int key_len, SHA256_DIGEST_SIZE); } -static int zephyr_shim_init_sha256(const struct device *unused) +static int zephyr_shim_init_sha256(void) { - ARG_UNUSED(unused); - if (!device_is_ready(sha256_hw_dev)) { k_oops(); } diff --git a/zephyr/shim/src/system.c b/zephyr/shim/src/system.c index 387cedf9ab..ab0847e629 100644 --- a/zephyr/shim/src/system.c +++ b/zephyr/shim/src/system.c @@ -335,10 +335,8 @@ static int check_reset_cause(void) return 0; } -test_export_static int system_preinitialize(const struct device *unused) +test_export_static int system_preinitialize(void) { - ARG_UNUSED(unused); - if (bbram_dev && !device_is_ready(bbram_dev)) { LOG_ERR("Error: device %s is not ready", bbram_dev->name); return -1; diff --git a/zephyr/shim/src/tasks.c b/zephyr/shim/src/tasks.c index 2dde7d2610..aa89c9ee5c 100644 --- a/zephyr/shim/src/tasks.c +++ b/zephyr/shim/src/tasks.c @@ -393,10 +393,8 @@ void start_ec_tasks(void) * This allows us to set events on tasks before they even start, e.g. in * INIT_HOOKS. */ -int init_signals(const struct device *unused) +int init_signals(void) { - ARG_UNUSED(unused); - for (size_t i = 0; i < TASK_ID_COUNT + EXTRA_TASK_COUNT; ++i) { struct task_ctx_base_data *const data = task_get_base_data(i); diff --git a/zephyr/shim/src/tcpc.c b/zephyr/shim/src/tcpc.c index 842c2584ab..dbe05d9565 100644 --- a/zephyr/shim/src/tcpc.c +++ b/zephyr/shim/src/tcpc.c @@ -98,8 +98,31 @@ MAYBE_CONST struct tcpc_config_t tcpc_config[] = { DT_FOREACH_STATUS_OKAY( * Define a struct tcpc_config_t for every TCPC node in the tree with the * "is-alt" property set. */ +DT_FOREACH_STATUS_OKAY_VARGS(ANX7447_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_ANX7447) +DT_FOREACH_STATUS_OKAY_VARGS(CCGXXF_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_CCGXXF) +DT_FOREACH_STATUS_OKAY_VARGS(FUSB302_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_FUSB302) +DT_FOREACH_STATUS_OKAY_VARGS(PS8XXX_COMPAT, TCPC_ALT_DEFINE, TCPC_CONFIG_PS8XXX) +DT_FOREACH_STATUS_OKAY_VARGS(NCT38XX_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_NCT38XX) +DT_FOREACH_STATUS_OKAY_VARGS(RAA489000_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_RAA489000) +DT_FOREACH_STATUS_OKAY_VARGS(RT1718S_TCPC_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_RT1718S) DT_FOREACH_STATUS_OKAY_VARGS(RT1715_TCPC_COMPAT, TCPC_ALT_DEFINE, TCPC_CONFIG_RT1715) +DT_FOREACH_STATUS_OKAY_VARGS(TCPCI_COMPAT, TCPC_ALT_DEFINE, TCPC_CONFIG_TCPCI) + +#ifdef TEST_BUILD +DT_FOREACH_STATUS_OKAY_VARGS(TCPCI_EMUL_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_TCPCI_EMUL) +DT_FOREACH_STATUS_OKAY_VARGS(PS8XXX_EMUL_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_PS8XXX_EMUL) +DT_FOREACH_STATUS_OKAY_VARGS(ANX7447_EMUL_COMPAT, TCPC_ALT_DEFINE, + TCPC_CONFIG_ANX7447_EMUL) +#endif #ifdef CONFIG_PLATFORM_EC_TCPC_INTERRUPT diff --git a/zephyr/subsys/ap_pwrseq/Kconfig b/zephyr/subsys/ap_pwrseq/Kconfig index 9eaa37c017..8bb064aac9 100644 --- a/zephyr/subsys/ap_pwrseq/Kconfig +++ b/zephyr/subsys/ap_pwrseq/Kconfig @@ -169,6 +169,15 @@ config AP_PWRSEQ_S0IX_ERROR_RECOVERY Failure information is reported via the EC_CMD_HOST_SLEEP_EVENT host command. +config AP_PWRSEQ_S0IX_COUNTER + bool "Enable S0ix counter" + depends on AP_PWRSEQ_S0IX + depends on AP_PWRSEQ_HOST_SLEEP + default y + help + Enables counter which increases at every transitions to S0ix state. + Counter can be read via host command. + config AP_PWRSEQ_DEBUG_MODE_COMMAND bool "Console commands to enable/disable AP debug mode" depends on X86_NON_DSX_PWRSEQ diff --git a/zephyr/subsys/ap_pwrseq/power_host_sleep.c b/zephyr/subsys/ap_pwrseq/power_host_sleep.c index 96335b066b..82e84a02fd 100644 --- a/zephyr/subsys/ap_pwrseq/power_host_sleep.c +++ b/zephyr/subsys/ap_pwrseq/power_host_sleep.c @@ -192,6 +192,10 @@ enum ap_power_sleep_type ap_power_sleep_get_notify(void) return sleep_state; } +#ifdef CONFIG_AP_PWRSEQ_S0IX_COUNTER +atomic_t s0ix_counter; +#endif + void ap_power_sleep_notify_transition(enum ap_power_sleep_type check_state) { if (sleep_state != check_state) @@ -204,6 +208,9 @@ void ap_power_sleep_notify_transition(enum ap_power_sleep_type check_state) */ power_s0ix_suspend_clear_masks(); ap_power_ev_send_callbacks(AP_POWER_SUSPEND); +#ifdef CONFIG_AP_PWRSEQ_S0IX_COUNTER + atomic_inc(&s0ix_counter); +#endif } else if (check_state == AP_POWER_SLEEP_RESUME) { ap_power_ev_send_callbacks(AP_POWER_RESUME); /* @@ -251,7 +258,6 @@ void ap_power_chipset_handle_host_sleep_event( ap_power_sleep_set_notify(AP_POWER_SLEEP_SUSPEND); ap_power_ev_send_callbacks(AP_POWER_S0IX_SUSPEND_START); power_signal_enable(PWR_SLP_S0); - } else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) { /* * Set sleep state to resume; restore SCI/SMI masks; diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_chipset_power_state.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_chipset_power_state.c index a8db0bdefe..58629cab82 100644 --- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_chipset_power_state.c +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_chipset_power_state.c @@ -173,13 +173,12 @@ static void x86_non_dsx_chipset_state_exit_cb(const struct device *dev, } } -static int x86_non_dsx_chipset_init_events(const struct device *dev) +static int x86_non_dsx_chipset_init_events(void) { static struct ap_pwrseq_state_callback ap_pwrseq_entry_cb; static struct ap_pwrseq_state_callback ap_pwrseq_exit_cb; const struct device *ap_pwrseq_dev = ap_pwrseq_get_instance(); - ARG_UNUSED(dev); power_signal_init(); ap_pwrseq_entry_cb.cb = x86_non_dsx_chipset_state_entry_cb; diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_host_sleep.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_host_sleep.c index 2e16aba1bb..550e414ed0 100644 --- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_host_sleep.c +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_host_sleep.c @@ -173,7 +173,7 @@ static void ap_power_sleep_event_handler(struct ap_power_ev_callback *cb, /* * Registers callback for s0ix events. */ -static int ap_power_sleep_s0ix_event(const struct device *unused) +static int ap_power_sleep_s0ix_event(void) { static struct ap_power_ev_callback cb; diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c index 829ac13f73..69b9cc4a8d 100644 --- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c @@ -731,7 +731,7 @@ static void init_pwr_seq_state(void) } /* Initialize power sequence system state */ -static int pwrseq_init(const struct device *dev) +static int pwrseq_init(void) { LOG_INF("Pwrseq Init"); diff --git a/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c b/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c index 9c9a41d601..50a2becf21 100644 --- a/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c +++ b/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c @@ -576,9 +576,8 @@ int power_signal_emul_unload(void) * * @return 0 Return success only. */ -static int power_signal_emul_work_q_init(const struct device *dev) +static int power_signal_emul_work_q_init(void) { - ARG_UNUSED(dev); struct k_work_queue_config cfg = { .name = "psignal_emul", .no_yield = true, diff --git a/zephyr/test/amd/prj.conf b/zephyr/test/amd/prj.conf index ced2cda8f5..36d99e8716 100644 --- a/zephyr/test/amd/prj.conf +++ b/zephyr/test/amd/prj.conf @@ -12,4 +12,4 @@ CONFIG_PLATFORM_EC=y CONFIG_EMUL=y CONFIG_GPIO=y -CONFIG_AP_X86_AMD=y +CONFIG_AP_X86_AMD=y
\ No newline at end of file diff --git a/zephyr/test/ap_power/boards/alderlake.dts b/zephyr/test/ap_power/boards/alderlake.dts index 4d641cad4a..58c68529c3 100644 --- a/zephyr/test/ap_power/boards/alderlake.dts +++ b/zephyr/test/ap_power/boards/alderlake.dts @@ -362,4 +362,35 @@ nodes = <&en_pp3300_emul &en_pp5000_emul &ec_soc_dsw_pwrok_emul &ec_pch_rsmrst_s3_dsw_pwrok_fail_emul>; }; + + pch_sleep: pch-sleep { + compatible = "intel,ap-pwr-signal-emul"; + input-signal = <&pch_pwrok>; + + slp-s0-suspend-emul { + output-signal = <&slp_s0>; + init-value=<1>; + }; + }; + + tp-sys-sleep { + compatible = "intel,ap-pwr-test-platform"; + nodes = <&pch_sleep>; + }; + + pch_wake: pch-wake { + compatible = "intel,ap-pwr-signal-emul"; + input-signal = <&pch_pwrok>; + + slp-s0-resume-emul { + output-signal = <&slp_s0>; + init-value=<0>; + }; + }; + + tp-sys-wake { + compatible = "intel,ap-pwr-test-platform"; + nodes = <&pch_wake>; + }; + }; diff --git a/zephyr/test/ap_power/src/ap_pwrseq.c b/zephyr/test/ap_power/src/ap_pwrseq.c index 3081272d27..a968b0c38d 100644 --- a/zephyr/test/ap_power/src/ap_pwrseq.c +++ b/zephyr/test/ap_power/src/ap_pwrseq.c @@ -6,7 +6,9 @@ #include "ap_power/ap_power.h" #include "ap_power/ap_power_interface.h" #include "chipset.h" +#include "ec_commands.h" #include "emul/emul_power_signals.h" +#include "host_command.h" #include "test_mocks.h" #include "test_state.h" @@ -84,6 +86,90 @@ ZTEST(ap_pwrseq, test_ap_pwrseq_0) "AP_POWER_RESUME event not generated"); } +ZTEST(ap_pwrseq, test_ap_pwrseq_0_sleep) +{ + struct ec_params_host_sleep_event_v1 host_sleep_ev_p = { + .sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND, + .suspend_params = { EC_HOST_SLEEP_TIMEOUT_DEFAULT }, + }; + struct ec_response_host_sleep_event_v1 host_sleep_ev_r; + struct host_cmd_handler_args host_sleep_ev_args = BUILD_HOST_COMMAND( + EC_CMD_HOST_SLEEP_EVENT, 1, host_sleep_ev_r, host_sleep_ev_p); + + struct ec_params_s0ix_cnt s0ix_cnt_ev_p = { + .flags = EC_S0IX_COUNTER_RESET + }; + struct ec_response_s0ix_cnt s0ix_cnt_ev_r; + struct host_cmd_handler_args s0ix_cnt_ev_args = BUILD_HOST_COMMAND( + EC_CMD_GET_S0IX_COUNTER, 0, s0ix_cnt_ev_r, s0ix_cnt_ev_p); + + /* Verify that counter is set to 0 */ + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get s0ix counter"); + zassert_equal(s0ix_cnt_ev_r.s0ix_counter, 0); + + /* Send host sleep event */ + zassert_ok(host_command_process(&host_sleep_ev_args)); + + /* Assert SLP_S0# */ + zassert_equal(0, + power_signal_emul_load( + EMUL_POWER_SIGNAL_TEST_PLATFORM(tp_sys_sleep)), + "Unable to load test platform `tp_sys_g3_to_s0`"); + + k_msleep(500); + + /* + * Verify that counter has been increased, + * clear the flag for get command + */ + s0ix_cnt_ev_p.flags = 0; + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get s0ix counter"); + zassert_equal(s0ix_cnt_ev_r.s0ix_counter, 1); +} + +ZTEST(ap_pwrseq, test_ap_pwrseq_0_wake) +{ + struct ec_params_host_sleep_event_v1 p = { + .sleep_event = HOST_SLEEP_EVENT_S0IX_RESUME, + .suspend_params = { EC_HOST_SLEEP_TIMEOUT_DEFAULT }, + }; + struct ec_response_host_sleep_event_v1 r; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_HOST_SLEEP_EVENT, 1, r, p); + struct ec_params_s0ix_cnt s0ix_cnt_ev_p = { .flags = 0 }; + struct ec_response_s0ix_cnt s0ix_cnt_ev_r; + struct host_cmd_handler_args s0ix_cnt_ev_args = BUILD_HOST_COMMAND( + EC_CMD_GET_S0IX_COUNTER, 0, s0ix_cnt_ev_r, s0ix_cnt_ev_p); + + /* Confirm that counters keeps the same value through wakeup */ + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get s0ix counter"); + zassert_equal(s0ix_cnt_ev_r.s0ix_counter, 1); + + zassert_equal(0, + power_signal_emul_load( + EMUL_POWER_SIGNAL_TEST_PLATFORM(tp_sys_wake)), + "Unable to load test platform `tp_sys_g3_to_s0`"); + + k_msleep(500); + zassert_ok(host_command_process(&args)); + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get sleep counter"); + zassert_equal(s0ix_cnt_ev_r.s0ix_counter, 1); + + /* Verify the reset command sets the counter to zero */ + s0ix_cnt_ev_p.flags = EC_S0IX_COUNTER_RESET; + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get s0ix counter"); + + s0ix_cnt_ev_p.flags = 0; + zassert_ok(host_command_process(&s0ix_cnt_ev_args), + "Failed to get s0ix counter"); + zassert_equal(s0ix_cnt_ev_r.s0ix_counter, 0); +} + ZTEST(ap_pwrseq, test_ap_pwrseq_1) { zassert_equal(0, diff --git a/zephyr/test/ap_power/testcase.yaml b/zephyr/test/ap_power/testcase.yaml index 8fbea99560..cba1157944 100644 --- a/zephyr/test/ap_power/testcase.yaml +++ b/zephyr/test/ap_power/testcase.yaml @@ -8,6 +8,7 @@ tests: extra_configs: - CONFIG_EMUL_POWER_SIGNALS=y - CONFIG_X86_NON_DSX_PWRSEQ_ADL=y + - CONFIG_AP_PWRSEQ_S0IX=y - CONFIG_AP_X86_INTEL_ADL=y - CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S4=y - CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI_VW_SLP_S5=y diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt index 2b2688ce4d..c2e521585e 100644 --- a/zephyr/test/drivers/CMakeLists.txt +++ b/zephyr/test/drivers/CMakeLists.txt @@ -38,6 +38,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PANIC_OUTPUT panic_output) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_POWER_HOST_SLEEP power_host_sleep) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_RT1718S rt1718s) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_RT9490 rt9490) +add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_RANDOM random) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_SHIM_GPIO_ID shim_gpio_id) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_SHIM_PWM_HC shim_pwm_hc) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_SHIM_RTC shim_rtc) @@ -74,6 +75,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PS8XXX ps8xxx) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_GPIO_UNHOOK gpio_unhook) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_HOST_COMMAND_MEMORY_DUMP host_command_memory_dump) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ANX7452 anx7452) +add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_SM5803 sm5803) get_target_property(TEST_SOURCES_NEW app SOURCES) diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig index 726859068f..0a39a54ec6 100644 --- a/zephyr/test/drivers/Kconfig +++ b/zephyr/test/drivers/Kconfig @@ -120,6 +120,11 @@ config LINK_TEST_SUITE_RT1718S config LINK_TEST_SUITE_RT9490 bool "Link and test the rt9490 tests" +config LINK_TEST_SUITE_RANDOM + bool "Link and run random (trng) tests" + help + Include the test suite exercising RNG code in the binary. + config LINK_TEST_SUITE_SHIM_GPIO_ID bool "Link and run the gpio tests" @@ -242,4 +247,7 @@ config LINK_TEST_SUITE_ANX7452 Include the test suite of ANX7452 retimer in the binary. The tests use I2C emulation. +config LINK_TEST_SUITE_SM5803 + bool "Link and test the SM5803 charger tests" + source "Kconfig.zephyr" diff --git a/zephyr/test/drivers/boards/native_posix.overlay b/zephyr/test/drivers/boards/native_posix.overlay index d4aefdd4cd..ac5945f586 100644 --- a/zephyr/test/drivers/boards/native_posix.overlay +++ b/zephyr/test/drivers/boards/native_posix.overlay @@ -172,7 +172,7 @@ gpios = <&gpio0 13 GPIO_INPUT>; }; gpio_usb_c0_ppc_int: usb_c0_ppc_int { - gpios = <&gpio0 14 GPIO_INPUT>; + gpios = <&gpio0 14 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; }; gpio_switchcap_pg_int_l: switchcap_pg_int_l { gpios = <&gpio0 15 (GPIO_OUTPUT | GPIO_INPUT)>; @@ -1033,45 +1033,44 @@ pwm-led-pins { compatible = "cros-ec,pwm-led-pins"; - color-off-left { - led-color = "LED_OFF"; + left-led { led-id = "EC_LED_ID_LEFT_LED"; led-pwms = <&pwmled_blue_left &pwmled_white_left>; - led-values = <0 0>; - }; - color-off-right { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_RIGHT_LED"; - led-pwms = <&pwmled_amber_right &pwmled_white_right>; - led-values = <0 0>; - }; - color-blue-left { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pwms = <&pwmled_blue_left &pwmled_white_left>; - led-values = <100 0>; - }; - color-amber-right { - led-color = "LED_AMBER"; - led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_AMBER"; - led-pwms = <&pwmled_amber_right &pwmled_white_right>; - led-values = <100 0>; - }; - color-white-left { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_LEFT_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pwms = <&pwmled_blue_left &pwmled_white_left>; - led-values = <0 100>; + + color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + color-blue { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <100 0>; + }; + color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; - color-white-right { - led-color = "LED_WHITE"; + + right-led { led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_WHITE"; led-pwms = <&pwmled_amber_right &pwmled_white_right>; - led-values = <0 100>; + + color-off { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + color-amber { + led-color = "LED_AMBER"; + br-color = "EC_LED_COLOR_AMBER"; + led-values = <100 0>; + }; + color-white { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 100>; + }; }; }; diff --git a/zephyr/test/drivers/cbi_flash/src/cbi_flash.c b/zephyr/test/drivers/cbi_flash/src/cbi_flash.c index 1c93da1d2c..7863983d52 100644 --- a/zephyr/test/drivers/cbi_flash/src/cbi_flash.c +++ b/zephyr/test/drivers/cbi_flash/src/cbi_flash.c @@ -16,7 +16,7 @@ #define CBI_FLASH_NODE DT_NODELABEL(cbi_flash) #define CBI_FLASH_OFFSET DT_PROP(CBI_FLASH_NODE, offset) -FAKE_VALUE_FUNC(int, crec_flash_read, int, int, char *); +FAKE_VALUE_FUNC(int, crec_flash_unprotected_read, int, int, char *); ZTEST(cbi_flash, test_cbi_flash_is_write_protected) { @@ -42,7 +42,7 @@ ZTEST(cbi_flash, test_cbi_flash_load) input_data[index] = index % 255; } cbi_config.drv->store(input_data); - crec_flash_read_fake.return_val = crec_flash_physical_read( + crec_flash_unprotected_read_fake.return_val = crec_flash_physical_read( CBI_FLASH_OFFSET, CBI_IMAGE_SIZE, data); zassert_ok(cbi_config.drv->load(0, data, 0)); @@ -55,7 +55,7 @@ ZTEST(cbi_flash, test_cbi_flash_load_error) { uint8_t data[CBI_IMAGE_SIZE]; - crec_flash_read_fake.return_val = EC_ERROR_INVAL; + crec_flash_unprotected_read_fake.return_val = EC_ERROR_INVAL; zassert_equal(cbi_config.drv->load(0, data, 0), EC_ERROR_INVAL); } @@ -78,7 +78,7 @@ ZTEST(cbi_flash, test_cbi_flash_store_fail) static void cbi_flash_before(void *fixture) { ARG_UNUSED(fixture); - RESET_FAKE(crec_flash_read); + RESET_FAKE(crec_flash_unprotected_read); } ZTEST_SUITE(cbi_flash, drivers_predicate_post_main, NULL, cbi_flash_before, diff --git a/zephyr/test/drivers/default/src/bb_retimer.c b/zephyr/test/drivers/default/src/bb_retimer.c index aa31dbceed..ea335c2965 100644 --- a/zephyr/test/drivers/default/src/bb_retimer.c +++ b/zephyr/test/drivers/default/src/bb_retimer.c @@ -628,23 +628,23 @@ ZTEST_USER(bb_retimer, test_bb_console_cmd) int rv; /* Validate well formed shell commands */ - rv = shell_execute_cmd(get_ec_shell(), "bb 1 r 2"); + rv = shell_execute_cmd(get_ec_shell(), "retimer 1 r 2"); zassert_ok(rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb 1 w 2 0"); + rv = shell_execute_cmd(get_ec_shell(), "retimer 1 w 2 0"); zassert_ok(rv, "rv=%d", rv); /* Validate errors for malformed shell commands */ - rv = shell_execute_cmd(get_ec_shell(), "bb x"); + rv = shell_execute_cmd(get_ec_shell(), "retimer x"); zassert_equal(EC_ERROR_PARAM_COUNT, rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb x r 2"); + rv = shell_execute_cmd(get_ec_shell(), "retimer x r 2"); zassert_equal(EC_ERROR_PARAM1, rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb 0 r 2"); - zassert_equal(EC_ERROR_PARAM1, rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb 1 x 2"); + rv = shell_execute_cmd(get_ec_shell(), "retimer 0 r 2"); + zassert_equal(EC_ERROR_UNIMPLEMENTED, rv, "rv=%d", rv); + rv = shell_execute_cmd(get_ec_shell(), "retimer 1 x 2"); zassert_equal(EC_ERROR_PARAM2, rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb 1 r x"); + rv = shell_execute_cmd(get_ec_shell(), "retimer 1 r x"); zassert_equal(EC_ERROR_PARAM3, rv, "rv=%d", rv); - rv = shell_execute_cmd(get_ec_shell(), "bb 1 w 2 x"); + rv = shell_execute_cmd(get_ec_shell(), "retimer 1 w 2 x"); zassert_equal(EC_ERROR_PARAM4, rv, "rv=%d", rv); } diff --git a/zephyr/test/drivers/default/src/bmi160.c b/zephyr/test/drivers/default/src/bmi160.c index 257040b6dd..e11febbd96 100644 --- a/zephyr/test/drivers/default/src/bmi160.c +++ b/zephyr/test/drivers/default/src/bmi160.c @@ -347,7 +347,7 @@ ZTEST_USER(bmi160, test_bmi_gyr_set_offset) const struct emul *emul = EMUL_DT_GET(BMI_NODE); struct i2c_common_emul_data *common_data = emul_bmi_get_i2c_common_data(emul); - int16_t input_v[3]; + int16_t input_v[3] = { 0, 0, 0 }; int16_t temp = 0; intv3_t ret_v; intv3_t exp_v; @@ -417,6 +417,55 @@ ZTEST_USER(bmi160, test_bmi_gyr_set_offset) } /** + * Test set gyroscope offset with extreme values. + */ +ZTEST_USER(bmi160, test_bmi_gyr_set_offset_min_max) +{ + struct motion_sensor_t *ms; + const struct emul *emul = EMUL_DT_GET(BMI_NODE); + int16_t input_v[3]; + int16_t temp = 0; + intv3_t ret_v; + intv3_t exp_v; + + ms = &motion_sensors[BMI_GYR_SENSOR_ID]; + + /* Set expected offsets */ + exp_v[0] = 8176; + exp_v[1] = -8192; + exp_v[2] = 0; + /* Set some extreme values. */ + input_v[0] = INT16_MAX; + input_v[1] = INT16_MIN; + input_v[2] = 0; + /* Disable rotation */ + ms->rot_standard_ref = NULL; + + /* Test set offset without rotation */ + zassert_equal(EC_SUCCESS, ms->drv->set_offset(ms, input_v, temp)); + get_emul_gyr_offset(emul, ret_v); + compare_int3v(exp_v, ret_v); + /* Gyroscope offset should be enabled */ + zassert_true(bmi_emul_get_reg(emul, BMI160_OFFSET_EN_GYR98) & + BMI160_OFFSET_GYRO_EN, + NULL); + + /* Setup rotation and rotate input for set_offset function */ + ms->rot_standard_ref = &test_rotation; + convert_int3v_int16(input_v, ret_v); + rotate_int3v_by_test_rotation(ret_v); + convert_int3v_int16(ret_v, input_v); + + /* Test set offset with rotation */ + zassert_equal(EC_SUCCESS, ms->drv->set_offset(ms, input_v, temp)); + get_emul_gyr_offset(emul, ret_v); + compare_int3v(exp_v, ret_v); + zassert_true(bmi_emul_get_reg(emul, BMI160_OFFSET_EN_GYR98) & + BMI160_OFFSET_GYRO_EN, + NULL); +} + +/** * Try to set accelerometer range and check if expected range was set * in driver and in emulator. */ @@ -2154,6 +2203,9 @@ static void bmi160_after(void *state) acc_ms->drv->set_data_rate(acc_ms, 0, 0); gyr_ms->drv->set_data_rate(gyr_ms, 0, 0); + + gyr_ms->rot_standard_ref = NULL; + acc_ms->rot_standard_ref = NULL; } ZTEST_SUITE(bmi160, drivers_predicate_pre_main, NULL, bmi160_before, diff --git a/zephyr/test/drivers/default/src/lis2dw12.c b/zephyr/test/drivers/default/src/lis2dw12.c index 4cacf725ba..e7609300a0 100644 --- a/zephyr/test/drivers/default/src/lis2dw12.c +++ b/zephyr/test/drivers/default/src/lis2dw12.c @@ -337,14 +337,14 @@ ZTEST(lis2dw12, test_lis2dw12_set_rate) test_params[i].expected_reg_val, odr_bits, LIS2DW12_ODR_MAX_VAL); - /* Check if high performance mode was enabled if rate > - * 200,000mHz + /* Check if high performance mode was enabled if rate >= + * 50,000mHz */ uint8_t mode_bits = lis2dw12_emul_peek_mode(emul); uint8_t lpmode_bits = lis2dw12_emul_peek_lpmode(emul); - if (odr_bits > LIS2DW12_ODR_200HZ_VAL) { + if (odr_bits >= LIS2DW12_ODR_50HZ_VAL) { /* High performance mode, LP mode immaterial */ zassert_equal(mode_bits, LIS2DW12_HIGH_PERF, "MODE[1:0] should be 0x%x, but got 0x%x", diff --git a/zephyr/test/drivers/flash/src/flash.c b/zephyr/test/drivers/flash/src/flash.c index 17bb1da373..c3d9c65b36 100644 --- a/zephyr/test/drivers/flash/src/flash.c +++ b/zephyr/test/drivers/flash/src/flash.c @@ -564,32 +564,301 @@ static uint16_t read_flash_helper32(uint32_t offset, uint32_t *output) ZTEST_USER(flash, test_console_cmd_flash_erase__happy) { /* Immediately before the region to erase */ - zassert_ok(write_flash_helper32(0x40000 - 4, 0x5A5A5A5A)); + zassert_ok(write_flash_helper32(0x10000 - 4, 0x5A5A5A5A)); /* Start and end of the region we will erase */ - zassert_ok(write_flash_helper32(0x40000, 0xA1B2C3D4)); - zassert_ok(write_flash_helper32(0x50000 - 4, 0x1A2B3C4D)); + zassert_ok(write_flash_helper32(0x10000, 0xA1B2C3D4)); + zassert_ok(write_flash_helper32(0x20000 - 4, 0x1A2B3C4D)); /* Immediately after the region to erase */ - zassert_ok(write_flash_helper32(0x50000, 0xA5A5A5A5)); + zassert_ok(write_flash_helper32(0x20000, 0xA5A5A5A5)); + + CHECK_CONSOLE_CMD("flasherase 0x10000 0x10000", NULL, EC_SUCCESS); + + uint32_t output; + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x10000 - 4, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x20000, &output)); + zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x10000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x20000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +#ifdef CONFIG_PLATFORM_EC_CBI_FLASH +ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_0) +{ + uint32_t output; + + /* Immediately before the region to erase */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5A5A)); + /* Immediately after the region to erase */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5)); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x3F000 0x1000", NULL, EC_SUCCESS); + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_left) +{ + uint32_t output; + + /* Immediately before the region to erase */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5A5A)); + /* Immediately after the region to erase */ + zassert_ok(write_flash_helper32(0x50000, 0x5A5A5A5A)); + /* Immediately after the CBI region */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5)); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x3F000 0x11000", NULL, EC_SUCCESS); + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x50000, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x50000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_right) +{ + uint32_t output; + + /* Immediately before the region to erase */ + zassert_ok(write_flash_helper32(0x2F000 - 4, 0x5A5A5A5A)); + /* Immediately after the region to erase */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5)); + /* Immediately before the CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0xA5A5A5AA)); + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0xA5A5A5AA, "Got %08x", output); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x2F000 0x11000", NULL, EC_SUCCESS); + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x2F000 - 4, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x2F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} - CHECK_CONSOLE_CMD("flasherase 0x40000 0x10000", NULL, EC_SUCCESS); +ZTEST_USER(flash, test_console_cmd_flash_erase__left) +{ + uint32_t output; + /* Immediately before the region to erase */ + zassert_ok(write_flash_helper32(0x3E000 - 4, 0x5A5A5A5A)); + zassert_ok(write_flash_helper32(0x3E000, 0x5A5AAA5A)); + /* Immediately before the CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5AAA)); + /* Immediately after the CBI region */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5)); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x3E000 0x1000", NULL, EC_SUCCESS); + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x3E000 - 4, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x3E000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +ZTEST_USER(flash, test_console_cmd_flash_erase__right) +{ uint32_t output; + /* Immediately before the CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x5A5A5AAA)); + /* Immediately after the CBI region */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A5A5A5)); + zassert_ok(write_flash_helper32(0x41000 - 4, 0x555A5A5A)); + /* Immediately after the region to erase */ + zassert_ok(write_flash_helper32(0x41000, 0x5A5A5A5A)); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x40000 0x1000", NULL, EC_SUCCESS); + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0x5A5A5AAA, "Got %08x", output); + zassert_ok(read_flash_helper32(0x41000, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + + /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x41000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +ZTEST_USER(flash, test_console_cmd_flash_erase__cbi_overlap_1) +{ + uint32_t output; + + /* Immediately before the region to erase */ + zassert_ok(write_flash_helper32(0x20000 - 4, 0x5A5A5A5A)); + /* Immediately after the region to erase */ + zassert_ok(write_flash_helper32(0x50000, 0xA5A5A5A5)); + /* Immediately before the CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x555A5A5A)); + /* Immediately after the CBI region */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A555A5)); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0x555A5A5A, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A555A5, "Got %08x", output); + + CHECK_CONSOLE_CMD("flasherase 0x20000 0x30000", NULL, EC_SUCCESS); + + /* These should remain untouched */ + zassert_ok(read_flash_helper32(0x20000 - 4, &output)); zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); zassert_ok(read_flash_helper32(0x50000, &output)); zassert_equal(output, 0xA5A5A5A5, "Got %08x", output); /* These are within the erase region and should be reset to all FF */ + zassert_ok(read_flash_helper32(0x20000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); zassert_ok(read_flash_helper32(0x40000, &output)); zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); zassert_ok(read_flash_helper32(0x50000 - 4, &output)); zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); } +ZTEST_USER(flash, test_console_cmd_flash_write__cbi_0) +{ + uint32_t output; + + /* Immediately before the CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 4, 0x555A5A5A)); + zassert_ok(read_flash_helper32(0x3F000 - 4, &output)); + zassert_equal(output, 0x555A5A5A, "Got %08x", output); + /* Immediately after the CBI region */ + zassert_ok(write_flash_helper32(0x40000, 0xA5A555A5)); + zassert_ok(read_flash_helper32(0x40000, &output)); + zassert_equal(output, 0xA5A555A5, "Got %08x", output); + + /* The CBI region */ + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + zassert_ok(write_flash_helper32(0x10000, 0x5A5A5A5A)); + zassert_ok(read_flash_helper32(0x10000, &output)); + zassert_equal(output, 0x5A5A5A5A, "Got %08x", output); + + zassert_ok(write_flash_helper32(0x50000, 0x5AAA5A5A)); + zassert_ok(read_flash_helper32(0x50000, &output)); + zassert_equal(output, 0x5AAA5A5A, "Got %08x", output); + + zassert_ok(write_flash_helper32(0x3F000, 0x5A5A5A5A)); + zassert_ok(read_flash_helper32(0x3F000, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); + + zassert_ok(write_flash_helper32(0x40000 - 4, 0x5AAA5A5A)); + zassert_ok(read_flash_helper32(0x40000 - 4, &output)); + zassert_equal(output, 0xFFFFFFFF, "Got %08x", output); +} + +ZTEST_USER(flash, test_console_cmd_flash_write__cbi_1) +{ + uint32_t output; + + /* At the start of CBI region */ + zassert_ok(write_flash_helper32(0x3F000 - 2, 0x555A5A5A)); + zassert_ok(read_flash_helper32(0x3F000 - 2, &output)); + zassert_equal(output, 0xFFFF5A5A, "Got %08x", output); + + /* At the end of CBI region */ + zassert_ok(write_flash_helper32(0x40000 - 2, 0xA5A555A5)); + zassert_ok(read_flash_helper32(0x40000 - 2, &output)); + zassert_equal(output, 0xA5A5FFFF, "Got %08x", output); +} +#endif + ZTEST_USER(flash, test_console_cmd_flash_write__flash_locked) { /* Force write protection on */ diff --git a/zephyr/test/drivers/led_driver/led_pins.dts b/zephyr/test/drivers/led_driver/led_pins.dts index cf57102a3c..dc672f56cd 100644 --- a/zephyr/test/drivers/led_driver/led_pins.dts +++ b/zephyr/test/drivers/led_driver/led_pins.dts @@ -14,51 +14,44 @@ gpio-led-pins { compatible = "cros-ec,gpio-led-pins"; - color_off_left: color-off-left { - led-color = "LED_OFF"; + left-led { led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; led-pins = <&gpio_ec_chg_led_y_c1 &gpio_ec_chg_led_w_c1>; - led-values = <0 0>; + color_off_left: color-off-left { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + color_blue_left: color-blue-left { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <1 0>; + }; + color_white_left: color-white-left { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 1>; + }; }; - color_off_right: color-off-right { - led-color = "LED_OFF"; - led-id = "EC_LED_ID_RIGHT_LED"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0>; - led-values = <0 0>; - }; - color_blue_left: color-blue-left { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_y_c1 - &gpio_ec_chg_led_w_c1>; - led-values = <1 0>; - }; - color_blue_right: color-blue-right { - led-color = "LED_BLUE"; - led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_BLUE"; - led-pins = <&gpio_ec_chg_led_y_c0 - &gpio_ec_chg_led_w_c0>; - led-values = <1 0>; - }; - color_white_left: color-white-left { - led-color = "LED_WHITE"; - led-id = "EC_LED_ID_SYSRQ_DEBUG_LED"; - br-color = "EC_LED_COLOR_WHITE"; - led-pins = <&gpio_ec_chg_led_y_c1 - &gpio_ec_chg_led_w_c1>; - led-values = <0 1>; - }; - color_white_right: color-white-right { - led-color = "LED_WHITE"; + + right-led { led-id = "EC_LED_ID_RIGHT_LED"; - br-color = "EC_LED_COLOR_WHITE"; led-pins = <&gpio_ec_chg_led_y_c0 &gpio_ec_chg_led_w_c0>; - led-values = <0 1>; + color_off_right: color-off-right { + led-color = "LED_OFF"; + led-values = <0 0>; + }; + color_blue_right: color-blue-right { + led-color = "LED_BLUE"; + br-color = "EC_LED_COLOR_BLUE"; + led-values = <1 0>; + }; + color_white_right: color-white-right { + led-color = "LED_WHITE"; + br-color = "EC_LED_COLOR_WHITE"; + led-values = <0 1>; + }; }; }; }; diff --git a/zephyr/test/drivers/power_host_sleep/src/test_power_host_sleep.c b/zephyr/test/drivers/power_host_sleep/src/test_power_host_sleep.c index 28617e2d59..46ff0cef65 100644 --- a/zephyr/test/drivers/power_host_sleep/src/test_power_host_sleep.c +++ b/zephyr/test/drivers/power_host_sleep/src/test_power_host_sleep.c @@ -397,5 +397,33 @@ ZTEST(power_host_sleep, test_set_get_host_sleep_state) HOST_SLEEP_EVENT_S0IX_RESUME); } +ZTEST(power_host_sleep, verify_increment_change_state) +{ + struct ec_params_s0ix_cnt params = { .flags = EC_S0IX_COUNTER_RESET }; + struct ec_response_s0ix_cnt rsp; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_GET_S0IX_COUNTER, 0, rsp, params); + + /* Verify that counter is set to 0 */ + zassert_ok(host_command_process(&args), "Failed to get sleep counter"); + zassert_equal(rsp.s0ix_counter, 0); + + /* Simulate S0ix state */ + sleep_set_notify(SLEEP_NOTIFY_SUSPEND); + sleep_notify_transition(SLEEP_NOTIFY_SUSPEND, HOOK_CHIPSET_SUSPEND); + + /* Confirm counter incrementation */ + params.flags = 0; + zassert_ok(host_command_process(&args), "Failed to get sleep counter"); + zassert_equal(rsp.s0ix_counter, 1); + + /* Reset counter and re-fetch it to verify that reset works */ + params.flags = EC_S0IX_COUNTER_RESET; + zassert_ok(host_command_process(&args), "Failed to get sleep counter"); + params.flags = 0; + zassert_ok(host_command_process(&args), "Failed to get sleep counter"); + zassert_equal(rsp.s0ix_counter, 0); +} + ZTEST_SUITE(power_host_sleep, drivers_predicate_post_main, NULL, power_host_sleep_before_after, power_host_sleep_before_after, NULL); diff --git a/zephyr/test/drivers/random/CMakeLists.txt b/zephyr/test/drivers/random/CMakeLists.txt new file mode 100644 index 0000000000..0858abf2f6 --- /dev/null +++ b/zephyr/test/drivers/random/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +target_sources(app PRIVATE src/random.c) diff --git a/zephyr/test/drivers/random/src/random.c b/zephyr/test/drivers/random/src/random.c new file mode 100644 index 0000000000..f8849c839c --- /dev/null +++ b/zephyr/test/drivers/random/src/random.c @@ -0,0 +1,96 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "console.h" +#include "ec_commands.h" +#include "host_command.h" +#include "test/drivers/test_mocks.h" +#include "test/drivers/test_state.h" +#include "trng.h" + +#include <zephyr/shell/shell_dummy.h> +#include <zephyr/ztest.h> + +ZTEST_USER(random, test_hostcmd_rand) +{ + uint8_t rand_response1[16]; + uint8_t rand_response2[16]; + struct ec_params_rand_num params = { + .num_rand_bytes = 16, + }; + struct host_cmd_handler_args args1 = BUILD_HOST_COMMAND( + EC_CMD_RAND_NUM, EC_VER_RAND_NUM, rand_response1, params); + struct host_cmd_handler_args args2 = BUILD_HOST_COMMAND( + EC_CMD_RAND_NUM, EC_VER_RAND_NUM, rand_response2, params); + + /* + * It's necessary to set response_max, because 'ec_response_rand_num' + * structure has flexible array member. + */ + args1.response_max = 16; + args2.response_max = 16; + system_is_locked_fake.return_val = 0; + + zassert_ok(host_command_process(&args1), NULL); + zassert_ok(host_command_process(&args2), NULL); + zassert_equal(args1.response_size, params.num_rand_bytes); + zassert_equal(args2.response_size, params.num_rand_bytes); + zassert_true(memcmp(rand_response1, rand_response2, + params.num_rand_bytes) != 0); + zassert_equal(system_is_locked_fake.call_count, 2); +} + +ZTEST_USER(random, test_hostcmd_rand_overflow) +{ + uint8_t rand_response[16]; + struct ec_params_rand_num params = { + .num_rand_bytes = 16, + }; + struct host_cmd_handler_args args = BUILD_HOST_COMMAND( + EC_CMD_RAND_NUM, EC_VER_RAND_NUM, rand_response, params); + + /* Change maximum response size to small value. */ + args.response_max = 8; + system_is_locked_fake.return_val = 0; + + zassert_equal(host_command_process(&args), EC_RES_OVERFLOW); +} + +ZTEST_USER(random, test_hostcmd_rand_access_denied) +{ + uint8_t rand_response[16]; + struct ec_params_rand_num params = { + .num_rand_bytes = 16, + }; + + system_is_locked_fake.return_val = 1; + + zassert_equal( + ec_cmd_rand_num(NULL, ¶ms, + (struct ec_response_rand_num *)rand_response), + EC_RES_ACCESS_DENIED, NULL); + zassert_equal(system_is_locked_fake.call_count, 1); +} + +ZTEST_USER(random, test_console_cmd_rand) +{ + const struct shell *shell_zephyr = get_ec_shell(); + const char *outbuffer; + size_t buffer_size; + + shell_backend_dummy_clear_output(shell_zephyr); + + zassert_ok(shell_execute_cmd(shell_zephyr, "rand")); + outbuffer = shell_backend_dummy_get_output(shell_zephyr, &buffer_size); + + /* + * Output has "rand 64_random_characters" format, so buffer should have + * at least 69 characters. + */ + zassert_true(buffer_size >= 69, "buffer size is %d", buffer_size); + zassert_not_null(strstr(outbuffer, "rand ")); +} + +ZTEST_SUITE(random, drivers_predicate_post_main, NULL, NULL, NULL, NULL); diff --git a/zephyr/test/drivers/sm5803/CMakeLists.txt b/zephyr/test/drivers/sm5803/CMakeLists.txt new file mode 100644 index 0000000000..f7dfa41b4c --- /dev/null +++ b/zephyr/test/drivers/sm5803/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +target_sources(app PRIVATE src/sm5803.c src/usbc.c) diff --git a/zephyr/test/drivers/sm5803/prj.conf b/zephyr/test/drivers/sm5803/prj.conf new file mode 100644 index 0000000000..67e8d4287e --- /dev/null +++ b/zephyr/test/drivers/sm5803/prj.conf @@ -0,0 +1,6 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_PLATFORM_EC_CHARGER_SM5803=y +CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=15000 diff --git a/zephyr/test/drivers/sm5803/sm5803.dts b/zephyr/test/drivers/sm5803/sm5803.dts new file mode 100644 index 0000000000..4e0fab39e3 --- /dev/null +++ b/zephyr/test/drivers/sm5803/sm5803.dts @@ -0,0 +1,32 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + usbc { + port0@0 { + compatible = "named-usbc-port"; + chg = <&sm5803_emul>; + }; + }; + + gpio2: gpio@2000 { + status = "okay"; + compatible = "zephyr,gpio-emul"; + reg = <0x2000 0x4>; + falling-edge; + gpio-controller; + #gpio-cells = <2>; + ngpios = <1>; + }; +}; + +&i2c0 { + sm5803_emul: sm5803@32 { + compatible = "cros,sm5803-emul", "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + interrupt-gpios = <&gpio2 0 (GPIO_ACTIVE_LOW)>; + }; +}; diff --git a/zephyr/test/drivers/sm5803/src/sm5803.c b/zephyr/test/drivers/sm5803/src/sm5803.c new file mode 100644 index 0000000000..159f91bc71 --- /dev/null +++ b/zephyr/test/drivers/sm5803/src/sm5803.c @@ -0,0 +1,709 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery_smart.h" +#include "charger.h" +#include "driver/charger/sm5803.h" +#include "emul/emul_common_i2c.h" +#include "emul/emul_sm5803.h" +#include "emul/tcpc/emul_tcpci_partner_src.h" +#include "test/drivers/charger_utils.h" +#include "test/drivers/test_state.h" +#include "test/drivers/utils.h" + +#include <zephyr/drivers/emul.h> +#include <zephyr/ztest.h> + +#define CHARGER_NUM get_charger_num(&sm5803_drv) +#define SM5803_EMUL EMUL_DT_GET(DT_NODELABEL(sm5803_emul)) + +ZTEST_SUITE(sm5803, drivers_predicate_post_main, NULL, NULL, NULL, NULL); + +ZTEST(sm5803, test_chip_id) +{ + int id; + + /* Emulator only implements chip revision 3. */ + zassert_ok(sm5803_drv.device_id(CHARGER_NUM, &id)); + zassert_equal(id, 3); + + /* After a successful read, the value is cached. */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), + SM5803_REG_CHIP_ID); + zassert_ok(sm5803_drv.device_id(CHARGER_NUM, &id)); +} + +struct i2c_log_entry { + bool write; + uint8_t i2c_addr; + uint8_t reg_addr; + uint8_t value; +}; + +struct i2c_log { + struct i2c_log_entry entries[128]; + size_t entries_used; + size_t entries_asserted; +}; + +#define LOG_ASSERT(_write, _i2c_addr, _reg_addr, _value) \ + do { \ + zassert_true(log_ptr->entries_asserted < \ + log_ptr->entries_used, \ + "No more I2C transactions to verify " \ + "(logged %d)", \ + log_ptr->entries_used); \ + size_t i = log_ptr->entries_asserted++; \ + struct i2c_log_entry *entry = &log_ptr->entries[i]; \ + \ + zassert(entry->write == _write && \ + entry->i2c_addr == _i2c_addr && \ + entry->reg_addr == _reg_addr && \ + (!_write || entry->value == _value), \ + "I2C log mismatch", \ + "Transaction %d did not match expectations:\n" \ + "expected %5s of address %#04x register" \ + " %#04x with value %#04x\n" \ + " found %s of address %#04x register" \ + " %#04x with value %#04x", \ + i, _write ? "write" : "read", _i2c_addr, _reg_addr, \ + _value, entry->write ? "write" : "read", \ + entry->i2c_addr, entry->reg_addr, entry->value); \ + } while (0) + +#define LOG_ASSERT_R(_i2c_addr, _reg_addr) \ + LOG_ASSERT(false, _i2c_addr, _reg_addr, 0) +#define LOG_ASSERT_W(_i2c_addr, _reg_addr, _value) \ + LOG_ASSERT(true, _i2c_addr, _reg_addr, _value) +#define LOG_ASSERT_RW(_i2c_addr, _reg_addr, _value) \ + do { \ + LOG_ASSERT_R(_i2c_addr, _reg_addr); \ + LOG_ASSERT_W(_i2c_addr, _reg_addr, _value); \ + } while (0) + +/* + * Generate a function for each I2C address to log the correct address, because + * the target pointer is the same for each I2C address and there's no way to + * determine from parameters what address we're meant to be. + */ +#define DEFINE_LOG_FNS(name, addr) \ + static int i2c_log_write_##name(const struct emul *target, int reg, \ + uint8_t val, int bytes, void *ctx) \ + { \ + struct i2c_log *log = ctx; \ + \ + if (log->entries_used >= ARRAY_SIZE(log->entries)) { \ + return -ENOSPC; \ + } \ + \ + zassert_equal(target->bus_type, EMUL_BUS_TYPE_I2C); \ + log->entries[log->entries_used++] = (struct i2c_log_entry){ \ + .write = true, \ + .i2c_addr = addr, \ + .reg_addr = reg, \ + .value = val, \ + }; \ + \ + /* Discard write. */ \ + return 0; \ + } \ + \ + static int i2c_log_read_##name(const struct emul *target, int reg, \ + uint8_t *val, int bytes, void *ctx) \ + { \ + struct i2c_log *log = ctx; \ + \ + if (log->entries_used >= ARRAY_SIZE(log->entries)) { \ + return -ENOSPC; \ + } \ + \ + zassert_equal(target->bus_type, EMUL_BUS_TYPE_I2C); \ + log->entries[log->entries_used++] = (struct i2c_log_entry){ \ + .write = false, \ + .i2c_addr = addr, \ + .reg_addr = reg, \ + }; \ + \ + /* Fall through to emulator read. */ \ + return 1; \ + } + +DEFINE_LOG_FNS(main, SM5803_ADDR_MAIN_FLAGS); +DEFINE_LOG_FNS(meas, SM5803_ADDR_MEAS_FLAGS); +DEFINE_LOG_FNS(chg, SM5803_ADDR_CHARGER_FLAGS); +DEFINE_LOG_FNS(test, SM5803_ADDR_TEST_FLAGS); + +static void configure_i2c_log(const struct emul *emul, struct i2c_log *log) +{ + i2c_common_emul_set_read_func(sm5803_emul_get_i2c_main(emul), + i2c_log_read_main, log); + i2c_common_emul_set_write_func(sm5803_emul_get_i2c_main(emul), + i2c_log_write_main, log); + i2c_common_emul_set_read_func(sm5803_emul_get_i2c_meas(emul), + i2c_log_read_meas, log); + i2c_common_emul_set_write_func(sm5803_emul_get_i2c_meas(emul), + i2c_log_write_meas, log); + i2c_common_emul_set_read_func(sm5803_emul_get_i2c_chg(emul), + i2c_log_read_chg, log); + i2c_common_emul_set_write_func(sm5803_emul_get_i2c_chg(emul), + i2c_log_write_chg, log); + i2c_common_emul_set_read_func(sm5803_emul_get_i2c_test(emul), + i2c_log_read_test, log); + i2c_common_emul_set_write_func(sm5803_emul_get_i2c_test(emul), + i2c_log_write_test, log); +} + +static void verify_init_common(struct i2c_log *const log_ptr) +{ + /* Enable LDOs */ + LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_REFERENCE, 0); + /* Psys DAC */ + LOG_ASSERT_RW(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_PSYS1, 0x05); + /* ADC sigma delta */ + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_CC_CONFIG1, 0x09); + /* PROCHOT comparators */ + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PHOT1, 0x2d); + /* DPM voltage */ + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_DPM_VL_SET_MSB, + 0x12); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_DPM_VL_SET_LSB, + 0x04); + /* Default input current limit */ + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_CHG_ILIM, 0x05); + /* Interrupts */ + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT1_EN, 0x04); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT4_EN, 0x13); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_TINT_HIGH_TH, 0xd1); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_TINT_LOW_TH, 0); + LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT2_EN, 0x81); + /* Charging is exclusively EC-controlled */ + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW2, 0x40); + /* Battery parameters */ + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FAST_CONF5, 0x02); + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PRE_FAST_CONF_REG1, + 0); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_PRECHG, 0x02); + /* BFET limits */ + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_BFET_PWR_MAX_TH, 0x33); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_BFET_PWR_HWSAFE_MAX_TH, + 0xcd); + LOG_ASSERT_RW(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_INT3_EN, 0x06); + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW3, 0); + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_SWITCHER_CONF, + 0x01); +} + +/** + * Driver internal "init completed" flag needs to be cleared to actually run + * init. + */ +extern bool chip_inited[1]; +/** Driver internal cached value of chip device ID. */ +extern int dev_id; + +ZTEST(sm5803, test_init_2s) +{ + struct i2c_log log = {}; + struct i2c_log *const log_ptr = &log; + + /* Hook up logging functions for each I2C address. */ + configure_i2c_log(SM5803_EMUL, &log); + + /* Emulator defaults to 2S PMODE so we don't need to set it. */ + chip_inited[0] = false; + sm5803_drv.init(CHARGER_NUM); + + /* Ensures we're in a safe state for operation. */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); + /* Checks VBUS presence and disables charger. */ + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); + /* Gets chip ID (already cached) and PMODE. */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_PLATFORM); + /* Writes a lot of registers for presumably important reasons. */ + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x26, 0xdc); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x21, 0x9b); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1a, 0x08); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x3e, 0x3c); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xbf); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xD2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xD1); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7F); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x01); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0x50); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7F); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5A, 0x13); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5B, 0x52); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5D, 0xD0); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7D, 0x97); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7E, 0x07); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x33, 0x3C); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5C, 0x7A); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x73, 0x22); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x88); + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, 0x34, 0x80); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0x01); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x43, 0x10); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x47, 0x10); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x48, 0x04); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); + verify_init_common(log_ptr); + + zassert_equal(log.entries_asserted, log.entries_used, + "recorded %d transactions but only verified %d", + log.entries_used, log.entries_asserted); + + /* + * Running init again should check and update VBUS presence but not + * re-run complete initialization. Doing more than that probably means + * the first init failed. + */ + log.entries_used = 0; + sm5803_drv.init(CHARGER_NUM); + zassert_equal(log.entries_used, 6); +} + +ZTEST(sm5803, test_init_3s) +{ + struct i2c_log log = {}; + struct i2c_log *const log_ptr = &log; + + /* Hook up logging functions for each I2C address. */ + configure_i2c_log(SM5803_EMUL, &log); + + /* Set 3S PMODE and run init */ + chip_inited[0] = false; + sm5803_emul_set_pmode(SM5803_EMUL, 0x14); + sm5803_drv.init(CHARGER_NUM); + + /* Ensures we're in a safe state for operation. */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); + /* Checks VBUS presence and disables charger. */ + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); + /* Gets chip ID (already cached) and PMODE. */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_PLATFORM); + /* Writes a lot of registers for presumably important reasons. */ + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x26, 0xd8); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x21, 0x9b); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1a, 0x08); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x3e, 0x3c); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4b, 0xa6); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xbf); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xD2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xD1); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7F); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x01); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0x50); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7F); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5A, 0x13); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5B, 0x50); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5D, 0xB0); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7D, 0x67); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x7E, 0x04); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x33, 0x3C); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5C, 0x7A); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x73, 0x22); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x88); + LOG_ASSERT_RW(SM5803_ADDR_CHARGER_FLAGS, 0x34, 0x80); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0x01); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x43, 0x10); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x47, 0x10); + LOG_ASSERT_W(SM5803_ADDR_TEST_FLAGS, 0x48, 0x04); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); + verify_init_common(log_ptr); + + zassert_equal(log.entries_asserted, log.entries_used, + "recorded %d transactions but only verified %d", + log.entries_used, log.entries_asserted); +} + +ZTEST(sm5803, test_init_rev2) +{ + struct i2c_log log = {}; + struct i2c_log *const log_ptr = &log; + + /* Hook up logging functions for each I2C address. */ + configure_i2c_log(SM5803_EMUL, &log); + + chip_inited[0] = false; + dev_id = -1; + sm5803_emul_set_device_id(SM5803_EMUL, 2); + sm5803_drv.init(CHARGER_NUM); + + /* Ensures we're in a safe state for operation. */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CLOCK_SEL); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1, 0xf7); + /* Checks VBUS presence and disables charger. */ + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_GPADC_CONFIG1); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_MSB); + LOG_ASSERT_R(SM5803_ADDR_MEAS_FLAGS, SM5803_REG_VBUS_MEAS_LSB); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, SM5803_REG_FLOW1, 0); + /* Gets chip ID */ + LOG_ASSERT_R(SM5803_ADDR_MAIN_FLAGS, SM5803_REG_CHIP_ID); + /* Writes a lot of registers for presumably important reasons. */ + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x20, 0x08); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x30, 0xc0); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x80, 0x01); + LOG_ASSERT_W(SM5803_ADDR_MEAS_FLAGS, 0x08, 0xc2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1d, 0x40); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x1f, 0x09); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x22, 0xb3); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x23, 0x81); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x28, 0xb7); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4a, 0x82); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4b, 0xa3); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4c, 0xa8); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4d, 0xca); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4e, 0x07); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x4f, 0xff); + + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x50, 0x98); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x51, 0); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x52, 0x77); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x53, 0xd2); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x54, 0x02); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x55, 0xd1); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x56, 0x7f); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x57, 0x02); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x58, 0xd1); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x59, 0x7f); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5a, 0x13); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5b, 0x50); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5c, 0x5b); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5d, 0xb0); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5e, 0x3c); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x5f, 0x3c); + + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x60, 0x44); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x61, 0x20); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x65, 0x35); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x66, 0x29); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x67, 0x64); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x68, 0x88); + LOG_ASSERT_W(SM5803_ADDR_CHARGER_FLAGS, 0x69, 0xc7); + + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 1); + LOG_ASSERT_RW(SM5803_ADDR_TEST_FLAGS, 0x8e, 0x20); + LOG_ASSERT_W(SM5803_ADDR_MAIN_FLAGS, 0x1f, 0); + + verify_init_common(log_ptr); + + zassert_equal(log.entries_asserted, log.entries_used, + "recorded %d transactions but only verified %d", + log.entries_used, log.entries_asserted); +} + +ZTEST(sm5803, test_fast_charge_current) +{ + int ma; + + /* + * Can set and read back charge current limit, + * which is adjusted when 0. + */ + zassert_ok(charger_set_current(CHARGER_NUM, 0)); + zassert_equal(1, sm5803_emul_get_fast_charge_current_limit(SM5803_EMUL), + "Zero current limit should be converted to nonzero"); + zassert_ok(charger_get_current(CHARGER_NUM, &ma)); + zassert_equal(ma, 100, + "Actual current should be 100 mA times register value"); + + /* Errors are propagated. */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), + SM5803_REG_FAST_CONF4); + zassert_not_equal( + 0, charger_set_current(CHARGER_NUM, 1000), + "set_current should fail if FAST_CONF4 is unreadable"); + zassert_not_equal( + 0, charger_get_current(CHARGER_NUM, &ma), + "get_current should fail if FAST_CONF4 is unreadable"); +} + +ZTEST(sm5803, test_measure_input_current) +{ + int ma; + + sm5803_emul_set_input_current(SM5803_EMUL, 852); + zassert_ok(charger_get_input_current(CHARGER_NUM, &ma)); + zassert_equal(ma, 849, "actual returned input current was %d", ma); + + /* Communication errors bubble up */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_IBUS_CHG_MEAS_LSB); + zassert_not_equal(0, charger_get_input_current(CHARGER_NUM, &ma)); + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_IBUS_CHG_MEAS_MSB); + zassert_not_equal(0, charger_get_input_current(CHARGER_NUM, &ma)); +} + +ZTEST(sm5803, test_input_current_limit) +{ + int icl; + bool reached; + + /* Can set and read back the input current limit. */ + zassert_ok(charger_set_input_current_limit(CHARGER_NUM, 2150)); + zassert_equal(21, sm5803_emul_read_chg_reg(SM5803_EMUL, + SM5803_REG_CHG_ILIM)); + zassert_ok(charger_get_input_current_limit(CHARGER_NUM, &icl)); + zassert_equal(2100, icl, + "expected 2100 mA input current limit, but was %d", icl); + + /* Can also check whether input current is limited. */ + zassert_ok(charger_is_icl_reached(CHARGER_NUM, &reached)); + zassert_false(reached); + sm5803_emul_set_input_current(SM5803_EMUL, 2400); + zassert_ok(charger_is_icl_reached(CHARGER_NUM, &reached)); + zassert_true(reached); + + /* Communication errors bubble up. */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), + SM5803_REG_CHG_ILIM); + zassert_not_equal(0, + charger_get_input_current_limit(CHARGER_NUM, &icl)); + i2c_common_emul_set_write_fail_reg(sm5803_emul_get_i2c_chg(SM5803_EMUL), + SM5803_REG_CHG_ILIM); + zassert_not_equal(0, + charger_set_input_current_limit(CHARGER_NUM, 1400)); +} + +/* Analog measurement of VBUS. */ +ZTEST(sm5803, test_get_vbus_voltage) +{ + int mv; + + /* Regular measurement with VBUS ADC enabled works. */ + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5032); + zassert_ok(charger_get_vbus_voltage(CHARGER_NUM, &mv)); + /* 5.031 is the nearest value representable by the VBUS ADC. */ + zassert_equal(mv, 5031, "driver reported %d mV VBUS", mv); + + /* Communication errors for ADC value bubble up. */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_VBUS_MEAS_LSB); + zassert_not_equal(0, charger_get_vbus_voltage(CHARGER_NUM, &mv)); + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_VBUS_MEAS_MSB); + zassert_not_equal(0, charger_get_vbus_voltage(CHARGER_NUM, &mv)); + + /* Returns a NOT_POWERED error if the VBUS ADC is disabled. */ + sm5803_emul_set_gpadc_conf(SM5803_EMUL, + (uint8_t)~SM5803_GPADCC1_VBUS_EN, 0); + zassert_equal(EC_ERROR_NOT_POWERED, + charger_get_vbus_voltage(CHARGER_NUM, &mv)); +} + +ZTEST(sm5803, test_get_battery_current) +{ + int ma; + + sm5803_emul_set_battery_current(SM5803_EMUL, 1234); + zassert_ok(charger_get_actual_current(CHARGER_NUM, &ma)); + /* 1229 mA is nearest value representable at ADC resolution */ + zassert_equal(ma, 1229, "read value was %d", ma); + + /* Communication errors bubble up. */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_IBAT_CHG_AVG_MEAS_LSB); + zassert_not_equal(0, charger_get_actual_current(CHARGER_NUM, &ma)); + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_meas(SM5803_EMUL), + SM5803_REG_IBAT_CHG_AVG_MEAS_MSB); + zassert_not_equal(0, charger_get_actual_current(CHARGER_NUM, &ma)); +} + +/* Digital VBUS presence detection derived from DHG_DET. */ +ZTEST(sm5803, test_digital_vbus_presence_detect) +{ + /* + * CHG_DET going high (from VBUS presence) triggers an interrupt and + * presence update. + */ + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); + k_sleep(K_SECONDS(1)); /* Allow interrupt to be serviced. */ + zassert_true(sm5803_is_vbus_present(CHARGER_NUM)); + + /* VBUS going away triggers another interrupt and update. */ + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 0); + k_sleep(K_SECONDS(1)); /* Allow interrupt to be serviced. */ + zassert_false(sm5803_is_vbus_present(CHARGER_NUM)); +} + +/* VBUS detection for PD, analog or digital depending on chip state. */ +ZTEST(sm5803, test_check_vbus_level) +{ + /* Default state with VBUS ADC enabled: uses analog value */ + zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_REMOVED)); + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); + zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); + + /* 4.6V is less than vSafe5V */ + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 4600); + k_sleep(K_SECONDS(1)); + zassert_false(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); + + /* + * With ADC disabled, uses digital presence only. 4.6V is high enough + * to trip CHG_DET but wasn't enough to count as present with the analog + * reading. + */ + sm5803_emul_set_gpadc_conf(SM5803_EMUL, 0, 0); + zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_PRESENT)); + + /* 0.4V is !CHG_DET */ + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 400); + k_sleep(K_SECONDS(1)); + zassert_true(sm5803_check_vbus_level(CHARGER_NUM, VBUS_REMOVED)); +} + +ZTEST(sm5803, test_lpm) +{ + const struct emul *tcpci_emul = EMUL_GET_USBC_BINDING(0, tcpc); + struct tcpci_partner_data partner; + struct tcpci_src_emul_data partner_src; + uint8_t gpadc1, gpadc2; + uint8_t cc_conf1; + uint8_t flow1, flow2, flow3; + + tcpci_partner_init(&partner, PD_REV30); + partner.extensions = tcpci_src_emul_init(&partner_src, &partner, NULL); + + /* Connect 5V source. */ + zassert_ok(tcpci_partner_connect_to_tcpci(&partner, tcpci_emul)); + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5000); + k_sleep(K_SECONDS(10)); + + /* Charger should now have exited runtime LPM. */ + zassert_false(sm5803_emul_is_clock_slowed(SM5803_EMUL)); + sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); + /* All except IBAT_DISCHG enabled. */ + zassert_equal(gpadc1, 0xf7, "actual value was %#x", gpadc1); + /* Default value. */ + zassert_equal(gpadc2, 1, "actual value was %#x", gpadc2); + /* Sigma-delta for Coulomb Counter is enabled. */ + cc_conf1 = sm5803_emul_get_cc_config(SM5803_EMUL); + zassert_equal(cc_conf1, 0x09, "actual value was %#x", cc_conf1); + /* Charger is sinking. */ + sm5803_emul_get_flow_regs(SM5803_EMUL, &flow1, &flow2, &flow3); + zassert_equal(flow1, 0x01, "FLOW1 should be set for sinking, was %#x", + flow1); + + /* Disconnect source, causing charger to go to runtime LPM. */ + zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul)); + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 24); + k_sleep(K_SECONDS(10)); + + zassert_true(sm5803_emul_is_clock_slowed(SM5803_EMUL)); + /* Sigma delta was disabled. */ + cc_conf1 = sm5803_emul_get_cc_config(SM5803_EMUL); + zassert_equal(sm5803_emul_get_cc_config(SM5803_EMUL), 0x01, + "actual value was %#x", cc_conf1); + /* + * Runtime LPM hook runs before the charge manager updates, so we expect + * the GPADCs to be left on because the charger is still set for sinking + * when it goes to runtime LPM. + */ + sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); + zassert_equal(gpadc1, 0xf7, "actual value was %#x", gpadc1); + zassert_equal(gpadc2, 1, "actual value was %#x", gpadc2); + + /* + * Reconnect the source and inhibit charging, so GPADCs can be disabled + * when we disconnect it. + */ + zassert_ok(tcpci_partner_connect_to_tcpci(&partner, tcpci_emul)); + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 5010); + k_sleep(K_SECONDS(10)); + zassert_ok(charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE)); + zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul)); + sm5803_emul_set_vbus_voltage(SM5803_EMUL, 0); + k_sleep(K_SECONDS(10)); + + /* This time LPM actually did disable the GPADCs. */ + sm5803_emul_get_gpadc_conf(SM5803_EMUL, &gpadc1, &gpadc2); + zassert_equal(gpadc1, 0, "actual value was %#x", gpadc1); + zassert_equal(gpadc2, 0, "actual value was %#x", gpadc2); +} + +ZTEST(sm5803, test_get_battery_cells) +{ + int cells; + + /* Default PMODE reports 2s */ + zassert_ok(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells)); + zassert_equal(cells, 2); + + /* 3s PMODE is 3s */ + sm5803_emul_set_pmode(SM5803_EMUL, 0x14); + zassert_ok(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells)); + zassert_equal(cells, 3); + + /* Unrecognized PMODE is an error */ + sm5803_emul_set_pmode(SM5803_EMUL, 0x1f); + zassert_not_equal(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells), 0); + zassert_equal(cells, -1); + + /* Communication error bubbles up */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), + SM5803_REG_PLATFORM); + zassert_not_equal(sm5803_drv.get_battery_cells(CHARGER_NUM, &cells), 0); +} + +ZTEST(sm5803, test_gpio) +{ + /* Open drain output */ + zassert_ok(sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_OUTPUT, 1)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x42); + /* Set output high, from default of low. */ + zassert_ok(sm5803_set_gpio0_level(CHARGER_NUM, 1)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x43); + /* Set it low again. */ + zassert_ok(sm5803_set_gpio0_level(CHARGER_NUM, 0)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x42); + + /* Push-pull prochot. */ + zassert_ok(sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_PROCHOT, 0)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x00); + + /* CHG_DET output enable lives in this register too */ + zassert_ok(sm5803_configure_chg_det_od(CHARGER_NUM, 1)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x80); + zassert_ok(sm5803_configure_chg_det_od(CHARGER_NUM, 0)); + zassert_equal(sm5803_emul_get_gpio_ctrl(SM5803_EMUL), 0x00); + + /* Communication errors bubble up */ + i2c_common_emul_set_read_fail_reg(sm5803_emul_get_i2c_main(SM5803_EMUL), + SM5803_REG_GPIO0_CTRL); + zassert_not_equal( + sm5803_configure_gpio0(CHARGER_NUM, GPIO0_MODE_INPUT, 0), 0); + zassert_not_equal(sm5803_set_gpio0_level(CHARGER_NUM, 0), 0); + zassert_not_equal(sm5803_configure_chg_det_od(CHARGER_NUM, 1), 0); +} diff --git a/zephyr/test/drivers/sm5803/src/usbc.c b/zephyr/test/drivers/sm5803/src/usbc.c new file mode 100644 index 0000000000..8028842a04 --- /dev/null +++ b/zephyr/test/drivers/sm5803/src/usbc.c @@ -0,0 +1,42 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "driver/charger/sm5803.h" +#include "driver/tcpm/tcpci.h" +#include "emul/emul_sm5803.h" +#include "test/drivers/charger_utils.h" + +#include <zephyr/drivers/emul.h> +#include <zephyr/drivers/gpio/gpio_emul.h> + +__override bool pd_check_vbus_level(int port, enum vbus_level level) +{ + return sm5803_check_vbus_level(port, level); +} + +static void pin_interrupt_handler(const struct device *gpio, + struct gpio_callback *const cb, + gpio_port_pins_t pins) +{ + sm5803_interrupt(get_charger_num(&sm5803_drv)); +} + +static int configure_charger_interrupt(void) +{ + const struct gpio_dt_spec *gpio = sm5803_emul_get_interrupt_gpio( + EMUL_DT_GET(DT_NODELABEL(sm5803_emul))); + static struct gpio_callback callback; + + if (!device_is_ready(gpio->port)) + k_oops(); + + gpio_emul_input_set(gpio->port, gpio->pin, 1); + gpio_pin_configure_dt(gpio, GPIO_INPUT | GPIO_ACTIVE_LOW); + gpio_init_callback(&callback, pin_interrupt_handler, BIT(gpio->pin)); + gpio_add_callback(gpio->port, &callback); + gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_EDGE_TO_ACTIVE); + + return 0; +} +SYS_INIT(configure_charger_interrupt, APPLICATION, 10); diff --git a/zephyr/test/drivers/system/src/system.c b/zephyr/test/drivers/system/src/system.c index 2bd8554994..051723f194 100644 --- a/zephyr/test/drivers/system/src/system.c +++ b/zephyr/test/drivers/system/src/system.c @@ -98,11 +98,61 @@ ZTEST(system, test_system_common_pre_init__watch_dog_panic) uint32_t info; uint8_t exception; + /* Watchdog reset should result in any existing panic data being + * overwritten + */ + panic_set_reason(PANIC_SW_DIV_ZERO, 0x12, 0x34); + + /* Clear all reset flags and set them arbitrarily */ + system_set_reset_flags(EC_RESET_FLAG_WATCHDOG); + system_common_pre_init(); + panic_get_reason(&reason, &info, &exception); + zassert_equal(reason, PANIC_SW_WATCHDOG); + zassert_equal(info, 0); + zassert_equal(exception, 0); +} + +ZTEST(system, test_system_common_pre_init__watch_dog_panic_already_initialized) +{ + uint32_t reason; + uint32_t info; + uint8_t exception; + + /* Watchdog reset should not overwrite panic info if already filled + * in with watchdog panic info that HAS NOT been read by host + */ + panic_set_reason(PANIC_SW_WATCHDOG, 0x12, 0x34); + + /* Clear all reset flags and set them arbitrarily */ + system_set_reset_flags(EC_RESET_FLAG_WATCHDOG); + system_common_pre_init(); + panic_get_reason(&reason, &info, &exception); + zassert_equal(reason, PANIC_SW_WATCHDOG); + zassert_equal(info, 0x12); + zassert_equal(exception, 0x34); +} + +ZTEST(system, test_system_common_pre_init__watch_dog_panic_already_read) +{ + uint32_t reason; + uint32_t info; + uint8_t exception; + struct panic_data *pdata; + + /* Watchdog reset should overwrite panic info if already filled + * in with watchdog panic info that HAS been read by host + */ + panic_set_reason(PANIC_SW_WATCHDOG, 0x12, 0x34); + pdata = get_panic_data_write(); + pdata->flags |= PANIC_DATA_FLAG_OLD_HOSTCMD; + /* Clear all reset flags and set them arbitrarily */ system_set_reset_flags(EC_RESET_FLAG_WATCHDOG); system_common_pre_init(); panic_get_reason(&reason, &info, &exception); zassert_equal(reason, PANIC_SW_WATCHDOG); + zassert_equal(info, 0); + zassert_equal(exception, 0); } ZTEST(system, test_system_encode_save_flags) diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml index dbae8be1e2..cb63d66fc8 100644 --- a/zephyr/test/drivers/testcase.yaml +++ b/zephyr/test/drivers/testcase.yaml @@ -285,6 +285,7 @@ tests: - CONFIG_PLATFORM_EC_POWERSEQ_SC7280=n - CONFIG_POWER_SEQUENCE_MOCK=y - CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y + - CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y drivers.ps8xxx: extra_configs: - CONFIG_LINK_TEST_SUITE_PS8XXX=y @@ -312,6 +313,14 @@ tests: extra_dtc_overlay_files: - ./boards/native_posix.overlay - ./rt9490/charger.dts + drivers.random: + extra_configs: + - CONFIG_LINK_TEST_SUITE_RANDOM=y + - CONFIG_PLATFORM_EC_RANDOM=y + - CONFIG_PLATFORM_EC_HOSTCMD_RAND=y + - CONFIG_PLATFORM_EC_CONSOLE_CMD_RAND=y + extra_dtc_overlay_files: + - ./boards/native_posix.overlay drivers.shim_gpio_id: extra_configs: - CONFIG_LINK_TEST_SUITE_SHIM_GPIO_ID=y @@ -329,6 +338,15 @@ tests: - CONFIG_PLATFORM_EC_RTC=y - CONFIG_PLATFORM_EC_HOSTCMD=y - CONFIG_PLATFORM_EC_HOSTCMD_RTC=y + drivers.sm5803: + extra_conf_files: + - prj.conf + - sm5803/prj.conf + extra_configs: + - CONFIG_LINK_TEST_SUITE_SM5803=y + extra_dtc_overlay_files: + - boards/native_posix.overlay + - sm5803/sm5803.dts drivers.system: tags: common system extra_configs: @@ -423,6 +441,8 @@ tests: - usbc_tcpc/tcpc_alts.dts extra_configs: - CONFIG_LINK_TEST_SUITE_USBC_TCPC=y + - CONFIG_PLATFORM_EC_USB_PD_DUAL_ROLE_AUTO_TOGGLE=n + - CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=n drivers.usbc_retimer.anx7483: extra_configs: - CONFIG_LINK_TEST_SUITE_USBC_RETIMER_ANX7483=y @@ -471,3 +491,12 @@ tests: - anx7452/usbc.dts extra_configs: - CONFIG_LINK_TEST_SUITE_ANX7452=y + drivers.flash_cbi: + extra_dtc_overlay_files: + - boards/native_posix.overlay + - cbi_flash/binman.dts + extra_configs: + - CONFIG_LINK_TEST_SUITE_FLASH=y + - CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y + - CONFIG_PLATFORM_EC_FLASH_SIZE_BYTES=0x80000 + - CONFIG_PLATFORM_EC_CBI_FLASH=y diff --git a/zephyr/test/drivers/usbc_retimer/src/anx7483.c b/zephyr/test/drivers/usbc_retimer/src/anx7483.c index e0d6544b3d..1d0d034c14 100644 --- a/zephyr/test/drivers/usbc_retimer/src/anx7483.c +++ b/zephyr/test/drivers/usbc_retimer/src/anx7483.c @@ -22,6 +22,16 @@ int anx7483_get(const struct usb_mux *me, mux_state_t *mux_state); int anx7483_read(const struct usb_mux *me, uint8_t reg, int *val); int anx7483_write(const struct usb_mux *me, uint8_t reg, uint8_t val); +extern const struct anx7483_tuning_set anx7483_usb_enabled[]; +extern const struct anx7483_tuning_set anx7483_dp_enabled[]; +extern const struct anx7483_tuning_set anx7483_dock_noflip[]; +extern const struct anx7483_tuning_set anx7483_dock_flip[]; + +extern const size_t anx7483_usb_enabled_count; +extern const size_t anx7483_dp_enabled_count; +extern const size_t anx7483_dock_noflip_count; +extern const size_t anx7483_dock_flip_count; + static struct usb_mux mux = { .i2c_port = I2C_PORT_NODELABEL(i2c3), .i2c_addr_flags = 0x3e, @@ -43,6 +53,18 @@ static int anx7483_emul_test_set_reg(int reg, uint8_t val) return anx7483_emul_set_reg(ANX7483_EMUL, reg, val); } +static int anx7483_emul_test_get_eq(enum anx7483_tune_pin pin, + enum anx7483_eq_setting *eq) +{ + return anx7483_emul_get_eq(ANX7483_EMUL, pin, eq); +} + +static int anx7483_test_set_eq(enum anx7483_tune_pin pin, + enum anx7483_eq_setting eq) +{ + return anx7483_set_eq(&mux, pin, eq); +} + static int anx7483_i2c_read(int reg, int *data) { return anx7483_read(&mux, reg, data); @@ -230,55 +252,49 @@ ZTEST(anx7483, test_init) * equalization for a pin. */ -ZTEST(anx7483, test_set_eq) +ZTEST(anx7483, test_set_eq_func) { int rv; - uint8_t val; + enum anx7483_eq_setting eq; - rv = anx7483_set_eq(&mux, ANX7483_PIN_UTX1, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_UTX1, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_UTX1, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); - rv = anx7483_set_eq(&mux, ANX7483_PIN_UTX2, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_UTX2, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_UTX2, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); - rv = anx7483_set_eq(&mux, ANX7483_PIN_URX1, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_URX1, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_URX1, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); - rv = anx7483_set_eq(&mux, ANX7483_PIN_URX2, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_URX2, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_URX2, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); - rv = anx7483_set_eq(&mux, ANX7483_PIN_DRX1, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_DRX1, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_DRX1, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); - rv = anx7483_set_eq(&mux, ANX7483_PIN_DRX2, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(ANX7483_PIN_DRX2, ANX7483_EQ_SETTING_12_5DB); zexpect_ok(rv); - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); + rv = anx7483_emul_test_get_eq(ANX7483_PIN_DRX2, &eq); zexpect_ok(rv); - zexpect_equal((val >> ANX7483_CFG0_EQ_SHIFT) & 0xf, - ANX7483_EQ_SETTING_12_5DB); + zexpect_equal(eq, ANX7483_EQ_SETTING_12_5DB); /* Test invalid pin. */ - rv = anx7483_set_eq(&mux, 0xff, ANX7483_EQ_SETTING_12_5DB); + rv = anx7483_test_set_eq(0xff, ANX7483_EQ_SETTING_12_5DB); zexpect_not_equal(rv, 0); } @@ -936,526 +952,231 @@ ZTEST(anx7483, test_emul_update_reserved) /* * Tests that the ANX7483 driver correctly configures the default tuning for - * USB. The register values should match those in the anx7483_usb_enabled struct - * within the driver. + * USB. */ ZTEST(anx7483, test_tuning_usb) { + /* + * Vendor defined tuning settings, these should match those in the + * anx7483_usb_enabled struct within the driver. + */ + const struct anx7483_tuning_set usb_enabled[] = { + { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_DRX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_DRX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + + { ANX7483_URX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_URX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_DRX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_DRX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + + { ANX7483_URX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + { ANX7483_URX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + { ANX7483_DRX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + { ANX7483_DRX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + + { ANX7483_UTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + + { ANX7483_URX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_URX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_DRX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_DRX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + + { ANX7483_URX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_OUT }, + { ANX7483_URX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_OUT }, + { ANX7483_DRX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_OUT }, + { ANX7483_DRX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_OUT }, + + { ANX7483_UTX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_UTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DTX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + }; int rv; - uint8_t val; rv = anx7483_set_default_tuning(&mux, USB_PD_MUX_USB_ENABLED); zexpect_ok(rv); - /* CFG0 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - /* CFG1 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - /* CFG2 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - /* CFG3 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_OUT); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_OUT); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_OUT); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_OUT); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - /* CFG4 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG4_REG, &val); + zassert_equal(ARRAY_SIZE(usb_enabled), anx7483_usb_enabled_count); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL, usb_enabled, + ARRAY_SIZE(usb_enabled)); zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); } /* * Tests that the ANX7483 driver correctly configures the default tuning for - * DisplayPort. The register values should match those in the anx7483_dp_enabled - * struct within the driver. + * DisplayPort. */ ZTEST(anx7483, test_tuning_dp) { + /* + * Vendor defined tuning settings, these should match those in the + * anx7483_dp_enabled struct within the driver. + */ + const struct anx7483_tuning_set dp_enabled[] = { + { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, + + { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_UTX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_UTX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + + { ANX7483_URX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_URX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_UTX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_UTX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + + { ANX7483_URX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_URX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DRX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DRX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + + { ANX7483_URX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_URX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_UTX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_UTX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + + { ANX7483_URX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_URX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_UTX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_UTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DRX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DRX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DTX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + }; int rv; - uint8_t val; rv = anx7483_set_default_tuning(&mux, USB_PD_MUX_DP_ENABLED); zexpect_ok(rv); - /* CFG0 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - /* CFG1 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - /* CFG2 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - /* CFG3 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - /* CFG4 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG4_REG, &val); + zassert_equal(ARRAY_SIZE(dp_enabled), anx7483_dp_enabled_count); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL, dp_enabled, + ARRAY_SIZE(dp_enabled)); zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); } /* * Tests that the ANX7483 driver correctly configures the default tuning for - * dock mode in a non-flipped state. The register values should match those in - * the anx7483_dock_noflip struct within the driver. + * dock mode in a non-flipped state. */ ZTEST(anx7483, test_tuning_dock_noflip) { + /* + * Vendor defined tuning settings, these should match those in the + * anx7483_dock_noflip struct within the driver. + */ + const test_export_static struct anx7483_tuning_set dock_noflip[] = { + { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, + + { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_DRX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_UTX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + + { ANX7483_URX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_DRX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_URX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_UTX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + + { ANX7483_URX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + { ANX7483_DRX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + + { ANX7483_URX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DRX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + + { ANX7483_URX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_DRX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_URX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_UTX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + + { ANX7483_URX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_URX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_UTX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_UTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DRX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DRX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DTX1_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + }; int rv; - uint8_t val; rv = anx7483_set_default_tuning(&mux, USB_PD_MUX_DOCK); zexpect_ok(rv); - /* Corresponds to anx7483_dock_noflip. */ - /* CFG0 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - /* CFG1 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - /* CFG2 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - /* CFG3 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG3_REG, &val); + zassert_equal(ARRAY_SIZE(dock_noflip), anx7483_dock_noflip_count); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL, dock_noflip, + ARRAY_SIZE(dock_noflip)); zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - /* CFG4 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); } /* * Tests that the ANX7483 driver correctly configures the default tuning for - * dock mode in a flipped state. The register values should match those in - * the anx7483_dock_flip struct within the driver. + * dock mode in a flipped state. */ ZTEST(anx7483, test_tuning_dock_flip) { + /* + * Vendor defined tuning settings, these should match those in the + * anx7483_dock_flip struct within the driver. + */ + const test_export_static struct anx7483_tuning_set dock_flip[] = { + { ANX7483_AUX_SNOOPING_CTRL_REG, ANX7483_AUX_SNOOPING_DEF }, + + { ANX7483_URX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_DRX2_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_URX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + { ANX7483_UTX1_PORT_CFG2_REG, ANX7483_CFG2_DEF }, + + { ANX7483_URX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_DRX2_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_URX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + { ANX7483_UTX1_PORT_CFG0_REG, ANX7483_CFG0_DEF }, + + { ANX7483_URX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + { ANX7483_DRX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_ENABLE }, + + { ANX7483_URX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_UTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX2_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DTX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + { ANX7483_DRX1_PORT_CFG4_REG, ANX7483_CFG4_TERM_DISABLE }, + + { ANX7483_URX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_UTX1_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_URX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + { ANX7483_DRX2_PORT_CFG1_REG, ANX7483_CFG1_DEF }, + + { ANX7483_URX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_URX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_UTX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_UTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DRX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DRX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + { ANX7483_DTX1_PORT_CFG3_REG, ANX7483_CFG3_100Ohm_IN }, + { ANX7483_DTX2_PORT_CFG3_REG, ANX7483_CFG3_90Ohm_IN }, + }; int rv; - uint8_t val; rv = anx7483_set_default_tuning( &mux, USB_PD_MUX_DOCK | USB_PD_MUX_POLARITY_INVERTED); zexpect_ok(rv); - /* CFG0 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG0_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG0_DEF); - - /* CFG1 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG1_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG1_DEF); - - /* CFG2 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG2_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG2_DEF); - - /* CFG3 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_100Ohm_IN); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG3_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG3_90Ohm_IN); - - /* CFG4 */ - rv = anx7483_emul_test_get_reg(ANX7483_URX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_URX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DRX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_ENABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_UTX2_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX1_PORT_CFG4_REG, &val); - zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); - - rv = anx7483_emul_test_get_reg(ANX7483_DTX2_PORT_CFG4_REG, &val); + zassert_equal(ARRAY_SIZE(dock_flip), anx7483_dock_flip_count); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL, dock_flip, + ARRAY_SIZE(dock_flip)); zexpect_ok(rv); - zexpect_equal(val, ANX7483_CFG4_TERM_DISABLE); } diff --git a/zephyr/test/drivers/usbc_tcpc/src/tcpc_shim.c b/zephyr/test/drivers/usbc_tcpc/src/tcpc_shim.c index eb15a45416..a947682a11 100644 --- a/zephyr/test/drivers/usbc_tcpc/src/tcpc_shim.c +++ b/zephyr/test/drivers/usbc_tcpc/src/tcpc_shim.c @@ -17,26 +17,34 @@ static struct tcpc_config_t tcpc_config_saved[] = { DT_FOREACH_STATUS_OKAY( ZTEST(tcpc_shim, test_tcpc_alts_exist) { - zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_0_alt)); - zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_1_alt)); + /* Verify all TCPC types are able to create an alternate TCPC entry */ + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_anx7447_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_ccgxxf_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_fusb302_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_ps8xxx_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_raa489000_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_nct38xx_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_rt1718s_alt)); + zassert_not_null(&TCPC_ALT_FROM_NODELABEL(tcpc_alt)); } ZTEST(tcpc_shim, test_tcpc_alt_enable) { /* Enable an alternate TCPC on each USB-C port */ - TCPC_ENABLE_ALTERNATE_BY_NODELABEL(0, tcpc_rt1715_0_alt); - TCPC_ENABLE_ALTERNATE_BY_NODELABEL(1, tcpc_rt1715_1_alt); + TCPC_ENABLE_ALTERNATE_BY_NODELABEL(0, tcpc_ps8xxx_alt); + TCPC_ENABLE_ALTERNATE_BY_NODELABEL(1, tcpc_rt1715_alt); zassert_mem_equal(&tcpc_config[0], - &TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_0_alt), + &TCPC_ALT_FROM_NODELABEL(tcpc_ps8xxx_alt), sizeof(struct tcpc_config_t)); zassert_mem_equal(&tcpc_config[1], - &TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_1_alt), + &TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_alt), sizeof(struct tcpc_config_t)); - TCPC_ENABLE_ALTERNATE_BY_NODELABEL(0, tcpc_rt1715_1_alt); + TCPC_ENABLE_ALTERNATE_BY_NODELABEL(0, tcpc_anx7447_alt); zassert_mem_equal(&tcpc_config[0], - &TCPC_ALT_FROM_NODELABEL(tcpc_rt1715_1_alt), + &TCPC_ALT_FROM_NODELABEL(tcpc_anx7447_alt), sizeof(struct tcpc_config_t)); } diff --git a/zephyr/test/drivers/usbc_tcpc/tcpc_alts.dts b/zephyr/test/drivers/usbc_tcpc/tcpc_alts.dts index 5534d42a97..8fe20cf879 100644 --- a/zephyr/test/drivers/usbc_tcpc/tcpc_alts.dts +++ b/zephyr/test/drivers/usbc_tcpc/tcpc_alts.dts @@ -14,7 +14,54 @@ #size-cells = <0>; status = "okay"; - tcpc_rt1715_0_alt: tcpc-rt1715-0-alt@a{ + tcpc_anx7447_alt: tcpc-anx7447-alt@2c { + compatible = "analogix,anx7447-tcpc", "cros,i2c-mock"; + reg = <0x2c>; + tcpc-flags = <( + TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR)>; + is-alt; + }; + + tcpc_ccgxxf_alt: tcpc-ccgxxf-alt@11 { + compatible = "cypress,ccgxxf", "cros,i2c-mock"; + reg = <0x11>; + is-alt; + }; + + tcpc_fusb302_alt: tcpc-fusb302-alt@22 { + compatible = "fairchild,fusb302", "cros,i2c-mock"; + reg = <0x22>; + is-alt; + }; + + tcpc_ps8xxx_alt: tcpc-ps8xxx-alt@b { + compatible = "parade,ps8xxx", "cros,i2c-mock"; + reg = < 0xb >; + tcpc-flags = < 0xd8 >; + is-alt; + }; + + tcpc_raa489000_alt: tcpc-raa489000-alt@e { + compatible = "renesas,raa489000", "cros,i2c-mock"; + reg = <0xe>; + tcpc-flags = <( + TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR)>; + is-alt; + }; + + tcpc_nct38xx_alt: tcpc-nct38xx-alt@73 { + compatible = "nuvoton,nct38xx", "cros,i2c-mock"; + reg = <0x73>; + tcpc-flags = <( + TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_NO_DEBUG_ACC_CONTROL)>; + is-alt; + }; + + + tcpc_rt1715_alt: tcpc-rt1715-alt@a{ compatible = "richtek,rt1715-tcpc", "cros,i2c-mock"; reg = <0xa>; tcpc-flags = <( @@ -23,10 +70,19 @@ is-alt; }; - tcpc_rt1715_1_alt: tcpc-rt1715-1-alt@b{ - compatible = "richtek,rt1715-tcpc", "cros,i2c-mock"; - reg = <0xb>; - tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>; + tcpc_rt1718s_alt: tcpc-rt1718s-alt@40 { + compatible = "richtek,rt1718s-tcpc", "cros,i2c-mock"; + reg = <0x40>; + tcpc-flags = <( + TCPC_FLAGS_ALERT_OD | + TCPC_FLAGS_CONTROL_VCONN | + TCPC_FLAGS_CONTROL_FRS)>; + is-alt; + }; + + tcpc_alt: tcpc-alt@41 { + compatible = "cros-ec,tcpci", "cros,i2c-mock"; + reg = <0x41>; is-alt; }; }; diff --git a/zephyr/test/krabby/CMakeLists.txt b/zephyr/test/krabby/CMakeLists.txt index eb99938456..529bb24682 100644 --- a/zephyr/test/krabby/CMakeLists.txt +++ b/zephyr/test/krabby/CMakeLists.txt @@ -15,7 +15,8 @@ zephyr_include_directories( target_sources(app PRIVATE src/stubs.c ${PLATFORM_EC_PROGRAM_DIR}/corsola/src/ite_usbc.c - ${PLATFORM_EC_PROGRAM_DIR}/corsola/src/ite_usb_pd_policy.c) + ${PLATFORM_EC_PROGRAM_DIR}/corsola/src/ite_usb_pd_policy.c + ${PLATFORM_EC_PROGRAM_DIR}/corsola/src/usb_pd_policy.c) target_sources_ifdef(CONFIG_TEST_KRABBY app PRIVATE diff --git a/zephyr/test/krabby/common.dtsi b/zephyr/test/krabby/common.dtsi index e62b044bbc..d37ef93981 100644 --- a/zephyr/test/krabby/common.dtsi +++ b/zephyr/test/krabby/common.dtsi @@ -47,7 +47,7 @@ compatible = "named-usbc-port"; status = "okay"; reg = <1>; - tcpc = <&tcpci_emul>; + tcpc = <&rt1718s_emul>; ppc = <&ppc1_emul>; usb-mux-chain-1 { compatible = "cros-ec,usb-mux-chain"; @@ -147,6 +147,12 @@ frs_en_gpio = <&gpio_ec_x_gpio1>; alert_gpio = <&gpio_x_ec_gpio2>; }; + + rt1718s_emul: rt1718s@2c { + compatible = "cros,rt1718s-tcpc-emul", "richtek,rt1718s-tcpc"; + status = "okay"; + reg = <0x2c>; + }; }; &adc0 { diff --git a/zephyr/test/krabby/krabby.tentacruel.overlay b/zephyr/test/krabby/krabby.tentacruel.overlay index 3ae38d8daa..8183d3826c 100644 --- a/zephyr/test/krabby/krabby.tentacruel.overlay +++ b/zephyr/test/krabby/krabby.tentacruel.overlay @@ -15,6 +15,12 @@ /delete-node/ &{/hibernate-wake-pins}; +/* + * The unused-pins functionality is not currently tested. Remove + * to avoid mismatches in the GPIO flags configuration. + */ +/delete-node/ &{/unused-pins}; + / { name_temp_charger: charger { compatible = "cros-ec,temp-sensor-thermistor"; diff --git a/zephyr/test/krabby/src/stubs.c b/zephyr/test/krabby/src/stubs.c index df1613528d..6e1bcc3b7f 100644 --- a/zephyr/test/krabby/src/stubs.c +++ b/zephyr/test/krabby/src/stubs.c @@ -13,11 +13,6 @@ __override void board_set_charge_limit(int port, int supplier, int charge_ma, { } -int pd_check_vconn_swap(int port) -{ - return 0; -} - int board_get_adjusted_usb_pd_port_count(int port) { return 2; diff --git a/zephyr/test/krabby/src/usbc_config.c b/zephyr/test/krabby/src/usbc_config.c index 0b6c8bc80d..909a8f38a7 100644 --- a/zephyr/test/krabby/src/usbc_config.c +++ b/zephyr/test/krabby/src/usbc_config.c @@ -4,12 +4,16 @@ */ #include "adc.h" +#include "baseboard_usbc_config.h" #include "charge_manager.h" #include "driver/ppc/syv682x.h" #include "driver/ppc/syv682x_public.h" +#include "driver/tcpm/rt1718s.h" #include "emul/emul_common_i2c.h" #include "emul/emul_syv682x.h" +#include "emul/tcpc/emul_rt1718s.h" #include "i2c/i2c.h" +#include "test_state.h" #include "usb_pd.h" #include "usbc_ppc.h" @@ -17,7 +21,7 @@ #include <zephyr/drivers/emul.h> #include <zephyr/ztest.h> -bool ppc_sink_enabled(int port) +static bool ppc_sink_enabled(int port) { const struct emul *emul = (port == 0) ? EMUL_DT_GET(DT_NODELABEL(ppc0_emul)) : @@ -29,6 +33,17 @@ bool ppc_sink_enabled(int port) return !(val & (SYV682X_CONTROL_1_PWR_ENB | SYV682X_CONTROL_1_HV_DR)); } +static bool usb_c1_source_gpio_enabled(void) +{ + const struct emul *emul = EMUL_DT_GET(DT_NODELABEL(rt1718s_emul)); + uint16_t val = 0; + + rt1718s_emul_get_reg(emul, RT1718S_GPIO_CTRL(GPIO_EN_USB_C1_SOURCE), + &val); + + return val & RT1718S_GPIO_CTRL_O; +} + ZTEST(usbc_config, test_set_active_charge_port) { /* reset ppc state */ @@ -59,7 +74,7 @@ ZTEST(usbc_config, test_set_active_charge_port) zassert_false(ppc_sink_enabled(0), NULL); zassert_true(ppc_sink_enabled(1), NULL); - /* turn of sourcing, sinking port 0 */ + /* turn off sourcing, sinking port 0 */ pd_power_supply_reset(0); zassert_ok(board_set_active_charge_port(0), NULL); zassert_true(ppc_sink_enabled(0), NULL); @@ -104,6 +119,16 @@ ZTEST(usbc_config, test_set_active_charge_port_fail) zassert_false(ppc_sink_enabled(1), NULL); } +ZTEST(usbc_config, test_rt1718s_gpio_toggle) +{ + /* toggle sourcing on port 1, expect rt1718s gpio also changes */ + zassert_false(usb_c1_source_gpio_enabled()); + zassert_ok(pd_set_power_supply_ready(1)); + zassert_true(usb_c1_source_gpio_enabled()); + pd_power_supply_reset(1); + zassert_false(usb_c1_source_gpio_enabled()); +} + ZTEST(usbc_config, test_adc_channel) { zassert_equal(board_get_vbus_adc(0), ADC_VBUS_C0, NULL); @@ -128,4 +153,5 @@ static void reset_ppc_state(void *fixture) board_set_active_charge_port(CHARGE_PORT_NONE); } -ZTEST_SUITE(usbc_config, NULL, NULL, reset_ppc_state, NULL, NULL); +ZTEST_SUITE(usbc_config, krabby_predicate_post_main, NULL, reset_ppc_state, + NULL, NULL); diff --git a/zephyr/test/nissa/CMakeLists.txt b/zephyr/test/nissa/CMakeLists.txt index dc351aa3b6..6574575a09 100644 --- a/zephyr/test/nissa/CMakeLists.txt +++ b/zephyr/test/nissa/CMakeLists.txt @@ -10,8 +10,17 @@ add_subdirectory(${PLATFORM_EC}/zephyr/test/test_utils test_utils) zephyr_include_directories("${PLATFORM_EC_PROGRAM_DIR}/nissa/include") -target_sources(app PRIVATE src/stubs.c src/sub_board.c) +target_sources(app PRIVATE src/stubs.c) -target_sources(app PRIVATE - ${PLATFORM_EC_PROGRAM_DIR}/nissa/src/sub_board.c +target_sources_ifdef( + CONFIG_TEST_NISSA_SUB_BOARD + app PRIVATE + src/sub_board.c + src/log_module.c + ${PLATFORM_EC_PROGRAM_DIR}/nissa/src/sub_board.c) + +target_sources_ifdef( + CONFIG_TEST_NISSA_COMMON + app PRIVATE + src/common.c ${PLATFORM_EC_PROGRAM_DIR}/nissa/src/common.c) diff --git a/zephyr/test/nissa/Kconfig b/zephyr/test/nissa/Kconfig index f8215bbf37..9e6d4de468 100644 --- a/zephyr/test/nissa/Kconfig +++ b/zephyr/test/nissa/Kconfig @@ -2,6 +2,24 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +choice TEST_TARGET + prompt "Select test target to build" + help + Select the build target for a given test. Each test target must select + exactly one, because some tests assume configuration that conflicts with + others. + + config TEST_NISSA_SUB_BOARD + bool "Tests for sub_board.c" + help + The test target that exercises nissa/src/sub_board.c. + + config TEST_NISSA_COMMON + bool "Tests for common.c" + help + The test target that exercises nissa/src/common.c. +endchoice + module = NISSA module-str = Nissa board-specific code (unit tests) source "subsys/logging/Kconfig.template.log_config" diff --git a/zephyr/test/nissa/boards/chargers.dts b/zephyr/test/nissa/boards/chargers.dts new file mode 100644 index 0000000000..5d72d197a7 --- /dev/null +++ b/zephyr/test/nissa/boards/chargers.dts @@ -0,0 +1,54 @@ +/ { + named-i2c-ports { + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c_ctrl7>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; + + usbc { + port0@0 { + chg = <&chg_port0>; + }; + port1@1 { + chg = <&chg_port1>; + }; + }; + + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k", "battery-smart"; + }; + }; +}; + +&i2c_ctrl3 { + chg_port0: sm5803_primary@32 { + compatible = "cros,sm5803-emul", "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + interrupt-gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; +}; + +&i2c_ctrl5 { + chg_port1: sm5803_secondary@32 { + compatible = "cros,sm5803-emul", "siliconmitus,sm5803"; + status = "okay"; + reg = <0x32>; + interrupt-gpios = <&gpio0 2 GPIO_INPUT_PULL_UP>; + }; +}; + +&i2c_ctrl7 { + battery: sb@b { + compatible = "zephyr,smart-battery-emul"; + reg = <0xb>; + cycle-count = <6>; + version = "BATTERY_SPEC_VER_1_1_WITH_PEC"; + desired-charg-volt = <11250>; + desired-charg-cur = <2400>; + mf-name = "LGC"; + dev-name = "AP18C8K"; + }; +}; diff --git a/zephyr/test/nissa/boards/generic_npcx.dts b/zephyr/test/nissa/boards/generic_npcx.dts index 1639dc80c8..7849f19473 100644 --- a/zephyr/test/nissa/boards/generic_npcx.dts +++ b/zephyr/test/nissa/boards/generic_npcx.dts @@ -20,6 +20,8 @@ gpio-hpd-odl = &gpio_sb_4; /* LTE */ gpio-en-sub-s5-rails = &gpio_sb_2; + + gpio-wp = &gpio_ec_wp_odl; }; gpio-interrupts { @@ -49,6 +51,10 @@ gpios = <&gpioe 4 GPIO_OUTPUT>; }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + entering_rw { gpios = <&gpio0 3 GPIO_OUTPUT>; enum-name = "GPIO_ENTERING_RW"; diff --git a/zephyr/test/nissa/charger.conf b/zephyr/test/nissa/charger.conf new file mode 100644 index 0000000000..d96973deb5 --- /dev/null +++ b/zephyr/test/nissa/charger.conf @@ -0,0 +1,24 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Additional configuration for emulated Nissa boards where tests require +# charger-related code. + +CONFIG_PLATFORM_EC_HOSTCMD=y +CONFIG_PLATFORM_EC_CHARGER=y +CONFIG_PLATFORM_EC_OCPC=y +CONFIG_PLATFORM_EC_CHARGER_SM5803=y +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10 +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22 +CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=n +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n +CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y +# charger_get_system_power() in RAA489000 driver +CONFIG_PLATFORM_EC_CHARGER_PSYS_READ=n +CONFIG_ADC_SHELL=n +CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=15000 +CONFIG_PLATFORM_EC_VBOOT_HASH=n diff --git a/zephyr/test/nissa/prj.conf b/zephyr/test/nissa/prj.conf index 3d4f0e5f3d..62c2b29782 100644 --- a/zephyr/test/nissa/prj.conf +++ b/zephyr/test/nissa/prj.conf @@ -19,6 +19,7 @@ CONFIG_PLATFORM_EC_USB_PD_DISCHARGE=n CONFIG_PLATFORM_EC_USB_CHARGER=n CONFIG_PLATFORM_EC_USB_PD_HOST_CMD=n CONFIG_PLATFORM_EC_USB_PORT_ENABLE_DYNAMIC=y +CONFIG_PLATFORM_EC_SWITCH=n # Allow the test fixture to use k_malloc CONFIG_HEAP_MEM_POOL_SIZE=1024
\ No newline at end of file diff --git a/zephyr/test/nissa/src/common.c b/zephyr/test/nissa/src/common.c new file mode 100644 index 0000000000..2c97fb4e76 --- /dev/null +++ b/zephyr/test/nissa/src/common.c @@ -0,0 +1,128 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ap_power/ap_power_events.h" +#include "battery.h" +#include "charger.h" +#include "emul/emul_sm5803.h" +#include "hooks.h" +#include "ocpc.h" +#include "usb_pd.h" + +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/fff.h> +#include <zephyr/ztest.h> + +FAKE_VALUE_FUNC(enum battery_present, battery_is_present); +FAKE_VALUE_FUNC(int, board_set_active_charge_port, int); +FAKE_VALUE_FUNC(uint8_t, board_get_usb_pd_port_count); +FAKE_VALUE_FUNC(int, power_button_is_pressed); + +static void suite_before(void *fixture) +{ + RESET_FAKE(battery_is_present); + RESET_FAKE(board_get_usb_pd_port_count); + board_get_usb_pd_port_count_fake.return_val = 2; + RESET_FAKE(board_set_active_charge_port); + RESET_FAKE(power_button_is_pressed); +} + +ZTEST_SUITE(nissa_common, NULL, NULL, suite_before, NULL, NULL); + +ZTEST(nissa_common, test_pen_power_control) +{ + const struct gpio_dt_spec *const pen_power = + GPIO_DT_FROM_NODELABEL(gpio_en_pp5000_pen_x); + + hook_notify(HOOK_INIT); + zassert_false(gpio_emul_output_get(pen_power->port, pen_power->pin), + "Pen power should be off by default"); + + ap_power_ev_send_callbacks(AP_POWER_STARTUP); + zassert_true(gpio_emul_output_get(pen_power->port, pen_power->pin), + "Pen power should be on after AP startup"); + + ap_power_ev_send_callbacks(AP_POWER_SHUTDOWN); + zassert_false(gpio_emul_output_get(pen_power->port, pen_power->pin), + "Pen power should be off after AP shutdown"); +} + +ZTEST(nissa_common, test_hibernate) +{ + const struct gpio_dt_spec *const hibernate_enable = + GPIO_DT_FROM_NODELABEL(gpio_en_slp_z); + + zassert_false(gpio_emul_output_get(hibernate_enable->port, + hibernate_enable->pin), + "Hibernate pin should be low by default"); + board_hibernate_late(); + zassert_true(gpio_emul_output_get(hibernate_enable->port, + hibernate_enable->pin), + "Hibernate pin should go high to hibernate"); +} + +ZTEST(nissa_common, test_vconn_swap) +{ + const struct gpio_dt_spec *const dsw_pwrok = + GPIO_DT_FROM_NODELABEL(gpio_ec_soc_dsw_pwrok); + + /* AP 5V rail is off. */ + zassert_false(gpio_pin_get_dt(dsw_pwrok)); + zassert_false(pd_check_vconn_swap(0)); + zassert_false(pd_check_vconn_swap(1)); + + /* + * Case with the rail on is untestable because emulated GPIOs don't + * allow getting the current value of output pins. + */ +} + +ZTEST(nissa_common, test_ocpc_configuration) +{ + int kp, kp_div; + int ki, ki_div; + int kd, kd_div; + struct ocpc_data ocpc_data = {}; + + ocpc_get_pid_constants(&kp, &kp_div, &ki, &ki_div, &kd, &kd_div); + + /* + * Only proportional control is used, at 1/32 gain. Gain of integral and + * derivative terms is zero. + */ + zassert_equal(kp, 1); + zassert_equal(kp_div, 32); + zassert_equal(ki, 0); + zassert_not_equal(ki_div, 0); + zassert_equal(kd, 0); + zassert_not_equal(kd_div, 0); + + /* With two chargers, we note that Isys can't be measured. */ + zassert_equal(CONFIG_USB_PD_PORT_MAX_COUNT, 2); + board_get_usb_pd_port_count_fake.return_val = 2; + board_ocpc_init(&ocpc_data); + zassert_equal(ocpc_data.chg_flags[1], OCPC_NO_ISYS_MEAS_CAP); +} + +void board_get_battery_cells(void); + +ZTEST(nissa_common, test_sm5803_buck_boost_forbidden) +{ + const struct emul *const charger_emul = + EMUL_DT_GET(DT_NODELABEL(chg_port0)); + int cells; + + /* Default 2S PMODE allows 12V charging. */ + zassert_ok(charger_get_battery_cells(0, &cells)); + zassert_equal(cells, 2); + zassert_true(pd_is_valid_input_voltage(12000)); + + /* 3S forbids 12V charging. */ + sm5803_emul_set_pmode(charger_emul, 0x16 /* 3S, 1.5A with BFET */); + zassert_ok(charger_get_battery_cells(0, &cells)); + zassert_equal(cells, 3); + board_get_battery_cells(); /* Refresh cached cell count */ + zassert_false(pd_is_valid_input_voltage(12000)); +} diff --git a/zephyr/test/nissa/src/log_module.c b/zephyr/test/nissa/src/log_module.c new file mode 100644 index 0000000000..e8556a5886 --- /dev/null +++ b/zephyr/test/nissa/src/log_module.c @@ -0,0 +1,8 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +LOG_MODULE_REGISTER(nissa, CONFIG_NISSA_LOG_LEVEL); diff --git a/zephyr/test/nissa/src/stubs.c b/zephyr/test/nissa/src/stubs.c index 970232197e..0e45fefc17 100644 --- a/zephyr/test/nissa/src/stubs.c +++ b/zephyr/test/nissa/src/stubs.c @@ -8,6 +8,8 @@ #include "common.h" +#include <zephyr/fff.h> + __overridable void pd_power_supply_reset(int port) { } @@ -22,6 +24,11 @@ __overridable void pd_set_input_current_limit(int port, uint32_t max_ma, { } +__overridable int pd_check_vconn_swap(int port) +{ + return 0; +} + __overridable void usb_interrupt_c0(enum gpio_signal signal) { } diff --git a/zephyr/test/nissa/testcase.yaml b/zephyr/test/nissa/testcase.yaml index c9b568e326..cd519cbefb 100644 --- a/zephyr/test/nissa/testcase.yaml +++ b/zephyr/test/nissa/testcase.yaml @@ -8,3 +8,14 @@ tests: nissa.sub_board: extra_dtc_overlay_files: - "boards/generic_npcx.dts" + extra_configs: + - CONFIG_TEST_NISSA_SUB_BOARD=y + nissa.common: + extra_dtc_overlay_files: + - "boards/generic_npcx.dts" + - "boards/chargers.dts" + extra_conf_files: + - "prj.conf" + - "charger.conf" + extra_configs: + - CONFIG_TEST_NISSA_COMMON=y diff --git a/zephyr/test/ocpc/CMakeLists.txt b/zephyr/test/ocpc/CMakeLists.txt new file mode 100644 index 0000000000..2a46e14245 --- /dev/null +++ b/zephyr/test/ocpc/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}") +project(ocpc) + +# Include FFF fakes +add_subdirectory(${PLATFORM_EC}/zephyr/test/test_utils test_utils) + +target_sources(app PRIVATE src/fakes.c) +target_sources(app PRIVATE src/main.c) +target_sources(app PRIVATE src/ocpc.c) diff --git a/zephyr/test/ocpc/boards/native_posix.overlay b/zephyr/test/ocpc/boards/native_posix.overlay new file mode 100644 index 0000000000..d581c38af1 --- /dev/null +++ b/zephyr/test/ocpc/boards/native_posix.overlay @@ -0,0 +1,171 @@ +/* Copyright 2020 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <board-overlays/native_posix.dts> +#include <npcx_emul.dts> +#include <dt-bindings/usb_pd_tcpm.h> +#include <dt-bindings/usbc_mux.h> + +/ { + batteries { + default_battery: lgc { + compatible = "lgc,ac17a8m", "battery-smart"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c_ctrl3>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c_ctrl5>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c_ctrl7>; + enum-names = "I2C_PORT_BATTERY", "I2C_PORT_VIRTUAL_BATTERY"; + }; + }; + + named-adc-channels { + compatible = "named-adc-channels"; + + vbus { + enum-name = "ADC_VBUS"; + io-channels = <&adc0 1>; + /* Measure VBUS through a 1/10 voltage divider */ + mul = <10>; + }; + }; + + aliases { + gpio-wp = &gpio_wp; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_wp: ec-flash-wp-odl { + gpios = <&gpio0 0 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpio0 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_lid_open: lid_open { + gpios = <&gpio0 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + chg = <&isl923x_emul_0>; + tcpc = <&tcpci_emul_0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + chg = <&isl923x_emul_1>; + tcpc = <&tcpci_emul_1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + adc0: adc { + compatible = "zephyr,adc-emul"; + nchannels = <6>; + ref-internal-mv = <3300>; + #io-channel-cells = <1>; + status = "okay"; + }; +}; + +&i2c_ctrl7 { + battery: sb@b { + compatible = "zephyr,smart-battery-emul"; + reg = <0xb>; + cycle-count = <99>; + version = "BATTERY_SPEC_VER_1_1_WITH_PEC"; + /* Real battery voltages are multiples of 4.4V. */ + desired-charg-volt = <5000>; + desired-charg-cur = <1000>; + mf-name = "LGC"; + dev-name = "AC17A8M"; + }; +}; + +&i2c_ctrl3 { + tcpci_emul_0: tcpci_emul@82 { + compatible = "renesas,raa489000", "cros,i2c-mock"; + status = "okay"; + reg = <0x82>; + }; + isl923x_emul_0: isl923x@9 { + compatible = "cros,isl923x-emul"; + status = "okay"; + reg = <0x9>; + battery = <&battery>; + }; +}; + +&i2c_ctrl5 { + tcpci_emul_1: tcpci_emul@82 { + compatible = "renesas,raa489000", "cros,i2c-mock"; + status = "okay"; + reg = <0x82>; + }; + isl923x_emul_1: isl923x@9 { + compatible = "cros,isl923x-emul"; + status = "okay"; + reg = <0x9>; + battery = <&battery>; + }; +};
\ No newline at end of file diff --git a/zephyr/test/ocpc/prj.conf b/zephyr/test/ocpc/prj.conf new file mode 100644 index 0000000000..adfb4b5fae --- /dev/null +++ b/zephyr/test/ocpc/prj.conf @@ -0,0 +1,40 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +# Basic EC functions +CONFIG_SHIMMED_TASKS=y +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_PLATFORM_EC_HOOKS=y +CONFIG_PLATFORM_EC_HOSTCMD=y + +# Unwanted features +CONFIG_PLATFORM_EC_VBOOT_HASH=n +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n +CONFIG_PLATFORM_EC_USBC_PPC=n +CONFIG_PLATFORM_EC_USB_CHARGER=n + +# Power and charger-related +CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_CHARGER=y +CONFIG_PLATFORM_EC_OCPC=y +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10 +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE=n +CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y +CONFIG_PLATFORM_EC_OCPC_DEF_DRIVELIMIT_MILLIVOLTS=200 +CONFIG_PLATFORM_EC_I2C_VIRTUAL_BATTERY=y +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y +CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y + +# Console +CONFIG_SHELL_BACKEND_DUMMY=y +CONFIG_SHELL_BACKEND_SERIAL=n +CONFIG_SERIAL=y +CONFIG_RING_BUFFER=y diff --git a/zephyr/test/ocpc/src/fakes.c b/zephyr/test/ocpc/src/fakes.c new file mode 100644 index 0000000000..0ff17ecddc --- /dev/null +++ b/zephyr/test/ocpc/src/fakes.c @@ -0,0 +1,43 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +int battery_is_present(void) +{ + return 1; +} + +int board_set_active_charge_port(int port) +{ + return 0; +} + +int pd_set_power_supply_ready(int port) +{ + return 0; +} + +void pd_power_supply_reset(int port) +{ +} + +int board_is_sourcing_vbus(int port) +{ + return 0; +} + +int pd_check_vconn_swap(int port) +{ + return 0; +} + +int extpower_is_present(void) +{ + return 0; +} + +int lid_is_open(void) +{ + return 0; +} diff --git a/zephyr/test/ocpc/src/main.c b/zephyr/test/ocpc/src/main.c new file mode 100644 index 0000000000..5fa0a3b080 --- /dev/null +++ b/zephyr/test/ocpc/src/main.c @@ -0,0 +1,23 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_app_main.h" +#include "hooks.h" + +#include <zephyr/kernel.h> +#include <zephyr/ztest.h> + +void test_main(void) +{ + ec_app_main(); + + k_sleep(K_MSEC(1000)); + + /* Run all the suites that depend on main being called */ + ztest_run_test_suites(NULL); + + /* Check that every suite ran */ + ztest_verify_all_test_suites_ran(); +} diff --git a/zephyr/test/ocpc/src/ocpc.c b/zephyr/test/ocpc/src/ocpc.c new file mode 100644 index 0000000000..004d0c2408 --- /dev/null +++ b/zephyr/test/ocpc/src/ocpc.c @@ -0,0 +1,151 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "console.h" +#include "host_command.h" +#include "ocpc.h" + +#include <string.h> + +#include <zephyr/drivers/emul.h> +#include <zephyr/fff.h> +#include <zephyr/shell/shell_dummy.h> +#include <zephyr/ztest.h> + +FAKE_VOID_FUNC(ocpc_get_pid_constants, int *, int *, int *, int *, int *, + int *); + +static int test_kp, test_kp_div, test_ki, test_ki_div, test_kd, test_kd_div; + +static void get_pid_constants_custom_fake(int *kp, int *kp_div, int *ki, + int *ki_div, int *kd, int *kd_div) +{ + *kp = test_kp; + *kp_div = test_kp_div; + *ki = test_ki; + *ki_div = test_ki_div; + *kd = test_kd; + *kd_div = test_kd_div; +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__read) +{ + const char *outbuffer; + size_t buffer_size; + + /* With no args, print current state */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + /* Check for some expected lines */ + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Kp = 1 / 4"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Ki = 1 / 15"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Kd = 1 / 10"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__write) +{ + const char *outbuffer; + size_t buffer_size; + + /* Call a few times to change each parameter and examine output of final + * command. + */ + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid p 2 3")); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid i 4 5")); + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid d 6 7")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Kp = 2 / 3"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Ki = 4 / 5"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Kd = 6 / 7"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__bad_param) +{ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "ocpcpid y 0 0")); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcdrvlmt) +{ + const char *outbuffer; + size_t buffer_size; + + /* Set to 100mV */ + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdrvlmt 100")); + + /* Read back and verify */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdrvlmt")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Drive Limit = 100"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcdebug) +{ + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug ena")); + zassert_true(test_ocpc_get_debug_output()); + zassert_false(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug dis")); + zassert_false(test_ocpc_get_debug_output()); + zassert_false(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug viz")); + zassert_false(test_ocpc_get_debug_output()); + zassert_true(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug all")); + zassert_true(test_ocpc_get_debug_output()); + zassert_true(test_ocpc_get_viz_output()); + + /* Bad param */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "ocpcdebug foo")); + + /* Missing param */ + zassert_equal(EC_ERROR_PARAM_COUNT, + shell_execute_cmd(get_ec_shell(), "ocpcdebug")); +} + +static void reset(void *fixture) +{ + ARG_UNUSED(fixture); + + /* Reset */ + RESET_FAKE(ocpc_get_pid_constants); + + /* Load values that match ocpc.c's defaults */ + test_kp = 1; + test_kp_div = 4; + test_ki = 1; + test_ki_div = 15; + test_kd = 1; + test_kd_div = 10; + + ocpc_get_pid_constants_fake.custom_fake = get_pid_constants_custom_fake; + + /* Force an update which will use the above parameters. */ + ocpc_set_pid_constants(); +} + +ZTEST_SUITE(ocpc, NULL, NULL, reset, reset, NULL); diff --git a/zephyr/test/ocpc/testcase.yaml b/zephyr/test/ocpc/testcase.yaml new file mode 100644 index 0000000000..31fa165ef1 --- /dev/null +++ b/zephyr/test/ocpc/testcase.yaml @@ -0,0 +1,4 @@ +common: + platform_allow: native_posix +tests: + ocpc.default: {} diff --git a/zephyr/test/rex/boards/rex/rex.dtsi b/zephyr/test/rex/boards/rex/rex.dtsi index 0f30563537..9a2f2802d5 100644 --- a/zephyr/test/rex/boards/rex/rex.dtsi +++ b/zephyr/test/rex/boards/rex/rex.dtsi @@ -5,3 +5,15 @@ #include "../native_posix.overlay" #include "../../../../program/rex/rex/cbi.dtsi" + +/ { + /* Unused Stub */ + named-i2c-ports { + compatible = "named-i2c-ports"; + + named_i2c0: i2c0 { + i2c-port = <&i2c0>; + enum-names = "I2C_PORT_USB_MUX"; + }; + }; +}; diff --git a/zephyr/test/rex/prj.conf b/zephyr/test/rex/prj.conf index dc936eca7a..0fe26fc39e 100644 --- a/zephyr/test/rex/prj.conf +++ b/zephyr/test/rex/prj.conf @@ -15,3 +15,5 @@ CONFIG_LOG_MODE_MINIMAL=y CONFIG_AP_X86_INTEL_MTL=y CONFIG_TEST_DISABLE_AP_PWRSEQ=y + +CONFIG_EMUL_COMMON_I2C=y diff --git a/zephyr/test/skyrim/Kconfig b/zephyr/test/skyrim/Kconfig index c75d199114..ca6c1d5e21 100644 --- a/zephyr/test/skyrim/Kconfig +++ b/zephyr/test/skyrim/Kconfig @@ -75,6 +75,11 @@ config TEST_BOARD_USB_PD_POLICY bool "Enable USB PD policy specific tests" select TEST_ENABLE_USB_PD_HOST_CMD +config TEST_BOARD_POWER_SIGNALS + bool "Enable power signals tests" + select AP_POWER_CONTROL + select BOARD_USB_HUB_RESET + config TEST_BOARD_PPC_CONFIG bool "Enable PPC config tests" @@ -84,6 +89,10 @@ config TEST_BOARD_PPC_CONFIG_CUSTOM config TEST_BOARD_USB_MUX_CONFIG bool "Enable USB mux config tests" + select AP_POWER_CONTROL + select PLATFORM_EC_USB_MUX_MOCK + select PLATFORM_EC_USBC_RETIMER_PS8811 + select PLATFORM_EC_USB_MUX_RUNTIME_CONFIG config TEST_BOARD_USB_MUX_CONFIG_CUSTOM bool "Enable USB mux config tests with a variant-specific test file" @@ -93,10 +102,19 @@ config SKYRIM_LOG_LEVEL int "Fake config to allow building" default 4 # Log level debug by default +config AP_POWER_CONTROL + bool "Fake config to enable this feature" + config TEST_ENABLE_USB_PD_HOST_CMD bool "Fake config to enable this feature" config USB_PD_DISCHARGE bool "Fake config to enable this feature" +config PLATFORM_EC_USB_MUX_RUNTIME_CONFIG + bool "Fake config to enable this feature" + +config BOARD_USB_HUB_RESET + bool "Fake config to enable this feature" + source "Kconfig.zephyr" diff --git a/zephyr/test/skyrim/boards/native_posix.overlay b/zephyr/test/skyrim/boards/native_posix.overlay index 279f5e954b..aa3b9118b4 100644 --- a/zephyr/test/skyrim/boards/native_posix.overlay +++ b/zephyr/test/skyrim/boards/native_posix.overlay @@ -63,6 +63,108 @@ gpios = <&gpio0 11 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; }; + + /* Power signals */ + usb_a1_retimer_en: usb_a1_retimer_en { + gpios = <&gpio0 12 GPIO_OUTPUT_LOW>; + enum-name = "IOEX_USB_A1_RETIMER_EN"; + }; + + gpio_ec_disable_disp_bl: ec_disable_disp_bl { + gpios = <&gpio0 13 GPIO_OUTPUT_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT_L"; + }; + + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpio0 14 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S3_L"; + alias = "GPIO_PCH_SLP_S0_L"; + }; + + gpio_slp_s5_l: slp_s5_l { + gpios = <&gpio0 15 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S5_L"; + }; + + gpio_s0_pgood: pg_pcore_s0_r_od { + gpios = <&gpio0 16 GPIO_INPUT>; + enum-name = "GPIO_S0_PGOOD"; + }; + + gpio_prochot_odl: prochot_odl { + gpios = <&gpio0 17 GPIO_INPUT>; + enum-name = "GPIO_CPU_PROCHOT"; + }; + + gpio_pg_lpddr5_s0_od: pg_lpddr5_s0_od { + gpios = <&gpio0 18 GPIO_INPUT>; + }; + + gpio_pg_lpddr5_s3_od: pg_lpddr5_s3_od { + gpios = <&gpio0 19 GPIO_INPUT>; + }; + + gpio_en_pwr_s3: en_pwr_s3 { + gpios = <&gpio0 20 GPIO_OUTPUT_LOW>; + }; + + gpio_en_pwr_s0_r: en_pwr_s0_r { + /* + * Needs to be configured as I/O to allow tested code to + * read this pin. + */ + gpios = <&gpio0 21 (GPIO_OUTPUT_LOW | GPIO_INPUT)>; + }; + + gpio_pg_groupc_s0_od: pg_groupc_s0_od { + gpios = <&gpio0 22 GPIO_INPUT>; + }; + + gpio_en_pwr_pcore_s0_r: en_pwr_pcore_s0_r { + /* + * Needs to be configured as I/O to allow tested code to + * read this pin. + */ + gpios = <&gpio0 23 (GPIO_OUTPUT_LOW | GPIO_INPUT)>; + }; + + gpio_pcore_ocp_r_l: pcore_ocp_r_l { + gpios = <&gpio0 24 GPIO_INPUT>; + }; + + /* STB dumping GPIOs */ + gpio_ec_sfh_int_h: ec_sfh_int_h { + gpios = <&gpio0 25 GPIO_OUTPUT_LOW>; + }; + gpio_sfh_ec_int_h: sfh_ec_int_h { + gpios = <&gpio0 26 GPIO_INPUT>; + }; + + gpio_ec_soc_pwr_good: ec_soc_pwr_good { + gpios = <&gpio0 27 GPIO_OUTPUT_LOW>; + }; + + gpio_ec_soc_pwr_btn_l: ec_soc_pwr_btn_l { + gpios = <&gpio0 28 GPIO_OUTPUT_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + /* + * Needs to be configured as I/O to allow tested code to + * read this pin. + */ + gpios = <&gpio0 29 (GPIO_OUTPUT_LOW | GPIO_INPUT)>; + enum-name = "GPIO_PCH_RSMRST_L"; + }; + + gpio_soc_thermtrip_odl: soc_thermtrip_odl { + gpios = <&gpio0 30 GPIO_INPUT>; + }; + + gpio_hub_rst: hub_rst { + gpios = <&gpio0 31 GPIO_OUTPUT_HIGH>; + }; }; gpio-interrupts { @@ -73,6 +175,111 @@ flags = <GPIO_INT_EDGE_FALLING>; handler = "bmi3xx_interrupt"; }; + + int_pg_groupc_s0: pg_groupc_s0 { + irq-pin = <&gpio_pg_groupc_s0_od>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_interrupt_handler"; + }; + + int_pg_lpddr_s0: pg_lpddr_s0 { + irq-pin = <&gpio_pg_lpddr5_s0_od>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_interrupt_handler"; + }; + + int_pg_lpddr_s3: pg_lpddr_s3 { + irq-pin = <&gpio_pg_lpddr5_s3_od>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_interrupt_handler"; + }; + + int_prochot: prochot { + irq-pin = <&gpio_prochot_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "throttle_ap_prochot_input_interrupt"; + }; + + int_soc_pcore_ocp: soc_pcore_ocp { + irq-pin = <&gpio_pcore_ocp_r_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "baseboard_soc_pcore_ocp"; + }; + + int_soc_thermtrip: soc_thermtrip { + irq-pin = <&gpio_soc_thermtrip_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "baseboard_soc_thermtrip"; + }; + + int_stb_dump: stb_dump { + irq-pin = <&gpio_sfh_ec_int_h>; + flags = <GPIO_INT_EDGE_RISING>; + handler = "power_interrupt_handler"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_tcpc0: tcpc0 { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_TCPC0"; + }; + + i2c_tcpc1: tcpc1 { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_TCPC1"; + }; + + i2c_sensor: sensor { + i2c-port = <&i2c6_1>; + enum-names = "I2C_PORT_SENSOR"; + }; + }; + + i2c0_0: i2c@400 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = <I2C_BITRATE_STANDARD>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x400 4>; + + anx7483_port0: anx7483_emul0@3e { + compatible = "cros,anx7483-emul", "analogix,anx7483"; + reg = <0x3e>; + board-set = "board_anx7483_c0_mux_set"; + }; + }; + + i2c1_0: i2c@500 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = <I2C_BITRATE_STANDARD>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x500 4>; + + anx7483_port1: anx7483_emul1@3e { + compatible = "cros,anx7483-emul", "analogix,anx7483"; + reg = <0x3e>; + board-set = "board_anx7483_c1_mux_set"; + }; + + ps8811_port1: ps8811_emul@72 { + compatible = "cros,ps8811-emul"; + reg = <0x72>; + }; + }; + + i2c6_1: i2c@600 { + status = "okay"; + compatible = "zephyr,i2c-emul-controller"; + clock-frequency = <I2C_BITRATE_STANDARD>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x600 4>; }; skyrim-fw-config { @@ -155,22 +362,32 @@ }; }; - named-i2c-ports { - compatible = "named-i2c-ports"; + usbc { + #address-cells = <1>; + #size-cells = <0>; - eeprom { - i2c-port = <&i2c0>; - enum-names = "I2C_PORT_EEPROM"; - }; + usbc_port0: port0@0 { + compatible = "named-usbc-port"; + reg = <0>; - i2c_sensor: sensor { - i2c-port = <&i2c0>; - enum-names = "I2C_PORT_SENSOR"; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&anx7483_port0>; + }; }; + usbc_port1: port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + + usb-mux-chain-1-anx { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&anx7483_port1>; + }; + }; }; }; &gpio0 { - ngpios = <23>; + ngpios = <32>; }; diff --git a/zephyr/test/skyrim/prj.conf b/zephyr/test/skyrim/prj.conf index d9b3ba4ab9..a20cf94249 100644 --- a/zephyr/test/skyrim/prj.conf +++ b/zephyr/test/skyrim/prj.conf @@ -11,5 +11,9 @@ CONFIG_PLATFORM_EC_CBI=y CONFIG_CROS_EC=y CONFIG_PLATFORM_EC=y CONFIG_PLATFORM_EC_HOOKS=y +CONFIG_TEST_DISABLE_PLATFORM_EC_USBC=y CONFIG_EMUL=y CONFIG_GPIO=y +CONFIG_EMUL_COMMON_I2C=y + +CONFIG_AP_X86_AMD=y diff --git a/zephyr/test/skyrim/testcase.yaml b/zephyr/test/skyrim/testcase.yaml index b2bf8d2a06..62ccfad80e 100644 --- a/zephyr/test/skyrim/testcase.yaml +++ b/zephyr/test/skyrim/testcase.yaml @@ -5,11 +5,20 @@ common: platform_allow: native_posix tests: - # Baseboard tests + # Baseboard tests TEST_BOARD_POWER_SIGNALS skyrim.baseboard: extra_configs: - CONFIG_TEST_BOARD_BASEBOARD=y + skyrim.baseboard.power_signals: + extra_configs: + - CONFIG_TEST_BOARD_BASEBOARD=y + - CONFIG_TEST_BOARD_POWER_SIGNALS=y + - CONFIG_PLATFORM_EC_AMD_STB_DUMP=y + - CONFIG_PLATFORM_EC_THROTTLE_AP=y + - CONFIG_PLATFORM_EC_THROTTLE_AP_NO_FAN=y + - CONFIG_PLATFORM_EC_THROTTLE_AP_SINGLE_PIN=y + skyrim.baseboard.usb_pd_policy: extra_configs: - CONFIG_TEST_BOARD_BASEBOARD=y @@ -36,6 +45,11 @@ tests: - CONFIG_TEST_BOARD_CRYSTALDRIFT=y - CONFIG_TEST_BOARD_PPC_CONFIG=y + skyrim.crystaldrift.usb_mux_config: + extra_configs: + - CONFIG_TEST_BOARD_CRYSTALDRIFT=y + - CONFIG_TEST_BOARD_USB_MUX_CONFIG_CUSTOM=y + # Frostflow tests skyrim.frostflow: extra_configs: @@ -61,6 +75,11 @@ tests: - CONFIG_TEST_BOARD_MARKARTH=y - CONFIG_TEST_BOARD_PPC_CONFIG=y + skyrim.markarth.usb_mux_config: + extra_configs: + - CONFIG_TEST_BOARD_MARKARTH=y + - CONFIG_TEST_BOARD_USB_MUX_CONFIG_CUSTOM=y + # Skyrim tests skyrim.skyrim: extra_configs: @@ -76,17 +95,22 @@ tests: - CONFIG_TEST_BOARD_SKYRIM=y - CONFIG_TEST_BOARD_FAN=y + skyrim.skyrim.form_factor: + extra_configs: + - CONFIG_TEST_BOARD_SKYRIM=y + - CONFIG_TEST_BOARD_FORM_FACTOR=y + extra_dtc_overlay_files: + - ./boards/skyrim/skyrim.dtsi + skyrim.skyrim.ppc_config: extra_configs: - CONFIG_TEST_BOARD_SKYRIM=y - CONFIG_TEST_BOARD_PPC_CONFIG=y - skyrim.skyrim.form_factor: + skyrim.skyrim.usb_mux_config: extra_configs: - CONFIG_TEST_BOARD_SKYRIM=y - - CONFIG_TEST_BOARD_FORM_FACTOR=y - extra_dtc_overlay_files: - - ./boards/skyrim/skyrim.dtsi + - CONFIG_TEST_BOARD_USB_MUX_CONFIG_CUSTOM=y # Winterhold tests skyrim.winterhold: @@ -97,3 +121,8 @@ tests: extra_configs: - CONFIG_TEST_BOARD_WINTERHOLD=y - CONFIG_TEST_BOARD_PPC_CONFIG_CUSTOM=y + + skyrim.winterhold.usb_mux_config: + extra_configs: + - CONFIG_TEST_BOARD_WINTERHOLD=y + - CONFIG_TEST_BOARD_USB_MUX_CONFIG_CUSTOM=y diff --git a/zephyr/test/skyrim/tests/baseboard/CMakeLists.txt b/zephyr/test/skyrim/tests/baseboard/CMakeLists.txt index 06d1d0e72f..cad84421a9 100644 --- a/zephyr/test/skyrim/tests/baseboard/CMakeLists.txt +++ b/zephyr/test/skyrim/tests/baseboard/CMakeLists.txt @@ -3,4 +3,5 @@ # found in the LICENSE file. target_sources(app PRIVATE src/common.c) -target_sources_ifdef(CONFIG_TEST_BOARD_USB_PD_POLICY app PRIVATE src/usb_pd_policy.c ${PLATFORM_EC_PROGRAM_DIR}/skyrim/src/usb_pd_policy.c)
\ No newline at end of file +target_sources_ifdef(CONFIG_TEST_BOARD_USB_PD_POLICY app PRIVATE src/usb_pd_policy.c ${PLATFORM_EC_PROGRAM_DIR}/skyrim/src/usb_pd_policy.c) +target_sources_ifdef(CONFIG_TEST_BOARD_POWER_SIGNALS app PRIVATE src/power_signals ${PLATFORM_EC_PROGRAM_DIR}/skyrim/src/power_signals.c)
\ No newline at end of file diff --git a/zephyr/test/skyrim/tests/baseboard/src/power_signals.c b/zephyr/test/skyrim/tests/baseboard/src/power_signals.c new file mode 100644 index 0000000000..c4bfba04a7 --- /dev/null +++ b/zephyr/test/skyrim/tests/baseboard/src/power_signals.c @@ -0,0 +1,388 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "ap_power/ap_power.h" +#include "charger.h" +#include "gpio.h" +#include "gpio/gpio_int.h" +#include "ioexpander.h" +#include "power.h" + +#include <zephyr/drivers/gpio.h> +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/fff.h> +#include <zephyr/ztest.h> + +void baseboard_suspend_change(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data); +void baseboard_init(void); +void baseboard_set_soc_pwr_pgood(enum gpio_signal unused); +bool board_supports_pcore_ocp(void); +void board_pwrbtn_to_pch(int level); +void baseboard_s0_pgood(enum gpio_signal signal); +void baseboard_set_en_pwr_pcore(enum gpio_signal unused); +void baseboard_en_pwr_s0(enum gpio_signal signal); +void baseboard_set_en_pwr_s3(enum gpio_signal signal); +void baseboard_s5_pgood(enum gpio_signal signal); + +void baseboard_soc_thermtrip(enum gpio_signal signal); +void baseboard_soc_pcore_ocp(enum gpio_signal signal); + +FAKE_VOID_FUNC(chipset_force_shutdown, enum chipset_shutdown_reason); +FAKE_VALUE_FUNC(int, extpower_is_present); +FAKE_VOID_FUNC(print_charger_prochot, int); +FAKE_VOID_FUNC(power_signal_interrupt, enum gpio_signal); +FAKE_VOID_FUNC(power_interrupt_handler, enum gpio_signal); + +int chipset_in_state(int mask) +{ + return mask & CHIPSET_STATE_ON; +} + +static int gpio_emul_output_get_dt(const struct gpio_dt_spec *dt) +{ + return gpio_emul_output_get(dt->port, dt->pin); +} + +static int gpio_emul_input_set_dt(const struct gpio_dt_spec *dt, int value) +{ + return gpio_emul_input_set(dt->port, dt->pin, value); +} + +/* Toggles the pin and checks that the interrupt handler was called. */ +int test_interrupt(const struct gpio_dt_spec *dt) +{ + int rv; + int old_count = power_interrupt_handler_fake.call_count; + + rv = gpio_emul_input_set_dt(dt, 0); + if (rv) + return rv; + + rv = gpio_emul_input_set_dt(dt, 1); + if (rv) + return rv; + + rv = gpio_emul_input_set_dt(dt, 1); + if (rv) + return rv; + + return power_interrupt_handler_fake.call_count <= old_count; +} + +static void power_signals_before(void *fixture) +{ + ARG_UNUSED(fixture); + RESET_FAKE(chipset_force_shutdown); + RESET_FAKE(extpower_is_present); + RESET_FAKE(print_charger_prochot); + RESET_FAKE(power_signal_interrupt); + RESET_FAKE(power_interrupt_handler); +} + +ZTEST_SUITE(power_signals, NULL, NULL, power_signals_before, NULL, NULL); + +ZTEST(power_signals, test_baseboard_suspend_change) +{ + const struct gpio_dt_spec *gpio_ec_disable_disp_bl = + GPIO_DT_FROM_NODELABEL(gpio_ec_disable_disp_bl); + const struct gpio_dt_spec *usb_a1_retimer_en = + GPIO_DT_FROM_NODELABEL(usb_a1_retimer_en); + + struct ap_power_ev_data data; + + data.event = AP_POWER_SUSPEND; + baseboard_suspend_change(NULL, data); + zassert_true(gpio_emul_output_get_dt(gpio_ec_disable_disp_bl)); + zassert_false(gpio_emul_output_get_dt(usb_a1_retimer_en)); + + data.event = AP_POWER_RESUME; + baseboard_suspend_change(NULL, data); + zassert_false(gpio_emul_output_get_dt(gpio_ec_disable_disp_bl)); + zassert_true(gpio_emul_output_get_dt(usb_a1_retimer_en)); +} + +ZTEST(power_signals, test_baseboard_init) +{ + const struct gpio_dt_spec *gpio_pg_groupc_s0_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_groupc_s0_od); + const struct gpio_dt_spec *gpio_pg_lpddr5_s0_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_lpddr5_s0_od); + const struct gpio_dt_spec *gpio_pg_lpddr5_s3_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_lpddr5_s3_od); + const struct gpio_dt_spec *gpio_soc_thermtrip_odl = + GPIO_DT_FROM_NODELABEL(gpio_soc_thermtrip_odl); + const struct gpio_dt_spec *gpio_sfh_ec_int_h = + GPIO_DT_FROM_NODELABEL(gpio_sfh_ec_int_h); + const struct gpio_dt_spec *gpio_prochot_odl = + GPIO_DT_FROM_NODELABEL(gpio_prochot_odl); + + baseboard_init(); + + /* Trigger interrupts to validate that they've been enabled. */ + /* These interrupts use the generic test handler. */ + zassert_ok(test_interrupt(gpio_pg_groupc_s0_od)); + zassert_ok(test_interrupt(gpio_pg_lpddr5_s0_od)); + zassert_ok(test_interrupt(gpio_pg_lpddr5_s3_od)); + zassert_ok(test_interrupt(gpio_sfh_ec_int_h)); + + /* Verify that the thermal trip interrupt triggers a shutdown. */ + zassert_ok(gpio_emul_input_set_dt(gpio_soc_thermtrip_odl, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_soc_thermtrip_odl, 0)); + zassert_equal(chipset_force_shutdown_fake.call_count, 1); + zassert_equal(chipset_force_shutdown_fake.arg0_val, + CHIPSET_SHUTDOWN_THERMAL); + + /* Test that our prochot handler prints out charger info. */ + zassert_ok(gpio_emul_input_set_dt(gpio_prochot_odl, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_prochot_odl, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_prochot_odl, 1)); + /* Give plenty of time for the deferred logic to run. */ + k_msleep(500); + zassert_equal(print_charger_prochot_fake.call_count, 1); +} + +ZTEST(power_signals, test_baseboard_set_soc_pwr_pgood) +{ + const struct gpio_dt_spec *gpio_en_pwr_pcore_s0_r = + GPIO_DT_FROM_NODELABEL(gpio_en_pwr_pcore_s0_r); + const struct gpio_dt_spec *gpio_pg_lpddr5_s0_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_lpddr5_s0_od); + const struct gpio_dt_spec *gpio_s0_pgood = + GPIO_DT_FROM_NODELABEL(gpio_s0_pgood); + + const struct gpio_dt_spec *gpio_ec_soc_pwr_good = + GPIO_DT_FROM_NODELABEL(gpio_ec_soc_pwr_good); + + /* Test all combinations of these power pins. */ + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 0)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 0)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 0)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 0)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 1)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 1)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 1)); + baseboard_set_soc_pwr_pgood(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); + + zassert_ok(gpio_pin_set_dt(gpio_en_pwr_pcore_s0_r, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_s0_pgood, 1)); + baseboard_set_soc_pwr_pgood(0); + zassert_true(gpio_emul_output_get_dt(gpio_ec_soc_pwr_good)); +} + +ZTEST(power_signals, test_board_supports_pcore_ocp) +{ + zassert_true(board_supports_pcore_ocp()); +} + +ZTEST(power_signals, test_baseboard_set_en_pwr_pcore) +{ + const struct gpio_dt_spec *gpio_pg_lpddr5_s3_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_lpddr5_s3_od); + const struct gpio_dt_spec *gpio_pg_groupc_s0_od = + GPIO_DT_FROM_NODELABEL(gpio_pg_groupc_s0_od); + const struct gpio_dt_spec *gpio_en_pwr_s0_r = + GPIO_DT_FROM_NODELABEL(gpio_en_pwr_s0_r); + + const struct gpio_dt_spec *gpio_en_pwr_pcore_s0_r = + GPIO_DT_FROM_NODELABEL(gpio_en_pwr_pcore_s0_r); + + /* Test all combinations of these power pins. */ + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 0)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 0)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 0)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 0)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 1)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 1)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 1)); + baseboard_set_en_pwr_pcore(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_pg_lpddr5_s3_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_groupc_s0_od, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_en_pwr_s0_r, 1)); + baseboard_set_en_pwr_pcore(0); + zassert_true(gpio_emul_output_get_dt(gpio_en_pwr_pcore_s0_r)); +} + +ZTEST(power_signals, test_baseboard_en_pwr_s0) +{ + const struct gpio_dt_spec *gpio_slp_s3_l = + GPIO_DT_FROM_NODELABEL(gpio_slp_s3_l); + const struct gpio_dt_spec *gpio_pg_pwr_s5 = + GPIO_DT_FROM_NODELABEL(gpio_pg_pwr_s5); + + const struct gpio_dt_spec *gpio_en_pwr_s0_r = + GPIO_DT_FROM_NODELABEL(gpio_en_pwr_s0_r); + + /* Test all combinations of these power pins. */ + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s3_l, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 0)); + baseboard_en_pwr_s0(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s3_l, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 0)); + baseboard_en_pwr_s0(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s3_l, 0)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 1)); + baseboard_en_pwr_s0(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_s0_r)); + + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s3_l, 1)); + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 1)); + baseboard_en_pwr_s0(0); + zassert_true(gpio_emul_output_get_dt(gpio_en_pwr_s0_r)); + + /* Ensure we always are chaining off the normal handler. */ + zassert_equal(power_signal_interrupt_fake.call_count, 4); +} + +ZTEST(power_signals, test_baseboard_set_en_pwr_s3) +{ + const struct gpio_dt_spec *gpio_slp_s5_l = + GPIO_DT_FROM_NODELABEL(gpio_slp_s5_l); + + const struct gpio_dt_spec *gpio_en_pwr_s3 = + GPIO_DT_FROM_NODELABEL(gpio_en_pwr_s3); + + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s5_l, 0)); + baseboard_set_en_pwr_s3(0); + zassert_false(gpio_emul_output_get_dt(gpio_en_pwr_s3)); + + zassert_ok(gpio_emul_input_set_dt(gpio_slp_s5_l, 1)); + baseboard_set_en_pwr_s3(0); + zassert_true(gpio_emul_output_get_dt(gpio_en_pwr_s3)); + + /* Ensure we always are chaining off the normal handler. */ + zassert_equal(power_signal_interrupt_fake.call_count, 2); +} + +ZTEST(power_signals, test_baseboard_s5_pgood) +{ + const struct gpio_dt_spec *gpio_pg_pwr_s5 = + GPIO_DT_FROM_NODELABEL(gpio_pg_pwr_s5); + const struct gpio_dt_spec *gpio_hub_rst = + GPIO_DT_FROM_NODELABEL(gpio_hub_rst); + + /* Test the path that waits 30 ms after S5 PGOOD. */ + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 1)); + baseboard_s5_pgood(0); + k_msleep(300); + zassert_false(gpio_emul_output_get_dt(gpio_hub_rst)); + + /* Test other path. */ + zassert_ok(gpio_emul_input_set_dt(gpio_pg_pwr_s5, 0)); + baseboard_s5_pgood(0); + zassert_true(gpio_emul_output_get_dt(gpio_hub_rst)); +} + +static void set_rsmrst_l(struct k_work *work) +{ + const struct gpio_dt_spec *gpio_ec_soc_rsmrst_l = + GPIO_DT_FROM_NODELABEL(gpio_ec_soc_rsmrst_l); + + k_msleep(10); + gpio_emul_input_set_dt(gpio_ec_soc_rsmrst_l, 1); +} +K_WORK_DEFINE(set_rsmrst_l_work, set_rsmrst_l); + +ZTEST(power_signals, test_board_pwrbtn_to_pch) +{ + const struct gpio_dt_spec *gpio_ec_soc_rsmrst_l = + GPIO_DT_FROM_NODELABEL(gpio_ec_soc_rsmrst_l); + const struct gpio_dt_spec *gpio_ec_soc_pwr_btn_l = + GPIO_DT_FROM_NODELABEL(gpio_ec_soc_pwr_btn_l); + + /* Test delay when asserting PWRBTN_L and RSMRST_L are low. */ + zassert_ok(gpio_emul_input_set_dt(gpio_ec_soc_rsmrst_l, 0)); + k_work_submit(&set_rsmrst_l_work); + board_pwrbtn_to_pch(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_btn_l)); + + /* Test timeout. */ + zassert_ok(gpio_emul_input_set_dt(gpio_ec_soc_rsmrst_l, 0)); + board_pwrbtn_to_pch(0); + zassert_false(gpio_emul_output_get_dt(gpio_ec_soc_pwr_btn_l)); + + /* Test when PWRBTN_L is not asserted. */ + board_pwrbtn_to_pch(1); + zassert_true(gpio_emul_output_get_dt(gpio_ec_soc_pwr_btn_l)); +} + +ZTEST(power_signals, test_baseboard_soc_pcore_ocp) +{ + baseboard_soc_pcore_ocp(0); + zassert_equal(chipset_force_shutdown_fake.call_count, 1); + zassert_equal(chipset_force_shutdown_fake.arg0_val, + CHIPSET_SHUTDOWN_BOARD_CUSTOM); +} diff --git a/zephyr/test/skyrim/tests/common/CMakeLists.txt b/zephyr/test/skyrim/tests/common/CMakeLists.txt index 49da87b372..53dd9da3c4 100644 --- a/zephyr/test/skyrim/tests/common/CMakeLists.txt +++ b/zephyr/test/skyrim/tests/common/CMakeLists.txt @@ -30,5 +30,10 @@ endif() # USB mux config if (DEFINED CONFIG_TEST_BOARD_USB_MUX_CONFIG) - target_sources(app PRIVATE ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/usb_mux_config.c) + target_sources(app PRIVATE + ${PLATFORM_EC}/driver/usb_mux/usb_mux.c + ${PLATFORM_EC}/zephyr/shim/src/usb_muxes.c + src/usb_mux_config.c + ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/usb_mux_config.c + ) endif()
\ No newline at end of file diff --git a/zephyr/test/skyrim/tests/common/src/common.c b/zephyr/test/skyrim/tests/common/src/common.c index b369d0bdaa..0be4550026 100644 --- a/zephyr/test/skyrim/tests/common/src/common.c +++ b/zephyr/test/skyrim/tests/common/src/common.c @@ -2,6 +2,48 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "common.h" +#include "usbc/usb_muxes.h" + #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(skyrim, CONFIG_SKYRIM_LOG_LEVEL); + +/* + * Provide weak definitons for interrupt handlers. This minimizes the number + * of test-specific device tree overrides needed. + */ + +test_mockable void baseboard_soc_pcore_ocp(enum gpio_signal signal) +{ +} + +test_mockable void baseboard_soc_thermtrip(enum gpio_signal signal) +{ +} + +test_mockable int bmi3xx_interrupt(enum gpio_signal signal) +{ + return -EINVAL; +} + +test_mockable int board_anx7483_c0_mux_set(const struct usb_mux *me, + mux_state_t mux_state) +{ + return -EINVAL; +} + +test_mockable int board_anx7483_c1_mux_set(const struct usb_mux *me, + mux_state_t mux_state) +{ + return -EINVAL; +} + +test_mockable int power_interrupt_handler(const struct gpio_dt_spec *dt) +{ + return -EINVAL; +} + +test_mockable void throttle_ap_prochot_input_interrupt(enum gpio_signal signal) +{ +} diff --git a/zephyr/test/skyrim/tests/common/src/usb_mux_config.c b/zephyr/test/skyrim/tests/common/src/usb_mux_config.c new file mode 100644 index 0000000000..ea663ba2cb --- /dev/null +++ b/zephyr/test/skyrim/tests/common/src/usb_mux_config.c @@ -0,0 +1,62 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "chipset.h" +#include "usbc/usb_muxes.h" +#include "ztest/usb_mux_config.h" + +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/fff.h> +#include <zephyr/ztest.h> + +int ioex_set_flip(int port, mux_state_t mux_state); +int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state); + +DEFINE_FAKE_VOID_FUNC(usb_mux_enable_alternative); + +__override uint8_t board_get_usb_pd_port_count(void) +{ + return CONFIG_USB_PD_PORT_MAX_COUNT; +} + +enum tcpc_cc_polarity pd_get_polarity(int port) +{ + return 0; +} + +FAKE_VOID_FUNC(chipset_force_shutdown, enum chipset_shutdown_reason); +FAKE_VALUE_FUNC(int, extpower_is_present); + +int chipset_in_state(int mask) +{ + return mask & CHIPSET_STATE_ON; +} + +ZTEST_SUITE(usb_mux_config_common, NULL, NULL, NULL, NULL, NULL); + +ZTEST(usb_mux_config_common, test_ioex_set_flip) +{ + const struct gpio_dt_spec *c0 = + GPIO_DT_FROM_NODELABEL(ioex_usb_c0_sbu_flip); + const struct gpio_dt_spec *c1 = + GPIO_DT_FROM_NODELABEL(ioex_usb_c1_sbu_flip); + int rv; + + /* Value of the corresponding pin should match flipped status. */ + rv = ioex_set_flip(0, 0); + zassert_ok(rv); + zassert_equal(gpio_emul_output_get(c0->port, c0->pin), 0); + + rv = ioex_set_flip(0, USB_PD_MUX_POLARITY_INVERTED); + zassert_ok(rv); + zassert_equal(gpio_emul_output_get(c0->port, c0->pin), 1); + + rv = ioex_set_flip(1, 0); + zassert_ok(rv); + zassert_equal(gpio_emul_output_get(c1->port, c1->pin), 0); + + rv = ioex_set_flip(1, USB_PD_MUX_POLARITY_INVERTED); + zassert_ok(rv); + zassert_equal(gpio_emul_output_get(c1->port, c1->pin), 1); +} diff --git a/zephyr/test/skyrim/tests/frostflow/src/usb_mux_config.c b/zephyr/test/skyrim/tests/frostflow/src/usb_mux_config.c index 688453d13f..24e7e78dbf 100644 --- a/zephyr/test/skyrim/tests/frostflow/src/usb_mux_config.c +++ b/zephyr/test/skyrim/tests/frostflow/src/usb_mux_config.c @@ -9,11 +9,6 @@ #include <driver/retimer/ps8811.h> #include <usbc/usb_muxes.h> -FAKE_VALUE_FUNC(int, ps8811_i2c_read, const struct usb_mux *, int, int, int *); -FAKE_VALUE_FUNC(int, ps8811_i2c_field_update, const struct usb_mux *, int, int, - uint8_t, uint8_t); -FAKE_VALUE_FUNC(int, ps8811_i2c_write, const struct usb_mux *, int, int, int); - int board_c0_amd_fp6_mux_set(const struct usb_mux *me, mux_state_t mux_state); int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state); @@ -47,19 +42,3 @@ ZTEST(usb_mux_config, test_board_c0_amd_fp6_mux_set) zassert_equal(rv, EC_SUCCESS); zassert_equal(gpio_emul_output_get(c1->port, c1->pin), 1); } - -ZTEST(usb_mux_config, test_board_c1_ps8818_mux_set) -{ - const struct gpio_dt_spec *gpio = - GPIO_DT_FROM_NODELABEL(gpio_usb_c1_in_hpd); - struct usb_mux mux; - - /* gpio_usb_c1_in_hpd should match if DP is enabled. */ - mux.usb_port = 0; - zassert_ok(board_c1_ps8818_mux_set(&mux, 0)); - zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); - - mux.usb_port = 1; - zassert_ok(board_c1_ps8818_mux_set(&mux, USB_PD_MUX_DP_ENABLED)); - zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1); -} diff --git a/zephyr/test/skyrim/tests/skyrim/CMakeLists.txt b/zephyr/test/skyrim/tests/skyrim/CMakeLists.txt index 48ebbf074b..adf1708004 100644 --- a/zephyr/test/skyrim/tests/skyrim/CMakeLists.txt +++ b/zephyr/test/skyrim/tests/skyrim/CMakeLists.txt @@ -5,3 +5,5 @@ target_sources(app PRIVATE src/common.c) target_sources_ifdef(CONFIG_TEST_BOARD_FORM_FACTOR app PRIVATE src/form_factor.c ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/form_factor.c) + +target_sources_ifdef(CONFIG_TEST_BOARD_USB_MUX_CONFIG app PRIVATE src/usb_mux_config.c) diff --git a/zephyr/test/skyrim/tests/skyrim/src/usb_mux_config.c b/zephyr/test/skyrim/tests/skyrim/src/usb_mux_config.c new file mode 100644 index 0000000000..91aafad1b2 --- /dev/null +++ b/zephyr/test/skyrim/tests/skyrim/src/usb_mux_config.c @@ -0,0 +1,194 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "cros_cbi.h" +#include "emul/retimer/emul_anx7483.h" +#include "usbc/usb_muxes.h" +#include "ztest/usb_mux_config.h" + +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/fff.h> +#include <zephyr/ztest.h> + +#define ANX7483_EMUL0 EMUL_DT_GET(DT_NODELABEL(anx7483_port0)) +#define ANX7483_EMUL1 EMUL_DT_GET(DT_NODELABEL(anx7483_port1)) + +int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state); +void setup_mux(void); + +extern const struct anx7483_tuning_set anx7483_usb_enabled[]; +extern const struct anx7483_tuning_set anx7483_dp_enabled[]; +extern const struct anx7483_tuning_set anx7483_dock_noflip[]; +extern const struct anx7483_tuning_set anx7483_dock_flip[]; + +extern const size_t anx7483_usb_enabled_count; +extern const size_t anx7483_dp_enabled_count; +extern const size_t anx7483_dock_noflip_count; +extern const size_t anx7483_dock_flip_count; + +FAKE_VALUE_FUNC(int, cros_cbi_get_fw_config, enum cbi_fw_config_field_id, + uint32_t *); + +static bool alt_retimer; +static int cros_cbi_get_fw_config_mock(enum cbi_fw_config_field_id field_id, + uint32_t *value) +{ + if (field_id != FW_IO_DB) + return -EINVAL; + + *value = alt_retimer ? FW_IO_DB_PS8811_PS8818 : FW_IO_DB_NONE_ANX7483; + return 0; +} + +static void usb_mux_config_before(void *fixture) +{ + ARG_UNUSED(fixture); + RESET_FAKE(cros_cbi_get_fw_config); + + cros_cbi_get_fw_config_fake.custom_fake = cros_cbi_get_fw_config_mock; +} + +ZTEST_SUITE(usb_mux_config, NULL, NULL, usb_mux_config_before, NULL, NULL); + +ZTEST(usb_mux_config, test_board_anx7483_c0_mux_set) +{ + int rv; + + usb_mux_init(0); + + usb_mux_set(0, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT, 0); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL0, anx7483_usb_enabled, + anx7483_usb_enabled_count); + zexpect_ok(rv); + + usb_mux_set(0, USB_PD_MUX_DP_ENABLED, USB_SWITCH_CONNECT, 0); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL0, anx7483_dp_enabled, + anx7483_dp_enabled_count); + zexpect_ok(rv); + + usb_mux_set(0, USB_PD_MUX_DOCK, USB_SWITCH_CONNECT, 0); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL0, anx7483_dock_noflip, + anx7483_dock_noflip_count); + zexpect_ok(rv); + + usb_mux_set(0, USB_PD_MUX_DOCK | USB_PD_MUX_POLARITY_INVERTED, + USB_SWITCH_CONNECT, 0); + rv = anx7483_emul_validate_tuning(ANX7483_EMUL0, anx7483_dock_flip, + anx7483_dock_flip_count); + zexpect_ok(rv); +} + +ZTEST(usb_mux_config, test_board_anx7483_c1_mux_set) +{ + int rv; + enum anx7483_eq_setting eq; + + alt_retimer = false; + setup_mux(); + + usb_mux_init(1); + + /* Test USB mux state. */ + usb_mux_set(1, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT, 0); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_DRX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_DRX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + /* Test DP mux state. */ + usb_mux_set(1, USB_PD_MUX_DP_ENABLED, USB_SWITCH_CONNECT, 0); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_UTX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_UTX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + /* Test dock mux state. */ + usb_mux_set(1, USB_PD_MUX_DOCK, USB_SWITCH_CONNECT, 0); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_DRX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_UTX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + /* Test flipped dock mux state. */ + usb_mux_set(1, USB_PD_MUX_DOCK | USB_PD_MUX_POLARITY_INVERTED, + USB_SWITCH_CONNECT, 0); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_URX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_UTX1, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); + + rv = anx7483_emul_get_eq(ANX7483_EMUL1, ANX7483_PIN_DRX2, &eq); + zassert_ok(rv); + zassert_equal(eq, ANX7483_EQ_SETTING_12_5DB); +} + +ZTEST(usb_mux_config, test_board_c1_ps8818_mux_set) +{ + const struct gpio_dt_spec *c1 = + GPIO_DT_FROM_NODELABEL(gpio_usb_c1_in_hpd); + const struct usb_mux mux = { + .usb_port = 1, + }; + + board_c1_ps8818_mux_set(&mux, USB_PD_MUX_USB_ENABLED); + zassert_false(gpio_emul_output_get(c1->port, c1->pin)); + + board_c1_ps8818_mux_set(&mux, USB_PD_MUX_DP_ENABLED); + zassert_true(gpio_emul_output_get(c1->port, c1->pin)); +} + +ZTEST(usb_mux_config, test_setup_mux) +{ + alt_retimer = false; + setup_mux(); + zassert_equal(usb_mux_enable_alternative_fake.call_count, 0); + + alt_retimer = true; + setup_mux(); + zassert_equal(usb_mux_enable_alternative_fake.call_count, 1); +} diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py index ca6632e075..54ecad076a 100644 --- a/zephyr/zmake/tests/test_zmake.py +++ b/zephyr/zmake/tests/test_zmake.py @@ -164,8 +164,11 @@ class TestFilters: assert not recs @staticmethod - def test_filter_info(zmake_factory_from_dir, tmp_path): + def test_filter_info(zmake_factory_from_dir, tmp_path, monkeypatch): """Test what appears on the INFO level""" + monkeypatch.setattr( + os, "environ", {"TOOL_PATH_ninja": "/usr/bin/ninja"} + ) recs = do_test_with_log_level(zmake_factory_from_dir, logging.INFO) # TODO: Remove sets and figure out how to check the lines are in the # right order. @@ -192,8 +195,11 @@ class TestFilters: assert expected == set(recs) @staticmethod - def test_filter_debug(zmake_factory_from_dir, tmp_path): + def test_filter_debug(zmake_factory_from_dir, tmp_path, monkeypatch): """Test what appears on the DEBUG level""" + monkeypatch.setattr( + os, "environ", {"TOOL_PATH_ninja": "/usr/bin/ninja"} + ) recs = do_test_with_log_level(zmake_factory_from_dir, logging.DEBUG) # TODO: Remove sets and figure out how to check the lines are in the # right order. diff --git a/zephyr/zmake/zmake/compare_builds.py b/zephyr/zmake/zmake/compare_builds.py index 54d51dd18a..80b7b59b12 100644 --- a/zephyr/zmake/zmake/compare_builds.py +++ b/zephyr/zmake/zmake/compare_builds.py @@ -137,12 +137,14 @@ class CheckoutConfig: work_dir: pathlib.Path = dataclasses.field(default_factory=pathlib.Path) zephyr_dir: pathlib.Path = dataclasses.field(default_factory=pathlib.Path) modules_dir: pathlib.Path = dataclasses.field(default_factory=pathlib.Path) + projects_dir: pathlib.Path = dataclasses.field(default_factory=pathlib.Path) def __post_init__(self): self.full_ref = get_git_hash(self.ref) self.work_dir = pathlib.Path(self.temp_dir) / self.full_ref self.zephyr_dir = self.work_dir / "zephyr-base" self.modules_dir = self.work_dir / "modules" + self.projects_dir = self.modules_dir / "ec" / "zephyr" os.mkdir(self.work_dir) diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py index 70988a12c5..4c6d840535 100644 --- a/zephyr/zmake/zmake/zmake.py +++ b/zephyr/zmake/zmake/zmake.py @@ -383,6 +383,7 @@ class Zmake: transformed_module = {module_name: new_path} self.module_paths.update(transformed_module) + self.projects_dir = checkout.projects_dir self.zephyr_base = checkout.zephyr_dir self.logger.info("Building projects at %s", checkout.ref) |