diff options
author | YH Lin <yueherngl@google.com> | 2023-05-11 20:47:00 +0000 |
---|---|---|
committer | YH Lin <yueherngl@google.com> | 2023-05-11 20:47:00 +0000 |
commit | 8641442366bd7c2c133e302a57f904dfac3c896b (patch) | |
tree | d0dca100ca02a89210decc54b7124d26bb75ef6a | |
parent | e79a9dab1721c3d7da1475f3f802c4ea871a48ec (diff) | |
parent | 5df400b0377c9e1b5bb6cfc53ba7dfedde91f944 (diff) | |
download | chrome-ec-8641442366bd7c2c133e302a57f904dfac3c896b.tar.gz |
Merge remote-tracking branch cros/main into firmware-brya-14505.B-main
Generated by: util/update_release_branch.py --baseboard brya --relevant_paths_file
baseboard/brya/relevant-paths.txt firmware-brya-14505.B-main
Relevant changes:
git log --oneline e79a9dab17..5df400b037 -- baseboard/brya board/agah
board/anahera board/banshee board/brya board/crota board/felwinter
board/gimble board/hades board/kano board/marasov board/mithrax
board/omnigul board/osiris board/primus board/redrix board/taeko
board/taniks board/vell board/volmar driver/bc12/pi3usb9201_public.*
driver/charger/bq25710.* driver/ppc/nx20p348x.*
driver/ppc/syv682x_public.* driver/retimer/bb_retimer_public.*
driver/tcpm/nct38xx.* driver/tcpm/ps8xxx_public.* driver/tcpm/tcpci.*
include/power/alderlake* include/intel_x86.h power/alderlake*
power/intel_x86.c util/getversion.sh
76d2b9b1e4 battery: Deprecate CONFIG_BATTERY_LEVEL_NEAR_FULL
3d5b996f73 Hades: Fast forward DSW_PWROK to PCH_PWROK
56af450c1a Agah: Fast forward DSW_PWROK to PCH_PWROK
b729eab7c7 charger: Move charger_state_v2.h into charge_state.h
47acf64182 charger: Rename charge_get_state() to led_pwr_get_state()
632c7c935a power/x86: Add dedicated interrupt handler for pwrok
0fff3a0bd4 omnigul: Add condition use Accel and Gyro by FWCONFIG.
7540daff3f driver/tcpm/nct38xx: Remove write to RO register
3f279f30d4 GPU: Rename DC_ATLEAST_SOC to DC_ATMOST_SOC
BRANCH=None
BUG=b:218332694 b:216485035 b:280818345 b:280351196 b:280001153
BUG=b:279918234
TEST=`emerge-[brya,hades,draco] chromeos-ec`
Force-Relevant-Builds: all
Change-Id: I19f2f6c5573d8c748ac63b488a808f10de352b1d
Signed-off-by: YH Lin <yueherngl@google.com>
341 files changed, 4480 insertions, 2338 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f80363c806..fd26b98172 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,8 +40,6 @@ before_script: - export MODULES_DIR="$CI_PROJECT_DIR/modules" - export ZEPHYR_BASE="${CI_PROJECT_DIR}/zephyr/main" - export REPO_BASE="${CI_PROJECT_DIR}/repo" - - git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git - - export PATH="${CI_PROJECT_DIR}/depot_tools:$PATH" - git config --global --add safe.directory '*' # Get Zephyr repo and modules - checkout_at_date() { @@ -97,6 +95,8 @@ before_script: rev="$(git rev-list -n 1 --before="${date}" "${branch}")" ; } - ec_commit_date="$(cd ${EC_DIR} ; git log -1 HEAD --format=%cd --date=iso)" + - checkout_at_date "https://chromium.googlesource.com/chromium/tools/depot_tools.git" "main" "${CI_PROJECT_DIR}/depot_tools" "${ec_commit_date}" + - export PATH="${CI_PROJECT_DIR}/depot_tools:$PATH" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr" "main" "${ZEPHYR_BASE}" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr/cmsis" "chromeos-main" "${MODULES_DIR}/cmsis" "${ec_commit_date}" - checkout_at_date "https://chromium.googlesource.com/chromiumos/third_party/zephyr/hal_stm32" "chromeos-main" "${MODULES_DIR}/hal_stm32" "${ec_commit_date}" diff --git a/Makefile.toolchain b/Makefile.toolchain index a3061ac9ff..4f5b173bd9 100644 --- a/Makefile.toolchain +++ b/Makefile.toolchain @@ -42,6 +42,8 @@ CLANG_BOARDS:= \ nami_fp \ nocturne_fp \ nucleo-dartmonkey \ + nucleo-h743zi \ + nucleo-f412zg \ ifeq ($(filter $(BOARD), $(CLANG_BOARDS)), $(BOARD)) CC=clang diff --git a/baseboard/asurada/baseboard.c b/baseboard/asurada/baseboard.c index 0e467140b3..7ff873963d 100644 --- a/baseboard/asurada/baseboard.c +++ b/baseboard/asurada/baseboard.c @@ -9,7 +9,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/baseboard/asurada/usbc_config.c b/baseboard/asurada/usbc_config.c index 89b027124e..391b9134c5 100644 --- a/baseboard/asurada/usbc_config.c +++ b/baseboard/asurada/usbc_config.c @@ -10,7 +10,7 @@ #include "bc12/mt6360_public.h" #include "bc12/pi3usb9201_public.h" #include "button.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "charger/isl923x_public.h" #include "console.h" diff --git a/baseboard/brya/charger_bq25720.c b/baseboard/brya/charger_bq25720.c index 4976abdea6..827152e115 100644 --- a/baseboard/brya/charger_bq25720.c +++ b/baseboard/brya/charger_bq25720.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/baseboard/cherry/baseboard.c b/baseboard/cherry/baseboard.c index 36df319f8c..c162331f89 100644 --- a/baseboard/cherry/baseboard.c +++ b/baseboard/cherry/baseboard.c @@ -9,7 +9,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "chipset.h" #include "common.h" @@ -313,10 +312,10 @@ __override int board_rt1718s_init(int port) /* gpio 1/2 output high when receiving frx signal */ RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO1_VBUS_CTRL, - RT1718S_GPIO1_VBUS_CTRL_FRS_RX_VBUS, + RT1718S_GPIO_VBUS_CTRL_FRS_RX_VBUS, 0xFF)); RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO2_VBUS_CTRL, - RT1718S_GPIO2_VBUS_CTRL_FRS_RX_VBUS, + RT1718S_GPIO_VBUS_CTRL_FRS_RX_VBUS, 0xFF)); /* Turn on SBU switch */ diff --git a/baseboard/goroh/baseboard.c b/baseboard/goroh/baseboard.c index c94e7a3af9..554437ab6e 100644 --- a/baseboard/goroh/baseboard.c +++ b/baseboard/goroh/baseboard.c @@ -11,7 +11,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/baseboard/grunt/baseboard.c b/baseboard/grunt/baseboard.c index 37bb61b423..10e66c50dc 100644 --- a/baseboard/grunt/baseboard.c +++ b/baseboard/grunt/baseboard.c @@ -9,7 +9,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/baseboard/guybrush/baseboard.c b/baseboard/guybrush/baseboard.c index c79d14cf6d..b65aa5ba8b 100644 --- a/baseboard/guybrush/baseboard.c +++ b/baseboard/guybrush/baseboard.c @@ -10,7 +10,6 @@ #include "charge_manager.h" #include "charge_ramp.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "chip/npcx/ps2_chip.h" #include "chip/npcx/pwm_chip.h" diff --git a/baseboard/hatch/baseboard.c b/baseboard/hatch/baseboard.c index b4e37e6bc8..b342cd74ed 100644 --- a/baseboard/hatch/baseboard.c +++ b/baseboard/hatch/baseboard.c @@ -7,7 +7,7 @@ #include "atomic.h" #include "battery_fuel_gauge.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "console.h" #include "cros_board_info.h" diff --git a/baseboard/intelrvp/chg_usb_pd.c b/baseboard/intelrvp/chg_usb_pd.c index c4ae3ea72d..60ad6e5cdb 100644 --- a/baseboard/intelrvp/chg_usb_pd.c +++ b/baseboard/intelrvp/chg_usb_pd.c @@ -6,7 +6,7 @@ /* Common USB PD charge configuration */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "gpio.h" #include "hooks.h" #include "tcpm/tcpci.h" diff --git a/baseboard/intelrvp/chg_usb_pd_mecc_1_0.c b/baseboard/intelrvp/chg_usb_pd_mecc_1_0.c index 3f2959ebdb..1d18109f6f 100644 --- a/baseboard/intelrvp/chg_usb_pd_mecc_1_0.c +++ b/baseboard/intelrvp/chg_usb_pd_mecc_1_0.c @@ -6,7 +6,7 @@ /* Intel-RVP family-specific configuration */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "console.h" #include "driver/ppc/sn5s330.h" #include "gpio.h" diff --git a/baseboard/intelrvp/led_states.c b/baseboard/intelrvp/led_states.c index 6bcee159a3..bee35a85a2 100644 --- a/baseboard/intelrvp/led_states.c +++ b/baseboard/intelrvp/led_states.c @@ -22,7 +22,7 @@ static enum led_states led_get_state(void) int charge_lvl; enum led_states new_state = LED_NUM_STATES; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Get percent charge */ charge_lvl = charge_get_percent(); @@ -115,7 +115,7 @@ static void led_update_battery(void) static enum pwr_led_states pwr_led_get_state(void) { if (extpower_is_present()) { - if (charge_get_state() == PWR_STATE_CHARGE_NEAR_FULL) + if (led_pwr_get_state() == PWR_STATE_CHARGE_NEAR_FULL) return PWR_LED_STATE_OFF; else return PWR_LED_STATE_ON; diff --git a/baseboard/kukui/charger_mt6370.c b/baseboard/kukui/charger_mt6370.c index 80587745ea..c4300c5552 100644 --- a/baseboard/kukui/charger_mt6370.c +++ b/baseboard/kukui/charger_mt6370.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger_mt6370.h" #include "console.h" #include "driver/charger/rt946x.h" @@ -330,14 +330,14 @@ void mt6370_charger_profile_override(struct charge_state_data *curr) /* * When the charger says it's done charging, even if fuel gauge says - * SOC < BATTERY_LEVEL_NEAR_FULL, we'll overwrite SOC with - * BATTERY_LEVEL_NEAR_FULL. So we can ensure both Chrome OS UI + * SOC < CONFIG_BATT_HOST_FULL_FACTOR, we'll overwrite SOC with + * CONFIG_BATT_HOST_FULL_FACTOR. So we can ensure both Chrome OS UI * and battery LED indicate full charge. * * Enable this hack on on-board gauge only (b/142097561) */ if (IS_ENABLED(CONFIG_BATTERY_MAX17055) && rt946x_is_charge_done()) { - curr->batt.state_of_charge = MAX(BATTERY_LEVEL_NEAR_FULL, + curr->batt.state_of_charge = MAX(CONFIG_BATT_HOST_FULL_FACTOR, curr->batt.state_of_charge); } } diff --git a/baseboard/kukui/usb_pd_policy.c b/baseboard/kukui/usb_pd_policy.c index 2f2c141510..1ca7935762 100644 --- a/baseboard/kukui/usb_pd_policy.c +++ b/baseboard/kukui/usb_pd_policy.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "console.h" #include "gpio.h" diff --git a/baseboard/octopus/baseboard.h b/baseboard/octopus/baseboard.h index 2913a014d0..622f7770e8 100644 --- a/baseboard/octopus/baseboard.h +++ b/baseboard/octopus/baseboard.h @@ -313,6 +313,9 @@ #define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) #endif /* VARIANT_OCTOPUS_NO_SENSORS */ +/* System safe mode for improved panic debugging */ +#define CONFIG_SYSTEM_SAFE_MODE + /* * Sensor stack in EC/Kernel depends on a hardware interrupt pin from EC->AP, so * do not define CONFIG_MKBP_USE_HOST_EVENT since all octopus boards use @@ -321,6 +324,12 @@ #define CONFIG_MKBP_EVENT #define CONFIG_MKBP_USE_GPIO +/* Free up more flash. */ +#undef CONFIG_CMD_ACCELSPOOF +#undef CONFIG_CMD_MFALLOW +#undef CONFIG_CMD_MD +#undef CONFIG_CMD_MMAPINFO + #ifndef __ASSEMBLER__ #include "gpio_signal.h" diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c index dcf16cf7c6..e54656f08a 100644 --- a/baseboard/zork/baseboard.c +++ b/baseboard/zork/baseboard.c @@ -11,7 +11,6 @@ #include "charge_manager.h" #include "charge_ramp.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/agah/board.c b/board/agah/board.c index 91b326c868..7884ac1e97 100644 --- a/board/agah/board.c +++ b/board/agah/board.c @@ -39,8 +39,8 @@ struct d_notify_policy d_notify_policies[] = { [D_NOTIFY_1] = AC_ATLEAST_W(100), [D_NOTIFY_2] = AC_ATLEAST_W(65), [D_NOTIFY_3] = AC_DC, - [D_NOTIFY_4] = DC_ATLEAST_SOC(20), - [D_NOTIFY_5] = DC_ATLEAST_SOC(5), + [D_NOTIFY_4] = DC_ATMOST_SOC(20), + [D_NOTIFY_5] = DC_ATMOST_SOC(5), }; BUILD_ASSERT(ARRAY_SIZE(d_notify_policies) == D_NOTIFY_COUNT); diff --git a/board/agah/board.h b/board/agah/board.h index 35ecdc58e6..ba2889130d 100644 --- a/board/agah/board.h +++ b/board/agah/board.h @@ -96,6 +96,7 @@ #define GPIO_PCH_WAKE_L GPIO_EC_PCH_INT_ODL #define GPIO_PG_EC_ALL_SYS_PWRGD GPIO_SEQ_EC_ALL_SYS_PG #define GPIO_PG_EC_DSW_PWROK GPIO_SEQ_EC_DSW_PWROK +#define GPIO_PCH_DSW_PWROK GPIO_PCH_PWROK #define GPIO_PG_EC_RSMRST_ODL GPIO_SEQ_EC_RSMRST_ODL #define GPIO_POWER_BUTTON_L GPIO_GSC_EC_PWR_BTN_ODL #define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL diff --git a/board/agah/charger_isl9241.c b/board/agah/charger_isl9241.c index 902bd57aa3..892c857ad6 100644 --- a/board/agah/charger_isl9241.c +++ b/board/agah/charger_isl9241.c @@ -35,7 +35,6 @@ #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/agah/gpio.inc b/board/agah/gpio.inc index c9308fd903..7f120d9ba6 100644 --- a/board/agah/gpio.inc +++ b/board/agah/gpio.inc @@ -8,13 +8,13 @@ #define MODULE_KB MODULE_KEYBOARD_SCAN /* INTERRUPT GPIOs: */ +GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, intel_x86_pwrok_signal_interrupt) GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(GSC_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW, power_button_interrupt) GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) -GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SEQ_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SLP_SUS_L, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt) diff --git a/board/agah/led.c b/board/agah/led.c index d5b27f128d..e92b369e68 100644 --- a/board/agah/led.c +++ b/board/agah/led.c @@ -112,7 +112,7 @@ static void led_set_battery(void) battery_ticks++; if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery( @@ -123,7 +123,7 @@ static void led_set_battery(void) return; } - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/ambassador/board.c b/board/ambassador/board.c index d8de0ec5fa..dd839574b5 100644 --- a/board/ambassador/board.c +++ b/board/ambassador/board.c @@ -8,7 +8,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "common.h" #include "core/cortex-m/cpu.h" diff --git a/board/anahera/board.c b/board/anahera/board.c index 4b328e6db2..f5fc90a9aa 100644 --- a/board/anahera/board.c +++ b/board/anahera/board.c @@ -6,7 +6,7 @@ #include "battery.h" #include "button.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/anahera/charger.c b/board/anahera/charger.c index 4976abdea6..827152e115 100644 --- a/board/anahera/charger.c +++ b/board/anahera/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/anahera/led.c b/board/anahera/led.c index 1d76fc342d..205bf5a713 100644 --- a/board/anahera/led.c +++ b/board/anahera/led.c @@ -136,7 +136,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/asurada/board.c b/board/asurada/board.c index 82cda97dfd..a9b5e0aab4 100644 --- a/board/asurada/board.c +++ b/board/asurada/board.c @@ -7,7 +7,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/asurada/led.c b/board/asurada/led.c index ca29f0be45..e793e6ff13 100644 --- a/board/asurada/led.c +++ b/board/asurada/led.c @@ -143,7 +143,7 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) static void update_led(enum ec_led_id led_id, bool is_active_charge_port, int duty, int tick) { - enum charge_state power_state = charge_get_state(); + enum led_pwr_state power_state = led_pwr_get_state(); if (power_state == PWR_STATE_IDLE) { /* Factory mode: blinking white (2sec on + 2sec off) */ diff --git a/board/atlas/board.h b/board/atlas/board.h index 144afda14c..bde6d3e07a 100644 --- a/board/atlas/board.h +++ b/board/atlas/board.h @@ -64,7 +64,8 @@ /* Battery */ #define CONFIG_BATTERY_CUT_OFF #define CONFIG_BATTERY_DEVICE_CHEMISTRY "LION" -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 95 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 95 #define CONFIG_BATTERY_HW_PRESENT_CUSTOM #define CONFIG_BATTERY_PRESENT_CUSTOM #define CONFIG_BATTERY_SMART diff --git a/board/aurash/board.c b/board/aurash/board.c index 64a8ca6015..ec833141a7 100644 --- a/board/aurash/board.c +++ b/board/aurash/board.c @@ -7,7 +7,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/banshee/charger.c b/board/banshee/charger.c index c6ee062ab5..76e2712181 100644 --- a/board/banshee/charger.c +++ b/board/banshee/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/banshee/led.c b/board/banshee/led.c index f0ea78cab2..15df2be5db 100644 --- a/board/banshee/led.c +++ b/board/banshee/led.c @@ -252,9 +252,9 @@ static int led_get_charge_percent(void) static void select_active_port_led(int port) { - if ((charge_get_state() == PWR_STATE_DISCHARGE && + if ((led_pwr_get_state() == PWR_STATE_DISCHARGE && led_get_charge_percent() < 10) || - charge_get_state() == PWR_STATE_ERROR) { + led_pwr_get_state() == PWR_STATE_ERROR) { gpio_set_level(GPIO_LEFT_SIDE, 1); gpio_set_level(GPIO_RIGHT_SIDE, 1); } else if (port == RIGHT_PORT) { @@ -299,7 +299,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(EC_LED_COLOR_AMBER); diff --git a/board/beadrix/board.c b/board/beadrix/board.c index d14996c6e5..92da9f5295 100644 --- a/board/beadrix/board.c +++ b/board/beadrix/board.c @@ -8,7 +8,7 @@ #include "adc_chip.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/bc12/pi3usb9201.h" #include "driver/charger/isl923x.h" diff --git a/board/beadrix/led.c b/board/beadrix/led.c index 8bef7c0bd9..56b8b736e5 100644 --- a/board/beadrix/led.c +++ b/board/beadrix/led.c @@ -66,7 +66,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_RED; diff --git a/board/beetley/board.c b/board/beetley/board.c index 697e2a50fe..7bd12e9bdb 100644 --- a/board/beetley/board.c +++ b/board/beetley/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_lis2dw12.h" diff --git a/board/berknip/led.c b/board/berknip/led.c index c2b0e69cbb..17ad80fa40 100644 --- a/board/berknip/led.c +++ b/board/berknip/led.c @@ -138,7 +138,7 @@ static void led_set_battery(void) * system suspend with non-charging state. */ if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(RIGHT_PORT, @@ -156,7 +156,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/blipper/board.c b/board/blipper/board.c index 58867cafb2..15a2d4b520 100644 --- a/board/blipper/board.c +++ b/board/blipper/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_lis2dw12.h" diff --git a/board/bloog/led.c b/board/bloog/led.c index c11244b613..6a1b85712b 100644 --- a/board/bloog/led.c +++ b/board/bloog/led.c @@ -139,7 +139,7 @@ static void led_set_battery(void) if (!board_is_convertible()) { if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(0, power_ticks & 0x4 ? LED_WHITE : @@ -152,7 +152,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/boten/board.c b/board/boten/board.c index fe23078c4c..c352d12f78 100644 --- a/board/boten/board.c +++ b/board/boten/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_lis2dw12.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/boxy/board.c b/board/boxy/board.c index e9cd9fb227..a0f8dd6683 100644 --- a/board/boxy/board.c +++ b/board/boxy/board.c @@ -9,7 +9,7 @@ #include "board.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/ppc/syv682x_public.h" #include "driver/tcpm/it83xx_pd.h" @@ -54,6 +54,11 @@ const struct adc_t adc_channels[] = { .factor_div = ADC_READ_MAX + 1, .shift = 0, .channel = CHIP_ADC_CH3 }, + [ADC_VBUS] = { .name = "VBUS", /* 113/1113 voltage divider */ + .factor_mul = ADC_MAX_MVOLT * 1113, + .factor_div = (ADC_READ_MAX + 1) * 113, + .shift = 0, + .channel = CHIP_ADC_CH4 }, [ADC_TEMP_SENSOR_3] = { .name = "TEMP_SENSOR3", .factor_mul = ADC_MAX_MVOLT, .factor_div = ADC_READ_MAX + 1, @@ -153,8 +158,6 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); void board_init(void) { - gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT); - /* Enable PPC interrupt */ gpio_enable_interrupt(GPIO_USB_C0_FAULT_L); } @@ -214,50 +217,6 @@ void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) * - CHARGE_PORT_NONE will never be selected. */ -/* List of BJ adapters */ -enum bj_adapter { - BJ_NONE, - BJ_65W_19V, -}; - -/* Barrel-jack power adapter ratings. */ -static const struct charge_port_info bj_adapters[] = { - [BJ_NONE] = { .current = 0, .voltage = 0 }, - [BJ_65W_19V] = { .current = 3420, .voltage = 19000 }, -}; -#define BJ_ADP_RATING_DEFAULT BJ_65W_19V /* BJ power ratings default */ -#define ADP_DEBOUNCE_MS 1000 /* Debounce time for BJ plug/unplug */ - -/* Debounced connection state of the barrel jack */ -static int8_t bj_adp_connected = -1; -static void adp_connect_deferred(void) -{ - const struct charge_port_info *pi; - int connected = gpio_get_level(GPIO_BJ_ADP_PRESENT); - - /* Debounce */ - if (connected == bj_adp_connected) - return; - - if (connected) { - pi = &bj_adapters[BJ_ADP_RATING_DEFAULT]; - } else { - /* No barrel-jack, zero out this power supply */ - pi = &bj_adapters[BJ_NONE]; - } - /* This will result in a call to board_set_active_charge_port */ - charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED, - DEDICATED_CHARGE_PORT, pi); - bj_adp_connected = connected; -} -DECLARE_DEFERRED(adp_connect_deferred); - -/* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */ -void adp_connect_interrupt(enum gpio_signal signal) -{ - hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC); -} - int board_set_active_charge_port(int port) { const int active_port = charge_manager_get_active_charge_port(); @@ -275,8 +234,6 @@ int board_set_active_charge_port(int port) return EC_ERROR_INVAL; if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - int bj_requested; - if (charge_manager_get_active_charge_port() != CHARGE_PORT_NONE) /* Change is only permitted while the system is off */ return EC_ERROR_INVAL; @@ -287,9 +244,8 @@ int board_set_active_charge_port(int port) * reinitializing after sysjump). Reject requests that aren't * in sync with our outputs. */ - bj_requested = port == CHARGE_PORT_BARRELJACK; - if (bj_adp_connected != bj_requested) - return EC_ERROR_INVAL; + + /* TODO: add this part after two type-c function is finished. */ } CPRINTUSB("New charger p%d", port); @@ -318,25 +274,15 @@ static void board_charge_manager_init(void) charge_manager_update_charge(j, i, NULL); } - port = gpio_get_level(GPIO_BJ_ADP_PRESENT) ? CHARGE_PORT_BARRELJACK : - CHARGE_PORT_TYPEC0; - CPRINTUSB("Power source is p%d (%s)", port, - port == CHARGE_PORT_TYPEC0 ? "USB-C" : "BJ"); + port = CHARGE_PORT_TYPEC0; + CPRINTUSB("Power source is p%d (USB-C)", port); /* Initialize the power source supplier */ switch (port) { case CHARGE_PORT_TYPEC0: typec_set_input_current_limit(port, 3000, 5000); break; - case CHARGE_PORT_BARRELJACK: - charge_manager_update_charge( - CHARGE_SUPPLIER_DEDICATED, DEDICATED_CHARGE_PORT, - &bj_adapters[BJ_ADP_RATING_DEFAULT]); - break; } - - /* Report charge state from the barrel jack. */ - adp_connect_deferred(); } DECLARE_HOOK(HOOK_INIT, board_charge_manager_init, HOOK_PRIO_INIT_CHARGE_MANAGER + 1); diff --git a/board/boxy/board.h b/board/boxy/board.h index c9f3989e11..5d7c7e99dd 100644 --- a/board/boxy/board.h +++ b/board/boxy/board.h @@ -36,8 +36,6 @@ #undef PD_MAX_POWER_MW #define PD_MAX_POWER_MW 65000 #define CONFIG_USB_PD_VBUS_DETECT_GPIO -/* ADC sensors could measure VBUS on this board, but components are DNS */ -#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT /* Override macro for C0 only */ #define PORT_TO_HPD(port) (GPIO_USB_C0_DP_HPD) @@ -133,7 +131,6 @@ enum charge_port { CHARGE_PORT_TYPEC0, - CHARGE_PORT_BARRELJACK, }; enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_COUNT }; @@ -150,6 +147,7 @@ enum adc_channel { ADC_VSNS_PP3300_A, /* ADC0 */ ADC_TEMP_SENSOR_1, /* ADC2 */ ADC_TEMP_SENSOR_2, /* ADC3 */ + ADC_VBUS, /* ADC4 */ ADC_TEMP_SENSOR_3, /* ADC13 */ ADC_PPVAR_PWR_IN_IMON, /* ADC15 */ ADC_SNS_PPVAR_PWR_IN, /* ADC16 */ diff --git a/board/boxy/gpio.inc b/board/boxy/gpio.inc index f1e49964ae..c21ff3e870 100644 --- a/board/boxy/gpio.inc +++ b/board/boxy/gpio.inc @@ -43,7 +43,6 @@ GPIO_INT(EC_WP_OD, PIN(A, 6), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(EC_RECOVERY_BTN_OD, PIN(K, 7), GPIO_INT_BOTH, button_interrupt) /* Recovery button input from H1 */ GPIO_INT(H1_EC_RECOVERY_BTN_ODL, PIN(K, 4), GPIO_INT_BOTH, button_interrupt) -GPIO_INT(BJ_ADP_PRESENT, PIN(A, 7), GPIO_INT_BOTH, adp_connect_interrupt) GPIO_INT(USB_C0_FAULT_L, PIN(K, 0), GPIO_INT_FALLING, ppc_interrupt) GPIO_INT(USB_C1_FAULT_L, PIN(K, 3), GPIO_INT_FALLING, ppc_interrupt) @@ -151,18 +150,14 @@ ALTERNATE(PIN_MASK(A, BIT(4) | BIT(5)), 0, MODULE_I2C, 0) /* I2C5 - HDMI1_SRC_DDC */ /* ADC */ -ALTERNATE(PIN_MASK(I, BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC2: - TEMP_SENSOR_1, - ADC3: TEMP_SENSOR_2 - */ -ALTERNATE(PIN_MASK(L, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, - 0) /* ADC13: - TEMP_SENSOR_3, - ADC15: - ANALOG_PPVAR_PWR_IN_IMON, - ADC16: - SNS_PPVAR_PWR_IN - */ +/* ADC2: TEMP_SENSOR_1, ADC3: TEMP_SENSOR_2, ADC4: VBUS */ +ALTERNATE(PIN_MASK(I, BIT(2) | BIT(3) | BIT(4)), 0, MODULE_ADC, 0) +/* + * ADC13: TEMP_SENSOR_3 + * ADC15: ANALOG_PPVAR_PWR_IN_IMON + * ADC16: SNS_PPVAR_PWR_IN + */ +ALTERNATE(PIN_MASK(L, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* PWM */ ALTERNATE(PIN_MASK(A, BIT(1) | BIT(2) | BIT(3)), 0, MODULE_PWM, diff --git a/board/brask/board.c b/board/brask/board.c index be41092f0e..8bdb113ac5 100644 --- a/board/brask/board.c +++ b/board/brask/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/brya/charger.c b/board/brya/charger.c index 4976abdea6..827152e115 100644 --- a/board/brya/charger.c +++ b/board/brya/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/bugzzy/board.c b/board/bugzzy/board.c index c3f62e8787..5102db15be 100644 --- a/board/bugzzy/board.c +++ b/board/bugzzy/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/burnet/led.c b/board/burnet/led.c index 68c4c9e839..750b3a217d 100644 --- a/board/burnet/led.c +++ b/board/burnet/led.c @@ -129,7 +129,7 @@ static void led_set_battery(void) if (!board_is_convertible()) { if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x2 ? LED_WHITE : LED_OFF); return; @@ -138,7 +138,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/cappy2/board.c b/board/cappy2/board.c index 99f9f1bf73..9525e9c1f2 100644 --- a/board/cappy2/board.c +++ b/board/cappy2/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/bc12/pi3usb9201.h" #include "driver/charger/isl923x.h" diff --git a/board/careena/led.c b/board/careena/led.c index fda7503974..c0f111ac4d 100644 --- a/board/careena/led.c +++ b/board/careena/led.c @@ -93,7 +93,7 @@ static void led_set_battery(void) /* override battery led for system suspend */ if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x4 ? LED_WHITE : LED_OFF); return; @@ -101,7 +101,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/cherry/board.c b/board/cherry/board.c index f8700404ed..8d3faaf621 100644 --- a/board/cherry/board.c +++ b/board/cherry/board.c @@ -5,7 +5,7 @@ /* Cherry board configuration */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "console.h" #include "driver/accel_bma422.h" diff --git a/board/chronicler/board.c b/board/chronicler/board.c index daec7df9c3..ca6ae5c392 100644 --- a/board/chronicler/board.c +++ b/board/chronicler/board.c @@ -9,7 +9,7 @@ #include "battery_smart.h" #include "button.h" #include "cbi_ec_fw_config.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "driver/sync.h" #include "driver/tcpm/ps8xxx.h" diff --git a/board/chronicler/led.c b/board/chronicler/led.c index fd5308f09d..7566c7b633 100644 --- a/board/chronicler/led.c +++ b/board/chronicler/led.c @@ -140,7 +140,7 @@ static void led_set_battery(void) * LEDs to indicate system suspend without charging state. */ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery( @@ -152,7 +152,7 @@ static void led_set_battery(void) suspend_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/coachz/led.c b/board/coachz/led.c index 01873eae3e..61ecc46181 100644 --- a/board/coachz/led.c +++ b/board/coachz/led.c @@ -72,7 +72,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/constitution/board.c b/board/constitution/board.c index deb00f6c2c..8a3e56032e 100644 --- a/board/constitution/board.c +++ b/board/constitution/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/coral/board.h b/board/coral/board.h index 4b570db1e5..f5cc6bb706 100644 --- a/board/coral/board.h +++ b/board/coral/board.h @@ -49,7 +49,8 @@ #define CONFIG_BATTERY_DEVICE_CHEMISTRY "LION" #define CONFIG_BATTERY_CUT_OFF #define CONFIG_BATTERY_HW_PRESENT_CUSTOM -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 94 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 94 #define CONFIG_BATTERY_PRESENT_CUSTOM #define CONFIG_BATTERY_SMART diff --git a/board/coral/led.c b/board/coral/led.c index b8515c14c7..22cbca4fa2 100644 --- a/board/coral/led.c +++ b/board/coral/led.c @@ -174,7 +174,7 @@ static enum led_states led_get_state(void) int charge_lvl; enum led_states new_state = LED_NUM_STATES; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Get percent charge */ charge_lvl = charge_get_percent(); diff --git a/board/corori/board.c b/board/corori/board.c index 545765b0d7..0717b73750 100644 --- a/board/corori/board.c +++ b/board/corori/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/corori/board.h b/board/corori/board.h index 16628d4619..5db8be64cc 100644 --- a/board/corori/board.h +++ b/board/corori/board.h @@ -37,7 +37,8 @@ /* LED defines */ #define CONFIG_LED_COMMON -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 94 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 94 #define GPIO_BAT_LED_AMBER GPIO_LED_Y_ODL #define GPIO_PWR_LED_WHITE GPIO_LED_W_ODL diff --git a/board/corori/led.c b/board/corori/led.c index f47871a4ed..da32dfa7f8 100644 --- a/board/corori/led.c +++ b/board/corori/led.c @@ -118,7 +118,7 @@ static enum led_states led_get_state(void) { enum led_states new_state = LED_NUM_STATES; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: new_state = STATE_CHARGING; break; diff --git a/board/corori2/board.c b/board/corori2/board.c index 7bfc7d2e10..909099c6f8 100644 --- a/board/corori2/board.c +++ b/board/corori2/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/cret/board.c b/board/cret/board.c index 4439a30044..59edd8145a 100644 --- a/board/cret/board.c +++ b/board/cret/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/crota/charger.c b/board/crota/charger.c index ce19b66194..7b3edd270d 100644 --- a/board/crota/charger.c +++ b/board/crota/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/crota/led.c b/board/crota/led.c index 4b4be6fe39..86fc187521 100644 --- a/board/crota/led.c +++ b/board/crota/led.c @@ -98,7 +98,7 @@ __override enum led_states board_led_get_state(enum led_states desired_state) /* Make sure when battery is pre-charging, the LED will blinking. * Otherwise it will wait 30 seconds then blinking. */ - if (charge_get_state() == PWR_STATE_IDLE) { + if (led_pwr_get_state() == PWR_STATE_IDLE) { if (charge_get_flags() & CHARGE_FLAG_EXTERNAL_POWER) desired_state = STATE_BATTERY_ERROR; } diff --git a/board/damu/board.h b/board/damu/board.h index 857f5d2390..64aa8404ec 100644 --- a/board/damu/board.h +++ b/board/damu/board.h @@ -8,6 +8,9 @@ #ifndef __CROS_EC_BOARD_H #define __CROS_EC_BOARD_H +/* Save some flash space */ +#undef CONFIG_CHARGE_DEBUG + #define VARIANT_KUKUI_JACUZZI #define VARIANT_KUKUI_BATTERY_SMART #define VARIANT_KUKUI_CHARGER_ISL9238 diff --git a/board/dibbi/board.c b/board/dibbi/board.c index 5b7e8dd7c5..200a53043c 100644 --- a/board/dibbi/board.c +++ b/board/dibbi/board.c @@ -9,7 +9,7 @@ #include "board.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/ppc/syv682x_public.h" #include "driver/tcpm/it83xx_pd.h" diff --git a/board/dirinboz/led.c b/board/dirinboz/led.c index b4063177f4..f50393003d 100644 --- a/board/dirinboz/led.c +++ b/board/dirinboz/led.c @@ -142,7 +142,7 @@ static void led_set_battery(void) * system suspend with non-charging state. */ if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(RIGHT_PORT, @@ -154,7 +154,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/dojo/board.c b/board/dojo/board.c index ca85def38c..28788d4641 100644 --- a/board/dojo/board.c +++ b/board/dojo/board.c @@ -7,7 +7,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "console.h" #include "cros_board_info.h" diff --git a/board/dojo/led.c b/board/dojo/led.c index 4b2b379a1b..f1af389f60 100644 --- a/board/dojo/led.c +++ b/board/dojo/led.c @@ -134,7 +134,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/dooly/board.c b/board/dooly/board.c index d0711c9c12..306fc86ae3 100644 --- a/board/dooly/board.c +++ b/board/dooly/board.c @@ -9,7 +9,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "common.h" #include "core/cortex-m/cpu.h" diff --git a/board/dratini/led.c b/board/dratini/led.c index 035bd963d5..16c0699a8e 100644 --- a/board/dratini/led.c +++ b/board/dratini/led.c @@ -156,7 +156,7 @@ static void led_set_battery(void) if (!board_is_convertible()) { if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(0, power_ticks & 0x4 ? LED_WHITE : @@ -169,7 +169,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/drawcia/board.c b/board/drawcia/board.c index aa0c23c585..78459b6ef5 100644 --- a/board/drawcia/board.c +++ b/board/drawcia/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/drawcia/led.c b/board/drawcia/led.c index 0fee248506..f9b504d13f 100644 --- a/board/drawcia/led.c +++ b/board/drawcia/led.c @@ -124,7 +124,7 @@ static void led_set_battery(void) */ if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) { if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x2 ? LED_WHITE : LED_OFF); return; @@ -133,7 +133,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/drawcia_riscv/board.c b/board/drawcia_riscv/board.c index 6cd76b17bd..d8d0189635 100644 --- a/board/drawcia_riscv/board.c +++ b/board/drawcia_riscv/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/drawcia_riscv/led.c b/board/drawcia_riscv/led.c index d72626b2a2..f53a376a33 100644 --- a/board/drawcia_riscv/led.c +++ b/board/drawcia_riscv/led.c @@ -124,7 +124,7 @@ static void led_set_battery(void) */ if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) { if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x2 ? LED_WHITE : LED_OFF); return; @@ -133,7 +133,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/driblee/board.c b/board/driblee/board.c index fd03b64e03..739be95ce3 100644 --- a/board/driblee/board.c +++ b/board/driblee/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/drobit/board.c b/board/drobit/board.c index d51097f97d..ab4e98c887 100644 --- a/board/drobit/board.c +++ b/board/drobit/board.c @@ -7,7 +7,7 @@ #include "accelgyro.h" #include "button.h" #include "cbi_ec_fw_config.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "driver/bc12/pi3usb9201.h" #include "driver/ppc/syv682x.h" diff --git a/board/eldrid/board.c b/board/eldrid/board.c index e43bc79b5b..c5a0bb437e 100644 --- a/board/eldrid/board.c +++ b/board/eldrid/board.c @@ -7,7 +7,7 @@ #include "accelgyro.h" #include "button.h" #include "cbi_ec_fw_config.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "driver/accel_bma2x2.h" #include "driver/accelgyro_bmi160.h" diff --git a/board/elemi/led.c b/board/elemi/led.c index 810b8281db..8ba177a0db 100644 --- a/board/elemi/led.c +++ b/board/elemi/led.c @@ -140,7 +140,7 @@ static void led_set_battery(void) * system suspend without charging state. */ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery( @@ -152,7 +152,7 @@ static void led_set_battery(void) suspend_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/elm/led.c b/board/elm/led.c index 211d1b2bbf..06de348884 100644 --- a/board/elm/led.c +++ b/board/elm/led.c @@ -136,7 +136,7 @@ static void elm_led_set_battery(void) 0 : (1000 * remaining_capacity) / full_charge_capacity; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: if (permillage < FULL_BATTERY_PERMILLAGE) { bat_led_set(BAT_LED_BLUE, 0); diff --git a/board/eve/board.h b/board/eve/board.h index a5cade1cc8..f72fd9b523 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -86,7 +86,8 @@ #define CONFIG_BATTERY_CRITICAL_SHUTDOWN_CUT_OFF #define CONFIG_BATTERY_CUT_OFF #define CONFIG_BATTERY_DEVICE_CHEMISTRY "LION" -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 94 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 94 #define CONFIG_BATTERY_PRESENT_CUSTOM #define CONFIG_BATTERY_HW_PRESENT_CUSTOM #define CONFIG_BATTERY_SMART diff --git a/board/eve/led.c b/board/eve/led.c index e3dd8c09c4..3a8acff556 100644 --- a/board/eve/led.c +++ b/board/eve/led.c @@ -486,7 +486,7 @@ static enum led_pattern led_get_double_tap_pattern(int percent_chg) static void led_select_pattern(enum led_pattern *pattern_desired, int tap) { - enum charge_state chg_state = charge_get_state(); + enum led_pwr_state chg_state = led_pwr_get_state(); int side; int percent_chg; enum led_pattern new_pattern; diff --git a/board/ezkinil/board.c b/board/ezkinil/board.c index 03d0727b70..d2124188ce 100644 --- a/board/ezkinil/board.c +++ b/board/ezkinil/board.c @@ -6,7 +6,7 @@ #include "adc.h" #include "button.h" #include "cbi_ssfc.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "cros_board_info.h" #include "driver/accel_kionix.h" #include "driver/accel_kx022.h" diff --git a/board/felwinter/charger_isl9241.c b/board/felwinter/charger_isl9241.c index ddb37cbbcb..b86d92965b 100644 --- a/board/felwinter/charger_isl9241.c +++ b/board/felwinter/charger_isl9241.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/gaelin/board.c b/board/gaelin/board.c index a2d760b92a..3b87757351 100644 --- a/board/gaelin/board.c +++ b/board/gaelin/board.c @@ -6,7 +6,7 @@ #include "assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/galtic/board.c b/board/galtic/board.c index 68a36216fe..a05c9f470d 100644 --- a/board/galtic/board.c +++ b/board/galtic/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_bma2x2.h" #include "driver/accel_kionix.h" diff --git a/board/gelarshie/led.c b/board/gelarshie/led.c index e8b4dbbd8e..4c84965c41 100644 --- a/board/gelarshie/led.c +++ b/board/gelarshie/led.c @@ -72,7 +72,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/gimble/board.c b/board/gimble/board.c index 8b849f7613..0a04dc5714 100644 --- a/board/gimble/board.c +++ b/board/gimble/board.c @@ -6,7 +6,7 @@ #include "battery.h" #include "button.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/gimble/charger.c b/board/gimble/charger.c index 4976abdea6..827152e115 100644 --- a/board/gimble/charger.c +++ b/board/gimble/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/gladios/board.c b/board/gladios/board.c index b0fad206c0..551c53f20f 100644 --- a/board/gladios/board.c +++ b/board/gladios/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/gooey/board.c b/board/gooey/board.c index 6a9d07dbce..0160832c04 100644 --- a/board/gooey/board.c +++ b/board/gooey/board.c @@ -8,7 +8,7 @@ #include "adc_chip.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_lis2dw12.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/goroh/board.c b/board/goroh/board.c index a9eaa35b92..d13c7cfb1b 100644 --- a/board/goroh/board.c +++ b/board/goroh/board.c @@ -7,7 +7,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/gumboz/led.c b/board/gumboz/led.c index c90caeec12..a506684a92 100644 --- a/board/gumboz/led.c +++ b/board/gumboz/led.c @@ -163,7 +163,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/haboki/board.c b/board/haboki/board.c index 2b5e852824..74cf39483b 100644 --- a/board/haboki/board.c +++ b/board/haboki/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/haboki/led.c b/board/haboki/led.c index c6e481e285..4acc6f708d 100644 --- a/board/haboki/led.c +++ b/board/haboki/led.c @@ -124,7 +124,7 @@ static void led_set_battery(void) */ if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) { if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x2 ? LED_WHITE : LED_OFF); return; @@ -133,7 +133,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/hades/board.c b/board/hades/board.c index a8cd55e56c..91721d6b59 100644 --- a/board/hades/board.c +++ b/board/hades/board.c @@ -40,8 +40,8 @@ struct d_notify_policy d_notify_policies[] = { [D_NOTIFY_1] = AC_ATLEAST_W(100), [D_NOTIFY_2] = AC_ATLEAST_W(65), [D_NOTIFY_3] = AC_DC, - [D_NOTIFY_4] = DC_ATLEAST_SOC(20), - [D_NOTIFY_5] = DC_ATLEAST_SOC(5), + [D_NOTIFY_4] = DC_ATMOST_SOC(20), + [D_NOTIFY_5] = DC_ATMOST_SOC(5), }; BUILD_ASSERT(ARRAY_SIZE(d_notify_policies) == D_NOTIFY_COUNT); diff --git a/board/hades/board.h b/board/hades/board.h index 6b2af13935..31baee2038 100644 --- a/board/hades/board.h +++ b/board/hades/board.h @@ -99,6 +99,7 @@ #define GPIO_PCH_WAKE_L GPIO_EC_PCH_INT_ODL #define GPIO_PG_EC_ALL_SYS_PWRGD GPIO_SEQ_EC_ALL_SYS_PG #define GPIO_PG_EC_DSW_PWROK GPIO_SEQ_EC_DSW_PWROK +#define GPIO_PCH_DSW_PWROK GPIO_PCH_PWROK #define GPIO_PG_EC_RSMRST_ODL GPIO_SEQ_EC_RSMRST_ODL #define GPIO_POWER_BUTTON_L GPIO_GSC_EC_PWR_BTN_ODL #define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL diff --git a/board/hades/charger_isl9241.c b/board/hades/charger_isl9241.c index 4886191fcc..ad59c5f139 100644 --- a/board/hades/charger_isl9241.c +++ b/board/hades/charger_isl9241.c @@ -35,7 +35,6 @@ #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/hades/gpio.inc b/board/hades/gpio.inc index 318a14906c..e0d490e5a7 100644 --- a/board/hades/gpio.inc +++ b/board/hades/gpio.inc @@ -8,13 +8,13 @@ #define MODULE_KB MODULE_KEYBOARD_SCAN /* INTERRUPT GPIOs: */ +GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, intel_x86_pwrok_signal_interrupt) GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) GPIO_INT(EC_PROCHOT_IN_L, PIN(A, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt) GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(GSC_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW, power_button_interrupt) GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_PULL_UP | GPIO_HIB_WAKE_HIGH, lid_interrupt) GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) -GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SEQ_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(SLP_SUS_L, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt) diff --git a/board/hades/led.c b/board/hades/led.c index 580c8e1679..c160baa5e8 100644 --- a/board/hades/led.c +++ b/board/hades/led.c @@ -120,7 +120,7 @@ static void led_set_battery(void) battery_ticks++; if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery( @@ -131,7 +131,7 @@ static void led_set_battery(void) return; } - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/hammer/board.h b/board/hammer/board.h index 5d7b912ff2..d5ab4699ac 100644 --- a/board/hammer/board.h +++ b/board/hammer/board.h @@ -313,6 +313,7 @@ /* * Add rollback protection, and independent RW region protection. */ +#define CONFIG_LIBCRYPTOC #define CONFIG_ROLLBACK #define CONFIG_ROLLBACK_SECRET_SIZE 32 #define CONFIG_ROLLBACK_SECRET_LOCAL_ENTROPY_SIZE 32 diff --git a/board/hammer/variants.h b/board/hammer/variants.h index f649f27982..12b955dc43 100644 --- a/board/hammer/variants.h +++ b/board/hammer/variants.h @@ -208,7 +208,7 @@ /* GMR sensor for tablet mode detection */ #if defined(BOARD_DON) || defined(BOARD_MASTERBALL) || \ defined(BOARD_MOONBALL) || defined(BOARD_WHISKERS) || \ - defined(BOARD_EEL) + defined(BOARD_EEL) || defined(BOARD_JEWEL) #define CONFIG_GMR_TABLET_MODE #endif diff --git a/board/herobrine/led.c b/board/herobrine/led.c index fb68e85deb..475604dd42 100644 --- a/board/herobrine/led.c +++ b/board/herobrine/led.c @@ -93,7 +93,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/homestar/led.c b/board/homestar/led.c index f6b3cddf48..b1e819a92f 100644 --- a/board/homestar/led.c +++ b/board/homestar/led.c @@ -81,7 +81,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: case PWR_STATE_CHARGE_NEAR_FULL: if (chipset_in_state(CHIPSET_STATE_ON | @@ -91,7 +91,7 @@ static void board_led_set_battery(void) /* battery capa <= 5%, Red */ color = LED_RED; } else if (percent > BATTERY_LEVEL_CRITICAL && - percent < BATTERY_LEVEL_NEAR_FULL) { + percent < CONFIG_BATT_HOST_FULL_FACTOR) { /* 5% < battery capa < 97%, Orange */ color = LED_AMBER; } else { diff --git a/board/hyperdebug/gpio.c b/board/hyperdebug/gpio.c index 5bcabe226d..dbffa7fefb 100644 --- a/board/hyperdebug/gpio.c +++ b/board/hyperdebug/gpio.c @@ -28,6 +28,34 @@ const struct dac_t dac_channels[GPIO_COUNT] = { }; /* + * GPIO structure for keeping extra flags such as GPIO_OPEN_DRAIN, to be applied + * whenever the pin is switched into "alternate" mode. + */ +struct gpio_alt_flags { + /* Port base address */ + uint32_t port; + + /* Bitmask on that port (multiple bits allowed) */ + uint32_t mask; + + /* Flags (GPIO_*; see above). */ + uint32_t flags; +}; + +/* + * Construct the gpio_alt_flags array, this really is just a subset of the + * columns in the gpio_alt_funcs array in common/gpio.c (which is not accessible + * from here). This array is used by extra_alternate_flags(). + */ +#define ALTERNATE(pinmask, function, module, flagz) \ + { GPIO_##pinmask, .flags = (flagz) }, + +static __const_data const struct gpio_alt_flags gpio_alt_flags[] = { +#include "gpio.wrap" +}; +#undef ALTERNATE + +/* * A cyclic buffer is used to record events (edges) of one or more GPIO * signals. Each event records the time since the previous event, and the * signal that changed (the direction of change is not explicitly recorded). @@ -284,6 +312,30 @@ static void stop_all_gpio_monitoring(void) } } +/* + * Return GPIO_OPEN_DRAIN or any other special flags to apply when the given + * signal is in "alternate" mode. + */ +static uint32_t extra_alternate_flags(enum gpio_signal signal) +{ + const struct gpio_info *g = gpio_list + signal; + const struct gpio_alt_flags *af; + + /* Find the first ALTERNATE() declaration for the given pin. */ + for (af = gpio_alt_flags; + af < gpio_alt_flags + ARRAY_SIZE(gpio_alt_flags); af++) { + if (af->port != g->port) + continue; + + if (af->mask & g->mask) { + return af->flags; + } + } + + /* No ALTERNATE() declaration mention the given pin. */ + return 0; +} + /** * Find a GPIO signal by name. * @@ -344,7 +396,7 @@ static int command_gpio_mode(int argc, const char **argv) /* Disable digital output, when DAC is overriding. */ flags |= GPIO_INPUT; } else if (strcasecmp(argv[2], "alternate") == 0) - flags |= GPIO_ALTERNATE; + flags |= GPIO_ALTERNATE | extra_alternate_flags(gpio); else return EC_ERROR_PARAM2; @@ -484,7 +536,7 @@ static int command_gpio_multiset(int argc, const char **argv) /* Disable digital output, when DAC is overriding. */ flags |= GPIO_INPUT; } else if (strcasecmp(argv[4], "alternate") == 0) - flags |= GPIO_ALTERNATE; + flags |= GPIO_ALTERNATE | extra_alternate_flags(gpio); else return EC_ERROR_PARAM4; } @@ -686,6 +738,11 @@ static int command_gpio_monitoring_read(int argc, const char **argv) gpio_list[gpios[i]].name); return EC_ERROR_PARAM3 + i; } + if (slot->signal_no != i) { + ccprintf("Error: Inconsistent order at %s\n", + gpio_list[gpios[i]].name); + return EC_ERROR_PARAM3 + i; + } if (buf == NULL) { buf = slot->buffer; } else if (buf != slot->buffer) { @@ -872,6 +929,9 @@ static int command_reinit(int argc, const char **argv) if (flags & GPIO_DEFAULT) continue; + if (flags & GPIO_ALTERNATE) + flags |= extra_alternate_flags(i); + /* Set up GPIO based on flags */ gpio_set_flags_by_mask(g->port, g->mask, flags); } diff --git a/board/hyperdebug/i2c.c b/board/hyperdebug/i2c.c index 6687b47c38..46b46f9278 100644 --- a/board/hyperdebug/i2c.c +++ b/board/hyperdebug/i2c.c @@ -16,17 +16,20 @@ const struct i2c_port_t i2c_ports[] = { .port = 0, .kbps = 100, .scl = GPIO_CN7_2, - .sda = GPIO_CN7_4 }, + .sda = GPIO_CN7_4, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED }, { .name = "I2C2", .port = 1, .kbps = 100, .scl = GPIO_CN9_19, - .sda = GPIO_CN9_21 }, + .sda = GPIO_CN9_21, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED }, { .name = "I2C3", .port = 2, .kbps = 100, .scl = GPIO_CN9_11, - .sda = GPIO_CN9_9 }, + .sda = GPIO_CN9_9, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -59,7 +62,7 @@ static int find_i2c_by_name(const char *name) static void print_i2c_info(int index) { - uint32_t bits_per_second = 100000; + uint32_t bits_per_second = 1000 * i2c_freq_to_khz(i2c_get_freq(index)); ccprintf(" %d %s %d bps\n", index, i2c_ports[index].name, bits_per_second); @@ -95,13 +98,52 @@ static int command_i2c_info(int argc, const char **argv) return EC_SUCCESS; } +static int command_i2c_set_speed(int argc, const char **argv) +{ + int index; + uint32_t desired_speed; + char *e; + if (argc < 5) + return EC_ERROR_PARAM_COUNT; + + index = find_i2c_by_name(argv[3]); + if (index < 0) + return EC_ERROR_PARAM3; + + desired_speed = strtoi(argv[4], &e, 0); + if (*e) + return EC_ERROR_PARAM4; + + if (desired_speed >= 1000000) { + i2c_set_freq(index, I2C_FREQ_1000KHZ); + } else if (desired_speed >= 400000) { + i2c_set_freq(index, I2C_FREQ_400KHZ); + } else { + i2c_set_freq(index, I2C_FREQ_100KHZ); + } + return EC_SUCCESS; +} + +static int command_i2c_set(int argc, const char **argv) +{ + if (argc < 3) + return EC_ERROR_PARAM_COUNT; + if (!strcasecmp(argv[2], "speed")) + return command_i2c_set_speed(argc, argv); + return EC_ERROR_PARAM2; +} + static int command_i2c(int argc, const char **argv) { if (argc < 2) return EC_ERROR_PARAM_COUNT; if (!strcasecmp(argv[1], "info")) return command_i2c_info(argc, argv); + if (!strcasecmp(argv[1], "set")) + return command_i2c_set(argc, argv); return EC_ERROR_PARAM1; } -DECLARE_CONSOLE_COMMAND_FLAGS(i2c, command_i2c, "info [PORT]", +DECLARE_CONSOLE_COMMAND_FLAGS(i2c, command_i2c, + "info [PORT]" + "\nset speed PORT BPS", "I2C bus manipulation", CMD_FLAG_RESTRICTED); diff --git a/board/jinlon/led.c b/board/jinlon/led.c index a77ee8ba62..43a936e0a2 100644 --- a/board/jinlon/led.c +++ b/board/jinlon/led.c @@ -148,7 +148,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/kakadu/led.c b/board/kakadu/led.c index 26e1ea22bb..ba833e0e22 100644 --- a/board/kakadu/led.c +++ b/board/kakadu/led.c @@ -26,13 +26,13 @@ const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); static void kakadu_led_set_battery(void) { - enum charge_state chstate; + enum led_pwr_state chstate; enum power_state powerstate; static uint8_t prv_white, prv_amber; static uint8_t time_cnt; uint8_t br[EC_LED_COLOR_COUNT] = { 0 }; - chstate = charge_get_state(); + chstate = led_pwr_get_state(); powerstate = power_get_state(); switch (chstate) { diff --git a/board/kano/charger.c b/board/kano/charger.c index ddb37cbbcb..b86d92965b 100644 --- a/board/kano/charger.c +++ b/board/kano/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/kappa/led.c b/board/kappa/led.c index d9ecb33da0..6fb3b830f8 100644 --- a/board/kappa/led.c +++ b/board/kappa/led.c @@ -87,7 +87,7 @@ static void led_set_battery(void) /* override battery led for system suspend */ if (chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_STANDBY) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { led_set_color_battery(power_ticks++ & 0x2 ? LED_WHITE : LED_OFF); return; @@ -95,7 +95,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/katsu/led.c b/board/katsu/led.c index 3ce9466613..346c5caa19 100644 --- a/board/katsu/led.c +++ b/board/katsu/led.c @@ -26,13 +26,13 @@ const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); static void katsu_led_set_battery(void) { - enum charge_state chstate; + enum led_pwr_state chstate; enum power_state powerstate; static uint8_t prv_white, prv_amber; static uint8_t time_cnt; uint8_t br[EC_LED_COLOR_COUNT] = { 0 }; - chstate = charge_get_state(); + chstate = led_pwr_get_state(); powerstate = power_get_state(); switch (chstate) { diff --git a/board/kingoftown/led.c b/board/kingoftown/led.c index 2bbb0de0af..add916cdea 100644 --- a/board/kingoftown/led.c +++ b/board/kingoftown/led.c @@ -106,7 +106,7 @@ static void board_led_set_battery(void) * charging. */ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_blink_cycle = power_ticks % (2 * TIMES_TICK_ONE_SEC); @@ -121,7 +121,7 @@ static void board_led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/kinox/board.c b/board/kinox/board.c index 5748e5b013..02d741ddc5 100644 --- a/board/kinox/board.c +++ b/board/kinox/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/kracko/board.c b/board/kracko/board.c index 025ec5109c..2f69f43632 100644 --- a/board/kracko/board.c +++ b/board/kracko/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/kukui/led.c b/board/kukui/led.c index 9cfdf855be..7529f831f9 100644 --- a/board/kukui/led.c +++ b/board/kukui/led.c @@ -15,7 +15,7 @@ const enum ec_led_id supported_led_ids[] = { EC_LED_ID_BATTERY_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -static enum charge_state prv_chstate = PWR_STATE_INIT; +static enum led_pwr_state prv_chstate = PWR_STATE_INIT; #define LED_OFF MT6370_LED_ID_OFF #define LED_RED MT6370_LED_ID1 @@ -29,11 +29,11 @@ static enum charge_state prv_chstate = PWR_STATE_INIT; static void kukui_led_set_battery(void) { - enum charge_state chstate; + enum led_pwr_state chstate; static uint8_t prv_r, prv_g, prv_b; uint8_t br[EC_LED_COLOR_COUNT] = { 0 }; - chstate = charge_get_state(); + chstate = led_pwr_get_state(); if (prv_chstate == chstate && chstate != PWR_STATE_DISCHARGE) return; diff --git a/board/kuldax/board.c b/board/kuldax/board.c index 545ee3c23c..c5fb16c5e7 100644 --- a/board/kuldax/board.c +++ b/board/kuldax/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/lalala/board.c b/board/lalala/board.c index ed8c5ae2e5..2d9c004f20 100644 --- a/board/lalala/board.c +++ b/board/lalala/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/lantis/board.c b/board/lantis/board.c index 92c030def1..600f141639 100644 --- a/board/lantis/board.c +++ b/board/lantis/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/lantis/led.c b/board/lantis/led.c index 3b66ad6d6b..75242a60ba 100644 --- a/board/lantis/led.c +++ b/board/lantis/led.c @@ -175,7 +175,7 @@ static void led_set_battery(void) */ if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) { if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(RIGHT_PORT, power_ticks & 0x2 ? @@ -190,7 +190,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: set_active_port_color(LED_AMBER); break; diff --git a/board/lazor/led.c b/board/lazor/led.c index cf1f68d77e..c550a96896 100644 --- a/board/lazor/led.c +++ b/board/lazor/led.c @@ -69,7 +69,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/lisbon/board.c b/board/lisbon/board.c index b0fad206c0..551c53f20f 100644 --- a/board/lisbon/board.c +++ b/board/lisbon/board.c @@ -6,7 +6,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" diff --git a/board/madoo/board.c b/board/madoo/board.c index a1cdb024f9..bb031c3acf 100644 --- a/board/madoo/board.c +++ b/board/madoo/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/madoo/led.c b/board/madoo/led.c index 5d17acee6e..214a941da8 100644 --- a/board/madoo/led.c +++ b/board/madoo/led.c @@ -79,7 +79,7 @@ int battery_safety_check(void) int rv; /* ignore battery in error state because it has other behavior */ - if (charge_get_state() == PWR_STATE_ERROR) + if (led_pwr_get_state() == PWR_STATE_ERROR) return false; /* turn off LED due to a safety fault */ @@ -130,7 +130,7 @@ __override void led_set_color_battery(enum ec_led_colors color) if (battery_safety_check()) { gpio_set_level(GPIO_BAT_LED_AMBER_L, LED_OFF_LVL); gpio_set_level(GPIO_EC_CHG_LED_R_Y, LED_OFF_LVL); - } else if (charge_get_state() == PWR_STATE_ERROR && + } else if (led_pwr_get_state() == PWR_STATE_ERROR && system_get_board_version() >= 3) { gpio_set_level(GPIO_EC_CHG_LED_R_W, LED_OFF_LVL); gpio_set_level(GPIO_EC_CHG_LED_R_Y, LED_ON_LVL); diff --git a/board/magolor/board.c b/board/magolor/board.c index af524d9bfa..7759a38a0c 100644 --- a/board/magolor/board.c +++ b/board/magolor/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/marasov/charger.c b/board/marasov/charger.c index c531286643..d78c345f94 100644 --- a/board/marasov/charger.c +++ b/board/marasov/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/marzipan/led.c b/board/marzipan/led.c index 0a6d8df959..cb55fdddae 100644 --- a/board/marzipan/led.c +++ b/board/marzipan/led.c @@ -69,7 +69,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/mchpevb1/led.c b/board/mchpevb1/led.c index 8a5d85e97d..98a72c7c85 100644 --- a/board/mchpevb1/led.c +++ b/board/mchpevb1/led.c @@ -119,7 +119,7 @@ static void board_led_set_battery(void) * Same as the chromeos spec * Green/Amber for CHARGE_FLAG_FORCE_IDLE */ - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: board_led_set_color_battery(LED_AMBER); break; diff --git a/board/metaknight/board.c b/board/metaknight/board.c index cde7ed51ec..7675c7c8f5 100644 --- a/board/metaknight/board.c +++ b/board/metaknight/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/mithrax/charger_isl9241.c b/board/mithrax/charger_isl9241.c index c6ee062ab5..76e2712181 100644 --- a/board/mithrax/charger_isl9241.c +++ b/board/mithrax/charger_isl9241.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/moli/board.c b/board/moli/board.c index e3a7bd0fa9..a8e4eddc9d 100644 --- a/board/moli/board.c +++ b/board/moli/board.c @@ -7,7 +7,7 @@ #include "builtin/assert.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/morphius/board.h b/board/morphius/board.h index b430055930..ca3ecf4f03 100644 --- a/board/morphius/board.h +++ b/board/morphius/board.h @@ -23,7 +23,8 @@ #define CONFIG_ASSERT_CCD_MODE_ON_DTS_CONNECT #undef CONFIG_LED_ONOFF_STATES -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 91 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 91 #undef ZORK_PS8818_RX_INPUT_TERM #define ZORK_PS8818_RX_INPUT_TERM PS8818_RX_INPUT_TERM_85_OHM diff --git a/board/morphius/led.c b/board/morphius/led.c index 23f715da02..89c2f01793 100644 --- a/board/morphius/led.c +++ b/board/morphius/led.c @@ -162,7 +162,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ led_set_color_battery(LED_AMBER); diff --git a/board/mrbland/led.c b/board/mrbland/led.c index fbc7bf3c19..d2ef61f5c4 100644 --- a/board/mrbland/led.c +++ b/board/mrbland/led.c @@ -100,7 +100,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: case PWR_STATE_CHARGE_NEAR_FULL: if (chipset_in_state(CHIPSET_STATE_ON | @@ -110,7 +110,7 @@ static void board_led_set_battery(void) /* battery capa <= 5%, Red */ color = LED_RED; } else if (percent > BATTERY_LEVEL_CRITICAL && - percent < BATTERY_LEVEL_NEAR_FULL) { + percent < CONFIG_BATT_HOST_FULL_FACTOR) { /* 5% < battery capa < 97%, Orange */ color = LED_AMBER; } else { @@ -159,7 +159,7 @@ static void board_led_set_power(void) power_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: case PWR_STATE_CHARGE_NEAR_FULL: case PWR_STATE_DISCHARGE: diff --git a/board/nami/led.c b/board/nami/led.c index a92302b860..dda550cdf6 100644 --- a/board/nami/led.c +++ b/board/nami/led.c @@ -504,12 +504,12 @@ void config_leds(enum led_charge_state charge) static void call_handler(void) { int soc; - enum charge_state cs; + enum led_pwr_state cs; if (!led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) return; - cs = charge_get_state(); + cs = led_pwr_get_state(); soc = charge_get_display_charge(); if (soc < 0) cs = PWR_STATE_ERROR; diff --git a/board/nautilus/led.c b/board/nautilus/led.c index 3fab136610..92e2dd6e8c 100644 --- a/board/nautilus/led.c +++ b/board/nautilus/led.c @@ -70,7 +70,7 @@ static void nautilus_led_set_power_battery(void) { static unsigned int power_ticks; enum led_color cur_led_color = LED_RED; - enum charge_state chg_state = charge_get_state(); + enum led_pwr_state chg_state = led_pwr_get_state(); int charge_percent = charge_get_percent(); if (chipset_in_state(CHIPSET_STATE_ON)) { @@ -91,7 +91,7 @@ static void nautilus_led_set_power_battery(void) switch (chg_state) { case PWR_STATE_DISCHARGE: if ((charge_get_flags() & CHARGE_FLAG_EXTERNAL_POWER) && - charge_percent >= BATTERY_LEVEL_NEAR_FULL) + charge_percent >= CONFIG_BATT_HOST_FULL_FACTOR) cur_led_color = LED_GREEN; else cur_led_color = LED_OFF; diff --git a/board/nipperkin/led.c b/board/nipperkin/led.c index 5390748af1..99f0c616fe 100644 --- a/board/nipperkin/led.c +++ b/board/nipperkin/led.c @@ -140,7 +140,7 @@ static void led_set_battery(void) * system suspend with non-charging state. */ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { power_ticks++; led_set_color_battery(LED_RIGHT_PORT, @@ -158,7 +158,7 @@ static void led_set_battery(void) power_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/nocturne/battery.c b/board/nocturne/battery.c index bfb4b25467..4914f89b2e 100644 --- a/board/nocturne/battery.c +++ b/board/nocturne/battery.c @@ -8,7 +8,7 @@ #include "battery.h" #include "battery_smart.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/nocturne/board.c b/board/nocturne/board.c index b566d43e41..de7671163b 100644 --- a/board/nocturne/board.c +++ b/board/nocturne/board.c @@ -9,7 +9,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "chipset.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/oak/led.c b/board/oak/led.c index cbf951dec5..b8ae3be780 100644 --- a/board/oak/led.c +++ b/board/oak/led.c @@ -154,7 +154,7 @@ static void oak_led_set_battery(int board_version) * - Battery discharging capacity<10%, red blink * - Battery error: Red ON */ - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: bat_led_set(BAT_LED_AMBER, 1); break; @@ -219,7 +219,7 @@ static void oak_led_set_battery(int board_version) * situation: Orange in blinking mode (1s on, 1s off) * Using battery or not connected to AC power: OFF */ - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: bat_led_set(BAT_LED_ORANGE, 1); break; diff --git a/board/omnigul/charger.c b/board/omnigul/charger.c index dc8fa76be3..b3ca8dc104 100644 --- a/board/omnigul/charger.c +++ b/board/omnigul/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/omnigul/fw_config.c b/board/omnigul/fw_config.c index 5ac34a56b5..34b460dad1 100644 --- a/board/omnigul/fw_config.c +++ b/board/omnigul/fw_config.c @@ -41,3 +41,8 @@ union omnigul_cbi_fw_config get_fw_config(void) { return fw_config; } + +bool ec_cfg_has_tabletmode(void) +{ + return (fw_config.tab_mode == TABLETMODE_ENABLED); +} diff --git a/board/omnigul/fw_config.h b/board/omnigul/fw_config.h index d30c09cb24..d0facef0da 100644 --- a/board/omnigul/fw_config.h +++ b/board/omnigul/fw_config.h @@ -53,4 +53,6 @@ union omnigul_cbi_fw_config { */ union omnigul_cbi_fw_config get_fw_config(void); +bool ec_cfg_has_tabletmode(void); + #endif /* __BOARD_OMNIGUL_FW_CONFIG_H_ */ diff --git a/board/omnigul/sensors.c b/board/omnigul/sensors.c index e203a194c4..a2d08bd045 100644 --- a/board/omnigul/sensors.c +++ b/board/omnigul/sensors.c @@ -8,9 +8,11 @@ #include "common.h" #include "driver/accel_lis2dw12.h" #include "driver/accelgyro_lsm6dso.h" +#include "fw_config.h" #include "gpio.h" #include "hooks.h" #include "motion_sense.h" +#include "tablet_mode.h" #include "temp_sensor.h" #include "temp_sensor/thermistor.h" #include "thermal.h" @@ -134,10 +136,19 @@ const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); static void baseboard_sensors_init(void) { - /* Enable gpio interrupt for lid accel sensor */ - gpio_enable_interrupt(GPIO_EC_ACCEL_INT_R_L); - /* Enable gpio interrupt for base accelgyro sensor */ - gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L); + if (ec_cfg_has_tabletmode()) { + /* Enable gpio interrupt for lid accel sensor */ + gpio_enable_interrupt(GPIO_EC_ACCEL_INT_R_L); + /* Enable gpio interrupt for base accelgyro sensor */ + gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L); + } else { + gmr_tablet_switch_disable(); + /* Base accel is not stuffed, don't allow line to float */ + gpio_set_flags(GPIO_EC_ACCEL_INT_R_L, + GPIO_INPUT | GPIO_PULL_DOWN); + gpio_set_flags(GPIO_EC_IMU_INT_R_L, + GPIO_INPUT | GPIO_PULL_DOWN); + } } DECLARE_HOOK(HOOK_INIT, baseboard_sensors_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/board/osiris/charger.c b/board/osiris/charger.c index c6ee062ab5..76e2712181 100644 --- a/board/osiris/charger.c +++ b/board/osiris/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/pazquel/led.c b/board/pazquel/led.c index 180e9829f5..0b67b83878 100644 --- a/board/pazquel/led.c +++ b/board/pazquel/led.c @@ -68,7 +68,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_RED; diff --git a/board/pirika/board.c b/board/pirika/board.c index f153da2ce7..d1baae03f2 100644 --- a/board/pirika/board.c +++ b/board/pirika/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_kionix.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/pompom/led.c b/board/pompom/led.c index 31fccbf4e2..2668f05e0f 100644 --- a/board/pompom/led.c +++ b/board/pompom/led.c @@ -85,7 +85,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/poppy/led.c b/board/poppy/led.c index f388dd0326..7f94a84147 100644 --- a/board/poppy/led.c +++ b/board/poppy/led.c @@ -96,7 +96,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/primus/board.c b/board/primus/board.c index 2a8ff39ac7..f42e83c509 100644 --- a/board/primus/board.c +++ b/board/primus/board.c @@ -7,7 +7,7 @@ #include "button.h" #include "charge_manager.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/primus/board.h b/board/primus/board.h index 7346acc2ab..3fb8b868c6 100644 --- a/board/primus/board.h +++ b/board/primus/board.h @@ -131,7 +131,8 @@ #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* LED */ -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 91 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 91 /* Fan features */ #define CONFIG_CUSTOM_FAN_CONTROL diff --git a/board/primus/charger.c b/board/primus/charger.c index 4976abdea6..827152e115 100644 --- a/board/primus/charger.c +++ b/board/primus/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/primus/led.c b/board/primus/led.c index 269b497c4b..b25eade32c 100644 --- a/board/primus/led.c +++ b/board/primus/led.c @@ -69,7 +69,7 @@ static void led_set_color_battery(enum ec_led_colors color) static void led_set_battery(void) { - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ led_set_color_battery(EC_LED_COLOR_AMBER); diff --git a/board/prism/board.h b/board/prism/board.h index 42768de2e7..c4bf4de58e 100644 --- a/board/prism/board.h +++ b/board/prism/board.h @@ -184,6 +184,7 @@ /* * Add rollback protection, and independent RW region protection. */ +#define CONFIG_LIBCRYPTOC #define CONFIG_ROLLBACK #define CONFIG_ROLLBACK_SECRET_SIZE 32 #define CONFIG_ROLLBACK_SECRET_LOCAL_ENTROPY_SIZE 32 diff --git a/board/puff/board.c b/board/puff/board.c index ce2a59d8cb..7e5c2ad8e6 100644 --- a/board/puff/board.c +++ b/board/puff/board.c @@ -8,7 +8,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "common.h" #include "core/cortex-m/cpu.h" diff --git a/board/quackingstick/led.c b/board/quackingstick/led.c index ef3a858e2b..202a7e7847 100644 --- a/board/quackingstick/led.c +++ b/board/quackingstick/led.c @@ -72,7 +72,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate amber on when charging. */ color = LED_AMBER; diff --git a/board/rammus/board.h b/board/rammus/board.h index 096d419fe9..bfe8f75e53 100644 --- a/board/rammus/board.h +++ b/board/rammus/board.h @@ -75,7 +75,8 @@ #define CONFIG_BATTERY_HW_PRESENT_CUSTOM #define CONFIG_BATTERY_DEVICE_CHEMISTRY "LION" #define CONFIG_BATTERY_SMART -#define CONFIG_BATTERY_LEVEL_NEAR_FULL 94 +#undef CONFIG_BATT_HOST_FULL_FACTOR +#define CONFIG_BATT_HOST_FULL_FACTOR 94 /* Charger */ #define CONFIG_CHARGE_MANAGER diff --git a/board/rammus/led.c b/board/rammus/led.c index 5ae415a61a..e9b7edec7f 100644 --- a/board/rammus/led.c +++ b/board/rammus/led.c @@ -123,7 +123,7 @@ static void rammus_led_set_power(void) static void rammus_led_set_battery(void) { - enum charge_state chg_state = charge_get_state(); + enum led_pwr_state chg_state = led_pwr_get_state(); int charge_percent = charge_get_percent(); static unsigned int charge_ticks; @@ -131,7 +131,7 @@ static void rammus_led_set_battery(void) switch (chg_state) { case PWR_STATE_DISCHARGE: if ((charge_get_flags() & CHARGE_FLAG_EXTERNAL_POWER) && - charge_percent >= BATTERY_LEVEL_NEAR_FULL) + charge_percent >= CONFIG_BATT_HOST_FULL_FACTOR) config_battery_led(LED_STATE_FULL); else config_battery_led(LED_STATE_DISCHARGE); diff --git a/board/redrix/charger.c b/board/redrix/charger.c index 4976abdea6..827152e115 100644 --- a/board/redrix/charger.c +++ b/board/redrix/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/redrix/led.c b/board/redrix/led.c index 0eae346948..194ba6cb7d 100644 --- a/board/redrix/led.c +++ b/board/redrix/led.c @@ -158,7 +158,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/reef/led.c b/board/reef/led.c index 8bc52dbc75..adc9ab823f 100644 --- a/board/reef/led.c +++ b/board/reef/led.c @@ -95,7 +95,7 @@ static void led_set_battery(void) static int battery_ticks; static int suspend_ticks; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/reef_it8320/led.c b/board/reef_it8320/led.c index 630fdf336d..c150b237c4 100644 --- a/board/reef_it8320/led.c +++ b/board/reef_it8320/led.c @@ -96,7 +96,7 @@ static void led_set_battery(void) static int battery_ticks; static int suspend_ticks; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/reef_mchp/led.c b/board/reef_mchp/led.c index 96ea6bb958..37ec8493e7 100644 --- a/board/reef_mchp/led.c +++ b/board/reef_mchp/led.c @@ -96,7 +96,7 @@ static void led_set_battery(void) static int battery_ticks; static int suspend_ticks; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: led_set_color_battery(LED_AMBER); break; diff --git a/board/sasuke/board.c b/board/sasuke/board.c index bc96165f4d..502fa60bd5 100644 --- a/board/sasuke/board.c +++ b/board/sasuke/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/sasukette/board.c b/board/sasukette/board.c index f5076382e6..7284d2d3c8 100644 --- a/board/sasukette/board.c +++ b/board/sasukette/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/bc12/pi3usb9201.h" diff --git a/board/scarlet/battery.c b/board/scarlet/battery.c index 5d4412f66c..f38e1f7896 100644 --- a/board/scarlet/battery.c +++ b/board/scarlet/battery.c @@ -243,12 +243,12 @@ int charger_profile_override(struct charge_state_data *curr) /* * When the charger says it's done charging, even if fuel gauge says - * SOC < BATTERY_LEVEL_NEAR_FULL, we'll overwrite SOC with - * BATTERY_LEVEL_NEAR_FULL. So we can ensure both Chrome OS UI + * SOC < CONFIG_BATT_HOST_FULL_FACTOR, we'll overwrite SOC with + * CONFIG_BATT_HOST_FULL_FACTOR. So we can ensure both Chrome OS UI * and battery LED indicate full charge. */ if (rt946x_is_charge_done()) { - curr->batt.state_of_charge = MAX(BATTERY_LEVEL_NEAR_FULL, + curr->batt.state_of_charge = MAX(CONFIG_BATT_HOST_FULL_FACTOR, curr->batt.state_of_charge); /* * This is a workaround for b:78792296. When AP is off and diff --git a/board/scarlet/board.c b/board/scarlet/board.c index 9c26757ba0..daa247b385 100644 --- a/board/scarlet/board.c +++ b/board/scarlet/board.c @@ -8,7 +8,6 @@ #include "button.h" #include "charge_manager.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/scarlet/led.c b/board/scarlet/led.c index 6f42f462cf..f4a3bae9f4 100644 --- a/board/scarlet/led.c +++ b/board/scarlet/led.c @@ -63,7 +63,7 @@ static void scarlet_led_set_battery(void) battery_second++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: bat_led_set_color(LED_AMBER); break; @@ -74,7 +74,7 @@ static void scarlet_led_set_battery(void) else if (charge_get_percent() < 10) bat_led_set_color((battery_second & 3) ? LED_OFF : LED_AMBER); - else if (charge_get_percent() >= BATTERY_LEVEL_NEAR_FULL && + else if (charge_get_percent() >= CONFIG_BATT_HOST_FULL_FACTOR && (chflags & CHARGE_FLAG_EXTERNAL_POWER)) bat_led_set_color(LED_GREEN); else diff --git a/board/shotzo/board.c b/board/shotzo/board.c index ca90a54301..6ae6d8e55c 100644 --- a/board/shotzo/board.c +++ b/board/shotzo/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/charger/sm5803.h" diff --git a/board/spherion/board.c b/board/spherion/board.c index 0170a8998e..b6df18b119 100644 --- a/board/spherion/board.c +++ b/board/spherion/board.c @@ -7,7 +7,7 @@ #include "adc.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/storo/board.c b/board/storo/board.c index 854838d844..d8f1b09ae1 100644 --- a/board/storo/board.c +++ b/board/storo/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "cros_board_info.h" #include "driver/accel_bma2x2.h" diff --git a/board/taeko/board.c b/board/taeko/board.c index a654d4c76a..aaf7f215ff 100644 --- a/board/taeko/board.c +++ b/board/taeko/board.c @@ -7,7 +7,7 @@ #include "button.h" #include "charge_manager.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/taeko/charger.c b/board/taeko/charger.c index 4976abdea6..827152e115 100644 --- a/board/taeko/charger.c +++ b/board/taeko/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/taniks/board.c b/board/taniks/board.c index 5657de1fe7..fdda313c9e 100644 --- a/board/taniks/board.c +++ b/board/taniks/board.c @@ -7,7 +7,7 @@ #include "button.h" #include "charge_manager.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/taniks/charger.c b/board/taniks/charger.c index 4976abdea6..827152e115 100644 --- a/board/taniks/charger.c +++ b/board/taniks/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/taranza/board.c b/board/taranza/board.c index 3c9cc62e2b..2fdeebb57b 100644 --- a/board/taranza/board.c +++ b/board/taranza/board.c @@ -9,7 +9,7 @@ #include "board.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/ppc/syv682x_public.h" #include "driver/tcpm/it83xx_pd.h" @@ -20,8 +20,6 @@ #include "intc.h" #include "power.h" #include "power_button.h" -#include "pwm.h" -#include "pwm_chip.h" #include "switch.h" #include "system.h" #include "tablet_mode.h" @@ -112,29 +110,6 @@ const int usb_port_enable[USB_PORT_COUNT] = { GPIO_EN_USB_A3_VBUS, GPIO_EN_USB_A4_VBUS, }; -/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ -const struct pwm_t pwm_channels[] = { - [PWM_CH_LED_RED] = { - .channel = 1, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 2400, - }, - - [PWM_CH_LED_GREEN] = { - .channel = 2, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 2400, - }, - - [PWM_CH_LED_BLUE] = { - .channel = 3, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 2400, - } - -}; -BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); - /* Thermistors */ const struct temp_sensor_t temp_sensors[] = { [TEMP_SENSOR_1] = { .name = "Memory", diff --git a/board/taranza/board.h b/board/taranza/board.h index 9078e4a137..23453da79c 100644 --- a/board/taranza/board.h +++ b/board/taranza/board.h @@ -77,13 +77,6 @@ #undef CONFIG_BATTERY_REVIVE_DISCONNECT #undef CONFIG_BATTERY_SMART -/* LED */ -#define CONFIG_LED_PWM -#define CONFIG_LED_PWM_COUNT 1 - -/* PWM */ -#define CONFIG_PWM - /* Thermistors */ #define CONFIG_TEMP_SENSOR #define CONFIG_THERMISTOR @@ -137,13 +130,6 @@ enum charge_port { enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_COUNT }; -enum pwm_channel { - PWM_CH_LED_RED, - PWM_CH_LED_GREEN, - PWM_CH_LED_BLUE, - PWM_CH_COUNT, -}; - /* ADC channels */ enum adc_channel { ADC_VSNS_PP3300_A, /* ADC0 */ diff --git a/board/taranza/gpio.inc b/board/taranza/gpio.inc index 7a9b1c3fdc..652c457f62 100644 --- a/board/taranza/gpio.inc +++ b/board/taranza/gpio.inc @@ -129,6 +129,9 @@ GPIO(ECH1_PACKET_MODE, PIN(C, 0), GPIO_OUT_LOW) GPIO(EN_RS232_X, PIN(E, 6), GPIO_OUT_LOW) GPIO(UART0_RX, PIN(B, 1), GPIO_OUT_LOW) /* UART_EC_TX_DBG_RX */ +/* LED */ +GPIO(LED_W_ODL, PIN(A, 2), GPIO_OUT_HIGH) + /* NC pins, enable internal pull-down to avoid floating state. */ GPIO(GPIOG0_NC, PIN(G, 0), GPIO_INPUT | GPIO_PULL_DOWN) GPIO(GPIOG3_NC, PIN(G, 3), GPIO_INPUT | GPIO_PULL_DOWN) @@ -142,6 +145,8 @@ GPIO(GPIOI4_NC, PIN(I, 4), GPIO_INPUT | GPIO_PULL_DOWN) GPIO(GPIOJ6_NC, PIN(J, 6), GPIO_INPUT | GPIO_PULL_DOWN) GPIO(GPIOK3_NC, PIN(K, 3), GPIO_INPUT | GPIO_PULL_DOWN) GPIO(GPIOM6_NC, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOA1_NC, PIN(A, 1), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(GPIOA3_NC, PIN(A, 3), GPIO_INPUT | GPIO_PULL_DOWN) /* Alternate functions GPIO definitions */ /* UART */ @@ -172,8 +177,3 @@ ALTERNATE(PIN_MASK(L, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, ADC16: SNS_PPVAR_PWR_IN */ - -/* PWM */ -ALTERNATE(PIN_MASK(A, BIT(1) | BIT(2) | BIT(3)), 0, MODULE_PWM, - 0) /* LED_[R,G,B]_ODL - */ diff --git a/board/taranza/led.c b/board/taranza/led.c index 31ab932829..4f41c3c6c1 100644 --- a/board/taranza/led.c +++ b/board/taranza/led.c @@ -3,78 +3,65 @@ * found in the LICENSE file. */ -/* Taranza specific PWM LED settings. */ +/* Taranza specific LED settings. */ -#include "common.h" +#include "chipset.h" #include "ec_commands.h" -#include "led_pwm.h" -#include "pwm.h" -#include "util.h" +#include "gpio.h" +#include "hooks.h" +#include "led_common.h" + +#define LED_ON_LVL 0 +#define LED_OFF_LVL 1 const enum ec_led_id supported_led_ids[] = { EC_LED_ID_POWER_LED, }; + const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -/* One physical LED with red, green, and blue. */ -struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { - /* Red, Green, Blue */ - [EC_LED_COLOR_RED] = { 100, 0, 0 }, - [EC_LED_COLOR_GREEN] = { 0, 100, 0 }, - [EC_LED_COLOR_BLUE] = { 0, 0, 100 }, - [EC_LED_COLOR_YELLOW] = { 50, 50, 0 }, - [EC_LED_COLOR_WHITE] = { 50, 50, 50 }, - [EC_LED_COLOR_AMBER] = { 70, 30, 0 }, +enum led_color { + LED_OFF = 0, + LED_WHITE, + LED_COLOR_COUNT /* Number of colors, not a color itself */ }; -/* One logical LED with red, green, and blue channels. */ -struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { - { - .ch0 = PWM_CH_LED_RED, - .ch1 = PWM_CH_LED_GREEN, - .ch2 = PWM_CH_LED_BLUE, - .enable = &pwm_enable, - .set_duty = &pwm_set_duty, - }, -}; +static int led_set_color_power(enum led_color color) +{ + switch (color) { + case LED_WHITE: + gpio_set_level(GPIO_LED_W_ODL, LED_ON_LVL); + break; + case LED_OFF: + gpio_set_level(GPIO_LED_W_ODL, LED_OFF_LVL); + break; + default: + return EC_ERROR_UNKNOWN; + } + return EC_SUCCESS; +} void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { - memset(brightness_range, '\0', - sizeof(*brightness_range) * EC_LED_COLOR_COUNT); - brightness_range[EC_LED_COLOR_RED] = 100; - brightness_range[EC_LED_COLOR_GREEN] = 100; - brightness_range[EC_LED_COLOR_BLUE] = 100; - brightness_range[EC_LED_COLOR_YELLOW] = 100; - brightness_range[EC_LED_COLOR_WHITE] = 100; - brightness_range[EC_LED_COLOR_AMBER] = 100; + brightness_range[EC_LED_COLOR_WHITE] = 1; } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { - enum pwm_led_id pwm_id; - - /* Convert ec_led_id to pwm_led_id. */ - if (led_id == EC_LED_ID_POWER_LED) - pwm_id = PWM_LED0; + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(LED_WHITE); else - return EC_ERROR_UNKNOWN; - - if (brightness[EC_LED_COLOR_RED]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_RED); - else if (brightness[EC_LED_COLOR_GREEN]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_GREEN); - else if (brightness[EC_LED_COLOR_BLUE]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_BLUE); - else if (brightness[EC_LED_COLOR_YELLOW]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_YELLOW); - else if (brightness[EC_LED_COLOR_WHITE]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); - else if (brightness[EC_LED_COLOR_AMBER]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); - else - /* Otherwise, the "color" is "off". */ - set_pwm_led_color(pwm_id, -1); + led_set_color_power(LED_OFF); return EC_SUCCESS; } + +/* Called by hook task every TICK */ +static void led_tick(void) +{ + if (chipset_in_state(CHIPSET_STATE_ON)) + led_set_color_power(LED_WHITE); + else + led_set_color_power(LED_OFF); +} +DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); diff --git a/board/trogdor/led.c b/board/trogdor/led.c index 3a7d8df108..4b9a8aa005 100644 --- a/board/trogdor/led.c +++ b/board/trogdor/led.c @@ -93,7 +93,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/vell/charger.c b/board/vell/charger.c index 3f57ca11ed..59d8812993 100644 --- a/board/vell/charger.c +++ b/board/vell/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/vell/led.c b/board/vell/led.c index 2f44788bd5..22e8187364 100644 --- a/board/vell/led.c +++ b/board/vell/led.c @@ -155,7 +155,7 @@ static void led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/board/vilboz/board.c b/board/vilboz/board.c index c14a2152ec..d759865fc7 100644 --- a/board/vilboz/board.c +++ b/board/vilboz/board.c @@ -5,7 +5,7 @@ #include "battery_smart.h" #include "button.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "cros_board_info.h" #include "driver/accel_lis2dw12.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/volmar/charger.c b/board/volmar/charger.c index c6ee062ab5..76e2712181 100644 --- a/board/volmar/charger.c +++ b/board/volmar/charger.c @@ -4,7 +4,7 @@ */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/waddledee/board.c b/board/waddledee/board.c index 814e2e8921..229573eb42 100644 --- a/board/waddledee/board.c +++ b/board/waddledee/board.c @@ -8,7 +8,7 @@ #include "adc_chip.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_kionix.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/waddledoo/board.c b/board/waddledoo/board.c index 7dc87f38da..80234defdf 100644 --- a/board/waddledoo/board.c +++ b/board/waddledoo/board.c @@ -9,7 +9,7 @@ #include "button.h" #include "cbi_fw_config.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/waddledoo2/board.c b/board/waddledoo2/board.c index 7adb032f98..8a7a2b461d 100644 --- a/board/waddledoo2/board.c +++ b/board/waddledoo2/board.c @@ -10,7 +10,7 @@ #include "cbi_fw_config.h" #include "cbi_ssfc.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" diff --git a/board/wheelie/board.c b/board/wheelie/board.c index a8c5859e9d..f2acbb4efa 100644 --- a/board/wheelie/board.c +++ b/board/wheelie/board.c @@ -8,7 +8,7 @@ #include "adc_chip.h" #include "button.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "driver/accel_lis2dh.h" #include "driver/accelgyro_lsm6dsm.h" diff --git a/board/wormdingler/led.c b/board/wormdingler/led.c index f6b3cddf48..b1e819a92f 100644 --- a/board/wormdingler/led.c +++ b/board/wormdingler/led.c @@ -81,7 +81,7 @@ static void board_led_set_battery(void) battery_ticks++; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: case PWR_STATE_CHARGE_NEAR_FULL: if (chipset_in_state(CHIPSET_STATE_ON | @@ -91,7 +91,7 @@ static void board_led_set_battery(void) /* battery capa <= 5%, Red */ color = LED_RED; } else if (percent > BATTERY_LEVEL_CRITICAL && - percent < BATTERY_LEVEL_NEAR_FULL) { + percent < CONFIG_BATT_HOST_FULL_FACTOR) { /* 5% < battery capa < 97%, Orange */ color = LED_AMBER; } else { diff --git a/chip/stm32/i2c-stm32l4.c b/chip/stm32/i2c-stm32l4.c index db0077c275..a4b9452379 100644 --- a/chip/stm32/i2c-stm32l4.c +++ b/chip/stm32/i2c-stm32l4.c @@ -116,10 +116,9 @@ static const uint32_t timingr_regs[I2C_CLK_SRC_COUNT][I2C_FREQ_COUNT] = { }, }; -static void i2c_set_freq_port(const struct i2c_port_t *p, - enum stm32_i2c_clk_src src, enum i2c_freq freq) +int chip_i2c_set_freq(int port, enum i2c_freq freq) { - int port = p->port; + enum stm32_i2c_clk_src src = I2C_CLK_SRC_16MHZ; /* Disable port */ STM32_I2C_CR1(port) = 0; @@ -130,6 +129,13 @@ static void i2c_set_freq_port(const struct i2c_port_t *p, STM32_I2C_CR1(port) = STM32_I2C_CR1_PE; pdata[port].freq = freq; + + return EC_SUCCESS; +} + +enum i2c_freq chip_i2c_get_freq(int port) +{ + return pdata[port].freq; } /** @@ -142,7 +148,6 @@ static void i2c_init_port(const struct i2c_port_t *p) int port = p->port; uint32_t val; enum i2c_freq freq; - enum stm32_i2c_clk_src src = I2C_CLK_SRC_16MHZ; /* Enable I2C clock */ if (!(STM32_RCC_APB1ENR1 & (1 << (21 + port)))) @@ -176,7 +181,7 @@ static void i2c_init_port(const struct i2c_port_t *p) } /* Set up initial bus frequencies */ - i2c_set_freq_port(p, src, freq); + chip_i2c_set_freq(p->port, freq); /* Set up default timeout */ i2c_set_timeout(port, 0); diff --git a/common/build.mk b/common/build.mk index 0c5250cf18..bbc0789f9b 100644 --- a/common/build.mk +++ b/common/build.mk @@ -68,6 +68,9 @@ common-$(CONFIG_CHARGER)+=charger.o ifneq ($(CONFIG_CHARGER),) common-$(CONFIG_BATTERY)+=charge_state_v2.o endif +ifneq ($(CONFIG_EC_EC_COMM_BATTERY_CLIENT),) +common-$(CONFIG_BATTERY)+=charger_base.o +endif common-$(CONFIG_CHARGER_PROFILE_OVERRIDE_COMMON)+=charger_profile_override.o common-$(CONFIG_CMD_I2CWEDGE)+=i2c_wedge.o common-$(CONFIG_COMMON_GPIO)+=gpio.o gpio_commands.o diff --git a/common/charge_manager.c b/common/charge_manager.c index 2c79047efa..47874afc01 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -9,7 +9,7 @@ #include "builtin/assert.h" #include "charge_manager.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "console.h" #include "dps.h" diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index 2835f6b7f8..a603d4f108 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -11,13 +11,12 @@ #include "charge_manager.h" #include "charge_state.h" #include "charger.h" +#include "charger_base.h" #include "charger_profile_override.h" #include "chipset.h" #include "common.h" #include "console.h" #include "ec_commands.h" -#include "ec_ec_comm_client.h" -#include "ec_ec_comm_server.h" #include "extpower.h" #include "gpio.h" #include "hooks.h" @@ -73,8 +72,6 @@ static timestamp_t uvp_throttle_start_time; #endif /* CONFIG_THROTTLE_AP_ON_BAT_OLTAGE */ -static int charge_request(int voltage, int current); - static uint8_t battery_level_shutdown; /* @@ -84,9 +81,8 @@ static uint8_t battery_level_shutdown; static const struct battery_info *batt_info; static struct charge_state_data curr; static enum charge_state_v2 prev_state; -static int prev_ac, prev_charge, prev_full, prev_disp_charge; +static int prev_ac, prev_charge, prev_disp_charge; static enum battery_present prev_bp; -static int is_full; /* battery not accepting current */ static enum ec_charge_control_mode chg_ctl_mode; static int manual_voltage; /* Manual voltage override (-1 = no override) */ static int manual_current; /* Manual current override (-1 = no override) */ @@ -100,6 +96,11 @@ static struct current_limit { int soc; /* Minimum battery SoC at which the limit will be applied. */ } current_limit = { -1U, 0 }; +/* State which is reported out from the charger */ +struct state { + bool is_full; /* battery is full, i.e. not accepting current */ +} local_state; + /* * The timestamp when the battery charging current becomes stable. * When a new charging status happens, charger needs several seconds to @@ -119,31 +120,6 @@ STATIC_IF(CONFIG_USB_PD_PREFER_MV) int stable_current; STATIC_IF(CONFIG_USB_PD_PREFER_MV) int desired_mw; STATIC_IF_NOT(CONFIG_USB_PD_PREFER_MV) struct pd_pref_config_t pd_pref_config; -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT -static int base_connected; -/* Base has responded to one of our commands already. */ -static int base_responsive; -static int charge_base; -static int prev_charge_base; -static int prev_current_base; -static int prev_allow_charge_base; -static int prev_current_lid; - -/* - * In debugging mode, with AC, input current to allocate to base. Negative - * value disables manual mode. - */ -static int manual_ac_current_base = -1; -/* - * In debugging mode, when discharging, current to transfer from lid to base - * (negative to transfer from base to lid). Only valid when enabled is true. - */ -static int manual_noac_enabled; -static int manual_noac_current_base; -#else -static const int base_connected; -#endif - /* Is battery connected but unresponsive after precharge? */ static int battery_seems_dead; @@ -158,7 +134,6 @@ static int battery_seems_disconnected; static int battery_was_removed; static int problems_exist; -static int debugging; static const char *const prob_text[] = { "static update", "set voltage", "set current", "set mode", @@ -167,6 +142,26 @@ static const char *const prob_text[] = { }; BUILD_ASSERT(ARRAY_SIZE(prob_text) == NUM_PROBLEM_TYPES); +#ifdef CONFIG_CHARGE_DEBUG +static bool is_debugging; +#endif + +void set_debugging(bool val) +{ +#ifdef CONFIG_CHARGE_DEBUG + is_debugging = val; +#endif +} + +static bool debugging(void) +{ +#ifdef CONFIG_CHARGE_DEBUG + return is_debugging; +#else + return false; +#endif +} + /* * TODO(crosbug.com/p/27639): When do we decide a problem is real and not * just intermittent? And what do we do about it? @@ -231,538 +226,6 @@ static bool battery_sustainer_enabled(void) return sustain_soc.lower != -1 && sustain_soc.upper != -1; } -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT -/* - * Parameters for dual-battery policy. - * TODO(b:71881017): This should be made configurable by AP in the future. - */ -struct dual_battery_policy { - /*** Policies when AC is not connected. ***/ - /* Voltage to use when using OTG mode between lid and base (mV) */ - uint16_t otg_voltage; - /* Maximum current to apply from base to lid (mA) */ - uint16_t max_base_to_lid_current; - /* - * Margin to apply between provided OTG output current and input current - * limit, to make sure that input charger does not overcurrent output - * charger. input_current = (1-margin) * output_current. (/128) - */ - uint8_t margin_otg_current; - - /* Only do base to lid OTG when base battery above this value (%) */ - uint8_t min_charge_base_otg; - - /* - * When base/lid battery percentage is below this value, do - * battery-to-battery charging. (%) - */ - uint8_t max_charge_base_batt_to_batt; - uint8_t max_charge_lid_batt_to_batt; - - /*** Policies when AC is connected. ***/ - /* Minimum power to allocate to base (mW), includes some margin to allow - * base to charge when critically low. - */ - uint16_t min_base_system_power; - - /* Smoothing factor for lid power (/128) */ - uint8_t lid_system_power_smooth; - /* - * Smoothing factor for base/lid battery power, when the battery power - * is decreasing only: we try to estimate the maximum power that the - * battery is willing to take and always reset it when it draws more - * than the estimate. (/128) - */ - uint8_t battery_power_smooth; - - /* - * Margin to add to requested base/lid battery power, to figure out how - * much current to allocate. allocation = (1+margin) * request. (/128) - */ - uint8_t margin_base_battery_power; - uint8_t margin_lid_battery_power; - - /* Maximum current to apply from lid to base (mA) */ - uint16_t max_lid_to_base_current; -}; - -static const struct dual_battery_policy db_policy = { - .otg_voltage = 12000, /* mV */ - .max_base_to_lid_current = 1800, /* mA, about 2000mA with margin. */ - .margin_otg_current = 13, /* /128 = 10.1% */ - .min_charge_base_otg = 5, /* % */ - .max_charge_base_batt_to_batt = 4, /* % */ - .max_charge_lid_batt_to_batt = 10, /* % */ - .min_base_system_power = 1300, /* mW */ - .lid_system_power_smooth = 32, /* 32/128 = 0.25 */ - .battery_power_smooth = 1, /* 1/128 = 0.008 */ - .margin_base_battery_power = 32, /* 32/128 = 0.25 */ - .margin_lid_battery_power = 32, /* 32/128 = 0.25 */ - .max_lid_to_base_current = 2000, /* mA */ -}; - -/* Add at most "value" to power_var, subtracting from total_power budget. */ -#define CHG_ALLOCATE(power_var, total_power, value) \ - do { \ - int val_capped = MIN(value, total_power); \ - (power_var) += val_capped; \ - (total_power) -= val_capped; \ - } while (0) - -/* Update base battery information */ -static void update_base_battery_info(void) -{ - struct ec_response_battery_dynamic_info *const bd = - &battery_dynamic[BATT_IDX_BASE]; - - base_connected = board_is_base_connected(); - - if (!base_connected) { - const int invalid_flags = EC_BATT_FLAG_INVALID_DATA; - /* Invalidate static/dynamic information */ - if (bd->flags != invalid_flags) { - bd->flags = invalid_flags; - - host_set_single_event(EC_HOST_EVENT_BATTERY); - host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); - } - charge_base = -1; - base_responsive = 0; - prev_current_base = 0; - prev_allow_charge_base = 0; - } else if (base_responsive) { - int old_flags = bd->flags; - int flags_changed; - int old_full_capacity = bd->full_capacity; - - ec_ec_client_base_get_dynamic_info(); - flags_changed = (old_flags != bd->flags); - /* Fetch static information when flags change. */ - if (flags_changed) - ec_ec_client_base_get_static_info(); - - battery_memmap_refresh(BATT_IDX_BASE); - - /* Newly connected battery, or change in capacity. */ - if (old_flags & EC_BATT_FLAG_INVALID_DATA || - ((old_flags & EC_BATT_FLAG_BATT_PRESENT) != - (bd->flags & EC_BATT_FLAG_BATT_PRESENT)) || - old_full_capacity != bd->full_capacity) - host_set_single_event(EC_HOST_EVENT_BATTERY); - - if (flags_changed) - host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); - - /* Update charge_base */ - if (bd->flags & (BATT_FLAG_BAD_FULL_CAPACITY | - BATT_FLAG_BAD_REMAINING_CAPACITY)) - charge_base = -1; - else if (bd->full_capacity > 0) - charge_base = 100 * bd->remaining_capacity / - bd->full_capacity; - else - charge_base = 0; - } -} - -/** - * Setup current settings for base, and record previous values, if the base - * is responsive. - * - * @param current_base Current to be drawn by base (negative to provide power) - * @param allow_charge_base Whether base battery should be charged (only makes - * sense with positive current) - */ -static int set_base_current(int current_base, int allow_charge_base) -{ - /* "OTG" voltage from base to lid. */ - const int otg_voltage = db_policy.otg_voltage; - int ret; - - ret = ec_ec_client_base_charge_control(current_base, otg_voltage, - allow_charge_base); - if (ret) { - /* Ignore errors until the base is responsive. */ - if (base_responsive) - return ret; - } else { - base_responsive = 1; - prev_current_base = current_base; - prev_allow_charge_base = allow_charge_base; - } - - return EC_RES_SUCCESS; -} - -/** - * Setup current settings for lid and base, in a safe way. - * - * @param current_base Current to be drawn by base (negative to provide power) - * @param allow_charge_base Whether base battery should be charged (only makes - * sense with positive current) - * @param current_lid Current to be drawn by lid (negative to provide power) - * @param allow_charge_lid Whether lid battery should be charged - */ -static void set_base_lid_current(int current_base, int allow_charge_base, - int current_lid, int allow_charge_lid) -{ - /* "OTG" voltage from lid to base. */ - const int otg_voltage = db_policy.otg_voltage; - - int lid_first; - int ret; - int chgnum = 0; - - /* TODO(b:71881017): This is still quite verbose during charging. */ - if (prev_current_base != current_base || - prev_allow_charge_base != allow_charge_base || - prev_current_lid != current_lid) { - CPRINTS("Base/Lid: %d%s/%d%s mA", current_base, - allow_charge_base ? "+" : "", current_lid, - allow_charge_lid ? "+" : ""); - } - - /* - * To decide whether to first control the lid or the base, we first - * control the side that _reduces_ current that would be drawn, then - * setup one that would start providing power, then increase current. - */ - if (current_lid >= 0 && current_lid < prev_current_lid) - lid_first = 1; /* Lid decreases current */ - else if (current_base >= 0 && current_base < prev_current_base) - lid_first = 0; /* Base decreases current */ - else if (current_lid < 0) - lid_first = 1; /* Lid provide power */ - else - lid_first = 0; /* All other cases: control the base first */ - - if (!lid_first && base_connected) { - ret = set_base_current(current_base, allow_charge_base); - if (ret) - return; - } - - if (current_lid >= 0) { - ret = charge_set_output_current_limit(CHARGER_SOLO, 0, 0); - if (ret) - return; - ret = charger_set_input_current_limit(chgnum, current_lid); - if (ret) - return; - if (allow_charge_lid) - ret = charge_request(curr.requested_voltage, - curr.requested_current); - else - ret = charge_request(0, 0); - } else { - ret = charge_set_output_current_limit( - CHARGER_SOLO, -current_lid, otg_voltage); - } - - if (ret) - return; - - prev_current_lid = current_lid; - - if (lid_first && base_connected) { - ret = set_base_current(current_base, allow_charge_base); - if (ret) - return; - } - - /* - * Make sure cross-power is enabled (it might not be enabled right after - * plugging the base, or when an adapter just got connected). - */ - if (base_connected && current_base != 0) - board_enable_base_power(1); -} - -/** - * Smooth power value, covering some edge cases. - * Compute s*curr+(1-s)*prev, where s is in 1/128 unit. - */ -static int smooth_value(int prev, int curr, int s) -{ - if (curr < 0) - curr = 0; - if (prev < 0) - return curr; - - return prev + s * (curr - prev) / 128; -} - -/** - * Add margin m to value. Compute (1+m)*value, where m is in 1/128 unit. - */ -static int add_margin(int value, int m) -{ - return value + m * value / 128; -} - -static void charge_allocate_input_current_limit(void) -{ - /* - * All the power numbers are in mW. - * - * Since we work with current and voltage in mA and mV, multiplying them - * gives numbers in uW, which are dangerously close to overflowing when - * doing intermediate computations (60W * 100 overflows a 32-bit int, - * for example). We therefore divide the product by 1000 and re-multiply - * the power numbers by 1000 when converting them back to current. - */ - int total_power = 0; - - static int prev_base_battery_power = -1; - int base_battery_power = 0; - int base_battery_power_max = 0; - - static int prev_lid_system_power = -1; - int lid_system_power; - - static int prev_lid_battery_power = -1; - int lid_battery_power = 0; - int lid_battery_power_max = 0; - - int power_base = 0; - int power_lid = 0; - - int current_base = 0; - int current_lid = 0; - - int charge_lid = charge_get_percent(); - - const struct ec_response_battery_dynamic_info *const base_bd = - &battery_dynamic[BATT_IDX_BASE]; - - if (!base_connected) { - set_base_lid_current(0, 0, curr.desired_input_current, 1); - prev_base_battery_power = -1; - return; - } - - /* Charging */ - if (curr.desired_input_current > 0 && curr.input_voltage > 0) - total_power = - curr.desired_input_current * curr.input_voltage / 1000; - - /* - * TODO(b:71723024): We should be able to replace this test by curr.ac, - * but the value is currently wrong, especially during transitions. - */ - if (total_power <= 0) { - int base_critical = - charge_base >= 0 && - charge_base < db_policy.max_charge_base_batt_to_batt; - - /* Discharging */ - prev_base_battery_power = -1; - prev_lid_system_power = -1; - prev_lid_battery_power = -1; - - /* Manual control */ - if (manual_noac_enabled) { - int lid_current, base_current; - - if (manual_noac_current_base > 0) { - base_current = -manual_noac_current_base; - lid_current = add_margin( - manual_noac_current_base, - db_policy.margin_otg_current); - } else { - lid_current = manual_noac_current_base; - base_current = add_margin( - -manual_noac_current_base, - db_policy.margin_otg_current); - } - - set_base_lid_current(base_current, 0, lid_current, 0); - return; - } - - /* - * System is off, cut power to the base. We'll reset the base - * when system restarts, or when AC is plugged. - */ - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - set_base_lid_current(0, 0, 0, 0); - if (base_responsive) { - /* Base still responsive, put it to sleep. */ - CPRINTF("Hibernating base\n"); - ec_ec_client_hibernate(); - base_responsive = 0; - board_enable_base_power(0); - } - return; - } - - /* - * System is suspended, let the lid and base run on their - * own power. However, if the base battery is critically low, we - * still want to provide power to the base, to make sure it - * stays alive to be able to wake the system on keyboard or - * touchpad events. - */ - if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - !base_critical) { - set_base_lid_current(0, 0, 0, 0); - return; - } - - if (charge_base > db_policy.min_charge_base_otg) { - int lid_current = db_policy.max_base_to_lid_current; - int base_current = add_margin( - lid_current, db_policy.margin_otg_current); - /* Draw current from base to lid */ - set_base_lid_current( - -base_current, 0, lid_current, - charge_lid < - db_policy.max_charge_lid_batt_to_batt); - } else { - /* - * Base battery is too low, apply power to it, and allow - * it to charge if it is critically low. - * - * TODO(b:71881017): When suspended, this will make the - * battery charge oscillate between 3 and 4 percent, - * which might not be great for battery life. We need - * some hysteresis. - */ - /* - * TODO(b:71881017): Precompute (ideally, at build time) - * the base_current, so we do not need to do a division - * here. - */ - int base_current = - (db_policy.min_base_system_power * 1000) / - db_policy.otg_voltage; - int lid_current = add_margin( - base_current, db_policy.margin_otg_current); - - set_base_lid_current(base_current, base_critical, - -lid_current, 0); - } - - return; - } - - /* Manual control */ - if (manual_ac_current_base >= 0) { - int current_base = manual_ac_current_base; - int current_lid = - curr.desired_input_current - manual_ac_current_base; - - if (current_lid < 0) { - current_base = curr.desired_input_current; - current_lid = 0; - } - - set_base_lid_current(current_base, 1, current_lid, 1); - return; - } - - /* Estimate system power. */ - lid_system_power = charger_get_system_power() / 1000; - - /* Smooth system power, as it is very spiky */ - lid_system_power = smooth_value(prev_lid_system_power, lid_system_power, - db_policy.lid_system_power_smooth); - prev_lid_system_power = lid_system_power; - - /* - * TODO(b:71881017): Smoothing the battery power isn't necessarily a - * good idea: if the system takes up too much power, we may reduce the - * estimate power too quickly, leading to oscillations when the system - * power goes down. Instead, we should probably estimate the current - * based on remaining capacity. - */ - /* Estimate lid battery power. */ - if (!(curr.batt.flags & - (BATT_FLAG_BAD_VOLTAGE | BATT_FLAG_BAD_CURRENT))) - lid_battery_power = - curr.batt.current * curr.batt.voltage / 1000; - if (lid_battery_power < prev_lid_battery_power) - lid_battery_power = - smooth_value(prev_lid_battery_power, lid_battery_power, - db_policy.battery_power_smooth); - if (!(curr.batt.flags & - (BATT_FLAG_BAD_DESIRED_VOLTAGE | BATT_FLAG_BAD_DESIRED_CURRENT))) - lid_battery_power_max = curr.batt.desired_current * - curr.batt.desired_voltage / 1000; - - lid_battery_power = MIN(lid_battery_power, lid_battery_power_max); - - /* Estimate base battery power. */ - if (!(base_bd->flags & EC_BATT_FLAG_INVALID_DATA)) { - base_battery_power = base_bd->actual_current * - base_bd->actual_voltage / 1000; - base_battery_power_max = base_bd->desired_current * - base_bd->desired_voltage / 1000; - } - if (base_battery_power < prev_base_battery_power) - base_battery_power = smooth_value( - prev_base_battery_power, base_battery_power, - db_policy.battery_power_smooth); - base_battery_power = MIN(base_battery_power, base_battery_power_max); - - if (debugging) { - CPRINTF("%s:\n", __func__); - CPRINTF("total power: %d\n", total_power); - CPRINTF("base battery power: %d (%d)\n", base_battery_power, - base_battery_power_max); - CPRINTF("lid system power: %d\n", lid_system_power); - CPRINTF("lid battery power: %d\n", lid_battery_power); - CPRINTF("percent base/lid: %d%% %d%%\n", charge_base, - charge_lid); - } - - prev_lid_battery_power = lid_battery_power; - prev_base_battery_power = base_battery_power; - - if (total_power > 0) { /* Charging */ - /* Allocate system power */ - CHG_ALLOCATE(power_base, total_power, - db_policy.min_base_system_power); - CHG_ALLOCATE(power_lid, total_power, lid_system_power); - - /* Allocate lid, then base battery power */ - lid_battery_power = add_margin( - lid_battery_power, db_policy.margin_lid_battery_power); - CHG_ALLOCATE(power_lid, total_power, lid_battery_power); - - base_battery_power = - add_margin(base_battery_power, - db_policy.margin_base_battery_power); - CHG_ALLOCATE(power_base, total_power, base_battery_power); - - /* Give everything else to the lid. */ - CHG_ALLOCATE(power_lid, total_power, total_power); - if (debugging) - CPRINTF("power: base %d mW / lid %d mW\n", power_base, - power_lid); - - current_base = 1000 * power_base / curr.input_voltage; - current_lid = 1000 * power_lid / curr.input_voltage; - - if (current_base > db_policy.max_lid_to_base_current) { - current_lid += (current_base - - db_policy.max_lid_to_base_current); - current_base = db_policy.max_lid_to_base_current; - } - - if (debugging) - CPRINTF("current: base %d mA / lid %d mA\n", - current_base, current_lid); - - set_base_lid_current(current_base, 1, current_lid, 1); - } else { /* Discharging */ - } - - if (debugging) - CPRINTF("====\n"); -} -#endif /* CONFIG_EC_EC_COMM_BATTERY_CLIENT */ - static const char *const state_list[] = { "idle", "discharge", "charge", "precharge" }; BUILD_ASSERT(ARRAY_SIZE(state_list) == NUM_STATES_V2); @@ -835,9 +298,10 @@ static void dump_charge_state(void) #ifdef CONFIG_CHARGER_OTG DUMP(output_current, "%dmA"); #endif -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - DUMP(input_voltage, "%dmV"); -#endif + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) { + ccprintf("input_voltage = %dmV\n", + charger_base_get_input_voltage(&curr)); + } ccprintf("chg_ctl_mode = %s (%d)\n", cmode < CHARGE_CONTROL_COUNT ? mode_text[cmode] : "UNDEF", cmode); @@ -848,7 +312,7 @@ static void dump_charge_state(void) ccprintf("battery_seems_disconnected = %d\n", battery_seems_disconnected); ccprintf("battery_was_removed = %d\n", battery_was_removed); - ccprintf("debug output = %s\n", debugging ? "on" : "off"); + ccprintf("debug output = %s\n", debugging() ? "on" : "off"); ccprintf("Battery sustainer = %s (%d%% ~ %d%%)\n", battery_sustainer_enabled() ? "on" : "off", sustain_soc.lower, sustain_soc.upper); @@ -863,7 +327,8 @@ bool charging_progress_displayed(void) return rv; } -static void show_charging_progress(void) +/* Output to the console so progress is visible */ +static void show_charging_progress(bool is_full) { int rv = 0, minutes, to_full, chgnum = 0; int dsoc; @@ -915,11 +380,10 @@ static void show_charging_progress(void) to_full ? "to full" : "to empty", is_full ? ", not accepting current" : ""); -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - CPRINTS("Base battery %d%%", charge_base); -#endif + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) + charger_base_show_charge(); - if (debugging) { + if (debugging()) { ccprintf("battery:\n"); print_battery_debug(); ccprintf("charger:\n"); @@ -956,16 +420,17 @@ __overridable int board_should_charger_bypass(void) return false; } -/* - * Ask the charger for some voltage and current. If either value is 0, - * charging is disabled; otherwise it's enabled. Negative values are ignored. - */ -static int charge_request(int voltage, int current) +int charge_request(bool use_curr, bool is_full) { int r1 = EC_SUCCESS, r2 = EC_SUCCESS, r3 = EC_SUCCESS, r4 = EC_SUCCESS; static int prev_volt, prev_curr; bool should_bypass; + int voltage = 0, current = 0; + if (use_curr) { + voltage = curr.requested_voltage; + current = curr.requested_current; + } if (!voltage || !current) { #ifdef CONFIG_CHARGER_NARROW_VDC current = 0; @@ -1494,8 +959,7 @@ void charger_init(void) } DECLARE_HOOK(HOOK_INIT, charger_init, HOOK_PRIO_DEFAULT); -/* Wake up the task when something important happens */ -static void charge_wakeup(void) +void charge_wakeup(void) { task_wake(TASK_ID_CHARGER); } @@ -1503,11 +967,6 @@ DECLARE_HOOK(HOOK_CHIPSET_RESUME, charge_wakeup, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_AC_CHANGE, charge_wakeup, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_POWER_SUPPLY_CHANGE, charge_wakeup, HOOK_PRIO_DEFAULT); -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT -/* Reset the base on S5->S0 transition. */ -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_base_reset, HOOK_PRIO_DEFAULT); -#endif - #ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE static void bat_low_voltage_throttle_reset(void) { @@ -1520,7 +979,7 @@ DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, bat_low_voltage_throttle_reset, static int get_desired_input_current(enum battery_present batt_present, const struct charger_info *const info) { - if (batt_present == BP_YES || system_is_locked() || base_connected) { + if (batt_present == BP_YES || system_is_locked() || base_connected()) { #ifdef CONFIG_CHARGE_MANAGER int ilim = charge_manager_get_charger_current(); return ilim == CHARGE_CURRENT_UNINITIALIZED ? @@ -1635,16 +1094,9 @@ static void revive_battery(int *need_static) battery_seems_dead = battery_was_removed = 0; } -/* Main loop */ -void charger_task(void *u) +/* Set up the initial state of the charger task */ +static void charger_setup(const struct charger_info *info) { - int sleep_usec; - int battery_critical; - int need_static = 1; - const struct charger_info *const info = charger_get_info(); - int prev_plt_and_desired_mw; - int chgnum = 0; - /* Get the battery-specific values */ batt_info = battery_get_info(); @@ -1652,12 +1104,11 @@ void charger_task(void *u) chg_ctl_mode = CHARGE_CONTROL_NORMAL; shutdown_target_time.val = 0UL; battery_seems_dead = 0; -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - base_responsive = 0; - curr.input_voltage = CHARGE_VOLTAGE_UNINITIALIZED; - battery_dynamic[BATT_IDX_BASE].flags = EC_BATT_FLAG_INVALID_DATA; - charge_base = -1; -#endif + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) { + charger_base_setup(); + charger_base_set_input_voltage(&curr, + CHARGE_VOLTAGE_UNINITIALIZED); + } #ifdef CONFIG_OCPC ocpc_init(&curr.ocpc); charge_set_active_chg_chip(CHARGE_PORT_NONE); @@ -1685,428 +1136,469 @@ void charger_task(void *u) } battery_level_shutdown = board_set_battery_level_shutdown(); +} - while (1) { - /* Let's see what's going on... */ - curr.ts = get_time(); - sleep_usec = 0; - problems_exist = 0; - battery_critical = 0; - curr.ac = extpower_is_present(); -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT +/* check for and handle any state-of-charge change with the battery */ +void check_battery_change_soc(bool is_full, bool prev_full) +{ + if ((!(curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && + curr.batt.state_of_charge != prev_charge) || + (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT) && + charger_base_charge_changed()) || + is_full != prev_full || (curr.state != prev_state) || + (charge_get_display_charge() != prev_disp_charge)) { + show_charging_progress(is_full); + prev_charge = curr.batt.state_of_charge; + prev_disp_charge = charge_get_display_charge(); + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) + charger_base_charge_update(); + hook_notify(HOOK_BATTERY_SOC_CHANGE); + } +} + +/* We've noticed a change in AC presence, let the board know */ +static void process_ac_change(const int chgnum) +{ + board_check_extpower(); + if (curr.ac) { /* - * When base is powering the system, make sure curr.ac stays 0. - * TODO(b:71723024): Fix extpower_is_present() in hardware - * instead. + * Some chargers are unpowered when the AC is off, so we'll + * reinitialize it when AC comes back and set the input current + * limit. Try again if it fails. */ - if (base_responsive && prev_current_base < 0) - curr.ac = 0; + int rv = charger_post_init(); + + if (rv != EC_SUCCESS) { + charge_problem(PR_POST_INIT, rv); + } else if (curr.desired_input_current != + CHARGE_CURRENT_UNINITIALIZED) { + rv = charger_set_input_current_limit( + chgnum, curr.desired_input_current); + if (rv != EC_SUCCESS) + charge_problem(PR_SET_INPUT_CURR, rv); + } - /* System is off: if AC gets connected, reset the base. */ - if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && !prev_ac && - curr.ac) - board_base_reset(); -#endif - if (curr.ac != prev_ac) { - /* - * We've noticed a change in AC presence, let the board - * know. - */ - board_check_extpower(); - if (curr.ac) { - /* - * Some chargers are unpowered when the AC is - * off, so we'll reinitialize it when AC - * comes back and set the input current limit. - * Try again if it fails. - */ - int rv = charger_post_init(); - - if (rv != EC_SUCCESS) { - charge_problem(PR_POST_INIT, rv); - } else if (curr.desired_input_current != - CHARGE_CURRENT_UNINITIALIZED) { - rv = charger_set_input_current_limit( - chgnum, + if (rv == EC_SUCCESS) + prev_ac = curr.ac; + } else { + /* Some things are only meaningful on AC */ + set_chg_ctrl_mode(CHARGE_CONTROL_NORMAL); + battery_seems_dead = 0; + prev_ac = curr.ac; + + /* + * b/187967523, we should clear charge current, otherwise it + * will affect typeC output. This should be ok for all chargers. + */ + charger_set_current(chgnum, 0); + } +} + +/* Handle a change in the battery-present state */ +static void process_battery_present_change(const struct charger_info *info, + int chgnum) +{ + prev_bp = curr.batt.is_present; + + /* Update battery info due to change of battery */ + batt_info = battery_get_info(); + + curr.desired_input_current = get_desired_input_current(prev_bp, info); + if (curr.desired_input_current != CHARGE_CURRENT_UNINITIALIZED) + charger_set_input_current_limit(chgnum, curr.desired_input_current); - if (rv != EC_SUCCESS) - charge_problem( - PR_SET_INPUT_CURR, rv); - } + hook_notify(HOOK_BATTERY_SOC_CHANGE); +} - if (rv == EC_SUCCESS) - prev_ac = curr.ac; - } else { - /* Some things are only meaningful on AC */ - set_chg_ctrl_mode(CHARGE_CONTROL_NORMAL); - battery_seems_dead = 0; - prev_ac = curr.ac; +/* Decide on the charge state we are in */ +static void decide_charge_state(int *need_staticp, int *battery_criticalp) +{ + /* battery current stable now, so save the current. */ + if (IS_ENABLED(CONFIG_USB_PD_PREFER_MV) && + get_time().val > stable_ts.val && curr.batt.current >= 0) + stable_current = curr.batt.current; - /* - * b/187967523, we should clear charge current, - * otherwise it will effect typeC output.this - * should be ok for all chargers. - */ - charger_set_current(chgnum, 0); - } - } + /* + * Now decide what we want to do about it. We'll normally just pass + * along whatever the battery wants to the charger. Note that if + * battery_get_params() can't get valid values from the battery it uses + * (0, 0), which is probably safer than blindly applying power to a + * battery we can't talk to. + */ + if (curr.batt.flags & + (BATT_FLAG_BAD_DESIRED_VOLTAGE | BATT_FLAG_BAD_DESIRED_CURRENT)) { + curr.requested_voltage = 0; + curr.requested_current = 0; + } else { + curr.requested_voltage = curr.batt.desired_voltage; + curr.requested_current = curr.batt.desired_current; + } -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - update_base_battery_info(); -#endif + /* If we *know* there's no battery, wait for one to appear. */ + if (curr.batt.is_present == BP_NO) { + if (!curr.ac) + CPRINTS("running with no battery and no AC"); + set_charge_state(ST_IDLE); + curr.batt_is_charging = 0; + battery_was_removed = 1; + return; + } - charger_get_params(&curr.chg); - battery_get_params(&curr.batt); -#ifdef CONFIG_OCPC - if (curr.ac) - ocpc_get_adcs(&curr.ocpc); -#endif /* CONFIG_OCPC */ + /* + * Always check the disconnect state if the battery is present. This is + * because the battery disconnect state is one of the items used to + * decide whether or not to leave safe mode. + * + * Note: For our purposes, an unresponsive battery is considered to be + * disconnected + */ + battery_seems_disconnected = battery_get_disconnect_state() != + BATTERY_NOT_DISCONNECTED; - if (prev_bp != curr.batt.is_present) { - prev_bp = curr.batt.is_present; + /* + * If we had trouble talking to the battery or the charger, we should + * probably do nothing for a bit, and if it doesn't get better then flag + * it as an error. + */ + if (curr.chg.flags & CHG_FLAG_BAD_ANY) + charge_problem(PR_CHG_FLAGS, curr.chg.flags); + if (curr.batt.flags & BATT_FLAG_BAD_ANY) + charge_problem(PR_BATT_FLAGS, curr.batt.flags); - /* Update battery info due to change of battery */ - batt_info = battery_get_info(); - need_static = 1; + /* + * If AC is present, check if input current is sufficient to actually + * charge battery. + */ + curr.batt_is_charging = curr.ac && (curr.batt.current >= 0); - curr.desired_input_current = - get_desired_input_current(prev_bp, info); - if (curr.desired_input_current != - CHARGE_CURRENT_UNINITIALIZED) - charger_set_input_current_limit( - chgnum, curr.desired_input_current); - hook_notify(HOOK_BATTERY_SOC_CHANGE); - } + /* Don't let the battery hurt itself. */ + *battery_criticalp = shutdown_on_critical_battery(); - battery_validate_params(&curr.batt); + if (!curr.ac) { + set_charge_state(ST_DISCHARGE); + return; + } - notify_host_of_over_current(&curr.batt); + /* Okay, we're on AC and we should have a battery. */ - /* battery current stable now, saves the current. */ - if (IS_ENABLED(CONFIG_USB_PD_PREFER_MV) && - get_time().val > stable_ts.val && curr.batt.current >= 0) - stable_current = curr.batt.current; + /* Used for factory tests. */ + if (get_chg_ctrl_mode() != CHARGE_CONTROL_NORMAL) { + set_charge_state(ST_IDLE); + return; + } - /* - * Now decide what we want to do about it. We'll normally just - * pass along whatever the battery wants to the charger. Note - * that if battery_get_params() can't get valid values from the - * battery it uses (0, 0), which is probably safer than blindly - * applying power to a battery we can't talk to. - */ - if (curr.batt.flags & (BATT_FLAG_BAD_DESIRED_VOLTAGE | - BATT_FLAG_BAD_DESIRED_CURRENT)) { - curr.requested_voltage = 0; - curr.requested_current = 0; - } else { - curr.requested_voltage = curr.batt.desired_voltage; - curr.requested_current = curr.batt.desired_current; - } + /* If the battery is not responsive, try to wake it up. */ + if (!(curr.batt.flags & BATT_FLAG_RESPONSIVE)) { + wakeup_battery(need_staticp); + return; + } - /* If we *know* there's no battery, wait for one to appear. */ - if (curr.batt.is_present == BP_NO) { - if (!curr.ac) - CPRINTS("running with no battery and no AC"); - set_charge_state(ST_IDLE); - curr.batt_is_charging = 0; - battery_was_removed = 1; - goto wait_for_it; + /* + * When the battery voltage is lower than voltage_min,precharge first to + * protect the battery + */ + if (IS_ENABLED(CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION)) { + if (!(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE) && + curr.batt.voltage <= batt_info->voltage_min) { + deep_charge_battery(need_staticp); + return; } /* - * Always check the disconnect state if the battery is present. - * This is because the battery disconnect state is one of the - * items used to decide whether or not to leave safe mode. - * - * Note: For our purposes, an unresponsive battery is - * considered to be disconnected + * Finished deep charge before timeout. Clear the flag so that + * we can do deep charge again (when it's deeply discharged + * again). */ - battery_seems_disconnected = battery_get_disconnect_state() != - BATTERY_NOT_DISCONNECTED; + if ((curr.batt.flags & BATT_FLAG_DEEP_CHARGE)) + curr.batt.flags &= ~BATT_FLAG_DEEP_CHARGE; + } + /* The battery is responding. Yay. Try to use it. */ - /* - * If we had trouble talking to the battery or the charger, we - * should probably do nothing for a bit, and if it doesn't get - * better then flag it as an error. - */ - if (curr.chg.flags & CHG_FLAG_BAD_ANY) - charge_problem(PR_CHG_FLAGS, curr.chg.flags); - if (curr.batt.flags & BATT_FLAG_BAD_ANY) - charge_problem(PR_BATT_FLAGS, curr.batt.flags); + revive_battery(need_staticp); - /* - * If AC is present, check if input current is sufficient to - * actually charge battery. - */ - curr.batt_is_charging = curr.ac && (curr.batt.current >= 0); + set_charge_state(ST_CHARGE); +} - /* Don't let the battery hurt itself. */ - battery_critical = shutdown_on_critical_battery(); +/* Determine voltage/current to request and make it so */ +static void adjust_requested_vi(const struct charger_info *const info, + bool is_full) +{ + /* Turn charger off if it's not needed */ + if (!IS_ENABLED(CONFIG_CHARGER_MAINTAIN_VBAT) && + (curr.state == ST_IDLE || curr.state == ST_DISCHARGE)) { + curr.requested_voltage = 0; + curr.requested_current = 0; + } - if (!curr.ac) { - set_charge_state(ST_DISCHARGE); - goto wait_for_it; - } + /* Apply external limits */ + if (curr.requested_current > user_current_limit) + curr.requested_current = user_current_limit; - /* Okay, we're on AC and we should have a battery. */ + /* Round to valid values */ + curr.requested_voltage = + charger_closest_voltage(curr.requested_voltage); + curr.requested_current = + charger_closest_current(curr.requested_current); - /* Used for factory tests. */ - if (get_chg_ctrl_mode() != CHARGE_CONTROL_NORMAL) { - set_charge_state(ST_IDLE); - goto wait_for_it; + /* Charger only accepts request when AC is on. */ + if (curr.ac) { + /* + * Some batteries would wake up after cut-off if we keep + * charging it. Thus, we only charge when AC is on and battery + * is not cut off yet. + */ + if (battery_is_cut_off()) { + curr.requested_voltage = 0; + curr.requested_current = 0; } - - /* If the battery is not responsive, try to wake it up. */ - if (!(curr.batt.flags & BATT_FLAG_RESPONSIVE)) { - wakeup_battery(&need_static); - goto wait_for_it; + /* + * As a safety feature, some chargers will stop charging if we + * don't communicate with it frequently enough. In manual mode, + * we'll just tell it what it knows. + */ + else { + if (manual_voltage != -1) + curr.requested_voltage = manual_voltage; + if (manual_current != -1) + curr.requested_current = manual_current; } - + } else if (!IS_ENABLED(CONFIG_CHARGER_MAINTAIN_VBAT)) { + curr.requested_voltage = charger_closest_voltage( + curr.batt.voltage + info->voltage_step); + curr.requested_current = -1; /* - * When the battery voltage is lower than voltage_min,precharge - * first to protect the battery + * On EC-EC server, do not charge if curr.ac is 0: there might + * still be some external power available but we do not want to + * use it for charging. */ - if (IS_ENABLED(CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION)) { - if (!(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE) && - (curr.batt.voltage <= batt_info->voltage_min)) { - deep_charge_battery(&need_static); - goto wait_for_it; - } + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_SERVER)) + curr.requested_current = 0; + } + + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) { + base_charge_allocate_input_current_limit(&curr, is_full, + debugging()); + } else { + charge_request(true, is_full); + } +} + +/* Handle selection of the preferred voltage */ +static void process_preferred_voltage(void) +{ + int is_pd_supply; + int port; + int bat_spec_desired_mw; + int prev_plt_and_desired_mw; + /* sjg@: Attempt to get code coverage on this function b/281109948 */ + if (!IS_ENABLED(CONFIG_USB_PD_PREFER_MV)) + return; + + is_pd_supply = charge_manager_get_supplier() == CHARGE_SUPPLIER_PD; + port = charge_manager_get_active_charge_port(); + bat_spec_desired_mw = + curr.batt.desired_current * curr.batt.desired_voltage / 1000; + + /* save previous plt_and_desired_mw, since it will be updated below */ + prev_plt_and_desired_mw = charge_get_plt_plus_bat_desired_mw(); + + /* + * Update desired power by the following rules: + * 1. If the battery is not charging with PD, we reset the desired_mw to + * the battery spec. The actual desired_mw will be evaluated when it + * starts charging with PD again. + * 2. If the battery SoC under battery's constant voltage percent (this + * is a rough value that can be applied to most batteries), the battery + * can fully sink the power, the desired power should be the same as the + * battery spec, and we don't need to use evaluated value + * stable_current. + * 3. If the battery SoC is above battery's constant voltage percent, + * the real battery desired charging power will decrease slowly and so + * does the charging current. We can evaluate the battery desired power + * by the product of stable_current and battery voltage. + */ + if (!is_pd_supply) + desired_mw = bat_spec_desired_mw; + else if (curr.batt.state_of_charge < pd_pref_config.cv) + desired_mw = bat_spec_desired_mw; + else if (stable_current != CHARGE_CURRENT_UNINITIALIZED) + desired_mw = curr.batt.voltage * stable_current / 1000; + + /* if the plt_and_desired_mw changes, re-evaluate PDO */ + if (is_pd_supply && + prev_plt_and_desired_mw != charge_get_plt_plus_bat_desired_mw()) + pd_set_new_power_request(port); +} + +/* Calculate the sleep duration, before we run around the task loop again */ +int calculate_sleep_dur(int battery_critical, int sleep_usec) +{ + /* How long to sleep? */ + if (problems_exist) { + /* If there are errors, don't wait very long. */ + sleep_usec = CHARGE_POLL_PERIOD_SHORT; + } else if (sleep_usec <= 0) { + /* default values depend on the state */ + if (!curr.ac && + (curr.state == ST_IDLE || curr.state == ST_DISCHARGE)) { +#ifdef CONFIG_CHARGER_OTG + int output_current = curr.output_current; +#else + int output_current = 0; +#endif /* - * Finished deep charge before timeout. Clear the flag - * so that we can do deep charge again (when it's deeply - * discharged again). + * If AP is off and we do not provide power, we can + * sleep a long time. */ - if ((curr.batt.flags & BATT_FLAG_DEEP_CHARGE)) { - curr.batt.flags &= ~BATT_FLAG_DEEP_CHARGE; - } + if (chipset_in_state(CHIPSET_STATE_ANY_OFF | + CHIPSET_STATE_ANY_SUSPEND) && + output_current == 0) + sleep_usec = CHARGE_POLL_PERIOD_VERY_LONG; + else + /* Discharging, not too urgent */ + sleep_usec = CHARGE_POLL_PERIOD_LONG; + } else { + /* AC present, so pay closer attention */ + sleep_usec = CHARGE_POLL_PERIOD_CHARGE; } - /* The battery is responding. Yay. Try to use it. */ + } - revive_battery(&need_static); + /* Adjust for time spent in the charge loop */ + sleep_usec -= (int)(get_time().val - curr.ts.val); + if (sleep_usec < CHARGE_MIN_SLEEP_USEC) + sleep_usec = CHARGE_MIN_SLEEP_USEC; + else if (sleep_usec > CHARGE_MAX_SLEEP_USEC) + sleep_usec = CHARGE_MAX_SLEEP_USEC; - set_charge_state(ST_CHARGE); + /* + * If battery is critical, ensure that the sleep time is not very long + * since we might want to hibernate or cut-off battery sooner. + */ + if (battery_critical && + (sleep_usec > CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US)) + sleep_usec = CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US; - wait_for_it: - if (IS_ENABLED(CONFIG_CHARGER_PROFILE_OVERRIDE) && - get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL) { - sleep_usec = charger_profile_override(&curr); - if (sleep_usec < 0) - charge_problem(PR_CUSTOM, sleep_usec); - } + return sleep_usec; +} - if (IS_ENABLED(CONFIG_BATTERY_CHECK_CHARGE_TEMP_LIMITS) && - battery_outside_charging_temperature()) { - curr.requested_current = 0; - curr.requested_voltage = 0; - curr.batt.flags &= ~BATT_FLAG_WANT_CHARGE; - if (curr.state != ST_DISCHARGE) - curr.state = ST_IDLE; - } +/* check external power and handle any changes */ +static void check_extpower(int chgnum) +{ + curr.ac = extpower_is_present(); + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) { + if (base_check_extpower(curr.ac, prev_ac)) + curr.ac = 0; + } -#ifdef CONFIG_CHARGE_MANAGER - if (curr.batt.state_of_charge >= - CONFIG_CHARGE_MANAGER_BAT_PCT_SAFE_MODE_EXIT && - !battery_seems_disconnected) { - charge_manager_leave_safe_mode(); - } -#endif + if (curr.ac != prev_ac) + process_ac_change(chgnum); +} - /* Keep the AP informed */ - if (need_static) - need_static = update_static_battery_info(); - /* Wait on the dynamic info until the static info is good. */ - if (!need_static) - update_dynamic_battery_info(); - notify_host_of_low_battery_charge(); - notify_host_of_low_battery_voltage(); +/* processing for new charge state, returning updated sleep_usec */ +static int process_charge_state(int *need_staticp, int sleep_usec) +{ + if (IS_ENABLED(CONFIG_CHARGER_PROFILE_OVERRIDE) && + get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL) { + sleep_usec = charger_profile_override(&curr); + if (sleep_usec < 0) + charge_problem(PR_CUSTOM, sleep_usec); + } - /* And the EC console */ - is_full = calc_is_full(); + if (IS_ENABLED(CONFIG_BATTERY_CHECK_CHARGE_TEMP_LIMITS) && + battery_outside_charging_temperature()) { + curr.requested_current = 0; + curr.requested_voltage = 0; + curr.batt.flags &= ~BATT_FLAG_WANT_CHARGE; + if (curr.state != ST_DISCHARGE) + curr.state = ST_IDLE; + } - /* Run battery sustainer (no-op if not applicable). */ - sustain_battery_soc(); + if (IS_ENABLED(CONFIG_CHARGE_MANAGER) && + curr.batt.state_of_charge >= + CONFIG_CHARGE_MANAGER_BAT_PCT_SAFE_MODE_EXIT && + !battery_seems_disconnected) + charge_manager_leave_safe_mode(); - /* Run battery soc check for setting the current limit. */ - current_limit_battery_soc(); + /* Keep the AP informed */ + if (*need_staticp) + *need_staticp = update_static_battery_info(); - if ((!(curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && - curr.batt.state_of_charge != prev_charge) || -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - (charge_base != prev_charge_base) || -#endif - (is_full != prev_full) || (curr.state != prev_state) || - (charge_get_display_charge() != prev_disp_charge)) { - show_charging_progress(); - prev_charge = curr.batt.state_of_charge; - prev_disp_charge = charge_get_display_charge(); -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - prev_charge_base = charge_base; -#endif - hook_notify(HOOK_BATTERY_SOC_CHANGE); - } - prev_full = is_full; + /* Wait on the dynamic info until the static info is good. */ + if (!*need_staticp) + update_dynamic_battery_info(); + notify_host_of_low_battery_charge(); + notify_host_of_low_battery_voltage(); -#ifndef CONFIG_CHARGER_MAINTAIN_VBAT - /* Turn charger off if it's not needed */ - if (curr.state == ST_IDLE || curr.state == ST_DISCHARGE) { - curr.requested_voltage = 0; - curr.requested_current = 0; - } -#endif + return sleep_usec; +} - /* Apply external limits */ - if (curr.requested_current > user_current_limit) - curr.requested_current = user_current_limit; +/* Main loop */ +void charger_task(void *u) +{ + int sleep_usec; + int battery_critical; + int need_static = 1; + const struct charger_info *const info = charger_get_info(); + int chgnum = 0; + bool is_full = false; /* battery not accepting current */ + bool prev_full = false; - /* Round to valid values */ - curr.requested_voltage = - charger_closest_voltage(curr.requested_voltage); - curr.requested_current = - charger_closest_current(curr.requested_current); + /* Set up the task - note that charger_init() has already run. */ + charger_setup(info); - /* Charger only accpets request when AC is on. */ - if (curr.ac) { - /* - * Some batteries would wake up after cut-off if we keep - * charging it. Thus, we only charge when AC is on and - * battery is not cut off yet. - */ - if (battery_is_cut_off()) { - curr.requested_voltage = 0; - curr.requested_current = 0; - } - /* - * As a safety feature, some chargers will stop - * charging if we don't communicate with it frequently - * enough. In manual mode, we'll just tell it what it - * knows. - */ - else { - if (manual_voltage != -1) - curr.requested_voltage = manual_voltage; - if (manual_current != -1) - curr.requested_current = manual_current; - } - } else { -#ifndef CONFIG_CHARGER_MAINTAIN_VBAT - curr.requested_voltage = charger_closest_voltage( - curr.batt.voltage + info->voltage_step); - curr.requested_current = -1; -#endif -#ifdef CONFIG_EC_EC_COMM_BATTERY_SERVER - /* - * On EC-EC server, do not charge if curr.ac is 0: there - * might still be some external power available but we - * do not want to use it for charging. - */ - curr.requested_current = 0; -#endif - } + while (1) { + /* Let's see what's going on... */ + curr.ts = get_time(); + sleep_usec = 0; + problems_exist = 0; + battery_critical = 0; -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - charge_allocate_input_current_limit(); -#else - charge_request(curr.requested_voltage, curr.requested_current); -#endif + check_extpower(chgnum); - /* How long to sleep? */ - if (problems_exist) - /* If there are errors, don't wait very long. */ - sleep_usec = CHARGE_POLL_PERIOD_SHORT; - else if (sleep_usec <= 0) { - /* default values depend on the state */ - if (!curr.ac && (curr.state == ST_IDLE || - curr.state == ST_DISCHARGE)) { -#ifdef CONFIG_CHARGER_OTG - int output_current = curr.output_current; -#else - int output_current = 0; -#endif - /* - * If AP is off and we do not provide power, we - * can sleep a long time. - */ - if (chipset_in_state( - CHIPSET_STATE_ANY_OFF | - CHIPSET_STATE_ANY_SUSPEND) && - output_current == 0) - sleep_usec = - CHARGE_POLL_PERIOD_VERY_LONG; - else - /* Discharging, not too urgent */ - sleep_usec = CHARGE_POLL_PERIOD_LONG; - } else { - /* AC present, so pay closer attention */ - sleep_usec = CHARGE_POLL_PERIOD_CHARGE; - } + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) + base_update_battery_info(); + + charger_get_params(&curr.chg); + battery_get_params(&curr.batt); +#ifdef CONFIG_OCPC + if (curr.ac) + ocpc_get_adcs(&curr.ocpc); +#endif /* CONFIG_OCPC */ + + if (prev_bp != curr.batt.is_present) { + process_battery_present_change(info, chgnum); + need_static = 1; } - if (IS_ENABLED(CONFIG_USB_PD_PREFER_MV)) { - int is_pd_supply = charge_manager_get_supplier() == - CHARGE_SUPPLIER_PD; - int port = charge_manager_get_active_charge_port(); - int bat_spec_desired_mw = curr.batt.desired_current * - curr.batt.desired_voltage / - 1000; + battery_validate_params(&curr.batt); - /* - * save the previous plt_and_desired_mw, since it - * will be updated below - */ - prev_plt_and_desired_mw = - charge_get_plt_plus_bat_desired_mw(); + notify_host_of_over_current(&curr.batt); - /* - * Update desired power by the following rules: - * 1. If the battery is not charging with PD, we reset - * the desired_mw to the battery spec. The actual - * desired_mw will be evaluated when it starts charging - * with PD again. - * 2. If the battery SoC under battery's constant - * voltage percent (this is a rough value that can be - * applied to most batteries), the battery can fully - * sink the power, the desired power should be the - * same as the battery spec, and we don't need to use - * evaluated value stable_current. - * 3. If the battery SoC is above battery's constant - * voltage percent, the real battery desired charging - * power will decrease slowly and so does the charging - * current. We can evaluate the battery desired power - * by the product of stable_current and battery voltage. - */ - if (!is_pd_supply) - desired_mw = bat_spec_desired_mw; - else if (curr.batt.state_of_charge < pd_pref_config.cv) - desired_mw = bat_spec_desired_mw; - else if (stable_current != CHARGE_CURRENT_UNINITIALIZED) - desired_mw = curr.batt.voltage * - stable_current / 1000; - - /* if the plt_and_desired_mw changes, re-evaluate PDO */ - if (is_pd_supply && - prev_plt_and_desired_mw != - charge_get_plt_plus_bat_desired_mw()) - pd_set_new_power_request(port); - } + decide_charge_state(&need_static, &battery_critical); + sleep_usec = process_charge_state(&need_static, sleep_usec); - /* Adjust for time spent in this loop */ - sleep_usec -= (int)(get_time().val - curr.ts.val); - if (sleep_usec < CHARGE_MIN_SLEEP_USEC) - sleep_usec = CHARGE_MIN_SLEEP_USEC; - else if (sleep_usec > CHARGE_MAX_SLEEP_USEC) - sleep_usec = CHARGE_MAX_SLEEP_USEC; + /* And the EC console */ + is_full = calc_is_full(); - /* - * If battery is critical, ensure that the sleep time is not - * very long since we might want to hibernate or cut-off - * battery sooner. - */ - if (battery_critical && - (sleep_usec > CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US)) - sleep_usec = CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US; + /* Run battery sustainer (no-op if not applicable). */ + sustain_battery_soc(); + + /* Run battery soc check for setting the current limit. */ + current_limit_battery_soc(); + + check_battery_change_soc(is_full, prev_full); + + prev_full = is_full; + + adjust_requested_vi(info, is_full); + process_preferred_voltage(); + + /* Report our state */ + local_state.is_full = is_full; + + sleep_usec = calculate_sleep_dur(battery_critical, sleep_usec); task_wait_event(sleep_usec); } } @@ -2235,18 +1727,17 @@ bool charge_prevent_power_on(bool power_button_pressed) static int battery_near_full(void) { - if (charge_get_percent() < BATTERY_LEVEL_NEAR_FULL) + if (charge_get_display_charge() < 1000) return 0; -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - if (charge_base > -1 && charge_base < BATTERY_LEVEL_NEAR_FULL) + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT) && + !charger_base_charge_near_full()) return 0; -#endif return 1; } -enum charge_state charge_get_state(void) +enum led_pwr_state led_pwr_get_state(void) { uint32_t chflags; @@ -2313,7 +1804,7 @@ int charge_get_percent(void) * to the battery, that'll be zero, which is probably as good as * anything. */ - return is_full ? 100 : curr.batt.state_of_charge; + return local_state.is_full ? 100 : curr.batt.state_of_charge; } test_mockable int charge_get_display_charge(void) @@ -2383,9 +1874,8 @@ int charge_set_input_current_limit(int ma, int mv) if (IS_ENABLED(CONFIG_OCPC)) chgnum = charge_get_active_chg_chip(); -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - curr.input_voltage = mv; -#endif + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) + charger_base_set_input_voltage(&curr, mv); /* * If battery is not present, we are not locked, and base is not * connected then allow system to pull as much input current as needed. @@ -2393,7 +1883,7 @@ int charge_set_input_current_limit(int ma, int mv) * browning out due to insufficient input current. */ if (curr.batt.is_present != BP_YES && !system_is_locked() && - !base_connected) { + !base_connected()) { int prev_input = 0; charger_get_input_current_limit(chgnum, &prev_input); @@ -2447,13 +1937,16 @@ int charge_set_input_current_limit(int ma, int mv) } curr.desired_input_current = ma; -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - /* Wake up charger task to allocate current between lid and base. */ - charge_wakeup(); - return EC_SUCCESS; -#else - return charger_set_input_current_limit(chgnum, ma); -#endif + if (IS_ENABLED(CONFIG_EC_EC_COMM_BATTERY_CLIENT)) { + /* + * Wake up charger task to allocate current between lid and + * base. + */ + charge_wakeup(); + return EC_SUCCESS; + } else { + return charger_set_input_current_limit(chgnum, ma); + } } #ifdef CONFIG_OCPC @@ -2819,11 +2312,15 @@ static int command_chgstate(int argc, const char **argv) CHARGE_CONTROL_NORMAL); if (rv) return rv; - } else if (!strcasecmp(argv[1], "debug")) { + } else if (IS_ENABLED(CONFIG_CHARGE_DEBUG) && + !strcasecmp(argv[1], "debug")) { + int val; + if (argc <= 2) return EC_ERROR_PARAM_COUNT; - if (!parse_bool(argv[2], &debugging)) + if (!parse_bool(argv[2], &val)) return EC_ERROR_PARAM2; + set_debugging(val); } else if (!strcasecmp(argv[1], "sustain")) { int lower, upper; @@ -2846,57 +2343,12 @@ static int command_chgstate(int argc, const char **argv) dump_charge_state(); return EC_SUCCESS; } +#ifdef CONFIG_CHARGE_DEBUG +#define CHGSTATE_DEBUG_HELP "|debug on|off" +#else +#define CHGSTATE_DEBUG_HELP "" +#endif DECLARE_CONSOLE_COMMAND(chgstate, command_chgstate, - "[idle|discharge|debug on|off]" + "[idle|discharge" CHGSTATE_DEBUG_HELP "]" "\n[sustain <lower> <upper>]", "Get/set charge state machine status"); - -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT -static int command_chgdualdebug(int argc, const char **argv) -{ - int val; - char *e; - - if (argc > 1) { - if (argv[1][0] == 'c') { - if (argc <= 2) - return EC_ERROR_PARAM_COUNT; - - if (!strcasecmp(argv[2], "auto")) { - val = -1; - } else { - val = strtoi(argv[2], &e, 0); - if (*e || val < 0) - return EC_ERROR_PARAM2; - } - - manual_ac_current_base = val; - charge_wakeup(); - } else if (argv[1][0] == 'd') { - if (argc <= 2) - return EC_ERROR_PARAM_COUNT; - - if (!strcasecmp(argv[2], "auto")) { - manual_noac_enabled = 0; - } else { - val = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - manual_noac_current_base = val; - manual_noac_enabled = 1; - } - charge_wakeup(); - } else { - return EC_ERROR_PARAM1; - } - } else { - ccprintf("Base/Lid: %d%s/%d mA\n", prev_current_base, - prev_allow_charge_base ? "+" : "", prev_current_lid); - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(chgdualdebug, command_chgdualdebug, - "[charge (auto|<current>)|discharge (auto|<current>)]", - "Manually control dual-battery charging algorithm."); -#endif diff --git a/common/charger.c b/common/charger.c index 12e1961f4b..0f4f6f7a9c 100644 --- a/common/charger.c +++ b/common/charger.c @@ -7,7 +7,7 @@ #include "battery_smart.h" #include "builtin/assert.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "console.h" diff --git a/common/charger_base.c b/common/charger_base.c new file mode 100644 index 0000000000..c2f49dcf21 --- /dev/null +++ b/common/charger_base.c @@ -0,0 +1,687 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery charging task and state machine. + */ + +#include "charge_state.h" +#include "charger.h" +#include "charger_base.h" +#include "common.h" +#include "console.h" +#include "ec_ec_comm_client.h" +#include "hooks.h" +#include "string.h" +#include "util.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_CHARGER, outstr) +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ##args) + +/* Base has responded to one of our commands already. */ +static int base_responsive; +static int charge_base; +static int prev_charge_base; +static int prev_current_base; +static int prev_allow_charge_base; +static int prev_current_lid; + +/* + * In debugging mode, with AC, input current to allocate to base. Negative + * value disables manual mode. + */ +static int manual_ac_current_base = -1; +/* + * In debugging mode, when discharging, current to transfer from lid to base + * (negative to transfer from base to lid). Only valid when enabled is true. + */ +static int manual_noac_enabled; +static int manual_noac_current_base; + +/* + * Parameters for dual-battery policy. + * TODO(b:71881017): This should be made configurable by AP in the future. + */ +struct dual_battery_policy { + /*** Policies when AC is not connected. ***/ + /* Voltage to use when using OTG mode between lid and base (mV) */ + uint16_t otg_voltage; + /* Maximum current to apply from base to lid (mA) */ + uint16_t max_base_to_lid_current; + /* + * Margin to apply between provided OTG output current and input current + * limit, to make sure that input charger does not overcurrent output + * charger. input_current = (1-margin) * output_current. (/128) + */ + uint8_t margin_otg_current; + + /* Only do base to lid OTG when base battery above this value (%) */ + uint8_t min_charge_base_otg; + + /* + * When base/lid battery percentage is below this value, do + * battery-to-battery charging. (%) + */ + uint8_t max_charge_base_batt_to_batt; + uint8_t max_charge_lid_batt_to_batt; + + /*** Policies when AC is connected. ***/ + /* Minimum power to allocate to base (mW), includes some margin to allow + * base to charge when critically low. + */ + uint16_t min_base_system_power; + + /* Smoothing factor for lid power (/128) */ + uint8_t lid_system_power_smooth; + /* + * Smoothing factor for base/lid battery power, when the battery power + * is decreasing only: we try to estimate the maximum power that the + * battery is willing to take and always reset it when it draws more + * than the estimate. (/128) + */ + uint8_t battery_power_smooth; + + /* + * Margin to add to requested base/lid battery power, to figure out how + * much current to allocate. allocation = (1+margin) * request. (/128) + */ + uint8_t margin_base_battery_power; + uint8_t margin_lid_battery_power; + + /* Maximum current to apply from lid to base (mA) */ + uint16_t max_lid_to_base_current; +}; + +static const struct dual_battery_policy db_policy = { + .otg_voltage = 12000, /* mV */ + .max_base_to_lid_current = 1800, /* mA, about 2000mA with margin. */ + .margin_otg_current = 13, /* /128 = 10.1% */ + .min_charge_base_otg = 5, /* % */ + .max_charge_base_batt_to_batt = 4, /* % */ + .max_charge_lid_batt_to_batt = 10, /* % */ + .min_base_system_power = 1300, /* mW */ + .lid_system_power_smooth = 32, /* 32/128 = 0.25 */ + .battery_power_smooth = 1, /* 1/128 = 0.008 */ + .margin_base_battery_power = 32, /* 32/128 = 0.25 */ + .margin_lid_battery_power = 32, /* 32/128 = 0.25 */ + .max_lid_to_base_current = 2000, /* mA */ +}; + +/* Add at most "value" to power_var, subtracting from total_power budget. */ +#define CHG_ALLOCATE(power_var, total_power, value) \ + do { \ + int val_capped = MIN(value, total_power); \ + (power_var) += val_capped; \ + (total_power) -= val_capped; \ + } while (0) + +/* Check if a base is connected */ +bool base_connected(void) +{ + return board_is_base_connected(); +} + +/** + * Setup current settings for base, and record previous values, if the base + * is responsive. + * + * @param current_base Current to be drawn by base (negative to provide power) + * @param allow_charge_base Whether base battery should be charged (only makes + * sense with positive current) + */ +static int set_base_current(int current_base, int allow_charge_base) +{ + /* "OTG" voltage from base to lid. */ + const int otg_voltage = db_policy.otg_voltage; + int ret; + + ret = ec_ec_client_base_charge_control(current_base, otg_voltage, + allow_charge_base); + if (ret) { + /* Ignore errors until the base is responsive. */ + if (base_responsive) + return ret; + } else { + base_responsive = 1; + prev_current_base = current_base; + prev_allow_charge_base = allow_charge_base; + } + + return EC_RES_SUCCESS; +} + +/** + * Setup current settings for lid and base, in a safe way. + * + * @param current_base Current to be drawn by base (negative to provide power) + * @param allow_charge_base Whether base battery should be charged (only makes + * sense with positive current) + * @param current_lid Current to be drawn by lid (negative to provide power) + * @param allow_charge_lid Whether lid battery should be charged + * @param is_full Whether the lid battery is full + */ +static void set_base_lid_current(int current_base, int allow_charge_base, + int current_lid, int allow_charge_lid, + bool is_full) +{ + /* "OTG" voltage from lid to base. */ + const int otg_voltage = db_policy.otg_voltage; + + int lid_first; + int ret; + int chgnum = 0; + + /* TODO(b:71881017): This is still quite verbose during charging. */ + if (prev_current_base != current_base || + prev_allow_charge_base != allow_charge_base || + prev_current_lid != current_lid) { + CPRINTS("Base/Lid: %d%s/%d%s mA", current_base, + allow_charge_base ? "+" : "", current_lid, + allow_charge_lid ? "+" : ""); + } + + /* + * To decide whether to first control the lid or the base, we first + * control the side that _reduces_ current that would be drawn, then + * setup one that would start providing power, then increase current. + */ + if (current_lid >= 0 && current_lid < prev_current_lid) + lid_first = 1; /* Lid decreases current */ + else if (current_base >= 0 && current_base < prev_current_base) + lid_first = 0; /* Base decreases current */ + else if (current_lid < 0) + lid_first = 1; /* Lid provide power */ + else + lid_first = 0; /* All other cases: control the base first */ + + if (!lid_first && base_connected()) { + ret = set_base_current(current_base, allow_charge_base); + if (ret) + return; + } + + if (current_lid >= 0) { + ret = charge_set_output_current_limit(CHARGER_SOLO, 0, 0); + if (ret) + return; + ret = charger_set_input_current_limit(chgnum, current_lid); + if (ret) + return; + ret = charge_request(allow_charge_lid, is_full); + } else { + ret = charge_set_output_current_limit( + CHARGER_SOLO, -current_lid, otg_voltage); + } + + if (ret) + return; + + prev_current_lid = current_lid; + + if (lid_first && base_connected()) { + ret = set_base_current(current_base, allow_charge_base); + if (ret) + return; + } + + /* + * Make sure cross-power is enabled (it might not be enabled right after + * plugging the base, or when an adapter just got connected). + */ + if (base_connected() && current_base != 0) + board_enable_base_power(1); +} + +/** + * Smooth power value, covering some edge cases. + * Compute s*curr+(1-s)*prev, where s is in 1/128 unit. + */ +static int smooth_value(int prev, int curr, int s) +{ + if (curr < 0) + curr = 0; + if (prev < 0) + return curr; + + return prev + s * (curr - prev) / 128; +} + +/** + * Add margin m to value. Compute (1+m)*value, where m is in 1/128 unit. + */ +static int add_margin(int value, int m) +{ + return value + m * value / 128; +} + +void base_charge_allocate_input_current_limit( + const struct charge_state_data *curr, bool is_full, bool debugging) +{ + /* + * All the power numbers are in mW. + * + * Since we work with current and voltage in mA and mV, multiplying them + * gives numbers in uW, which are dangerously close to overflowing when + * doing intermediate computations (60W * 100 overflows a 32-bit int, + * for example). We therefore divide the product by 1000 and re-multiply + * the power numbers by 1000 when converting them back to current. + */ + int total_power = 0; + + static int prev_base_battery_power = -1; + int base_battery_power = 0; + int base_battery_power_max = 0; + + static int prev_lid_system_power = -1; + int lid_system_power; + + static int prev_lid_battery_power = -1; + int lid_battery_power = 0; + int lid_battery_power_max = 0; + + int power_base = 0; + int power_lid = 0; + + int current_base = 0; + int current_lid = 0; + + int charge_lid = charge_get_percent(); + + const struct ec_response_battery_dynamic_info *const base_bd = + &battery_dynamic[BATT_IDX_BASE]; + const struct batt_params *batt = &curr->batt; + + if (!base_connected()) { + set_base_lid_current(0, 0, curr->desired_input_current, 1, + is_full); + prev_base_battery_power = -1; + return; + } + + /* Charging */ + if (curr->desired_input_current > 0 && curr->input_voltage > 0) + total_power = curr->desired_input_current * + curr->input_voltage / 1000; + + /* + * TODO(b:71723024): We should be able to replace this test by curr.ac, + * but the value is currently wrong, especially during transitions. + */ + if (total_power <= 0) { + int base_critical = + charge_base >= 0 && + charge_base < db_policy.max_charge_base_batt_to_batt; + + /* Discharging */ + prev_base_battery_power = -1; + prev_lid_system_power = -1; + prev_lid_battery_power = -1; + + /* Manual control */ + if (manual_noac_enabled) { + int lid_current, base_current; + + if (manual_noac_current_base > 0) { + base_current = -manual_noac_current_base; + lid_current = add_margin( + manual_noac_current_base, + db_policy.margin_otg_current); + } else { + lid_current = manual_noac_current_base; + base_current = add_margin( + -manual_noac_current_base, + db_policy.margin_otg_current); + } + + set_base_lid_current(base_current, 0, lid_current, 0, + is_full); + return; + } + + /* + * System is off, cut power to the base. We'll reset the base + * when system restarts, or when AC is plugged. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + set_base_lid_current(0, 0, 0, 0, is_full); + if (base_responsive) { + /* Base still responsive, put it to sleep. */ + CPRINTF("Hibernating base\n"); + ec_ec_client_hibernate(); + base_responsive = 0; + board_enable_base_power(0); + } + return; + } + + /* + * System is suspended, let the lid and base run on their + * own power. However, if the base battery is critically low, we + * still want to provide power to the base, to make sure it + * stays alive to be able to wake the system on keyboard or + * touchpad events. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + !base_critical) { + set_base_lid_current(0, 0, 0, 0, is_full); + return; + } + + if (charge_base > db_policy.min_charge_base_otg) { + int lid_current = db_policy.max_base_to_lid_current; + int base_current = add_margin( + lid_current, db_policy.margin_otg_current); + /* Draw current from base to lid */ + set_base_lid_current( + -base_current, 0, lid_current, + charge_lid < + db_policy.max_charge_lid_batt_to_batt, + is_full); + } else { + /* + * Base battery is too low, apply power to it, and allow + * it to charge if it is critically low. + * + * TODO(b:71881017): When suspended, this will make the + * battery charge oscillate between 3 and 4 percent, + * which might not be great for battery life. We need + * some hysteresis. + */ + /* + * TODO(b:71881017): Precompute (ideally, at build time) + * the base_current, so we do not need to do a division + * here. + */ + int base_current = + (db_policy.min_base_system_power * 1000) / + db_policy.otg_voltage; + int lid_current = add_margin( + base_current, db_policy.margin_otg_current); + + set_base_lid_current(base_current, base_critical, + -lid_current, 0, is_full); + } + + return; + } + + /* Manual control */ + if (manual_ac_current_base >= 0) { + int current_base = manual_ac_current_base; + int current_lid = + curr->desired_input_current - manual_ac_current_base; + + if (current_lid < 0) { + current_base = curr->desired_input_current; + current_lid = 0; + } + + set_base_lid_current(current_base, 1, current_lid, 1, is_full); + return; + } + + /* Estimate system power. */ + lid_system_power = charger_get_system_power() / 1000; + + /* Smooth system power, as it is very spiky */ + lid_system_power = smooth_value(prev_lid_system_power, lid_system_power, + db_policy.lid_system_power_smooth); + prev_lid_system_power = lid_system_power; + + /* + * TODO(b:71881017): Smoothing the battery power isn't necessarily a + * good idea: if the system takes up too much power, we may reduce the + * estimate power too quickly, leading to oscillations when the system + * power goes down. Instead, we should probably estimate the current + * based on remaining capacity. + */ + /* Estimate lid battery power. */ + if (!(batt->flags & (BATT_FLAG_BAD_VOLTAGE | BATT_FLAG_BAD_CURRENT))) + lid_battery_power = batt->current * batt->voltage / 1000; + if (lid_battery_power < prev_lid_battery_power) + lid_battery_power = + smooth_value(prev_lid_battery_power, lid_battery_power, + db_policy.battery_power_smooth); + if (!(batt->flags & + (BATT_FLAG_BAD_DESIRED_VOLTAGE | BATT_FLAG_BAD_DESIRED_CURRENT))) + lid_battery_power_max = + batt->desired_current * batt->desired_voltage / 1000; + + lid_battery_power = MIN(lid_battery_power, lid_battery_power_max); + + /* Estimate base battery power. */ + if (!(base_bd->flags & EC_BATT_FLAG_INVALID_DATA)) { + base_battery_power = base_bd->actual_current * + base_bd->actual_voltage / 1000; + base_battery_power_max = base_bd->desired_current * + base_bd->desired_voltage / 1000; + } + if (base_battery_power < prev_base_battery_power) + base_battery_power = smooth_value( + prev_base_battery_power, base_battery_power, + db_policy.battery_power_smooth); + base_battery_power = MIN(base_battery_power, base_battery_power_max); + + if (debugging) { + CPRINTF("%s:\n", __func__); + CPRINTF("total power: %d\n", total_power); + CPRINTF("base battery power: %d (%d)\n", base_battery_power, + base_battery_power_max); + CPRINTF("lid system power: %d\n", lid_system_power); + CPRINTF("lid battery power: %d\n", lid_battery_power); + CPRINTF("percent base/lid: %d%% %d%%\n", charge_base, + charge_lid); + } + + prev_lid_battery_power = lid_battery_power; + prev_base_battery_power = base_battery_power; + + if (total_power > 0) { /* Charging */ + /* Allocate system power */ + CHG_ALLOCATE(power_base, total_power, + db_policy.min_base_system_power); + CHG_ALLOCATE(power_lid, total_power, lid_system_power); + + /* Allocate lid, then base battery power */ + lid_battery_power = add_margin( + lid_battery_power, db_policy.margin_lid_battery_power); + CHG_ALLOCATE(power_lid, total_power, lid_battery_power); + + base_battery_power = + add_margin(base_battery_power, + db_policy.margin_base_battery_power); + CHG_ALLOCATE(power_base, total_power, base_battery_power); + + /* Give everything else to the lid. */ + CHG_ALLOCATE(power_lid, total_power, total_power); + if (debugging) + CPRINTF("power: base %d mW / lid %d mW\n", power_base, + power_lid); + + current_base = 1000 * power_base / curr->input_voltage; + current_lid = 1000 * power_lid / curr->input_voltage; + + if (current_base > db_policy.max_lid_to_base_current) { + current_lid += (current_base - + db_policy.max_lid_to_base_current); + current_base = db_policy.max_lid_to_base_current; + } + + if (debugging) + CPRINTF("current: base %d mA / lid %d mA\n", + current_base, current_lid); + + set_base_lid_current(current_base, 1, current_lid, 1, is_full); + } else { /* Discharging */ + } + + if (debugging) + CPRINTF("====\n"); +} + +void base_update_battery_info(void) +{ + struct ec_response_battery_dynamic_info *const bd = + &battery_dynamic[BATT_IDX_BASE]; + + if (!base_connected()) { + const int invalid_flags = EC_BATT_FLAG_INVALID_DATA; + /* Invalidate static/dynamic information */ + if (bd->flags != invalid_flags) { + bd->flags = invalid_flags; + + host_set_single_event(EC_HOST_EVENT_BATTERY); + host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); + } + charge_base = -1; + base_responsive = 0; + prev_current_base = 0; + prev_allow_charge_base = 0; + } else if (base_responsive) { + int old_flags = bd->flags; + int flags_changed; + int old_full_capacity = bd->full_capacity; + + ec_ec_client_base_get_dynamic_info(); + flags_changed = (old_flags != bd->flags); + /* Fetch static information when flags change. */ + if (flags_changed) + ec_ec_client_base_get_static_info(); + + battery_memmap_refresh(BATT_IDX_BASE); + + /* Newly connected battery, or change in capacity. */ + if (old_flags & EC_BATT_FLAG_INVALID_DATA || + ((old_flags & EC_BATT_FLAG_BATT_PRESENT) != + (bd->flags & EC_BATT_FLAG_BATT_PRESENT)) || + old_full_capacity != bd->full_capacity) + host_set_single_event(EC_HOST_EVENT_BATTERY); + + if (flags_changed) + host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); + + /* Update charge_base */ + if (bd->flags & (BATT_FLAG_BAD_FULL_CAPACITY | + BATT_FLAG_BAD_REMAINING_CAPACITY)) + charge_base = -1; + else if (bd->full_capacity > 0) + charge_base = 100 * bd->remaining_capacity / + bd->full_capacity; + else + charge_base = 0; + } +} + +bool base_check_extpower(int ac, int prev_ac) +{ + bool zero_ac = false; + + /* + * When base is powering the system, make sure ac stays 0. + * TODO(b:71723024): Fix extpower_is_present() in hardware instead. + */ + if (base_responsive && prev_current_base < 0) { + ac = 0; + zero_ac = true; + } + + /* System is off: if AC gets connected, reset the base. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && !prev_ac && ac) + board_base_reset(); + + return zero_ac; +} + +static int command_chgdualdebug(int argc, const char **argv) +{ + int val; + char *e; + + if (argc > 1) { + if (argv[1][0] == 'c') { + if (argc <= 2) + return EC_ERROR_PARAM_COUNT; + + if (!strcasecmp(argv[2], "auto")) { + val = -1; + } else { + val = strtoi(argv[2], &e, 0); + if (*e || val < 0) + return EC_ERROR_PARAM2; + } + + manual_ac_current_base = val; + charge_wakeup(); + } else if (argv[1][0] == 'd') { + if (argc <= 2) + return EC_ERROR_PARAM_COUNT; + + if (!strcasecmp(argv[2], "auto")) { + manual_noac_enabled = 0; + } else { + val = strtoi(argv[2], &e, 0); + if (*e) + return EC_ERROR_PARAM2; + manual_noac_current_base = val; + manual_noac_enabled = 1; + } + charge_wakeup(); + } else { + return EC_ERROR_PARAM1; + } + } else { + ccprintf("Base/Lid: %d%s/%d mA\n", prev_current_base, + prev_allow_charge_base ? "+" : "", prev_current_lid); + } + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(chgdualdebug, command_chgdualdebug, + "[charge (auto|<current>)|discharge (auto|<current>)]", + "Manually control dual-battery charging algorithm."); + +void charger_base_setup(void) +{ + base_responsive = 0; + charge_base = -1; + battery_dynamic[BATT_IDX_BASE].flags = EC_BATT_FLAG_INVALID_DATA; +} + +bool charger_base_charge_changed(void) +{ + return charge_base != prev_charge_base; +} + +void charger_base_charge_update(void) +{ + prev_charge_base = charge_base; +} + +void charger_base_show_charge(void) +{ + CPRINTS("Base battery %d%%", charge_base); +} + +bool charger_base_charge_near_full(void) +{ + if (charge_base > -1 && charge_base < CONFIG_BATT_HOST_FULL_FACTOR) + return false; + + return true; +} + +int charger_base_get_input_voltage(const struct charge_state_data *curr) +{ + return curr->input_voltage; +} + +void charger_base_set_input_voltage(struct charge_state_data *curr, + int input_voltage) +{ + curr->input_voltage = input_voltage; +} + +/* Reset the base on S5->S0 transition. */ +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_base_reset, HOOK_PRIO_DEFAULT); diff --git a/common/ec_ec_comm_server.c b/common/ec_ec_comm_server.c index 174ac54757..3c83253138 100644 --- a/common/ec_ec_comm_server.c +++ b/common/ec_ec_comm_server.c @@ -6,7 +6,7 @@ */ #include "battery.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "common.h" #include "console.h" #include "crc8.h" diff --git a/common/host_command_pd.c b/common/host_command_pd.c index e7dbbc2b5f..062113fb0e 100644 --- a/common/host_command_pd.c +++ b/common/host_command_pd.c @@ -32,7 +32,7 @@ #ifdef CONFIG_HOSTCMD_PD_CHG_CTRL /* By default allow 5V charging only for the dead battery case */ -static enum pd_charge_state charge_state = PD_CHARGE_5V; +static enum pd_charge_state pd_chg_state = PD_CHARGE_5V; #define CHARGE_PORT_UNINITIALIZED -2 static int charge_port = CHARGE_PORT_UNINITIALIZED; @@ -48,7 +48,7 @@ void host_command_pd_send_status(enum pd_charge_state new_chg_state) #ifdef CONFIG_HOSTCMD_PD_CHG_CTRL /* Update PD MCU charge state if necessary */ if (new_chg_state != PD_CHARGE_NO_CHANGE) - charge_state = new_chg_state; + pd_chg_state = new_chg_state; #endif /* Wake PD HC task to send status */ task_set_event(TASK_ID_PDCMD, TASK_EVENT_EXCHANGE_PD_STATUS); @@ -74,7 +74,7 @@ static void pd_exchange_update_ec_status(struct ec_params_pd_status *ec_status, { /* Send PD charge state and battery state of charge */ #ifdef CONFIG_HOSTCMD_PD_CHG_CTRL - ec_status->charge_state = charge_state; + ec_status->charge_state = pd_chg_state; #endif if (charge_get_flags() & CHARGE_FLAG_BATT_RESPONSIVE) ec_status->batt_soc = charge_get_percent(); diff --git a/common/keyboard_8042.c b/common/keyboard_8042.c index f3c454382b..3329ce38c0 100644 --- a/common/keyboard_8042.c +++ b/common/keyboard_8042.c @@ -430,7 +430,7 @@ static void set_typematic_delays(uint8_t data) ((typematic_value_from_host & 0x7) + 8) / 240; } -static void reset_rate_and_delay(void) +test_export_static void reset_rate_and_delay(void) { set_typematic_delays(DEFAULT_TYPEMATIC_VALUE); } @@ -451,7 +451,7 @@ static void keyboard_wakeup(void) host_set_single_event(EC_HOST_EVENT_KEY_PRESSED); } -static void set_typematic_key(const uint8_t *scan_code, int32_t len) +test_export_static void set_typematic_key(const uint8_t *scan_code, int32_t len) { typematic_deadline.val = get_time().val + typematic_first_delay; memcpy(typematic_scan_code, scan_code, len); @@ -1390,3 +1390,30 @@ DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, keyboard_power_button, HOOK_PRIO_DEFAULT); #endif /* CONFIG_POWER_BUTTON && !CONFIG_MKBP_INPUT_DEVICES */ + +#ifdef TEST_BUILD +void test_keyboard_8042_set_resend_command(const uint8_t *data, int length) +{ + length = MIN(length, sizeof(resend_command)); + + memcpy(resend_command, data, length); + resend_command_len = length; +} + +void test_keyboard_8042_reset(void) +{ + /* Initialize controller ram */ + memset(controller_ram, 0, sizeof(controller_ram)); + controller_ram[0] = I8042_XLATE | I8042_AUX_DIS | I8042_KBD_DIS; + + /* Typematic state reset */ + reset_rate_and_delay(); + clear_typematic_key(); + + /* Use default scancode set # 2 */ + scancode_set = SCANCODE_SET_2; + + /* Keyboard not enabled (matches I8042_KBD_DIS bit being set) */ + keyboard_enabled = false; +} +#endif /* TEST_BUILD */ diff --git a/common/led_onoff_states.c b/common/led_onoff_states.c index 404ae06cd9..a08d1fe1bb 100644 --- a/common/led_onoff_states.c +++ b/common/led_onoff_states.c @@ -49,7 +49,7 @@ static enum led_states led_get_state(void) if (!IS_ENABLED(CONFIG_CHARGER)) return new_state; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Get percent charge */ charge_lvl = led_get_charge_percent(); diff --git a/common/led_policy_std.c b/common/led_policy_std.c index b9d95af639..6e89290c57 100644 --- a/common/led_policy_std.c +++ b/common/led_policy_std.c @@ -159,7 +159,7 @@ static void std_led_set_battery(void) * Same as the chromeos spec * Green/Amber for CHARGE_FLAG_FORCE_IDLE */ - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: bat_led_set_color(LED_AMBER); break; diff --git a/common/led_pwm.c b/common/led_pwm.c index 4f7297d003..1573eb03a9 100644 --- a/common/led_pwm.c +++ b/common/led_pwm.c @@ -168,7 +168,7 @@ static void pulse_leds(enum ec_led_colors color, int ontime, int period) #ifdef CONFIG_BATTERY static int show_charge_state(void) { - enum charge_state chg_st = charge_get_state(); + enum led_pwr_state chg_st = led_pwr_get_state(); /* * The colors listed below are the default, but can be overridden. diff --git a/common/lightbar.c b/common/lightbar.c index f3343c6a0c..3a96a2d5f5 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -265,7 +265,7 @@ static int get_battery_level(void) #ifdef HAS_TASK_CHARGER st.battery_percent = pct = charge_get_percent(); - st.battery_is_charging = (PWR_STATE_DISCHARGE != charge_get_state()); + st.battery_is_charging = (PWR_STATE_DISCHARGE != led_pwr_get_state()); st.battery_is_power_on_prevented = charge_prevent_power_on(0); #endif diff --git a/common/ocpc.c b/common/ocpc.c index 5d2d97dc2c..39e13dc046 100644 --- a/common/ocpc.c +++ b/common/ocpc.c @@ -8,7 +8,7 @@ #include "battery.h" #include "battery_fuel_gauge.h" #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "console.h" diff --git a/common/panic_output.c b/common/panic_output.c index a32303f52a..8dd5143277 100644 --- a/common/panic_output.c +++ b/common/panic_output.c @@ -329,7 +329,7 @@ DISABLE_GCC_WARNING("-Winfinite-recursion") #endif static void stack_overflow_recurse(int n) { - ccprintf("+%d", n); + panic_printf("+%d", n); /* * Force task context switch, since that's where we do stack overflow @@ -343,7 +343,7 @@ static void stack_overflow_recurse(int n) * Do work after the recursion, or else the compiler uses tail-chaining * and we don't actually consume additional stack. */ - ccprintf("-%d", n); + panic_printf("-%d", n); } ENABLE_CLANG_WARNING("-Winfinite-recursion") #if __GNUC__ >= 12 diff --git a/common/rollback.c b/common/rollback.c index 8e29b97d28..2ff7b3f40b 100644 --- a/common/rollback.c +++ b/common/rollback.c @@ -8,9 +8,6 @@ #include "builtin/assert.h" #include "common.h" #include "console.h" -#ifdef CONFIG_LIBCRYPTOC -#include "cryptoc/util.h" -#endif #include "flash.h" #include "hooks.h" #include "host_command.h" @@ -25,6 +22,18 @@ #include "trng.h" #include "util.h" +#ifdef CONFIG_ROLLBACK_SECRET_SIZE +#ifdef CONFIG_BORINGSSL_CRYPTO +#include "openssl/mem.h" +#define secure_clear(buffer, size) OPENSSL_cleanse(buffer, size) +#elif defined(CONFIG_LIBCRYPTOC) +#include "cryptoc/util.h" +#define secure_clear(buffer, size) always_memset(buffer, 0, size) +#else +#error One of CONFIG_BORINGSSL_CRYPTO or CONFIG_LIBCRYPTOC should be defined +#endif +#endif + /* Console output macros */ #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) @@ -73,7 +82,7 @@ static uint32_t unlock_rollback(void) static void clear_rollback(struct rollback_data *data) { #ifdef CONFIG_ROLLBACK_SECRET_SIZE - always_memset(data->secret, 0, sizeof(data->secret)); + secure_clear(data->secret, sizeof(data->secret)); #endif } @@ -222,7 +231,7 @@ static int add_entropy(uint8_t *dst, const uint8_t *src, const uint8_t *add, #ifdef CONFIG_ROLLBACK_SECRET_LOCAL_ENTROPY_SIZE failed: #endif - always_memset(&ctx, 0, sizeof(ctx)); + secure_clear(&ctx, sizeof(ctx)); return ret; } #else diff --git a/common/system_safe_mode.c b/common/system_safe_mode.c index e49e206b4f..b496bd4475 100644 --- a/common/system_safe_mode.c +++ b/common/system_safe_mode.c @@ -19,6 +19,8 @@ #define STACK_PRINT_SIZE_WORDS 32 +#define CANNOT_ENTER_SAFE_MODE_FMT "Cannot start SSM: %s\n" + static bool in_safe_mode; static const int safe_mode_allowed_hostcmds[] = { @@ -79,19 +81,11 @@ int disable_non_safe_mode_critical_tasks(void) void handle_system_safe_mode_timeout(void) { - panic_printf("Safe mode timeout after %d msec\n", - CONFIG_SYSTEM_SAFE_MODE_TIMEOUT_MSEC); + panic_printf("SSM timeout\n"); panic_reboot(); } DECLARE_DEFERRED(handle_system_safe_mode_timeout); -__overridable int schedule_system_safe_mode_timeout(void) -{ - hook_call_deferred(&handle_system_safe_mode_timeout_data, - CONFIG_SYSTEM_SAFE_MODE_TIMEOUT_MSEC * MSEC); - return EC_SUCCESS; -} - bool system_is_in_safe_mode(void) { return !!in_safe_mode; @@ -105,7 +99,7 @@ static void print_panic_stack(void) uint32_t sp; const struct panic_data *pdata = panic_get_data(); - ccprintf("\n========== Stack Contents ==========="); + ccprintf("\nStack Contents"); sp = get_panic_stack_pointer(pdata); for (int i = 0; i < STACK_PRINT_SIZE_WORDS; i++) { if (sp == 0 || @@ -133,7 +127,7 @@ bool command_is_allowed_in_safe_mode(int command) static void system_safe_mode_start(void) { - ccprintf("*** Post Panic System Safe Mode ***\n"); + ccprintf("Post Panic SSM\n"); if (IS_ENABLED(CONFIG_SYSTEM_SAFE_MODE_PRINT_STACK)) print_panic_stack(); if (IS_ENABLED(CONFIG_HOSTCMD_EVENTS)) @@ -144,25 +138,26 @@ DECLARE_DEFERRED(system_safe_mode_start); int start_system_safe_mode(void) { if (!system_is_in_rw()) { - panic_printf("Can only enter safe mode from RW image\n"); + panic_printf(CANNOT_ENTER_SAFE_MODE_FMT, "RO image"); return EC_ERROR_INVAL; } if (system_is_in_safe_mode()) { - panic_printf("Already in system safe mode"); + panic_printf(CANNOT_ENTER_SAFE_MODE_FMT, "Already in SSM"); return EC_ERROR_INVAL; } if (is_current_task_safe_mode_critical()) { /* TODO: Restart critical tasks */ - panic_printf( - "Fault in critical task, cannot enter system safe mode\n"); + panic_printf(CANNOT_ENTER_SAFE_MODE_FMT, + "Panic in critical task"); return EC_ERROR_INVAL; } disable_non_safe_mode_critical_tasks(); - schedule_system_safe_mode_timeout(); + hook_call_deferred(&handle_system_safe_mode_timeout_data, + CONFIG_SYSTEM_SAFE_MODE_TIMEOUT_MSEC * MSEC); /* * Schedule a deferred function to run immediately @@ -173,7 +168,7 @@ int start_system_safe_mode(void) in_safe_mode = true; - panic_printf("\nStarting system safe mode\n"); + panic_printf("Starting SSM\n"); return EC_SUCCESS; } diff --git a/common/usbc/ap_vdm_control.c b/common/usbc/ap_vdm_control.c index 08b8f727d6..e0ed9e3f33 100644 --- a/common/usbc/ap_vdm_control.c +++ b/common/usbc/ap_vdm_control.c @@ -9,6 +9,7 @@ */ #include "builtin/assert.h" +#include "chipset.h" #include "compile_time_macros.h" #include "console.h" #include "ec_commands.h" @@ -19,6 +20,7 @@ #include "tcpm/tcpm.h" #include "temp_sensor.h" #include "usb_pd.h" +#include "usb_pd_dp_hpd_gpio.h" #include "usb_pd_dpm_sm.h" #include <stdbool.h> @@ -41,6 +43,17 @@ #define DPM_ATTENTION_QUEUE_DEPTH 8 BUILD_ASSERT(POWER_OF_TWO(DPM_ATTENTION_QUEUE_DEPTH)); +/* + * timestamp of the next possible toggle to ensure the 2-ms spacing + * between IRQ_HPD. Note, other boards use the DP module to store this + * variable so it's globally accessible for board code. + * + * Note: This is also defined in the EC-driven DP module, and it's assumed + * that these modules are mutually exclusive and will not be compiled + * for the same board. + */ +uint64_t svdm_hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; + struct attention_queue_entry { int objects; uint32_t attention[PD_ATTENTION_MAX_VDO]; @@ -54,6 +67,10 @@ static struct { struct queue_state queue_state; struct attention_queue_entry queue_buffer[DPM_ATTENTION_QUEUE_DEPTH]; mutex_t queue_lock; + /* Have we seen the DP:Configure ACK? */ + bool dp_configured; + /* Did we get a HPD high signal before DP:Configure completed? */ + bool hpd_pending; } ap_storage[CONFIG_USB_PD_PORT_MAX_COUNT]; #ifdef CONFIG_ZEPHYR @@ -90,6 +107,27 @@ static void init_attention_queue_structs(void) } DECLARE_HOOK(HOOK_INIT, init_attention_queue_structs, HOOK_PRIO_FIRST); +/* Process HPD signals from the DP:Status or Attention contents */ +static void attention_hpd_process(int port, uint32_t vdo) +{ + bool hpd_level = PD_VDO_DPSTS_HPD_LVL(vdo); + bool hpd_irq = PD_VDO_DPSTS_HPD_IRQ(vdo); + + if (!ap_storage[port].dp_configured && hpd_level) + ap_storage[port].hpd_pending = true; + else + dp_hpd_gpio_set(port, hpd_level, hpd_irq); + + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + (hpd_irq || hpd_level)) + /* + * Wake up the AP. IRQ or level high indicates a DP + * sink is now present. + */ + if (IS_ENABLED(CONFIG_MKBP_EVENT)) + pd_notify_dp_alt_mode_entry(port); +} + void ap_vdm_attention_enqueue(int port, int length, uint32_t *buf) { struct attention_queue_entry new_entry; @@ -110,6 +148,10 @@ void ap_vdm_attention_enqueue(int port, int length, uint32_t *buf) pd_notify_event(port, PD_STATUS_EVENT_VDM_ATTENTION); mutex_unlock(&ap_storage[port].queue_lock); + + /* Process HPD from the message if we're configured */ + if (PD_VDO_VID(buf[0]) == USB_SID_DISPLAYPORT && length > 1) + attention_hpd_process(port, buf[1]); } static uint8_t ap_vdm_attention_pop(int port, uint32_t *buf, @@ -139,6 +181,9 @@ void ap_vdm_init(int port) /* Clear any stored AP messages */ ap_storage[port].vdm_reply_cnt = 0; queue_init(&ap_storage[port].attention_queue); + ap_storage[port].dp_configured = false; + ap_storage[port].hpd_pending = false; + dp_hpd_gpio_set(port, false, false); } void ap_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, @@ -155,6 +200,32 @@ void ap_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, /* Clear the flag now that reply fields are updated */ dpm_clear_vdm_request(port); + + if ((PD_VDO_VID(vdm[0]) == USB_SID_DISPLAYPORT) && + PD_VDO_SVDM(vdm[0]) && (PD_VDO_CMD(vdm[0]) == CMD_DP_CONFIG)) { + /* + * If this was a DP:Configure ACK, register it so we can start + * sending HPD signals + */ + ap_storage[port].dp_configured = true; + if (ap_storage[port].hpd_pending) + dp_hpd_gpio_set(port, true, false); + } else if ((PD_VDO_VID(vdm[0]) == USB_SID_DISPLAYPORT) && + PD_VDO_SVDM(vdm[0]) && + (PD_VDO_CMD(vdm[0]) == CMD_DP_STATUS) && vdo_count > 1) { + /* + * If this was a DP:Status ACK, register if the HPD signal was + * set in it. According to 3.9.2.2 USB PD-to-HPD Timing in + * VESA DisplayPort Alt Mode on USB Type-C Standard Version + * 2.0: + * "A USB PD-to-HPD converter shall drive a low level on its + * HPD driver whenever DisplayPort Configuration on the USB-C + * interface is not enabled" + * + * So we may not transmit this HPD high until DP:Configure ACK + */ + attention_hpd_process(port, vdm[1]); + } } void ap_vdm_naked(int port, enum tcpci_msg_type type, uint16_t svid, diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 0324132ac2..022d81109b 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -35,6 +35,12 @@ #include "usb_tbt_alt_mode.h" #include "usb_tc_sm.h" +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 43 + #ifdef CONFIG_ZEPHYR #include "temp_sensor/temp_sensor.h" #endif diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index d41a6ff86f..f4133dd890 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -382,7 +382,11 @@ SECTIONS * TODO(b/202863352): Unify clang and gcc behavior. */ #ifdef __clang__ +#if defined(SECTION_IS_RO) && defined(NPCX_RO_HEADER) + __data_lma_start = .; +#else __data_lma_start = LOADADDR(.data); +#endif #else __data_lma_start = .; #endif diff --git a/docs/write_protection.md b/docs/write_protection.md index 0ce6253a04..20d7e146ab 100644 --- a/docs/write_protection.md +++ b/docs/write_protection.md @@ -188,79 +188,6 @@ If the `ro_at_boot` flag set, and the EC resets with the HW gpio disabled, the EC will leave the flash unprotected (`ro_now` and `all_now` flags are not set) but leave `ro_at_boot` flag set. -### Changing Software Write Protection with flashrom - -#### View the current state of software write protection - -```bash -(chroot) $ flashrom -p ec --wp-status -``` - -``` -WP: status: 0x00 -WP: status.srp0: 0 -WP: write protect is disabled. -WP: write protect range: start=0x00000000, len=0x00000000 -``` - -#### Enable software write protection - -This is immediate. The protection range indicates the RO region of the firmware. - -```bash -(chroot) $ flashrom -p ec --wp-enable -``` - -``` -SUCCESS -``` - -```bash -(chroot) $ flashrom -p ec --wp-status -``` - -``` -WP: status: 0x80 -WP: status.srp0: 1 -WP: write protect is enabled. -WP: write protect range: start=0x00000000, len=0x0001f800 -``` - -#### Disable software write protection - -Disable can only be done with hardware write protect disabled. - -```bash -(chroot) $ flashrom -p ec --wp-disable -``` - -``` -FAILED: RO_AT_BOOT is not clear. -FAILED -``` - -Reboot with [hardware write protection](#hw_wp) disabled. Note that protection -is still enabled, but the protection range is zero. - -```bash -(chroot) $ flashrom -p ec --wp-status -``` - -``` -WP: status: 0x80 -WP: status.srp0: 1 -WP: write protect is enabled. -WP: write protect range: start=0x00000000, len=0x00000000 -``` - -```bash -(chroot) $ flashrom -p ec --wp-disable -``` - -``` -SUCCESS -``` - ## system_is_locked() The [`system_is_locked()`] function in the EC code returns false if the HW write diff --git a/driver/accelgyro_icm42607.c b/driver/accelgyro_icm42607.c index 48518fa315..07582ba88e 100644 --- a/driver/accelgyro_icm42607.c +++ b/driver/accelgyro_icm42607.c @@ -9,6 +9,7 @@ */ #include "accelgyro.h" +#include "builtin/endian.h" #include "console.h" #include "driver/accelgyro_icm42607.h" #include "driver/accelgyro_icm_common.h" @@ -960,6 +961,9 @@ static int icm42607_read_temp(const struct motion_sensor_t *s, int *temp_ptr) if (ret != EC_SUCCESS) return ret; + /* This register is big-endian and not configurable */ + val = be16toh(val); + /* ensure correct propagation of 16 bits sign bit */ val = sign_extend(val, 15); diff --git a/driver/charger/bq25710.c b/driver/charger/bq25710.c index 222d2f58a4..a13770a02c 100644 --- a/driver/charger/bq25710.c +++ b/driver/charger/bq25710.c @@ -9,7 +9,7 @@ #include "battery_smart.h" #include "bq257x0_regs.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "console.h" diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index a5fae9329d..997838f53e 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -9,7 +9,7 @@ #include "battery.h" #include "battery_smart.h" #include "builtin/assert.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c index 2bb3d75f28..3529f9d2a5 100644 --- a/driver/charger/isl9241.c +++ b/driver/charger/isl9241.c @@ -1215,7 +1215,7 @@ static int isl9241_ramp_get_current_limit(int chgnum) static void isl9241_restart_charge_voltage_when_full(void) { if (!chipset_in_or_transitioning_to_state(CHIPSET_STATE_ON) && - charge_get_state() == PWR_STATE_CHARGE_NEAR_FULL && + led_pwr_get_state() == PWR_STATE_CHARGE_NEAR_FULL && battery_get_disconnect_state() == BATTERY_NOT_DISCONNECTED) { charger_discharge_on_ac(1); msleep(50); diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index 391c60956a..a3e22c5b8b 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -7,7 +7,7 @@ #include "atomic.h" #include "battery.h" #include "battery_smart.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "extpower.h" #include "gpio.h" diff --git a/driver/led/ds2413.c b/driver/led/ds2413.c index 5268e52ac0..1b91f2b2b1 100644 --- a/driver/led/ds2413.c +++ b/driver/led/ds2413.c @@ -107,7 +107,7 @@ static void onewire_led_tick(void) } /* Translate charge state to LED color */ - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_IDLE: new_color = LED_GREEN; break; diff --git a/driver/nvidia_gpu.c b/driver/nvidia_gpu.c index b8a2195470..ff6e5fe39b 100644 --- a/driver/nvidia_gpu.c +++ b/driver/nvidia_gpu.c @@ -100,7 +100,7 @@ static void evaluate_d_notify_level(void) for (lvl = D_NOTIFY_5; lvl >= D_NOTIFY_1; lvl--) { if (policy[lvl].power_source == D_NOTIFY_DC) { - if (soc <= policy[lvl].dc.min_battery_soc) { + if (soc <= policy[lvl].dc.max_battery_soc) { set_d_notify_level(lvl); break; } diff --git a/driver/nvidia_gpu.h b/driver/nvidia_gpu.h index bfd1bba287..9d87914a91 100644 --- a/driver/nvidia_gpu.h +++ b/driver/nvidia_gpu.h @@ -35,7 +35,7 @@ struct d_notify_policy { unsigned int min_charger_watts; } ac; struct { - unsigned int min_battery_soc; + unsigned int max_battery_soc; } dc; }; }; @@ -50,9 +50,9 @@ struct d_notify_policy { .power_source = D_NOTIFY_AC_DC, \ } -#define DC_ATLEAST_SOC(S) \ +#define DC_ATMOST_SOC(S) \ { \ - .power_source = D_NOTIFY_DC, .dc.min_battery_soc = (S), \ + .power_source = D_NOTIFY_DC, .dc.max_battery_soc = (S), \ } void nvidia_gpu_init_policy(const struct d_notify_policy *policies); diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c index 120749fb62..3c4565cfd5 100644 --- a/driver/tcpm/nct38xx.c +++ b/driver/tcpm/nct38xx.c @@ -115,11 +115,6 @@ static int nct38xx_init(int port) /* Set FRS direction for SNK detect, if FRS is enabled */ if (tcpm_tcpc_has_frs_control(port)) { - reg = TCPC_REG_DEV_CAP_2_SNK_FR_SWAP; - rv = tcpc_write(port, TCPC_REG_DEV_CAP_2, reg); - if (rv) - return rv; - reg = TCPC_REG_CONFIG_EXT_1_FR_SWAP_SNK_DIR; rv = tcpc_write(port, TCPC_REG_CONFIG_EXT_1, reg); if (rv) diff --git a/driver/tcpm/rt1718s.c b/driver/tcpm/rt1718s.c index 3d4303a8b7..e8ee85368a 100644 --- a/driver/tcpm/rt1718s.c +++ b/driver/tcpm/rt1718s.c @@ -7,6 +7,7 @@ * RT1718S TCPC Driver */ +#include "battery.h" #include "console.h" #include "driver/tcpm/rt1718s.h" #include "driver/tcpm/tcpci.h" @@ -261,6 +262,11 @@ static int rt1718s_init(int port) { static bool need_sw_reset = true; + /* Do not reset the TCPC when device is no battery connected, otherwise + * the SINK GPIO to the PPC may be reset, and cause a brown-out. + */ + need_sw_reset &= battery_is_present() == BP_YES; + if (!system_jumped_late() && need_sw_reset) { RETURN_ERROR(rt1718s_sw_reset(port)); need_sw_reset = false; diff --git a/driver/tcpm/rt1718s.h b/driver/tcpm/rt1718s.h index 76bbfd48a8..d14e2bd498 100644 --- a/driver/tcpm/rt1718s.h +++ b/driver/tcpm/rt1718s.h @@ -92,9 +92,14 @@ #define RT1718S_ENA_SRC_VBUS_CTRL 0xE1 #define RT1718S_FAULT_OC1_VBUS_CTRL 0xE3 #define RT1718S_GPIO1_VBUS_CTRL 0xEA -#define RT1718S_GPIO1_VBUS_CTRL_FRS_RX_VBUS BIT(6) +#define RT1718S_GPIO_VBUS_CTRL_FRS_RX_VBUS BIT(6) +#define RT1718S_GPIO_VBUS_CTRL_FRS_TX_VBUS BIT(5) +#define RT1718S_GPIO_VBUS_CTRL_ENA_SRC_HV_VBUS_GPIO BIT(4) +#define RT1718S_GPIO_VBUS_CTRL_ENA_SRC_VBUS_GPIO BIT(3) +#define RT1718S_GPIO_VBUS_CTRL_DIS_SRC_VBUS_GPIO BIT(2) +#define RT1718S_GPIO_VBUS_CTRL_ENA_SNK_VBUS_GPIO BIT(1) +#define RT1718S_GPIO_VBUS_CTRL_DIS_SNK_VBUS_GPIO BIT(0) #define RT1718S_GPIO2_VBUS_CTRL 0xEB -#define RT1718S_GPIO2_VBUS_CTRL_FRS_RX_VBUS BIT(6) #define RT1718S_VBUS_CTRL_EN 0xEC #define RT1718S_VBUS_CTRL_EN_GPIO2_VBUS_PATH_EN BIT(7) #define RT1718S_VBUS_CTRL_EN_GPIO1_VBUS_PATH_EN BIT(6) diff --git a/include/battery.h b/include/battery.h index 0daa6205a7..23d9352643 100644 --- a/include/battery.h +++ b/include/battery.h @@ -25,13 +25,6 @@ /* Stop charge when charging and battery level >= this percentage */ #define BATTERY_LEVEL_FULL 100 -/* Tell host we're charged when battery level >= this percentage */ -#ifdef CONFIG_BATTERY_LEVEL_NEAR_FULL -#define BATTERY_LEVEL_NEAR_FULL CONFIG_BATTERY_LEVEL_NEAR_FULL -#else -#define BATTERY_LEVEL_NEAR_FULL 97 -#endif - /* * Send battery-low host event when discharging and battery level <= this level */ diff --git a/include/charge_state.h b/include/charge_state.h index dcf3430954..34576dc333 100644 --- a/include/charge_state.h +++ b/include/charge_state.h @@ -5,7 +5,13 @@ #ifndef __CROS_EC_CHARGE_STATE_H #define __CROS_EC_CHARGE_STATE_H +#include "battery.h" +#include "battery_smart.h" +#include "charger.h" +#include "chipset.h" #include "common.h" +#include "ec_ec_comm_client.h" +#include "ocpc.h" #include "stdbool.h" #include "timer.h" @@ -26,7 +32,7 @@ #endif /* Power states */ -enum charge_state { +enum led_pwr_state { /* Meta-state; unchanged from previous time through task loop */ PWR_STATE_UNCHANGE = 0, /* Initializing charge state machine at boot */ @@ -61,7 +67,7 @@ enum charge_state { /* Battery is responsive */ #define CHARGE_FLAG_BATT_RESPONSIVE BIT(2) -/* Debugging constants, in the same order as enum charge_state. This string +/* Debugging constants, in the same order as enum pwr_state. This string * table was moved here to sync with enum above. */ #define CHARGE_STATE_NAME_TABLE \ @@ -72,10 +78,50 @@ enum charge_state { } /* End of CHARGE_STATE_NAME_TABLE macro */ +/* + * The values exported by charge_get_state() and charge_get_flags() are used + * only to control the LEDs (with one not-quite-correct exception). For V2 + * we use a different set of states internally. + */ +enum charge_state_v2 { + ST_IDLE = 0, + ST_DISCHARGE, + ST_CHARGE, + ST_PRECHARGE, + + NUM_STATES_V2 +}; + +struct charge_state_data { + timestamp_t ts; + int ac; + int batt_is_charging; + struct charger_params chg; + struct batt_params batt; + enum charge_state_v2 state; + int requested_voltage; + int requested_current; + int desired_input_current; +#ifdef CONFIG_CHARGER_OTG + int output_current; +#endif +#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT + int input_voltage; +#endif +#ifdef CONFIG_OCPC + struct ocpc_data ocpc; +#endif +}; + +struct sustain_soc { + int8_t lower; + int8_t upper; +}; + /** * Return current charge state. */ -enum charge_state charge_get_state(void); +enum led_pwr_state led_pwr_get_state(void); /** * Return current charge v2 state. @@ -191,7 +237,185 @@ int charge_get_battery_temp(int idx, int *temp_ptr); */ const struct batt_params *charger_current_battery_params(void); +/** + * Set the output current limit and voltage. This is used to provide power from + * the charger chip ("OTG" mode). + * + * @param chgnum Charger index to act upon + * @param ma Maximum current to provide in mA (0 to disable output). + * @param mv Voltage in mV (ignored if ma == 0). + * @return EC_SUCCESS or error + */ +int charge_set_output_current_limit(int chgnum, int ma, int mv); + +/** + * Set the charge input current limit. This value is stored and sent every + * time AC is applied. + * + * The input current limit is automatically derated by + * CONFIG_CHARGER_INPUT_CURRENT_DERATE_PCT (if configured), and is clamped to + * no less than CONFIG_CHARGER_MIN_INPUT_CURRENT_LIMIT mA (if configured). + * + * @param ma New input current limit in mA + * @param mv Negotiated charge voltage in mV. + * @return EC_SUCCESS or error + */ +int charge_set_input_current_limit(int ma, int mv); + +/** + * Set the desired manual charge current when in idle mode. + * + * @param curr_ma: Charge current in mA. + */ +void chgstate_set_manual_current(int curr_ma); + +/** + * Set the desired manual charge voltage when in idle mode. + * + * @param volt_mv: Charge voltage in mV. + */ +void chgstate_set_manual_voltage(int volt_mv); + +/** + * Board-specific routine to indicate if the base is connected. + */ +int board_is_base_connected(void); + +/** + * Board-specific routine to enable power distribution between lid and base + * (current can flow both ways). + */ +void board_enable_base_power(int enable); + +/** + * Board-specific routine to reset the base (in case it is unresponsive, e.g. + * if we told it to hibernate). + */ +void board_base_reset(void); + +/** + * Callback with which boards determine action on critical low battery + * + * The default implementation is provided in charge_state_v2.c. Overwrite it + * to customize it. + * + * @param curr Pointer to struct charge_state_data + * @return Action to take. + */ +enum critical_shutdown +board_critical_shutdown_check(struct charge_state_data *curr); + +/** + * Callback to set battery level for shutdown + * + * A board can implement this to customize shutdown battery level at runtime. + * + * @return battery level for shutdown + */ +uint8_t board_set_battery_level_shutdown(void); + +/** + * Return system PLT power and battery's desired power. + * + * @return desired power in mW + */ +int charge_get_plt_plus_bat_desired_mw(void); + +/** + * Get the stable battery charging current. The current will be + * CHARGE_CURRENT_UNINITIALIZED if not yet stable. + * + * @return stable battery charging current in mA + */ +int charge_get_stable_current(void); + +/** + * Select which charger IC will actually be performing the charger switching. + * + * @param idx The index into the chg_chips table. + */ +void charge_set_active_chg_chip(int idx); + +/** + * Retrieve which charger IC is the active charger IC performing the charger + * switching. + */ +int charge_get_active_chg_chip(void); + +/** + * Set the stable current. + * + * @param ma: battery charging current in mA + */ +void charge_set_stable_current(int ma); + +/** + * Reset stable current counter stable_ts. Calling this function would set + * stable_current to CHARGE_CURRENT_UNINITIALIZED. + */ +void charge_reset_stable_current(void); + +/** + * Reset stable current counter stable_ts. Calling this function would set + * stable_current to CHARGE_CURRENT_UNINITIALIZED. + * + * @param us: sample stable current until us later. + */ +void charge_reset_stable_current_us(uint64_t us); + +/** + * Check if the battery charging current is stable by examining the timestamp. + * + * @return true if stable timestamp expired, false otherwise. + */ +bool charge_is_current_stable(void); + +/** + * Reset the OCPC internal state data and set the target VSYS to the current + * battery voltage for the auxiliary chargers. + */ +void trigger_ocpc_reset(void); + +/* Track problems in communicating with the battery or charger */ +enum problem_type { + PR_STATIC_UPDATE, + PR_SET_VOLTAGE, + PR_SET_CURRENT, + PR_SET_MODE, + PR_SET_INPUT_CURR, + PR_POST_INIT, + PR_CHG_FLAGS, + PR_BATT_FLAGS, + PR_CUSTOM, + PR_CFG_SEC_CHG, + + NUM_PROBLEM_TYPES +}; + +void charge_problem(enum problem_type p, int v); + +struct charge_state_data *charge_get_status(void); + +enum ec_charge_control_mode get_chg_ctrl_mode(void); + +__test_only void reset_prev_disp_charge(void); + +/** + * Whether or not the charging progress was shown. Note, calling this function + * will reset the value to false. + * + * @return Whether or not the charging progress was printed to the console + */ +__test_only bool charging_progress_displayed(void); + +/** + * Callback for boards to request charger to enable bypass mode on/off. + * + * @return True for requesting bypass on. False for requesting bypass off. + */ +int board_should_charger_bypass(void); + /* Config Charger */ -#include "charge_state_v2.h" +#include "charge_state.h" #endif /* __CROS_EC_CHARGE_STATE_H */ diff --git a/include/charge_state_v1.h b/include/charge_state_v1.h deleted file mode 100644 index 302fc0acf8..0000000000 --- a/include/charge_state_v1.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2013 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "battery.h" -#include "timer.h" - -#ifndef __CROS_EC_CHARGE_STATE_V1_H -#define __CROS_EC_CHARGE_STATE_V1_H - -/* Update period to prevent charger watchdog timeout */ -#define CHARGER_UPDATE_PERIOD (SECOND * 10) - -/* Power state error flags */ -#define F_CHARGER_INIT BIT(0) /* Charger initialization */ -#define F_CHARGER_VOLTAGE BIT(1) /* Charger maximum output voltage */ -#define F_CHARGER_CURRENT BIT(2) /* Charger maximum output current */ -#define F_BATTERY_VOLTAGE BIT(3) /* Battery voltage */ -#define F_BATTERY_MODE BIT(8) /* Battery mode */ -#define F_BATTERY_CAPACITY BIT(9) /* Battery capacity */ -#define F_BATTERY_STATE_OF_CHARGE BIT(10) /* State of charge, percentage */ -#define F_BATTERY_UNRESPONSIVE BIT(11) /* Battery not responding */ -#define F_BATTERY_NOT_CONNECTED BIT(12) /* Battery not connected */ -#define F_BATTERY_GET_PARAMS BIT(13) /* Any battery parameter bad */ - -#define F_BATTERY_MASK \ - (F_BATTERY_VOLTAGE | F_BATTERY_MODE | F_BATTERY_CAPACITY | \ - F_BATTERY_STATE_OF_CHARGE | F_BATTERY_UNRESPONSIVE | \ - F_BATTERY_NOT_CONNECTED | F_BATTERY_GET_PARAMS) -#define F_CHARGER_MASK (F_CHARGER_VOLTAGE | F_CHARGER_CURRENT | F_CHARGER_INIT) - -/* Power state data - * Status collection of charging state machine. - */ -struct charge_state_data { - int ac; - int charging_voltage; - int charging_current; - struct batt_params batt; - enum charge_state state; - uint32_t error; - timestamp_t ts; -}; - -/* State context - * The shared context for state handler. The context contains current and - * previous state. - */ -struct charge_state_context { - struct charge_state_data curr; - struct charge_state_data prev; - timestamp_t charge_state_updated_time; - uint32_t *memmap_batt_volt; - uint32_t *memmap_batt_rate; - uint32_t *memmap_batt_cap; - uint8_t *memmap_batt_flags; - /* Charger and battery pack info */ - const struct charger_info *charger; - const struct battery_info *battery; - /* Charging timestamps */ - timestamp_t charger_update_time; - timestamp_t trickle_charging_time; - timestamp_t voltage_debounce_time; - timestamp_t shutdown_warning_time; - int battery_responsive; -}; - -#endif /* __CROS_EC_CHARGE_STATE_V1_H */ diff --git a/include/charge_state_v2.h b/include/charge_state_v2.h index 6d0b936f4a..72fd8a88ff 100644 --- a/include/charge_state_v2.h +++ b/include/charge_state_v2.h @@ -3,235 +3,7 @@ * found in the LICENSE file. */ -#include "battery.h" -#include "battery_smart.h" -#include "charger.h" -#include "chipset.h" -#include "ec_ec_comm_client.h" -#include "ocpc.h" -#include "timer.h" - -#include <stdbool.h> - #ifndef __CROS_EC_CHARGE_STATE_V2_H #define __CROS_EC_CHARGE_STATE_V2_H -/* - * The values exported by charge_get_state() and charge_get_flags() are used - * only to control the LEDs (with one not-quite-correct exception). For V2 - * we use a different set of states internally. - */ -enum charge_state_v2 { - ST_IDLE = 0, - ST_DISCHARGE, - ST_CHARGE, - ST_PRECHARGE, - - NUM_STATES_V2 -}; - -struct charge_state_data { - timestamp_t ts; - int ac; - int batt_is_charging; - struct charger_params chg; - struct batt_params batt; - enum charge_state_v2 state; - int requested_voltage; - int requested_current; - int desired_input_current; -#ifdef CONFIG_CHARGER_OTG - int output_current; -#endif -#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT - int input_voltage; -#endif -#ifdef CONFIG_OCPC - struct ocpc_data ocpc; -#endif -}; - -struct sustain_soc { - int8_t lower; - int8_t upper; -}; - -/** - * Set the output current limit and voltage. This is used to provide power from - * the charger chip ("OTG" mode). - * - * @param chgnum Charger index to act upon - * @param ma Maximum current to provide in mA (0 to disable output). - * @param mv Voltage in mV (ignored if ma == 0). - * @return EC_SUCCESS or error - */ -int charge_set_output_current_limit(int chgnum, int ma, int mv); - -/** - * Set the charge input current limit. This value is stored and sent every - * time AC is applied. - * - * The input current limit is automatically derated by - * CONFIG_CHARGER_INPUT_CURRENT_DERATE_PCT (if configured), and is clamped to - * no less than CONFIG_CHARGER_MIN_INPUT_CURRENT_LIMIT mA (if configured). - * - * @param ma New input current limit in mA - * @param mv Negotiated charge voltage in mV. - * @return EC_SUCCESS or error - */ -int charge_set_input_current_limit(int ma, int mv); - -/** - * Set the desired manual charge current when in idle mode. - * - * @param curr_ma: Charge current in mA. - */ -void chgstate_set_manual_current(int curr_ma); - -/** - * Set the desired manual charge voltage when in idle mode. - * - * @param volt_mv: Charge voltage in mV. - */ -void chgstate_set_manual_voltage(int volt_mv); - -/** - * Board-specific routine to indicate if the base is connected. - */ -int board_is_base_connected(void); - -/** - * Board-specific routine to enable power distribution between lid and base - * (current can flow both ways). - */ -void board_enable_base_power(int enable); - -/** - * Board-specific routine to reset the base (in case it is unresponsive, e.g. - * if we told it to hibernate). - */ -void board_base_reset(void); - -/** - * Callback with which boards determine action on critical low battery - * - * The default implementation is provided in charge_state_v2.c. Overwrite it - * to customize it. - * - * @param curr Pointer to struct charge_state_data - * @return Action to take. - */ -enum critical_shutdown -board_critical_shutdown_check(struct charge_state_data *curr); - -/** - * Callback to set battery level for shutdown - * - * A board can implement this to customize shutdown battery level at runtime. - * - * @return battery level for shutdown - */ -uint8_t board_set_battery_level_shutdown(void); - -/** - * Return system PLT power and battery's desired power. - * - * @return desired power in mW - */ -int charge_get_plt_plus_bat_desired_mw(void); - -/** - * Get the stable battery charging current. The current will be - * CHARGE_CURRENT_UNINITIALIZED if not yet stable. - * - * @return stable battery charging current in mA - */ -int charge_get_stable_current(void); - -/** - * Select which charger IC will actually be performing the charger switching. - * - * @param idx The index into the chg_chips table. - */ -void charge_set_active_chg_chip(int idx); - -/** - * Retrieve which charger IC is the active charger IC performing the charger - * switching. - */ -int charge_get_active_chg_chip(void); - -/** - * Set the stable current. - * - * @param ma: battery charging current in mA - */ -void charge_set_stable_current(int ma); - -/** - * Reset stable current counter stable_ts. Calling this function would set - * stable_current to CHARGE_CURRENT_UNINITIALIZED. - */ -void charge_reset_stable_current(void); - -/** - * Reset stable current counter stable_ts. Calling this function would set - * stable_current to CHARGE_CURRENT_UNINITIALIZED. - * - * @param us: sample stable current until us later. - */ -void charge_reset_stable_current_us(uint64_t us); - -/** - * Check if the battery charging current is stable by examining the timestamp. - * - * @return true if stable timestamp expired, false otherwise. - */ -bool charge_is_current_stable(void); - -/** - * Reset the OCPC internal state data and set the target VSYS to the current - * battery voltage for the auxiliary chargers. - */ -void trigger_ocpc_reset(void); - -/* Track problems in communicating with the battery or charger */ -enum problem_type { - PR_STATIC_UPDATE, - PR_SET_VOLTAGE, - PR_SET_CURRENT, - PR_SET_MODE, - PR_SET_INPUT_CURR, - PR_POST_INIT, - PR_CHG_FLAGS, - PR_BATT_FLAGS, - PR_CUSTOM, - PR_CFG_SEC_CHG, - - NUM_PROBLEM_TYPES -}; - -void charge_problem(enum problem_type p, int v); - -struct charge_state_data *charge_get_status(void); - -enum ec_charge_control_mode get_chg_ctrl_mode(void); - -__test_only void reset_prev_disp_charge(void); - -/** - * Whether or not the charging progress was shown. Note, calling this function - * will reset the value to false. - * - * @return Whether or not the charging progress was printed to the console - */ -__test_only bool charging_progress_displayed(void); - -/** - * Callback for boards to request charger to enable bypass mode on/off. - * - * @return True for requesting bypass on. False for requesting bypass off. - */ -int board_should_charger_bypass(void); - #endif /* __CROS_EC_CHARGE_STATE_V2_H */ diff --git a/include/charger.h b/include/charger.h index 468d267bb8..0f5a9b3e7c 100644 --- a/include/charger.h +++ b/include/charger.h @@ -435,4 +435,17 @@ void print_charger_prochot(int chgnum); */ int charger_get_min_bat_pct_for_power_on(void); +/* Wake up the task when something important happens */ +void charge_wakeup(void); + +/* + * Ask the charger for some voltage and current. If either value is 0, + * charging is disabled; otherwise it's enabled. Negative values are ignored. + * + * @param use_curr Use values from requested voltage and current (otherwise use + * 0 for both) + * @param is_full Battery is full + */ +int charge_request(bool use_curr, bool is_full); + #endif /* __CROS_EC_CHARGER_H */ diff --git a/include/charger_base.h b/include/charger_base.h new file mode 100644 index 0000000000..efe4a6885f --- /dev/null +++ b/include/charger_base.h @@ -0,0 +1,64 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Charger functions related to a connected keyboard called a 'base' */ + +#ifndef __CROS_EC_CHARGER_BASE_H +#define __CROS_EC_CHARGER_BASE_H + +#include <stdbool.h> + +struct charge_state_data; + +/* allocate power between the base and the lid */ +void base_charge_allocate_input_current_limit( + const struct charge_state_data *curr, bool is_full, bool debugging); + +/* + * Check base external-power settings and react as needed + * + * @param ac Current ac value from struct charge_state_data + * @param prev_ac Previous value of ac + * Returns true if ac should be zeroed, false to leave it along + */ +bool base_check_extpower(int ac, int prev_ac); + +/* Update base battery information */ +void base_update_battery_info(void); + +#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT +/* Check if there is a base and it is connected */ +bool base_connected(void); + +#else +static inline bool base_connected(void) +{ + return false; +} +#endif + +/* Set up the charger task for the base */ +void charger_base_setup(void); + +/* Check if charge_base has changed since last time */ +bool charger_base_charge_changed(void); + +/* Update prev_charge_base with charge_base */ +void charger_base_charge_update(void); + +/* Show the current charge level of the base on the console */ +void charger_base_show_charge(void); + +/* Check if the base charge is near full */ +bool charger_base_charge_near_full(void); + +/* Get the base input-voltage */ +int charger_base_get_input_voltage(const struct charge_state_data *curr); + +/* Set the input voltage for the base */ +void charger_base_set_input_voltage(struct charge_state_data *curr, + int input_voltage); + +#endif /* __CROS_EC_CHARGER_BASE_H */ diff --git a/include/charger_profile_override.h b/include/charger_profile_override.h index 24606d3c3d..4648fb0ced 100644 --- a/include/charger_profile_override.h +++ b/include/charger_profile_override.h @@ -8,7 +8,7 @@ #ifndef __CROS_EC_CHARGER_PROFILE_OVERRIDE_H #define __CROS_EC_CHARGER_PROFILE_OVERRIDE_H -#include "charge_state_v2.h" +#include "charge_state.h" #define TEMPC_TENTHS_OF_DEG(c) ((c)*10) diff --git a/include/config.h b/include/config.h index 3279cbc821..a3a2edb1ed 100644 --- a/include/config.h +++ b/include/config.h @@ -631,12 +631,6 @@ #define CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT (30 * 60 * SECOND) /* - * Specify the battery percentage at which the host is told it is full. - * If this value is not specified the default is 97% set in battery.h. - */ -#undef CONFIG_BATTERY_LEVEL_NEAR_FULL - -/* * Use memory mapped region to store battery information. It supports only * single battery systems. V2 should be used unless there is a reason not to. */ @@ -1636,6 +1630,10 @@ #undef CONFIG_CMD_CHARGEN #endif #define CONFIG_CMD_CHARGER + +/* Extra debugging info for the charger */ +#define CONFIG_CHARGE_DEBUG + #undef CONFIG_CMD_CHARGER_ADC_AMON_BMON #undef CONFIG_CMD_CHARGER_DUMP #undef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE @@ -6308,6 +6306,7 @@ #define CONFIG_USBC_OCP #endif +#ifndef CONFIG_ZEPHYR /*****************************************************************************/ /* * Define CONFIG_USB_PD_VBUS_MEASURE_CHARGER if the charger on the board @@ -6318,19 +6317,24 @@ defined(CONFIG_CHARGER_MT6370) || defined(CONFIG_CHARGER_BQ25710) || \ defined(CONFIG_CHARGER_BQ25720) || defined(CONFIG_CHARGER_ISL9241) || \ defined(CONFIG_CHARGER_RAA489110) +#if !defined(CONFIG_USB_PD_VBUS_MEASURE_TCPC) && \ + !defined(CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT) && \ + !defined(CONFIG_USB_PD_VBUS_MEASURE_BY_BOARD) #define CONFIG_USB_PD_VBUS_MEASURE_CHARGER +#endif /* VBUS_MEASURE options */ #ifdef CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT #error CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT defined, but charger can measure -#endif -#endif - +#endif /* VBUS_NOT_PRESENT */ +#endif /* Charger chips */ +#endif /* CONFIG_ZEPHYR */ /*****************************************************************************/ /* * Define CONFIG_USB_PD_VBUS_MEASURE_TCPC if the tcpc on the board supports * VBUS measurement. */ -#if defined(CONFIG_USB_PD_TCPM_FUSB302) +#if defined(CONFIG_USB_PD_TCPM_FUSB302) && \ + !defined(CONFIG_USB_PD_VBUS_MEASURE_CHARGER) #define CONFIG_USB_PD_VBUS_MEASURE_TCPC #endif @@ -6436,14 +6440,6 @@ /*****************************************************************************/ /* - * Define CONFIG_LIBCRYPTOC if a board needs to read secret data from the - * anti-rollback block. - */ -#ifdef CONFIG_ROLLBACK_SECRET_SIZE -#define CONFIG_LIBCRYPTOC -#endif - -/* * Handle task-dependent configs. * * This prevent sub-modules from being compiled when the task and parent module diff --git a/include/hooks.h b/include/hooks.h index a1bb97e55d..ea4eb0b480 100644 --- a/include/hooks.h +++ b/include/hooks.h @@ -222,7 +222,7 @@ enum hook_type { HOOK_POWER_BUTTON_CHANGE, /* - * Battery state of charge changed + * Battery state-of-charge changed * * Hook routines are called from the charger task. */ diff --git a/include/keyboard_8042.h b/include/keyboard_8042.h index bd56106f1d..fbc5bcf073 100644 --- a/include/keyboard_8042.h +++ b/include/keyboard_8042.h @@ -59,4 +59,29 @@ void send_aux_data_to_host_interrupt(uint8_t data); */ void send_aux_data_to_device(uint8_t data); +#ifdef TEST_BUILD + +/** + * @brief Expose function for testing to set typematic scan code + * + * @param scan_code Pointer to byte array with scan code + * @param len Length of scan code in number of bytes + */ +void set_typematic_key(const uint8_t *scan_code, int32_t len); + +/** + * @brief Force-set the resend command buffer for testing. + * + * @param data Pointer to command to copy from + * @param length Number of bytes to copy (capped at MAX_SCAN_CODE_LEN) + */ +__test_only void test_keyboard_8042_set_resend_command(const uint8_t *data, + int length); + +/** + * @brief Reset typematic, RAM, and scancode set for testing purposes. + */ +__test_only void test_keyboard_8042_reset(void); +#endif /* TEST_BUILD */ + #endif /* __CROS_EC_KEYBOARD_8042_H */ diff --git a/include/power.h b/include/power.h index 728903be01..de51b2cfce 100644 --- a/include/power.h +++ b/include/power.h @@ -218,6 +218,17 @@ static inline void power_signal_interrupt(enum gpio_signal signal) #endif /* !CONFIG_AP_POWER_CONTROL */ /** + * Interrupt handler for pwrok signal. This interrupt handler should be used + * when there is a requirement to have minimum pass through delay between the + * pwrok coming to the EC and the pwrok that goes to the PCH for high->low + * transitions. Low->high transitions are still handled from within the chipset + * task power state machine. + * + * @param signal - The gpio signal that triggered the interrupt. + */ +void intel_x86_pwrok_signal_interrupt(enum gpio_signal signal); + +/** * Interrupt handler for rsmrst signal GPIO. This interrupt handler should be * used when there is a requirement to have minimum pass through delay between * the rsmrst coming to the EC and the rsmrst that goes to the PCH for high->low diff --git a/include/system_safe_mode.h b/include/system_safe_mode.h index 6c8909bf43..766d0535af 100644 --- a/include/system_safe_mode.h +++ b/include/system_safe_mode.h @@ -47,13 +47,6 @@ int disable_non_safe_mode_critical_tasks(void); int start_system_safe_mode(void); /** - * Schedules safe mode timeout. - * - * @return EC_SUCCESS or EC_xxx on error - */ -int schedule_system_safe_mode_timeout(void); - -/** * This handler is called when safe mode times out. */ void handle_system_safe_mode_timeout(void); diff --git a/include/usb_pd.h b/include/usb_pd.h index e85c5cc80a..b5981abc46 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -5,6 +5,12 @@ /* USB Power delivery module */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 13 + #ifndef __CROS_EC_USB_PD_H #define __CROS_EC_USB_PD_H diff --git a/power/intel_x86.c b/power/intel_x86.c index 223942f897..5efdf20ce4 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -529,6 +529,27 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) return state; } +#ifdef GPIO_PCH_DSW_PWROK +void intel_x86_pwrok_signal_interrupt(enum gpio_signal signal) +{ + int in = gpio_get_level(GPIO_PG_EC_DSW_PWROK); + int out = gpio_get_level(GPIO_PCH_DSW_PWROK); + + /* + * This function is called when pwrok changes state. If pwrok + * has been asserted (high -> low) then pass this new state to PCH. + */ + if (!in && (in != out)) + gpio_set_level(GPIO_PCH_DSW_PWROK, in); + + /* + * Call the main power signal interrupt handler to wake up the chipset + * task which handles low->high pwrok pass through. + */ + power_signal_interrupt(signal); +} +#endif + void intel_x86_rsmrst_signal_interrupt(enum gpio_signal signal) { int rsmrst_in = gpio_get_level(GPIO_PG_EC_RSMRST_ODL); diff --git a/test/nvidia_gpu.c b/test/nvidia_gpu.c index b660943e04..3e03197e50 100644 --- a/test/nvidia_gpu.c +++ b/test/nvidia_gpu.c @@ -20,8 +20,8 @@ #include <stdio.h> struct d_notify_policy d_notify_policies[] = { - AC_ATLEAST_W(100), AC_ATLEAST_W(65), AC_DC, - DC_ATLEAST_SOC(20), DC_ATLEAST_SOC(5), + AC_ATLEAST_W(100), AC_ATLEAST_W(65), AC_DC, + DC_ATMOST_SOC(20), DC_ATMOST_SOC(5), }; extern enum d_notify_level d_notify_level; diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c index f47e349672..482770ff1c 100644 --- a/test/sbs_charging_v2.c +++ b/test/sbs_charging_v2.c @@ -124,10 +124,10 @@ enum ec_status charger_profile_override_set_param(uint32_t param, test_static int wait_charging_state(void) { - enum charge_state state; + enum led_pwr_state state; task_wake(TASK_ID_CHARGER); msleep(WAIT_CHARGER_TASK); - state = charge_get_state(); + state = led_pwr_get_state(); ccprintf("[CHARGING TEST] state = %d\n", state); return state; } @@ -206,7 +206,7 @@ test_static void ev_clear(int event) test_static int test_charge_state(void) { - enum charge_state state; + enum led_pwr_state state; uint32_t flags; /* On AC */ @@ -504,7 +504,7 @@ test_static int test_external_funcs(void) TEST_ASSERT(!(flags & CHARGE_FLAG_FORCE_IDLE)); /* and the rest */ - TEST_ASSERT(charge_get_state() == PWR_STATE_CHARGE); + TEST_ASSERT(led_pwr_get_state() == PWR_STATE_CHARGE); TEST_ASSERT(!charge_want_shutdown()); TEST_ASSERT(charge_get_percent() == 50); temp = 0; @@ -519,7 +519,7 @@ test_static int test_external_funcs(void) #define CHG_OPT2 0x4000 test_static int test_hc_charge_state(void) { - enum charge_state state; + enum led_pwr_state state; int i, rv, tmp; struct ec_params_charge_state params; struct ec_response_charge_state resp; diff --git a/third_party/rules.mk b/third_party/rules.mk index 888ef41c06..c5075cfd40 100644 --- a/third_party/rules.mk +++ b/third_party/rules.mk @@ -15,10 +15,6 @@ ifeq ($(CONFIG_LIBCRYPTOC),y) # $ make CRYPTOC_DIR=~/src/cryptoc BOARD=bloonchipper CRYPTOC_DIR ?= ../../third_party/cryptoc -# The boringssl path can be overridden on invocation, as in the following -# example: $ make BORINGSSL_DIR=~/src/boringssl BOARD=bloonchipper -BORINGSSL_DIR ?= ../../third_party/boringssl - # SUPPORT_UNALIGNED indicates to libcryptoc that provided data buffers # may be unaligned and please handle them safely. cmd_libcryptoc = $(MAKE) -C $(CRYPTOC_DIR) \ @@ -29,6 +25,39 @@ cmd_libcryptoc_clean = $(cmd_libcryptoc) -q && echo clean CPPFLAGS += -I$(CRYPTOC_DIR)/include CRYPTOC_LDFLAGS := -L$(out)/cryptoc -lcryptoc +# Conditionally force the rebuilding of libcryptoc.a only if it would be +# changed. +# Note, we use ifndef to ensure the likelyhood of rebuilding is much higher. +# For example, if variable cmd_libcryptoc_clean is modified or blank, +# we will rebuild. +ifneq ($(shell $(cmd_libcryptoc_clean)),clean) +.PHONY: $(out)/cryptoc/libcryptoc.a +endif +# Rewrite the CFLAGS include paths to be absolute, since cryptoc is built +# using a different working directory. This is only relevant because +# cryptoc makes use of stdlibs, which EC provides from the builtin/ directory. +$(out)/cryptoc/libcryptoc.a: CFLAGS := $(patsubst -I%,-I$(abspath %),$(CFLAGS)) +$(out)/cryptoc/libcryptoc.a: + +$(call quiet,libcryptoc,MAKE ) + +# Link RO and RW against cryptoc. +$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) +$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: $(out)/cryptoc/libcryptoc.a +$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) +$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(out)/cryptoc/libcryptoc.a + +# Host test executables (including fuzz tests). +$(out)/$(PROJECT).exe: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) +$(out)/$(PROJECT).exe: $(out)/cryptoc/libcryptoc.a + +# On-device tests. +third-party-test-targets=$(foreach test,$(test-list-y),\ + $(out)/RW/$(test).RW.elf $(out)/RO/$(test).RO.elf) +$(third-party-test-targets): LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) +$(third-party-test-targets): $(out)/cryptoc/libcryptoc.a + +endif # CONFIG_LIBCRYPTOC + ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) ifndef CMAKE_SYSTEM_PROCESSOR $(error ERROR: Set CMAKE_SYSTEM_PROCESSOR in core/$(CORE)/toolchain.mk) @@ -37,6 +66,10 @@ ifndef OPENSSL_NO_ASM $(error ERROR: Set OPENSSL_NO_ASM in core/$(CORE)/toolchain.mk) endif +# The boringssl path can be overridden on invocation, as in the following +# example: $ make BORINGSSL_DIR=~/src/boringssl BOARD=bloonchipper +BORINGSSL_DIR ?= ../../third_party/boringssl + BORINGSSL_OUTDIR := $(out)/third_party/boringssl/crypto BORINGSSL_TOOLCHAIN := \ $(shell pwd)/third_party/boringssl/boringssl-toolchain.cmake @@ -69,54 +102,21 @@ CPPFLAGS += -I$(shell pwd)/third_party/boringssl/include # TODO(b/273639386): Remove these workarounds when the upstream supports # better way to disable the filesystem, threads and locks usages. CPPFLAGS += -D__TRUSTY__ -endif - -# Conditionally force the rebuilding of libcryptoc.a only if it would be -# changed. -# Note, we use ifndef to ensure the likelyhood of rebuilding is much higher. -# For example, if variable cmd_libcryptoc_clean is modified or blank, -# we will rebuild. -ifneq ($(shell $(cmd_libcryptoc_clean)),clean) -.PHONY: $(out)/cryptoc/libcryptoc.a -endif -# Rewrite the CFLAGS include paths to be absolute, since cryptoc is built -# using a different working directory. This is only relevant because -# cryptoc makes use of stdlibs, which EC provides from the builtin/ directory. -$(out)/cryptoc/libcryptoc.a: CFLAGS := $(patsubst -I%,-I$(abspath %),$(CFLAGS)) -$(out)/cryptoc/libcryptoc.a: - +$(call quiet,libcryptoc,MAKE ) -# Link RO and RW against cryptoc. -$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) -$(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: $(out)/cryptoc/libcryptoc.a -$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) -$(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(out)/cryptoc/libcryptoc.a -ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) $(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) $(out)/RO/ec.RO.elf $(out)/RO/ec.RO_B.elf: $(BORINGSSL_OUTDIR)/libcrypto.a $(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) $(out)/RW/ec.RW.elf $(out)/RW/ec.RW_B.elf: $(BORINGSSL_OUTDIR)/libcrypto.a -endif -# Host test executables (including fuzz tests). -$(out)/$(PROJECT).exe: LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) -$(out)/$(PROJECT).exe: $(out)/cryptoc/libcryptoc.a -ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) $(out)/$(PROJECT).exe: LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) $(out)/$(PROJECT).exe: $(BORINGSSL_OUTDIR)/libcrypto.a -endif # On-device tests. third-party-test-targets=$(foreach test,$(test-list-y),\ $(out)/RW/$(test).RW.elf $(out)/RO/$(test).RO.elf) -$(third-party-test-targets): LDFLAGS_EXTRA += $(CRYPTOC_LDFLAGS) -$(third-party-test-targets): $(out)/cryptoc/libcryptoc.a -ifeq ($(CONFIG_BORINGSSL_CRYPTO), y) $(third-party-test-targets): LDFLAGS_EXTRA += $(BORINGSSL_LDFLAGS) $(third-party-test-targets): $(BORINGSSL_OUTDIR)/libcrypto.a -endif - -endif # CONFIG_LIBCRYPTOC +endif # CONFIG_BORINGSSL_CRYPTO # Build and link against googletest in *test* builds if configured. ifeq ($(TEST_BUILD),y) diff --git a/util/config_allowed.txt b/util/config_allowed.txt index a469d0c156..e29d35f848 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -79,7 +79,6 @@ CONFIG_BATTERY_BQ27621 CONFIG_BATTERY_BQ4050 CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT CONFIG_BATTERY_CUTOFF_DELAY_US -CONFIG_BATTERY_LEVEL_NEAR_FULL CONFIG_BATTERY_LOW_VOLTAGE_PROTECTION CONFIG_BATTERY_LOW_VOLTAGE_TIMEOUT CONFIG_BATTERY_MAX17055 diff --git a/util/flash_ec b/util/flash_ec index 93406c0793..3d1f949996 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -147,8 +147,8 @@ BITBANG_RATE="57600" # Could be overwritten by a command line option. # Flags DEFINE_integer bitbang_rate "${BITBANG_RATE}" \ - "UART baud rate to use when bit bang programming, "\ -"standard UART rates from 9600 to 57600 are supported." + "UART baud rate to use when bit bang programming, " \ + "standard UART rates from 9600 to 57600 are supported." DEFINE_string board "" \ "The board to run debugger on." DEFINE_string chip "" \ @@ -794,7 +794,7 @@ function servo_save_add() { # Don't save the control with the prefix, because # dut_control will add the prefix again when we restore # the settings. - save=( "${CTRL_RESULT#${DUT_CTRL_PREFIX}}" "${save[@]}" ) + save=( "${CTRL_RESULT#"${DUT_CTRL_PREFIX}"}" "${save[@]}" ) fi ;; 2) save=( "$1:$2" "${save[@]}" ) @@ -850,6 +850,7 @@ function claim_pty() { # reverse order to SIGSTOP parents before children for pid in $(echo "${pids}" | tac -s " "); do + # shellcheck disable=SC2009 if ps -o cmd= "${pid}" | grep -qE "(servod|/sbin/init)"; then info "Skip stopping servod or init: process ${pid}." else diff --git a/util/inject-keys.py b/util/inject-keys.py index 71eb7a3281..8efdb17208 100755 --- a/util/inject-keys.py +++ b/util/inject-keys.py @@ -14,7 +14,7 @@ import subprocess import sys -KEYMATRIX = { +KEYMATRIX_0 = { "`": (3, 1), "1": (6, 1), "2": (6, 4), @@ -90,6 +90,91 @@ KEYMATRIX = { "<left>": (7, 12), } +KEYMATRIX_1 = { + "`": (3, 1), + "1": (7, 1), + "2": (6, 4), + "3": (6, 2), + "4": (6, 3), + "5": (3, 3), + "6": (3, 6), + "7": (6, 6), + "8": (6, 5), + "9": (6, 9), + "0": (0, 9), + "-": (3, 8), + "=": (0, 8), + "q": (6, 12), + "w": (7, 4), + "e": (5, 8), + "r": (7, 3), + "t": (2, 3), + "y": (2, 6), + "u": (7, 6), + "i": (7, 5), + "o": (6, 8), + "p": (7, 8), + "[": (2, 8), + "]": (2, 5), + "\\": (1, 11), + "a": (4, 1), + "s": (5, 6), + "d": (0, 14), + "f": (4, 3), + "g": (1, 3), + "h": (1, 6), + "j": (4, 6), + "k": (4, 5), + "l": (4, 9), + ";": (4, 8), + "'": (1, 8), + "z": (7, 9), + "x": (5, 5), + "c": (7, 13), + "v": (7, 2), + "b": (0, 3), + "n": (0, 6), + "m": (5, 1), + ",": (5, 4), + ".": (5, 9), + "/": (6, 11), + " ": (5, 3), + "<right>": (1, 12), + "<alt_r>": (0, 10), + "<down>": (5, 11), + "<tab>": (6, 1), + "<f10>": (1, 4), + "<shift_r>": (7, 7), + "<ctrl_r>": (4, 0), + "<esc>": (1, 1), + "<backspace>": (7, 11), + "<f2>": (3, 2), + "<alt_l>": (6, 10), + "<ctrl_l>": (2, 0), + "<f1>": (4, 2), + "<search>": (3, 0), + "<f3>": (2, 2), + "<f4>": (1, 2), + "<f5>": (4, 4), + "<f6>": (3, 4), + "<f7>": (2, 4), + "<f8>": (2, 9), + "<f9>": (1, 9), + "<up>": (2, 11), + "<shift_l>": (1, 7), + "<enter>": (4, 11), + "<left>": (0, 12), +} + +# Extensible: when new model comes up in future that deviates from default keyboard matrix, +# and most certainly different from frostflow, new KEYMATRIX_x entry can be defined first, +# and then add an "model_name" : KEYMATRIX_x to here. +MODEL_KBMATRIX_MAP = { + "default_matrix": KEYMATRIX_0, + "frostflow": KEYMATRIX_1, + # "mithrax" is another model that uses same kb matrix with frostflow, + # can add "mithrax" : KEYMATRIX_1 +} UNSHIFT_TABLE = { "~": "`", @@ -120,6 +205,7 @@ for c in string.ascii_lowercase: def inject_event(key, press): + """Function inject_event().""" if len(key) >= 2 and key[0] != "<": key = "<" + key + ">" if key not in KEYMATRIX: @@ -132,11 +218,13 @@ def inject_event(key, press): def inject_key(key): + """Function inject_key().""" inject_event(key, True) inject_event(key, False) def inject_string(string): + """Function inject_string().""" for c in string: if c in KEYMATRIX: inject_key(c) @@ -149,7 +237,20 @@ def inject_string(string): sys.exit(1) +def read_dutmodel(): + """Function read_dutmodel().""" + try: + output = subprocess.check_output( + "cros_config / name", stderr=subprocess.DEVNULL, shell=True + ) + modelstr = str(output, "UTF-8") + except subprocess.SubprocessError: + modelstr = "" + return modelstr + + def usage(): + """Function usage().""" print( "Usage: %s [-s <string>] [-k <key>]" % this_script, "[-p <pressed-key>] [-r <released-key>] ...", @@ -160,6 +261,7 @@ def usage(): def help(): + """Function help().""" usage() print("Valid keys are:") i = 0 @@ -173,6 +275,7 @@ def help(): def usage_check(asserted_condition, message): + """Function usage_check().""" if asserted_condition: return print("%s:" % this_script, message) @@ -198,6 +301,11 @@ for i in range(1, arg_len, 2): "unknown flag: %s" % sys.argv[i], ) +KEYMATRIX = KEYMATRIX_0 +model = read_dutmodel() +if model in MODEL_KBMATRIX_MAP: + KEYMATRIX = MODEL_KBMATRIX_MAP[model] + for i in range(1, arg_len, 2): flag = sys.argv[i] arg = sys.argv[i + 1] diff --git a/util/preupload/lib.py b/util/preupload/lib.py index 87a1226507..ced5f2a980 100644 --- a/util/preupload/lib.py +++ b/util/preupload/lib.py @@ -30,5 +30,5 @@ def argument_parser(): """Returns an ArgumentParser with standard options configured.""" parser = argparse.ArgumentParser() parser.add_argument("-c", "--commit", default=PRE_SUBMIT) - parser.add_argument("filename", nargs="+", type=Path) + parser.add_argument("filename", nargs="*", type=Path) return parser diff --git a/util/uut/main.cc b/util/uut/main.cc index 7f7923b2bf..df34191acc 100644 --- a/util/uut/main.cc +++ b/util/uut/main.cc @@ -141,6 +141,12 @@ const static struct npcx_chip_info chip_info[] = { .chip_id = 0x09, .flash_size = 512 * 1024, }, + { + /* NPCX997F */ + .device_id = 0x22, + .chip_id = 0x09, + .flash_size = 1024 * 1024, + }, }; /*--------------------------------------------------------------------------- * Functions prototypes diff --git a/zephyr/Kconfig.charger b/zephyr/Kconfig.charger index 7c50f9fe31..e147d07a3c 100644 --- a/zephyr/Kconfig.charger +++ b/zephyr/Kconfig.charger @@ -71,6 +71,16 @@ config PLATFORM_EC_CHARGE_STATE_DEBUG this config will allow the EC_CMD_CHARGE_STATE host command to use the CHARGE_STATE_CMD_GET_PARAM command to query the current charge state. +config PLATFORM_EC_CHARGE_DEBUG + bool "Add a debug sub-command to the 'chgstate' command" + depends on PLATFORM_EC_CHARGE_MANAGER + default y + help + Enables the 'chgstate debug' command which allows extra debugging to + be shown when charging, or when a separate base (with battery) is + used. This adds a little to the code size, but can normally be safely + enabled. + config PLATFORM_EC_CMD_PWR_AVG bool "Enable the console command to print power average" depends on PLATFORM_EC_CHARGE_MANAGER diff --git a/zephyr/Kconfig.temperature b/zephyr/Kconfig.temperature index 84e65907e4..37a62185e2 100644 --- a/zephyr/Kconfig.temperature +++ b/zephyr/Kconfig.temperature @@ -110,6 +110,8 @@ config PLATFORM_EC_FAN available. Also enables a periodic task (1s) to verify fan is running (is not stalled). +if PLATFORM_EC_FAN + config PLATFORM_EC_CUSTOM_FAN_CONTROL bool "Fan custom control support" default n @@ -125,7 +127,6 @@ config PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL their own fan duty control mechanism by implementing the routine board_override_fan_control_duty(). -if PLATFORM_EC_FAN config PLATFORM_EC_NUM_FANS int "Number of fans" diff --git a/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts b/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts index 73d3b8e3f3..0995127bdb 100644 --- a/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts +++ b/zephyr/boards/riscv/it8xxx2/it82202ax-512.dts @@ -31,5 +31,6 @@ }; }; }; + pad-after = <0>; }; }; diff --git a/zephyr/dts/bindings/battery/battery-smart.yaml b/zephyr/dts/bindings/battery/battery-smart.yaml index 75a1bdcac5..9c48620186 100644 --- a/zephyr/dts/bindings/battery/battery-smart.yaml +++ b/zephyr/dts/bindings/battery/battery-smart.yaml @@ -20,6 +20,7 @@ properties: - "byd,x0y5m" - "byd,wv3k8" - "cdt,c340152" + - "celxpert,b300049" - "celxpert,c235-41" - "celxpert,l22c3pg0" - "cosmx,ap20cbl" diff --git a/zephyr/dts/bindings/battery/celxpert_b300049.yaml b/zephyr/dts/bindings/battery/celxpert_b300049.yaml new file mode 100644 index 0000000000..eb16ee69f6 --- /dev/null +++ b/zephyr/dts/bindings/battery/celxpert_b300049.yaml @@ -0,0 +1,59 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: "Celxpert B300049" +compatible: "celxpert,b300049" + +include: battery-smart.yaml + +properties: + enum-name: + type: string + default: "celxpert,b300049" + + # Fuel gauge + manuf_name: + default: "AS3FXXE3KA" + device_name: + default: "B300049" + ship_mode_reg_addr: + default: 0x00 + ship_mode_reg_data: + default: [0x10, 0x10] + # Charging/Discharging FETs Status + # Register SBS_PackStatus_ACCESS (0x99) + # Bit-3: XDSG + # Bit-2: XCHG + fet_reg_addr: + default: 0x99 + fet_reg_mask: + default: 0x08 + fet_disconnect_val: + default: 0x08 + fet_cfet_mask: + default: 0x04 + fet_cfet_off_val: + default: 0x04 + + # Battery info + voltage_max: + default: 8800 + voltage_normal: + default: 7920 + voltage_min: + default: 6000 + precharge_current: + default: 256 + start_charging_min_c: + default: 0 + start_charging_max_c: + default: 45 + charging_min_c: + default: 0 + charging_max_c: + default: 60 + discharging_min_c: + default: -20 + discharging_max_c: + default: 60 diff --git a/zephyr/dts/bindings/battery/gfl,mfp-549358.yaml b/zephyr/dts/bindings/battery/gfl,mfp-549358.yaml index 9f044fd443..1cf4181b58 100644 --- a/zephyr/dts/bindings/battery/gfl,mfp-549358.yaml +++ b/zephyr/dts/bindings/battery/gfl,mfp-549358.yaml @@ -18,17 +18,17 @@ properties: ship_mode_reg_data: default: [0x0010, 0x0010] fet_mfgacc_support: - default: 0 + default: 1 fet_reg_addr: - default: 0x43 + default: 0x54 fet_reg_mask: - default: 0x0001 + default: 0x0006 fet_disconnect_val: default: 0x0000 fet_cfet_mask: - default: 0x0002 + default: 0x4000 fet_cfet_off_val: - default: 0x0000 + default: 0x4000 # Battery info voltage_max: diff --git a/zephyr/dts/bindings/emul/zephyr,icm42607-emul.yaml b/zephyr/dts/bindings/emul/zephyr,icm42607-emul.yaml new file mode 100644 index 0000000000..c3bffa33c8 --- /dev/null +++ b/zephyr/dts/bindings/emul/zephyr,icm42607-emul.yaml @@ -0,0 +1,9 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: Zephyr ICM42607 Emulator + +compatible: "zephyr,icm42607-emul" + +include: base.yaml diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index 65daeafbde..018ac8421f 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi260.c) zephyr_library_sources_ifdef(CONFIG_EMUL_CLOCK_CONTROL emul_clock_control.c) zephyr_library_sources_ifdef(CONFIG_EMUL_COMMON_I2C emul_common_i2c.c) zephyr_library_sources_ifdef(CONFIG_EMUL_CROS_FLASH emul_flash.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_ICM42607 emul_icm42607.c) zephyr_library_sources_ifdef(CONFIG_EMUL_ISL923X emul_isl923x.c) zephyr_library_sources_ifdef(CONFIG_EMUL_CHARGER_ISL9241 emul_isl9241.c) zephyr_library_sources_ifdef(CONFIG_EMUL_KB_RAW emul_kb_raw.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index 78e4a88a1d..756a1530cf 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -210,6 +210,14 @@ config EMUL_PS8743 Enable the PS8743 usb mux. This driver use emulated I2C bus. Emulator API is available in zephyr/include/emul/emul_ps8743.h. +config EMUL_ICM42607 + bool "icm42607 emulator" + default y + depends on DT_HAS_ZEPHYR_ICM42607_EMUL_ENABLED + select EMUL_COMMON_I2C + help + Enable the ICM42607 accelerometer and gyroscope emulator. + rsource "Kconfig.ln9310" rsource "Kconfig.lis2dw12" rsource "Kconfig.i2c_mock" diff --git a/zephyr/emul/emul_icm42607.c b/zephyr/emul/emul_icm42607.c new file mode 100644 index 0000000000..62576d6027 --- /dev/null +++ b/zephyr/emul/emul_icm42607.c @@ -0,0 +1,222 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "driver/accelgyro_icm42607.h" +#include "emul/emul_icm42607.h" +#include "emul/emul_stub_device.h" +#include "queue.h" +#include "util.h" + +#include <zephyr/device.h> + +#define DT_DRV_COMPAT zephyr_icm42607_emul + +#define REG_MAX 255 + +struct icm42607_data { + struct i2c_common_emul_data common; + uint8_t user_bank_0[REG_MAX + 1]; + uint8_t mreg1[REG_MAX + 1]; + uint8_t mreg2[REG_MAX + 1]; + struct queue fifo; +}; + +static const uint8_t user_bank_0_default_values[REG_MAX + 1] = { + [ICM42607_REG_MCLK_RDY] = ICM42607_MCLK_RDY, /* always powered on */ + [ICM42607_REG_WHO_AM_I] = ICM42607_CHIP_ICM42607P, + [ICM42607_REG_INTF_CONFIG0] = 0x30, /* big endian by default */ +}; +static const uint8_t mreg1_default_values[REG_MAX + 1] = {}; +static const uint8_t mreg2_default_values[REG_MAX + 1] = {}; + +static void icm42607_emul_fifo_flush(const struct emul *emul) +{ + struct icm42607_data *data = emul->data; + uint8_t unused; + + while (queue_remove_unit(&data->fifo, &unused) == 1) + ; +} + +void icm42607_emul_reset(const struct emul *emul) +{ + struct icm42607_data *data = emul->data; + + memcpy(data->user_bank_0, user_bank_0_default_values, REG_MAX + 1); + memcpy(data->mreg1, mreg1_default_values, REG_MAX + 1); + memcpy(data->mreg2, mreg2_default_values, REG_MAX + 1); + icm42607_emul_fifo_flush(emul); +} + +int icm42607_emul_peek_reg(const struct emul *emul, int reg) +{ + struct icm42607_data *data = emul->data; + uint8_t *regs = data->user_bank_0; + + if (!IN_RANGE(reg, 0, REG_MAX)) { + return -1; + } + return regs[reg]; +} + +int icm42607_emul_write_reg(const struct emul *emul, int reg, int val) +{ + struct icm42607_data *data = emul->data; + uint8_t *regs = data->user_bank_0; + + if (!IN_RANGE(reg, 0, REG_MAX)) { + return -1; + } + + regs[reg] = val; + + return 0; +} + +void icm42607_emul_push_fifo(const struct emul *emul, const uint8_t *src, + int size) +{ + struct icm42607_data *data = emul->data; + struct queue *fifo = &data->fifo; + + queue_add_units(fifo, src, size); +} + +static int icm42607_emul_read(const struct emul *emul, int reg, uint8_t *val, + int bytes, void *unused_data) +{ + struct icm42607_data *data = emul->data; + uint8_t *regs = data->user_bank_0; + int pos = reg + bytes; + + if (!IN_RANGE(pos, 0, REG_MAX)) { + return -1; + } + + if (reg == ICM42607_REG_FIFO_COUNT) { + int fifo_count = queue_count(&data->fifo); + + if (bytes == 0) { + *val = fifo_count & 0xff; + } else { + *val = (fifo_count >> 8) & 0xff; + } + + return bytes < 2 ? 0 : -1; + } + + if (reg == ICM42607_REG_FIFO_DATA) { + return queue_remove_unit(&data->fifo, val) == 1 ? 0 : -1; + } + + if (pos == ICM42607_REG_M_R) { + int block_sel = regs[ICM42607_REG_BLK_SEL_R]; + int mreg_addr = regs[ICM42607_REG_MADDR_R]; + + if (!IN_RANGE(mreg_addr, 0, REG_MAX)) { + return -1; + } + + if (block_sel == 0) { + *val = data->mreg1[mreg_addr]; + return 0; + } + if (block_sel == 0x28) { + *val = data->mreg2[mreg_addr]; + return 0; + } + + return -1; + } + + *val = regs[pos]; + + return 0; +} + +static int icm42607_emul_write(const struct emul *emul, int reg, uint8_t val, + int bytes, void *unused_data) +{ + struct icm42607_data *data = emul->data; + uint8_t *regs = data->user_bank_0; + int pos = reg + bytes - 1; + + if (!IN_RANGE(pos, 0, REG_MAX) || !IN_RANGE(val, 0, UINT8_MAX)) { + return -1; + } + + if (reg == ICM42607_REG_SIGNAL_PATH_RESET) { + if (bytes == 1 && (val & ICM42607_FIFO_FLUSH)) { + icm42607_emul_fifo_flush(emul); + } + return 0; + } + + if (pos == ICM42607_REG_M_W) { + int block_sel = regs[ICM42607_REG_BLK_SEL_W]; + int mreg_addr = regs[ICM42607_REG_MADDR_W]; + + if (!IN_RANGE(mreg_addr, 0, REG_MAX)) { + return -1; + } + + if (block_sel == 0) { + data->mreg1[mreg_addr] = val; + return 0; + } + if (block_sel == 0x28) { + data->mreg2[mreg_addr] = val; + return 0; + } + + return -1; + } + + regs[pos] = val; + + return 0; +} + +static int icm42607_emul_init(const struct emul *emul, + const struct device *parent) +{ + struct icm42607_data *data = (struct icm42607_data *)emul->data; + struct i2c_common_emul_data *common_data = &data->common; + + i2c_common_emul_init(common_data); + i2c_common_emul_set_read_func(common_data, icm42607_emul_read, NULL); + i2c_common_emul_set_write_func(common_data, icm42607_emul_write, NULL); + + icm42607_emul_reset(emul); + + return 0; +} + +struct i2c_common_emul_data * +emul_icm42607_get_i2c_common_data(const struct emul *emul) +{ + struct icm42607_data *data = (struct icm42607_data *)emul->data; + + return &data->common; +} + +#define INIT_ICM42607_EMUL(n) \ + static struct i2c_common_emul_cfg common_cfg_##n; \ + static struct icm42607_data icm42607_data_##n; \ + static struct i2c_common_emul_cfg common_cfg_##n = { \ + .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \ + .data = &icm42607_data_##n.common, \ + .addr = DT_INST_REG_ADDR(n) \ + }; \ + static struct icm42607_data icm42607_data_##n = { \ + .common = { .cfg = &common_cfg_##n }, \ + .fifo = QUEUE_NULL(1024, uint8_t), \ + }; \ + EMUL_DT_INST_DEFINE(n, icm42607_emul_init, &icm42607_data_##n, \ + &common_cfg_##n, &i2c_common_emul_api, NULL) + +DT_INST_FOREACH_STATUS_OKAY(INIT_ICM42607_EMUL) + +DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE); diff --git a/zephyr/include/dt-bindings/battery.h b/zephyr/include/dt-bindings/battery.h index 24ffb2082c..af7ee8aa11 100644 --- a/zephyr/include/dt-bindings/battery.h +++ b/zephyr/include/dt-bindings/battery.h @@ -14,7 +14,6 @@ #define BATTERY_LEVEL_SHUTDOWN 3 #define BATTERY_LEVEL_CRITICAL 5 #define BATTERY_LEVEL_LOW 10 -#define BATTERY_LEVEL_NEAR_FULL 97 #define BATTERY_LEVEL_FULL 100 /* Battery status */ diff --git a/zephyr/include/dt-bindings/cros-kb-raw/ite_cros_kb_raw.h b/zephyr/include/dt-bindings/cros-kb-raw/ite_cros_kb_raw.h deleted file mode 100644 index 53769f5dbf..0000000000 --- a/zephyr/include/dt-bindings/cros-kb-raw/ite_cros_kb_raw.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright 2021 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_ITE_CROS_KB_RAW_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_ITE_CROS_KB_RAW_H_ - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_ITE_CROS_KB_RAW_H_ */ diff --git a/zephyr/include/dt-bindings/cros-kb-raw/mchp_cros_kb_raw.h b/zephyr/include/dt-bindings/cros-kb-raw/mchp_cros_kb_raw.h deleted file mode 100644 index b520e154da..0000000000 --- a/zephyr/include/dt-bindings/cros-kb-raw/mchp_cros_kb_raw.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright 2022 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_MCHP_CROS_KB_RAW_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_MCHP_CROS_KB_RAW_H_ - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_MCHP_CROS_KB_RAW_H_ */ diff --git a/zephyr/include/dt-bindings/cros-kb-raw/npcx_cros_kb_raw.h b/zephyr/include/dt-bindings/cros-kb-raw/npcx_cros_kb_raw.h deleted file mode 100644 index f979ae8481..0000000000 --- a/zephyr/include/dt-bindings/cros-kb-raw/npcx_cros_kb_raw.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2020 Google LLC - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_NPCX_CROS_KB_RAW_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_NPCX_CROS_KB_RAW_H_ - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CROS_KB_RAW_NPCX_CROS_KB_RAW_H_ */ diff --git a/zephyr/include/emul/emul_icm42607.h b/zephyr/include/emul/emul_icm42607.h new file mode 100644 index 0000000000..b1c331a58c --- /dev/null +++ b/zephyr/include/emul/emul_icm42607.h @@ -0,0 +1,27 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef EMUL_ICM42607_H +#define EMUL_ICM42607_H + +#include "emul/emul_common_i2c.h" + +#include <stdint.h> + +#include <zephyr/drivers/emul.h> + +void icm42607_emul_reset(const struct emul *emul); + +int icm42607_emul_peek_reg(const struct emul *emul, int reg); + +int icm42607_emul_write_reg(const struct emul *emul, int reg, int val); + +void icm42607_emul_push_fifo(const struct emul *emul, const uint8_t *src, + int size); + +struct i2c_common_emul_data * +emul_icm42607_get_i2c_common_data(const struct emul *emul); + +#endif diff --git a/zephyr/program/corsola/magikarp/project.overlay b/zephyr/program/corsola/magikarp/project.overlay index 3628f6770d..349e066f07 100644 --- a/zephyr/program/corsola/magikarp/project.overlay +++ b/zephyr/program/corsola/magikarp/project.overlay @@ -224,8 +224,7 @@ bat-power-state-charge { charge-state = "PWR_STATE_CHARGE"; /* Battery percent range (>= Empty, <= 94%) */ - batt-lvl = <BATTERY_LEVEL_EMPTY - (BATTERY_LEVEL_NEAR_FULL - 3)>; + batt-lvl = <BATTERY_LEVEL_EMPTY 94>; color-0 { led-color = <&color_battery_amber>; }; @@ -234,8 +233,7 @@ bat-power-state-charge-near-full { charge-state = "PWR_STATE_CHARGE"; /* Battery percent range (>= 95%, <= Full) */ - batt-lvl = <(BATTERY_LEVEL_NEAR_FULL - 2) - BATTERY_LEVEL_FULL>; + batt-lvl = <95 BATTERY_LEVEL_FULL>; color-0 { led-color = <&color_battery_white>; }; diff --git a/zephyr/program/corsola/src/npcx_usbc.c b/zephyr/program/corsola/src/npcx_usbc.c index 10a977696e..2e1d8d11c5 100644 --- a/zephyr/program/corsola/src/npcx_usbc.c +++ b/zephyr/program/corsola/src/npcx_usbc.c @@ -11,6 +11,7 @@ #endif #include "baseboard_usbc_config.h" +#include "battery.h" #include "console.h" #include "driver/ppc/nx20p348x.h" #include "driver/tcpm/anx7447.h" @@ -53,8 +54,10 @@ DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); void board_tcpc_init(void) { - /* Only reset TCPC if not sysjump */ - if (!system_jumped_late()) { + /* Reset TCPC if we only we have a battery connected, or the SINK + * gpio to the PPC might be reset and cause brown-out. + */ + if (!system_jumped_late() && battery_is_present() == BP_YES) { /* TODO(crosbug.com/p/61098): How long do we need to wait? */ board_reset_pd_mcu(); } @@ -84,7 +87,13 @@ __override int board_rt1718s_init(int port) { static bool gpio_initialized; - if (!system_jumped_late() && !gpio_initialized) { + /* Reset TCPC sink/source control when it's a power-on reset or has a + * battery. Do not alter the carried GPIO status or this might stop PPC + * sinking and brown-out the system when battery disconnected. + */ + if (!system_jumped_late() && !gpio_initialized && + (battery_is_present() == BP_YES || + (system_get_reset_flags() & EC_RESET_FLAG_POWER_ON))) { /* set GPIO 1~3 as push pull, as output, output low. */ rt1718s_gpio_set_flags(port, RT1718S_GPIO1, GPIO_OUT_LOW); rt1718s_gpio_set_flags(port, RT1718S_GPIO2, GPIO_OUT_LOW); @@ -94,11 +103,18 @@ __override int board_rt1718s_init(int port) /* 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, + RT1718S_GPIO_VBUS_CTRL_FRS_RX_VBUS, 0)); - RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO2_VBUS_CTRL, - RT1718S_GPIO2_VBUS_CTRL_FRS_RX_VBUS, - 0xFF)); + /* GPIO1 EN_SNK high when received TCPCI SNK enabled command */ + RETURN_ERROR(rt1718s_update_bits8( + port, RT1718S_GPIO1_VBUS_CTRL, + RT1718S_GPIO_VBUS_CTRL_ENA_SNK_VBUS_GPIO, 0xFF)); + /* GPIO2 EN_SRC high when received TCPCI SRC enabled command */ + RETURN_ERROR(rt1718s_update_bits8( + port, RT1718S_GPIO2_VBUS_CTRL, + RT1718S_GPIO_VBUS_CTRL_FRS_RX_VBUS | + RT1718S_GPIO_VBUS_CTRL_ENA_SRC_VBUS_GPIO, + 0xFF)); /* Trigger GPIO 1/2 change when FRS signal received */ RETURN_ERROR(rt1718s_update_bits8( diff --git a/zephyr/program/corsola/src/usbc.c b/zephyr/program/corsola/src/usbc.c index 181b3df141..71c02ff54f 100644 --- a/zephyr/program/corsola/src/usbc.c +++ b/zephyr/program/corsola/src/usbc.c @@ -6,7 +6,7 @@ /* Corsola baseboard-specific USB-C configuration */ #include "baseboard_usbc_config.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "console.h" #include "ec_commands.h" #include "extpower.h" diff --git a/zephyr/program/corsola/starmie/project.overlay b/zephyr/program/corsola/starmie/project.overlay index d8c6a48631..2358026e2d 100644 --- a/zephyr/program/corsola/starmie/project.overlay +++ b/zephyr/program/corsola/starmie/project.overlay @@ -20,8 +20,8 @@ / { batteries { - default_battery: c235 { - compatible = "celxpert,c235-41", "battery-smart"; + default_battery: b300049 { + compatible = "celxpert,b300049", "battery-smart"; }; }; gpio-interrupts { diff --git a/zephyr/program/corsola/tentacruel/project.overlay b/zephyr/program/corsola/tentacruel/project.overlay index 79e8f4a05b..e23d3561e8 100644 --- a/zephyr/program/corsola/tentacruel/project.overlay +++ b/zephyr/program/corsola/tentacruel/project.overlay @@ -270,8 +270,7 @@ bat-power-state-charge { charge-state = "PWR_STATE_CHARGE"; /* Battery percent range (>= Empty, <= 94%) */ - batt-lvl = <BATTERY_LEVEL_EMPTY - (BATTERY_LEVEL_NEAR_FULL - 3)>; + batt-lvl = <BATTERY_LEVEL_EMPTY 94>; color-0 { led-color = <&color_battery_amber>; }; @@ -280,8 +279,7 @@ bat-power-state-charge-near-full { charge-state = "PWR_STATE_CHARGE"; /* Battery percent range (>= 95%, <= Full) */ - batt-lvl = <(BATTERY_LEVEL_NEAR_FULL - 2) - BATTERY_LEVEL_FULL>; + batt-lvl = <95 BATTERY_LEVEL_FULL>; color-0 { led-color = <&color_battery_white>; }; diff --git a/zephyr/program/corsola/tentacruel/src/temp.c b/zephyr/program/corsola/tentacruel/src/temp.c index 2e584640be..72fcc526bd 100644 --- a/zephyr/program/corsola/tentacruel/src/temp.c +++ b/zephyr/program/corsola/tentacruel/src/temp.c @@ -62,7 +62,7 @@ static void current_update(void) temp = average_tempature(); #ifndef CONFIG_TEST - if (charge_get_state() == PWR_STATE_DISCHARGE) { + if (led_pwr_get_state() == PWR_STATE_DISCHARGE) { current_level = 0; uptime = 0; dntime = 0; diff --git a/zephyr/program/corsola/voltorb/project.conf b/zephyr/program/corsola/voltorb/project.conf index 3cb4f46e06..d2693d0de8 100644 --- a/zephyr/program/corsola/voltorb/project.conf +++ b/zephyr/program/corsola/voltorb/project.conf @@ -41,6 +41,7 @@ CONFIG_PLATFORM_EC_EXTPOWER_DEBOUNCE_MS=800 # Battery config CONFIG_PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV=15000 +CONFIG_PLATFORM_EC_SMART_BATTERY_OPTIONAL_MFG_FUNC=y # Remove debug options and features for FW QUAL CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=n diff --git a/zephyr/program/corsola/voltorb/project.overlay b/zephyr/program/corsola/voltorb/project.overlay index 7ae230a47e..e5c5df3ab7 100644 --- a/zephyr/program/corsola/voltorb/project.overlay +++ b/zephyr/program/corsola/voltorb/project.overlay @@ -81,17 +81,26 @@ compatible = "cros-ec,led-policy"; /* Voltorb LED bat charge */ - bat-power-state-charge { + bat-power-state-charge-lvl-1 { charge-state = "PWR_STATE_CHARGE"; /* Battery percent range (>= Empty, <= 96%) */ - batt-lvl = <BATTERY_LEVEL_EMPTY - (BATTERY_LEVEL_NEAR_FULL - 1)>; + batt-lvl = <BATTERY_LEVEL_EMPTY 96>; color-0 { led-color = <&color_amber>; }; }; + bat-power-state-charge-lvl-2 { + charge-state = "PWR_STATE_CHARGE"; + /* Battery percent range (>= 97, <= 100%) */ + batt-lvl = <97 100>; + + color-0 { + led-color = <&color_blue>; + }; + }; + /* Voltorb LED bat charge near full */ bat-power-state-charge-near-full { charge-state = "PWR_STATE_CHARGE_NEAR_FULL"; diff --git a/zephyr/program/geralt/src/usbc_config.c b/zephyr/program/geralt/src/usbc_config.c index 64a55ffb75..f0c56c5a8b 100644 --- a/zephyr/program/geralt/src/usbc_config.c +++ b/zephyr/program/geralt/src/usbc_config.c @@ -6,7 +6,7 @@ /* Geralt baseboard-specific USB-C configuration */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "console.h" #include "driver/tcpm/it83xx_pd.h" #include "gpio.h" diff --git a/zephyr/program/intelrvp/adlrvp/prj.conf b/zephyr/program/intelrvp/adlrvp/prj.conf index 9c372bc9ae..ef0584c4bd 100644 --- a/zephyr/program/intelrvp/adlrvp/prj.conf +++ b/zephyr/program/intelrvp/adlrvp/prj.conf @@ -40,7 +40,6 @@ CONFIG_PLATFORM_EC_TEMP_SENSOR_POWER=y CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC=y CONFIG_PLATFORM_EC_USB_PD_DUAL_ROLE_AUTO_TOGGLE=n CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y -CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_TCPC=y CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n CONFIG_PLATFORM_EC_USBC_RETIMER_INTEL_BB_RUNTIME_CONFIG=n CONFIG_PLATFORM_EC_USB_MUX_TUSB1044=y diff --git a/zephyr/program/intelrvp/mtlrvp/prj.conf b/zephyr/program/intelrvp/mtlrvp/prj.conf index ccc27e04f7..8fe89d712a 100644 --- a/zephyr/program/intelrvp/mtlrvp/prj.conf +++ b/zephyr/program/intelrvp/mtlrvp/prj.conf @@ -46,6 +46,7 @@ CONFIG_PLATFORM_EC_USBC_PPC=y CONFIG_PLATFORM_EC_USB_PD_PPC=y CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_PPC=y CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_PPC=y CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=y CONFIG_PLATFORM_EC_USB_PD_TCPC_LOW_POWER=y diff --git a/zephyr/program/intelrvp/src/chg_usb_pd.c b/zephyr/program/intelrvp/src/chg_usb_pd.c index 084617cb98..1b2c1a8736 100644 --- a/zephyr/program/intelrvp/src/chg_usb_pd.c +++ b/zephyr/program/intelrvp/src/chg_usb_pd.c @@ -6,7 +6,7 @@ /* Common USB PD charge configuration */ #include "charge_manager.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "gpio.h" #include "hooks.h" #include "intelrvp.h" diff --git a/zephyr/program/intelrvp/src/intel_rvp_led.c b/zephyr/program/intelrvp/src/intel_rvp_led.c index 0e4d872963..91af0dfb55 100644 --- a/zephyr/program/intelrvp/src/intel_rvp_led.c +++ b/zephyr/program/intelrvp/src/intel_rvp_led.c @@ -80,7 +80,7 @@ static void pulse_leds(enum pwm_led_id id, int period) static void update_charger_led(enum pwm_led_id id) { - enum charge_state chg_st = charge_get_state(); + enum led_pwr_state chg_st = led_pwr_get_state(); /* * The colors listed below are the default, but can be overridden. diff --git a/zephyr/program/myst/CMakeLists.txt b/zephyr/program/myst/CMakeLists.txt index c339dbeef7..ece440da75 100644 --- a/zephyr/program/myst/CMakeLists.txt +++ b/zephyr/program/myst/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.20.5) find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}") +cros_ec_library_include_directories(include) zephyr_library_sources("src/common.c") zephyr_library_sources("src/power_signals.c") diff --git a/zephyr/program/myst/i2c.dtsi b/zephyr/program/myst/i2c.dtsi index 58ba31911b..905cbc7f80 100644 --- a/zephyr/program/myst/i2c.dtsi +++ b/zephyr/program/myst/i2c.dtsi @@ -76,15 +76,16 @@ tcpc_port0: rt1716@70 { compatible = "richtek,rt1716"; reg = <0x70>; - tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>; - /* TBD */ + tcpc-flags = <( + TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V)>; irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>; }; - ppc_port0: ktu1125@78 { + ppc_port0: ktu1125@38 { compatible = "kinetic,ktu1125"; status = "okay"; - reg = <0x78>; + reg = <0x38>; }; }; @@ -105,7 +106,7 @@ reg = <0x40>; }; - tcpc_port1: rt1718s-tcpc@40 { + tcpc_rt1718_port1: rt1718s-tcpc@40 { compatible = "richtek,rt1718s-tcpc"; reg = <0x40>; tcpc-flags = <( @@ -117,15 +118,28 @@ * the "named-gpios" node will be dealt with at a later date. */ irq-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + is-alt; }; - ppc_port1: nx20p348x@71 { + ppc_nx20p_port1: nx20p348x@71 { compatible = "nxp,nx20p348x"; status = "okay"; reg = <0x71>; + is-alt; + }; + + tcpc_ps8815_port1: ps8xxx@b { + compatible = "parade,ps8xxx"; + reg = <0xb>; + is-alt; }; - /* TODO: add SKU-B DB b/275610001 */ + ppc_ktu1125_port1: ktu1125@38 { + compatible = "kinetic,ktu1125"; + status = "okay"; + reg = <0x38>; + is-alt; + }; }; &i2c_ctrl1 { diff --git a/zephyr/program/myst/include/usbc_config.h b/zephyr/program/myst/include/usbc_config.h new file mode 100644 index 0000000000..1c983ba8e9 --- /dev/null +++ b/zephyr/program/myst/include/usbc_config.h @@ -0,0 +1,20 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Myst type-c definitions */ + +#ifndef __CROS_EC_USBC_CONFIG_H +#define __CROS_EC_USBC_CONFIG_H + +void ppc_interrupt(enum gpio_signal signal); + +/* USB-A ports */ +enum usba_port { USBA_PORT_A0 = 0, USBA_PORT_A1, USBA_PORT_COUNT }; + +/* USB-C ports */ +enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; +BUILD_ASSERT(USBC_PORT_COUNT == CONFIG_USB_PD_PORT_MAX_COUNT); + +#endif /* __CROS_EC_USBC_CONFIG_H */ diff --git a/zephyr/program/myst/myst/CMakeLists.txt b/zephyr/program/myst/myst/CMakeLists.txt index 9dc79f913e..09e319e8c4 100644 --- a/zephyr/program/myst/myst/CMakeLists.txt +++ b/zephyr/program/myst/myst/CMakeLists.txt @@ -4,6 +4,6 @@ cros_ec_library_include_directories_ifdef(CONFIG_BOARD_MYST include) zephyr_library_sources( - "src/ppc_config.c" "src/keyboard.c" + "src/usb_mux_config.c" ) diff --git a/zephyr/program/myst/myst/src/ppc_config.c b/zephyr/program/myst/myst/src/ppc_config.c deleted file mode 100644 index a16e38a25d..0000000000 --- a/zephyr/program/myst/myst/src/ppc_config.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Myst board-specific PPC code */ - -#include "driver/ppc/aoz1380_public.h" -#include "driver/ppc/nx20p348x.h" -#include "usbc_ppc.h" - -#include <zephyr/drivers/gpio.h> - -#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ##args) -#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ##args) - -void ppc_interrupt(enum gpio_signal signal) -{ - switch (signal) { - case GPIO_USB_C0_PPC_INT_ODL: - break; - - case GPIO_USB_C1_PPC_INT_ODL: - break; - - default: - break; - } -} diff --git a/zephyr/program/myst/myst/src/usb_mux_config.c b/zephyr/program/myst/myst/src/usb_mux_config.c new file mode 100644 index 0000000000..561202fd23 --- /dev/null +++ b/zephyr/program/myst/myst/src/usb_mux_config.c @@ -0,0 +1,92 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Myst board-specific USB-C mux configuration */ + +#include "console.h" +#include "cros_board_info.h" +#include "cros_cbi.h" +#include "hooks.h" +#include "usb_mux.h" +#include "usbc/ppc.h" +#include "usbc/tcpci.h" +#include "usbc/usb_muxes.h" +#include "usbc_config.h" + +#include <zephyr/drivers/gpio.h> +#include <zephyr/logging/log.h> + +LOG_MODULE_DECLARE(myst, CONFIG_MYST_LOG_LEVEL); + +uint32_t get_io_db_type_from_cached_cbi(void) +{ + uint32_t io_db_type; + int ret = cros_cbi_get_fw_config(FW_IO_DB, &io_db_type); + + if (ret != 0) { + io_db_type = FW_IO_DB_NONE; + LOG_ERR("Failed to get IO_DB value: %d", ret); + } + + return io_db_type; +} + +__override uint8_t board_get_usb_pd_port_count(void) +{ + if (get_io_db_type_from_cached_cbi() == FW_IO_DB_NONE) + return CONFIG_USB_PD_PORT_MAX_COUNT - 1; + else + return CONFIG_USB_PD_PORT_MAX_COUNT; +} + +void ppc_interrupt(enum gpio_signal signal) +{ + uint32_t io_db_type = get_io_db_type_from_cached_cbi(); + + switch (signal) { + case GPIO_USB_C0_PPC_INT_ODL: + ktu1125_interrupt(USBC_PORT_C0); + break; + + case GPIO_USB_C1_PPC_INT_ODL: + if (io_db_type == FW_IO_DB_SKU_A) { + nx20p348x_interrupt(USBC_PORT_C1); + } + if (io_db_type == FW_IO_DB_SKU_B) { + ktu1125_interrupt(USBC_PORT_C1); + } + break; + + default: + break; + } +} + +static void setup_mux(void) +{ + switch (get_io_db_type_from_cached_cbi()) { + default: + case FW_IO_DB_NONE: + LOG_INF("USB DB: not connected"); + break; + + case FW_IO_DB_SKU_A: + LOG_INF("USB DB: Setting SKU_A DB"); + TCPC_ENABLE_ALTERNATE_BY_NODELABEL(USBC_PORT_C1, + tcpc_rt1718_port1); + PPC_ENABLE_ALTERNATE_BY_NODELABEL(USBC_PORT_C1, + ppc_nx20p_port1); + break; + + case FW_IO_DB_SKU_B: + LOG_INF("USB DB: Setting SKU_B DB"); + TCPC_ENABLE_ALTERNATE_BY_NODELABEL(USBC_PORT_C1, + tcpc_ps8815_port1); + PPC_ENABLE_ALTERNATE_BY_NODELABEL(USBC_PORT_C1, + ppc_ktu1125_port1); + break; + } +} +DECLARE_HOOK(HOOK_INIT, setup_mux, HOOK_PRIO_INIT_I2C); diff --git a/zephyr/program/myst/program.conf b/zephyr/program/myst/program.conf index 49d4cc00ad..e96b2580f4 100644 --- a/zephyr/program/myst/program.conf +++ b/zephyr/program/myst/program.conf @@ -78,6 +78,7 @@ CONFIG_PLATFORM_EC_CHARGER_MIN_POWER_MW_FOR_POWER_ON=50000 # USB-C CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8815=y +CONFIG_PLATFORM_EC_USBC_PPC=y CONFIG_PLATFORM_EC_USBC_SS_MUX_DFP_ONLY=y CONFIG_PLATFORM_EC_USB_MUX_RUNTIME_CONFIG=y CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC=y @@ -90,10 +91,15 @@ CONFIG_PLATFORM_EC_USB_PD_LOGGING=y CONFIG_PLATFORM_EC_USB_PD_REV30=y CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n CONFIG_PLATFORM_EC_USB_PD_TCPC_LOW_POWER=y -CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n +CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=y CONFIG_PLATFORM_EC_USB_PD_USB4=n CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y +# Bring up configs +CONFIG_SHELL_HISTORY_BUFFER=256 +CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y +CONFIG_PLATFORM_EC_BRINGUP=y + # Disable FRS for bringup CONFIG_PLATFORM_EC_USB_PD_FRS=n CONFIG_PLATFORM_EC_USB_PD_FRS_TCPC=n diff --git a/zephyr/program/myst/src/usbc_config.c b/zephyr/program/myst/src/usbc_config.c index c3aafd9da9..5d2401a6af 100644 --- a/zephyr/program/myst/src/usbc_config.c +++ b/zephyr/program/myst/src/usbc_config.c @@ -9,11 +9,12 @@ #include "charge_manager.h" #include "charge_ramp.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "cros_board_info.h" #include "cros_cbi.h" #include "driver/charger/isl9241.h" +#include "driver/ppc/ktu1125_public.h" +#include "driver/ppc/nx20p348x.h" #include "driver/tcpm/rt1718s.h" #include "driver/usb_mux/amd_fp6.h" #include "gpio/gpio_int.h" @@ -22,6 +23,7 @@ #include "usb_mux.h" #include "usb_pd_tcpm.h" #include "usbc/usb_muxes.h" +#include "usbc_config.h" #include "usbc_ppc.h" #include <zephyr/drivers/gpio.h> @@ -29,13 +31,6 @@ #define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ##args) #define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ##args) -/* USB-A ports */ -enum usba_port { USBA_PORT_A0 = 0, USBA_PORT_A1, USBA_PORT_COUNT }; - -/* USB-C ports */ -enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; -BUILD_ASSERT(USBC_PORT_COUNT == CONFIG_USB_PD_PORT_MAX_COUNT); - static void usbc_interrupt_init(void) { /* Enable PPC interrupts. */ @@ -57,7 +52,7 @@ int board_set_active_charge_port(int port) CPRINTSUSB("Disabling all charger ports"); /* Disable all ports. */ - for (i = 0; i < ppc_cnt; i++) { + for (i = 0; i < board_get_usb_pd_port_count(); i++) { /* * Do not return early if one fails otherwise we can * get into a boot loop assertion failure. @@ -83,7 +78,7 @@ int board_set_active_charge_port(int port) * Turn off the other ports' sink path FETs, before enabling the * requested charge port. */ - for (i = 0; i < ppc_cnt; i++) { + for (i = 0; i < board_get_usb_pd_port_count(); i++) { if (i == port) continue; diff --git a/zephyr/program/myst/usbc.dtsi b/zephyr/program/myst/usbc.dtsi index 8e8579d328..b63c0347bd 100644 --- a/zephyr/program/myst/usbc.dtsi +++ b/zephyr/program/myst/usbc.dtsi @@ -24,8 +24,6 @@ compatible = "named-usbc-port"; reg = <1>; bc12 = <&bc12_port1>; - tcpc = <&tcpc_port1>; - ppc = <&ppc_port1>; usb-mux-chain-1-anx { compatible = "cros-ec,usb-mux-chain"; usb-muxes = <&amd_fp6_port1>; diff --git a/zephyr/program/nissa/CMakeLists.txt b/zephyr/program/nissa/CMakeLists.txt index e2f85139bf..cd45f00a3a 100644 --- a/zephyr/program/nissa/CMakeLists.txt +++ b/zephyr/program/nissa/CMakeLists.txt @@ -118,7 +118,6 @@ if(DEFINED CONFIG_BOARD_ULDREN) "uldren/src/kb_backlight.c" "uldren/src/keyboard.c" ) - zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "uldren/src/fan.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "uldren/src/usbc.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "uldren/src/charger.c") endif() diff --git a/zephyr/program/nissa/craask/src/usbc.c b/zephyr/program/nissa/craask/src/usbc.c index 88fc54d3a3..5df3a09bb8 100644 --- a/zephyr/program/nissa/craask/src/usbc.c +++ b/zephyr/program/nissa/craask/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/joxer/src/usbc.c b/zephyr/program/nissa/joxer/src/usbc.c index e3e18e0f33..54fea2f663 100644 --- a/zephyr/program/nissa/joxer/src/usbc.c +++ b/zephyr/program/nissa/joxer/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/sm5803.h" #include "driver/tcpm/it83xx_pd.h" diff --git a/zephyr/program/nissa/nereid/src/usbc.c b/zephyr/program/nissa/nereid/src/usbc.c index e3e18e0f33..54fea2f663 100644 --- a/zephyr/program/nissa/nereid/src/usbc.c +++ b/zephyr/program/nissa/nereid/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/sm5803.h" #include "driver/tcpm/it83xx_pd.h" diff --git a/zephyr/program/nissa/nivviks/src/usbc.c b/zephyr/program/nissa/nivviks/src/usbc.c index 88fc54d3a3..5df3a09bb8 100644 --- a/zephyr/program/nissa/nivviks/src/usbc.c +++ b/zephyr/program/nissa/nivviks/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/pujjo/src/usbc.c b/zephyr/program/nissa/pujjo/src/usbc.c index 59d876c4db..0b5fe3b809 100644 --- a/zephyr/program/nissa/pujjo/src/usbc.c +++ b/zephyr/program/nissa/pujjo/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/src/common.c b/zephyr/program/nissa/src/common.c index def29ccd02..aaca2ecc6b 100644 --- a/zephyr/program/nissa/src/common.c +++ b/zephyr/program/nissa/src/common.c @@ -4,7 +4,7 @@ */ #include "battery.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "hooks.h" diff --git a/zephyr/program/nissa/uldren/cbi.dtsi b/zephyr/program/nissa/uldren/cbi.dtsi index 9d865a38bb..02aa0607f9 100644 --- a/zephyr/program/nissa/uldren/cbi.dtsi +++ b/zephyr/program/nissa/uldren/cbi.dtsi @@ -7,44 +7,47 @@ /* Uldren-specific fw_config fields. */ nissa-fw-config { /* - * FW_CONFIG field to enable KB back light or not. + * FW_CONFIG field to enable USB DB. */ - kb-bl { - enum-name = "FW_KB_BL"; - start = <4>; - size = <1>; + sub-board { + enum-name = "FW_SUB_BOARD"; + start = <1>; + size = <2>; - no-kb-bl { + sub-board-1 { compatible = "cros-ec,cbi-fw-config-value"; - enum-name = "FW_KB_BL_NOT_PRESENT"; + enum-name = "FW_SUB_BOARD_1"; value = <0>; - default; }; - kb-bl-present { + sub-board-2 { compatible = "cros-ec,cbi-fw-config-value"; - enum-name = "FW_KB_BL_PRESENT"; - value = <1>; + enum-name = "FW_SUB_BOARD_2"; + value = <3>; + }; + sub-board-3 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_SUB_BOARD_3"; + value = <2>; }; }; - /* - * FW_CONFIG field to enable USB DB. + * FW_CONFIG field to enable KB back light or not. */ - db-usb { - enum-name = "FW_DB_USB"; - start = <6>; + kb-bl { + enum-name = "FW_KB_BL"; + start = <5>; size = <1>; - no-db-usb { + no-kb-bl { compatible = "cros-ec,cbi-fw-config-value"; - enum-name = "FW_DB_USB_NOT_PRESENT"; + enum-name = "FW_KB_BL_NOT_PRESENT"; value = <0>; + default; }; - db-usb-present { + kb-bl-present { compatible = "cros-ec,cbi-fw-config-value"; - enum-name = "FW_DB_USB_PRESENT"; + enum-name = "FW_KB_BL_PRESENT"; value = <1>; - default; }; }; @@ -67,5 +70,6 @@ value = <1>; }; }; +/delete-node/ fan; }; }; diff --git a/zephyr/program/nissa/uldren/led_policy.dtsi b/zephyr/program/nissa/uldren/led_policy.dtsi index 95c614cafc..afc4e25f71 100644 --- a/zephyr/program/nissa/uldren/led_policy.dtsi +++ b/zephyr/program/nissa/uldren/led_policy.dtsi @@ -7,7 +7,7 @@ power-state-charge { charge-state = "PWR_STATE_CHARGE"; batt-lvl = <BATTERY_LEVEL_EMPTY - BATTERY_LEVEL_NEAR_FULL>; + BATTERY_LEVEL_FULL>; color-0 { led-color = <&color_white>; diff --git a/zephyr/program/nissa/uldren/src/fan.c b/zephyr/program/nissa/uldren/src/fan.c deleted file mode 100644 index 32f9d3c65e..0000000000 --- a/zephyr/program/nissa/uldren/src/fan.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2023 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "cros_cbi.h" -#include "fan.h" -#include "gpio/gpio.h" -#include "hooks.h" - -#include <zephyr/devicetree.h> -#include <zephyr/drivers/gpio.h> -#include <zephyr/logging/log.h> - -LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); - -/* - * Nirwen fan support - */ -static void fan_init(void) -{ - int ret; - uint32_t val; - /* - * Retrieve the fan config. - */ - ret = cros_cbi_get_fw_config(FW_FAN, &val); - if (ret != 0) { - LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_FAN); - return; - } - if (val != FW_FAN_PRESENT) { - /* Disable the fan */ - fan_set_count(0); - } else { - /* Configure the fan enable GPIO */ - gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_fan_enable), - GPIO_OUTPUT); - } -} -DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST); diff --git a/zephyr/program/nissa/uldren/src/usbc.c b/zephyr/program/nissa/uldren/src/usbc.c index aaba5492dd..33c63472e8 100644 --- a/zephyr/program/nissa/uldren/src/usbc.c +++ b/zephyr/program/nissa/uldren/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/xivu/led_policy.dtsi b/zephyr/program/nissa/xivu/led_policy.dtsi index 562e361ec5..598480f865 100644 --- a/zephyr/program/nissa/xivu/led_policy.dtsi +++ b/zephyr/program/nissa/xivu/led_policy.dtsi @@ -14,8 +14,8 @@ power-state-charge-lvl-2 { charge-state = "PWR_STATE_CHARGE"; - /* Battery percent range (>= 95%, <= Near Full) */ - batt-lvl = <95 97>; + /* Battery percent range (>= 95%, <= 100%) */ + batt-lvl = <95 100>; color-0 { led-color = <&color_white>; diff --git a/zephyr/program/nissa/xivu/src/usbc.c b/zephyr/program/nissa/xivu/src/usbc.c index 6b95a3b1f4..d77abf37db 100644 --- a/zephyr/program/nissa/xivu/src/usbc.c +++ b/zephyr/program/nissa/xivu/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/xivur/src/usbc.c b/zephyr/program/nissa/xivur/src/usbc.c index 639bd3adbb..a0bd74b3a6 100644 --- a/zephyr/program/nissa/xivur/src/usbc.c +++ b/zephyr/program/nissa/xivur/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/isl923x_public.h" #include "driver/retimer/anx7483_public.h" diff --git a/zephyr/program/nissa/yaviks/project.conf b/zephyr/program/nissa/yaviks/project.conf index 2e52005cad..06c63967c6 100644 --- a/zephyr/program/nissa/yaviks/project.conf +++ b/zephyr/program/nissa/yaviks/project.conf @@ -45,3 +45,6 @@ CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_CDP_SDP_ONLY=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_DEFAULT_CDP=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_INVERTED=y + +# Charger +CONFIG_PLATFORM_EC_CHARGER_INPUT_CURRENT_DERATE_PCT=0 diff --git a/zephyr/program/nissa/yaviks/src/led.c b/zephyr/program/nissa/yaviks/src/led.c index 7671bd3a92..db93ae4b47 100644 --- a/zephyr/program/nissa/yaviks/src/led.c +++ b/zephyr/program/nissa/yaviks/src/led.c @@ -140,7 +140,7 @@ static void led_set_battery(void) * system suspend with non-charging state. */ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery(RIGHT_PORT, @@ -158,7 +158,7 @@ static void led_set_battery(void) suspend_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); diff --git a/zephyr/program/nissa/yaviks/src/usbc.c b/zephyr/program/nissa/yaviks/src/usbc.c index c9950ae73b..307109fa9d 100644 --- a/zephyr/program/nissa/yaviks/src/usbc.c +++ b/zephyr/program/nissa/yaviks/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/sm5803.h" #include "driver/tcpm/it83xx_pd.h" @@ -235,6 +235,25 @@ __override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) } } +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* + * b:213937755: Yaviks C1 port is OCPC (One Charger IC Per Type-C) + * architecture, The charging current is controlled by increasing Vsys. + * However, the charger SM5803 is not limit current while Vsys + * increasing, we can see the current overshoot to ~3.6A to cause + * C1 port brownout with low power charger (5V). To avoid C1 port + * brownout at low power charger connected. Limit charge current to 2A. + */ + if (charge_mv <= 5000 && port == 1) + charge_ma = MIN(charge_ma, 2000); + else + charge_ma = charge_ma * 96 / 100; + + charge_set_input_current_limit(charge_ma, charge_mv); +} + void board_reset_pd_mcu(void) { /* diff --git a/zephyr/program/nissa/yavilla/gpio.dtsi b/zephyr/program/nissa/yavilla/gpio.dtsi index d063b897d9..a18e674b11 100644 --- a/zephyr/program/nissa/yavilla/gpio.dtsi +++ b/zephyr/program/nissa/yavilla/gpio.dtsi @@ -209,6 +209,9 @@ gpio_c0_charger_led_amber_l: c0_charger_led_amber_l { gpios = <&gpioj 7 GPIO_OUTPUT_HIGH>; }; + gpio_power_led_white_l: power_led_white_l { + gpios = <&gpioa 3 GPIO_OUTPUT_HIGH>; + }; gpio_ec_kso_02_inv: ec_kso_02_inv { gpios = <&gpioksol 2 GPIO_OUTPUT_HIGH>; enum-name = "GPIO_KBD_KSO2"; diff --git a/zephyr/program/nissa/yavilla/project.conf b/zephyr/program/nissa/yavilla/project.conf index bbabd05b37..30818c4419 100644 --- a/zephyr/program/nissa/yavilla/project.conf +++ b/zephyr/program/nissa/yavilla/project.conf @@ -31,6 +31,7 @@ CONFIG_PLATFORM_EC_CUSTOM_FAN_CONTROL=y # LED CONFIG_PLATFORM_EC_LED_PWM=n +CONFIG_PLATFORM_EC_LED_ONOFF_STATES=n CONFIG_NISSA_SUB_BOARD=n @@ -40,3 +41,6 @@ CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_CDP_SDP_ONLY=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_DEFAULT_CDP=y CONFIG_PLATFORM_EC_USB_PORT_POWER_SMART_INVERTED=y + +# Charger +CONFIG_PLATFORM_EC_CHARGER_INPUT_CURRENT_DERATE_PCT=0 diff --git a/zephyr/program/nissa/yavilla/src/keyboard.c b/zephyr/program/nissa/yavilla/src/keyboard.c index 93db22132f..d942405faa 100644 --- a/zephyr/program/nissa/yavilla/src/keyboard.c +++ b/zephyr/program/nissa/yavilla/src/keyboard.c @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors +/* Copyright 2023 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -14,24 +14,8 @@ LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); -/* Keyboard scan setting */ -__override struct keyboard_scan_config keyscan_config = { - /* Increase from 50 us, because KSO_02 passes through the H1. */ - .output_settle_us = 80, - /* Other values should be the same as the default configuration. */ - .debounce_down_us = 9 * MSEC, - .debounce_up_us = 30 * MSEC, - .scan_period_us = 3 * MSEC, - .min_post_scan_delay_us = 1000, - .poll_timeout_us = 100 * MSEC, - .actual_key_mask = { - 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xa4, 0xff, 0xf6, 0x55, 0xfe, 0xff, 0xff, 0xff, /* full set */ - }, -}; - -static const struct ec_response_keybd_config yavilla_kb_w_kb_light = { - .num_top_row_keys = 13, +static const struct ec_response_keybd_config kb_tablet_present = { + .num_top_row_keys = 10, .action_keys = { TK_BACK, /* T1 */ TK_REFRESH, /* T2 */ @@ -40,18 +24,16 @@ static const struct ec_response_keybd_config yavilla_kb_w_kb_light = { TK_SNAPSHOT, /* T5 */ TK_BRIGHTNESS_DOWN, /* T6 */ TK_BRIGHTNESS_UP, /* T7 */ - TK_KBD_BKLIGHT_TOGGLE, /* T8 */ - TK_PLAY_PAUSE, /* T9 */ - TK_MICMUTE, /* T10 */ - TK_VOL_MUTE, /* T11 */ - TK_VOL_DOWN, /* T12 */ - TK_VOL_UP, /* T13 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ }, - .capabilities = KEYBD_CAP_NUMERIC_KEYPAD, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, + /* No function keys, no numeric keypad */ }; -static const struct ec_response_keybd_config yavilla_kb_wo_kb_light = { - .num_top_row_keys = 13, +static const struct ec_response_keybd_config kb_tablet_absent = { + .num_top_row_keys = 10, .action_keys = { TK_BACK, /* T1 */ TK_REFRESH, /* T2 */ @@ -60,14 +42,11 @@ static const struct ec_response_keybd_config yavilla_kb_wo_kb_light = { TK_SNAPSHOT, /* T5 */ TK_BRIGHTNESS_DOWN, /* T6 */ TK_BRIGHTNESS_UP, /* T7 */ - TK_PLAY_PAUSE, /* T8 */ - TK_MICMUTE, /* T9 */ - TK_VOL_MUTE, /* T10 */ - TK_VOL_DOWN, /* T11 */ - TK_VOL_UP, /* T12 */ - TK_MENU, /* T13 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ }, - .capabilities = KEYBD_CAP_NUMERIC_KEYPAD, + /* No function keys, no numeric keypad and no screenlock key */ }; __override const struct ec_response_keybd_config * @@ -75,12 +54,12 @@ board_vivaldi_keybd_config(void) { uint32_t val; - cros_cbi_get_fw_config(FW_KB_BACKLIGHT, &val); + cros_cbi_get_fw_config(FW_TABLET, &val); - if (val == FW_KB_BACKLIGHT_OFF) - return &yavilla_kb_wo_kb_light; + if (val == FW_TABLET_PRESENT) + return &kb_tablet_present; else - return &yavilla_kb_w_kb_light; + return &kb_tablet_absent; } /* @@ -109,17 +88,16 @@ DECLARE_HOOK(HOOK_INIT, kb_layout_init, HOOK_PRIO_POST_FIRST); /* * Map keyboard connector pins to EC GPIO pins for factory test. * Pins mapped to {-1, -1} are skipped. - * The connector has 30 pins total, and there is no pin 0. + * The connector has 24 pins total, and there is no pin 0. */ const int keyboard_factory_scan_pins[][2] = { { -1, -1 }, { GPIO_KSOH, 4 }, { GPIO_KSOH, 0 }, { GPIO_KSOH, 1 }, - { GPIO_KSOH, 3 }, { GPIO_KSOH, 2 }, { -1, -1 }, { -1, -1 }, - { GPIO_KSOL, 5 }, { GPIO_KSOL, 6 }, { -1, -1 }, { GPIO_KSOL, 3 }, - { GPIO_KSOL, 2 }, { GPIO_KSI, 0 }, { GPIO_KSOL, 1 }, { GPIO_KSOL, 4 }, - { GPIO_KSI, 3 }, { GPIO_KSI, 2 }, { GPIO_KSOL, 0 }, { GPIO_KSI, 5 }, - { GPIO_KSI, 4 }, { GPIO_KSOL, 7 }, { GPIO_KSI, 6 }, { GPIO_KSI, 7 }, - { GPIO_KSI, 1 }, { -1, -1 }, { GPIO_KSOH, 5 }, { -1, -1 }, - { GPIO_KSOH, 6 }, { -1, -1 }, { -1, -1 }, + { GPIO_KSOH, 3 }, { GPIO_KSOH, 2 }, { GPIO_KSOL, 5 }, { GPIO_KSOL, 6 }, + { GPIO_KSOL, 3 }, { GPIO_KSOL, 2 }, { GPIO_KSI, 0 }, { GPIO_KSOL, 1 }, + { GPIO_KSOL, 4 }, { GPIO_KSI, 3 }, { GPIO_KSI, 2 }, { GPIO_KSOL, 0 }, + { GPIO_KSI, 5 }, { GPIO_KSI, 4 }, { GPIO_KSOL, 7 }, { GPIO_KSI, 6 }, + { GPIO_KSI, 7 }, { GPIO_KSI, 1 }, { -1, -1 }, { -1, -1 }, + { -1, -1 }, }; const int keyboard_factory_scan_pins_used = ARRAY_SIZE(keyboard_factory_scan_pins); diff --git a/zephyr/program/nissa/yavilla/src/led.c b/zephyr/program/nissa/yavilla/src/led.c index a1ae6b24cf..d123af8142 100644 --- a/zephyr/program/nissa/yavilla/src/led.c +++ b/zephyr/program/nissa/yavilla/src/led.c @@ -7,6 +7,7 @@ #include "charge_manager.h" #include "charge_state.h" #include "chipset.h" +#include "cros_cbi.h" #include "ec_commands.h" #include "gpio.h" #include "hooks.h" @@ -15,9 +16,16 @@ #include <stdint.h> +#include <zephyr/logging/log.h> + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + #define BAT_LED_ON 0 #define BAT_LED_OFF 1 +#define PWR_LED_ON 0 +#define PWR_LED_OFF 1 + #define BATT_LOW_BCT 10 #define LED_TICKS_PER_CYCLE 4 @@ -25,8 +33,11 @@ #define LED_ON_TICKS 2 #define POWER_LED_ON_S3_TICKS 2 -const enum ec_led_id supported_led_ids[] = { EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED }; +static bool power_led_support; + +const enum ec_led_id supported_led_ids[] = { EC_LED_ID_RIGHT_LED, + EC_LED_ID_LEFT_LED, + EC_LED_ID_POWER_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); @@ -37,16 +48,16 @@ enum led_color { LED_COLOR_COUNT /* Number of colors, not a color itself */ }; -enum led_port { LEFT_PORT = 0, RIGHT_PORT }; +enum led_port { RIGHT_PORT = 0, LEFT_PORT }; static void led_set_color_battery(int port, enum led_color color) { const struct gpio_dt_spec *amber_led, *white_led; - if (port == LEFT_PORT) { + if (port == RIGHT_PORT) { amber_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_amber_l); white_led = GPIO_DT_FROM_NODELABEL(gpio_c0_charger_led_white_l); - } else if (port == RIGHT_PORT) { + } else if (port == LEFT_PORT) { amber_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_amber_l); white_led = GPIO_DT_FROM_NODELABEL(gpio_c1_charger_led_white_l); } @@ -69,6 +80,22 @@ static void led_set_color_battery(int port, enum led_color color) } } +static void led_set_color_power(enum led_color color) +{ + switch (color) { + case LED_OFF: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_white_l), + PWR_LED_OFF); + break; + case LED_WHITE: + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_power_led_white_l), + PWR_LED_ON); + break; + default: + break; + } +} + void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { switch (led_id) { @@ -80,6 +107,9 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) brightness_range[EC_LED_COLOR_WHITE] = 1; brightness_range[EC_LED_COLOR_AMBER] = 1; break; + case EC_LED_ID_POWER_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + break; default: break; } @@ -104,6 +134,12 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) else led_set_color_battery(RIGHT_PORT, LED_OFF); break; + case EC_LED_ID_POWER_LED: + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(LED_WHITE); + else + led_set_color_power(LED_OFF); + break; default: return EC_ERROR_PARAM1; } @@ -135,12 +171,12 @@ static void led_set_battery(void) battery_ticks++; /* - * Override battery LEDs for Yavilla, Yavilla is non-power LED - * design, blinking both two side battery white LEDs to indicate + * Override battery LEDs for Yavilla without power led support, + * blinking both two side battery white LEDs to indicate * system suspend with non-charging state. */ - if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - charge_get_state() != PWR_STATE_CHARGE) { + if (!power_led_support && chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + led_pwr_get_state() != PWR_STATE_CHARGE) { suspend_ticks++; led_set_color_battery(RIGHT_PORT, @@ -158,7 +194,7 @@ static void led_set_battery(void) suspend_ticks = 0; - switch (charge_get_state()) { + switch (led_pwr_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ set_active_port_color(LED_AMBER); @@ -223,9 +259,51 @@ static void led_set_battery(void) } } +static void led_set_power(void) +{ + static int power_ticks; + + power_ticks++; + + if (chipset_in_state(CHIPSET_STATE_ON)) + led_set_color_power(LED_WHITE); + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + led_set_color_power((power_ticks % LED_TICKS_PER_CYCLE_S3 < + POWER_LED_ON_S3_TICKS) ? + LED_WHITE : + LED_OFF); + else + led_set_color_power(LED_OFF); +} + +static void power_led_check(void) +{ + int ret; + uint32_t val; + + /* + * Retrieve the tablet config. + */ + ret = cros_cbi_get_fw_config(FW_TABLET, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FW_TABLET); + return; + } + + if (val == FW_TABLET_PRESENT) + power_led_support = true; + else /* Clameshell */ + power_led_support = false; +} +DECLARE_HOOK(HOOK_INIT, power_led_check, HOOK_PRIO_DEFAULT); + /* Called by hook task every TICK(IT83xx 500ms) */ static void led_tick(void) { led_set_battery(); + + if (power_led_support && + led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) + led_set_power(); } DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); diff --git a/zephyr/program/nissa/yavilla/src/usbc.c b/zephyr/program/nissa/yavilla/src/usbc.c index c9950ae73b..3cbdd23625 100644 --- a/zephyr/program/nissa/yavilla/src/usbc.c +++ b/zephyr/program/nissa/yavilla/src/usbc.c @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "chipset.h" #include "driver/charger/sm5803.h" #include "driver/tcpm/it83xx_pd.h" @@ -235,6 +235,25 @@ __override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) } } +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* + * b:213937755: Yavilla C1 port is OCPC (One Charger IC Per Type-C) + * architecture, The charging current is controlled by increasing Vsys. + * However, the charger SM5803 is not limit current while Vsys + * increasing, we can see the current overshoot to ~3.6A to cause + * C1 port brownout with low power charger (5V). To avoid C1 port + * brownout at low power charger connected. Limit charge current to 2A. + */ + if (charge_mv <= 5000 && port == 1) + charge_ma = MIN(charge_ma, 2000); + else + charge_ma = charge_ma * 96 / 100; + + charge_set_input_current_limit(charge_ma, charge_mv); +} + void board_reset_pd_mcu(void) { /* diff --git a/zephyr/program/rex/program.conf b/zephyr/program/rex/program.conf index 0e572e373c..0dd7f48994 100644 --- a/zephyr/program/rex/program.conf +++ b/zephyr/program/rex/program.conf @@ -137,3 +137,6 @@ CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y CONFIG_PLATFORM_EC_ALS_TCS3400=y + +# System Boot Time +CONFIG_SYSTEM_BOOT_TIME_LOGGING=y diff --git a/zephyr/program/rex/src/usbc_config.c b/zephyr/program/rex/src/usbc_config.c index d2471c3daf..115d010ff5 100644 --- a/zephyr/program/rex/src/usbc_config.c +++ b/zephyr/program/rex/src/usbc_config.c @@ -7,7 +7,6 @@ #include "charge_manager.h" #include "charge_ramp.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "driver/charger/isl9241.h" #include "driver/ppc/nx20p348x.h" diff --git a/zephyr/program/skyrim/frostflow/led_policy.dtsi b/zephyr/program/skyrim/frostflow/led_policy.dtsi index 28e33219a0..178ba9085a 100644 --- a/zephyr/program/skyrim/frostflow/led_policy.dtsi +++ b/zephyr/program/skyrim/frostflow/led_policy.dtsi @@ -14,8 +14,8 @@ power-state-charge-lvl-2 { charge-state = "PWR_STATE_CHARGE"; - /* Battery percent range (>= 95%, <= Near Full) */ - batt-lvl = <95 97>; + /* Battery percent range (>= 95%, <= 100%) */ + batt-lvl = <95 100>; color-0 { led-color = <&color_white>; diff --git a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c index b73c6370b8..c7c03bc8cb 100644 --- a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c +++ b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c @@ -5,6 +5,7 @@ /* Frostflow board-specific USB-C mux configuration */ +#include "ap_power/ap_power.h" #include "chipset.h" #include "common.h" #include "console.h" @@ -175,8 +176,26 @@ void baseboard_a1_retimer_setup(void) } DECLARE_DEFERRED(baseboard_a1_retimer_setup); -void board_chipset_startup(void) +test_export_static void board_resume_change(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) { - hook_call_deferred(&baseboard_a1_retimer_setup_data, 500 * MSEC); + switch (data.event) { + default: + return; + + case AP_POWER_STARTUP: + /* Any retimer tuning can be done after the retimer turns on */ + hook_call_deferred(&baseboard_a1_retimer_setup_data, 20 * MSEC); + break; + } +} + +void board_callback_init(void) +{ + static struct ap_power_ev_callback cb; + + /* Setup a resume callback */ + ap_power_ev_init_callback(&cb, board_resume_change, AP_POWER_STARTUP); + ap_power_ev_add_callback(&cb); } -DECLARE_HOOK(HOOK_INIT, board_chipset_startup, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_INIT, board_callback_init, HOOK_PRIO_DEFAULT); diff --git a/zephyr/program/skyrim/markarth/led_policy.dtsi b/zephyr/program/skyrim/markarth/led_policy.dtsi index 07354d3060..78a6488d7a 100644 --- a/zephyr/program/skyrim/markarth/led_policy.dtsi +++ b/zephyr/program/skyrim/markarth/led_policy.dtsi @@ -44,14 +44,14 @@ charge-state = "PWR_STATE_DISCHARGE"; chipset-state = "POWER_S3"; - /* Blue 1 sec, off 1 sec */ + /* Amber 1 sec, off 3 sec */ color-0 { - led-color = <&color_blue>; + led-color = <&color_amber>; period-ms = <1000>; }; color-1 { led-color = <&color_off>; - period-ms = <1000>; + period-ms = <3000>; }; }; diff --git a/zephyr/program/skyrim/markarth/project.conf b/zephyr/program/skyrim/markarth/project.conf index 4f00aa256c..4e9e437875 100644 --- a/zephyr/program/skyrim/markarth/project.conf +++ b/zephyr/program/skyrim/markarth/project.conf @@ -27,3 +27,7 @@ CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y # Fan CONFIG_PLATFORM_EC_CUSTOM_FAN_CONTROL=y + +# Markarth modify monitor VBUS from TCPC +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=n +CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_TCPC=y diff --git a/zephyr/program/skyrim/src/power_signals.c b/zephyr/program/skyrim/src/power_signals.c index 5814359606..ede5d1ec75 100644 --- a/zephyr/program/skyrim/src/power_signals.c +++ b/zephyr/program/skyrim/src/power_signals.c @@ -65,9 +65,13 @@ baseboard_suspend_change(struct ap_power_ev_callback *cb, return; case AP_POWER_SUSPEND: - /* Disable display backlight and retimer */ + /* Disable display backlight */ gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_disable_disp_bl), 1); + break; + + case AP_POWER_SHUTDOWN: + /* Retimer disable */ ioex_set_level(IOEX_USB_A1_RETIMER_EN, 0); break; @@ -75,6 +79,9 @@ baseboard_suspend_change(struct ap_power_ev_callback *cb, /* Enable retimer and display backlight */ gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(gpio_ec_disable_disp_bl), 0); + break; + + case AP_POWER_STARTUP: ioex_set_level(IOEX_USB_A1_RETIMER_EN, 1); /* Any retimer tuning can be done after the retimer turns on */ break; @@ -106,7 +113,8 @@ test_export_static void baseboard_init(void) /* Setup a suspend/resume callback */ ap_power_ev_init_callback(&cb, baseboard_suspend_change, - AP_POWER_RESUME | AP_POWER_SUSPEND); + AP_POWER_STARTUP | AP_POWER_SHUTDOWN | + AP_POWER_RESUME | AP_POWER_SUSPEND); ap_power_ev_add_callback(&cb); /* Enable Power Group interrupts. */ gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_pg_groupc_s0)); diff --git a/zephyr/program/skyrim/src/usbc_config.c b/zephyr/program/skyrim/src/usbc_config.c index ab1d444df8..922e863027 100644 --- a/zephyr/program/skyrim/src/usbc_config.c +++ b/zephyr/program/skyrim/src/usbc_config.c @@ -9,7 +9,6 @@ #include "charge_manager.h" #include "charge_ramp.h" #include "charge_state.h" -#include "charge_state_v2.h" #include "charger.h" #include "cros_board_info.h" #include "cros_cbi.h" diff --git a/zephyr/program/skyrim/winterhold/CMakeLists.txt b/zephyr/program/skyrim/winterhold/CMakeLists.txt index 0596978c05..632f11d8f1 100644 --- a/zephyr/program/skyrim/winterhold/CMakeLists.txt +++ b/zephyr/program/skyrim/winterhold/CMakeLists.txt @@ -12,3 +12,6 @@ zephyr_library_sources( "src/alt_charger.c" "src/thermal.c" ) + +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL + "src/fan.c") diff --git a/zephyr/program/skyrim/winterhold/src/fan.c b/zephyr/program/skyrim/winterhold/src/fan.c new file mode 100644 index 0000000000..a5061a660f --- /dev/null +++ b/zephyr/program/skyrim/winterhold/src/fan.c @@ -0,0 +1,90 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "console.h" +#include "fan.h" +#include "math_util.h" +#include "thermal.h" + +#include <zephyr/kernel.h> + +#define CPRINTS(format, args...) cprints(CC_THERMAL, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_THERMAL, format, ##args) + +K_TIMER_DEFINE(grace_period_timer, NULL, NULL); + +enum fan_status board_override_fan_control_duty(int ch) +{ + int duty, rpm_diff, deviation, duty_step; + struct fan_data *data = &fan_data[ch]; + int rpm_actual = data->rpm_actual; + int rpm_target = data->rpm_target; + + /* This works with one fan only. */ + if (ch != 0) { + CPRINTS("Only FAN0 is supported!"); + return FAN_STATUS_FRUSTRATED; + } + + /* Wait for fan RPM to catch up after its duty has been changed. */ + if (k_timer_remaining_ticks(&grace_period_timer) != 0) + return FAN_STATUS_LOCKED; + + duty = fan_get_duty(ch); + if (duty == 0 && rpm_target == 0) + return FAN_STATUS_STOPPED; + + /* + * If the current RPM is close enough to the target just leave it. + * It's always going to fluctuate a bit anyway. + */ + deviation = fans[ch].rpm->rpm_deviation * rpm_target / 100; + rpm_diff = rpm_target - rpm_actual; + if (rpm_diff > deviation) { + /* Can't set duty higher than 100%... */ + if (duty == 100) + return FAN_STATUS_FRUSTRATED; + } else if (rpm_diff < -deviation) { + /* Can't set duty lower than 1%... */ + if (duty == 1 && rpm_target != 0) + return FAN_STATUS_FRUSTRATED; + } else { + return FAN_STATUS_LOCKED; + } + + /* + * The rpm_diff -> duty_step conversion is specific to a specific + * whiterun fan. + * It has been determined empirically. + */ + if (ABS(rpm_diff) >= 2500) { + duty_step = 35; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 2000) { + duty_step = 28; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 1000) { + duty_step = 14; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 500) { + duty_step = 6; + k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); + } else if (ABS(rpm_diff) >= 250) { + duty_step = 3; + k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); + } else { + duty_step = 1; + k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); + } + + if (rpm_diff > 0) + duty = MIN(duty + duty_step, 100); + else + duty = MAX(duty - duty_step, 1); + + fan_set_duty(ch, duty); + + return FAN_STATUS_CHANGING; +} diff --git a/zephyr/program/skyrim/winterhold/src/thermal.c b/zephyr/program/skyrim/winterhold/src/thermal.c index 00e162e45a..0ccd9dd9e2 100644 --- a/zephyr/program/skyrim/winterhold/src/thermal.c +++ b/zephyr/program/skyrim/winterhold/src/thermal.c @@ -4,11 +4,9 @@ */ #include "body_detection.h" -#include "fan.h" #include "hooks.h" #include "host_command.h" #include "lid_switch.h" -#include "math_util.h" #include "temp_sensor/temp_sensor.h" #include "thermal.h" @@ -211,82 +209,3 @@ static void detect_temp_change(void) } } DECLARE_HOOK(HOOK_SECOND, detect_temp_change, HOOK_PRIO_TEMP_SENSOR_DONE); - -#ifdef CONFIG_PLATFORM_EC_CUSTOM_FAN_DUTY_CONTROL - -K_TIMER_DEFINE(grace_period_timer, NULL, NULL); - -enum fan_status board_override_fan_control_duty(int ch) -{ - int duty, rpm_diff, deviation, duty_step; - struct fan_data *data = &fan_data[ch]; - int rpm_actual = data->rpm_actual; - int rpm_target = data->rpm_target; - - /* This works with one fan only. */ - if (ch != 0) { - CPRINTS("Only FAN0 is supported!"); - return FAN_STATUS_FRUSTRATED; - } - - /* Wait for fan RPM to catch up after its duty has been changed. */ - if (k_timer_remaining_ticks(&grace_period_timer) != 0) - return FAN_STATUS_LOCKED; - - duty = fan_get_duty(ch); - if (duty == 0 && rpm_target == 0) - return FAN_STATUS_STOPPED; - - /* - * If the current RPM is close enough to the target just leave it. - * It's always going to fluctuate a bit anyway. - */ - deviation = fans[ch].rpm->rpm_deviation * rpm_target / 100; - rpm_diff = rpm_target - rpm_actual; - if (rpm_diff > deviation) { - /* Can't set duty higher than 100%... */ - if (duty == 100) - return FAN_STATUS_FRUSTRATED; - } else if (rpm_diff < -deviation) { - /* Can't set duty lower than 1%... */ - if (duty == 1 && rpm_target != 0) - return FAN_STATUS_FRUSTRATED; - } else { - return FAN_STATUS_LOCKED; - } - - /* - * The rpm_diff -> duty_step conversion is specific to a specific - * whiterun fan. - * It has been determined empirically. - */ - if (ABS(rpm_diff) >= 2500) { - duty_step = 35; - k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); - } else if (ABS(rpm_diff) >= 2000) { - duty_step = 28; - k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); - } else if (ABS(rpm_diff) >= 1000) { - duty_step = 14; - k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); - } else if (ABS(rpm_diff) >= 500) { - duty_step = 6; - k_timer_start(&grace_period_timer, K_MSEC(800), K_NO_WAIT); - } else if (ABS(rpm_diff) >= 250) { - duty_step = 3; - k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); - } else { - duty_step = 1; - k_timer_start(&grace_period_timer, K_MSEC(600), K_NO_WAIT); - } - - if (rpm_diff > 0) - duty = MIN(duty + duty_step, 100); - else - duty = MAX(duty - duty_step, 1); - - fan_set_duty(ch, duty); - - return FAN_STATUS_CHANGING; -} -#endif diff --git a/zephyr/shim/include/atomic.h b/zephyr/shim/include/atomic.h index beb8b111ed..540a43ccbc 100644 --- a/zephyr/shim/include/atomic.h +++ b/zephyr/shim/include/atomic.h @@ -3,6 +3,12 @@ * found in the LICENSE file. */ +/* + * TODO(b/272518464): Work around coreboot GCC preprocessor bug. + * #line marks the *next* line, so it is off by one. + */ +#line 11 + #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 153b150293..132494d5f4 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -1153,6 +1153,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_CHARGE_STATE_DEBUG #endif +#undef CONFIG_CHARGE_DEBUG +#ifdef CONFIG_PLATFORM_EC_CHARGE_DEBUG +#define CONFIG_CHARGE_DEBUG +#endif + #undef CONFIG_CMD_PWR_AVG #ifdef CONFIG_PLATFORM_EC_CMD_PWR_AVG #define CONFIG_CMD_PWR_AVG diff --git a/zephyr/shim/src/led_driver/led.c b/zephyr/shim/src/led_driver/led.c index da648a4636..84eab2c6fe 100644 --- a/zephyr/shim/src/led_driver/led.c +++ b/zephyr/shim/src/led_driver/led.c @@ -61,7 +61,7 @@ DT_FOREACH_CHILD_STATUS_OKAY_VARGS( #define MAX_COLOR 4 struct node_prop_t { - enum charge_state pwr_state; + enum led_pwr_state pwr_state; enum power_state chipset_state; int batt_state_mask; int batt_state; @@ -202,7 +202,7 @@ static int match_node(int node_idx) { /* 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(); + enum led_pwr_state pwr_state = led_pwr_get_state(); if (node_array[node_idx].pwr_state != pwr_state) return -1; diff --git a/zephyr/shim/src/ppc.c b/zephyr/shim/src/ppc.c index ec5f2f26e1..9959097b9b 100644 --- a/zephyr/shim/src/ppc.c +++ b/zephyr/shim/src/ppc.c @@ -40,9 +40,15 @@ CHECK_COMPAT(SYV682X_COMPAT, usbc_id, ppc_id, PPC_CHIP_SYV682X) \ CHECK_COMPAT(SYV682X_EMUL_COMPAT, usbc_id, ppc_id, PPC_CHIP_SYV682X) -#define PPC_CHIP(usbc_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, ppc), \ - (PPC_CHIP_FIND(usbc_id, DT_PHANDLE(usbc_id, ppc))), ()) +/* clang-format off */ +#define PPC_CHIP_STUB(usbc_id) \ + [USBC_PORT_NEW(usbc_id)] = {}, +/* clang-format on */ + +#define PPC_CHIP(usbc_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, ppc), \ + (PPC_CHIP_FIND(usbc_id, DT_PHANDLE(usbc_id, ppc))), \ + (PPC_CHIP_STUB(usbc_id))) #define PPC_CHIP_ALT(usbc_id) \ COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, ppc_alt), \ diff --git a/zephyr/shim/src/system_safe_mode.c b/zephyr/shim/src/system_safe_mode.c index 0acb5b270f..98ccc83c53 100644 --- a/zephyr/shim/src/system_safe_mode.c +++ b/zephyr/shim/src/system_safe_mode.c @@ -39,11 +39,3 @@ static void safe_mode_timeout_cb(struct k_timer *unused) handle_system_safe_mode_timeout(); } K_TIMER_DEFINE(safe_mode_timeout, safe_mode_timeout_cb, NULL); - -__override int schedule_system_safe_mode_timeout(void) -{ - k_timer_start(&safe_mode_timeout, - K_MSEC(CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE_TIMEOUT_MSEC), - K_NO_WAIT); - return EC_SUCCESS; -} diff --git a/zephyr/shim/src/tcpc.c b/zephyr/shim/src/tcpc.c index a7fb1c11df..5d6bbf6156 100644 --- a/zephyr/shim/src/tcpc.c +++ b/zephyr/shim/src/tcpc.c @@ -71,9 +71,15 @@ LOG_MODULE_REGISTER(tcpc, CONFIG_GPIO_LOG_LEVEL); CHECK_COMPAT(TCPCI_COMPAT, usbc_id, tcpc_id, TCPC_CONFIG_TCPCI) \ TCPC_CHIP_FIND_EMUL(usbc_id, tcpc_id) -#define TCPC_CHIP(usbc_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, tcpc), \ - (TCPC_CHIP_FIND(usbc_id, DT_PHANDLE(usbc_id, tcpc))), ()) +/* clang-format off */ +#define TCPC_CHIP_STUB(usbc_id) \ + [USBC_PORT_NEW(usbc_id)] = {}, +/* clang-format on */ + +#define TCPC_CHIP(usbc_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, tcpc), \ + (TCPC_CHIP_FIND(usbc_id, DT_PHANDLE(usbc_id, tcpc))), \ + (TCPC_CHIP_STUB(usbc_id))) #define MAYBE_CONST \ COND_CODE_1(CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG, (), (const)) diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt index 417d96bf36..f8c778bee2 100644 --- a/zephyr/test/drivers/CMakeLists.txt +++ b/zephyr/test/drivers/CMakeLists.txt @@ -26,10 +26,12 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_COMMON_CBI_GPIO common_cbi_gpio) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_COMMON_CHARGER common_charger) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_CHARGESPLASH chargesplash) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_FLASH flash) +add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ICM42607 icm42607) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ISL923X isl923x) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ISL9241 isl9241) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_I2C_CONTROLLER i2c_controller) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_IT8XXX2_HW_SHA256 it8xxx2_hw_sha256) +add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_KEYBOARD_8042 keyboard_8042) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_KEYBOARD_SCAN keyboard_scan) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_LED_DRIVER led_driver) add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_MKBP mkbp) diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig index c3aaac274b..634eb00a71 100644 --- a/zephyr/test/drivers/Kconfig +++ b/zephyr/test/drivers/Kconfig @@ -65,6 +65,9 @@ config LINK_TEST_SUITE_HOST_COMMANDS config LINK_TEST_SUITE_HOST_COMMAND_READ_MEMMAP bool "Link and test the host command read memmap tests" +config LINK_TEST_SUITE_ICM42607 + bool "Link and test the icm42607 tests" + config LINK_TEST_SUITE_ISL923X bool "Link and test the isl923x tests" @@ -80,6 +83,9 @@ config LINK_TEST_SUITE_IT8XXX2_HW_SHA256 Include the it8xxx2_hw_sha256 test suite in the binary. +config LINK_TEST_SUITE_KEYBOARD_8042 + bool "Link and test the keyboard_8042 tests" + config LINK_TEST_SUITE_KEYBOARD_SCAN bool "Link and test the keyboard_scan tests" select PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK diff --git a/zephyr/test/drivers/ap_vdm_control/prj.conf b/zephyr/test/drivers/ap_vdm_control/prj.conf index 215a8ab36d..5267603e32 100644 --- a/zephyr/test/drivers/ap_vdm_control/prj.conf +++ b/zephyr/test/drivers/ap_vdm_control/prj.conf @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +CONFIG_PLATFORM_EC_USB_PD_DP_HPD_GPIO=y CONFIG_PLATFORM_EC_USB_MUX_AP_CONTROL=y CONFIG_PLATFORM_EC_USB_MUX_TASK=y CONFIG_PLATFORM_EC_USB_PD_VDM_AP_CONTROL=y diff --git a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c index 6c31880625..a5f5fbd7ef 100644 --- a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c +++ b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c @@ -13,10 +13,13 @@ #include <stdint.h> +#include <zephyr/drivers/gpio/gpio_emul.h> #include <zephyr/kernel.h> #include <zephyr/sys/byteorder.h> #include <zephyr/ztest.h> +#include <gpio.h> + #define TEST_PORT USBC_PORT_C0 struct ap_vdm_control_fixture { @@ -871,3 +874,242 @@ ZTEST_F(ap_vdm_control, test_no_ec_dp_mode) status = host_cmd_typec_status(TEST_PORT); zassert_equal(status.dp_pin, 0); } + +ZTEST_F(ap_vdm_control, test_vdm_hpd_level) +{ + uint32_t vdm_attention_data[2]; + int opos = 1; + const struct gpio_dt_spec *gpio = + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd); + + /* HPD GPIO should be low before the test */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); + + run_verify_dp_entry(fixture, opos); + + /* Now send Attention to change HPD */ + vdm_attention_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, + VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) | + VDO_SVDM_VERS(VDM_VER20); + vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */ + true, /* HPD_HI|LOW - Changed*/ + 0, /* request exit DP */ + 0, /* request exit USB */ + 0, /* MF pref */ + true, /* DP Enabled */ + 0, /* power low e.g. normal */ + 0x2 /* Connected as Sink */); + tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF, + vdm_attention_data, 2, 0); + + k_sleep(K_MSEC(100)); + /* + * Verify the HPD GPIO is set now + */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1); +} + +ZTEST_F(ap_vdm_control, test_vdm_hpd_irq_ignored) +{ + uint32_t vdm_attention_data[2]; + int opos = 1; + const struct gpio_dt_spec *gpio = + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd); + + /* HPD GPIO should be low before the test */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); + + run_verify_dp_entry(fixture, opos); + + /* Send our bad Attention message */ + vdm_attention_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, + VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) | + VDO_SVDM_VERS(VDM_VER20); + vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */ + false, /* HPD_HI|LOW - Changed*/ + 0, /* request exit DP */ + 0, /* request exit USB */ + 0, /* MF pref */ + true, /* DP Enabled */ + 0, /* power low e.g. normal */ + 0x2 /* Connected as Sink */); + tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF, + vdm_attention_data, 2, 0); + + k_sleep(K_MSEC(100)); + /* + * Verify the HPD IRQ was rejected since HPD is low + */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); +} + +ZTEST_F(ap_vdm_control, test_vdm_status_hpd) +{ + int opos = 1; + const struct gpio_dt_spec *gpio = + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd); + + /* HPD GPIO should be low before the test */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); + + /* Set up our slightly different DP Status */ + fixture->partner.dp_status_vdm[VDO_INDEX_HDR + 1] = + VDO_DP_STATUS(0, /* IRQ_HPD */ + true, /* HPD_HI|LOW - Changed*/ + 0, /* request exit DP */ + 0, /* request exit USB */ + 1, /* MF pref */ + true, /* DP Enabled */ + 0, /* power low e.g. normal */ + 0x2 /* Connected as Sink */); + + /* Run Entry step by step to check HPD at each point */ + struct typec_vdm_req req = { + .vdm_data = { VDO(USB_SID_DISPLAYPORT, 1, + CMD_ENTER_MODE | VDO_OPOS(opos)) | + VDO_SVDM_VERS(VDM_VER20) }, + .vdm_data_objects = 1, + .partner_type = TYPEC_PARTNER_SOP, + }; + + /* Step 1: EnterMode */ + host_cmd_typec_control_vdm_req(TEST_PORT, req); + k_sleep(K_MSEC(100)); + + verify_expected_reply(req.partner_type, + fixture->partner.enter_mode_vdos, + fixture->partner.enter_mode_vdm); + + /* Step 2: DP Status */ + req.vdm_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS | VDO_OPOS(opos)) | + VDO_SVDM_VERS(VDM_VER20); + req.vdm_data[1] = VDO_DP_STATUS(0, /* HPD IRQ ... not applicable */ + 0, /* HPD level ... not applicable */ + 0, /* exit DP? ... no */ + 0, /* usb mode? ... no */ + 0, /* multi-function ... no */ + 0, /* currently enabled ... no */ + 0, /* power low? ... no */ + 1 /* DP source connected */); + req.vdm_data_objects = 2; + req.partner_type = TYPEC_PARTNER_SOP; + + host_cmd_typec_control_vdm_req(TEST_PORT, req); + k_sleep(K_MSEC(100)); + + verify_expected_reply(req.partner_type, fixture->partner.dp_status_vdos, + fixture->partner.dp_status_vdm); + /* Wait for it... */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); + + /* Step 3: DP Configure */ + req.vdm_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG | VDO_OPOS(opos)) | + VDO_SVDM_VERS(VDM_VER20); + req.vdm_data[1] = VDO_DP_CFG(MODE_DP_PIN_D, /* pin mode */ + 1, /* DPv1.3 signaling */ + 2); /* Set that partner should be DP sink + */ + req.vdm_data_objects = 2; + req.partner_type = TYPEC_PARTNER_SOP; + + host_cmd_typec_control_vdm_req(TEST_PORT, req); + k_sleep(K_MSEC(100)); + + verify_expected_reply(req.partner_type, fixture->partner.dp_config_vdos, + fixture->partner.dp_config_vdm); + /* Now! */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1); +} + +ZTEST_F(ap_vdm_control, test_vdm_hpd_disconnect_clear) +{ + uint32_t vdm_attention_data[2]; + int opos = 1; + const struct gpio_dt_spec *gpio = + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd); + + run_verify_dp_entry(fixture, opos); + + /* Test that we see our Attention message */ + vdm_attention_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, + VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) | + VDO_SVDM_VERS(VDM_VER20); + vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */ + true, /* HPD_HI|LOW - Changed*/ + 0, /* request exit DP */ + 0, /* request exit USB */ + 0, /* MF pref */ + true, /* DP Enabled */ + 0, /* power low e.g. normal */ + 0x2 /* Connected as Sink */); + tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF, + vdm_attention_data, 2, 0); + + k_sleep(K_MSEC(100)); + /* + * Verify the HPD GPIO is set now + */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1); + + /* And disconnect */ + disconnect_source_from_port(fixture->tcpci_emul, fixture->charger_emul); + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); +} + +ZTEST_F(ap_vdm_control, test_vdm_wake_on_dock) +{ + uint32_t vdm_attention_data[2]; + int opos = 1; + const struct gpio_dt_spec *gpio = + GPIO_DT_FROM_NODELABEL(gpio_usb_c0_hpd); + + /* HPD GPIO should be low before the test */ + zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0); + + run_verify_dp_entry(fixture, opos); + + /* Now put the AP to "sleep" */ + test_set_chipset_to_power_level(POWER_S3); + + /* Drain the MKBP event queue first */ + struct host_cmd_handler_args args; + struct ec_response_get_next_event event; + + args.version = 0; + args.command = EC_CMD_GET_NEXT_EVENT; + args.params = NULL; + args.params_size = 0; + args.response = &event; + args.response_max = sizeof(event); + args.response_size = 0; + + while (host_command_process(&args) == EC_RES_SUCCESS) { + } + + /* Test that we see our Attention message cause an event */ + vdm_attention_data[0] = + VDO(USB_SID_DISPLAYPORT, 1, + VDO_OPOS(opos) | VDO_CMDT(CMDT_INIT) | CMD_ATTENTION) | + VDO_SVDM_VERS(VDM_VER20); + vdm_attention_data[1] = VDO_DP_STATUS(1, /* IRQ_HPD */ + true, /* HPD_HI|LOW - Changed*/ + 0, /* request exit DP */ + 0, /* request exit USB */ + 0, /* MF pref */ + true, /* DP Enabled */ + 0, /* power low e.g. normal */ + 0x2 /* Connected as Sink */); + tcpci_partner_send_data_msg(&fixture->partner, PD_DATA_VENDOR_DEF, + vdm_attention_data, 2, 0); + + k_sleep(K_MSEC(100)); + + /* Look for our MKBP event */ + zassert_equal(host_command_process(&args), EC_RES_SUCCESS); + zassert_equal(event.event_type, EC_MKBP_EVENT_DP_ALT_MODE_ENTERED); +} diff --git a/zephyr/test/drivers/common/src/stubs.c b/zephyr/test/drivers/common/src/stubs.c index cdb1a0f6a4..c623b95a82 100644 --- a/zephyr/test/drivers/common/src/stubs.c +++ b/zephyr/test/drivers/common/src/stubs.c @@ -7,7 +7,7 @@ #include "battery_fuel_gauge.h" #include "bc12/pi3usb9201_public.h" #include "charge_ramp.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "charger.h" #include "charger/isl923x_public.h" #include "charger/isl9241_public.h" diff --git a/zephyr/test/drivers/common_charger/src/test_charge_state_v2.c b/zephyr/test/drivers/common_charger/src/test_charge_state_v2.c index 9dfeb5e734..a62ec2b0ea 100644 --- a/zephyr/test/drivers/common_charger/src/test_charge_state_v2.c +++ b/zephyr/test/drivers/common_charger/src/test_charge_state_v2.c @@ -4,7 +4,7 @@ */ #include "battery.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "math_util.h" #include "test/drivers/test_state.h" diff --git a/zephyr/test/drivers/default/src/charge_state_prevent_power_on.c b/zephyr/test/drivers/default/src/charge_state_prevent_power_on.c index ce47ff8042..07e15ea1f6 100644 --- a/zephyr/test/drivers/default/src/charge_state_prevent_power_on.c +++ b/zephyr/test/drivers/default/src/charge_state_prevent_power_on.c @@ -4,7 +4,6 @@ */ #include "charge_state.h" -#include "charge_state_v2.h" #include "test/drivers/test_state.h" #include <zephyr/ztest.h> diff --git a/zephyr/test/drivers/default/src/console_cmd/charge_state.c b/zephyr/test/drivers/default/src/console_cmd/charge_state.c index 8cfd11324f..851725af36 100644 --- a/zephyr/test/drivers/default/src/console_cmd/charge_state.c +++ b/zephyr/test/drivers/default/src/console_cmd/charge_state.c @@ -4,7 +4,6 @@ */ #include "charge_state.h" -#include "charge_state_v2.h" #include "console.h" #include "ec_commands.h" #include "test/drivers/test_state.h" diff --git a/zephyr/test/drivers/default/src/integration/usbc/usb_20v_3a_pd_charger.c b/zephyr/test/drivers/default/src/integration/usbc/usb_20v_3a_pd_charger.c index f2afa5be9a..8b1bd1a6f1 100644 --- a/zephyr/test/drivers/default/src/integration/usbc/usb_20v_3a_pd_charger.c +++ b/zephyr/test/drivers/default/src/integration/usbc/usb_20v_3a_pd_charger.c @@ -166,20 +166,20 @@ ZTEST_F(usb_attach_20v_3a_pd_charger, test_disconnect_battery_not_charging) ZTEST_F(usb_attach_20v_3a_pd_charger, test_disconnect_charge_state) { - struct ec_response_charge_state charge_state; + struct ec_response_charge_state state; disconnect_charger_from_port(fixture); - charge_state = host_cmd_charge_state(0); + state = host_cmd_charge_state(0); - zassert_false(charge_state.get_state.ac, "AC_OK not triggered"); - zassert_equal(charge_state.get_state.chg_current, 0, + zassert_false(state.get_state.ac, "AC_OK not triggered"); + zassert_equal(state.get_state.chg_current, 0, "Max charge current expected 0mA, but was %dmA", - charge_state.get_state.chg_current); - zassert_equal(charge_state.get_state.chg_input_current, + state.get_state.chg_current); + zassert_equal(state.get_state.chg_input_current, CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, "Charge input current limit expected %dmA, but was %dmA", CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, - charge_state.get_state.chg_input_current); + state.get_state.chg_input_current); } ZTEST_F(usb_attach_20v_3a_pd_charger, test_disconnect_typec_status) diff --git a/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_sink.c b/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_sink.c index 930e393691..bff3d9661e 100644 --- a/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_sink.c +++ b/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_sink.c @@ -149,20 +149,20 @@ ZTEST_F(usb_attach_5v_3a_pd_sink, test_disconnect_battery_discharging) ZTEST_F(usb_attach_5v_3a_pd_sink, test_disconnect_charge_state) { - struct ec_response_charge_state charge_state; + struct ec_response_charge_state state; disconnect_sink_from_port(fixture->tcpci_emul); - charge_state = host_cmd_charge_state(0); + state = host_cmd_charge_state(0); - zassert_false(charge_state.get_state.ac, "AC_OK not triggered"); - zassert_equal(charge_state.get_state.chg_current, 0, + zassert_false(state.get_state.ac, "AC_OK not triggered"); + zassert_equal(state.get_state.chg_current, 0, "Max charge current expected 0mA, but was %dmA", - charge_state.get_state.chg_current); - zassert_equal(charge_state.get_state.chg_input_current, + state.get_state.chg_current); + zassert_equal(state.get_state.chg_input_current, CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, "Charge input current limit expected %dmA, but was %dmA", CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, - charge_state.get_state.chg_input_current); + state.get_state.chg_input_current); } ZTEST_F(usb_attach_5v_3a_pd_sink, test_disconnect_typec_status) diff --git a/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_source.c b/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_source.c index c23fe6ed38..252509f9ba 100644 --- a/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_source.c +++ b/zephyr/test/drivers/default/src/integration/usbc/usb_5v_3a_pd_source.c @@ -162,20 +162,20 @@ ZTEST_F(usb_attach_5v_3a_pd_source, test_disconnect_battery_not_charging) ZTEST_F(usb_attach_5v_3a_pd_source, test_disconnect_charge_state) { - struct ec_response_charge_state charge_state; + struct ec_response_charge_state state; disconnect_source_from_port(fixture->tcpci_emul, fixture->charger_emul); - charge_state = host_cmd_charge_state(TEST_PORT); + state = host_cmd_charge_state(TEST_PORT); - zassert_false(charge_state.get_state.ac, "AC_OK not triggered"); - zassert_equal(charge_state.get_state.chg_current, 0, + zassert_false(state.get_state.ac, "AC_OK not triggered"); + zassert_equal(state.get_state.chg_current, 0, "Max charge current expected 0mA, but was %dmA", - charge_state.get_state.chg_current); - zassert_equal(charge_state.get_state.chg_input_current, + state.get_state.chg_current); + zassert_equal(state.get_state.chg_input_current, CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, "Charge input current limit expected %dmA, but was %dmA", CONFIG_PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT, - charge_state.get_state.chg_input_current); + state.get_state.chg_input_current); } ZTEST_F(usb_attach_5v_3a_pd_source, test_disconnect_typec_status) diff --git a/zephyr/test/drivers/dps/src/dps_selection.c b/zephyr/test/drivers/dps/src/dps_selection.c index 4fd0175ffa..bc897ae0bb 100644 --- a/zephyr/test/drivers/dps/src/dps_selection.c +++ b/zephyr/test/drivers/dps/src/dps_selection.c @@ -4,7 +4,7 @@ */ #include "battery.h" -#include "charge_state_v2.h" +#include "charge_state.h" #include "console.h" #include "dps.h" #include "ec_commands.h" diff --git a/zephyr/test/drivers/icm42607/CMakeLists.txt b/zephyr/test/drivers/icm42607/CMakeLists.txt new file mode 100644 index 0000000000..6b4b8a083b --- /dev/null +++ b/zephyr/test/drivers/icm42607/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Add source files +target_sources(app PRIVATE src/icm42607.c) diff --git a/zephyr/test/drivers/icm42607/prj.conf b/zephyr/test/drivers/icm42607/prj.conf new file mode 100644 index 0000000000..16c1ae7c03 --- /dev/null +++ b/zephyr/test/drivers/icm42607/prj.conf @@ -0,0 +1,6 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_PLATFORM_EC_ACCELGYRO_ICM42607=y +CONFIG_PLATFORM_EC_ACCELGYRO_ICM_COMM_I2C=y diff --git a/zephyr/test/drivers/icm42607/sensor.dts b/zephyr/test/drivers/icm42607/sensor.dts new file mode 100644 index 0000000000..8734ce001a --- /dev/null +++ b/zephyr/test/drivers/icm42607/sensor.dts @@ -0,0 +1,74 @@ +/ { + aliases { + icm42607-int = &ms_icm42607_accel; + }; + + motionsense-mutex { + mutex_icm42607: icm42607-mutex { + }; + }; + + motionsense-sensor-data { + icm42607_data: icm42607-drv-data { + compatible = "cros-ec,drvdata-icm42607"; + status = "okay"; + }; + }; + + motionsense-sensor { + ms_icm42607_accel: ms-icm42607-accel { + compatible = "cros-ec,icm42607-accel"; + status = "okay"; + + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&mutex_icm42607>; + port = <&named_i2c1>; + drv-data = <&icm42607_data>; + i2c-spi-addr-flags = "ICM42607_ADDR1_FLAGS"; + active-mask = "SENSOR_ACTIVE_S0_S3_S5"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <10000>; + }; + ec-s3 { + odr = <10000>; + }; + ec-s5 { + odr = <10000>; + }; + }; + }; + + ms_icm42607_gyro: ms-icm42607-gryo { + compatible = "cros-ec,icm42607-gyro"; + status = "okay"; + + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&mutex_icm42607>; + port = <&named_i2c1>; + drv-data = <&icm42607_data>; + i2c-spi-addr-flags = "ICM42607_ADDR1_FLAGS"; + active-mask = "SENSOR_ACTIVE_S0_S3_S5"; + }; + }; +}; + +&i2c1 { + icm42607_emul: icm42607@69 { + compatible = "zephyr,icm42607-emul"; + status = "okay"; + reg = <0x69>; + }; +}; + +/* motionsense framework supports at most 8 sensors, remove two so we can add + * our test target. + */ +&ms_bmi160_accel { + status = "disabled"; +}; +&ms_bmi160_gyro { + status = "disabled"; +}; diff --git a/zephyr/test/drivers/icm42607/src/icm42607.c b/zephyr/test/drivers/icm42607/src/icm42607.c new file mode 100644 index 0000000000..20d2736063 --- /dev/null +++ b/zephyr/test/drivers/icm42607/src/icm42607.c @@ -0,0 +1,466 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "accelgyro.h" +#include "driver/accelgyro_icm42607.h" +#include "driver/accelgyro_icm_common.h" +#include "emul/emul_icm42607.h" +#include "motion_sense.h" +#include "motion_sense_fifo.h" +#include "test/drivers/test_state.h" + +#include <zephyr/kernel.h> +#include <zephyr/ztest.h> + +#define ICM42607_NODE DT_NODELABEL(icm42607_emul) +#define ACC_SENSOR_ID SENSOR_ID(DT_NODELABEL(ms_icm42607_accel)) +#define GYR_SENSOR_ID SENSOR_ID(DT_NODELABEL(ms_icm42607_gyro)) + +static const struct emul *emul = EMUL_DT_GET(ICM42607_NODE); +static struct motion_sensor_t *acc = &motion_sensors[ACC_SENSOR_ID]; +static struct motion_sensor_t *gyr = &motion_sensors[GYR_SENSOR_ID]; + +static void icm42607_set_temp(uint16_t val) +{ + icm42607_emul_write_reg(emul, ICM42607_REG_TEMP_DATA, val >> 8); + icm42607_emul_write_reg(emul, ICM42607_REG_TEMP_DATA + 1, val & 0xFF); +} + +static bool check_sensor_enabled(enum motionsensor_type type) +{ + int reg = icm42607_emul_peek_reg(emul, ICM42607_REG_PWR_MGMT0); + + if (type == MOTIONSENSE_TYPE_ACCEL) { + int mode = reg & 3; + + return mode == 2; + } else if (type == MOTIONSENSE_TYPE_GYRO) { + int mode = (reg >> 2) & 3; + + return mode == 3; + } + + return false; +} + +static void icm42607_push_packet(const int16_t *acc, const int16_t *gyr) +{ + uint8_t buf[16]; + int packet_size = 0; + + if (acc && gyr) { + buf[0] = BIT(6) | BIT(5); /* acc + gyr */ + memcpy(buf + 1, acc, 6); + memcpy(buf + 7, gyr, 6); + packet_size = 16; + } else if (acc) { + buf[0] = BIT(6); /* acc */ + memcpy(buf + 1, acc, 6); + packet_size = 8; + } else if (gyr) { + buf[0] = BIT(5); /* gyr */ + memcpy(buf + 1, gyr, 6); + packet_size = 8; + } + + icm42607_emul_write_reg(emul, ICM42607_REG_INT_STATUS, BIT(2)); + icm42607_emul_push_fifo(emul, buf, packet_size); +} + +static int motion_sense_fifo_pop(int *sensor_num, int16_t *data) +{ + struct ec_response_motion_sensor_data resp = {}; + uint16_t resp_size; + + while (motion_sense_fifo_read(sizeof(resp), 1, &resp, &resp_size)) { + if (resp.flags & MOTIONSENSE_SENSOR_FLAG_TIMESTAMP) { + continue; + } + + *sensor_num = resp.sensor_num; + memcpy(data, resp.data, sizeof(resp.data)); + + return 0; + } + + return -1; +} + +static void test_fifo(const int16_t *acc_expected, const int16_t *gyr_expected) +{ + int sensor_num = -1; + int16_t data[3] = {}; + + motion_sense_fifo_reset(); + acc->oversampling_ratio = 1; + gyr->oversampling_ratio = 1; + + icm42607_push_packet(acc_expected, gyr_expected); + icm42607_interrupt(0); + k_sleep(K_SECONDS(1)); + + if (acc_expected) { + zassert_equal(motion_sense_fifo_pop(&sensor_num, data), 0); + zassert_equal(sensor_num, ACC_SENSOR_ID); + zassert_equal(acc_expected[0], data[0]); + zassert_equal(acc_expected[1], data[1]); + zassert_equal(acc_expected[2], data[2]); + } + + if (gyr_expected) { + zassert_equal(motion_sense_fifo_pop(&sensor_num, data), 0); + zassert_equal(sensor_num, GYR_SENSOR_ID); + zassert_equal(gyr_expected[0], data[0]); + zassert_equal(gyr_expected[1], data[1]); + zassert_equal(gyr_expected[2], data[2]); + } +} + +/* verify that icm42607 driver returns error when too many data in fifo */ +ZTEST_USER(icm42607, test_fifo_full) +{ + const uint8_t junk[512] = {}; + int sensor_num = -1; + int16_t data[3] = {}; + + icm42607_push_packet((int16_t[]){ -32768, -32768, -32768 }, NULL); + icm42607_emul_push_fifo(emul, junk, sizeof(junk)); + icm42607_interrupt(0); + k_sleep(K_SECONDS(1)); + + zassert_not_equal(motion_sense_fifo_pop(&sensor_num, data), 0); +} + +ZTEST_USER(icm42607, test_invalid_packet) +{ + const uint8_t junk[16] = { + 0x80, + }; /* bad packet header */ + int sensor_num = -1; + int16_t data[3] = {}; + + icm42607_emul_push_fifo(emul, junk, sizeof(junk)); + icm42607_interrupt(0); + k_sleep(K_SECONDS(1)); + + zassert_not_equal(motion_sense_fifo_pop(&sensor_num, data), 0); +} + +/* verify that icm42607 driver doesn't send bad data to motionsense fifo */ +ZTEST_USER(icm42607, test_invalid_sensor_data) +{ + int sensor_num = -1; + int16_t data[3] = {}; + + icm42607_push_packet((int16_t[]){ -32768, -32768, -32768 }, NULL); + icm42607_interrupt(0); + k_sleep(K_SECONDS(1)); + + zassert_not_equal(motion_sense_fifo_pop(&sensor_num, data), 0); +} + +ZTEST_USER(icm42607, test_fifo_read) +{ + /* 2 sensor packet */ + test_fifo((int16_t[]){ 1111, 2222, 3333 }, + (int16_t[]){ 4444, 5555, 6666 }); + + /* acc only */ + test_fifo((int16_t[]){ 1111, 2222, 3333 }, NULL); + + /* gyr only */ + test_fifo(NULL, (int16_t[]){ 4444, 5555, 6666 }); +} + +ZTEST_USER(icm42607, test_resolution) +{ + zassert_equal(acc->drv->get_resolution(acc), 16); +} + +/* verify that set_data_rate enables or disables the sensor */ +ZTEST_USER(icm42607, test_sensor_enable) +{ + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_ACCEL)); + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_GYRO)); + + zassert_ok(acc->drv->set_data_rate(acc, 12500, 1)); + zassert_true(check_sensor_enabled(MOTIONSENSE_TYPE_ACCEL)); + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_GYRO)); + + zassert_ok(acc->drv->set_data_rate(gyr, 12500, 1)); + zassert_true(check_sensor_enabled(MOTIONSENSE_TYPE_ACCEL)); + zassert_true(check_sensor_enabled(MOTIONSENSE_TYPE_GYRO)); + + zassert_ok(acc->drv->set_data_rate(gyr, 0, 1)); + zassert_true(check_sensor_enabled(MOTIONSENSE_TYPE_ACCEL)); + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_GYRO)); + + zassert_ok(acc->drv->set_data_rate(acc, 0, 1)); + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_ACCEL)); + zassert_false(check_sensor_enabled(MOTIONSENSE_TYPE_GYRO)); +} + +ZTEST_USER(icm42607, test_data_rate) +{ + zassert_ok(acc->drv->set_data_rate(acc, 12500, 1)); + zassert_equal(acc->drv->get_data_rate(acc), 12500); + zassert_equal(icm42607_emul_peek_reg(emul, ICM42607_REG_ACCEL_CONFIG0) & + 0xF, + 0xC); + + /* 24Hz should round up to 25Hz */ + zassert_ok(gyr->drv->set_data_rate(gyr, 24000, 1)); + zassert_equal(gyr->drv->get_data_rate(gyr), 25000); + zassert_equal(icm42607_emul_peek_reg(emul, ICM42607_REG_GYRO_CONFIG0) & + 0xF, + 0xB); + + /* return error if data rate is out of supported range */ + zassert_not_equal(gyr->drv->set_data_rate(gyr, 6250, 0), 0); + zassert_not_equal(acc->drv->set_data_rate(acc, 1600000, 0), 0); +} + +ZTEST_USER(icm42607, test_offset_out_of_range) +{ + int16_t acc_offset[3]; + int16_t acc_offset_input[3] = { 10000, -10000, 0 }; + int16_t acc_temp; + + zassert_ok(acc->drv->init(acc)); + + zassert_ok(acc->drv->set_offset(acc, acc_offset_input, 40)); + zassert_ok(acc->drv->get_offset(acc, acc_offset, &acc_temp)); + + /* icm42607 internally stores offset in 12bit signed integer, + * input is clamped into range [2047, -2048], and then scaled to + * ec unit, so the result is [1023.5, -1024] => [1024, -1024] + */ + zassert_equal(acc_offset[0], 1024); + zassert_equal(acc_offset[1], -1024, "got %d", acc_offset[1]); + zassert_equal(acc_offset[2], 0); + zassert_equal(acc_temp, EC_MOTION_SENSE_INVALID_CALIB_TEMP); +} + +ZTEST_USER(icm42607, test_offset) +{ + int16_t acc_offset[3], gyr_offset[3]; + /* use multiplies of 32 to avoid rounding error */ + int16_t acc_offset_expected[3] = { 32, 32 * 2, 32 * 3 }; + int16_t gyr_offset_expected[3] = { 32 * 4, 32 * 5, 32 * 6 }; + int16_t acc_temp, gyr_temp; + + zassert_ok(acc->drv->init(acc)); + zassert_ok(gyr->drv->init(gyr)); + + zassert_ok(acc->drv->set_offset(acc, acc_offset_expected, 40)); + zassert_ok(gyr->drv->set_offset(gyr, gyr_offset_expected, 80)); + zassert_ok(acc->drv->get_offset(acc, acc_offset, &acc_temp)); + zassert_ok(gyr->drv->get_offset(gyr, gyr_offset, &gyr_temp)); + + zassert_equal(acc_offset[0], acc_offset_expected[0]); + zassert_equal(acc_offset[1], acc_offset_expected[1]); + zassert_equal(acc_offset[2], acc_offset_expected[2]); + zassert_equal(acc_temp, EC_MOTION_SENSE_INVALID_CALIB_TEMP); + zassert_equal(gyr_offset[0], gyr_offset_expected[0]); + zassert_equal(gyr_offset[1], gyr_offset_expected[1]); + zassert_equal(gyr_offset[2], gyr_offset_expected[2]); + zassert_equal(gyr_temp, EC_MOTION_SENSE_INVALID_CALIB_TEMP); +} + +ZTEST_USER(icm42607, test_scale) +{ + uint16_t acc_scale[3], gyr_scale[3]; + int16_t acc_temp, gyr_temp; + + zassert_ok(acc->drv->init(acc)); + zassert_ok(gyr->drv->init(gyr)); + + zassert_ok(acc->drv->set_scale(acc, (uint16_t[3]){ 1, 2, 3 }, 4)); + zassert_ok(gyr->drv->set_scale(gyr, (uint16_t[3]){ 5, 6, 7 }, 8)); + zassert_ok(gyr->drv->get_scale(acc, acc_scale, &acc_temp)); + zassert_ok(gyr->drv->get_scale(gyr, gyr_scale, &gyr_temp)); + + zassert_equal(acc_scale[0], 1); + zassert_equal(acc_scale[1], 2); + zassert_equal(acc_scale[2], 3); + zassert_equal(acc_temp, EC_MOTION_SENSE_INVALID_CALIB_TEMP); + zassert_equal(gyr_scale[0], 5); + zassert_equal(gyr_scale[1], 6); + zassert_equal(gyr_scale[2], 7); + zassert_equal(gyr_temp, EC_MOTION_SENSE_INVALID_CALIB_TEMP); +} + +ZTEST_USER(icm42607, test_invalid_read) +{ + intv3_t v; + + zassert_ok(acc->drv->init(acc)); + zassert_ok(gyr->drv->init(gyr)); + + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ, 0x00); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 1, 0x80); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 2, 0x00); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 3, 0x80); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 4, 0x00); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 5, 0x80); + + /* return cached value (raw_xyz) on invalid data */ + zassert_ok(acc->drv->read(acc, v)); + zassert_equal(v[0], 0); + zassert_equal(v[1], 0); + zassert_equal(v[2], 0); +} + +/* verify that read() works correctly, and scale is applied */ +ZTEST_USER(icm42607, test_read) +{ + intv3_t v; + const uint16_t scale[3] = { 16384, 16384, 16384 }; /* 0.5x scale */ + + zassert_ok(acc->drv->init(acc)); + zassert_ok(gyr->drv->init(gyr)); + + /* verify that sensor data format is configured to little endian */ + int intf_config0 = + icm42607_emul_peek_reg(emul, ICM42607_REG_INTF_CONFIG0); + zassert_equal(intf_config0 & ICM42607_SENSOR_DATA_ENDIAN, 0); + zassert_ok(acc->drv->set_scale(acc, scale, 0)); + + /* test accel read, 16bit LE */ + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ, 0x01); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 1, 0x02); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 2, 0x03); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 3, 0x04); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 4, 0x05); + icm42607_emul_write_reg(emul, ICM42607_REG_ACCEL_DATA_XYZ + 5, 0x06); + + zassert_ok(acc->drv->read(acc, v)); + zassert_equal(v[0], 0x0201 / 2); + zassert_equal(v[1], 0x0403 / 2); + zassert_equal(v[2], 0x0605 / 2); + + /* test gyro read, 16bit LE */ + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ, 0x0A); + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ + 1, 0x0B); + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ + 2, 0x0C); + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ + 3, 0x0D); + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ + 4, 0x0E); + icm42607_emul_write_reg(emul, ICM42607_REG_GYRO_DATA_XYZ + 5, 0x0F); + + zassert_ok(gyr->drv->read(gyr, v)); + zassert_equal(v[0], 0x0B0A); + zassert_equal(v[1], 0x0D0C); + zassert_equal(v[2], 0x0F0E); +} + +/* read() immediately after sensor enabled should fail */ +ZTEST_USER(icm42607, test_read_not_stabilized) +{ + intv3_t v; + + zassert_ok(acc->drv->set_data_rate(acc, 0, 1)); + zassert_ok(acc->drv->set_data_rate(acc, 10000, 1)); + zassert_not_equal(acc->drv->read(acc, v), 0); + + sleep(1); + zassert_equal(acc->drv->read(acc, v), 0); +} + +ZTEST_USER(icm42607, test_set_range) +{ + int reg_val; + + /* set 5G, round down to 4G, expect reg val = 2 */ + zassert_ok(acc->drv->set_range(acc, 5, 0)); + reg_val = (icm42607_emul_peek_reg(emul, ICM42607_REG_ACCEL_CONFIG0) >> + 5) & + 3; + zassert_equal(reg_val, 2); + + /* set 5G, round up to 8G, expect reg val = 1 */ + zassert_ok(acc->drv->set_range(acc, 5, 1)); + reg_val = (icm42607_emul_peek_reg(emul, ICM42607_REG_ACCEL_CONFIG0) >> + 5) & + 3; + zassert_equal(reg_val, 1); + + /* set 1500dps, round down to 1000dps, expect reg val = 1 */ + zassert_ok(gyr->drv->set_range(gyr, 1500, 0)); + reg_val = + (icm42607_emul_peek_reg(emul, ICM42607_REG_GYRO_CONFIG0) >> 5) & + 3; + zassert_equal(reg_val, 1); + + /* set 1500dps, round down to 2000dps, expect reg val = 0 */ + zassert_ok(gyr->drv->set_range(gyr, 1500, 1)); + reg_val = + (icm42607_emul_peek_reg(emul, ICM42607_REG_GYRO_CONFIG0) >> 5) & + 3; + zassert_equal(reg_val, 0); +} + +/* Verify the temperature matches following formula: + * Temperature in C = (REG_DATA / 128) + 25 + */ +ZTEST_USER(icm42607, test_read_temp) +{ + int temp; + + /* expect 0C = 273.15K */ + icm42607_set_temp(-25 * 128); + zassert_ok(acc->drv->read_temp(acc, &temp)); + zassert_equal(temp, 273); + + /* expect 100C = 373.15K */ + icm42607_set_temp(75 * 128); + zassert_ok(acc->drv->read_temp(acc, &temp)); + zassert_equal(temp, 373); + + /* expect 25C = 298K */ + icm42607_set_temp(0); + zassert_ok(acc->drv->read_temp(acc, &temp)); + zassert_equal(temp, 298); + + /* reset value */ + icm42607_set_temp(-32768); + zassert_not_equal(acc->drv->read_temp(acc, &temp), 0); +} + +ZTEST_USER(icm42607, test_init) +{ + struct i2c_common_emul_data *common_data = + emul_icm42607_get_i2c_common_data(emul); + + icm42607_emul_write_reg(emul, ICM42607_REG_WHO_AM_I, + ICM42607_CHIP_ICM42607P); + zassert_ok(acc->drv->init(acc)); + + icm42607_emul_write_reg(emul, ICM42607_REG_WHO_AM_I, 0x87); + zassert_not_equal(acc->drv->init(acc), 0); + + i2c_common_emul_set_read_fail_reg(common_data, ICM42607_REG_WHO_AM_I); + zassert_not_equal(acc->drv->init(acc), 0); +} + +static void icm42607_before(void *fixture) +{ + struct i2c_common_emul_data *common_data = + emul_icm42607_get_i2c_common_data(emul); + + ARG_UNUSED(fixture); + + i2c_common_emul_set_read_fail_reg(common_data, + I2C_COMMON_EMUL_NO_FAIL_REG); + icm42607_emul_reset(emul); + icm_reset_stabilize_ts(acc); + icm_reset_stabilize_ts(gyr); + memset(acc->raw_xyz, 0, sizeof(intv3_t)); + memset(gyr->raw_xyz, 0, sizeof(intv3_t)); + motion_sense_fifo_reset(); + acc->oversampling_ratio = 1; + gyr->oversampling_ratio = 1; +} + +ZTEST_SUITE(icm42607, drivers_predicate_post_main, NULL, icm42607_before, NULL, + NULL); diff --git a/zephyr/test/drivers/keyboard_8042/CMakeLists.txt b/zephyr/test/drivers/keyboard_8042/CMakeLists.txt new file mode 100644 index 0000000000..ed131ec38e --- /dev/null +++ b/zephyr/test/drivers/keyboard_8042/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +target_sources(app PRIVATE + src/keyboard_8042.c +) + diff --git a/zephyr/test/drivers/keyboard_8042/src/keyboard_8042.c b/zephyr/test/drivers/keyboard_8042/src/keyboard_8042.c new file mode 100644 index 0000000000..82779bfdb2 --- /dev/null +++ b/zephyr/test/drivers/keyboard_8042/src/keyboard_8042.c @@ -0,0 +1,196 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "console.h" +#include "keyboard_8042.h" +#include "test/drivers/test_mocks.h" +#include "test/drivers/test_state.h" + +#include <string.h> + +#include <zephyr/drivers/emul.h> +#include <zephyr/drivers/gpio.h> +#include <zephyr/drivers/gpio/gpio_emul.h> +#include <zephyr/fff.h> +#include <zephyr/shell/shell_dummy.h> +#include <zephyr/ztest.h> + +ZTEST(keyboard_8042, test_console_cmd__typematic__status) +{ + const char *outbuffer; + size_t buffer_size; + + /* Set a typematic scan code to verify */ + const uint8_t scan_code[] = { 0x01, 0x02, 0x03 }; + + set_typematic_key(scan_code, ARRAY_SIZE(scan_code)); + + /* With no args, print current state */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 typematic")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + /* Check for some expected lines based off default typematic state */ + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "From host: 0x2b")); + zassert_ok(!strstr(outbuffer, "First delay: 500 ms")); + zassert_ok(!strstr(outbuffer, "Inter delay: 91 ms")); + zassert_ok( + !strstr(outbuffer, "Repeat scan code: {0x01, 0x02, 0x03, }")); +} + +ZTEST(keyboard_8042, test_console_cmd__typematic__set_delays) +{ + const char *outbuffer; + size_t buffer_size; + + /* Set first delay and inter delay */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 typematic 123 456")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + /* Check for some expected lines */ + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "First delay: 123 ms")); + zassert_ok(!strstr(outbuffer, "Inter delay: 456 ms")); +} + +ZTEST(keyboard_8042, test_console_cmd__codeset__set_codeset1) +{ + const char *outbuffer; + size_t buffer_size; + + /* Switch to codeset 1 and verify output */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 codeset 1")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Set: 1")); +} + +ZTEST(keyboard_8042, test_console_cmd__codeset__set_invalid) +{ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "8042 codeset 999")); +} + +ZTEST(keyboard_8042, test_console_cmd__ram__writeread) +{ + const char *outbuffer; + size_t buffer_size; + + /* Write a byte and verify the readback in console output */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 ctrlram 0x1f 0xaa")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "31 = 0xaa")); +} + +ZTEST(keyboard_8042, test_console_cmd__ram__invalid) +{ + /* Missing args */ + zassert_equal(EC_ERROR_PARAM_COUNT, + shell_execute_cmd(get_ec_shell(), "8042 ctrlram")); + + /* Address out of bounds */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "8042 ctrlram 9999")); +} + +ZTEST(keyboard_8042, test_console_cmd__enable__true) +{ + const char *outbuffer; + size_t buffer_size; + + /* Enable the keyboard and verify in console output */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 kbd y")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Enabled: 1")); +} + +ZTEST(keyboard_8042, test_console_cmd__enable__invalid) +{ + /* Non-bool arg */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "8042 kbd abc")); +} + +ZTEST(keyboard_8042, test_console_cmd__internal) +{ + const char *outbuffer; + size_t buffer_size; + + uint8_t resend_command[] = { 7, 8, 9 }; + + test_keyboard_8042_set_resend_command(resend_command, + ARRAY_SIZE(resend_command)); + + /* Dump the internal state of the keyboard driver */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042 internal")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "keyboard_enabled=0")); + zassert_ok(!strstr(outbuffer, "i8042_keyboard_irq_enabled=0")); + zassert_ok(!strstr(outbuffer, "i8042_aux_irq_enabled=0")); + zassert_ok(!strstr(outbuffer, "keyboard_enabled=0")); + zassert_ok(!strstr(outbuffer, "keystroke_enabled=0")); + zassert_ok(!strstr(outbuffer, "aux_chan_enabled=0")); + zassert_ok(!strstr(outbuffer, "controller_ram_address=0x00")); + zassert_ok(!strstr(outbuffer, "resend_command[]={0x07, 0x08, 0x09, }")); + zassert_ok(!strstr(outbuffer, "A20_status=0")); +} + +ZTEST(keyboard_8042, test_console_cmd__invalid) +{ + /* Non-existent subcommand */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "8042 foobar")); +} + +ZTEST(keyboard_8042, test_console_cmd__all) +{ + const char *outbuffer; + size_t buffer_size; + + /* Run all the subcommands */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "8042")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + /* Just look for the headers since we already tested the individual + * subcommands + */ + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "- Typematic:")); + zassert_ok(!strstr(outbuffer, "- Codeset:")); + zassert_ok(!strstr(outbuffer, "- Control RAM:")); + zassert_ok(!strstr(outbuffer, "- Keyboard:")); + zassert_ok(!strstr(outbuffer, "- Internal:")); +} + +static void reset(void *fixture) +{ + ARG_UNUSED(fixture); + + test_keyboard_8042_reset(); +} + +ZTEST_SUITE(keyboard_8042, drivers_predicate_post_main, NULL, reset, reset, + NULL); diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml index 695a2bcc66..06d75f9720 100644 --- a/zephyr/test/drivers/testcase.yaml +++ b/zephyr/test/drivers/testcase.yaml @@ -90,6 +90,7 @@ tests: - prj.conf - ap_mux_control/prj.conf drivers.ap_vdm_control: + timeout: 360 extra_configs: - CONFIG_LINK_TEST_SUITE_AP_VDM_CONTROL=y extra_conf_files: @@ -202,6 +203,15 @@ tests: - CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI=n - CONFIG_PLATFORM_EC_HOST_INTERFACE_SHI=y - CONFIG_PLATFORM_EC_SWITCH=n + drivers.icm42607: + extra_configs: + - CONFIG_PLATFORM_EC_ACCELGYRO_BMI160=n + - CONFIG_LINK_TEST_SUITE_ICM42607=y + - CONFIG_PLATFORM_EC_ACCELGYRO_ICM42607=y + - CONFIG_PLATFORM_EC_ACCELGYRO_ICM_COMM_I2C=y + extra_dtc_overlay_files: + - ./boards/native_posix.overlay + - ./icm42607/sensor.dts drivers.isl923x: extra_configs: - CONFIG_LINK_TEST_SUITE_ISL923X=y @@ -227,6 +237,11 @@ tests: extra_configs: - CONFIG_LINK_TEST_SUITE_IT8XXX2_HW_SHA256=y - CONFIG_PLATFORM_EC_SHA256_HW_ACCELERATE=y + drivers.keyboard_8042: + extra_configs: + - CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=n + - CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y + - CONFIG_LINK_TEST_SUITE_KEYBOARD_8042=y drivers.keyboard_scan: extra_configs: - CONFIG_LINK_TEST_SUITE_KEYBOARD_SCAN=y diff --git a/zephyr/test/ocpc/src/ocpc.c b/zephyr/test/ocpc/src/ocpc.c index dd7e2733e7..5d0da0c117 100644 --- a/zephyr/test/ocpc/src/ocpc.c +++ b/zephyr/test/ocpc/src/ocpc.c @@ -2,7 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#include "charge_state_v2.h" +#include "charge_state.h" #include "console.h" #include "host_command.h" #include "ocpc.h" diff --git a/zephyr/test/skyrim/testcase.yaml b/zephyr/test/skyrim/testcase.yaml index 403b8f7e6c..1dfae464cf 100644 --- a/zephyr/test/skyrim/testcase.yaml +++ b/zephyr/test/skyrim/testcase.yaml @@ -126,3 +126,9 @@ tests: extra_configs: - CONFIG_TEST_BOARD_WINTERHOLD=y - CONFIG_TEST_BOARD_USB_MUX_CONFIG_CUSTOM=y + + skyrim.winterhold.fan: + extra_configs: + - CONFIG_TEST_BOARD_WINTERHOLD=y + - CONFIG_TEST_BOARD_FAN=y + - CONFIG_TEST_BOARD_FAN_CUSTOM=y diff --git a/zephyr/test/skyrim/tests/baseboard/src/power_signals.c b/zephyr/test/skyrim/tests/baseboard/src/power_signals.c index c4bfba04a7..82e42acaa1 100644 --- a/zephyr/test/skyrim/tests/baseboard/src/power_signals.c +++ b/zephyr/test/skyrim/tests/baseboard/src/power_signals.c @@ -87,19 +87,31 @@ ZTEST(power_signals, test_baseboard_suspend_change) { const struct gpio_dt_spec *gpio_ec_disable_disp_bl = GPIO_DT_FROM_NODELABEL(gpio_ec_disable_disp_bl); - const struct gpio_dt_spec *usb_a1_retimer_en = - GPIO_DT_FROM_NODELABEL(usb_a1_retimer_en); struct ap_power_ev_data data; data.event = AP_POWER_SUSPEND; baseboard_suspend_change(NULL, data); zassert_true(gpio_emul_output_get_dt(gpio_ec_disable_disp_bl)); - zassert_false(gpio_emul_output_get_dt(usb_a1_retimer_en)); data.event = AP_POWER_RESUME; baseboard_suspend_change(NULL, data); zassert_false(gpio_emul_output_get_dt(gpio_ec_disable_disp_bl)); +} + +ZTEST(power_signals, test_baseboard_shutdown_change) +{ + const struct gpio_dt_spec *usb_a1_retimer_en = + GPIO_DT_FROM_NODELABEL(usb_a1_retimer_en); + + struct ap_power_ev_data data; + + data.event = AP_POWER_SHUTDOWN; + baseboard_suspend_change(NULL, data); + zassert_false(gpio_emul_output_get_dt(usb_a1_retimer_en)); + + data.event = AP_POWER_STARTUP; + baseboard_suspend_change(NULL, data); zassert_true(gpio_emul_output_get_dt(usb_a1_retimer_en)); } diff --git a/zephyr/test/skyrim/tests/winterhold/CMakeLists.txt b/zephyr/test/skyrim/tests/winterhold/CMakeLists.txt index 673b09bdcd..39ded69058 100644 --- a/zephyr/test/skyrim/tests/winterhold/CMakeLists.txt +++ b/zephyr/test/skyrim/tests/winterhold/CMakeLists.txt @@ -3,4 +3,5 @@ # found in the LICENSE file. target_sources(app PRIVATE src/common.c) -target_sources_ifdef(CONFIG_TEST_BOARD_PPC_CONFIG app PRIVATE src/ppc_config.c)
\ No newline at end of file +target_sources_ifdef(CONFIG_TEST_BOARD_PPC_CONFIG app PRIVATE src/ppc_config.c) +target_sources_ifdef(CONFIG_TEST_BOARD_FAN_CUSTOM app PRIVATE src/fan.c) diff --git a/zephyr/test/skyrim/tests/winterhold/src/fan.c b/zephyr/test/skyrim/tests/winterhold/src/fan.c new file mode 100644 index 0000000000..a7af0d2da1 --- /dev/null +++ b/zephyr/test/skyrim/tests/winterhold/src/fan.c @@ -0,0 +1,165 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <zephyr/fff.h> +#include <zephyr/kernel.h> +#include <zephyr/logging/log.h> +#include <zephyr/ztest.h> + +#include <cros_board_info.h> +#include <cros_cbi.h> +#include <fan.h> +#include <hooks.h> + +FAKE_VOID_FUNC(fan_set_duty, int, int); +FAKE_VALUE_FUNC(int, fan_get_duty, int); + +struct fan_conf conf; +struct fan_rpm rpm; + +const struct fan_t fans[1] = { { .conf = &conf, .rpm = &rpm } }; +struct fan_data fan_data[1]; + +K_TIMER_DEFINE(ktimer, NULL, NULL); + +static void fan_set_duty_mock(int ch, int duty) +{ + zassert_equal(ch, 0); + zassert_between_inclusive(duty, 0, 100); + + fan_data[ch].pwm_percent = duty; +} + +static int fan_get_duty_mock(int ch) +{ + zassert_equal(ch, 0); + zassert_between_inclusive(fan_data[ch].pwm_percent, 0, 100); + + return fan_data[ch].pwm_percent; +} + +static int duty_to_rpm(int duty) +{ + const float ratio = 0.015; + + zassert_between_inclusive(duty, 0, 100); + + return (int)((float)duty / ratio); +} + +static void fan_tick(void) +{ + int rpm_diff; + int duty; + + duty = fan_data[0].pwm_percent; + + rpm_diff = duty_to_rpm(duty) - fan_data[0].rpm_actual; + + /* Clamp rpm_diff. This essentially emulates fan inertia. */ + if (rpm_diff > 0) + rpm_diff = MIN(rpm_diff, 500); + if (rpm_diff < 0) + rpm_diff = MAX(rpm_diff, -500); + + fan_data[0].rpm_actual += rpm_diff; +} + +static void fan_test_begin(void *fixture) +{ + ARG_UNUSED(fixture); + RESET_FAKE(fan_set_duty); + RESET_FAKE(fan_get_duty); + + fan_set_duty_fake.custom_fake = fan_set_duty_mock; + fan_get_duty_fake.custom_fake = fan_get_duty_mock; + + /* + * This is normally read from DT. + * The problem is that we don't want to pull the entire fan framework + * for this test. Instead initialize it here. + * All the values come from + * zephyr/program/skyrim/winterhold/project.overlay. + */ + memset(&conf, 0, sizeof(conf)); + memset(&rpm, 0, sizeof(rpm)); + + rpm.rpm_max = 4800; + rpm.rpm_deviation = 3; + + memset(&fan_data[0], 0, sizeof(fan_data[0])); +} + +/* Only FAN 0 should be supported. */ +ZTEST(fan, test_fan_invalid_arg) +{ + enum fan_status status; + + status = board_override_fan_control_duty(1); + zassert_equal(status, FAN_STATUS_FRUSTRATED); +} + +/* + * Check whether we can ramp up into rpm_max in 5s. + * The time limit is selected on a per board basis. + * It depends on the thermal capacity of the radiator and CPU TDP. + * Basically we want to ensure that fan ramps up fast enough + * to prevent the CPU from thermal throttling. + */ +ZTEST(fan, test_fan_max_rpm) +{ + enum fan_status status; + int deviation; + + fan_data[0].rpm_target = rpm.rpm_max; + k_timer_start(&ktimer, K_SECONDS(5), K_NO_WAIT); + + while (k_timer_remaining_ticks(&ktimer) != 0) { + status = board_override_fan_control_duty(0); + zassert_not_equal(status, FAN_STATUS_FRUSTRATED); + fan_tick(); + k_sleep(K_TICKS(1)); + } + + deviation = rpm.rpm_deviation * rpm.rpm_max / 100; + zassert_true(fan_set_duty_fake.call_count > 1); + zassert_within(fan_data[0].rpm_actual, rpm.rpm_max, deviation); + zassert_equal(status, FAN_STATUS_LOCKED); +} + +/* Check for FAN_STATUS_STOPPED when the fan is in fact stopped. */ +ZTEST(fan, test_fan_off) +{ + enum fan_status status; + + status = board_override_fan_control_duty(0); + zassert_equal(status, FAN_STATUS_STOPPED); + zassert_equal(fan_set_duty_fake.call_count, 0); +} + +/* If we can't achieve selected RPM, FAN_STATUS_FRUSTRATED is expected. */ +ZTEST(fan, test_fan_frustrated_max) +{ + enum fan_status status; + + /* + * 10 seconds should be more than enough for implementation to realize + * that it can't get up to 10k RPM + */ + fan_data[0].rpm_target = 10000; + k_timer_start(&ktimer, K_SECONDS(10), K_NO_WAIT); + + while (k_timer_remaining_ticks(&ktimer) != 0) { + status = board_override_fan_control_duty(0); + if (status == FAN_STATUS_FRUSTRATED) + break; + + fan_tick(); + k_sleep(K_TICKS(1)); + } + zassert_true(fan_set_duty_fake.call_count > 1); + zassert_equal(status, FAN_STATUS_FRUSTRATED); +} + +ZTEST_SUITE(fan, NULL, NULL, fan_test_begin, NULL, NULL); diff --git a/zephyr/test/system_safe_mode/src/system_safe_mode.c b/zephyr/test/system_safe_mode/src/system_safe_mode.c index f75a27ec84..036bc4c8e0 100644 --- a/zephyr/test/system_safe_mode/src/system_safe_mode.c +++ b/zephyr/test/system_safe_mode/src/system_safe_mode.c @@ -177,7 +177,7 @@ ZTEST_USER(system_safe_mode, test_print_stack_contents) uint16_t write_count; regex_t regex; - char *regex_str = "========== Stack Contents ===========\n" + char *regex_str = "Stack Contents\n" "[0-9a-f]{8}: 00000000 00000001 00000002 00000003\n" "[0-9a-f]{8}: 00000004 00000005 00000006 00000007\n" "[0-9a-f]{8}: 00000008 00000009 0000000a 0000000b\n" |