diff options
author | Aseda Aboagye <aaboagye@google.com> | 2022-04-29 10:44:03 -0700 |
---|---|---|
committer | Aseda Aboagye <aaboagye@google.com> | 2022-04-29 10:44:03 -0700 |
commit | be06d222bccb9d7ba114dfcdccded453b390d14a (patch) | |
tree | 22678afe71e86dbfc067a47109dbc7245f5347d9 | |
parent | 61f735f5f0fb2fc57595d2838c906d22f442ea20 (diff) | |
parent | a588afd712c638e75df5c0b5b90d860d9f8a55c6 (diff) | |
download | chrome-ec-be06d222bccb9d7ba114dfcdccded453b390d14a.tar.gz |
Merge remote-tracking branch cros/main into firmware-dedede-13606.B-master
Relevant changes:
git log --oneline 61f735f5f0..a588afd712 -- baseboard/dedede
board/beadrix board/beetley board/blipper board/boten board/bugzzy
board/corori2 board/cret board/drawcia board/drawcia_riscv board/galtic
board/kracko board/lantis board/madoo board/magolor board/metaknight
board/pirika board/sasuke board/sasukette board/storo board/waddledee
board/waddledoo board/wheelie common/charge_state_v2.c 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
a588afd712 Storo: Increase pd_task stack size
4a5f4708c3 ISL923x: Disable input regulation with function
BRANCH=None
BUG=b:230833524 b:224616537
TEST=`make -j buildall`
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Change-Id: I60dba502c4b8a05c9def2803035f71c71c0527af
127 files changed, 3016 insertions, 472 deletions
diff --git a/baseboard/cherry/baseboard.c b/baseboard/cherry/baseboard.c index d7ab72565a..388252dd7d 100644 --- a/baseboard/cherry/baseboard.c +++ b/baseboard/cherry/baseboard.c @@ -568,7 +568,7 @@ static void baseboard_init(void) } DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT - 1); -__override int board_pd_set_frs_enable(int port, int enable) +__override int board_rt1718s_set_frs_enable(int port, int enable) { if (port == 1) /* diff --git a/baseboard/volteer/power.c b/baseboard/volteer/power.c index fa20cfa93f..b0d6b847ce 100644 --- a/baseboard/volteer/power.c +++ b/baseboard/volteer/power.c @@ -6,6 +6,7 @@ #include "gpio.h" #include "hooks.h" #include "power/icelake.h" +#include "throttle_ap.h" /* * PWROK signal configuration, see the PWROK Generation Flow Diagram (Figure @@ -48,9 +49,22 @@ const struct intel_x86_pwrok_signal pwrok_signal_deassert_list[] = { }; const int pwrok_signal_deassert_count = ARRAY_SIZE(pwrok_signal_deassert_list); +static const struct prochot_cfg volteer_prochot_cfg = { + .gpio_prochot_in = GPIO_EC_PROCHOT_IN_L, +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + .gpio_c10_in = GPIO_CPU_C10_GATE_L, + .c10_active_high = false, +#endif +}; + static void baseboard_init(void) { /* Enable monitoring of the PROCHOT input to the EC */ + throttle_ap_config_prochot(&volteer_prochot_cfg); gpio_enable_interrupt(GPIO_EC_PROCHOT_IN_L); + +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + gpio_enable_interrupt(GPIO_CPU_C10_GATE_L); +#endif } DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT); diff --git a/board/burnet/board.c b/board/burnet/board.c index 31122e1450..51cf4bc0db 100644 --- a/board/burnet/board.c +++ b/board/burnet/board.c @@ -17,7 +17,7 @@ #include "driver/accel_kionix.h" #include "driver/accelgyro_bmi_common.h" #include "driver/accelgyro_icm_common.h" -#include "driver/accelgyro_icm426xx.h" +#include "driver/accelgyro_icm42607.h" #include "driver/battery/max17055.h" #include "driver/bc12/pi3usb9201.h" #include "driver/charger/isl923x.h" @@ -339,7 +339,7 @@ static const mat33_fp_t base_bmi160_ref = { {0, 0, FLOAT_TO_FP(-1)} }; -static const mat33_fp_t base_icm426xx_ref = { +static const mat33_fp_t base_icm42607_ref = { {0, FLOAT_TO_FP(-1), 0}, {FLOAT_TO_FP(-1), 0, 0}, {0, 0, FLOAT_TO_FP(-1)} @@ -349,7 +349,7 @@ static const mat33_fp_t base_icm426xx_ref = { static struct accelgyro_saved_data_t g_bma253_data; static struct kionix_accel_data g_kx022_data; static struct bmi_drv_data_t g_bmi160_data; -static struct icm_drv_data_t g_icm426xx_data; +static struct icm_drv_data_t g_icm42607_data; struct motion_sensor_t lid_accel_kx022 = { .name = "Lid Accel", @@ -374,21 +374,21 @@ struct motion_sensor_t lid_accel_kx022 = { }, }; -struct motion_sensor_t base_accel_icm426xx = { +struct motion_sensor_t base_accel_icm42607 = { .name = "Base Accel", .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, + .chip = MOTIONSENSE_CHIP_ICM42607, .type = MOTIONSENSE_TYPE_ACCEL, .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, + .drv = &icm42607_drv, .mutex = &g_base_mutex, - .drv_data = &g_icm426xx_data, + .drv_data = &g_icm42607_data, .port = CONFIG_SPI_ACCEL_PORT, .i2c_spi_addr_flags = ACCEL_MK_SPI_ADDR_FLAGS(CONFIG_SPI_ACCEL_PORT), .default_range = 4, - .rot_standard_ref = &base_icm426xx_ref, - .min_frequency = ICM426XX_ACCEL_MIN_FREQ, - .max_frequency = ICM426XX_ACCEL_MAX_FREQ, + .rot_standard_ref = &base_icm42607_ref, + .min_frequency = ICM42607_ACCEL_MIN_FREQ, + .max_frequency = ICM42607_ACCEL_MAX_FREQ, .config = { /* EC use accel for angle detection */ [SENSOR_CONFIG_EC_S0] = { @@ -401,21 +401,21 @@ struct motion_sensor_t base_accel_icm426xx = { }, }; -struct motion_sensor_t base_gyro_icm426xx = { +struct motion_sensor_t base_gyro_icm42607 = { .name = "Base Gyro", .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, + .chip = MOTIONSENSE_CHIP_ICM42607, .type = MOTIONSENSE_TYPE_GYRO, .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, + .drv = &icm42607_drv, .mutex = &g_base_mutex, - .drv_data = &g_icm426xx_data, + .drv_data = &g_icm42607_data, .port = CONFIG_SPI_ACCEL_PORT, .i2c_spi_addr_flags = ACCEL_MK_SPI_ADDR_FLAGS(CONFIG_SPI_ACCEL_PORT), .default_range = 1000, /* dps */ - .rot_standard_ref = &base_icm426xx_ref, - .min_frequency = ICM426XX_GYRO_MIN_FREQ, - .max_frequency = ICM426XX_GYRO_MAX_FREQ, + .rot_standard_ref = &base_icm42607_ref, + .min_frequency = ICM42607_GYRO_MIN_FREQ, + .max_frequency = ICM42607_GYRO_MAX_FREQ, }; struct motion_sensor_t motion_sensors[] = { @@ -500,8 +500,8 @@ unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); void sensor_interrupt(enum gpio_signal signal) { switch (motion_sensors[BASE_ACCEL].chip) { - case MOTIONSENSE_CHIP_ICM426XX: - icm426xx_interrupt(signal); + case MOTIONSENSE_CHIP_ICM42607: + icm42607_interrupt(signal); break; case MOTIONSENSE_CHIP_BMI160: default: @@ -522,12 +522,12 @@ static void board_update_config(void) if (rv == EC_SUCCESS) motion_sensors[LID_ACCEL] = lid_accel_kx022; - /* Read icm-40608 chip content */ - rv = icm_read8(&base_accel_icm426xx, ICM426XX_REG_WHO_AM_I, &val); + /* Read icm-42607 chip content */ + rv = icm_read8(&base_accel_icm42607, ICM42607_REG_WHO_AM_I, &val); - if (rv == EC_SUCCESS && val == ICM426XX_CHIP_ICM40608) { - motion_sensors[BASE_ACCEL] = base_accel_icm426xx; - motion_sensors[BASE_GYRO] = base_gyro_icm426xx; + if (rv == EC_SUCCESS && val == ICM42607_CHIP_ICM42607P) { + motion_sensors[BASE_ACCEL] = base_accel_icm42607; + motion_sensors[BASE_GYRO] = base_gyro_icm42607; } CPRINTS("Lid Accel Chip: %d", motion_sensors[LID_ACCEL].chip); diff --git a/board/burnet/board.h b/board/burnet/board.h index 02196f96ec..004606abe7 100644 --- a/board/burnet/board.h +++ b/board/burnet/board.h @@ -58,9 +58,9 @@ #define CONFIG_ACCEL_INTERRUPTS #define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) -/* ICM426XX Base accel/gyro */ -#define CONFIG_ACCELGYRO_ICM426XX -#define CONFIG_ACCELGYRO_ICM426XX_INT_EVENT \ +/* ICM42607 Base accel/gyro */ +#define CONFIG_ACCELGYRO_ICM42607 +#define CONFIG_ACCELGYRO_ICM42607_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) #define CONFIG_ALS #define CONFIG_CMD_ACCEL_INFO diff --git a/board/chronicler/board.h b/board/chronicler/board.h index 87d1c2a21f..4cd634ef9a 100644 --- a/board/chronicler/board.h +++ b/board/chronicler/board.h @@ -28,6 +28,7 @@ /* Chipset features */ #define CONFIG_POWER_PP5000_CONTROL +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 /* Sensors */ #undef CONFIG_TABLET_MODE diff --git a/board/chronicler/gpio.inc b/board/chronicler/gpio.inc index b85322ac6c..b8b8d4f5e7 100644 --- a/board/chronicler/gpio.inc +++ b/board/chronicler/gpio.inc @@ -63,6 +63,7 @@ GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(6, 7), GPIO_INT_RISING, throttle_ap_c10_input_interrupt) GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) @@ -101,7 +102,6 @@ GPIO(C1_CHARGE_LED_WHITE_L, PIN(C, 2), GPIO_OUT_HIGH) /* White C1 port */ /* Unused signals */ GPIO(CHARGER_INT_L, PIN(7, 3), GPIO_INPUT) /* Interrupt not used from ISL9241, on board pull-up */ GPIO(EC_GP_SEL0_ODL, PIN(B, 6), GPIO_OUT_LOW) /* Cannot be configured as input, drive output low, don't rely on the default setting of PxDOUT register */ -GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) /* Unused power sequence signal from AP. Has an on-board pull-down. */ GPIO(EN_PP5000_USB_AG, PIN(A, 7), GPIO_INPUT | GPIO_PULL_UP) /* Unconnected power sequencing signal */ GPIO(UNUSED_GPIO41, PIN(4, 1), GPIO_INPUT | GPIO_PULL_UP) GPIO(UNUSED_GPIOF2, PIN(F, 2), GPIO_INPUT | GPIO_PULL_UP) @@ -176,4 +176,3 @@ ALTERNATE(PIN_MASK(0, BIT(0) | BIT(1) | BIT(2)), 0, MODULE_PMU, 0) /* GPIO00 = /* Temperature sensors */ ALTERNATE(PIN_MASK(4, BIT(2) | BIT(4) | BIT(5)), 0, MODULE_ADC, 0) /* TEMP_SENSOR1,2,4 */ ALTERNATE(PIN_MASK(F, BIT(1)), 0, MODULE_ADC, 0) /* TEMP_SENSOR3 */ - diff --git a/board/crota/sensors.c b/board/crota/sensors.c index 0416395f90..484bcf7a64 100644 --- a/board/crota/sensors.c +++ b/board/crota/sensors.c @@ -57,15 +57,15 @@ static struct lsm6dso_data lsm6dso_data; /* TODO(b/184779333): calibrate the orientation matrix on later board stage */ static const mat33_fp_t lid_standard_ref = { - { 0, FLOAT_TO_FP(1), 0}, { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(-1), 0}, { 0, 0, FLOAT_TO_FP(-1)} }; /* TODO(b/184779743): verify orientation matrix */ static const mat33_fp_t base_standard_ref = { - { FLOAT_TO_FP(1), 0, 0}, - { 0, FLOAT_TO_FP(-1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, FLOAT_TO_FP(1), 0}, { 0, 0, FLOAT_TO_FP(-1)} }; diff --git a/board/dojo/board.c b/board/dojo/board.c index a1d8ab5185..d8ce2cfbc5 100644 --- a/board/dojo/board.c +++ b/board/dojo/board.c @@ -88,6 +88,12 @@ static const mat33_fp_t lid_standard_ref = { { 0, 0, FLOAT_TO_FP(-1)} }; +static const mat33_fp_t bmi260_standard_ref = { + { 0, FLOAT_TO_FP(-1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + struct motion_sensor_t motion_sensors[] = { /* * Note: bmi160: supports accelerometer and gyro sensor @@ -177,7 +183,7 @@ struct motion_sensor_t bmi260_base_accel = { .drv_data = &g_bmi260_data, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = BMI260_ADDR0_FLAGS, - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &bmi260_standard_ref, .min_frequency = BMI_ACCEL_MIN_FREQ, .max_frequency = BMI_ACCEL_MAX_FREQ, .default_range = 4, /* g */ @@ -207,7 +213,7 @@ struct motion_sensor_t bmi260_base_gyro = { .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = BMI260_ADDR0_FLAGS, .default_range = 1000, /* dps */ - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &bmi260_standard_ref, .min_frequency = BMI_GYRO_MIN_FREQ, .max_frequency = BMI_GYRO_MAX_FREQ, }; diff --git a/board/dood/board.h b/board/dood/board.h index 169d8b38ff..6cede0dacc 100644 --- a/board/dood/board.h +++ b/board/dood/board.h @@ -61,6 +61,9 @@ /* SYV682 isn't connected to CC, so TCPC must provide VCONN */ #define CONFIG_USBC_PPC_SYV682X_NO_CC +/* prevent pd reset when battery soc under 2% */ +#define CONFIG_USB_PD_RESET_MIN_BATT_SOC 2 + #ifndef __ASSEMBLER__ diff --git a/board/felwinter/pwm.c b/board/felwinter/pwm.c index a35ed046cd..fea431c4ce 100644 --- a/board/felwinter/pwm.c +++ b/board/felwinter/pwm.c @@ -33,6 +33,6 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); static void board_pwm_init(void) { pwm_enable(PWM_CH_KBLIGHT, 1); - pwm_set_duty(PWM_CH_KBLIGHT, 50); + pwm_set_duty(PWM_CH_KBLIGHT, 0); } DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT); diff --git a/board/moli/board.c b/board/moli/board.c index b22b9aa50b..39438e6a9d 100644 --- a/board/moli/board.c +++ b/board/moli/board.c @@ -84,6 +84,8 @@ int board_set_active_charge_port(int port) switch (port) { case CHARGE_PORT_TYPEC0: case CHARGE_PORT_TYPEC1: + gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1); + break; case CHARGE_PORT_BARRELJACK: /* Make sure BJ adapter is sourcing power */ if (gpio_get_level(GPIO_BJ_ADP_PRESENT_ODL)) diff --git a/board/moli/board.h b/board/moli/board.h index fde3ec7286..f43e230d31 100644 --- a/board/moli/board.h +++ b/board/moli/board.h @@ -16,7 +16,7 @@ #define CONFIG_MP2964 /* Barrel Jack */ -#define DEDICATED_CHARGE_PORT 3 +#define DEDICATED_CHARGE_PORT 2 /* HDMI CEC */ #define CONFIG_CEC @@ -107,8 +107,8 @@ #define I2C_ADDR_MP2964_FLAGS 0x20 -#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x58 -#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x59 +#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x56 +#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x57 /* Enabling Thunderbolt-compatible mode */ #define CONFIG_USB_PD_TBT_COMPAT_MODE diff --git a/board/quackingstick/board.c b/board/quackingstick/board.c index 48414a2d0c..8806e8c845 100644 --- a/board/quackingstick/board.c +++ b/board/quackingstick/board.c @@ -20,7 +20,6 @@ #include "driver/tcpm/tcpci.h" #include "gpio.h" #include "hooks.h" -#include "led_common.h" #include "lid_switch.h" #include "mkbp_input_devices.h" #include "peripheral_charger.h" @@ -451,13 +450,6 @@ DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1); void board_hibernate(void) { int i; - uint8_t brightness_range[EC_LED_COLOR_COUNT] = { 0 }; - - /* - * Turn off LED. - */ - led_set_brightness(EC_LED_ID_BATTERY_LED, brightness_range); - led_auto_control(EC_LED_ID_BATTERY_LED, 0); /* * Sensors are unpowered in hibernate. Apply PD to the diff --git a/board/storo/ec.tasklist b/board/storo/ec.tasklist index d6fa610141..d54ff847e6 100644 --- a/board/storo/ec.tasklist +++ b/board/storo/ec.tasklist @@ -19,7 +19,7 @@ TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, ULTRA_TASK_STACK_SIZE) \ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, ULTRA_TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C0, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C1, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, TRENTA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, TRENTA_TASK_STACK_SIZE) \ TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, ULTRA_TASK_STACK_SIZE) \ TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, ULTRA_TASK_STACK_SIZE) diff --git a/board/vell/sensors.c b/board/vell/sensors.c index 3a4ceb2dc9..0528a62717 100644 --- a/board/vell/sensors.c +++ b/board/vell/sensors.c @@ -210,11 +210,11 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); #define THERMAL_CPU \ { \ .temp_host = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ [EC_TEMP_THRESH_HALT] = C_TO_K(95), \ }, \ .temp_host_release = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ }, \ } __maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; @@ -228,11 +228,11 @@ __maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; #define THERMAL_CHARGER \ { \ .temp_host = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ [EC_TEMP_THRESH_HALT] = C_TO_K(95), \ }, \ .temp_host_release = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ }, \ } __maybe_unused static const struct ec_thermal_config thermal_charger = diff --git a/board/volet/board.h b/board/volet/board.h index 4e957c449c..c75eeed31f 100644 --- a/board/volet/board.h +++ b/board/volet/board.h @@ -30,6 +30,7 @@ /* Chipset features */ #define CONFIG_POWER_PP5000_CONTROL +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 /* LED defines */ #define CONFIG_LED_ONOFF_STATES diff --git a/board/volet/gpio.inc b/board/volet/gpio.inc index bf5377a716..16471d0817 100644 --- a/board/volet/gpio.inc +++ b/board/volet/gpio.inc @@ -77,10 +77,10 @@ GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(6, 7), GPIO_INT_RISING, throttle_ap_c10_input_interrupt) GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) -GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) /* USB and USBC Signals */ GPIO(EN_PP5000_USBA, PIN(3, 5), GPIO_OUT_LOW) /* Enable USB-A charging - all ports */ diff --git a/board/volteer/board.h b/board/volteer/board.h index 5d820a0db0..db8dd29be1 100644 --- a/board/volteer/board.h +++ b/board/volteer/board.h @@ -34,6 +34,7 @@ /* Chipset features */ #define CONFIG_POWER_PP5000_CONTROL +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 /* LED defines */ #define CONFIG_LED_PWM diff --git a/board/volteer/gpio.inc b/board/volteer/gpio.inc index 89cfe9c5bd..45aa5b28c4 100644 --- a/board/volteer/gpio.inc +++ b/board/volteer/gpio.inc @@ -77,6 +77,7 @@ GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(6, 7), GPIO_INT_RISING, throttle_ap_c10_input_interrupt) GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) @@ -109,7 +110,6 @@ GPIO(EC_SLP_S0IX, PIN(7, 2), GPIO_INPUT | GPIO_PULL_UP) /* Unused signals */ GPIO(CHARGER_INT_L, PIN(7, 3), GPIO_INPUT) /* Interrupt not used from ISL9241, on board pull-up */ GPIO(EC_GP_SEL0_ODL, PIN(B, 6), GPIO_OUT_LOW) /* Cannot be configured as input, drive output low, don't rely on the default setting of PxDOUT register */ -GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) /* Unused power sequence signal from AP. Has an on-board pull-down. */ GPIO(EN_PP5000_USB_AG, PIN(A, 7), GPIO_INPUT | GPIO_PULL_UP) /* Unconnected power sequencing signal */ GPIO(UNUSED_GPIO41, PIN(4, 1), GPIO_INPUT | GPIO_PULL_UP) GPIO(UNUSED_GPIOF2, PIN(F, 2), GPIO_INPUT | GPIO_PULL_UP) @@ -185,4 +185,3 @@ ALTERNATE(PIN_MASK(0, BIT(0) | BIT(1) | BIT(2)), 0, MODULE_PMU, 0) /* GPIO00 = /* Temperature sensors */ ALTERNATE(PIN_MASK(4, BIT(2) | BIT(4) | BIT(5)), 0, MODULE_ADC, 0) /* TEMP_SENSOR1,2,4 */ ALTERNATE(PIN_MASK(F, BIT(1)), 0, MODULE_ADC, 0) /* TEMP_SENSOR3 */ - diff --git a/board/voxel/board.h b/board/voxel/board.h index a672cf8bc1..cd2ec0ef1f 100644 --- a/board/voxel/board.h +++ b/board/voxel/board.h @@ -30,6 +30,7 @@ /* Chipset features */ #define CONFIG_POWER_PP5000_CONTROL +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 /* LED defines */ #define CONFIG_LED_ONOFF_STATES diff --git a/board/voxel/gpio.inc b/board/voxel/gpio.inc index 5c16ff02bc..3b0c04d21d 100644 --- a/board/voxel/gpio.inc +++ b/board/voxel/gpio.inc @@ -77,10 +77,10 @@ GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(6, 7), GPIO_INT_RISING, throttle_ap_c10_input_interrupt) GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) -GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) /* USB and USBC Signals */ GPIO(EN_PP5000_USBA, PIN(3, 5), GPIO_OUT_LOW) /* Enable USB-A charging - all ports */ diff --git a/chip/host/system.c b/chip/host/system.c index 60d765deab..bf63af8bf0 100644 --- a/chip/host/system.c +++ b/chip/host/system.c @@ -133,7 +133,7 @@ test_mockable struct panic_data *panic_get_data(void) (__ram_data + RAM_DATA_SIZE - sizeof(struct panic_data)); } -test_mockable uintptr_t get_panic_data_start() +test_mockable uintptr_t get_panic_data_start(void) { return (uintptr_t) (__ram_data + RAM_DATA_SIZE - sizeof(struct panic_data)); diff --git a/common/throttle_ap.c b/common/throttle_ap.c index 6d794916ae..33e004ba7b 100644 --- a/common/throttle_ap.c +++ b/common/throttle_ap.c @@ -21,14 +21,20 @@ #define CPUTS(outstr) cputs(CC_THERMAL, outstr) #define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) +/* + * When C10 deasserts, PROCHOT may also change state when the corresponding + * power rail is turned back on. Recheck PROCHOT directly from the C10 exit + * using a shorter debounce than the PROCHOT interrupt. + */ #define PROCHOT_IN_DEBOUNCE_US (100 * MSEC) +#define C10_IN_DEBOUNCE_US (10 * MSEC) /*****************************************************************************/ /* This enforces the virtual OR of all throttling sources. */ K_MUTEX_DEFINE(throttle_mutex); static uint32_t throttle_request[NUM_THROTTLE_TYPES]; static int debounced_prochot_in; -static enum gpio_signal gpio_prochot_in = GPIO_COUNT; +static const struct prochot_cfg *prochot_cfg; void throttle_ap(enum throttle_level level, enum throttle_type type, @@ -78,17 +84,36 @@ void throttle_ap(enum throttle_level level, } +void throttle_ap_config_prochot(const struct prochot_cfg *cfg) +{ + prochot_cfg = cfg; +} + +__maybe_unused static bool prochot_is_gated_by_c10(int prochot_in) +{ +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + int c10_in = gpio_get_level(prochot_cfg->gpio_c10_in); + + if (!prochot_cfg->c10_active_high) + c10_in = !c10_in; + + if (c10_in && prochot_in) { + return true; + } +#endif + return false; +} + static void prochot_input_deferred(void) { int prochot_in; /* - * Shouldn't be possible, but better to protect against buffer - * overflow + * Validate board called throttle_ap_config_prochot(). */ - ASSERT(signal_is_gpio(gpio_prochot_in)); + ASSERT(prochot_cfg); - prochot_in = gpio_get_level(gpio_prochot_in); + prochot_in = gpio_get_level(prochot_cfg->gpio_prochot_in); if (IS_ENABLED(CONFIG_CPU_PROCHOT_ACTIVE_LOW)) prochot_in = !prochot_in; @@ -106,6 +131,14 @@ static void prochot_input_deferred(void) if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) return; + /* + * b/185810479 When the AP enters C10, the PROCHOT signal may not be + * valid. Refer to the CONFIG_CPU_PROCHOT_GATE_ON_C10 documentation + * for details. + */ + if (prochot_is_gated_by_c10(prochot_in)) + return; + debounced_prochot_in = prochot_in; if (debounced_prochot_in) { @@ -126,13 +159,6 @@ DECLARE_DEFERRED(prochot_input_deferred); void throttle_ap_prochot_input_interrupt(enum gpio_signal signal) { /* - * Save the PROCHOT signal that generated the interrupt so we don't - * rely on a specific pin name. - */ - if (gpio_prochot_in == GPIO_COUNT) - gpio_prochot_in = signal; - - /* * Trigger deferred notification of PROCHOT change so we can ignore * any pulses that are too short. */ @@ -140,6 +166,18 @@ void throttle_ap_prochot_input_interrupt(enum gpio_signal signal) PROCHOT_IN_DEBOUNCE_US); } +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 +void throttle_ap_c10_input_interrupt(enum gpio_signal signal) +{ + /* + * This interrupt is configured to fire only when the AP exits C10 + * and de-asserts the C10 signal. Recheck the PROCHOT signal in case + * another PROCHOT source is active when the AP exits C10. + */ + hook_call_deferred(&prochot_input_deferred_data, C10_IN_DEBOUNCE_US); +} +#endif + /*****************************************************************************/ /* Console commands */ #ifdef CONFIG_CMD_APTHROTTLE diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index cbf2d6bdf9..9e31edba61 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -144,6 +144,7 @@ static int validate_mode_request(struct svdm_amode_data *modep, void pd_prepare_sysjump(void) { +#ifndef CONFIG_ZEPHYR int i; /* Exit modes before sysjump so we can cleanly enter again later */ @@ -160,6 +161,7 @@ void pd_prepare_sysjump(void) task_wait_event_mask(TASK_EVENT_SYSJUMP_READY, -1); sysjump_task_waiting = TASK_ID_INVALID; } +#endif /* CONFIG_ZEPHYR */ } /* diff --git a/docs/zephyr/zephyr_pwm.md b/docs/zephyr/zephyr_pwm.md index 48221dd2a6..89be759d4a 100644 --- a/docs/zephyr/zephyr_pwm.md +++ b/docs/zephyr/zephyr_pwm.md @@ -28,8 +28,7 @@ For example for a keyboard backlight device: ``` kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; - frequency = <2400>; + pwms = <&pwm3 0 PWM_HZ(2400) PWM_POLARITY_NORMAL>; }; ``` @@ -110,8 +109,7 @@ channel per PWM on NPCX), normal polarity: / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; - frequency = <2400>; + pwms = <&pwm3 0 PWM_HZ(2400) PWM_POLARITY_NORMAL>; }; }; diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index c1e4f203fd..011a83de27 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -490,6 +490,23 @@ static enum ec_error_list isl923x_post_init(int chgnum) return EC_SUCCESS; } +static enum ec_error_list isl923x_set_hw_ramp(int chgnum, int enable) +{ + int rv, reg; + + rv = raw_read16(chgnum, ISL923X_REG_CONTROL0, ®); + if (rv) + return rv; + + /* HW ramp is controlled by input voltage regulation reference bits */ + if (enable) + reg &= ~ISL923X_C0_DISABLE_VREG; + else + reg |= ISL923X_C0_DISABLE_VREG; + + return raw_write16(chgnum, ISL923X_REG_CONTROL0, reg); +} + int isl923x_set_ac_prochot(int chgnum, uint16_t ma) { int rv; @@ -650,13 +667,8 @@ static void isl923x_init(int chgnum) goto init_fail; } } else { - if (raw_read16(chgnum, ISL923X_REG_CONTROL0, ®)) - goto init_fail; - /* Disable voltage regulation loop to disable charge ramp */ - reg |= ISL923X_C0_DISABLE_VREG; - - if (raw_write16(chgnum, ISL923X_REG_CONTROL0, reg)) + if (isl923x_set_hw_ramp(chgnum, 0)) goto init_fail; } @@ -979,23 +991,6 @@ enum ec_error_list isl9238c_resume(int chgnum) /* Hardware current ramping */ #ifdef CONFIG_CHARGE_RAMP_HW -static enum ec_error_list isl923x_set_hw_ramp(int chgnum, int enable) -{ - int rv, reg; - - rv = raw_read16(chgnum, ISL923X_REG_CONTROL0, ®); - if (rv) - return rv; - - /* HW ramp is controlled by input voltage regulation reference bits */ - if (enable) - reg &= ~ISL923X_C0_DISABLE_VREG; - else - reg |= ISL923X_C0_DISABLE_VREG; - - return raw_write16(chgnum, ISL923X_REG_CONTROL0, reg); -} - static int isl923x_ramp_is_stable(int chgnum) { /* diff --git a/driver/ppc/rt1718s.c b/driver/ppc/rt1718s.c index 5f6c73e13c..a7a378d934 100644 --- a/driver/ppc/rt1718s.c +++ b/driver/ppc/rt1718s.c @@ -10,6 +10,7 @@ #include "console.h" #include "driver/ppc/rt1718s.h" #include "driver/tcpm/tcpci.h" +#include "usb_pe_sm.h" #include "usbc_ppc.h" #include "util.h" diff --git a/driver/ppc/rt1739.c b/driver/ppc/rt1739.c index a99ec91b5c..ec5966b07c 100644 --- a/driver/ppc/rt1739.c +++ b/driver/ppc/rt1739.c @@ -161,11 +161,16 @@ static int rt1739_set_vconn(int port, int enable) } #endif +static int rt1739_get_device_id(int port, int *device_id) +{ + return read_reg(port, RT1739_REG_DEVICE_ID0, device_id); +} + static int rt1739_workaround(int port) { int device_id; - RETURN_ERROR(read_reg(port, RT1739_REG_DEVICE_ID0, &device_id)); + RETURN_ERROR(rt1739_get_device_id(port, &device_id)); switch (device_id) { case RT1739_DEVICE_ID_ES1: @@ -183,6 +188,7 @@ static int rt1739_workaround(int port) case RT1739_DEVICE_ID_ES2: CPRINTS("RT1739 ES2"); + /* Disable SWENB test output */ /* enter hidden mode */ RETURN_ERROR(write_reg(port, 0xF1, 0x62)); RETURN_ERROR(write_reg(port, 0xF0, 0x86)); @@ -191,6 +197,25 @@ static int rt1739_workaround(int port) /* leave hidden mode */ RETURN_ERROR(write_reg(port, 0xF1, 0)); RETURN_ERROR(write_reg(port, 0xF0, 0)); + + /* Set VBUS to VIN_LV leakage remove setting */ + RETURN_ERROR(write_reg(port, RT1739_VBUS_FAULT_DIS, 0)); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_CTRL1, 0)); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_SWITCH_CTRL, 0)); + msleep(5); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_SWITCH_CTRL, + RT1739_LV_SRC_EN)); + msleep(5); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_SWITCH_CTRL, 0)); + msleep(5); + RETURN_ERROR(write_reg(port, RT1739_VBUS_FAULT_DIS, + RT1739_OVP_DISVBUS_EN | + RT1739_UVLO_DISVBUS_EN | + RT1739_RCP_DISVBUS_EN | + RT1739_SCP_DISVBUS_EN)); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_CTRL1, + RT1739_HVLV_SCP_EN | + RT1739_HVLV_OCRC_EN)); break; default: @@ -231,6 +256,8 @@ static int rt1739_set_frs_enable(int port, int enable) static int rt1739_init(int port) { + int device_id, oc_setting; + atomic_clear(&flags[port]); RETURN_ERROR(write_reg(port, RT1739_REG_SW_RESET, RT1739_SW_RESET)); @@ -257,10 +284,15 @@ static int rt1739_init(int port) RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_OV_SETTING, (RT1739_OVP_SEL_23_0V << RT1739_VBUS_OVP_SEL_SHIFT) | (RT1739_OVP_SEL_23_0V << RT1739_VIN_HV_OVP_SEL_SHIFT))); - /* VBUS OCP -> 3.3A */ - RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_OC_SETTING, - (RT1739_LV_SRC_OCP_SEL_3_3A << RT1739_LV_SRC_OCP_SEL_SHIFT) | - (RT1739_HV_SINK_OCP_SEL_3_3A << RT1739_HV_SINK_OCP_SEL_SHIFT))); + /* VBUS OCP -> 3.3A (or 5.5A for ES2 HV Sink) */ + RETURN_ERROR(rt1739_get_device_id(port, &device_id)); + if (device_id == RT1739_DEVICE_ID_ES2) + oc_setting = (RT1739_LV_SRC_OCP_SEL_3_3A | + RT1739_HV_SINK_OCP_SEL_5_5A); + else + oc_setting = (RT1739_LV_SRC_OCP_SEL_3_3A | + RT1739_HV_SINK_OCP_SEL_3_3A); + RETURN_ERROR(write_reg(port, RT1739_REG_VBUS_OC_SETTING, oc_setting)); return EC_SUCCESS; } diff --git a/driver/ppc/rt1739.h b/driver/ppc/rt1739.h index ed16942ec1..2f9b196011 100644 --- a/driver/ppc/rt1739.h +++ b/driver/ppc/rt1739.h @@ -47,6 +47,10 @@ #define RT1739_HV_SRC_EN BIT(1) #define RT1739_HV_SNK_EN BIT(0) +#define RT1739_REG_VBUS_CTRL1 0x23 +#define RT1739_HVLV_SCP_EN BIT(1) +#define RT1739_HVLV_OCRC_EN BIT(0) + #define RT1739_REG_VBUS_OV_SETTING 0x24 #define RT1739_VBUS_OVP_SEL_SHIFT 0 @@ -61,16 +65,17 @@ #define RT1739_REG_VBUS_OC_SETTING 0x25 -#define RT1739_LV_SRC_OCP_SEL_SHIFT 4 -#define RT1739_LV_SRC_OCP_SEL_1_25A 0 -#define RT1739_LV_SRC_OCP_SEL_1_75A 1 -#define RT1739_LV_SRC_OCP_SEL_2_25A 2 -#define RT1739_LV_SRC_OCP_SEL_3_3A 3 - -#define RT1739_HV_SINK_OCP_SEL_SHIFT 0 -#define RT1739_HV_SINK_OCP_SEL_1_25A 0 -#define RT1739_HV_SINK_OCP_SEL_1_75A 1 -#define RT1739_HV_SINK_OCP_SEL_3_3A 2 +#define RT1739_LV_SRC_OCP_SHIFT 4 +#define RT1739_LV_SRC_OCP_SEL_1_25A (0 << RT1739_LV_SRC_OCP_SHIFT) +#define RT1739_LV_SRC_OCP_SEL_1_75A (1 << RT1739_LV_SRC_OCP_SHIFT) +#define RT1739_LV_SRC_OCP_SEL_2_25A (2 << RT1739_LV_SRC_OCP_SHIFT) +#define RT1739_LV_SRC_OCP_SEL_3_3A (3 << RT1739_LV_SRC_OCP_SHIFT) + +#define RT1739_HV_SINK_OCP_SHIFT 0 +#define RT1739_HV_SINK_OCP_SEL_1_25A (0 << RT1739_HV_SINK_OCP_SHIFT) +#define RT1739_HV_SINK_OCP_SEL_1_75A (1 << RT1739_HV_SINK_OCP_SHIFT) +#define RT1739_HV_SINK_OCP_SEL_3_3A (2 << RT1739_HV_SINK_OCP_SHIFT) +#define RT1739_HV_SINK_OCP_SEL_5_5A (3 << RT1739_HV_SINK_OCP_SHIFT) #define RT1739_VBUS_FAULT_DIS 0x26 #define RT1739_OVP_DISVBUS_EN BIT(6) diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c index 76177af886..d025191c6d 100644 --- a/driver/tcpm/anx7447.c +++ b/driver/tcpm/anx7447.c @@ -19,16 +19,8 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define vsafe5v_min (3800/25) -#define vsafe0v_max (800/25) -/* - * These interface are workable while ADC is enabled, before - * calling them should make sure ec driver finished chip initilization. - */ -#define is_equal_greater_safe5v(port) \ - (((anx7447_get_vbus_voltage(port))) > vsafe5v_min) -#define is_equal_greater_safe0v(port) \ - (((anx7447_get_vbus_voltage(port))) > vsafe0v_max) +#define VSAFE5V_MIN 3800 +#define VSAFE0V_MAX 800 struct anx_state { uint16_t i2c_addr_flags; @@ -403,14 +395,44 @@ static int anx7447_release(int port) return EC_SUCCESS; } +static int anx7447_get_vbus_voltage(int port, int *vbus) +{ + int val; + int error; + + /* + * b:214893572#comment33: This function is partially copied from + * tcpci_get_vbus_voltage because ANX7447 dev_cap_1 reports VBUS_MEASURE + * unsupported, however, it actually does. So we have an identical + * implementation but just skip the dev_cap_1 check. + */ + + error = tcpc_read16(port, TCPC_REG_VBUS_VOLTAGE, &val); + if (error) + return error; + + *vbus = TCPC_REG_VBUS_VOLTAGE_VBUS(val); + return EC_SUCCESS; +} + #ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -static int anx7447_get_vbus_voltage(int port) +/* + * This interface are workable while ADC is enabled, before + * calling them should make sure ec driver finished chip initialization. + */ +static bool is_equal_greater_safe0v(int port) { - int vbus_volt = 0; + int vbus; + int error; + + error = anx7447_get_vbus_voltage(port, &vbus); + if (error) + return true; - tcpc_read16(port, TCPC_REG_VBUS_VOLTAGE, &vbus_volt); + if (vbus > VSAFE0V_MAX) + return true; - return vbus_volt; + return false; } int anx7447_set_power_supply_ready(int port) @@ -839,6 +861,7 @@ const struct tcpm_drv anx7447_tcpm_drv = { #ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC .check_vbus_level = &tcpci_tcpm_check_vbus_level, #endif + .get_vbus_voltage = &anx7447_get_vbus_voltage, .select_rp_value = &tcpci_tcpm_select_rp_value, .set_cc = &anx7447_set_cc, .set_polarity = &anx7447_set_polarity, diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c index 7bed654132..e1d4ad5d5c 100644 --- a/driver/tcpm/it8xxx2.c +++ b/driver/tcpm/it8xxx2.c @@ -204,6 +204,7 @@ static enum tcpc_transmit_complete it8xxx2_tx_data(enum usbpd_port port, int r; uint32_t evt; uint8_t length = PD_HEADER_CNT(header); + uint8_t retry_count = pd_get_retry_count(port, type); /* Set message header */ IT83XX_USBPD_MHSR0(port) = (uint8_t)header; @@ -216,6 +217,10 @@ static enum tcpc_transmit_complete it8xxx2_tx_data(enum usbpd_port port, IT83XX_USBPD_MTSR0(port) = (IT83XX_USBPD_MTSR0(port) & ~0x7) | (type & 0x7); + /* According PD version set HW auto retry count */ + IT83XX_USBPD_PDCSR0(port) = (IT83XX_USBPD_PDCSR0(port) & ~0xC0) | + (retry_count << 6); + /* Limited by PD_HEADER_CNT() */ ASSERT(length <= 0x7); @@ -223,7 +228,7 @@ static enum tcpc_transmit_complete it8xxx2_tx_data(enum usbpd_port port, /* Set data */ memcpy((uint32_t *)&IT83XX_USBPD_TDO(port), buf, length * 4); - for (r = 0; r <= CONFIG_PD_RETRY_COUNT; r++) { + for (r = 0; r <= retry_count; r++) { /* Start Tx */ USBPD_KICK_TX_START(port); evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE, @@ -266,7 +271,7 @@ static enum tcpc_transmit_complete it8xxx2_tx_data(enum usbpd_port port, break; } - if (r > CONFIG_PD_RETRY_COUNT) + if (r > retry_count) return TCPC_TX_COMPLETE_DISCARDED; return TCPC_TX_COMPLETE_SUCCESS; @@ -765,9 +770,6 @@ static void it8xxx2_init(enum usbpd_port port, int role) /* Reset and disable HW auto generate message header */ IT83XX_USBPD_PDMSR(port) &= ~USBPD_REG_MASK_DISABLE_AUTO_GEN_TX_HEADER; USBPD_SW_RESET(port); - /* According PD version set HW auto retry count */ - IT83XX_USBPD_PDCSR0(port) = (IT83XX_USBPD_PDCSR0(port) & ~0xC0) | - (CONFIG_PD_RETRY_COUNT << 6); /* Disable Rx decode */ it8xxx2_tcpm_set_rx_enable(port, 0); if (IS_ENABLED(CONFIG_USB_PD_TCPMV1)) { diff --git a/driver/tcpm/rt1718s.c b/driver/tcpm/rt1718s.c index 4abc2b06b8..cd32f85da4 100644 --- a/driver/tcpm/rt1718s.c +++ b/driver/tcpm/rt1718s.c @@ -12,18 +12,27 @@ #include "driver/tcpm/tcpci.h" #include "driver/tcpm/tcpm.h" #include "gpio.h" +#include "hooks.h" #include "stdint.h" #include "system.h" #include "task.h" #include "timer.h" #include "usb_mux.h" #include "usb_pd.h" +#include "usb_pe_sm.h" #include "util.h" #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define RT1718S_SW_RESET_DELAY_MS 2 +#define RT1718S_SW_RESET_DELAY_MS 2 +/* Time for delay deasserting EN_FRS after FRS VBUS drop. */ +#define RT1718S_FRS_DIS_DELAY (5 * MSEC) + +#define FLAG_FRS_ENABLED BIT(0) +#define FLAG_FRS_RX_SIGNALLED BIT(1) +#define FLAG_FRS_VBUS_VALID_FALL BIT(2) +static atomic_t frs_flag[CONFIG_USB_PD_PORT_MAX_COUNT]; /* i2c_write function which won't wake TCPC from low power mode. */ static int rt1718s_write(int port, int reg, int val, int len) @@ -229,6 +238,10 @@ static int rt1718s_init(int port) RT1718S_RT2_VBUS_VOL_CTRL_VOL_SEL, RT1718S_VBUS_VOL_TO_REG(20))); + /* Set VCONN_OCP_SEL to 400mA */ + RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_VCONN_CONTROL_3, + RT1718S_VCONN_CONTROL_3_VCONN_OCP_SEL, 0x7F)); + /* Disable FOD function */ RETURN_ERROR(rt1718s_update_bits8(port, 0xCF, 0x40, 0x00)); @@ -253,10 +266,16 @@ static int rt1718s_init(int port) TCPC_REG_ALERT_MASK_VENDOR_DEF, MASK_SET)); - if (IS_ENABLED(CONFIG_USB_PD_FRS)) - /* Set Rx frs unmasked */ - RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_RT_MASK1, - RT1718S_RT_MASK1_M_RX_FRS, 0xFF)); + if (IS_ENABLED(CONFIG_USB_PD_FRS)) { + memset(frs_flag, 0, + sizeof(atomic_t) * CONFIG_USB_PD_PORT_MAX_COUNT); + /* Set Rx frs and valid vbus fall unmasked */ + RETURN_ERROR(rt1718s_update_bits8( + port, RT1718S_RT_MASK1, + RT1718S_RT_MASK1_M_RX_FRS | + RT1718S_RT_MASK1_M_VBUS_FRS_LOW, + 0xFF)); + } RETURN_ERROR(board_rt1718s_init(port)); @@ -359,6 +378,23 @@ static void rt1718s_bc12_usb_charger_task(const int port) } } +static void frs_gpio_disable_deferred(void) +{ + int i; + + for (i = 0; i < board_get_usb_pd_port_count(); ++i) { + if (frs_flag[i] & FLAG_FRS_VBUS_VALID_FALL) { + atomic_clear_bits(&frs_flag[i], + FLAG_FRS_RX_SIGNALLED | + FLAG_FRS_VBUS_VALID_FALL); + /* If the FRS gets enabled again, do not disable it. */ + if (!(frs_flag[i] & FLAG_FRS_ENABLED)) + board_rt1718s_set_frs_enable(i, 0); + } + } +} +DECLARE_DEFERRED(frs_gpio_disable_deferred); + void rt1718s_vendor_defined_alert(int port) { int rv, value; @@ -373,12 +409,68 @@ void rt1718s_vendor_defined_alert(int port) if (rv) return; - if ((int1 & RT1718S_RT_INT1_INT_RX_FRS)) { - pd_got_frs_signal(port); + if ((int1 & RT1718S_RT_INT1_INT_RX_FRS) && + frs_flag[port] & FLAG_FRS_ENABLED) { + /* + * 1. Sometimes we get Rx signalled even if the + * FRS is disabled, so filter it. + * 2. Only call pd_got_frs_signal when this is the first + * Rx interrupt for this FRS swap, and the FRS is + * enabled. The Rx interrupt may re-send when the + * sink voltage is 5V, and this will make us re-entry + * the FRS states. + * 3. When a FRS hub detached, RT1718S will + * raise FRS RX alert as well. In this case, + * we are unable to audit the errors in time, + * we will still enter the FRS AMS, but it will + * fail eventually, and back to CC open state. + */ + if (!(frs_flag[port] & FLAG_FRS_RX_SIGNALLED)) { + atomic_or(&frs_flag[port], + FLAG_FRS_RX_SIGNALLED); + /* notify TCPM we got FRS signal */ + pd_got_frs_signal(port); + } + } + + if ((int1 & RT1718S_RT_INT1_INT_VBUS_FRS_LOW)) { + /* + * Only process if have had rx signalled. + * VBUS_FRS_LOW alert could be raised multiple times + * if VBUS 5V is glitched. + */ + if ((frs_flag[port] & FLAG_FRS_RX_SIGNALLED) && + !(frs_flag[port] & FLAG_FRS_VBUS_VALID_FALL)) { + atomic_or(&frs_flag[port], + FLAG_FRS_VBUS_VALID_FALL); + /* + * b/223086905:comment8&comment17 + * We deferred the FRS disable + * (called to rt1718s_set_frs_enable()), now we + * can disable it after the VBUS fell. + */ + rt1718s_set_frs_enable(port, 0); + /* + * b/228422539:comment4 + * PPC HL5099 (pin-compatible to NX20P3483) + * suggested FRS gpio should be disabled after + * the SRC gpio enabled for 5ms to prevent the + * PPC from stopping sourcing the VBUS. + * Thought this is a workaround for HL5099, but + * it shouldn't affect other PPC chips since + * the DUT started sourcing the partner already. + */ + hook_call_deferred( + &frs_gpio_disable_deferred_data, + RT1718S_FRS_DIS_DELAY); + } + } + /* ignore other interrupts for faster frs handling */ + if (int1 & (RT1718S_RT_INT1_INT_RX_FRS | + RT1718S_RT_INT1_INT_VBUS_FRS_LOW)) { tcpc_write16(port, TCPC_REG_ALERT, - TCPC_REG_ALERT_VENDOR_DEF); - /* ignore other interrupts for faster frs handling */ + TCPC_REG_ALERT_VENDOR_DEF); return; } } @@ -519,6 +611,12 @@ out: } #ifdef CONFIG_USB_PD_FRS + +__overridable int board_rt1718s_set_frs_enable(int port, int enable) +{ + return EC_SUCCESS; +} + int rt1718s_set_frs_enable(int port, int enable) { /* @@ -528,15 +626,38 @@ int rt1718s_set_frs_enable(int port, int enable) int frs_ctrl2 = 0x10, vbus_ctrl_en = 0x3F; if (enable) { + atomic_or(&frs_flag[port], FLAG_FRS_ENABLED); frs_ctrl2 |= RT1718S_FRS_CTRL2_RX_FRS_EN; frs_ctrl2 |= RT1718S_FRS_CTRL2_VBUS_FRS_EN; vbus_ctrl_en |= RT1718S_VBUS_CTRL_EN_GPIO2_VBUS_PATH_EN; vbus_ctrl_en |= RT1718S_VBUS_CTRL_EN_GPIO1_VBUS_PATH_EN; + } else { + atomic_clear_bits(&frs_flag[port], FLAG_FRS_ENABLED); + if (FLAG_FRS_RX_SIGNALLED == + (frs_flag[port] & + (FLAG_FRS_RX_SIGNALLED | FLAG_FRS_VBUS_VALID_FALL))) { + /* + * Skip disable if we had only FRS_RX_SIGNALLED, and + * deferred the FRS register disable process in + * rt1718s_vendor_defined_alert. + */ + return EC_SUCCESS; + } } RETURN_ERROR(rt1718s_write8(port, RT1718S_FRS_CTRL2, frs_ctrl2)); RETURN_ERROR(rt1718s_write8(port, RT1718S_VBUS_CTRL_EN, vbus_ctrl_en)); + + /* + * b/223086905#comment13, b/228422539:comment4 + * If this function gets called when FRS RX signalled, then + * we'll deferred the GPIO disabled until the VBUS valid drop. So + * don't disable it here. + */ + if (enable || !(frs_flag[port] & FLAG_FRS_RX_SIGNALLED)) + RETURN_ERROR(board_rt1718s_set_frs_enable(port, enable)); + return EC_SUCCESS; } #endif diff --git a/driver/tcpm/rt1718s.h b/driver/tcpm/rt1718s.h index 2df05bcb2e..e108c41db2 100644 --- a/driver/tcpm/rt1718s.h +++ b/driver/tcpm/rt1718s.h @@ -37,6 +37,7 @@ #define RT1718S_VCONN_CONTROL_2_OVP_EN_CC1 BIT(7) #define RT1718S_VCONN_CONTROL_2_OVP_EN_CC2 BIT(6) #define RT1718S_VCONN_CONTROL_3 0x8C +#define RT1718S_VCONN_CONTROL_3_VCONN_OCP_SEL GENMASK(7, 5) #define RT1718S_VCONN_CONTROL_3_VCONN_OVP_DEG BIT(1) #define RT1718S_SYS_CTRL2 0x90 @@ -255,6 +256,15 @@ int rt1718s_set_frs_enable(int port, int enable); /** + * Board override for fast role swap. + * + * @param port USB-C port + * @param enable enable/disable FRS + * @return EC_SUCCESS if success, EC_ERROR_UNKNOWN otherwise. + */ +__override_proto int board_rt1718s_set_frs_enable(int port, int enable); + +/** * Software reset RT1718S * * @param port USB-C port diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 735ababffe..42e7bb357a 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -1334,7 +1334,6 @@ void tcpci_tcpc_alert(int port) int tcpci_get_vbus_voltage(int port, int *vbus) { int error, val; - int scale, measure; if (!(dev_cap_1[port] & TCPC_REG_DEV_CAP_1_VBUS_MEASURE_ALARM_CAPABLE)) return EC_ERROR_UNIMPLEMENTED; @@ -1343,16 +1342,7 @@ int tcpci_get_vbus_voltage(int port, int *vbus) if (error) return error; - /* - * 00: the measurement is not scaled - * 01: the measurement is divided by 2 - * 10: the measurement is divided by 4 - * 11: reserved - */ - scale = (val & TCPC_REG_VBUS_VOLTAGE_SCALE_FACTOR) >> 9; - measure = val & TCPC_REG_VBUS_VOLTAGE_MEASUREMENT; - - *vbus = (1 << scale) * measure * TCPC_REG_VBUS_VOLTAGE_LSB; + *vbus = TCPC_REG_VBUS_VOLTAGE_VBUS(val); return EC_SUCCESS; } diff --git a/include/config.h b/include/config.h index 8ba8a4de0c..f7a507655b 100644 --- a/include/config.h +++ b/include/config.h @@ -3623,6 +3623,14 @@ */ #undef CONFIG_CPU_PROCHOT_ACTIVE_LOW +/* + * When the AP enters C10, the power rails VCCIO, VCCSTG, and VCCPLL_OC may be + * turned off by the board. If the PROCHOT# signal is pulled up by any of + * these rails, PROCHOT cannot be relied upon while C10 is active. + * Enable this option to gate PROCHOT detection when C10 is active. + */ +#undef CONFIG_CPU_PROCHOT_GATE_ON_C10 + /* Support PS/2 interface */ #undef CONFIG_PS2 diff --git a/include/driver/tcpm/tcpci.h b/include/driver/tcpm/tcpci.h index 04016d0f06..6eebb074b0 100644 --- a/include/driver/tcpm/tcpci.h +++ b/include/driver/tcpm/tcpci.h @@ -281,6 +281,20 @@ #define TCPC_REG_VBUS_VOLTAGE_SCALE_FACTOR GENMASK(11, 10) #define TCPC_REG_VBUS_VOLTAGE_LSB 25 +/* + * 00: the measurement is not scaled + * 01: the measurement is divided by 2 + * 10: the measurement is divided by 4 + * 11: reserved + */ +#define TCPC_REG_VBUS_VOLTAGE_SCALE(x) \ + (1 << (((x) & TCPC_REG_VBUS_VOLTAGE_SCALE_FACTOR) >> 9)) +#define TCPC_REG_VBUS_VOLTAGE_MEASURE(x) \ + ((x) & TCPC_REG_VBUS_VOLTAGE_MEASUREMENT) +#define TCPC_REG_VBUS_VOLTAGE_VBUS(x) \ + (TCPC_REG_VBUS_VOLTAGE_SCALE(x) * TCPC_REG_VBUS_VOLTAGE_MEASURE(x) * \ + TCPC_REG_VBUS_VOLTAGE_LSB) + #define TCPC_REG_VBUS_SINK_DISCONNECT_THRESH 0x72 #define TCPC_REG_VBUS_SINK_DISCONNECT_THRESH_DEFAULT 0x008C /* 3.5 V */ diff --git a/include/led_pwm.h b/include/led_pwm.h index 7f286130e7..cb5ea70f14 100644 --- a/include/led_pwm.h +++ b/include/led_pwm.h @@ -20,7 +20,7 @@ struct pwm_led_dt_channel { const struct device *dev; uint32_t channel; pwm_flags_t flags; - uint32_t period_us; + uint32_t period_ns; }; struct pwm_led { diff --git a/include/throttle_ap.h b/include/throttle_ap.h index fbfa36aed3..09669d70b1 100644 --- a/include/throttle_ap.h +++ b/include/throttle_ap.h @@ -35,6 +35,19 @@ enum throttle_sources { }; /** + * PROCHOT detection GPIOs. PROCHOT in assumed to be active high unless + * CONFIG_CPU_PROCHOT_ACTIVE_LOW is enabled. + * C10 input polarity is explicitly specified in the struct below. + */ +struct prochot_cfg { + enum gpio_signal gpio_prochot_in; +#ifdef CONFIG_CPU_PROCHOT_GATE_ON_C10 + enum gpio_signal gpio_c10_in; + bool c10_active_high; +#endif +}; + +/** * Enable/disable CPU throttling. * * This is a virtual "OR" operation. Any caller can enable CPU throttling of @@ -53,6 +66,14 @@ void throttle_ap(enum throttle_level level, enum throttle_sources source); /** + * Configure the GPIOs used to monitor the PROCHOT signal. + * + * @param cfg GPIO configuration for the PROCHOT and optional C10 + * signals. + */ +void throttle_ap_config_prochot(const struct prochot_cfg *cfg); + +/** * Interrupt handler to monitor PROCHOT input to the EC. The PROCHOT signal * can be asserted by the AP or by other devices on the board, such as chargers * and voltage regulators. @@ -65,6 +86,18 @@ void throttle_ap(enum throttle_level level, */ void throttle_ap_prochot_input_interrupt(enum gpio_signal signal); +/** + * Interrupt handler to monitor the C10 input to the EC. The C10 signal + * can be asserted by the AP when entering an idle state. This interrupt + * is configured for the edge indicating C10 is de-asserting (GPIO_INT_RISING + * if the signal is active low, GPIO_INT_FALLING for an active high signal). + * + * The board initialization is responsible for enabling the interrupt. + * + * @param signal GPIO signal connected to C10 input. + */ +void throttle_ap_c10_input_interrupt(enum gpio_signal signal); + #else static inline void throttle_ap(enum throttle_level level, enum throttle_type type, diff --git a/test/kasa.c b/test/kasa.c index 3ecd32a556..6dea8a20e7 100644 --- a/test/kasa.c +++ b/test/kasa.c @@ -71,3 +71,11 @@ void run_test(int argc, char **argv) test_print_result(); } + +/* Mock out mkbp_send_event. Rarely, but occasionally, mkbp_send_event gets + * called and the coverage is thrown off. + */ +int mkbp_send_event(uint8_t event_type) +{ + return 1; +} diff --git a/util/config_allowed.txt b/util/config_allowed.txt index 38af58a947..d8e6959794 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -338,6 +338,7 @@ CONFIG_CONSOLE_INPUT_LINE_SIZE CONFIG_CONSOLE_UART CONFIG_CONSOLE_VERBOSE CONFIG_CPU_PROCHOT_ACTIVE_LOW +CONFIG_CPU_PROCHOT_GATE_ON_C10 CONFIG_CRC8 CONFIG_CROS_EC_RO_MEM_SIZE CONFIG_CROS_EC_RW_MEM_SIZE @@ -477,7 +478,6 @@ CONFIG_HID_HECI CONFIG_HOOK_DEBUG CONFIG_HOSTCMD_ALIGNED CONFIG_HOSTCMD_AP_SET_SKUID -CONFIG_HOSTCMD_BATTERY_V2 CONFIG_HOSTCMD_BUTTON CONFIG_HOSTCMD_DEBUG_MODE CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP diff --git a/util/powerd_lock.c b/util/powerd_lock.c index df34d03c6c..524b456df2 100644 --- a/util/powerd_lock.c +++ b/util/powerd_lock.c @@ -37,7 +37,7 @@ static const char lock_file_path[] = "/run/lock/power_override/battery_tool.lock"; -int disable_power_management() +int disable_power_management(void) { FILE *lock_file; int rc = 0; @@ -53,7 +53,7 @@ int disable_power_management() return rc; } -int restore_power_management() +int restore_power_management(void) { int result = 0; result = unlink(lock_file_path); diff --git a/zephyr/Kconfig.battery b/zephyr/Kconfig.battery index 4ffd7dc921..d069faf57e 100644 --- a/zephyr/Kconfig.battery +++ b/zephyr/Kconfig.battery @@ -229,6 +229,14 @@ config PLATFORM_EC_BATTERY_COUNT PLATFORM_EC_BATTERY_V2 is enabled. Note this is different from BATTERY_TYPE_COUNT. +config PLATFORM_EC_HOSTCMD_BATTERY_V2 + bool "Enable host command battery API v2" + default y + help + Include host commands to fetch battery information from + ec_response_battery_static/dynamic_info structures, only make sense + when PLATFORM_EC_BATTERY_V2 is enabled. + endif # PLATFORM_EC_BATTERY_V2 config PLATFORM_EC_BATTERY_TYPE_NO_AUTO_DETECT diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq index a99453f5a7..cee5be53a4 100644 --- a/zephyr/Kconfig.powerseq +++ b/zephyr/Kconfig.powerseq @@ -104,6 +104,15 @@ config PLATFORM_EC_POWERSEQ_CPU_PROCHOT_ACTIVE_LOW If CPU_PROCHOT should be treated as active-low, enable this configuration option. +config PLATFORM_EC_POWERSEQ_CPU_PROCHOT_GATE_ON_C10 + bool "Gate PROCHOT detection based on the AP C10 state" + default y if PLATFORM_EC_POWERSEQ_CPU_PROCHOT_ACTIVE_LOW + help + When the AP enters C10, the power rails VCCIO, VCCSTG, and VCCPLL_OC + may be turned off by the board. If the PROCHOT# signal is pulled up + by any of these rails, PROCHOT is not valid while the AP is in C10, + Enable this option to gate PROCHOT detection when C10 is active. + config PLATFORM_EC_POWERSEQ_RTC_RESET bool "Board has an RTC reset" help diff --git a/zephyr/boards/arm/mec1727/Kconfig.board b/zephyr/boards/arm/mec1727/Kconfig.board new file mode 100644 index 0000000000..66a3993185 --- /dev/null +++ b/zephyr/boards/arm/mec1727/Kconfig.board @@ -0,0 +1,15 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# "BOARD" below refers to a Zephyr board, which does not have a 1:1 +# mapping with the Chrome OS concept of a board. By Zephyr's +# conventions, we'll still call it "BOARD_*" to make this more +# applicable to be upstreamed, even though this code is shared by all +# projects using the MEC172x EVB board. +config BOARD_MEC1727 + bool "MEC1727 Zephyr Board" + depends on SOC_MEC172X_NSZ + # MCHP XEC doesn't actually have enough ram for coverage, but this will + # allow generating initial 0 line coverage. + select HAS_COVERAGE_SUPPORT diff --git a/zephyr/boards/arm/mec1727/Kconfig.defconfig b/zephyr/boards/arm/mec1727/Kconfig.defconfig new file mode 100644 index 0000000000..0708bda48c --- /dev/null +++ b/zephyr/boards/arm/mec1727/Kconfig.defconfig @@ -0,0 +1,35 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +if BOARD_MEC1727 + +config BOARD + default "mec1727" + +# Zephyr internal stack sizes + +config IDLE_STACK_SIZE + default 400 + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 1024 + +# Chromium EC stack sizes + +config TASK_CHARGER_STACK_SIZE + default 1056 + +config TASK_KEYSCAN_STACK_SIZE + default 1024 + +config TASK_PD_STACK_SIZE + default 1184 + +config TASK_PD_INT_STACK_SIZE + default 1024 + +config TASK_USB_CHG_STACK_SIZE + default 1024 + +endif # BOARD_MEC1727 diff --git a/zephyr/boards/arm/mec1727/board.cmake b/zephyr/boards/arm/mec1727/board.cmake new file mode 100644 index 0000000000..b67f47c819 --- /dev/null +++ b/zephyr/boards/arm/mec1727/board.cmake @@ -0,0 +1,5 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set(MCHP_IMAGE_FILE ${PROJECT_BINARY_DIR}/zephyr.mchp.bin) diff --git a/zephyr/boards/arm/mec1727/mec1727.dts b/zephyr/boards/arm/mec1727/mec1727.dts new file mode 100644 index 0000000000..c88e61b692 --- /dev/null +++ b/zephyr/boards/arm/mec1727/mec1727.dts @@ -0,0 +1,235 @@ +/* Copyright 2022 Microchip Technology Inc. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/dts-v1/; + +#include <cros/microchip/mec1727.dtsi> +#include <cros/thermistor/thermistor.dtsi> +#include <dt-bindings/gpio_defines.h> +#include <microchip/mec172xnsz.dtsi> +#include <microchip/mec172x/mec172xnsz-pinctrl.dtsi> + +/ { + model = "MEC1727"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,flash-controller = &int_flash; + }; + + pinmux: pinmux { + compatible = "microchip,xec-pinmux"; + + pinmux_000_036: pinmux-0 { + ph-reg = <&gpio_000_036>; + port-num = <0>; + }; + pinmux_040_076: pinmux-1 { + ph-reg = <&gpio_040_076>; + port-num = <1>; + }; + pinmux_100_136: pinmux-2 { + ph-reg = <&gpio_100_136>; + port-num = <2>; + }; + pinmux_140_176: pinmux-3 { + ph-reg = <&gpio_140_176>; + port-num = <3>; + }; + pinmux_200_236: pinmux-4 { + ph-reg = <&gpio_200_236>; + port-num = <4>; + }; + pinmux_240_276: pinmux-5 { + ph-reg = <&gpio_240_276>; + port-num = <5>; + }; + }; + + named-pwms { + compatible = "named-pwms"; + }; + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ddr_soc: ddr_soc { + label = "TEMP_DDR_SOC"; + enum-name = "ADC_TEMP_SENSOR_1_DDR_SOC"; + io-channels = <&adc0 5>; + }; + adc_ambient: ambient { + label = "TEMP_AMBIENT"; + enum-name = "ADC_TEMP_SENSOR_2_AMBIENT"; + io-channels = <&adc0 3>; + }; + adc_charger: charger { + label = "TEMP_CHARGER"; + enum-name = "ADC_TEMP_SENSOR_3_CHARGER"; + io-channels = <&adc0 0>; + }; + adc_wwan: wwan { + label = "TEMP_WWAN"; + enum-name = "ADC_TEMP_SENSOR_4_WWAN"; + io-channels = <&adc0 4>; + }; + }; + + soc { + /delete-node/ rtc@400f5000; + /delete-node/ kscan@40009c00; + + crtc: cros-rtc@400f5000 { + compatible = "microchip,xec-cros-rtc"; + reg = <0x400f5000 0x100>; + interrupts = <119 0>, <120 0>; + label = "CRTC"; + }; + + cros_kb_raw: cros-kb-raw@40009c00 { + compatible = "microchip,xec-cros-kb-raw"; + reg = <0x40009c00 0x18>; + label = "CROS_KB_RAW_0"; + interrupts = <135 0>; + }; + }; +}; + +&cpu0 { + status = "okay"; +/* cpu-power-states = <&suspend_to_idle_instant &suspend_to_idle_normal>; */ +}; + +&bbram { + status = "okay"; +}; + +&ecia { + status = "okay"; +}; + +/* Enable aggregated GIRQ24/25 for eSPI virtual wires */ +&girq24 { + status = "okay"; +}; + +&girq25 { + status = "okay"; +}; + +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_reset_n_gpio061 + &espi_cs_n_gpio066 + &espi_clk_gpio065 + &espi_io0_gpio070 + &espi_io1_gpio071 + &espi_io2_gpio072 + &espi_io3_gpio073>; + pinctrl-names = "default"; +}; + +/* Host facing devices on eSPI bus */ +&kbc0 { + status = "okay"; +}; + +&acpi_ec0 { + status = "okay"; +}; + +&acpi_ec1 { + status = "okay"; +}; + +&emi0 { + status = "okay"; +}; + +&p80bd0 { + status = "okay"; +}; + +&crtc { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_tx_gpio104 &uart0_rx_gpio105>; + pinctrl-names = "default"; +}; + +&spi0 { + status = "okay"; + clock-frequency = <12000000>; + lines = <2>; + port-sel = <2>; + chip-select = <0>; + pinctrl-0 = < &gpspi_cs_n_gpio116 + &gpspi_clk_gpio117 + &gpspi_io0_gpio074 + &gpspi_io1_gpio075 + &gpspi_wp_n_gpio076 >; + pinctrl-names = "default"; + + int_flash: sst25pf040@0 { + compatible ="jedec,spi-nor"; + /* 4194304 bits = 512K Bytes */ + size = <0x400000>; + label = "SST25PF040"; + reg = <0>; + spi-max-frequency = <40000000>; + status = "okay"; + jedec-id = [62 06 13]; + }; +}; + +&cros_kb_raw { + status = "okay"; + /* + * No KSO2 (It's inverted and implemented by GPIO for + * CONFIG_KEYBOARD_COL2_INVERTED.) + */ + pinctrl-0 = <&ksi0_gpio017 + &ksi1_gpio020 + &ksi2_gpio021 + &ksi3_gpio026 + &ksi4_gpio027 + &ksi5_gpio030 + &ksi6_gpio031 + &ksi7_gpio032 + &kso00_gpio040 + &kso01_gpio045 + &kso03_gpio047 + &kso04_gpio107 + &kso05_gpio112 + &kso06_gpio113 + &kso07_gpio120 + &kso08_gpio121 + &kso09_gpio122 + &kso10_gpio123 + &kso11_gpio124 + &kso12_gpio125>; + pinctrl-names = "default"; +}; + +/* Chrome design: KSI02 to H1 has not pull-up resistor */ +&ksi2_gpio021 { + bias-pull-up; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc00_gpio200 + &adc03_gpio203 + &adc04_gpio204 + &adc05_gpio205>; + pinctrl-names = "default"; +}; diff --git a/zephyr/boards/arm/mec1727/mec1727_defconfig b/zephyr/boards/arm/mec1727/mec1727_defconfig new file mode 100644 index 0000000000..69f0ff53f5 --- /dev/null +++ b/zephyr/boards/arm/mec1727/mec1727_defconfig @@ -0,0 +1,57 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# 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_MEC172X=y + +# Platform Configuration +CONFIG_SOC_MEC172X_NSZ=y +CONFIG_BOARD_MEC1727=y +CONFIG_RTOS_TIMER=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32768 +CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Pinmux Driver +CONFIG_PINMUX=y + +# Pinctrl Driver +CONFIG_PINCTRL=y + +# GPIO Controller +CONFIG_GPIO=y + +# Clock configuration +CONFIG_CLOCK_CONTROL=y + +# WATCHDOG configuration +CONFIG_WATCHDOG=y +CONFIG_WDT_XEC=y + +# Power Management +#CONFIG_PM=y +#CONFIG_PM_POLICY_APP=y +#CONFIG_UART_CONSOLE_INPUT_EXPIRED=y + +# BBRAM +CONFIG_BBRAM=y +CONFIG_BBRAM_XEC=y + +# SPI +CONFIG_SPI=y +# MCHP build config error CONFIG_SPI_FLASH=y + +# Flash +CONFIG_FLASH=y +CONFIG_SPI_NOR=y +# disabling this causes build error: calling function to read JEDEC ID +# MEC1727 internal SST25PF040 does not support SFDP +CONFIG_FLASH_JESD216_API=y diff --git a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index 5b770bf71f..3ad4f2b1b3 100644 --- a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -25,7 +25,7 @@ /* NOTE: &pwm number needs same with channel number */ pwm_led_test: pwm_led_test { - pwms = <&pwm0 PWM_CHANNEL_0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 PWM_CHANNEL_0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; }; @@ -155,7 +155,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm7 PWM_CHANNEL_7 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm7 PWM_CHANNEL_7 PWM_KHZ(30) PWM_POLARITY_NORMAL>; pwm-frequency = <30000>; tach = <&tach0>; rpm_min = <1500>; diff --git a/zephyr/drivers/cros_displight/cros_displight.c b/zephyr/drivers/cros_displight/cros_displight.c index b7c04e2bb1..d54706d0c8 100644 --- a/zephyr/drivers/cros_displight/cros_displight.c +++ b/zephyr/drivers/cros_displight/cros_displight.c @@ -21,14 +21,14 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, #define DISPLIGHT_PWM_NODE DT_INST_PWMS_CTLR(0) #define DISPLIGHT_PWM_CHANNEL DT_INST_PWMS_CHANNEL(0) #define DISPLIGHT_PWM_FLAGS DT_INST_PWMS_FLAGS(0) -#define DISPLIGHT_PWM_PERIOD_US (USEC_PER_SEC/DT_INST_PROP(0, frequency)) +#define DISPLIGHT_PWM_PERIOD_NS (NSEC_PER_SEC/DT_INST_PROP(0, frequency)) static int displight_percent; static void displight_set_duty(int percent) { const struct device *pwm_dev = DEVICE_DT_GET(DISPLIGHT_PWM_NODE); - uint32_t pulse_us; + uint32_t pulse_ns; int rv; if (!device_is_ready(pwm_dev)) { @@ -36,17 +36,15 @@ static void displight_set_duty(int percent) return; } - pulse_us = DIV_ROUND_NEAREST(DISPLIGHT_PWM_PERIOD_US * percent, 100); + pulse_ns = DIV_ROUND_NEAREST(DISPLIGHT_PWM_PERIOD_NS * percent, 100); LOG_DBG("displight PWM %s set percent (%d), pulse %d", - pwm_dev->name, percent, pulse_us); + pwm_dev->name, percent, pulse_ns); - rv = pwm_pin_set_usec(pwm_dev, DISPLIGHT_PWM_CHANNEL, - DISPLIGHT_PWM_PERIOD_US, pulse_us, - DISPLIGHT_PWM_FLAGS); + rv = pwm_set(pwm_dev, DISPLIGHT_PWM_CHANNEL, DISPLIGHT_PWM_PERIOD_NS, + pulse_ns, DISPLIGHT_PWM_FLAGS); if (rv) { - LOG_ERR("pwm_pin_set_usec() failed %s (%d)", - pwm_dev->name, rv); + LOG_ERR("pwm_set() failed %s (%d)", pwm_dev->name, rv); } } diff --git a/zephyr/drivers/cros_flash/cros_flash_xec.c b/zephyr/drivers/cros_flash/cros_flash_xec.c index f75518004d..aaa181c9bf 100644 --- a/zephyr/drivers/cros_flash/cros_flash_xec.c +++ b/zephyr/drivers/cros_flash/cros_flash_xec.c @@ -392,14 +392,6 @@ static int cros_flash_xec_init(const struct device *dev) return 0; } -/* TODO(b/205175314): Migrate cros-flash driver to Zephyr flash driver) */ -static int cros_flash_xec_read(const struct device *dev, int offset, int size, - char *dst_data) -{ - struct cros_flash_xec_data *data = dev->data; - - return flash_read(data->flash_dev, offset, dst_data, size); -} static int cros_flash_xec_write(const struct device *dev, int offset, int size, const char *src_data) @@ -565,7 +557,6 @@ static int cros_flash_xec_get_status(const struct device *dev, uint8_t *sr1, /* cros ec flash driver registration */ static const struct cros_flash_driver_api cros_flash_xec_driver_api = { .init = cros_flash_xec_init, - .physical_read = cros_flash_xec_read, .physical_write = cros_flash_xec_write, .physical_erase = cros_flash_xec_erase, .physical_get_protect = cros_flash_xec_get_protect, diff --git a/zephyr/drivers/cros_kblight/pwm_kblight.c b/zephyr/drivers/cros_kblight/pwm_kblight.c index 0f82f3ce99..c58d6cae06 100644 --- a/zephyr/drivers/cros_kblight/pwm_kblight.c +++ b/zephyr/drivers/cros_kblight/pwm_kblight.c @@ -21,7 +21,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, #define KBLIGHT_PWM_NODE DT_INST_PWMS_CTLR(0) #define KBLIGHT_PWM_CHANNEL DT_INST_PWMS_CHANNEL(0) #define KBLIGHT_PWM_FLAGS DT_INST_PWMS_FLAGS(0) -#define KBLIGHT_PWM_PERIOD_US (USEC_PER_SEC/DT_INST_PROP(0, frequency)) +#define KBLIGHT_PWM_PERIOD_NS (NSEC_PER_SEC/DT_INST_PROP(0, frequency)) static bool kblight_enabled; static int kblight_percent; @@ -29,7 +29,7 @@ static int kblight_percent; static void kblight_pwm_set_duty(int percent) { const struct device *pwm_dev = DEVICE_DT_GET(KBLIGHT_PWM_NODE); - uint32_t pulse_us; + uint32_t pulse_ns; int rv; if (!device_is_ready(pwm_dev)) { @@ -37,17 +37,15 @@ static void kblight_pwm_set_duty(int percent) return; } - pulse_us = DIV_ROUND_NEAREST(KBLIGHT_PWM_PERIOD_US * percent, 100); + pulse_ns = DIV_ROUND_NEAREST(KBLIGHT_PWM_PERIOD_NS * percent, 100); LOG_DBG("kblight PWM %s set percent (%d), pulse %d", - pwm_dev->name, percent, pulse_us); + pwm_dev->name, percent, pulse_ns); - rv = pwm_pin_set_usec(pwm_dev, KBLIGHT_PWM_CHANNEL, - KBLIGHT_PWM_PERIOD_US, pulse_us, - KBLIGHT_PWM_FLAGS); + rv = pwm_set(pwm_dev, KBLIGHT_PWM_CHANNEL, KBLIGHT_PWM_PERIOD_NS, + pulse_ns, KBLIGHT_PWM_FLAGS); if (rv) { - LOG_ERR("pwm_pin_set_usec() failed %s (%d)", - pwm_dev->name, rv); + LOG_ERR("pwm_set() failed %s (%d)", pwm_dev->name, rv); } } diff --git a/zephyr/dts/bindings/led/cros-ec,pwm-leds.yaml b/zephyr/dts/bindings/led/cros-ec,pwm-leds.yaml index 2b7d24d320..f854f84d50 100644 --- a/zephyr/dts/bindings/led/cros-ec,pwm-leds.yaml +++ b/zephyr/dts/bindings/led/cros-ec,pwm-leds.yaml @@ -21,10 +21,9 @@ properties: pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm1 0 0 PWM_POLARITY_INVERTED - &pwm0 0 0 PWM_POLARITY_INVERTED - &pwm2 0 0 PWM_POLARITY_INVERTED>; - + pwms = <&pwm1 0 PWM_HZ(4800) PWM_POLARITY_INVERTED + &pwm0 0 PWM_HZ(4800) PWM_POLARITY_INVERTED + &pwm2 0 PWM_HZ(4800) PWM_POLARITY_INVERTED>; }; }; cros-pwmleds { @@ -42,8 +41,7 @@ properties: pwmleds { compatible = "pwm-leds"; pwm_sidesel: pwm_sidesel { - pwms = <&pwm7 0 0 PWM_POLARITY_INVERTED>; - + pwms = <&pwm7 0 PWM_HZ(4800) PWM_POLARITY_INVERTED>; }; }; cros-pwmleds { diff --git a/zephyr/dts/bindings/leds/cros-ec,led-colors.yaml b/zephyr/dts/bindings/leds/cros-ec,led-colors.yaml index c919d625c2..f99804cb94 100644 --- a/zephyr/dts/bindings/leds/cros-ec,led-colors.yaml +++ b/zephyr/dts/bindings/leds/cros-ec,led-colors.yaml @@ -32,6 +32,11 @@ child-binding: - PWR_STATE_IDLE - PWR_STATE_CHARGE_NEAR_FULL + charge-port: + description: If the LED color depends on the charging port (left or right) + type: int + required: false + chipset-state: description: If the LED color depends on chipset state, this property is used to describe it. @@ -67,6 +72,19 @@ child-binding: - LED_YELLOW - LED_WHITE - LED_AMBER + led-id: + description: Used to link the color nodes with the pin nodes in + case of multiple LEDs. + type: string + required: true + enum: + - EC_LED_ID_BATTERY_LED + - EC_LED_ID_POWER_LED + - EC_LED_ID_ADAPTER_LED + - EC_LED_ID_LEFT_LED + - EC_LED_ID_RIGHT_LED + - EC_LED_ID_RECOVERY_HW_REINIT_LED + - EC_LED_ID_SYSRQ_DEBUG_LED period-ms: description: In case of blinking LEDs, amount of time in msecs the LED color is active. This value must be a diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c index 21cd16eb20..1faa82a4a7 100644 --- a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c +++ b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c @@ -329,6 +329,22 @@ static void tcpci_snk_emul_stop_partner_transition_timer( data->wait_for_ps_rdy = false; } +static enum tcpci_partner_handler_res +tcpci_snk_emul_handle_goto_min_req(struct tcpci_snk_emul_data *data, + struct tcpci_partner_data *common_data) +{ + data->wait_for_ps_rdy = true; + data->pd_completed = false; + tcpci_snk_emul_start_partner_transition_timer(data, common_data); + + return TCPCI_PARTNER_COMMON_MSG_HANDLED; +} + +void tcpci_snk_emul_clear_ping_received(struct tcpci_snk_emul_data *data) +{ + data->ping_received = false; +} + /** Check description in emul_tcpci_snk.h */ enum tcpci_partner_handler_res tcpci_snk_emul_handle_sop_msg( struct tcpci_snk_emul_data *data, @@ -357,7 +373,11 @@ enum tcpci_partner_handler_res tcpci_snk_emul_handle_sop_msg( 0); return TCPCI_PARTNER_COMMON_MSG_HANDLED; case PD_CTRL_PING: + data->ping_received = true; return TCPCI_PARTNER_COMMON_MSG_HANDLED; + case PD_CTRL_GOTO_MIN: + return tcpci_snk_emul_handle_goto_min_req(data, + common_data); case PD_CTRL_PS_RDY: __ASSERT(data->wait_for_ps_rdy, "Unexpected PS RDY message"); diff --git a/zephyr/include/cros/microchip/mec172x.dtsi b/zephyr/include/cros/microchip/mec172x.dtsi index 42e1859ef8..6833fa57d0 100644 --- a/zephyr/include/cros/microchip/mec172x.dtsi +++ b/zephyr/include/cros/microchip/mec172x.dtsi @@ -13,7 +13,8 @@ cros-ec,adc = &adc0; cros-ec,bbram = &bbram; cros-ec,espi = &espi0; - cros-ec,flash = &fiu0; + cros-ec,flash = &int_flash; + cros-ec,flash-controller = &fiu0; cros-ec,raw-kb = &cros_kb_raw; cros-ec,watchdog = &wdog; cros,rtc = &crtc; diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h index 0671fb7e2e..0c05768d31 100644 --- a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h +++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h @@ -35,6 +35,8 @@ struct tcpci_snk_emul_data { bool wait_for_ps_rdy; /** PS RDY was received and PD negotiation is completed */ bool pd_completed; + /** PD_CTRL_PING message received */ + bool ping_received; }; /** Structure describing standalone sink device emulator */ @@ -107,6 +109,13 @@ enum tcpci_partner_handler_res tcpci_snk_emul_handle_sop_msg( void tcpci_snk_emul_hard_reset(void *data); /** + * @brief Clear the ping received flag. + * + * @param sink_data + */ +void tcpci_snk_emul_clear_ping_received(struct tcpci_snk_emul_data *sink_data); + +/** * @} */ diff --git a/zephyr/projects/brya/fan.dts b/zephyr/projects/brya/fan.dts index d3032e83ec..46c00e057a 100644 --- a/zephyr/projects/brya/fan.dts +++ b/zephyr/projects/brya/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm5 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm5 0 PWM_KHZ(1) PWM_POLARITY_NORMAL>; pwm-frequency = <1000>; rpm_min = <2200>; rpm_start = <2200>; diff --git a/zephyr/projects/brya/keyboard.dts b/zephyr/projects/brya/keyboard.dts index 3030aee310..8cbcdb7a8c 100644 --- a/zephyr/projects/brya/keyboard.dts +++ b/zephyr/projects/brya/keyboard.dts @@ -6,7 +6,7 @@ / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm3 0 PWM_HZ(2400) PWM_POLARITY_NORMAL>; frequency = <2400>; }; }; diff --git a/zephyr/projects/brya/pwm_leds.dts b/zephyr/projects/brya/pwm_leds.dts index ed05cfe786..3157d367f2 100644 --- a/zephyr/projects/brya/pwm_leds.dts +++ b/zephyr/projects/brya/pwm_leds.dts @@ -7,12 +7,12 @@ pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm2 0 0 PWM_POLARITY_INVERTED - &pwm0 0 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm2 0 PWM_HZ(4800) PWM_POLARITY_INVERTED + &pwm0 0 PWM_HZ(4800) PWM_POLARITY_INVERTED>; }; pwm_led1: pwm_led_1 { - pwms = <&pwm1 0 0 PWM_POLARITY_INVERTED - &pwm7 0 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm1 0 PWM_HZ(4800) PWM_POLARITY_INVERTED + &pwm7 0 PWM_HZ(4800) PWM_POLARITY_INVERTED>; }; }; diff --git a/zephyr/projects/corsola/led_kingler.dts b/zephyr/projects/corsola/led_kingler.dts index 5ce5186305..19bb0978d8 100644 --- a/zephyr/projects/corsola/led_kingler.dts +++ b/zephyr/projects/corsola/led_kingler.dts @@ -7,9 +7,9 @@ pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm0 0 0 PWM_POLARITY_INVERTED - &pwm1 0 0 PWM_POLARITY_INVERTED - &pwm2 0 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm0 0 PWM_HZ(100) PWM_POLARITY_INVERTED + &pwm1 0 PWM_HZ(100) PWM_POLARITY_INVERTED + &pwm2 0 PWM_HZ(100) PWM_POLARITY_INVERTED>; }; }; diff --git a/zephyr/projects/corsola/led_krabby.dts b/zephyr/projects/corsola/led_krabby.dts index c9bf539f7f..b6761e56e5 100644 --- a/zephyr/projects/corsola/led_krabby.dts +++ b/zephyr/projects/corsola/led_krabby.dts @@ -8,13 +8,13 @@ compatible = "pwm-leds"; /* NOTE: &pwm number needs same with channel number */ led_power_white: ec_led1_odl { - pwms = <&pwm0 PWM_CHANNEL_0 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm0 PWM_CHANNEL_0 PWM_HZ(324) PWM_POLARITY_INVERTED>; }; led_battery_amber: ec_led2_odl { - pwms = <&pwm1 PWM_CHANNEL_1 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm1 PWM_CHANNEL_1 PWM_HZ(324) PWM_POLARITY_INVERTED>; }; led_battery_white: ec_led3_odl { - pwms = <&pwm2 PWM_CHANNEL_2 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm2 PWM_CHANNEL_2 PWM_HZ(324) PWM_POLARITY_INVERTED>; }; }; }; diff --git a/zephyr/projects/corsola/prj_kingler.conf b/zephyr/projects/corsola/prj_kingler.conf index fd28664a57..8901cd10d4 100644 --- a/zephyr/projects/corsola/prj_kingler.conf +++ b/zephyr/projects/corsola/prj_kingler.conf @@ -124,7 +124,7 @@ CONFIG_PLATFORM_EC_USB_PD_DEBUG_LEVEL=2 CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447=y CONFIG_PLATFORM_EC_USB_PD_TCPM_RT1718S=y CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y -CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_NOT_PRESENT=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_BY_BOARD=y # External power CONFIG_PLATFORM_EC_BACKLIGHT_LID=n diff --git a/zephyr/projects/corsola/src/kingler/usbc_config.c b/zephyr/projects/corsola/src/kingler/usbc_config.c index 1b688ca828..bc41eda949 100644 --- a/zephyr/projects/corsola/src/kingler/usbc_config.c +++ b/zephyr/projects/corsola/src/kingler/usbc_config.c @@ -44,7 +44,8 @@ struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, .drv = &anx7447_tcpm_drv, /* Alert is active-low, open-drain */ - .flags = TCPC_FLAGS_ALERT_OD, + .flags = TCPC_FLAGS_ALERT_OD | TCPC_FLAGS_VBUS_MONITOR | + TCPC_FLAGS_CONTROL_FRS, }, [USBC_PORT_C1] = { .bus_type = EC_BUS_TYPE_I2C, @@ -54,11 +55,11 @@ struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, .drv = &rt1718s_tcpm_drv, /* Alert is active-low, open-drain */ - .flags = TCPC_FLAGS_ALERT_OD, + .flags = TCPC_FLAGS_ALERT_OD | TCPC_FLAGS_VBUS_MONITOR | + TCPC_FLAGS_CONTROL_FRS, } }; - struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { [USBC_PORT_C0] = { .i2c_port = I2C_PORT_USB_C0, @@ -185,9 +186,9 @@ __override int board_rt1718s_init(int port) gpio_initialized = true; } - /* gpio 1/2 output high when receiving frs signal */ + /* gpio1 low, gpio2 output high when receiving frs signal */ RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO1_VBUS_CTRL, - RT1718S_GPIO1_VBUS_CTRL_FRS_RX_VBUS, 0xFF)); + RT1718S_GPIO1_VBUS_CTRL_FRS_RX_VBUS, 0)); RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO2_VBUS_CTRL, RT1718S_GPIO2_VBUS_CTRL_FRS_RX_VBUS, 0xFF)); @@ -211,6 +212,19 @@ __override int board_rt1718s_init(int port) return EC_SUCCESS; } +__override int board_rt1718s_set_frs_enable(int port, int enable) +{ + if (port == USBC_PORT_C1) + /* + * Use set_flags (implemented by a single i2c write) instead + * of set_level (= i2c_update) to save one read operation in + * FRS path. + */ + rt1718s_gpio_set_flags(port, GPIO_EN_USB_C1_FRS, + enable ? GPIO_OUT_HIGH : GPIO_OUT_LOW); + return EC_SUCCESS; +} + void board_reset_pd_mcu(void) { @@ -356,3 +370,24 @@ void bc12_interrupt(enum gpio_signal signal) { task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); } + +__override int board_get_vbus_voltage(int port) +{ + int voltage = 0; + int rv; + + switch (port) { + case USBC_PORT_C0: + rv = tcpc_config[USBC_PORT_C0].drv->get_vbus_voltage(port, + &voltage); + if (rv) + return 0; + break; + case USBC_PORT_C1: + rt1718s_get_adc(port, RT1718S_ADC_VBUS1, &voltage); + break; + default: + return 0; + } + return voltage; +} diff --git a/zephyr/projects/corsola/src/krabby/led.c b/zephyr/projects/corsola/src/krabby/led.c index 8e2cf10cd9..23db221d77 100644 --- a/zephyr/projects/corsola/src/krabby/led.c +++ b/zephyr/projects/corsola/src/krabby/led.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(board_led, LOG_LEVEL_ERR); /*If we need pwm output in ITE chip power saving mode, then we should set * frequency <= 324Hz. */ -#define BOARD_LED_PWM_PERIOD_US BOARD_LED_HZ_TO_PERIOD_US(324) +#define BOARD_LED_PWM_PERIOD_NS BOARD_LED_HZ_TO_PERIOD_NS(324) static const struct board_led_pwm_dt_channel board_led_power_white = BOARD_LED_PWM_DT_CHANNEL_INITIALIZER(DT_NODELABEL(led_power_white)); @@ -65,7 +65,7 @@ const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); static void board_led_pwm_set_duty(const struct board_led_pwm_dt_channel *ch, int percent) { - uint32_t pulse_us; + uint32_t pulse_ns; int rv; if (!device_is_ready(ch->dev)) { @@ -73,15 +73,15 @@ static void board_led_pwm_set_duty(const struct board_led_pwm_dt_channel *ch, return; } - pulse_us = DIV_ROUND_NEAREST(BOARD_LED_PWM_PERIOD_US * percent, 100); + pulse_ns = DIV_ROUND_NEAREST(BOARD_LED_PWM_PERIOD_NS * percent, 100); LOG_DBG("Board LED PWM %s set percent (%d), pulse %d", - ch->dev->name, percent, pulse_us); + ch->dev->name, percent, pulse_ns); - rv = pwm_pin_set_usec(ch->dev, ch->channel, BOARD_LED_PWM_PERIOD_US, - pulse_us, ch->flags); + rv = pwm_set(ch->dev, ch->channel, BOARD_LED_PWM_PERIOD_NS, pulse_ns, + ch->flags); if (rv) { - LOG_ERR("pwm_pin_set_usec() failed %s (%d)", ch->dev->name, rv); + LOG_ERR("pwm_set() failed %s (%d)", ch->dev->name, rv); } } diff --git a/zephyr/projects/herobrine/display.dts b/zephyr/projects/herobrine/display.dts index d683aa931f..6487e85255 100644 --- a/zephyr/projects/herobrine/display.dts +++ b/zephyr/projects/herobrine/display.dts @@ -6,7 +6,7 @@ / { displight { compatible = "cros-ec,displight"; - pwms = <&pwm5 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm5 0 PWM_HZ(4800) PWM_POLARITY_NORMAL>; frequency = <4800>; generic-pwm-channel = <1>; }; diff --git a/zephyr/projects/herobrine/keyboard.dts b/zephyr/projects/herobrine/keyboard.dts index 7237e56a1f..6ffb137ba1 100644 --- a/zephyr/projects/herobrine/keyboard.dts +++ b/zephyr/projects/herobrine/keyboard.dts @@ -6,7 +6,7 @@ / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm3 0 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; generic-pwm-channel = <0>; }; diff --git a/zephyr/projects/herobrine/led_villager.dts b/zephyr/projects/herobrine/led_villager.dts index a4f78b82ee..aa9f43c3d9 100644 --- a/zephyr/projects/herobrine/led_villager.dts +++ b/zephyr/projects/herobrine/led_villager.dts @@ -7,6 +7,7 @@ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -16,6 +17,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -26,10 +28,12 @@ /* Amber 1 sec, off 3 sec */ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; color-1 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <3000>; }; }; @@ -40,6 +44,7 @@ color-0 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -49,10 +54,12 @@ /* Amber 1 sec, off 1 sec */ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; color-1 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; }; @@ -62,6 +69,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -72,10 +80,12 @@ /* Blue 2 sec, Amber 2 sec */ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <2000>; }; color-1 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <2000>; }; }; @@ -86,6 +96,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; }; diff --git a/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/fan.dts b/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/fan.dts index 233888c0ca..e679867970 100644 --- a/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/fan.dts +++ b/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm3 0 PWM_KHZ(30) PWM_POLARITY_NORMAL>; pwm-frequency = <30000>; rpm_min = <3000>; rpm_start = <3000>; diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/fan.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/fan.dts index 84c8237a4c..dee444f441 100644 --- a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/fan.dts +++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm3 0 PWM_KHZ(30) PWM_POLARITY_NORMAL>; pwm-frequency = <30000>; rpm_min = <3200>; rpm_start = <2200>; diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts index bda90274ef..937119aa72 100644 --- a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts +++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts @@ -32,6 +32,10 @@ i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_KB_DISCRETE"; }; + port80 { + i2c-port = <&i2c7_0>; + enum-name = "I2C_PORT_PORT80"; + }; typec_aic1: typec-aic1{ i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_TYPEC_AIC_1"; @@ -108,6 +112,12 @@ reg = <0x39>; label = "KEYBOARD_DISCRETE"; }; + + seven_seg_display: max695x-seven-seg-display@38 { + compatible = "maxim,seven-seg-display"; + reg = <0x38>; + label = "MAX695X_SEVEN_SEG_DISPLAY"; + }; }; &i2c_ctrl7 { diff --git a/zephyr/projects/intelrvp/mtlrvp/prj.conf b/zephyr/projects/intelrvp/mtlrvp/prj.conf index 507665e6f1..bea2791efe 100644 --- a/zephyr/projects/intelrvp/mtlrvp/prj.conf +++ b/zephyr/projects/intelrvp/mtlrvp/prj.conf @@ -42,6 +42,5 @@ CONFIG_PLATFORM_EC_TEMP_SENSOR_POWER=y CONFIG_PLATFORM_EC_USB_PD_TCPM_NCT38XX=y CONFIG_PLATFORM_EC_USB_PD_TCPM_MUX=y -# TODO: Enable these in follow on CLs -CONFIG_PLATFORM_EC_VBOOT_HASH=n -CONFIG_PLATFORM_EC_VBOOT_EFS2=n +# 7-Segment Display +CONFIG_PLATFORM_EC_MAX695X_SEVEN_SEGMENT_DISPLAY=y diff --git a/zephyr/projects/nissa/BUILD.py b/zephyr/projects/nissa/BUILD.py index 6b8cc39dbf..1af33723eb 100644 --- a/zephyr/projects/nissa/BUILD.py +++ b/zephyr/projects/nissa/BUILD.py @@ -4,7 +4,7 @@ """Define zmake projects for nissa.""" -# Nivviks has NPCX993F, Nereid has ITE81302 +# Nivviks and Craask has NPCX993F, Nereid has ITE81302 def register_nissa_project( @@ -53,3 +53,16 @@ register_nissa_project( ], extra_kconfig_files=[here / "prj_nereid.conf"], ) + +register_nissa_project( + project_name="craask", + chip="npcx9", + extra_dts_overlays=[ + here / "craask_generated.dts", + here / "craask_overlay.dts", + here / "craask_motionsense.dts", + here / "craask_power_signals.dts", + here / "craask_pwm_leds.dts", + ], + extra_kconfig_files=[here / "prj_craask.conf"], +) diff --git a/zephyr/projects/nissa/CMakeLists.txt b/zephyr/projects/nissa/CMakeLists.txt index 496cf12c40..1ce861d33c 100644 --- a/zephyr/projects/nissa/CMakeLists.txt +++ b/zephyr/projects/nissa/CMakeLists.txt @@ -24,3 +24,8 @@ if(DEFINED CONFIG_BOARD_NEREID) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/nereid/usbc.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "src/nereid/charger.c") endif() +if(DEFINED CONFIG_BOARD_CRAASK) + project(nivviks) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/craask/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "src/craask/charger.c") +endif() diff --git a/zephyr/projects/nissa/Kconfig b/zephyr/projects/nissa/Kconfig index bc3d2a5b80..3f0ef5954a 100644 --- a/zephyr/projects/nissa/Kconfig +++ b/zephyr/projects/nissa/Kconfig @@ -14,6 +14,12 @@ config BOARD_NEREID Build Google Nereid reference board. Nereid has Intel ADL-N SoC with IT81302 EC. +config BOARD_CRAASK + bool "Google Craask Board" + help + Build Google Craask board. Craask has Intel ADL-N SoC + with NPCX993FA0BX EC. + module = NISSA module-str = Nissa board-specific code source "subsys/logging/Kconfig.template.log_config" diff --git a/zephyr/projects/nissa/craask_generated.dts b/zephyr/projects/nissa/craask_generated.dts new file mode 100644 index 0000000000..f4fd4d2384 --- /dev/null +++ b/zephyr/projects/nissa/craask_generated.dts @@ -0,0 +1,274 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * 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! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + label = "EC_VSENSE_PP1050_PROC"; + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + label = "EC_VSENSE_PP3300_S5"; + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + label = "TEMP_SENSOR_1"; + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + label = "TEMP_SENSOR_2"; + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_INPUT>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + 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"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio8 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-name = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-name = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-name = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-name = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-name = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0_0 { + status = "okay"; +}; + +&i2c1_0 { + status = "okay"; +}; + +&i2c3_0 { + status = "okay"; +}; + +&i2c5_1 { + status = "okay"; +}; + +&i2c7_0 { + status = "okay"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/craask_motionsense.dts b/zephyr/projects/nissa/craask_motionsense.dts new file mode 100644 index 0000000000..3162dd0526 --- /dev/null +++ b/zephyr/projects/nissa/craask_motionsense.dts @@ -0,0 +1,156 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + label = "LID_MUTEX"; + }; + + base_mutex: base-mutex { + label = "BASE_MUTEX"; + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <(-1) 0 0 + 0 1 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_data: lsm6dso-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The label "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + */ + motionsense-sensor { + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + label = "Base Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + label = "Base Gyro"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_data>; + }; + + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + label = "Lid Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/craask_overlay.dts b/zephyr/projects/nissa/craask_overlay.dts new file mode 100644 index 0000000000..3e38558731 --- /dev/null +++ b/zephyr/projects/nissa/craask_overlay.dts @@ -0,0 +1,289 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * 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> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_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"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "lsm6dso_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_prochot: ap_prochot { + irq-pin = <&gpio_ec_prochot_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "throttle_ap_prochot_input_interrupt"; + }; + }; + + named-gpios { + gpio_sb_1: sb_1 { + gpios = <&gpio0 2 GPIO_PULL_UP>; + no-auto-init; + }; + + gpio_sb_2: sb_2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + gpio_sb_3: sb_3 { + gpios = <&gpiof 4 GPIO_OPEN_DRAIN>; + no-auto-init; + }; + gpio_sb_4: sb_4 { + gpios = <&gpiof 5 GPIO_INPUT>; + no-auto-init; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Input GPIO when used with type-C port 1 + * Output when used with HDMI sub-board + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + gpio-en-rails-odl = &gpio_sb_1; + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HPD pins for HDMI sub-board. + */ + gpio-hdmi-en-odl = &gpio_sb_3; + gpio-hpd-odl = &gpio_sb_4; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + named-temp-sensors { + memory { + compatible = "cros-ec,temp-sensor-thermistor", + "cros-ec,temp-sensor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "DDR and SOC"; + enum-name = "TEMP_SENSOR_1"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_1>; + }; + charger { + compatible = "cros-ec,temp-sensor-thermistor", + "cros-ec,temp-sensor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "Charger"; + enum-name = "TEMP_SENSOR_2"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_2>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 { + compatible = "pericom,pi3usb9201"; + port = <&i2c_ec_i2c_usb_c0>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + chg { + compatible = "intersil,isl923x"; + status = "okay"; + port = <&i2c_ec_i2c_usb_c0>; + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 { + compatible = "pericom,pi3usb9201"; + port = <&i2c_ec_i2c_sub_usb_c1>; + }; + chg { + compatible = "intersil,isl923x"; + status = "okay"; + port = <&i2c_ec_i2c_sub_usb_c1>; + }; + }; + }; + + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 0 PWM_POLARITY_NORMAL>; + frequency = <10000>; + }; + + /* + * Set I2C pins for type C sub-board to be + * low voltage (I2C5_1). + * We do this for all boards, since the pins are + * 3.3V tolerant, and the only 2 types of sub-boards + * used on nivviks both have type-C ports on them. + */ + def-lvol-io-list { + compatible = "nuvoton,npcx-lvolctrl-def"; + lvol-io-pads = <&lvol_iof5 &lvol_iof4>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + label = "EEPROM_CBI"; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm6 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/craask_power_signals.dts b/zephyr/projects/nissa/craask_power_signals.dts new file mode 100644 index 0000000000..91876f0402 --- /dev/null +++ b/zephyr/projects/nissa/craask_power_signals.dts @@ -0,0 +1,220 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/craask_pwm_leds.dts b/zephyr/projects/nissa/craask_pwm_leds.dts new file mode 100644 index 0000000000..5fb301bfa5 --- /dev/null +++ b/zephyr/projects/nissa/craask_pwm_leds.dts @@ -0,0 +1,57 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 2 0 PWM_POLARITY_INVERTED>, + <&pwm0 0 0 PWM_POLARITY_INVERTED>, + <&pwm1 1 0 PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + frequency = <324>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = <100 20 100>; + + brightness-range = <100 100 100 0 0 0>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +/* Enable LEDs to work while CPU suspended */ + +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; diff --git a/zephyr/projects/nissa/nereid_keyboard.dts b/zephyr/projects/nissa/nereid_keyboard.dts index 800681bdce..1283db24d9 100644 --- a/zephyr/projects/nissa/nereid_keyboard.dts +++ b/zephyr/projects/nissa/nereid_keyboard.dts @@ -6,7 +6,7 @@ / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 0 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; }; }; diff --git a/zephyr/projects/nissa/nereid_motionsense.dts b/zephyr/projects/nissa/nereid_motionsense.dts index 9cc8761bda..37f83fd233 100644 --- a/zephyr/projects/nissa/nereid_motionsense.dts +++ b/zephyr/projects/nissa/nereid_motionsense.dts @@ -73,19 +73,23 @@ * List of motion sensors that creates motion_sensors array. * The label "lid_accel" and "base_accel" are used to indicate * motion sensor IDs for lid angle calculation. + * TODO:(b/229577857) The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. */ motionsense-sensor { - base_accel: base-accel { - compatible = "cros-ec,bmi3xx-accel"; + lid_accel: lid-accel { + compatible = "cros-ec,bma4xx"; status = "okay"; - label = "Base Accel"; + label = "Lid Accel"; active-mask = "SENSOR_ACTIVE_S0_S3"; - location = "MOTIONSENSE_LOC_BASE"; - mutex = <&base_mutex>; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; port = <&i2c_ec_i2c_sensor>; - rot-standard-ref = <&base_rot_ref>; - drv-data = <&bmi323_data>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&bma422_data>; configs { compatible = "cros-ec,motionsense-sensor-config"; @@ -100,31 +104,17 @@ }; }; - base_gyro: base-gyro { - compatible = "cros-ec,bmi3xx-gyro"; + base_accel: base-accel { + compatible = "cros-ec,bmi3xx-accel"; status = "okay"; - label = "Base Gyro"; + label = "Base Accel"; active-mask = "SENSOR_ACTIVE_S0_S3"; location = "MOTIONSENSE_LOC_BASE"; mutex = <&base_mutex>; port = <&i2c_ec_i2c_sensor>; rot-standard-ref = <&base_rot_ref>; drv-data = <&bmi323_data>; - }; - - lid_accel: lid-accel { - compatible = "cros-ec,bma4xx"; - status = "okay"; - - label = "Lid Accel"; - active-mask = "SENSOR_ACTIVE_S0_S3"; - location = "MOTIONSENSE_LOC_LID"; - mutex = <&lid_mutex>; - port = <&i2c_ec_i2c_sensor>; - rot-standard-ref = <&lid_rot_ref>; - default-range = <2>; - drv-data = <&bma422_data>; configs { compatible = "cros-ec,motionsense-sensor-config"; @@ -138,6 +128,19 @@ }; }; }; + + base_gyro: base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + label = "Base Gyro"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&bmi323_data>; + }; }; motionsense-sensor-info { diff --git a/zephyr/projects/nissa/nereid_pwm_leds.dts b/zephyr/projects/nissa/nereid_pwm_leds.dts index f096211cb5..178a21ea79 100644 --- a/zephyr/projects/nissa/nereid_pwm_leds.dts +++ b/zephyr/projects/nissa/nereid_pwm_leds.dts @@ -7,9 +7,9 @@ pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm1 1 0 PWM_POLARITY_INVERTED>, - <&pwm2 2 0 PWM_POLARITY_INVERTED>, - <&pwm3 3 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm3 3 PWM_HZ(324) PWM_POLARITY_INVERTED>; }; }; diff --git a/zephyr/projects/nissa/nivviks_keyboard.dts b/zephyr/projects/nissa/nivviks_keyboard.dts index 7fc6fcd125..98c452a12d 100644 --- a/zephyr/projects/nissa/nivviks_keyboard.dts +++ b/zephyr/projects/nissa/nivviks_keyboard.dts @@ -6,7 +6,7 @@ / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm6 6 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm6 6 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; }; }; diff --git a/zephyr/projects/nissa/nivviks_motionsense.dts b/zephyr/projects/nissa/nivviks_motionsense.dts index f3619b5aa9..690847af9f 100644 --- a/zephyr/projects/nissa/nivviks_motionsense.dts +++ b/zephyr/projects/nissa/nivviks_motionsense.dts @@ -80,8 +80,38 @@ * List of motion sensors that creates motion_sensors array. * The label "lid_accel" and "base_accel" are used to indicate * motion sensor IDs for lid angle calculation. + * TODO:(b/229577857) The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. */ motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + label = "Lid Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + base_accel: base-accel { compatible = "cros-ec,lsm6dso-accel"; status = "okay"; @@ -123,33 +153,6 @@ rot-standard-ref = <&base_rot_ref>; drv-data = <&lsm6dso_data>; }; - - lid_accel: lid-accel { - compatible = "cros-ec,lis2dw12"; - status = "okay"; - - label = "Lid Accel"; - active-mask = "SENSOR_ACTIVE_S0_S3"; - location = "MOTIONSENSE_LOC_LID"; - mutex = <&lid_mutex>; - port = <&i2c_ec_i2c_sensor>; - rot-standard-ref = <&lid_rot_ref>; - default-range = <2>; - drv-data = <&lis2dw12_data>; - i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; - configs { - compatible = - "cros-ec,motionsense-sensor-config"; - ec-s0 { - label = "SENSOR_CONFIG_EC_S0"; - odr = <(10000 | ROUND_UP_FLAG)>; - }; - ec-s3 { - label = "SENSOR_CONFIG_EC_S3"; - odr = <(10000 | ROUND_UP_FLAG)>; - }; - }; - }; }; motionsense-sensor-info { diff --git a/zephyr/projects/nissa/nivviks_overlay.dts b/zephyr/projects/nissa/nivviks_overlay.dts index 48b395d7f0..1beb0376f4 100644 --- a/zephyr/projects/nissa/nivviks_overlay.dts +++ b/zephyr/projects/nissa/nivviks_overlay.dts @@ -221,7 +221,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm5 5 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm5 5 PWM_KHZ(1) PWM_POLARITY_NORMAL>; pwm-frequency = <1000>; rpm_min = <2200>; rpm_start = <2200>; diff --git a/zephyr/projects/nissa/nivviks_pwm_leds.dts b/zephyr/projects/nissa/nivviks_pwm_leds.dts index 5fb301bfa5..eb9b805a56 100644 --- a/zephyr/projects/nissa/nivviks_pwm_leds.dts +++ b/zephyr/projects/nissa/nivviks_pwm_leds.dts @@ -7,9 +7,9 @@ pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm2 2 0 PWM_POLARITY_INVERTED>, - <&pwm0 0 0 PWM_POLARITY_INVERTED>, - <&pwm1 1 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>; }; }; diff --git a/zephyr/projects/nissa/prj_craask.conf b/zephyr/projects/nissa/prj_craask.conf new file mode 100644 index 0000000000..21789b916b --- /dev/null +++ b/zephyr/projects/nissa/prj_craask.conf @@ -0,0 +1,39 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# EC chip configuration: NPCX993 +CONFIG_BOARD_CRAASK=y +CONFIG_CROS_FLASH_NPCX=y +CONFIG_CROS_SYSTEM_NPCX=y +CONFIG_SOC_SERIES_NPCX9=y +CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y +CONFIG_SYSCON=y +CONFIG_TACH_NPCX=n + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO_AS_BASE=y +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y + +# Keyboard +CONFIG_CROS_KB_RAW_NPCX=y +CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=y + +# TCPC+PPC: both C0 and C1 (if present) are RAA489000 +CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y +# RAA489000 uses TCPCI but not a separate PPC, so custom function is required +CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y +# type C port 1 redriver +CONFIG_PLATFORM_EC_USBC_RETIMER_ANX7483=y + +# Charger driver and configuration +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22 + +# VSENSE: PP3300_S5 & PP1050_PROC +CONFIG_ADC_CMP_NPCX=y +CONFIG_SENSOR=y +CONFIG_SENSOR_SHELL=n diff --git a/zephyr/projects/nissa/src/board_power.c b/zephyr/projects/nissa/src/board_power.c index 83c693e897..b81e28c0f4 100644 --- a/zephyr/projects/nissa/src/board_power.c +++ b/zephyr/projects/nissa/src/board_power.c @@ -44,7 +44,7 @@ void board_ap_power_force_shutdown(void) power_signal_enable(PWR_PG_PP1P05); } - power_signal_set(PWR_EC_PCH_RSMRST, 1); + power_signal_set(PWR_EC_PCH_RSMRST, 0); power_signal_set(PWR_EC_SOC_DSW_PWROK, 0); while (power_signal_get(PWR_RSMRST) == 0 && diff --git a/zephyr/projects/nissa/src/craask/charger.c b/zephyr/projects/nissa/src/craask/charger.c new file mode 100644 index 0000000000..9479367d25 --- /dev/null +++ b/zephyr/projects/nissa/src/craask/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Craask does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + raa489000_hibernate(CHARGER_SECONDARY, true); + raa489000_hibernate(CHARGER_PRIMARY, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/src/craask/usbc.c b/zephyr/projects/nissa/src/craask/usbc.c new file mode 100644 index 0000000000..b4dbad582f --- /dev/null +++ b/zephyr/projects/nissa/src/craask/usbc.c @@ -0,0 +1,283 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, + { /* sub-board */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && + port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + task_set_event(USB_CHG_PORT_TO_TASK_ID(port), USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, + const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int (void) +{ + poll_usb_gpio(0, + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +static void poll_c1_int (void) +{ + poll_usb_gpio(1, + GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + &poll_c1_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } else { + port = 1; + ud = &poll_c1_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} + +const struct usb_mux *nissa_get_c1_sb_mux(void) +{ + static const struct usb_mux usbc1_anx7483 = { + .usb_port = 1, + .i2c_port = I2C_PORT_USB_C1_TCPC, + .i2c_addr_flags = ANX7483_I2C_ADDR0_FLAGS, + .driver = &anx7483_usb_retimer_driver, + }; + return &usbc1_anx7483; +} diff --git a/zephyr/projects/nissa/src/sub_board.c b/zephyr/projects/nissa/src/sub_board.c index 1282ffec54..cb6894e38c 100644 --- a/zephyr/projects/nissa/src/sub_board.c +++ b/zephyr/projects/nissa/src/sub_board.c @@ -28,17 +28,13 @@ static void hdmi_power_handler(struct ap_power_ev_callback *cb, /* Enable rails for S3 */ const struct gpio_dt_spec *s3_rail = GPIO_DT_FROM_ALIAS(gpio_hdmi_en_odl); - /* Enable rails for S5 */ - const struct gpio_dt_spec *s5_rail = - GPIO_DT_FROM_ALIAS(gpio_en_rails_odl); - /* Connect DDC to sub-board */ + /* Connect AP's DDC to sub-board (default is USB-C aux) */ const struct gpio_dt_spec *ddc_select = GPIO_DT_FROM_NODELABEL(gpio_hdmi_sel); switch (data.event) { case AP_POWER_PRE_INIT: - LOG_DBG("Enabling HDMI+USB-A PP5000 and selecting DDC"); - gpio_pin_set_dt(s5_rail, 1); + LOG_DBG("Connecting HDMI DDC to sub-board"); gpio_pin_set_dt(ddc_select, 1); break; case AP_POWER_STARTUP: @@ -50,9 +46,8 @@ static void hdmi_power_handler(struct ap_power_ev_callback *cb, gpio_pin_set_dt(s3_rail, 0); break; case AP_POWER_HARD_OFF: - LOG_DBG("Disabling HDMI+USB-A PP5000 and deselecting DDC"); + LOG_DBG("Disconnecting HDMI sub-board DDC"); gpio_pin_set_dt(ddc_select, 0); - gpio_pin_set_dt(s5_rail, 0); break; default: LOG_ERR("Unhandled HDMI power event %d", data.event); diff --git a/zephyr/projects/npcx_evb/npcx7/fan.dts b/zephyr/projects/npcx_evb/npcx7/fan.dts index 90b6bcb257..d3c53c0bbe 100644 --- a/zephyr/projects/npcx_evb/npcx7/fan.dts +++ b/zephyr/projects/npcx_evb/npcx7/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 0 PWM_KHZ(25) PWM_POLARITY_NORMAL>; pwm-frequency = <25000>; rpm_min = <1000>; rpm_start = <1000>; diff --git a/zephyr/projects/npcx_evb/npcx7/keyboard.dts b/zephyr/projects/npcx_evb/npcx7/keyboard.dts index f9e45d6e80..299e93a52a 100644 --- a/zephyr/projects/npcx_evb/npcx7/keyboard.dts +++ b/zephyr/projects/npcx_evb/npcx7/keyboard.dts @@ -31,7 +31,7 @@ kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm2 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm2 0 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; }; }; diff --git a/zephyr/projects/npcx_evb/npcx9/fan.dts b/zephyr/projects/npcx_evb/npcx9/fan.dts index 90b6bcb257..d3c53c0bbe 100644 --- a/zephyr/projects/npcx_evb/npcx9/fan.dts +++ b/zephyr/projects/npcx_evb/npcx9/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 0 PWM_KHZ(25) PWM_POLARITY_NORMAL>; pwm-frequency = <25000>; rpm_min = <1000>; rpm_start = <1000>; diff --git a/zephyr/projects/npcx_evb/npcx9/keyboard.dts b/zephyr/projects/npcx_evb/npcx9/keyboard.dts index f9e45d6e80..299e93a52a 100644 --- a/zephyr/projects/npcx_evb/npcx9/keyboard.dts +++ b/zephyr/projects/npcx_evb/npcx9/keyboard.dts @@ -31,7 +31,7 @@ kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm2 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm2 0 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; }; }; diff --git a/zephyr/projects/skyrim/fan.dts b/zephyr/projects/skyrim/fan.dts index 84fbfe675f..ba104044b2 100644 --- a/zephyr/projects/skyrim/fan.dts +++ b/zephyr/projects/skyrim/fan.dts @@ -8,7 +8,7 @@ compatible = "cros-ec,fans"; fan_0 { - pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 0 PWM_KHZ(25) PWM_POLARITY_NORMAL>; pwm-frequency = <25000>; rpm_min = <3100>; rpm_start = <3100>; diff --git a/zephyr/projects/skyrim/keyboard.dts b/zephyr/projects/skyrim/keyboard.dts index b574a6d97e..bc20b259dc 100644 --- a/zephyr/projects/skyrim/keyboard.dts +++ b/zephyr/projects/skyrim/keyboard.dts @@ -6,7 +6,7 @@ / { kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm1 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm1 0 PWM_HZ(100) PWM_POLARITY_NORMAL>; frequency = <100>; }; }; diff --git a/zephyr/projects/skyrim/pwm_leds.dts b/zephyr/projects/skyrim/pwm_leds.dts index 44bdc8bba6..7c70b7ce88 100644 --- a/zephyr/projects/skyrim/pwm_leds.dts +++ b/zephyr/projects/skyrim/pwm_leds.dts @@ -7,8 +7,8 @@ pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { - pwms = <&pwm2 0 0 PWM_POLARITY_INVERTED - &pwm3 0 0 PWM_POLARITY_INVERTED>; + pwms = <&pwm2 0 PWM_HZ(100) PWM_POLARITY_INVERTED + &pwm3 0 PWM_HZ(100) PWM_POLARITY_INVERTED>; }; }; diff --git a/zephyr/projects/trogdor/lazor/display.dts b/zephyr/projects/trogdor/lazor/display.dts index d683aa931f..6487e85255 100644 --- a/zephyr/projects/trogdor/lazor/display.dts +++ b/zephyr/projects/trogdor/lazor/display.dts @@ -6,7 +6,7 @@ / { displight { compatible = "cros-ec,displight"; - pwms = <&pwm5 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm5 0 PWM_HZ(4800) PWM_POLARITY_NORMAL>; frequency = <4800>; generic-pwm-channel = <1>; }; diff --git a/zephyr/projects/trogdor/lazor/keyboard.dts b/zephyr/projects/trogdor/lazor/keyboard.dts index 5a931c48b1..9a4fc0dd77 100644 --- a/zephyr/projects/trogdor/lazor/keyboard.dts +++ b/zephyr/projects/trogdor/lazor/keyboard.dts @@ -26,7 +26,7 @@ kblight { compatible = "cros-ec,kblight-pwm"; - pwms = <&pwm3 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm3 0 PWM_KHZ(10) PWM_POLARITY_NORMAL>; frequency = <10000>; generic-pwm-channel = <0>; }; diff --git a/zephyr/projects/trogdor/lazor/led.dts b/zephyr/projects/trogdor/lazor/led.dts index a4f78b82ee..aa9f43c3d9 100644 --- a/zephyr/projects/trogdor/lazor/led.dts +++ b/zephyr/projects/trogdor/lazor/led.dts @@ -7,6 +7,7 @@ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -16,6 +17,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -26,10 +28,12 @@ /* Amber 1 sec, off 3 sec */ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; color-1 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <3000>; }; }; @@ -40,6 +44,7 @@ color-0 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -49,10 +54,12 @@ /* Amber 1 sec, off 1 sec */ color-0 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; color-1 { led-color = "LED_OFF"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <1000>; }; }; @@ -62,6 +69,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; @@ -72,10 +80,12 @@ /* Blue 2 sec, Amber 2 sec */ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <2000>; }; color-1 { led-color = "LED_AMBER"; + led-id = "EC_LED_ID_BATTERY_LED"; period-ms = <2000>; }; }; @@ -86,6 +96,7 @@ color-0 { led-color = "LED_BLUE"; + led-id = "EC_LED_ID_BATTERY_LED"; }; }; }; diff --git a/zephyr/projects/trogdor/lazor/pwm_led.dts b/zephyr/projects/trogdor/lazor/pwm_led.dts index 0450c907af..e4823bd104 100644 --- a/zephyr/projects/trogdor/lazor/pwm_led.dts +++ b/zephyr/projects/trogdor/lazor/pwm_led.dts @@ -9,12 +9,12 @@ pwm_y: pwm_y { #led-pin-cells = <1>; - pwms = <&pwm0 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm0 0 PWM_HZ(324) PWM_POLARITY_NORMAL>; }; pwm_b: pwm_b { #led-pin-cells = <1>; - pwms = <&pwm2 0 0 PWM_POLARITY_NORMAL>; + pwms = <&pwm2 0 PWM_HZ(324) PWM_POLARITY_NORMAL>; }; }; diff --git a/zephyr/shim/chip/it8xxx2/power_policy.c b/zephyr/shim/chip/it8xxx2/power_policy.c index 7ef0259ae2..e1d9ea7bb2 100644 --- a/zephyr/shim/chip/it8xxx2/power_policy.c +++ b/zephyr/shim/chip/it8xxx2/power_policy.c @@ -30,7 +30,7 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) * could be used. */ if (pm_policy_state_lock_is_active( - pm_states[i].state)) { + pm_states[i].state, PM_ALL_SUBSTATES)) { continue; } diff --git a/zephyr/shim/chip/mchp/CMakeLists.txt b/zephyr/shim/chip/mchp/CMakeLists.txt index 6526ca3876..0948424275 100644 --- a/zephyr/shim/chip/mchp/CMakeLists.txt +++ b/zephyr/shim/chip/mchp/CMakeLists.txt @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -zephyr_library_include_directories(include) +cros_ec_library_include_directories(include) zephyr_library_sources(clock.c) zephyr_library_sources(gpio.c) diff --git a/zephyr/shim/chip/mchp/gpio.c b/zephyr/shim/chip/mchp/gpio.c index eaffbf5c28..f7e042d693 100644 --- a/zephyr/shim/chip/mchp/gpio.c +++ b/zephyr/shim/chip/mchp/gpio.c @@ -4,10 +4,9 @@ */ #include <device.h> +#include <drivers/gpio.h> #include <kernel.h> #include <logging/log.h> - -#include "gpio.h" #include "gpio/gpio.h" LOG_MODULE_REGISTER(shim_cros_gpio, LOG_LEVEL_ERR); diff --git a/zephyr/shim/chip/npcx/power_policy.c b/zephyr/shim/chip/npcx/power_policy.c index df7d2ff7a2..c95fcc56d8 100644 --- a/zephyr/shim/chip/npcx/power_policy.c +++ b/zephyr/shim/chip/npcx/power_policy.c @@ -23,7 +23,8 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) if (DEEP_SLEEP_ALLOWED) { for (int i = ARRAY_SIZE(residency_info) - 1; i >= 0; i--) { if (pm_policy_state_lock_is_active( - residency_info[i].state)) { + residency_info[i].state, + PM_ALL_SUBSTATES)) { continue; } diff --git a/zephyr/shim/include/board_led.h b/zephyr/shim/include/board_led.h index 9f775d4f1b..205c96c4c3 100644 --- a/zephyr/shim/include/board_led.h +++ b/zephyr/shim/include/board_led.h @@ -19,6 +19,6 @@ struct board_led_pwm_dt_channel { .flags = DT_PWMS_FLAGS(node_id), \ } -#define BOARD_LED_HZ_TO_PERIOD_US(freq_hz) (USEC_PER_SEC / freq_hz) +#define BOARD_LED_HZ_TO_PERIOD_NS(freq_hz) (NSEC_PER_SEC / freq_hz) #endif /* __BOARD_LED_H */ diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 93a1689787..ceaaa17193 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -190,6 +190,11 @@ #define CONFIG_BATTERY_V2 #endif +#undef CONFIG_HOSTCMD_BATTERY_V2 +#ifdef CONFIG_PLATFORM_EC_HOSTCMD_BATTERY_V2 +#define CONFIG_HOSTCMD_BATTERY_V2 +#endif + #undef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT #ifdef CONFIG_PLATFORM_EC_BATTERY_TYPE_NO_AUTO_DETECT #define CONFIG_BATTERY_TYPE_NO_AUTO_DETECT @@ -811,6 +816,11 @@ extern struct jump_data mock_jump_data; #define CONFIG_CPU_PROCHOT_ACTIVE_LOW #endif +#undef CONFIG_CPU_PROCHOT_GATE_ON_C10 +#ifdef CONFIG_PLATFORM_EC_POWERSEQ_CPU_PROCHOT_GATE_ON_C10 +#define CONFIG_CPU_PROCHOT_GATE_ON_C10 +#endif + #undef CONFIG_POWER_TRACK_HOST_SLEEP_STATE #if defined(CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP) || \ defined(CONFIG_AP_PWRSEQ_HOST_SLEEP) diff --git a/zephyr/shim/src/fan.c b/zephyr/shim/src/fan.c index 6051146897..49afb0f508 100644 --- a/zephyr/shim/src/fan.c +++ b/zephyr/shim/src/fan.c @@ -56,7 +56,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, .pwm = DEVICE_DT_GET(DT_PWMS_CTLR(node_id)), \ .channel = DT_PWMS_CHANNEL(node_id), \ .flags = DT_PWMS_FLAGS(node_id), \ - .period_us = (USEC_PER_SEC/DT_PROP(node_id, pwm_frequency)), \ + .period_ns = (NSEC_PER_SEC/DT_PROP(node_id, pwm_frequency)), \ .tach = DEVICE_DT_GET(DT_PHANDLE(node_id, tach)), \ }, @@ -107,7 +107,7 @@ struct fan_config { const struct device *pwm; uint32_t channel; pwm_flags_t flags; - uint32_t period_us; + uint32_t period_ns; const struct device *tach; }; @@ -121,7 +121,7 @@ static void fan_pwm_update(int ch) { const struct fan_config *cfg = &fan_config[ch]; struct fan_data *data = &fan_data[ch]; - uint32_t pulse_us; + uint32_t pulse_ns; int ret; if (!device_is_ready(cfg->pwm)) { @@ -130,20 +130,19 @@ static void fan_pwm_update(int ch) } if (data->pwm_enabled) { - pulse_us = DIV_ROUND_NEAREST( - cfg->period_us * data->pwm_percent, 100); + pulse_ns = DIV_ROUND_NEAREST( + cfg->period_ns * data->pwm_percent, 100); } else { - pulse_us = 0; + pulse_ns = 0; } LOG_DBG("FAN PWM %s set percent (%d), pulse %d", cfg->pwm->name, - data->pwm_percent, pulse_us); + data->pwm_percent, pulse_ns); - ret = pwm_pin_set_usec(cfg->pwm, cfg->channel, cfg->period_us, - pulse_us, cfg->flags); + ret = pwm_set(cfg->pwm, cfg->channel, cfg->period_ns, pulse_ns, + cfg->flags); if (ret) { - LOG_ERR("pwm_pin_set_usec() failed %s (%d)", - cfg->pwm->name, ret); + LOG_ERR("pwm_set() failed %s (%d)", cfg->pwm->name, ret); } } diff --git a/zephyr/shim/src/led_driver/led.c b/zephyr/shim/src/led_driver/led.c index 61cffa1958..b48641bc8f 100644 --- a/zephyr/shim/src/led_driver/led.c +++ b/zephyr/shim/src/led_driver/led.c @@ -27,7 +27,8 @@ LOG_MODULE_REGISTER(gpio_led, LOG_LEVEL_ERR); #define LED_COLOR_NODE DT_PATH(led_colors) struct led_color_node_t { - int led_color; + enum led_color color; + enum ec_led_id led_id; int acc_period; }; @@ -58,6 +59,7 @@ struct node_prop_t { enum charge_state pwr_state; enum power_state chipset_state; enum led_extra_flag_t led_extra_flag; + int charge_port; struct led_color_node_t led_colors[MAX_COLOR]; }; @@ -85,8 +87,10 @@ struct node_prop_t { #define LED_COLOR_INIT(color_num, color_num_plus_one, state_id) \ { \ - .led_color = GET_PROP(DT_CHILD(state_id, color_##color_num), \ + .color = GET_PROP(DT_CHILD(state_id, color_##color_num), \ led_color), \ + .led_id = GET_PROP_NVE(DT_CHILD(state_id, color_##color_num), \ + led_id), \ .acc_period = ACC_PERIOD(color_num_plus_one, state_id) \ } @@ -97,6 +101,9 @@ struct node_prop_t { { \ .pwr_state = GET_PROP(state_id, charge_state), \ .chipset_state = GET_PROP(state_id, chipset_state), \ + .charge_port = COND_CODE_1( \ + DT_NODE_HAS_PROP(state_id, charge_port), \ + (DT_PROP(state_id, charge_port)), (-1)), \ .led_extra_flag = GET_PROP(state_id, extra_flag), \ .led_colors = {LED_COLOR_INIT(0, 1, state_id), \ LED_COLOR_INIT(1, 2, state_id), \ @@ -168,100 +175,120 @@ static bool find_node_with_extra_flag(int i) return found_node; } -static int find_node(void) -{ - int i = 0; - - for (i = 0; i < ARRAY_SIZE(node_array); i++) { - /* Check if this node depends on power state */ - if (node_array[i].pwr_state != PWR_STATE_UNCHANGE) { - enum charge_state pwr_state = charge_get_state(); - - if (node_array[i].pwr_state != pwr_state) - continue; - } - - /* Check if this node depends on chipset state */ - if (node_array[i].chipset_state != 0) { - enum power_state chipset_state = - get_chipset_state(); - - /* Continue at current index as nodes are in sequence */ - if (node_array[i].chipset_state != chipset_state) - continue; - } +#define GET_PERIOD(n_idx, c_idx) node_array[n_idx].led_colors[c_idx].acc_period +#define GET_COLOR(n_idx, c_idx) node_array[n_idx].led_colors[c_idx].color +#define GET_ID(n_idx, c_idx) node_array[n_idx].led_colors[c_idx].led_id - /* Check if the node depends on any special flags */ - if (node_array[i].led_extra_flag != NONE) - if (!find_node_with_extra_flag(i)) - continue; +static void set_color(int node_idx, uint32_t ticks) +{ + int color_idx = 0; - /* We found the node */ - return i; + /* If accumulated period value is not 0, it's a blinking LED */ + if (GET_PERIOD(node_idx, MAX_COLOR - 1) != 0) { + /* Period is accumulated at the last index */ + ticks = ticks % GET_PERIOD(node_idx, MAX_COLOR - 1); } /* - * Didn't find a valid node that matches all the properties - * Return -1 to signify error + * Period value of 0 indicates solid LED color (non-blinking) + * In case of dual port battery LEDs, period value of 0 is + * also used to turn-off non-active port LED + * Nodes with period value of 0 strictly need to be listed before + * nodes with non-zero period values as we are accumulating the + * period at each node. + * + * TODO: Remove the strict sequence requirement for listing the + * zero-period value nodes. */ - return -1; + for (color_idx = 0; color_idx < MAX_COLOR; color_idx++) { + enum ec_led_id led_id = GET_ID(node_idx, color_idx); + enum led_color color = GET_COLOR(node_idx, color_idx); + int period = GET_PERIOD(node_idx, color_idx); + + if (led_id == 0xFF) + break; /* No more valid color nodes, break here */ + + if (!led_auto_control_is_enabled(led_id)) + break; /* Auto control is disabled */ + + /* + * Period value that we use here is in terms of number + * of ticks stored during initialization of the struct + */ + if (period == 0) + led_set_color(color, led_id); + else if (ticks < period) { + led_set_color(color, led_id); + break; + } + } } -#define GET_PERIOD(n_idx, c_idx) node_array[n_idx].led_colors[c_idx].acc_period -#define GET_COLOR(n_idx, c_idx) node_array[n_idx].led_colors[c_idx].led_color - -static int find_color(int node_idx, uint32_t ticks) +static int match_node(int node_idx) { - int color_idx = 0; + /* Check if this node depends on power state */ + if (node_array[node_idx].pwr_state != PWR_STATE_UNCHANGE) { + enum charge_state pwr_state = charge_get_state(); - /* If period value at index 0 is not 0, it's a blinking LED */ - if (GET_PERIOD(node_idx, 0) != 0) { - /* Period is accumulated at the last index */ - ticks = ticks % GET_PERIOD(node_idx, MAX_COLOR - 1); + if (node_array[node_idx].pwr_state != pwr_state) + return -1; + + /* Check if this node depends on charge port */ + if (node_array[node_idx].charge_port != -1) { + int port = charge_manager_get_active_charge_port(); - for (color_idx = 0; color_idx < MAX_COLOR; color_idx++) { - /* - * Period value that we use here is in terms of number - * of ticks stored during initialization of the struct - */ - if (ticks < GET_PERIOD(node_idx, color_idx)) - break; + if (node_array[node_idx].charge_port != port) + return -1; } } - return GET_COLOR(node_idx, color_idx); + /* Check if this node depends on chipset state */ + if (node_array[node_idx].chipset_state != 0) { + enum power_state chipset_state = get_chipset_state(); + + if (node_array[node_idx].chipset_state != chipset_state) + return -1; + } + + /* Check if the node depends on any special flags */ + if (node_array[node_idx].led_extra_flag != NONE) + if (!find_node_with_extra_flag(node_idx)) + return -1; + + /* We found the node that matches the current system state */ + return node_idx; } static void board_led_set_color(void) { - int color = LED_OFF; - int node = 0; static uint32_t ticks; + bool found_node = false; ticks++; /* - * Find a node that matches the current state of the system. Depending - * on the policy defined in led.dts, a node could depend on power-state, - * chipset-state, extra flags like battery percentage etc. - * We should always find a node that indicates the LED Behavior for + * Find all the nodes that match the current state of the system and + * set color for these nodes. Depending on the policy defined in + * led.dts, a node could depend on power-state, chipset-state, extra + * flags like battery percentage etc. + * We must find at least one node that indicates the LED Behavior for * current system state. */ - node = find_node(); - - if (node < 0) - LOG_ERR("Invalid node id, node with matching prop not found"); - else - color = find_color(node, ticks); + for (int i = 0; i < ARRAY_SIZE(node_array); i++) { + if (match_node(i) != -1) { + found_node = true; + set_color(i, ticks); + } + } - led_set_color(color); + if (!found_node) + LOG_ERR("Node with matching prop not found"); } -/* Called by hook task every second */ +/* Called by hook task every HOOK_TICK_INTERVAL_MS */ static void led_tick(void) { - if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) - board_led_set_color(); + board_led_set_color(); } DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); @@ -283,5 +310,5 @@ void led_control(enum ec_led_id led_id, enum ec_led_state state) led_auto_control(EC_LED_ID_BATTERY_LED, 0); - led_set_color(color); + led_set_color(color, led_id); } diff --git a/zephyr/shim/src/led_driver/led.h b/zephyr/shim/src/led_driver/led.h index 086d2312b5..f802142c18 100644 --- a/zephyr/shim/src/led_driver/led.h +++ b/zephyr/shim/src/led_driver/led.h @@ -11,12 +11,20 @@ #define COMPAT_GPIO_LED cros_ec_gpio_led_pins #define COMPAT_PWM_LED cros_ec_pwm_led_pins +#define PINS_ARRAY(id) DT_CAT(PINS_ARRAY_, id) + +/* + * Return string-token if the property exists, otherwise return 0 + */ #define GET_PROP(id, prop) \ COND_CODE_1(DT_NODE_HAS_PROP(id, prop), \ (DT_STRING_UPPER_TOKEN(id, prop)), \ (0)) -#define GET_BR_COLOR(id, prop) \ +/* + * Return string-token if the property exists, otherwise return -1 + */ +#define GET_PROP_NVE(id, prop) \ COND_CODE_1(DT_NODE_HAS_PROP(id, prop), \ (DT_STRING_UPPER_TOKEN(id, prop)), \ (-1)) @@ -30,13 +38,13 @@ #define PWM_LED_PINS_NODE DT_PATH(pwm_led_pins) enum led_color { -#if DT_NODE_EXISTS(GPIO_LED_PINS_NODE) - DT_FOREACH_CHILD_VARGS(GPIO_LED_PINS_NODE, - LED_ENUM_WITH_COMMA, led_color) -#elif DT_NODE_EXISTS(PWM_LED_PINS_NODE) - DT_FOREACH_CHILD_VARGS(PWM_LED_PINS_NODE, - LED_ENUM_WITH_COMMA, led_color) -#endif + LED_OFF, + LED_RED, + LED_GREEN, + LED_BLUE, + LED_YELLOW, + LED_WHITE, + LED_AMBER, LED_COLOR_COUNT /* Number of colors, not a color itself */ }; @@ -45,6 +53,6 @@ enum led_color { * * @param color LED Color to enable */ -void led_set_color(enum led_color color); +void led_set_color(enum led_color color, enum ec_led_id led_id); #endif /* __CROS_EC_LED_H__ */ diff --git a/zephyr/shim/src/led_driver/led_gpio.c b/zephyr/shim/src/led_driver/led_gpio.c index 89ab1caa3d..2395e4b510 100644 --- a/zephyr/shim/src/led_driver/led_gpio.c +++ b/zephyr/shim/src/led_driver/led_gpio.c @@ -17,8 +17,6 @@ LOG_MODULE_REGISTER(gpio_led, LOG_LEVEL_ERR); -#define LED_PIN_COUNT (LED_COLOR_COUNT - 1) - /* * Struct defining LED GPIO pin and value to set. */ @@ -45,7 +43,10 @@ struct led_pins_node_t { enum ec_led_colors br_color; /* Array of GPIO pins to set to enable particular color */ - struct gpio_pin_t gpio_pins[LED_PIN_COUNT]; + struct gpio_pin_t *gpio_pins; + + /* Number of pins per color */ + uint8_t pins_count; }; #define SET_PIN(node_id, prop, i) \ @@ -57,14 +58,20 @@ struct led_pins_node_t { #define SET_GPIO_PIN(node_id) \ { \ DT_FOREACH_PROP_ELEM(node_id, led_pins, SET_PIN) \ -} +}; + +#define GEN_PINS_ARRAY(id) \ +struct gpio_pin_t PINS_ARRAY(id)[] = SET_GPIO_PIN(id) + +DT_FOREACH_CHILD(GPIO_LED_PINS_NODE, 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), \ - .br_color = GET_BR_COLOR(node_id, br_color), \ - .gpio_pins = SET_GPIO_PIN(node_id) \ + .br_color = GET_PROP_NVE(node_id, br_color), \ + .gpio_pins = PINS_ARRAY(node_id), \ + .pins_count = DT_PROP_LEN(node_id, led_pins) \ }, struct led_pins_node_t pins_node[] = { @@ -76,15 +83,17 @@ struct led_pins_node_t pins_node[] = { * Set all the GPIO pins defined in the node to the defined value, * to enable the color. */ -void led_set_color(enum led_color color) +void led_set_color(enum led_color color, enum ec_led_id led_id) { - for (int i = 0; i < LED_COLOR_COUNT; i++) { - if (pins_node[i].led_color == color) { - for (int j = 0; j < LED_PIN_COUNT; j++) { + for (int i = 0; i < ARRAY_SIZE(pins_node); i++) { + if ((pins_node[i].led_color == color) && + (pins_node[i].led_id == led_id)) { + for (int j = 0; j < pins_node[i].pins_count; j++) { gpio_pin_set_dt(gpio_get_dt_spec( pins_node[i].gpio_pins[j].signal), pins_node[i].gpio_pins[j].val); } + break; /* Found the matching pin node, break here */ } } } @@ -108,13 +117,13 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) if ((br_color != -1) && (brightness[br_color] != 0)) { color_set = true; - led_set_color(pins_node[i].led_color); + led_set_color(pins_node[i].led_color, led_id); } } /* If no color was set, turn off the LED */ if (!color_set) - led_set_color(LED_OFF); + led_set_color(LED_OFF, led_id); return EC_SUCCESS; } diff --git a/zephyr/shim/src/led_driver/led_pwm.c b/zephyr/shim/src/led_driver/led_pwm.c index f61934c68b..eee80243cb 100644 --- a/zephyr/shim/src/led_driver/led_pwm.c +++ b/zephyr/shim/src/led_driver/led_pwm.c @@ -17,8 +17,6 @@ LOG_MODULE_REGISTER(pwm_led, LOG_LEVEL_ERR); -#define LED_PIN_COUNT (LED_COLOR_COUNT - 1) - /* * Struct defining LED PWM pin and duty cycle to set. */ @@ -26,7 +24,7 @@ struct pwm_pin_t { const struct device *pwm; uint8_t channel; pwm_flags_t flags; - uint32_t pulse_us; /* PWM Duty cycle us */ + uint32_t pulse_ns; /* PWM Duty cycle ns */ }; /* @@ -47,21 +45,24 @@ struct led_pins_node_t { enum ec_led_colors br_color; /* Array of PWM pins to set to enable particular color */ - struct pwm_pin_t pwm_pins[LED_PIN_COUNT]; + struct pwm_pin_t *pwm_pins; + + /* Number of pins per color */ + uint8_t pins_count; }; /* - * Period in us from frequency(Hz) defined in pins node + * Period in ns from frequency(Hz) defined in pins node * period in sec = 1/freq - * period in usec = (1*usec_per_sec)/freq - * This value is also used calculate duty_cycle in us (pulse_us below). - * Duty cycle in perct defined in pin node is used to calculate pulse_us - * pulse_us = (period_us*duty_cycle_in_perct)/100 - * Eg. freq = 500 Hz, period_us = 1000000/500 = 2000us - * duty_cycle = 50 %, pulse_us = (2000*50)/100 = 1000us + * period in nsec = (1*nsec_per_sec)/freq + * This value is also used calculate duty_cycle in ns (pulse_ns below). + * Duty cycle in perct defined in pin node is used to calculate pulse_ns + * pulse_ns = (period_ns*duty_cycle_in_perct)/100 + * e.g. freq = 500 Hz, period_ns = 1000000000/500 = 2000000ns + * duty_cycle = 50 %, pulse_ns = (2000000*50)/100 = 1000000ns */ -const uint32_t period_us = - (USEC_PER_SEC / DT_PROP(PWM_LED_PINS_NODE, pwm_frequency)); +const uint32_t period_ns = + (NSEC_PER_SEC / DT_PROP(PWM_LED_PINS_NODE, pwm_frequency)); #define SET_PIN(node_id, prop, i) \ { \ @@ -70,20 +71,27 @@ const uint32_t period_us = .channel = DT_PWMS_CHANNEL( \ DT_PHANDLE_BY_IDX(node_id, prop, i)), \ .flags = DT_PWMS_FLAGS(DT_PHANDLE_BY_IDX(node_id, prop, i)), \ - .pulse_us = DIV_ROUND_NEAREST( \ - period_us * DT_PHA_BY_IDX(node_id, prop, i, value), 100), \ + .pulse_ns = DIV_ROUND_NEAREST( \ + period_ns * DT_PHA_BY_IDX(node_id, prop, i, value), 100), \ }, #define SET_PWM_PIN(node_id) \ { \ DT_FOREACH_PROP_ELEM(node_id, led_pins, SET_PIN) \ -} +}; + +#define GEN_PINS_ARRAY(id) \ +struct pwm_pin_t PINS_ARRAY(id)[] = SET_PWM_PIN(id) + +DT_FOREACH_CHILD(PWM_LED_PINS_NODE, GEN_PINS_ARRAY) #define SET_PIN_NODE(node_id) \ { \ .led_color = GET_PROP(node_id, led_color), \ - .br_color = GET_BR_COLOR(node_id, br_color), \ - .pwm_pins = SET_PWM_PIN(node_id) \ + .led_id = GET_PROP(node_id, led_id), \ + .br_color = GET_PROP_NVE(node_id, br_color), \ + .pwm_pins = PINS_ARRAY(node_id), \ + .pins_count = DT_PROP_LEN(node_id, led_pins) \ }, struct led_pins_node_t pins_node[] = { @@ -94,18 +102,19 @@ struct led_pins_node_t pins_node[] = { * Iterate through LED pins nodes to find the color matching node. * Set all the PWM channels defined in the node to the defined value, * to enable the color. Defined value is duty cycle in percentage - * converted to duty cycle in us (pulse_us) + * converted to duty cycle in ns (pulse_ns) */ -void led_set_color(enum led_color color) +void led_set_color(enum led_color color, enum ec_led_id led_id) { - for (int i = 0; i < LED_COLOR_COUNT; i++) { - if (pins_node[i].led_color == color) { - for (int j = 0; j < LED_PIN_COUNT; j++) { - pwm_pin_set_usec( + for (int i = 0; i < ARRAY_SIZE(pins_node); i++) { + if ((pins_node[i].led_color == color) && + (pins_node[i].led_id == led_id)) { + for (int j = 0; j < pins_node[i].pins_count; j++) { + pwm_set( pins_node[i].pwm_pins[j].pwm, pins_node[i].pwm_pins[j].channel, - period_us, - pins_node[i].pwm_pins[j].pulse_us, + period_ns, + pins_node[i].pwm_pins[j].pulse_ns, pins_node[i].pwm_pins[j].flags); } break; /* Found the matching pin node, break here */ @@ -132,13 +141,13 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) if ((br_color != -1) && (brightness[br_color] != 0)) { color_set = true; - led_set_color(pins_node[i].led_color); + led_set_color(pins_node[i].led_color, led_id); } } /* If no color was set, turn off the LED */ if (!color_set) - led_set_color(LED_OFF); + led_set_color(LED_OFF, led_id); return EC_SUCCESS; } diff --git a/zephyr/shim/src/pwm_led.c b/zephyr/shim/src/pwm_led.c index cfa7005f04..5a72a07395 100644 --- a/zephyr/shim/src/pwm_led.c +++ b/zephyr/shim/src/pwm_led.c @@ -25,8 +25,8 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1, BUILD_ASSERT(DT_INST_PROP_LEN(0, leds) <= 2, "Unsupported number of LEDs defined"); -#define PWM_LED_PERIOD_US (USEC_PER_SEC/DT_INST_PROP(0, frequency)) -#define PWM_SIDESEL_PERIOD_US (PWM_LED_PERIOD_US * 2) +#define PWM_LED_PERIOD_NS (NSEC_PER_SEC/DT_INST_PROP(0, frequency)) +#define PWM_SIDESEL_PERIOD_NS (PWM_LED_PERIOD_NS * 2) #define PWM_LED_NAME(node_id) DT_STRING_UPPER_TOKEN(node_id, ec_led_name) #define PWM_LED_NAME_WITH_COMMA(node_id) PWM_LED_NAME(node_id), @@ -41,7 +41,7 @@ BUILD_ASSERT(ARRAY_SIZE(supported_led_ids) == DT_INST_PROP_LEN(0, leds), static void pwm_led_set_duty(const struct pwm_led_dt_channel *ch, int percent) { - uint32_t pulse_us; + uint32_t pulse_ns; int rv; if (!device_is_ready(ch->dev)) { @@ -49,31 +49,30 @@ static void pwm_led_set_duty(const struct pwm_led_dt_channel *ch, int percent) return; } - pulse_us = DIV_ROUND_NEAREST(ch->period_us * percent, 100); + pulse_ns = DIV_ROUND_NEAREST(ch->period_ns * percent, 100); LOG_DBG("LED PWM %s set percent (%d), pulse %d", ch->dev->name, percent, - pulse_us); + pulse_ns); - rv = pwm_pin_set_usec(ch->dev, ch->channel, ch->period_us, pulse_us, - ch->flags); + rv = pwm_set(ch->dev, ch->channel, ch->period_ns, pulse_ns, ch->flags); if (rv) { - LOG_ERR("pwm_pin_set_usec() failed %s (%d)", ch->dev->name, rv); + LOG_ERR("pwm_set() failed %s (%d)", ch->dev->name, rv); } } -#define PWM_CHANNEL_DT_BY_IDX_INIT(node_id, led_ch, _period_us) \ +#define PWM_CHANNEL_DT_BY_IDX_INIT(node_id, led_ch, _period_ns) \ { \ .dev = DEVICE_DT_GET(DT_PWMS_CTLR_BY_IDX(node_id, led_ch)), \ .channel = DT_PWMS_CHANNEL_BY_IDX(node_id, led_ch), \ .flags = DT_PWMS_FLAGS_BY_IDX(node_id, led_ch), \ - .period_us = _period_us, \ + .period_ns = _period_ns, \ } #define PWM_CHANNEL_DT_BY_IDX(node_id, prop, idx, led_ch) \ static const struct pwm_led_dt_channel _pwm_led_dt_##idx##_ch_##led_ch = \ PWM_CHANNEL_DT_BY_IDX_INIT( \ DT_PHANDLE_BY_IDX(node_id, prop, idx), led_ch, \ - PWM_LED_PERIOD_US); + PWM_LED_PERIOD_NS); #define PWM_CHANNEL_DT_BY_IDX_COND(node_id, prop, idx, led_ch) \ IF_ENABLED(DT_PROP_HAS_IDX( \ @@ -181,7 +180,7 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) static const struct pwm_led_dt_channel _pwm_led_dt_sidesel = PWM_CHANNEL_DT_BY_IDX_INIT(DT_INST_PROP(0, sidesel), 0, - PWM_SIDESEL_PERIOD_US); + PWM_SIDESEL_PERIOD_NS); /* Illuminates the LED on the side of the active charging port. If not charging, * illuminates both LEDs. diff --git a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h index cd7aa87b1d..4d127a5672 100644 --- a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h +++ b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h @@ -22,6 +22,7 @@ enum power_states_ndsx chipset_pwr_sm_run(enum power_states_ndsx curr_state); void init_chipset_pwr_seq_state(void); +enum power_states_ndsx chipset_pwr_seq_get_state(void); void request_exit_hardoff(bool should_exit); enum power_states_ndsx pwr_sm_get_state(void); void apshutdown(void); diff --git a/zephyr/subsys/ap_pwrseq/signal_adc.c b/zephyr/subsys/ap_pwrseq/signal_adc.c index a5f7ddddaa..b2c0598c29 100644 --- a/zephyr/subsys/ap_pwrseq/signal_adc.c +++ b/zephyr/subsys/ap_pwrseq/signal_adc.c @@ -98,17 +98,17 @@ static void set_high_trigger(enum pwr_sig_adc adc, bool enable) static void trigger_high(enum pwr_sig_adc adc) { + set_high_trigger(adc, false); atomic_set_bit(&adc_state[adc], ADC_BIT_VALUE); set_low_trigger(adc, true); - set_high_trigger(adc, false); LOG_DBG("power signal adc%d is HIGH", adc); power_signal_interrupt(config[adc].signal, 1); } static void trigger_low(enum pwr_sig_adc adc) { - atomic_clear_bit(&adc_state[adc], ADC_BIT_VALUE); set_low_trigger(adc, false); + atomic_clear_bit(&adc_state[adc], ADC_BIT_VALUE); set_high_trigger(adc, true); LOG_DBG("power signal adc%d is LOW", adc); power_signal_interrupt(config[adc].signal, 0); diff --git a/zephyr/subsys/ap_pwrseq/signal_vw.c b/zephyr/subsys/ap_pwrseq/signal_vw.c index ea22c48d08..d74c260ead 100644 --- a/zephyr/subsys/ap_pwrseq/signal_vw.c +++ b/zephyr/subsys/ap_pwrseq/signal_vw.c @@ -121,6 +121,8 @@ void power_signal_vw_init(void) vw_config[i].invert ? !vw_value : !!vw_value); + atomic_set_bit(&signal_valid, i); + } } } diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_adlp_pwrseq_sm.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_adlp_pwrseq_sm.c index 5567915737..3280aaec35 100644 --- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_adlp_pwrseq_sm.c +++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_adlp_pwrseq_sm.c @@ -162,6 +162,99 @@ void init_chipset_pwr_seq_state(void) power_signal_set(PWR_SYS_RST, 0); } +/** + * Determine the current state of the CPU from the + * power signals. + */ +enum power_states_ndsx chipset_pwr_seq_get_state(void) +{ +#define MASK_ALL_POWER_GOOD \ + (POWER_SIGNAL_MASK(PWR_RSMRST) | \ + POWER_SIGNAL_MASK(PWR_ALL_SYS_PWRGD) | \ + POWER_SIGNAL_MASK(PWR_DSW_PWROK) | \ + POWER_SIGNAL_MASK(PWR_PG_PP1P05)) +#define MASK_S0 \ + (MASK_ALL_POWER_GOOD | \ + POWER_SIGNAL_MASK(PWR_SLP_S0) | \ + POWER_SIGNAL_MASK(PWR_SLP_S3) | \ + POWER_SIGNAL_MASK(PWR_SLP_SUS) | \ + POWER_SIGNAL_MASK(PWR_SLP_S4) | \ + POWER_SIGNAL_MASK(PWR_SLP_S5)) +#define MASK_S5 \ + (MASK_ALL_POWER_GOOD | \ + POWER_SIGNAL_MASK(PWR_SLP_S5)) + + /* + * Chip is shut down. + */ + if ((power_get_signals() & MASK_ALL_POWER_GOOD) == 0) { + LOG_DBG("Power rails off, G3 state"); + return SYS_POWER_STATE_G3; + } + /* + * If not all the power rails are available, + * then force shutdown to G3 to get to known state. + */ + if ((power_get_signals() & MASK_ALL_POWER_GOOD) + != MASK_ALL_POWER_GOOD) { + ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3); + LOG_INF("Not all power rails up, forcing shutdown"); + return SYS_POWER_STATE_G3; + } + + /* + * All the power rails are good, so + * wait for virtual wire signals to become available. + * Not sure how long to wait? 5 seconds total. + */ + for (int delay = 0; delay < 500; k_msleep(10), delay++) { +#if defined(CONFIG_PLATFORM_EC_ESPI_VW_SLP_S3) + if (power_signal_get(PWR_SLP_S3) < 0) + continue; +#endif +#if defined(CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4) + if (power_signal_get(PWR_SLP_S4) < 0) + continue; +#endif +#if defined(CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5) + if (power_signal_get(PWR_SLP_S5) < 0) + continue; +#endif + /* + * All signals valid. + */ + LOG_DBG("All VW signals valid after %d ms", delay * 10); + break; + } + /* + * S0, all power OK, no suspend or sleep on. + */ + if ((power_get_signals() & MASK_S0) == MASK_ALL_POWER_GOOD) { + LOG_DBG("CPU in S0 state"); + return SYS_POWER_STATE_S0; + } + /* + * S3, all power OK, PWR_SLP_S3 on. + */ + if ((power_get_signals() & MASK_S0) == + (MASK_ALL_POWER_GOOD | POWER_SIGNAL_MASK(PWR_SLP_S3))) { + LOG_DBG("CPU in S3 state"); + return SYS_POWER_STATE_S3; + } + /* + * S5, all power OK, PWR_SLP_S5 on. + */ + if ((power_get_signals() & MASK_S5) == MASK_S5) { + LOG_DBG("CPU in S5 state"); + return SYS_POWER_STATE_S5; + } + /* + * Unable to determine state, force to G3. + */ + ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3); + LOG_INF("Unable to determine CPU state, forcing shutdown"); + return SYS_POWER_STATE_G3; +} enum power_states_ndsx chipset_pwr_sm_run(enum power_states_ndsx curr_state) { 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 b5f853cc95..f6d93fe655 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 @@ -328,10 +328,6 @@ static int common_pwr_sm_run(int state) return SYS_POWER_STATE_S0ix; case SYS_POWER_STATE_S0ixS0: - if (power_get_host_sleep_state() != - HOST_SLEEP_EVENT_S0IX_RESUME) - break; - /* * Disable idle task deep sleep. This means that the low * power idle task will not go into deep sleep while in S0. @@ -425,13 +421,56 @@ static int common_pwr_sm_run(int state) return state; } +/* + * Determine the current CPU state and ensure it + * is matching what is required. + */ +static void pwr_seq_set_initial_state(void) +{ + uint32_t reset_flags = system_get_reset_flags(); + /* Determine current state using chipset specific handler */ + enum power_states_ndsx state = chipset_pwr_seq_get_state(); + + /* + * Check reset flags, and ensure CPU is in correct state. + */ + if (reset_flags & EC_RESET_FLAG_AP_OFF) { + /* + * AP is expected to be off. + * If it isn't, force shutdown. + */ + if (state != SYS_POWER_STATE_G3) { + ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3); + } + pwr_sm_set_state(SYS_POWER_STATE_G3); + return; + } + /* + * Not in warm boot, but CPU is not shutdown. + */ + if (((reset_flags & EC_RESET_FLAG_SYSJUMP) == 0) && + (state != SYS_POWER_STATE_G3)) { + ap_power_force_shutdown(AP_POWER_SHUTDOWN_G3); + state = SYS_POWER_STATE_G3; + } + /* + * If CPU is off, set the state to start powering it up. + */ + if (state == SYS_POWER_STATE_G3) { + state = SYS_POWER_STATE_G3S5; + } + pwr_sm_set_state(state); +} + static void pwrseq_loop_thread(void *p1, void *p2, void *p3) { int32_t t_wait_ms = 10; enum power_states_ndsx curr_state, new_state; power_signal_mask_t this_in_signals; power_signal_mask_t last_in_signals = 0; - enum power_states_ndsx last_state = pwr_sm_get_state(); + enum power_states_ndsx last_state = -1; + + pwr_seq_set_initial_state(); while (1) { curr_state = pwr_sm_get_state(); @@ -499,8 +538,6 @@ static void init_pwr_seq_state(void) { init_chipset_pwr_seq_state(); request_exit_hardoff(false); - - pwr_sm_set_state(SYS_POWER_STATE_G3S5); } /* Initialize power sequence system state */ @@ -510,7 +547,6 @@ static int pwrseq_init(const struct device *dev) /* Initialize signal handlers */ power_signal_init(); - /* TODO: Define initial state of power sequence */ LOG_DBG("Init pwr seq state"); init_pwr_seq_state(); /* Create power sequence state handler core function thread */ diff --git a/zephyr/test/drivers/include/test/drivers/utils.h b/zephyr/test/drivers/include/test/drivers/utils.h index 7e01e0f164..2346d02bb9 100644 --- a/zephyr/test/drivers/include/test/drivers/utils.h +++ b/zephyr/test/drivers/include/test/drivers/utils.h @@ -310,6 +310,28 @@ int host_cmd_motion_sense_range(uint8_t sensor_num, int32_t range, struct ec_response_motion_sense *response); /** + * @brief Call the host command MOTION_SENSE with the sensor offset sub-command + * + * This function attempts to set the offset if the flags field includes + * MOTION_SENSE_SET_OFFSET. Otherwise, the temperature and offsets are ignored. + * The response field will include the current (after modification) offsets and + * temperature. + * + * @param sensor_num The sensor index in the motion_sensors array to query + * @param flags The flags to pass to the host command + * @param temperature The temperature at which the offsets were attained (set) + * @param offset_x The X offset to set + * @param offset_y The Y offset to set + * @param offset_z The Z offset to set + * @param response Pointer to the response data structure to fill on success + * @return The result code from the host command + */ +int host_cmd_motion_sense_offset(uint8_t sensor_num, uint16_t flags, + int16_t temperature, int16_t offset_x, + int16_t offset_y, int16_t offset_z, + struct ec_response_motion_sense *response); + +/** * Run the host command to get the PD discovery responses. * * @param port The USB-C port number diff --git a/zephyr/test/drivers/src/host_cmd/motion_sense.c b/zephyr/test/drivers/src/host_cmd/motion_sense.c index 0b26b9ceb8..3bfc39096b 100644 --- a/zephyr/test/drivers/src/host_cmd/motion_sense.c +++ b/zephyr/test/drivers/src/host_cmd/motion_sense.c @@ -12,6 +12,10 @@ #include "test/drivers/utils.h" FAKE_VALUE_FUNC(int, mock_set_range, struct motion_sensor_t *, int, int); +FAKE_VALUE_FUNC(int, mock_set_offset, const struct motion_sensor_t *, + const int16_t *, int16_t); +FAKE_VALUE_FUNC(int, mock_get_offset, const struct motion_sensor_t *, int16_t *, + int16_t *); /** * Get the size needed for a struct ec_response_motion_sense @@ -28,6 +32,8 @@ struct host_cmd_motion_sense_fixture { static struct host_cmd_motion_sense_fixture fixture = { .mock_drv = { .set_range = mock_set_range, + .set_offset = mock_set_offset, + .get_offset = mock_get_offset, }, }; @@ -42,6 +48,8 @@ static void host_cmd_motion_sense_before(void *state) { ARG_UNUSED(state); RESET_FAKE(mock_set_range); + RESET_FAKE(mock_set_offset); + RESET_FAKE(mock_get_offset); FFF_RESET_HISTORY(); motion_sensors[0].config[SENSOR_CONFIG_AP].odr = 0; @@ -346,3 +354,108 @@ ZTEST_USER_F(host_cmd_motion_sense, test_set_range) zassert_equal(4, mock_set_range_fake.arg1_history[0], NULL); zassert_equal(0, mock_set_range_fake.arg2_history[0], NULL); } + +ZTEST_USER(host_cmd_motion_sense, test_offset_invalid_sensor_num) +{ + struct ec_response_motion_sense response; + + zassert_equal(EC_RES_INVALID_PARAM, + host_cmd_motion_sense_offset( + /*sensor_num=*/0xff, /*flags=*/0, + /*temperature=*/0, /*offset_x=*/0, + /*offset_y=*/0, /*offset_z=*/0, &response), + NULL); +} + +ZTEST_USER(host_cmd_motion_sense, test_offset_missing_get_offset_in_driver) +{ + struct ec_response_motion_sense response; + struct accelgyro_drv drv = { 0 }; + + motion_sensors[0].drv = &drv; + + zassert_equal(EC_RES_INVALID_COMMAND, + host_cmd_motion_sense_offset( + /*sensor_num=*/0, /*flags=*/0, + /*temperature=*/0, /*offset_x=*/0, + /*offset_y=*/0, /*offset_z=*/0, &response), + NULL); +} + +ZTEST_USER(host_cmd_motion_sense, test_offset_missing_set_offset_in_driver) +{ + struct ec_response_motion_sense response; + struct accelgyro_drv drv = { 0 }; + + motion_sensors[0].drv = &drv; + + zassert_equal(EC_RES_INVALID_COMMAND, + host_cmd_motion_sense_offset( + /*sensor_num=*/0, + /*flags=*/MOTION_SENSE_SET_OFFSET, + /*temperature=*/0, /*offset_x=*/0, + /*offset_y=*/0, /*offset_z=*/0, &response), + NULL); +} + +ZTEST_USER_F(host_cmd_motion_sense, test_offset_fail_to_set) +{ + struct ec_response_motion_sense response; + + motion_sensors[0].drv = &this->mock_drv; + mock_set_offset_fake.return_val = EC_RES_ERROR; + + zassert_equal(EC_RES_ERROR, + host_cmd_motion_sense_offset( + /*sensor_num=*/0, + /*flags=*/MOTION_SENSE_SET_OFFSET, + /*temperature=*/0, /*offset_x=*/0, + /*offset_y=*/0, /*offset_z=*/0, &response), + NULL); + zassert_equal(1, mock_set_offset_fake.call_count, NULL); +} + +ZTEST_USER_F(host_cmd_motion_sense, test_offset_fail_to_get) +{ + struct ec_response_motion_sense response; + + motion_sensors[0].drv = &this->mock_drv; + mock_set_offset_fake.return_val = EC_RES_SUCCESS; + mock_get_offset_fake.return_val = EC_RES_ERROR; + + zassert_equal(EC_RES_ERROR, + host_cmd_motion_sense_offset( + /*sensor_num=*/0, + /*flags=*/MOTION_SENSE_SET_OFFSET, + /*temperature=*/0, /*offset_x=*/0, + /*offset_y=*/0, /*offset_z=*/0, &response), + NULL); + zassert_equal(1, mock_set_offset_fake.call_count, NULL); + zassert_equal(1, mock_get_offset_fake.call_count, NULL); + zassert_equal((int16_t *)&response.sensor_offset.offset, + mock_get_offset_fake.arg1_history[0], NULL); +} + +ZTEST_USER_F(host_cmd_motion_sense, test_get_offset) +{ + struct ec_response_motion_sense response; + + motion_sensors[0].drv = &this->mock_drv; + mock_get_offset_fake.return_val = EC_RES_SUCCESS; + mock_set_offset_fake.return_val = EC_RES_SUCCESS; + + zassert_ok(host_cmd_motion_sense_offset( + /*sensor_num=*/0, + /*flags=*/MOTION_SENSE_SET_OFFSET, + /*temperature=*/1, /*offset_x=*/2, + /*offset_y=*/3, /*offset_z=*/4, &response), + NULL); + zassert_equal(1, mock_set_offset_fake.call_count, NULL); + zassert_equal(1, mock_get_offset_fake.call_count, NULL); + zassert_equal((int16_t *)&response.sensor_offset.offset, + mock_get_offset_fake.arg1_history[0], NULL); + zassert_equal(1, mock_set_offset_fake.arg2_history[0], NULL); + zassert_equal(2, mock_set_offset_fake.arg1_history[0][0], NULL); + zassert_equal(3, mock_set_offset_fake.arg1_history[0][1], NULL); + zassert_equal(4, mock_set_offset_fake.arg1_history[0][2], NULL); +} diff --git a/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c b/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c index ae59cad868..3f6925be25 100644 --- a/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c +++ b/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c @@ -13,6 +13,7 @@ #include "tcpm/tcpci.h" #include "test/drivers/test_state.h" #include "test/drivers/utils.h" +#include "timer.h" #include "usb_pd.h" struct usb_attach_5v_3a_pd_sink_fixture { @@ -248,3 +249,43 @@ ZTEST_F(usb_attach_5v_3a_pd_sink, test_disconnect_power_info) "Expected the PD current limit to be >= 0, but got %dmA", power_info.meas.current_lim); } + +/** + * @brief TestPurpose: Verify GotoMin message. + * + * @details + * - TCPM is configured initially as Source + * - Initiate Goto_Min request + * - Verify emulated sink PD negotiation is completed + * + * Expected Results + * - Sink completes Goto Min PD negotiation + */ +ZTEST_F(usb_attach_5v_3a_pd_sink, verify_goto_min) +{ + pd_dpm_request(0, DPM_REQUEST_GOTO_MIN); + k_sleep(K_SECONDS(1)); + + zassert_true(this->sink_5v_3a.data.pd_completed, NULL); +} + +/** + * @brief TestPurpose: Verify Ping message. + * + * @details + * - TCPM is configured initially as Source + * - Initiate Ping request + * - Verify emulated sink received ping message + * + * Expected Results + * - Sink received ping message + */ +ZTEST_F(usb_attach_5v_3a_pd_sink, verify_ping_msg) +{ + tcpci_snk_emul_clear_ping_received(&this->sink_5v_3a.data); + + pd_dpm_request(0, DPM_REQUEST_SEND_PING); + k_sleep(K_USEC(PD_T_SOURCE_ACTIVITY)); + + zassert_true(this->sink_5v_3a.data.ping_received, NULL); +} diff --git a/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c b/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c index b6fe9a5c31..f45201650d 100644 --- a/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c +++ b/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c @@ -334,7 +334,7 @@ ZTEST_F(integration_usb_attach_src_then_snk, verify_src_port_pd_info) "Expected Charging at VBUS %dmV, but PD reports %dmV", DEFAULT_VBUS_MV, response.meas.voltage_now); - zassume_equal(response.meas.current_max, DEFAULT_VBUS_SRC_PORT_MA, + zassert_equal(response.meas.current_max, DEFAULT_VBUS_SRC_PORT_MA, "Charging at VBUS max %dmA, but PD reports %dmA", DEFAULT_VBUS_SRC_PORT_MA, response.meas.current_max); @@ -405,7 +405,7 @@ ZTEST_F(integration_usb_attach_snk_then_src, verify_src_port_pd_info) "Expected Charging at VBUS %dmV, but PD reports %dmV", DEFAULT_VBUS_MV, response.meas.voltage_now); - zassume_equal(response.meas.current_max, DEFAULT_VBUS_SRC_PORT_MA, + zassert_equal(response.meas.current_max, DEFAULT_VBUS_SRC_PORT_MA, "Charging at VBUS max %dmA, but PD reports %dmA", DEFAULT_VBUS_SRC_PORT_MA, response.meas.current_max); @@ -657,7 +657,7 @@ ZTEST_F(usb_detach_test, verify_detach_src_snk) "Expected Charging at VBUS %dmV, but PD reports %dmV", DEFAULT_VBUS_MV, src_power_info.meas.voltage_now); - zassume_equal(src_power_info.meas.current_max, 0, + zassert_equal(src_power_info.meas.current_max, 0, "Charging at VBUS max %dmA, but PD reports %dmA", 0, src_power_info.meas.current_max); } @@ -719,7 +719,7 @@ ZTEST_F(usb_detach_test, verify_detach_snk_src) "Expected Charging at VBUS %dmV, but PD reports %dmV", DEFAULT_VBUS_MV, src_power_info.meas.voltage_now); - zassume_equal(src_power_info.meas.current_max, 0, + zassert_equal(src_power_info.meas.current_max, 0, "Charging at VBUS max %dmA, but PD reports %dmA", 0, src_power_info.meas.current_max); } @@ -791,7 +791,7 @@ ZTEST_F(usb_detach_test, verify_detach_source) "Expected Charging at VBUS %dmV, but PD reports %dmV", DEFAULT_VBUS_MV, pd_power_info.meas.voltage_now); - zassume_equal(pd_power_info.meas.current_max, 0, + zassert_equal(pd_power_info.meas.current_max, 0, "Charging at VBUS max %dmA, but PD reports %dmA", 0, pd_power_info.meas.current_max); } diff --git a/zephyr/test/drivers/src/utils.c b/zephyr/test/drivers/src/utils.c index 4b528246c6..393bb87a13 100644 --- a/zephyr/test/drivers/src/utils.c +++ b/zephyr/test/drivers/src/utils.c @@ -193,6 +193,26 @@ int host_cmd_motion_sense_range(uint8_t sensor_num, int32_t range, return host_command_process(&args); } +int host_cmd_motion_sense_offset(uint8_t sensor_num, uint16_t flags, + int16_t temperature, int16_t offset_x, + int16_t offset_y, int16_t offset_z, + struct ec_response_motion_sense *response) +{ + struct ec_params_motion_sense params = { + .cmd = MOTIONSENSE_CMD_SENSOR_OFFSET, + .sensor_offset = { + .sensor_num = sensor_num, + .flags = flags, + .temp = temperature, + .offset = { offset_x, offset_y, offset_z }, + }, + }; + struct host_cmd_handler_args args = BUILD_HOST_COMMAND( + EC_CMD_MOTION_SENSE_CMD, 1, *response, params); + + return host_command_process(&args); +} + void host_cmd_typec_discovery(int port, enum typec_partner_type partner_type, void *response, size_t response_size) { diff --git a/zephyr/zmake/.pylintrc b/zephyr/zmake/.pylintrc index fd798870dd..a33a1fde1c 100644 --- a/zephyr/zmake/.pylintrc +++ b/zephyr/zmake/.pylintrc @@ -1,5 +1,5 @@ [MASTER] -init-hook='import sys; sys.path.extend(["zephyr/zmake", "/usr/lib64/python3.6/site-packages"])' +init-hook='import sys; sys.path.extend(["zephyr/zmake"])' [MESSAGES CONTROL] diff --git a/zephyr/zmake/run_tests.sh b/zephyr/zmake/run_tests.sh index 54d0bf98a4..4796704440 100755 --- a/zephyr/zmake/run_tests.sh +++ b/zephyr/zmake/run_tests.sh @@ -36,9 +36,3 @@ flake8 . # Check auto-generated README.md is as expected. python -m zmake generate-readme --diff - -# Check that cros lint has no errors, we can't actually call cros lint -# because there is no way to pass the -E flag to pylint. -# When there are no warnings, switch this to `cros lint` -find . -name '*.py' -print0 | xargs -0 \ - /mnt/host/source/chromite/cli/cros/pylint-2 '--rcfile=.pylintrc' -E |