summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCommit Bot <commit-bot@chromium.org>2021-08-03 03:00:00 +0000
committerCommit Bot <commit-bot@chromium.org>2021-08-03 03:00:00 +0000
commit1de9be8601ef4699173427bfb974256d77c0518b (patch)
tree1835aaabfe9f11a62b8aa31369cff949326ef5d5
parentad375f6d147a639dc7e1c4f803ec8ccd68cbcd1b (diff)
parent1c05115a1965036eb2212958daae574ec0ba00a9 (diff)
downloadchrome-ec-1de9be8601ef4699173427bfb974256d77c0518b.tar.gz
Merge "Merge remote-tracking branch cros/main into firmware-volteer-13672.B-main" into firmware-volteer-13672.B-main
-rw-r--r--baseboard/asurada/regulator.c2
-rw-r--r--baseboard/brya/baseboard.h2
-rw-r--r--baseboard/brya/usb_pd_policy.c5
-rw-r--r--baseboard/dragonegg/baseboard.c2
-rw-r--r--baseboard/dragonegg/baseboard.h2
-rw-r--r--baseboard/grunt/baseboard.c2
-rw-r--r--baseboard/grunt/baseboard.h2
-rw-r--r--baseboard/guybrush/baseboard.c2
-rw-r--r--baseboard/guybrush/baseboard.h2
-rw-r--r--baseboard/intelrvp/baseboard.h2
-rw-r--r--baseboard/intelrvp/ite_ec.c2
-rw-r--r--baseboard/intelrvp/mchp_ec.c2
-rw-r--r--baseboard/intelrvp/npcx_ec.c2
-rw-r--r--baseboard/ite_evb/baseboard.c4
-rw-r--r--baseboard/ite_evb/baseboard.h2
-rw-r--r--baseboard/kukui/baseboard.c25
-rw-r--r--baseboard/kukui/baseboard.h2
-rw-r--r--baseboard/octopus/baseboard.c2
-rw-r--r--baseboard/octopus/baseboard.h2
-rw-r--r--baseboard/volteer/baseboard.h2
-rw-r--r--baseboard/zork/baseboard.c2
-rw-r--r--baseboard/zork/baseboard.h2
-rw-r--r--baseboard/zork/variant_dalboz.c5
-rw-r--r--board/aleena/board.c2
-rw-r--r--board/aleena/board.h5
-rw-r--r--board/atlas/board.c2
-rw-r--r--board/atlas/board.h2
-rw-r--r--board/berknip/board.h5
-rw-r--r--board/blipper/board.c13
-rw-r--r--board/blipper/board.h1
-rw-r--r--board/bloog/board.h5
-rw-r--r--board/bobba/board.h2
-rw-r--r--board/boldar/board.c2
-rw-r--r--board/brya/keyboard.c2
-rw-r--r--board/burnet/board.c4
-rw-r--r--board/careena/board.h5
-rw-r--r--board/cerise/board.c2
-rw-r--r--board/cheza/base_detect.c2
-rw-r--r--board/chronicler/board.h5
-rw-r--r--board/chronicler/keyboard.c2
-rw-r--r--board/coachz/base_detect.c2
-rw-r--r--board/collis/board.c2
-rw-r--r--board/copano/board.c2
-rw-r--r--board/coral/board.c6
-rw-r--r--board/coral/board.h2
-rw-r--r--board/dalboz/board.c2
-rw-r--r--board/damu/board.c2
-rw-r--r--board/delbin/board.c2
-rw-r--r--board/dirinboz/board.c2
-rw-r--r--board/dirinboz/board.h5
-rw-r--r--board/dood/board.h2
-rw-r--r--board/dratini/board.h5
-rw-r--r--board/drawcia/board.h5
-rw-r--r--board/drobit/board.c2
-rw-r--r--board/eldrid/board.c2
-rw-r--r--board/elemi/board.c2
-rw-r--r--board/elemi/board.h5
-rw-r--r--board/eve/board.c4
-rw-r--r--board/eve/board.h2
-rw-r--r--board/ezkinil/board.h2
-rw-r--r--board/fennel/board.c105
-rw-r--r--board/fennel/board.h4
-rw-r--r--board/fennel/gpio.inc2
-rw-r--r--board/garg/board.h2
-rw-r--r--board/genesis/board.c70
-rw-r--r--board/genesis/board.h3
-rw-r--r--board/genesis/gpio.inc19
-rw-r--r--board/gimble/battery.c78
-rw-r--r--board/gimble/board.h18
-rw-r--r--board/gimble/gpio.inc3
-rw-r--r--board/gimble/keyboard.c2
-rw-r--r--board/gimble/sensors.c49
-rw-r--r--board/gimble/usbc_config.c20
-rw-r--r--board/glkrvp_ite/board.c2
-rw-r--r--board/glkrvp_ite/board.h2
-rw-r--r--board/gumboz/board.c2
-rw-r--r--board/gumboz/board.h5
-rw-r--r--board/haboki/board.h5
-rw-r--r--board/halvor/board.c2
-rw-r--r--board/hammer/board.c4
-rw-r--r--board/hammer/variants.h2
-rw-r--r--board/hatch_fp/board_rw.c6
-rw-r--r--board/hatch_fp/fpsensor_detect_rw.c6
-rw-r--r--board/herobrine_npcx7/board.c2
-rw-r--r--board/herobrine_npcx7/board.h2
-rw-r--r--board/herobrine_npcx9/board.c2
-rw-r--r--board/herobrine_npcx9/board.h2
-rw-r--r--board/homestar/base_detect.c2
-rw-r--r--board/homestar/board.c6
-rw-r--r--board/homestar/board.h8
-rw-r--r--board/icarus/board.h2
-rw-r--r--board/it8xxx2_pdevb/board.h1
-rw-r--r--board/jacuzzi/board.c4
-rw-r--r--board/jinlon/board.h5
-rw-r--r--board/kano/keyboard.c2
-rw-r--r--board/kappa/board.c2
-rw-r--r--board/kindred/board.h2
-rw-r--r--board/kracko/board.h6
-rw-r--r--board/lalala/board.c2
-rw-r--r--board/lalala/board.h2
-rw-r--r--board/lantis/board.h5
-rw-r--r--board/lazor/board.c2
-rw-r--r--board/lazor/board.h4
-rw-r--r--board/lindar/board.c4
-rw-r--r--board/lingcod/board.c4
-rw-r--r--board/magolor/board.c2
-rw-r--r--board/magolor/board.h5
-rw-r--r--board/makomo/board.c2
-rw-r--r--board/malefor/board.c4
-rw-r--r--board/marzipan/board.c2
-rw-r--r--board/marzipan/board.h2
-rw-r--r--board/meep/board.h5
-rw-r--r--board/morphius/board.h5
-rw-r--r--board/mrbland/base_detect.c2
-rw-r--r--board/munna/board.c3
-rw-r--r--board/munna/board.h5
-rw-r--r--board/munna/gpio.inc3
-rw-r--r--board/mushu/board.h6
-rw-r--r--board/nami/board.c2
-rw-r--r--board/nami/board.h4
-rw-r--r--board/nightfury/board.c2
-rw-r--r--board/nightfury/board.h2
-rw-r--r--board/npcx7_evb/board.c2
-rw-r--r--board/npcx7_evb/board.h2
-rw-r--r--board/npcx9_evb/board.c2
-rw-r--r--board/npcx9_evb/board.h2
-rw-r--r--board/npcx_evb/board.c2
-rw-r--r--board/npcx_evb/board.h2
-rw-r--r--board/npcx_evb_arm/board.c2
-rw-r--r--board/npcx_evb_arm/board.h2
-rw-r--r--board/nuwani/board.c2
-rw-r--r--board/pazquel/board.c2
-rw-r--r--board/pazquel/board.h2
-rw-r--r--board/pirika/board.c2
-rw-r--r--board/pirika/board.h2
-rw-r--r--board/pompom/board.c2
-rw-r--r--board/pompom/board.h2
-rw-r--r--board/poppy/base_detect_lux.c2
-rw-r--r--board/poppy/base_detect_poppy.c2
-rw-r--r--board/primus/board.h19
-rw-r--r--board/primus/ec.tasklist3
-rw-r--r--board/primus/gpio.inc4
-rw-r--r--board/primus/keyboard.c2
-rw-r--r--board/primus/led.c250
-rw-r--r--board/primus/pwm.c18
-rw-r--r--board/primus/sensors.c6
-rw-r--r--board/redrix/keyboard.c2
-rw-r--r--board/redrix/usbc_config.c14
-rw-r--r--board/reef/board.c5
-rw-r--r--board/reef/board.h2
-rw-r--r--board/reef_it8320/board.c4
-rw-r--r--board/reef_it8320/board.h2
-rw-r--r--board/reef_mchp/board.c5
-rw-r--r--board/reef_mchp/board.h2
-rw-r--r--board/samus/board.c2
-rw-r--r--board/samus/board.h2
-rw-r--r--board/shuboz/board.c2
-rw-r--r--board/stern/board.c2
-rw-r--r--board/taeko/keyboard.c2
-rw-r--r--board/terrador/board.c2
-rw-r--r--board/todor/board.c2
-rw-r--r--board/treeya/board.c2
-rw-r--r--board/trogdor/board.c2
-rw-r--r--board/trogdor/board.h2
-rw-r--r--board/trondo/board.c2
-rw-r--r--board/vilboz/board.c2
-rw-r--r--board/voema/board.c2
-rw-r--r--board/voema/board.h3
-rw-r--r--board/volet/board.c2
-rw-r--r--board/volet/board.h3
-rw-r--r--board/volteer/board.c19
-rw-r--r--board/volteer/build.mk1
-rw-r--r--board/volteer/keyboard.c26
-rw-r--r--board/voxel/board.c2
-rw-r--r--board/voxel/board.h3
-rw-r--r--board/waddledoo2/board.c2
-rw-r--r--board/waddledoo2/board.h2
-rw-r--r--board/willow/board.c2
-rw-r--r--chip/mt_scp/mt8192/intc.h3
-rw-r--r--chip/mt_scp/mt8195/intc.h3
-rw-r--r--chip/mt_scp/rv32i_common/intc.c12
-rw-r--r--chip/mt_scp/rv32i_common/registers.h3
-rw-r--r--chip/npcx/config_chip-npcx5.h6
-rw-r--r--chip/npcx/config_chip-npcx7.h7
-rw-r--r--chip/npcx/config_chip-npcx9.h7
-rw-r--r--chip/npcx/gpio_chip-npcx5.h6
-rw-r--r--chip/npcx/gpio_chip-npcx7.h6
-rw-r--r--chip/npcx/gpio_chip-npcx9.h8
-rw-r--r--common/i2c_controller.c20
-rw-r--r--common/keyboard_scan.c54
-rw-r--r--common/motion_lid.c2
-rw-r--r--common/motion_sense.c2
-rw-r--r--common/tablet_mode.c28
-rw-r--r--common/usbc/usb_pe_drp_sm.c49
-rw-r--r--common/vboot_hash.c6
-rw-r--r--core/cortex-m/ec.lds.S11
-rw-r--r--docs/configuration/keyboard.md4
-rw-r--r--docs/fingerprint/fingerprint-debugging.md4
-rw-r--r--driver/charger/sm5803.c118
-rw-r--r--driver/charger/sm5803.h22
-rw-r--r--driver/fingerprint/fpc/bep/fpc_private.c6
-rw-r--r--driver/ppc/nx20p348x.c2
-rw-r--r--include/config.h21
-rw-r--r--include/console_channel.inc3
-rw-r--r--include/driver/als_tcs3400.h (renamed from driver/als_tcs3400.h)0
-rw-r--r--include/i2c.h14
-rw-r--r--include/keyboard_scan.h12
-rw-r--r--include/led_onoff_states.h3
-rw-r--r--include/tablet_mode.h7
-rw-r--r--include/usb_pe_sm.h9
-rw-r--r--test/build.mk4
-rw-r--r--test/kb_scan.c181
l---------test/kb_scan_strict.tasklist1
-rw-r--r--test/motion_angle_tablet.c4
-rwxr-xr-xtest/run_device_tests.py24
-rw-r--r--test/stm32f_rtc.c21
-rw-r--r--test/test_config.h5
-rw-r--r--test/usb_pe_drp.c1
-rw-r--r--util/config_allowed.txt3
-rw-r--r--util/ec_parse_panicinfo.c13
-rwxr-xr-xutil/flash_jlink.py78
-rw-r--r--util/stm32mon.c17
-rw-r--r--zephyr/CMakeLists.txt2
-rw-r--r--zephyr/Kconfig19
-rw-r--r--zephyr/Kconfig.keyboard10
-rw-r--r--zephyr/Kconfig.system9
-rw-r--r--zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx760
-rw-r--r--zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx923
-rw-r--r--zephyr/boards/arm/npcx_evb/Kconfig.board18
-rw-r--r--zephyr/boards/arm/npcx_evb/Kconfig.defconfig7
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx7_evb.dts22
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig34
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx9_evb.dts21
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig33
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx_evb.dtsi17
-rw-r--r--zephyr/boards/arm/trogdor/trogdor.dts21
-rw-r--r--zephyr/boards/riscv/asurada/asurada.dts30
-rw-r--r--zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts5
-rw-r--r--zephyr/drivers/cros_shi/cros_shi_it8xxx2.c65
-rw-r--r--zephyr/dts/bindings/cros_mkbp_event/ec-mkbp-event.yaml13
-rw-r--r--zephyr/dts/bindings/emul/zephyr,tcs3400.yaml44
-rw-r--r--zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml8
-rw-r--r--zephyr/emul/CMakeLists.txt1
-rw-r--r--zephyr/emul/Kconfig12
-rw-r--r--zephyr/emul/emul_tcs3400.c858
-rw-r--r--zephyr/include/dt-bindings/wake_mask_event_defines.h2
-rw-r--r--zephyr/include/emul/emul_tcs3400.h255
-rw-r--r--zephyr/projects/asurada/hayato/CMakeLists.txt1
-rw-r--r--zephyr/projects/asurada/hayato/include/gpio_map.h4
-rw-r--r--zephyr/projects/asurada/hayato/prj.conf74
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt24
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/gpio.dts29
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/src/battery.c68
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/src/led.c163
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/src/switchcap.c22
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/src/usb_pd_policy.c258
-rw-r--r--zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c364
-rw-r--r--zephyr/projects/it8xxx2_evb/include/gpio_map.h4
-rw-r--r--zephyr/projects/it8xxx2_evb/zmake.yaml2
-rw-r--r--zephyr/projects/npcx_evb/npcx7/CMakeLists.txt11
-rw-r--r--zephyr/projects/npcx_evb/npcx7/gpio.dts107
-rw-r--r--zephyr/projects/npcx_evb/npcx7/include/gpio_map.h33
-rw-r--r--zephyr/projects/npcx_evb/npcx7/prj.conf29
-rw-r--r--zephyr/projects/npcx_evb/npcx7/zmake.yaml11
-rw-r--r--zephyr/projects/npcx_evb/npcx9/CMakeLists.txt11
-rw-r--r--zephyr/projects/npcx_evb/npcx9/gpio.dts107
-rw-r--r--zephyr/projects/npcx_evb/npcx9/include/gpio_map.h33
-rw-r--r--zephyr/projects/npcx_evb/npcx9/prj.conf33
-rw-r--r--zephyr/projects/npcx_evb/npcx9/zmake.yaml11
-rw-r--r--zephyr/projects/trogdor/herobrine_npcx7/gpio.dts29
-rw-r--r--zephyr/projects/trogdor/lazor/gpio.dts29
-rw-r--r--zephyr/projects/trogdor/trogdor/gpio.dts29
-rw-r--r--zephyr/projects/volteer/volteer/CMakeLists.txt2
-rw-r--r--zephyr/projects/volteer/volteer/prj.conf1
-rw-r--r--zephyr/shim/chip/CMakeLists.txt2
-rw-r--r--zephyr/shim/chip/it8xxx2/system.c10
-rw-r--r--zephyr/shim/chip/npcx/CMakeLists.txt1
-rw-r--r--zephyr/shim/chip/npcx/espi.c40
-rw-r--r--zephyr/shim/chip/posix/CMakeLists.txt5
-rw-r--r--zephyr/shim/chip/posix/espi.c49
-rw-r--r--zephyr/shim/include/config_chip.h20
-rw-r--r--zephyr/shim/include/zephyr_espi_shim.h51
-rw-r--r--zephyr/shim/include/zephyr_host_command.h9
-rw-r--r--zephyr/shim/src/espi.c11
-rw-r--r--zephyr/shim/src/i2c.c17
-rw-r--r--zephyr/test/drivers/overlay.dts105
-rw-r--r--zephyr/test/drivers/prj.conf2
-rw-r--r--zephyr/test/drivers/src/main.c2
-rw-r--r--zephyr/test/drivers/src/tcs3400.c622
-rw-r--r--zephyr/test/drivers/src/temp_sensor.c7
290 files changed, 5232 insertions, 806 deletions
diff --git a/baseboard/asurada/regulator.c b/baseboard/asurada/regulator.c
index 9809e2a607..35670bda82 100644
--- a/baseboard/asurada/regulator.c
+++ b/baseboard/asurada/regulator.c
@@ -4,7 +4,7 @@
*/
#include "common.h"
-#include "driver/bc12/mt6360.h"
+#include "bc12/mt6360_public.h"
/* SD Card */
int board_regulator_get_info(uint32_t index, char *name,
diff --git a/baseboard/brya/baseboard.h b/baseboard/brya/baseboard.h
index 9f7b817278..6a4efe942e 100644
--- a/baseboard/brya/baseboard.h
+++ b/baseboard/brya/baseboard.h
@@ -117,7 +117,7 @@
/* Common Keyboard Defines */
#define CONFIG_CMD_KEYBOARD
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_KEYPAD
#define CONFIG_KEYBOARD_PROTOCOL_8042
diff --git a/baseboard/brya/usb_pd_policy.c b/baseboard/brya/usb_pd_policy.c
index 919bab2a27..1637a8bfac 100644
--- a/baseboard/brya/usb_pd_policy.c
+++ b/baseboard/brya/usb_pd_policy.c
@@ -72,11 +72,6 @@ int pd_set_power_supply_ready(int port)
return EC_SUCCESS;
}
-int pd_snk_is_vbus_provided(int port)
-{
- return ppc_is_vbus_present(port);
-}
-
int board_vbus_source_enabled(int port)
{
return ppc_is_sourcing_vbus(port);
diff --git a/baseboard/dragonegg/baseboard.c b/baseboard/dragonegg/baseboard.c
index 2301a9cb0f..acbeadcf32 100644
--- a/baseboard/dragonegg/baseboard.c
+++ b/baseboard/dragonegg/baseboard.c
@@ -42,7 +42,7 @@
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/dragonegg/baseboard.h b/baseboard/dragonegg/baseboard.h
index a22ad924e9..47edb8f314 100644
--- a/baseboard/dragonegg/baseboard.h
+++ b/baseboard/dragonegg/baseboard.h
@@ -44,7 +44,7 @@
/* Common Keyboard Defines */
#define CONFIG_CMD_KEYBOARD
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/baseboard/grunt/baseboard.c b/baseboard/grunt/baseboard.c
index 35997db8d5..9d06fd4b78 100644
--- a/baseboard/grunt/baseboard.c
+++ b/baseboard/grunt/baseboard.c
@@ -482,7 +482,7 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/grunt/baseboard.h b/baseboard/grunt/baseboard.h
index 5206b0a5a2..c97ece285f 100644
--- a/baseboard/grunt/baseboard.h
+++ b/baseboard/grunt/baseboard.h
@@ -101,7 +101,7 @@
*/
#define CONFIG_BOARD_RESET_AFTER_POWER_ON
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PROTOCOL_8042
diff --git a/baseboard/guybrush/baseboard.c b/baseboard/guybrush/baseboard.c
index e20528f288..18da982b99 100644
--- a/baseboard/guybrush/baseboard.c
+++ b/baseboard/guybrush/baseboard.c
@@ -465,7 +465,7 @@ BUILD_ASSERT(ARRAY_SIZE(ioex_config) == USBC_PORT_COUNT);
BUILD_ASSERT(CONFIG_IO_EXPANDER_PORT_COUNT == USBC_PORT_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/guybrush/baseboard.h b/baseboard/guybrush/baseboard.h
index 1f8bf58094..abe5dddf0b 100644
--- a/baseboard/guybrush/baseboard.h
+++ b/baseboard/guybrush/baseboard.h
@@ -102,7 +102,7 @@
/* Keyboard Config */
#define CONFIG_KEYBOARD_BACKLIGHT
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_VIVALDI
diff --git a/baseboard/intelrvp/baseboard.h b/baseboard/intelrvp/baseboard.h
index 1ca3739d88..de4cb671ac 100644
--- a/baseboard/intelrvp/baseboard.h
+++ b/baseboard/intelrvp/baseboard.h
@@ -76,7 +76,7 @@
#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 15001
/* Keyboard */
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/baseboard/intelrvp/ite_ec.c b/baseboard/intelrvp/ite_ec.c
index d76d22bb63..bafddc5f9e 100644
--- a/baseboard/intelrvp/ite_ec.c
+++ b/baseboard/intelrvp/ite_ec.c
@@ -15,7 +15,7 @@
#include "usb_pd_tcpm.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 35,
.debounce_down_us = 5 * MSEC,
.debounce_up_us = 40 * MSEC,
diff --git a/baseboard/intelrvp/mchp_ec.c b/baseboard/intelrvp/mchp_ec.c
index adaba23d3a..2d6c203ef2 100644
--- a/baseboard/intelrvp/mchp_ec.c
+++ b/baseboard/intelrvp/mchp_ec.c
@@ -14,7 +14,7 @@
#include "usb_pd_tcpm.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/intelrvp/npcx_ec.c b/baseboard/intelrvp/npcx_ec.c
index c48e202f87..d6eca2e55b 100644
--- a/baseboard/intelrvp/npcx_ec.c
+++ b/baseboard/intelrvp/npcx_ec.c
@@ -12,7 +12,7 @@
#include "time.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 35,
.debounce_down_us = 5 * MSEC,
.debounce_up_us = 40 * MSEC,
diff --git a/baseboard/ite_evb/baseboard.c b/baseboard/ite_evb/baseboard.c
index 0bd537ef4f..00459b12bc 100644
--- a/baseboard/ite_evb/baseboard.c
+++ b/baseboard/ite_evb/baseboard.c
@@ -106,9 +106,8 @@ const struct fan_tach_t fan_tach[] = {
BUILD_ASSERT(ARRAY_SIZE(fan_tach) == PWM_HW_CH_TOTAL);
#endif /* defined(CONFIG_FANS) || defined(CONFIG_PWM) */
-#if defined(CONFIG_KEYBOARD_BOARD_CONFIG)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 35,
.debounce_down_us = 5 * MSEC,
.debounce_up_us = 40 * MSEC,
@@ -120,7 +119,6 @@ struct keyboard_scan_config keyscan_config = {
0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
},
};
-#endif
#if defined(CONFIG_SPI_FLASH_PORT)
/* SPI devices */
diff --git a/baseboard/ite_evb/baseboard.h b/baseboard/ite_evb/baseboard.h
index dfe289e3a6..7fe309491c 100644
--- a/baseboard/ite_evb/baseboard.h
+++ b/baseboard/ite_evb/baseboard.h
@@ -17,7 +17,7 @@
#define CONFIG_IT83XX_ENABLE_MOUSE_DEVICE
#define CONFIG_IT83XX_SMCLK2_ON_GPC7
#define CONFIG_IT83XX_VCC_3P3V
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_LOW_POWER_IDLE
#define CONFIG_LOW_POWER_S0
diff --git a/baseboard/kukui/baseboard.c b/baseboard/kukui/baseboard.c
index f17b3a4e82..03023b1068 100644
--- a/baseboard/kukui/baseboard.c
+++ b/baseboard/kukui/baseboard.c
@@ -100,6 +100,28 @@ enum kukui_board_version {
};
/* map from kukui_board_version to board id voltage in mv */
+#ifdef VARIANT_KUKUI_EC_IT81202
+const int16_t kukui_board_id_map[] = {
+ 136, /* 51.1K , 2.2K(gru 3.3K) ohm */
+ 388, /* 51.1k , 6.8K ohm */
+ 584, /* 51.1K , 11K ohm */
+ 785, /* 56K , 17.4K ohm */
+ 993, /* 51.1K , 22K ohm */
+ 1221, /* 51.1K , 30K ohm */
+ 1433, /* 51.1K , 39.2K ohm */
+ 1650, /* 56K , 56K ohm */
+ 1876, /* 47K , 61.9K ohm */
+ 2084, /* 47K , 80.6K ohm */
+ 2273, /* 56K , 124K ohm */
+ 2461, /* 51.1K , 150K ohm */
+ 2672, /* 47K , 200K ohm */
+ 2889, /* 47K , 330K ohm */
+ 3086, /* 47K , 680K ohm */
+ 3300, /* 56K , NC */
+};
+
+#define THRESHOLD_MV 103 /* Simply assume 3300/16/2 */
+#else
const int16_t kukui_board_id_map[] = {
109, /* 51.1K , 2.2K(gru 3.3K) ohm */
211, /* 51.1k , 6.8K ohm */
@@ -118,9 +140,10 @@ const int16_t kukui_board_id_map[] = {
1684, /* 47K , 680K ohm */
1800, /* 56K , NC */
};
-BUILD_ASSERT(ARRAY_SIZE(kukui_board_id_map) == BOARD_VERSION_COUNT);
#define THRESHOLD_MV 56 /* Simply assume 1800/16/2 */
+#endif /* VARIANT_KUKUI_EC_IT81202 */
+BUILD_ASSERT(ARRAY_SIZE(kukui_board_id_map) == BOARD_VERSION_COUNT);
int board_get_version(void)
{
diff --git a/baseboard/kukui/baseboard.h b/baseboard/kukui/baseboard.h
index 90a3e3dd05..66b88cd534 100644
--- a/baseboard/kukui/baseboard.h
+++ b/baseboard/kukui/baseboard.h
@@ -104,7 +104,7 @@
#define CONFIG_IO_EXPANDER_IT8801
#define CONFIG_IO_EXPANDER_PORT_COUNT 1
#define CONFIG_KEYBOARD_NOT_RAW
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#endif
#define CONFIG_KEYBOARD_COL2_INVERTED
diff --git a/baseboard/octopus/baseboard.c b/baseboard/octopus/baseboard.c
index c9a3094e2e..89da53e6dc 100644
--- a/baseboard/octopus/baseboard.c
+++ b/baseboard/octopus/baseboard.c
@@ -32,7 +32,7 @@
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/octopus/baseboard.h b/baseboard/octopus/baseboard.h
index 059dec29d9..8b05c30f4c 100644
--- a/baseboard/octopus/baseboard.h
+++ b/baseboard/octopus/baseboard.h
@@ -264,7 +264,7 @@
/* Common Keyboard Defines */
#define CONFIG_CMD_KEYBOARD
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h
index 4ea3d81676..38a464813a 100644
--- a/baseboard/volteer/baseboard.h
+++ b/baseboard/volteer/baseboard.h
@@ -64,7 +64,7 @@
/* Common Keyboard Defines */
#define CONFIG_CMD_KEYBOARD
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_KEYPAD
#define CONFIG_KEYBOARD_PROTOCOL_8042
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c
index 5bbb0cc65a..41c859ad7b 100644
--- a/baseboard/zork/baseboard.c
+++ b/baseboard/zork/baseboard.c
@@ -105,7 +105,7 @@ __overridable void board_set_charge_limit(int port, int supplier, int charge_ma,
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/baseboard/zork/baseboard.h b/baseboard/zork/baseboard.h
index 60db6e1cb2..d84ebbcef8 100644
--- a/baseboard/zork/baseboard.h
+++ b/baseboard/zork/baseboard.h
@@ -122,7 +122,7 @@
#define CONFIG_IO_EXPANDER
#define CONFIG_IO_EXPANDER_NCT38XX
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PROTOCOL_8042
#undef CONFIG_KEYBOARD_VIVALDI
diff --git a/baseboard/zork/variant_dalboz.c b/baseboard/zork/variant_dalboz.c
index 6c1af5da1f..a43518e984 100644
--- a/baseboard/zork/variant_dalboz.c
+++ b/baseboard/zork/variant_dalboz.c
@@ -57,6 +57,11 @@ int board_get_temp(int idx, int *temp_k)
if (chipset_in_state(CHIPSET_STATE_HARD_OFF))
return EC_ERROR_NOT_POWERED;
+ /* adc power not ready when transition to S5 */
+ if (chipset_in_or_transitioning_to_state(
+ CHIPSET_STATE_SOFT_OFF))
+ return EC_ERROR_NOT_POWERED;
+
channel = ADC_TEMP_SENSOR_SOC;
break;
default:
diff --git a/board/aleena/board.c b/board/aleena/board.c
index ded6cbf698..0343a399c5 100644
--- a/board/aleena/board.c
+++ b/board/aleena/board.c
@@ -169,7 +169,7 @@ void board_update_sensor_config_from_sku(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L,
GPIO_INPUT | GPIO_PULL_DOWN);
diff --git a/board/aleena/board.h b/board/aleena/board.h
index e0fd8da555..9ad2a8b94b 100644
--- a/board/aleena/board.h
+++ b/board/aleena/board.h
@@ -71,11 +71,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
void motion_interrupt(enum gpio_signal signal);
#endif /* !__ASSEMBLER__ */
diff --git a/board/atlas/board.c b/board/atlas/board.c
index ac617130ab..8d89bee074 100644
--- a/board/atlas/board.c
+++ b/board/atlas/board.c
@@ -70,7 +70,7 @@ static void tcpc_alert_event(enum gpio_signal signal)
#include "gpio_list.h"
/* Keyboard scan. Increase output_settle_us to 80us from default 50us. */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 80,
.debounce_down_us = 9 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/atlas/board.h b/board/atlas/board.h
index bc4844ee53..56685f1856 100644
--- a/board/atlas/board.h
+++ b/board/atlas/board.h
@@ -57,7 +57,7 @@
#define CONFIG_HOSTCMD_ESPI
#define CONFIG_HOSTCMD_ESPI_VW_SLP_S3
#define CONFIG_HOSTCMD_ESPI_VW_SLP_S4
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_REFRESH_ROW3
diff --git a/board/berknip/board.h b/board/berknip/board.h
index 368084fa25..5ef9e33f0c 100644
--- a/board/berknip/board.h
+++ b/board/berknip/board.h
@@ -199,11 +199,6 @@ extern const struct usb_mux usbc1_tusb544;
extern const struct usb_mux usbc1_ps8743;
extern struct usb_mux usbc1_amd_fp5_usb_mux;
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/blipper/board.c b/board/blipper/board.c
index e26b3d4d51..480ca5c6da 100644
--- a/board/blipper/board.c
+++ b/board/blipper/board.c
@@ -41,6 +41,19 @@
#define CPRINTUSB(format, args...) cprints(CC_USBCHARGE, format, ## args)
#define INT_RECHECK_US 5000
+__override struct keyboard_scan_config keyscan_config = {
+ .output_settle_us = 80,
+ .debounce_down_us = 30 * 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, 0xf5, 0xff,
+ 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
+ },
+};
+
/* C0 interrupt line shared by BC 1.2 and charger */
static void check_c0_line(void);
DECLARE_DEFERRED(check_c0_line);
diff --git a/board/blipper/board.h b/board/blipper/board.h
index cd4f9b0d2a..7d8278c61f 100644
--- a/board/blipper/board.h
+++ b/board/blipper/board.h
@@ -65,6 +65,7 @@
/* KeyBoard */
#define CONFIG_KEYBOARD_REFRESH_ROW3
#define CONFIG_KEYBOARD_KEYPAD
+#define CONFIG_KEYBOARD_STRICT_DEBOUNCE
/* USB Type A Features */
#define USB_PORT_COUNT 1
diff --git a/board/bloog/board.h b/board/bloog/board.h
index 458e7c7e4d..466c38aede 100644
--- a/board/bloog/board.h
+++ b/board/bloog/board.h
@@ -98,11 +98,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
int board_is_convertible(void);
#endif /* !__ASSEMBLER__ */
diff --git a/board/bobba/board.h b/board/bobba/board.h
index 31b9499b9d..23f73e7dbc 100644
--- a/board/bobba/board.h
+++ b/board/bobba/board.h
@@ -87,8 +87,6 @@
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
#include "gpio_signal.h"
#include "registers.h"
diff --git a/board/boldar/board.c b/board/boldar/board.c
index 357b2c9e46..59b7166123 100644
--- a/board/boldar/board.c
+++ b/board/boldar/board.c
@@ -51,7 +51,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/brya/keyboard.c b/board/brya/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/brya/keyboard.c
+++ b/board/brya/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/burnet/board.c b/board/burnet/board.c
index f7d53ac726..f0a8ec9824 100644
--- a/board/burnet/board.c
+++ b/board/burnet/board.c
@@ -90,7 +90,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
@@ -537,7 +537,7 @@ static void board_init(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Turn off GMR interrupt */
gmr_tablet_switch_disable();
/* Base accel is not stuffed, don't allow line to float */
diff --git a/board/careena/board.h b/board/careena/board.h
index b37567001c..75545cfcaa 100644
--- a/board/careena/board.h
+++ b/board/careena/board.h
@@ -58,11 +58,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/cerise/board.c b/board/cerise/board.c
index 8ca775b8e8..83884bd42f 100644
--- a/board/cerise/board.c
+++ b/board/cerise/board.c
@@ -88,7 +88,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/cheza/base_detect.c b/board/cheza/base_detect.c
index b47504144b..1703588dd0 100644
--- a/board/cheza/base_detect.c
+++ b/board/cheza/base_detect.c
@@ -101,7 +101,7 @@ static void base_detect_change(enum base_status status)
/* We don't enable dual-battery support. Set the base power directly. */
gpio_set_level(GPIO_EN_PPVAR_VAR_BASE, connected);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
}
static void print_base_detect_value(const char *str, int v)
diff --git a/board/chronicler/board.h b/board/chronicler/board.h
index 20670bd6e9..1d12b5058d 100644
--- a/board/chronicler/board.h
+++ b/board/chronicler/board.h
@@ -157,11 +157,6 @@ enum pwm_channel {
void board_reset_pd_mcu(void);
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/chronicler/keyboard.c b/board/chronicler/keyboard.c
index aeed7d7c63..b9cc378295 100644
--- a/board/chronicler/keyboard.c
+++ b/board/chronicler/keyboard.c
@@ -10,7 +10,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/coachz/base_detect.c b/board/coachz/base_detect.c
index 1a27538166..39e478d1c7 100644
--- a/board/coachz/base_detect.c
+++ b/board/coachz/base_detect.c
@@ -83,7 +83,7 @@ static void base_detect_change(enum base_status status)
return;
gpio_set_level(GPIO_EN_BASE, connected);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
base_set_state(connected);
current_base_status = status;
}
diff --git a/board/collis/board.c b/board/collis/board.c
index a5b561c3d0..5f643c8aa7 100644
--- a/board/collis/board.c
+++ b/board/collis/board.c
@@ -46,7 +46,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/copano/board.c b/board/copano/board.c
index deb9f3f951..23395b0a61 100644
--- a/board/copano/board.c
+++ b/board/copano/board.c
@@ -46,7 +46,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/coral/board.c b/board/coral/board.c
index d3be3c411a..2a63a60d13 100644
--- a/board/coral/board.c
+++ b/board/coral/board.c
@@ -456,7 +456,7 @@ static void board_set_tablet_mode(void)
if (SKU_IS_CONVERTIBLE(sku_id))
tablet_mode = !gpio_get_level(GPIO_TABLET_MODE_L);
- tablet_set_mode(tablet_mode);
+ tablet_set_mode(tablet_mode, TABLET_TRIGGER_LID);
}
/* Initialize board. */
@@ -911,7 +911,7 @@ static void sku_id_init(void)
CPRINTS("Disable tablet mode interrupt");
gpio_disable_interrupt(GPIO_TABLET_MODE_L);
/* Enfore device in laptop mode */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
}
}
}
@@ -990,7 +990,7 @@ __override uint32_t board_get_sku_id(void)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/coral/board.h b/board/coral/board.h
index 4316d991f1..24b0ecf86e 100644
--- a/board/coral/board.h
+++ b/board/coral/board.h
@@ -124,7 +124,7 @@
#define CONFIG_HOSTCMD_FLASH_SPI_INFO
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/board/dalboz/board.c b/board/dalboz/board.c
index 18d98b29e5..44015110cf 100644
--- a/board/dalboz/board.c
+++ b/board/dalboz/board.c
@@ -607,7 +607,7 @@ static void setup_fw_config(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/damu/board.c b/board/damu/board.c
index 38f354d251..c45d4e37a8 100644
--- a/board/damu/board.c
+++ b/board/damu/board.c
@@ -88,7 +88,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/delbin/board.c b/board/delbin/board.c
index cb58616607..b1d7754992 100644
--- a/board/delbin/board.c
+++ b/board/delbin/board.c
@@ -44,7 +44,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/dirinboz/board.c b/board/dirinboz/board.c
index 1daf425b2a..d7b3446197 100644
--- a/board/dirinboz/board.c
+++ b/board/dirinboz/board.c
@@ -493,7 +493,7 @@ static void setup_fw_config(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/dirinboz/board.h b/board/dirinboz/board.h
index ac6f69fc70..049d7884c8 100644
--- a/board/dirinboz/board.h
+++ b/board/dirinboz/board.h
@@ -175,11 +175,6 @@ void tcpc_alert_event(enum gpio_signal signal);
void bc12_interrupt(enum gpio_signal signal);
void ppc_interrupt(enum gpio_signal signal);
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/dood/board.h b/board/dood/board.h
index 530e2a0bf2..dcb5c93005 100644
--- a/board/dood/board.h
+++ b/board/dood/board.h
@@ -64,8 +64,6 @@
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
#include "gpio_signal.h"
#include "registers.h"
diff --git a/board/dratini/board.h b/board/dratini/board.h
index 5878f17af1..e75865e376 100644
--- a/board/dratini/board.h
+++ b/board/dratini/board.h
@@ -175,11 +175,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
bool board_is_convertible(void);
void ccd_mode_isr(enum gpio_signal signal);
diff --git a/board/drawcia/board.h b/board/drawcia/board.h
index 55adab5106..96e6b3f14d 100644
--- a/board/drawcia/board.h
+++ b/board/drawcia/board.h
@@ -147,11 +147,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/drobit/board.c b/board/drobit/board.c
index 71a236591d..3fb336976c 100644
--- a/board/drobit/board.c
+++ b/board/drobit/board.c
@@ -45,7 +45,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/eldrid/board.c b/board/eldrid/board.c
index 4e9dd5bb64..90d663e6f7 100644
--- a/board/eldrid/board.c
+++ b/board/eldrid/board.c
@@ -51,7 +51,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/elemi/board.c b/board/elemi/board.c
index b48dbc856e..5eab31d871 100644
--- a/board/elemi/board.c
+++ b/board/elemi/board.c
@@ -45,7 +45,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/elemi/board.h b/board/elemi/board.h
index cca3f1eaa0..f2ce54e83a 100644
--- a/board/elemi/board.h
+++ b/board/elemi/board.h
@@ -151,11 +151,6 @@ enum usbc_port {
void board_reset_pd_mcu(void);
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/eve/board.c b/board/eve/board.c
index 2bb1b42f46..81ea080e26 100644
--- a/board/eve/board.c
+++ b/board/eve/board.c
@@ -158,7 +158,7 @@ void anx74xx_cable_det_interrupt(enum gpio_signal signal)
#include "gpio_list.h"
/* Keyboard scan. Increase output_settle_us to 80us from default 50us. */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 80,
.debounce_down_us = 9 * MSEC,
.debounce_up_us = 30 * MSEC,
@@ -459,7 +459,7 @@ static void board_set_tablet_mode(void)
{
int flipped_360_mode = !gpio_get_level(GPIO_TABLET_MODE_L);
- tablet_set_mode(flipped_360_mode);
+ tablet_set_mode(flipped_360_mode, TABLET_TRIGGER_LID);
/* Update DPTF profile based on mode */
if (flipped_360_mode)
diff --git a/board/eve/board.h b/board/eve/board.h
index 6061f498a2..df80e4dccf 100644
--- a/board/eve/board.h
+++ b/board/eve/board.h
@@ -75,7 +75,7 @@
#define CONFIG_HOSTCMD_ESPI
#define CONFIG_HOSTCMD_ESPI_VW_SLP_S3
#define CONFIG_HOSTCMD_ESPI_VW_SLP_S4
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#undef CONFIG_KEYBOARD_VIVALDI
#define CONFIG_KEYBOARD_PROTOCOL_8042
diff --git a/board/ezkinil/board.h b/board/ezkinil/board.h
index 23d79e0361..b823ded45a 100644
--- a/board/ezkinil/board.h
+++ b/board/ezkinil/board.h
@@ -203,8 +203,6 @@ static inline bool ec_config_has_hdmi_conn_hpd(void)
? GPIO_DP1_HPD \
: GPIO_DP2_HPD)
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
extern const struct usb_mux usbc1_tusb544;
extern const struct usb_mux usbc1_ps8743;
extern struct usb_mux usbc1_amd_fp5_usb_mux;
diff --git a/board/fennel/board.c b/board/fennel/board.c
index dcc812a4d6..32decaac0c 100644
--- a/board/fennel/board.c
+++ b/board/fennel/board.c
@@ -16,6 +16,8 @@
#include "console.h"
#include "driver/accel_lis2dw12.h"
#include "driver/accelgyro_bmi_common.h"
+#include "driver/accelgyro_icm_common.h"
+#include "driver/accelgyro_icm42607.h"
#include "driver/battery/max17055.h"
#include "driver/bc12/pi3usb9201.h"
#include "driver/charger/isl923x.h"
@@ -87,7 +89,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
@@ -350,6 +352,61 @@ static const mat33_fp_t lid_standard_ref = {
static struct stprivate_data g_lis2dwl_data;
/* Base accel private data */
static struct bmi_drv_data_t g_bmi160_data;
+static struct icm_drv_data_t g_icm42607_data;
+
+enum base_accelgyro_type {
+ BASE_GYRO_NONE = 0,
+ BASE_GYRO_BMI160 = 1,
+ BASE_GYRO_ICM426XX = 2,
+};
+
+static enum base_accelgyro_type base_accelgyro_config;
+
+struct motion_sensor_t icm42607_base_accel = {
+ .name = "Accel",
+ .active_mask = SENSOR_ACTIVE_S0_S3,
+ .chip = MOTIONSENSE_CHIP_ICM42607,
+ .type = MOTIONSENSE_TYPE_ACCEL,
+ .location = MOTIONSENSE_LOC_BASE,
+ .drv = &icm42607_drv,
+ .mutex = &g_base_mutex,
+ .drv_data = &g_icm42607_data,
+ .port = CONFIG_SPI_ACCEL_PORT,
+ .i2c_spi_addr_flags = ACCEL_MK_SPI_ADDR_FLAGS(CONFIG_SPI_ACCEL_PORT),
+ .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/
+ .rot_standard_ref = NULL,
+ .min_frequency = ICM42607_ACCEL_MIN_FREQ,
+ .max_frequency = ICM42607_ACCEL_MAX_FREQ,
+ .config = {
+ /* EC use accel for angle detection */
+ [SENSOR_CONFIG_EC_S0] = {
+ .odr = 10000 | ROUND_UP_FLAG,
+ .ec_rate = 100 * MSEC,
+ },
+ /* Sensor on for angle detection */
+ [SENSOR_CONFIG_EC_S3] = {
+ .odr = 10000 | ROUND_UP_FLAG,
+ .ec_rate = 100 * MSEC,
+ },
+ },
+};
+
+struct motion_sensor_t icm42607_base_gyro = {
+ .name = "Gyro",
+ .active_mask = SENSOR_ACTIVE_S0_S3,
+ .chip = MOTIONSENSE_CHIP_ICM42607,
+ .type = MOTIONSENSE_TYPE_GYRO,
+ .location = MOTIONSENSE_LOC_BASE,
+ .drv = &icm42607_drv,
+ .mutex = &g_base_mutex,
+ .drv_data = &g_icm42607_data,
+ .port = CONFIG_SPI_ACCEL_PORT,
+ .i2c_spi_addr_flags = ACCEL_MK_SPI_ADDR_FLAGS(CONFIG_SPI_ACCEL_PORT),
+ .default_range = 1000, /* dps */
+ .rot_standard_ref = NULL,
+ .min_frequency = ICM42607_GYRO_MIN_FREQ,
+ .max_frequency = ICM42607_GYRO_MAX_FREQ,
+};
struct motion_sensor_t motion_sensors[] = {
[LID_ACCEL] = {
@@ -430,6 +487,52 @@ struct motion_sensor_t motion_sensors[] = {
};
const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
+static void board_detect_motionsensor(void)
+{
+ int ret;
+ int val;
+
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ return;
+ if (base_accelgyro_config != BASE_GYRO_NONE)
+ return;
+ /* Check base accelgyro chip */
+ ret = icm_read8(&icm42607_base_accel,
+ ICM42607_REG_WHO_AM_I, &val);
+ if (ret)
+ ccprints("Get ICM fail.");
+ if (val == ICM42607_CHIP_ICM42607P) {
+ motion_sensors[BASE_ACCEL] = icm42607_base_accel;
+ motion_sensors[BASE_GYRO] = icm42607_base_gyro;
+ }
+ base_accelgyro_config = (val == ICM42607_CHIP_ICM42607P)
+ ? BASE_GYRO_ICM426XX : BASE_GYRO_BMI160;
+ ccprints("BASE Accelgyro: %s", (val == ICM42607_CHIP_ICM42607P)
+ ? "ICM42607" : "BMI160");
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_detect_motionsensor,
+ HOOK_PRIO_DEFAULT);
+/*
+ * board_spi_enable() will be called in the board_init() when sysjump to rw
+ * the board_init() is DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT)
+ * the board_detect_motionsensor() reads data via sensor SPI
+ * so the priority of board_detect_motionsensor should be HOOK_PRIO_DEFAULT+1
+ */
+DECLARE_HOOK(HOOK_INIT, board_detect_motionsensor, HOOK_PRIO_DEFAULT + 1);
+
+void motion_interrupt(enum gpio_signal signal)
+{
+ switch (base_accelgyro_config) {
+ case BASE_GYRO_ICM426XX:
+ icm42607_interrupt(signal);
+ break;
+ case BASE_GYRO_BMI160:
+ default:
+ bmi160_interrupt(signal);
+ break;
+ }
+}
+
const struct it8801_pwm_t it8801_pwm_channels[] = {
[IT8801_PWM_CH_KBLIGHT] = {.index = 4},
};
diff --git a/board/fennel/board.h b/board/fennel/board.h
index 71a7c91e28..448c7debf0 100644
--- a/board/fennel/board.h
+++ b/board/fennel/board.h
@@ -57,6 +57,9 @@
#define CONFIG_ACCEL_INTERRUPTS
#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \
TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL)
+#define CONFIG_ACCELGYRO_ICM42607 /* Base accel second source*/
+#define CONFIG_ACCELGYRO_ICM42607_INT_EVENT \
+ TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL)
#define CONFIG_ALS
#define CONFIG_CMD_ACCEL_INFO
@@ -143,6 +146,7 @@ void emmc_cmd_interrupt(enum gpio_signal signal);
void bc12_interrupt(enum gpio_signal signal);
void board_reset_pd_mcu(void);
int board_get_version(void);
+void motion_interrupt(enum gpio_signal signal);
/* returns the i2c port number of charger/battery */
int board_get_charger_i2c(void);
diff --git a/board/fennel/gpio.inc b/board/fennel/gpio.inc
index 28d4035031..29518fbc4e 100644
--- a/board/fennel/gpio.inc
+++ b/board/fennel/gpio.inc
@@ -22,7 +22,7 @@ GPIO_INT(PMIC_EC_RESETB, PIN(B, 7), GPIO_INT_BOTH | GPIO_PULL_DOWN,
GPIO_INT(WARM_RESET_REQ, PIN(A, 3), GPIO_INT_RISING | GPIO_PULL_DOWN,
chipset_reset_request_interrupt)
GPIO_INT_RW(ACCEL_INT_ODL, PIN(A, 4), GPIO_INT_FALLING | GPIO_SEL_1P8V | GPIO_PULL_UP,
- bmi160_interrupt)
+ motion_interrupt)
GPIO_INT_RO(EMMC_CMD, PIN(B, 15), GPIO_INT_FALLING,
emmc_cmd_interrupt)
GPIO_INT(SPI1_NSS, PIN(A, 15), GPIO_INT_BOTH | GPIO_PULL_UP,
diff --git a/board/garg/board.h b/board/garg/board.h
index 6837e992b2..57bd10e007 100644
--- a/board/garg/board.h
+++ b/board/garg/board.h
@@ -60,8 +60,6 @@
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
#include "gpio_signal.h"
#include "registers.h"
diff --git a/board/genesis/board.c b/board/genesis/board.c
index ff056ec79a..5cc45388b8 100644
--- a/board/genesis/board.c
+++ b/board/genesis/board.c
@@ -51,9 +51,9 @@ static int32_t base_5v_power;
* Units are milliwatts (5v x ma current)
*/
#define PWR_BASE_LOAD (5*1335)
-#define PWR_FRONT_HIGH (5*1603)
-#define PWR_FRONT_LOW (5*963)
-#define PWR_REAR (5*1075)
+#define PWR_FRONT_HIGH (5*1500)
+#define PWR_FRONT_LOW (5*900)
+#define PWR_REAR (5*1500)
#define PWR_HDMI (5*562)
#define PWR_C_HIGH (5*3740)
#define PWR_C_LOW (5*2090)
@@ -70,11 +70,11 @@ static void update_5v_usage(void)
* Recalculate the 5V load, assuming no throttling.
*/
base_5v_power = PWR_BASE_LOAD;
- if (!gpio_get_level(GPIO_USB_A0_OC_ODL)) {
+ if (!gpio_get_level(GPIO_USB_A2_OC_ODL)) {
front_ports++;
base_5v_power += PWR_FRONT_LOW;
}
- if (!gpio_get_level(GPIO_USB_A1_OC_ODL)) {
+ if (!gpio_get_level(GPIO_USB_A3_OC_ODL)) {
front_ports++;
base_5v_power += PWR_FRONT_LOW;
}
@@ -83,11 +83,7 @@ static void update_5v_usage(void)
*/
if (front_ports > 0)
base_5v_power += PWR_FRONT_HIGH - PWR_FRONT_LOW;
- if (!gpio_get_level(GPIO_USB_A2_OC_ODL))
- base_5v_power += PWR_REAR;
- if (!gpio_get_level(GPIO_USB_A3_OC_ODL))
- base_5v_power += PWR_REAR;
- if (ec_config_get_usb4_present() && !gpio_get_level(GPIO_USB_A4_OC_ODL))
+ if (!gpio_get_level(GPIO_USB_A1_OC_ODL))
base_5v_power += PWR_REAR;
if (!gpio_get_level(GPIO_HDMI_CONN0_OC_ODL))
base_5v_power += PWR_HDMI;
@@ -247,19 +243,6 @@ const static struct ec_thermal_config thermal_a = {
.temp_fan_max = C_TO_K(84),
};
-const static struct ec_thermal_config thermal_b = {
- .temp_host = {
- [EC_TEMP_THRESH_WARN] = 0,
- [EC_TEMP_THRESH_HIGH] = C_TO_K(78),
- [EC_TEMP_THRESH_HALT] = C_TO_K(85),
- },
- .temp_host_release = {
- [EC_TEMP_THRESH_WARN] = 0,
- [EC_TEMP_THRESH_HIGH] = C_TO_K(70),
- [EC_TEMP_THRESH_HALT] = 0,
- },
-};
-
struct ec_thermal_config thermal_params[] = {
[TEMP_SENSOR_CORE] = thermal_a,
};
@@ -352,49 +335,12 @@ int extpower_is_present(void)
int board_is_c10_gate_enabled(void)
{
- /*
- * Puff proto drives EN_PP5000_HDMI from EN_S0_RAILS so we cannot gate
- * core rails while in S0 because HDMI should remain powered.
- * EN_PP5000_HDMI is a separate EC output on all other boards.
- */
- return board_version != 0;
+ return 0;
}
void board_enable_s0_rails(int enable)
{
- /* This output isn't connected on protos; safe to set anyway. */
- gpio_set_level(GPIO_EN_PP5000_HDMI, enable);
-}
-
-int ec_config_get_usb4_present(void)
-{
- return !(fw_config & EC_CFG_NO_USB4_MASK);
-}
-
-unsigned int ec_config_get_thermal_solution(void)
-{
- return (fw_config & EC_CFG_THERMAL_MASK) >> EC_CFG_THERMAL_L;
-}
-
-static void setup_thermal(void)
-{
- unsigned int table = ec_config_get_thermal_solution();
- /* Configure Fan */
- switch (table) {
- /* Default and table0 use single fan */
- case 0:
- default:
- thermal_params[TEMP_SENSOR_CORE] = thermal_a;
- break;
- /* Table1 is fanless */
- case 1:
- fan_set_count(0);
- thermal_params[TEMP_SENSOR_CORE] = thermal_b;
- break;
- }
}
-/* fan_set_count should be called before HOOK_INIT/HOOK_PRIO_DEFAULT */
-DECLARE_HOOK(HOOK_INIT, setup_thermal, HOOK_PRIO_DEFAULT - 1);
/*
* Power monitoring and management.
@@ -529,7 +475,7 @@ static void power_monitor(void)
if (diff & THROT_TYPE_A) {
int typea_bc = (new_state & THROT_TYPE_A) ? 1 : 0;
- gpio_set_level(GPIO_USB_A_LOW_PWR_OD, typea_bc);
+ gpio_set_level(GPIO_USB_A3_LOW_PWR_OD, typea_bc);
}
hook_call_deferred(&power_monitor_data, delay);
}
diff --git a/board/genesis/board.h b/board/genesis/board.h
index af7af55f7c..14d1a8475d 100644
--- a/board/genesis/board.h
+++ b/board/genesis/board.h
@@ -170,8 +170,6 @@ enum temp_sensor_id {
/* Board specific handlers */
-void board_reset_pd_mcu(void);
-void board_set_tcpc_power_mode(int port, int mode);
void led_alert(int enable);
void show_critical_error(void);
@@ -197,7 +195,6 @@ void show_critical_error(void);
#define EC_CFG_THERMAL_H 7
#define EC_CFG_THERMAL_MASK GENMASK(EC_CFG_THERMAL_H, EC_CFG_THERMAL_L)
-int ec_config_get_usb4_present(void);
unsigned int ec_config_get_thermal_solution(void);
#endif /* !__ASSEMBLER__ */
diff --git a/board/genesis/gpio.inc b/board/genesis/gpio.inc
index 6ab2b1602f..6a905fdf04 100644
--- a/board/genesis/gpio.inc
+++ b/board/genesis/gpio.inc
@@ -50,12 +50,9 @@ GPIO(BJ_ADP_PRESENT_L, PIN(8, 2), GPIO_INT_BOTH | GPIO_PULL_UP)
/* Port power control interrupts */
GPIO_INT(HDMI_CONN0_OC_ODL, PIN(0, 7), GPIO_INT_BOTH, port_ocp_interrupt)
GPIO_INT(HDMI_CONN1_OC_ODL, PIN(0, 6), GPIO_INT_BOTH, port_ocp_interrupt)
-GPIO_INT(USB_A0_OC_ODL, PIN(E, 4), GPIO_INT_BOTH, port_ocp_interrupt)
GPIO_INT(USB_A1_OC_ODL, PIN(A, 2), GPIO_INT_BOTH, port_ocp_interrupt)
GPIO_INT(USB_A2_OC_ODL, PIN(F, 5), GPIO_INT_BOTH, port_ocp_interrupt)
GPIO_INT(USB_A3_OC_ODL, PIN(0, 3), GPIO_INT_BOTH, port_ocp_interrupt)
-/* May be reconfigured as input */
-GPIO_INT(USB_A4_OC_ODL, PIN(B, 0), GPIO_OUT_LOW | GPIO_INT_BOTH, port_ocp_interrupt)
/* PCH/CPU signals */
GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW)
@@ -84,22 +81,29 @@ GPIO(EN_PPVAR_BJ_ADP_L, PIN(0, 4), GPIO_OUT_LOW)
/* USB type A */
GPIO(EN_PP5000_USB_VBUS, PIN(8, 3), GPIO_OUT_LOW)
GPIO(USB_A_LOW_PWR_OD, PIN(9, 4), GPIO_ODR_LOW)
-GPIO(USB_A2_STATUS_L, PIN(6, 1), GPIO_INPUT)
-GPIO(USB_A3_STATUS_L, PIN(C, 7), GPIO_INPUT)
+GPIO(USB_A3_LOW_PWR_OD, PIN(5, 0), GPIO_ODR_LOW)
+GPIO(USB_A1_STATUS_L, PIN(6, 1), GPIO_INPUT)
+GPIO(USB_A2_STATUS_L, PIN(C, 7), GPIO_INPUT)
+GPIO(USB_A3_STATUS_L, PIN(D, 2), GPIO_INPUT)
/* USB type C */
GPIO(USB_C0_TCPC_RST, PIN(9, 7), GPIO_OUT_LOW)
GPIO(USB_C0_POL_L, PIN(0, 0), GPIO_INPUT | GPIO_SEL_1P8V) /* USB-C Polarity */
+/* TPU */
+GPIO(PP3300_TPU_EN, PIN(E, 4), GPIO_OUT_HIGH)
+
+/* PSE controller */
+GPIO(EC_PSE_PWM_INT, PIN(B, 0), GPIO_INPUT) /* PSE controller interrupt */
+GPIO(EC_RST_LTC4291_L, PIN(9, 6), GPIO_OUT_HIGH) /* PSE controller reset */
+
/* Misc. */
GPIO(M2_SSD_PLN, PIN(A, 0), GPIO_INPUT)
GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW)
GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_ODR_HIGH)
GPIO(PACKET_MODE_EN, PIN(7, 5), GPIO_OUT_LOW)
-GPIO(EC_RST_LTC4291_L, PIN(9, 6), GPIO_OUT_HIGH) /* PSE controller reset */
/* HDMI/CEC */
-GPIO(EN_PP5000_HDMI, PIN(5, 0), GPIO_OUT_LOW)
GPIO(HDMI_CONN0_CEC_OUT, PIN(B, 1), GPIO_ODR_HIGH)
GPIO(HDMI_CONN0_CEC_IN, PIN(4, 0), GPIO_INPUT)
GPIO(HDMI_CONN1_CEC_OUT, PIN(9, 5), GPIO_ODR_HIGH)
@@ -161,7 +165,6 @@ UNUSED(PIN(3, 2)) /* E5 NC */
UNUSED(PIN(D, 6)) /* F6 NC */
UNUSED(PIN(3, 5)) /* F5 NC */
UNUSED(PIN(5, 6)) /* M2 NC */
-UNUSED(PIN(D, 2)) /* C11 NC */
UNUSED(PIN(8, 6)) /* J8 NC */
UNUSED(PIN(9, 3)) /* M11 NC */
UNUSED(PIN(7, 2)) /* H6 NC */
diff --git a/board/gimble/battery.c b/board/gimble/battery.c
index a18ab029b6..235503a6f1 100644
--- a/board/gimble/battery.c
+++ b/board/gimble/battery.c
@@ -32,67 +32,63 @@
* address, mask, and disconnect value need to be provided.
*/
const struct board_batt_params board_battery_info[] = {
- /* POW-TECH GQA05 Battery Information */
- [BATTERY_POWER_TECH] = {
- /* BQ40Z50 Fuel Gauge */
+ /* SMP 996QA193H Battery Information */
+ [BATTERY_SIMPLO_HIGHPOWER] = {
.fuel_gauge = {
- .manuf_name = "POW-TECH",
- .device_name = "BATGQA05L22",
+ .manuf_name = "333-1D-11-A",
.ship_mode = {
- .reg_addr = 0x00,
+ .reg_addr = 0x0,
.reg_data = { 0x0010, 0x0010 },
},
.fet = {
.mfgacc_support = 1,
- .reg_addr = 0x00,
- .reg_mask = 0x2000, /* XDSG */
- .disconnect_val = 0x2000,
- }
+ .reg_addr = 0x0,
+ .reg_mask = 0x0006,
+ .disconnect_val = 0x0,
+ },
},
.batt_info = {
- .voltage_max = TARGET_WITH_MARGIN(13050, 5),
- .voltage_normal = 11400, /* mV */
- .voltage_min = 9000, /* mV */
- .precharge_current = 280, /* mA */
- .start_charging_min_c = 0,
- .start_charging_max_c = 45,
- .charging_min_c = 0,
- .charging_max_c = 45,
- .discharging_min_c = -10,
- .discharging_max_c = 60,
+ .voltage_max = 13200, /* mV */
+ .voltage_normal = 11550, /* mV */
+ .voltage_min = 9000, /* mV */
+ .precharge_current = 256, /* mA */
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 45,
+ .charging_min_c = 0,
+ .charging_max_c = 45,
+ .discharging_min_c = -20,
+ .discharging_max_c = 60,
},
},
- /* LGC L17L3PB0 Battery Information */
- /*
- * Battery info provided by ODM on b/143477210, comment #11
- */
- [BATTERY_LGC011] = {
+ /* Cosmx CA407792G Battery Information */
+ [BATTERY_COSMX] = {
.fuel_gauge = {
- .manuf_name = "LGC",
+ .manuf_name = "333-AC-11-A",
.ship_mode = {
- .reg_addr = 0x00,
+ .reg_addr = 0x0,
.reg_data = { 0x0010, 0x0010 },
},
.fet = {
+ .mfgacc_support = 1,
.reg_addr = 0x0,
- .reg_mask = 0x6000,
- .disconnect_val = 0x6000,
- }
+ .reg_mask = 0x0006,
+ .disconnect_val = 0x0,
+ },
},
.batt_info = {
- .voltage_max = TARGET_WITH_MARGIN(13200, 5),
- .voltage_normal = 11550, /* mV */
- .voltage_min = 9000, /* mV */
- .precharge_current = 256, /* mA */
- .start_charging_min_c = 0,
- .start_charging_max_c = 45,
- .charging_min_c = 0,
- .charging_max_c = 60,
- .discharging_min_c = 0,
- .discharging_max_c = 75,
+ .voltage_max = 13200, /* mV */
+ .voltage_normal = 11550, /* mV */
+ .voltage_min = 9000, /* mV */
+ .precharge_current = 256, /* mA */
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 45,
+ .charging_min_c = 0,
+ .charging_max_c = 45,
+ .discharging_min_c = -10,
+ .discharging_max_c = 60,
},
},
};
BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT);
-const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_POWER_TECH;
+const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_SIMPLO_HIGHPOWER;
diff --git a/board/gimble/board.h b/board/gimble/board.h
index 05f3df026a..144be95449 100644
--- a/board/gimble/board.h
+++ b/board/gimble/board.h
@@ -40,9 +40,17 @@
/* Lid accel */
#define CONFIG_LID_ANGLE
+#define CONFIG_LID_ANGLE_UPDATE
#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL
#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL
+/* Enable sensor fifo, must also define the _SIZE and _THRES */
+#define CONFIG_ACCEL_FIFO
+/* FIFO size is in power of 2. */
+#define CONFIG_ACCEL_FIFO_SIZE 256
+/* Depends on how fast the AP boots and typical ODRs */
+#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3)
+
/* Sensor console commands */
#define CONFIG_CMD_ACCELS
#define CONFIG_CMD_ACCEL_INFO
@@ -175,13 +183,15 @@
enum adc_channel {
ADC_TEMP_SENSOR_1_DDR_SOC,
- ADC_TEMP_SENSOR_2_CHARGER,
+ ADC_TEMP_SENSOR_2_FAN,
+ ADC_TEMP_SENSOR_3_CHARGER,
ADC_CH_COUNT
};
enum temp_sensor_id {
TEMP_SENSOR_1_DDR_SOC,
- TEMP_SENSOR_2_CHARGER,
+ TEMP_SENSOR_2_FAN,
+ TEMP_SENSOR_3_CHARGER,
TEMP_SENSOR_COUNT
};
@@ -198,8 +208,8 @@ enum ioex_port {
};
enum battery_type {
- BATTERY_POWER_TECH,
- BATTERY_LGC011,
+ BATTERY_SIMPLO_HIGHPOWER,
+ BATTERY_COSMX,
BATTERY_TYPE_COUNT
};
diff --git a/board/gimble/gpio.inc b/board/gimble/gpio.inc
index 28699b5b17..a1f8934a67 100644
--- a/board/gimble/gpio.inc
+++ b/board/gimble/gpio.inc
@@ -68,7 +68,7 @@ GPIO(IMVP9_VRRDY_OD, PIN(4, 3), GPIO_INPUT)
GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW)
GPIO(POWER_LED_GATE, PIN(B, 6), GPIO_OUT_LOW) /* Power LED: White */
GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
-GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_OUT_LOW)
+GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW)
GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_LOW)
GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW)
@@ -95,7 +95,6 @@ ALTERNATE(PIN_MASK(C, 0x1c), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPI
/* ADC alternate functions */
ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */
ALTERNATE(PIN_MASK(4, 0x34), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1 */
-ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */
/* KB alternate functions */
ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */
diff --git a/board/gimble/keyboard.c b/board/gimble/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/gimble/keyboard.c
+++ b/board/gimble/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/gimble/sensors.c b/board/gimble/sensors.c
index 47149b05d0..2931e68d31 100644
--- a/board/gimble/sensors.c
+++ b/board/gimble/sensors.c
@@ -10,6 +10,7 @@
#include "driver/accel_bma2x2_public.h"
#include "driver/accelgyro_bmi_common.h"
#include "hooks.h"
+#include "keyboard_scan.h"
#include "motion_sense.h"
#include "temp_sensor.h"
#include "thermal.h"
@@ -24,13 +25,20 @@ const struct adc_t adc_channels[] = {
.factor_div = ADC_READ_MAX + 1,
.shift = 0,
},
- [ADC_TEMP_SENSOR_2_CHARGER] = {
- .name = "TEMP_CHARGER",
+ [ADC_TEMP_SENSOR_2_FAN] = {
+ .name = "TEMP_FAN",
.input_ch = NPCX_ADC_CH1,
.factor_mul = ADC_MAX_VOLT,
.factor_div = ADC_READ_MAX + 1,
.shift = 0,
},
+ [ADC_TEMP_SENSOR_3_CHARGER] = {
+ .name = "TEMP_CHARGER",
+ .input_ch = NPCX_ADC_CH6,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
};
BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
@@ -147,17 +155,23 @@ const struct temp_sensor_t temp_sensors[] = {
.read = get_temp_3v3_30k9_47k_4050b,
.idx = ADC_TEMP_SENSOR_1_DDR_SOC
},
- [TEMP_SENSOR_2_CHARGER] = {
+ [TEMP_SENSOR_2_FAN] = {
+ .name = "Fan",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_2_FAN
+ },
+ [TEMP_SENSOR_3_CHARGER] = {
.name = "Charger",
.type = TEMP_SENSOR_TYPE_BOARD,
.read = get_temp_3v3_30k9_47k_4050b,
- .idx = ADC_TEMP_SENSOR_2_CHARGER
+ .idx = ADC_TEMP_SENSOR_3_CHARGER
},
};
BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
/*
- * TODO(b/180681346): update for Alder Lake/brya
+ * TODO(b/194318801): confirm thermal limits setting for gimble
*
* Tiger Lake specifies 100 C as maximum TDP temperature. THRMTRIP# occurs at
* 130 C. However, sensor is located next to DDR, so we need to use the lower
@@ -176,7 +190,7 @@ static const struct ec_thermal_config thermal_cpu = {
};
/*
- * TODO(b/180681346): update for Alder Lake/brya
+ * TODO(b/194318801): confirm thermal limits setting for gimble
*
* Inductor limits - used for both charger and PP3300 regulator
*
@@ -203,6 +217,27 @@ static const struct ec_thermal_config thermal_inductor = {
/* this should really be "const" */
struct ec_thermal_config thermal_params[] = {
[TEMP_SENSOR_1_DDR_SOC] = thermal_cpu,
- [TEMP_SENSOR_2_CHARGER] = thermal_inductor,
+ /* TODO(b/194318801): confirm thermal limits setting for gimble */
+ [TEMP_SENSOR_2_FAN] = thermal_inductor,
+ [TEMP_SENSOR_3_CHARGER] = thermal_inductor,
};
BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);
+
+#ifndef TEST_BUILD
+void lid_angle_peripheral_enable(int enable)
+{
+ int chipset_in_s0 = chipset_in_state(CHIPSET_STATE_ON);
+
+ if (enable) {
+ keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE);
+ } else {
+ /*
+ * Ensure that the chipset is off before disabling the keyboard.
+ * When the chipset is on, the EC keeps the keyboard enabled and
+ * the AP decides whether to ignore input devices or not.
+ */
+ if (!chipset_in_s0)
+ keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE);
+ }
+}
+#endif
diff --git a/board/gimble/usbc_config.c b/board/gimble/usbc_config.c
index d5e228876e..83042ab91e 100644
--- a/board/gimble/usbc_config.c
+++ b/board/gimble/usbc_config.c
@@ -148,18 +148,10 @@ void config_usb_db_type(void)
CPRINTS("Configured USB DB type number is %d", db_type);
}
-static enum gpio_signal ps8xxx_rst_odl = GPIO_USB_C1_RT_RST_R_ODL;
-
static void ps8815_reset(void)
{
int val;
- gpio_set_level(ps8xxx_rst_odl, 0);
- msleep(GENERIC_MAX(PS8XXX_RESET_DELAY_MS,
- PS8815_PWR_H_RST_H_DELAY_MS));
- gpio_set_level(ps8xxx_rst_odl, 1);
- msleep(PS8815_FW_INIT_DELAY_MS);
-
CPRINTS("%s: patching ps8815 registers", __func__);
if (i2c_read8(I2C_PORT_USB_C1_TCPC,
@@ -177,6 +169,18 @@ static void ps8815_reset(void)
void board_reset_pd_mcu(void)
{
+ /* Port0 */
+ gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 0);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0);
+ msleep(GENERIC_MAX(PS8XXX_RESET_DELAY_MS,
+ PS8815_PWR_H_RST_H_DELAY_MS));
+
+ gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 1);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1);
+ /* wait for chips to come up */
+ msleep(PS8815_FW_INIT_DELAY_MS);
+
+ /* Port1 */
ps8815_reset();
usb_mux_hpd_update(USBC_PORT_C1, 0, 0);
}
diff --git a/board/glkrvp_ite/board.c b/board/glkrvp_ite/board.c
index b1102092b0..2a222ada7b 100644
--- a/board/glkrvp_ite/board.c
+++ b/board/glkrvp_ite/board.c
@@ -195,7 +195,7 @@ static void pmic_init(void)
DECLARE_HOOK(HOOK_INIT, pmic_init, HOOK_PRIO_INIT_I2C + 1);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 35,
.debounce_down_us = 5 * MSEC,
.debounce_up_us = 40 * MSEC,
diff --git a/board/glkrvp_ite/board.h b/board/glkrvp_ite/board.h
index 2816a02f86..da9313580b 100644
--- a/board/glkrvp_ite/board.h
+++ b/board/glkrvp_ite/board.h
@@ -52,7 +52,7 @@
#define DEDICATED_CHARGE_PORT 2
/* Keyboard */
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
/* UART */
diff --git a/board/gumboz/board.c b/board/gumboz/board.c
index 8108798d63..b04a09f0f5 100644
--- a/board/gumboz/board.c
+++ b/board/gumboz/board.c
@@ -497,7 +497,7 @@ static void setup_fw_config(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/gumboz/board.h b/board/gumboz/board.h
index 7375965bb1..e1ba89d63e 100644
--- a/board/gumboz/board.h
+++ b/board/gumboz/board.h
@@ -180,11 +180,6 @@ void tcpc_alert_event(enum gpio_signal signal);
void bc12_interrupt(enum gpio_signal signal);
void ppc_interrupt(enum gpio_signal signal);
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/haboki/board.h b/board/haboki/board.h
index 6161151a93..2f42b616e0 100644
--- a/board/haboki/board.h
+++ b/board/haboki/board.h
@@ -146,11 +146,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/halvor/board.c b/board/halvor/board.c
index 3f660c7f76..078d0520f6 100644
--- a/board/halvor/board.c
+++ b/board/halvor/board.c
@@ -41,7 +41,7 @@
#include "gpio_list.h" /* Must come after other header files. */
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/hammer/board.c b/board/hammer/board.c
index a9885cea81..911909653d 100644
--- a/board/hammer/board.c
+++ b/board/hammer/board.c
@@ -125,8 +125,7 @@ int usb_i2c_board_is_enabled(void)
return !system_is_locked();
}
-#ifdef CONFIG_KEYBOARD_BOARD_CONFIG
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 50,
.debounce_down_us = 9 * MSEC,
.debounce_up_us = 30 * MSEC,
@@ -139,7 +138,6 @@ struct keyboard_scan_config keyscan_config = {
},
};
#endif
-#endif
#if defined(BOARD_WAND) && defined(SECTION_IS_RW)
struct consumer const ec_ec_usart_consumer;
diff --git a/board/hammer/variants.h b/board/hammer/variants.h
index 60920dda53..fbfa985ba9 100644
--- a/board/hammer/variants.h
+++ b/board/hammer/variants.h
@@ -121,7 +121,7 @@
/* Assistant key */
#if defined(BOARD_HAMMER) || defined(BOARD_WAND) || defined(BOARD_WHISKERS)
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_ASSISTANT_KEY
#endif
diff --git a/board/hatch_fp/board_rw.c b/board/hatch_fp/board_rw.c
index 6e6b50b47c..09c78c5e5c 100644
--- a/board/hatch_fp/board_rw.c
+++ b/board/hatch_fp/board_rw.c
@@ -67,6 +67,12 @@ const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices);
static void configure_fp_sensor_spi(void)
{
+ /* The dragonclaw development board needs this enabled to enable the
+ * AND gate (U10) to CS. Production boards could disable this to save
+ * power since it's only needed for initial detection on those boards.
+ */
+ gpio_set_level(GPIO_DIVIDER_HIGHSIDE, 1);
+
/* Configure SPI GPIOs */
gpio_config_module(MODULE_SPI_CONTROLLER, 1);
diff --git a/board/hatch_fp/fpsensor_detect_rw.c b/board/hatch_fp/fpsensor_detect_rw.c
index 85ace2c679..274cfee054 100644
--- a/board/hatch_fp/fpsensor_detect_rw.c
+++ b/board/hatch_fp/fpsensor_detect_rw.c
@@ -24,7 +24,11 @@ enum fp_sensor_type get_fp_sensor_type(void)
ret = FP_SENSOR_TYPE_UNKNOWN;
break;
}
- gpio_set_level(GPIO_DIVIDER_HIGHSIDE, 0);
+ /* We leave GPIO_DIVIDER_HIGHSIDE enabled, since the dragonclaw
+ * development board use it to enable the AND gate (U10) to CS.
+ * Production boards could disable this to save power since it's
+ * only needed for initial detection on those boards.
+ */
return ret;
}
diff --git a/board/herobrine_npcx7/board.c b/board/herobrine_npcx7/board.c
index 5d4e26ea38..b5f55ea10c 100644
--- a/board/herobrine_npcx7/board.c
+++ b/board/herobrine_npcx7/board.c
@@ -43,7 +43,7 @@ const enum gpio_signal hibernate_wake_pins[] = {
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/herobrine_npcx7/board.h b/board/herobrine_npcx7/board.h
index 197cf01209..68ca138e90 100644
--- a/board/herobrine_npcx7/board.h
+++ b/board/herobrine_npcx7/board.h
@@ -23,7 +23,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* Battery */
diff --git a/board/herobrine_npcx9/board.c b/board/herobrine_npcx9/board.c
index eaf6ed0399..620880b607 100644
--- a/board/herobrine_npcx9/board.c
+++ b/board/herobrine_npcx9/board.c
@@ -43,7 +43,7 @@ const enum gpio_signal hibernate_wake_pins[] = {
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/herobrine_npcx9/board.h b/board/herobrine_npcx9/board.h
index 1800d1255f..14a8366684 100644
--- a/board/herobrine_npcx9/board.h
+++ b/board/herobrine_npcx9/board.h
@@ -20,7 +20,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* Battery */
diff --git a/board/homestar/base_detect.c b/board/homestar/base_detect.c
index 5527018160..2bd115ea2a 100644
--- a/board/homestar/base_detect.c
+++ b/board/homestar/base_detect.c
@@ -86,7 +86,7 @@ static void base_detect_change(enum base_status status)
return;
gpio_set_level(GPIO_EN_BASE, connected);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
base_set_state(connected);
current_base_status = status;
}
diff --git a/board/homestar/board.c b/board/homestar/board.c
index 79451b4e3f..8d277c4793 100644
--- a/board/homestar/board.c
+++ b/board/homestar/board.c
@@ -450,11 +450,7 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
__overridable uint16_t board_get_ps8xxx_product_id(int port)
{
- /* Coachz board rev 2+ changes TCPC from 8805 to 8755*/
- if (system_get_board_version() < 2)
- return PS8805_PRODUCT_ID;
-
- return PS8755_PRODUCT_ID;
+ return PS8805_PRODUCT_ID;
}
void board_tcpc_init(void)
diff --git a/board/homestar/board.h b/board/homestar/board.h
index d3fa5121d3..650ba638ec 100644
--- a/board/homestar/board.h
+++ b/board/homestar/board.h
@@ -54,6 +54,14 @@
#define CONFIG_DETACHABLE_BASE
#define CONFIG_BASE_ATTACHED_SWITCH
+/*
+ * Oled panel need to setup both vcc and backlight, AP will ctrl them.
+ * BL_DISABLE does not need to be controlled by ec.
+ */
+#ifdef CONFIG_BACKLIGHT_LID
+#undef CONFIG_BACKLIGHT_LID
+#endif
+
/* GPIO alias */
#define GPIO_AC_PRESENT GPIO_CHG_ACOK_OD
#define GPIO_WP_L GPIO_EC_FLASH_WP_ODL
diff --git a/board/icarus/board.h b/board/icarus/board.h
index e70fc7113d..b9232d65a5 100644
--- a/board/icarus/board.h
+++ b/board/icarus/board.h
@@ -115,8 +115,6 @@ enum battery_type {
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
#ifdef SECTION_IS_RO
/* Interrupt handler for AP jump to BL */
diff --git a/board/it8xxx2_pdevb/board.h b/board/it8xxx2_pdevb/board.h
index 3d92745f0e..8646c6c7b3 100644
--- a/board/it8xxx2_pdevb/board.h
+++ b/board/it8xxx2_pdevb/board.h
@@ -22,7 +22,6 @@
#undef CONFIG_FANS
#undef CONFIG_IT83XX_ENABLE_MOUSE_DEVICE
#undef CONFIG_IT83XX_SMCLK2_ON_GPC7
-#undef CONFIG_KEYBOARD_BOARD_CONFIG
#undef CONFIG_KEYBOARD_PROTOCOL_8042
#undef CONFIG_PECI
#undef CONFIG_PECI_COMMON
diff --git a/board/jacuzzi/board.c b/board/jacuzzi/board.c
index ae4a12b418..810f332c50 100644
--- a/board/jacuzzi/board.c
+++ b/board/jacuzzi/board.c
@@ -92,7 +92,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
@@ -341,7 +341,7 @@ static void board_init(void)
GPIO_INPUT | GPIO_PULL_DOWN);
#endif /* !VARIANT_KUKUI_NO_SENSORS */
/* Disable tablet mode. */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
gmr_tablet_switch_disable();
gpio_set_flags(GPIO_TABLET_MODE_L,
GPIO_INPUT | GPIO_PULL_UP);
diff --git a/board/jinlon/board.h b/board/jinlon/board.h
index ada665098e..beb30c8e12 100644
--- a/board/jinlon/board.h
+++ b/board/jinlon/board.h
@@ -183,11 +183,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/kano/keyboard.c b/board/kano/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/kano/keyboard.c
+++ b/board/kano/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/kappa/board.c b/board/kappa/board.c
index 7030c71c72..538c4d957b 100644
--- a/board/kappa/board.c
+++ b/board/kappa/board.c
@@ -86,7 +86,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/kindred/board.h b/board/kindred/board.h
index 99bdce09a9..79fc7c0642 100644
--- a/board/kindred/board.h
+++ b/board/kindred/board.h
@@ -179,8 +179,6 @@ enum battery_type {
/* Sensors without hardware FIFO are in forced mode */
#define CONFIG_ACCEL_FORCE_MODE_MASK (1 << LID_ACCEL)
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
void motion_interrupt(enum gpio_signal signal);
void ccd_mode_isr(enum gpio_signal signal);
diff --git a/board/kracko/board.h b/board/kracko/board.h
index e3443e1afc..ce26c90b70 100644
--- a/board/kracko/board.h
+++ b/board/kracko/board.h
@@ -143,12 +143,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/lalala/board.c b/board/lalala/board.c
index 42d6659072..c7f6bb2b05 100644
--- a/board/lalala/board.c
+++ b/board/lalala/board.c
@@ -72,7 +72,7 @@ const int usb_port_enable[USB_PORT_COUNT] = {
};
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/lalala/board.h b/board/lalala/board.h
index 5113db18e1..1cbb6bf7e2 100644
--- a/board/lalala/board.h
+++ b/board/lalala/board.h
@@ -35,7 +35,7 @@
#define GPIO_USB_C1_INT_ODL GPIO_SUB_USB_C1_INT_ODL
/* Keyboard */
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_KEYPAD
#define CONFIG_PWM_KBLIGHT
diff --git a/board/lantis/board.h b/board/lantis/board.h
index 31627fc5ce..df209187ac 100644
--- a/board/lantis/board.h
+++ b/board/lantis/board.h
@@ -139,11 +139,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/lazor/board.c b/board/lazor/board.c
index 688df9f4c2..d04f282c00 100644
--- a/board/lazor/board.c
+++ b/board/lazor/board.c
@@ -38,7 +38,7 @@
#include "gpio_list.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/lazor/board.h b/board/lazor/board.h
index 937f34e709..77198f69ee 100644
--- a/board/lazor/board.h
+++ b/board/lazor/board.h
@@ -18,7 +18,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* Battery */
@@ -118,8 +118,6 @@ enum battery_type {
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
/* Reset all TCPCs. */
void board_reset_pd_mcu(void);
diff --git a/board/lindar/board.c b/board/lindar/board.c
index 57d9fdeb14..621d0d305d 100644
--- a/board/lindar/board.c
+++ b/board/lindar/board.c
@@ -45,7 +45,7 @@
#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
@@ -76,7 +76,7 @@ static void board_init(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_EC_IMU_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/lingcod/board.c b/board/lingcod/board.c
index 56e9fb067e..88913a63af 100644
--- a/board/lingcod/board.c
+++ b/board/lingcod/board.c
@@ -44,7 +44,7 @@
#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
@@ -75,7 +75,7 @@ static void board_init(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_EC_IMU_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/magolor/board.c b/board/magolor/board.c
index 08ae6f1a04..399ec040b2 100644
--- a/board/magolor/board.c
+++ b/board/magolor/board.c
@@ -73,7 +73,7 @@ const int usb_port_enable[USB_PORT_COUNT] = {
#ifdef BOARD_MAGOLOR
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/magolor/board.h b/board/magolor/board.h
index 8f8367f95f..c1ef73cc64 100644
--- a/board/magolor/board.h
+++ b/board/magolor/board.h
@@ -49,7 +49,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_FACTORY_TEST
#ifdef BOARD_MAGOLOR
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_KEYPAD
#endif
#define CONFIG_PWM_KBLIGHT
@@ -207,9 +207,6 @@ enum battery_type {
BATTERY_TYPE_COUNT,
};
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-
void motion_interrupt(enum gpio_signal signal);
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/makomo/board.c b/board/makomo/board.c
index d0289a945d..1f1e3c3521 100644
--- a/board/makomo/board.c
+++ b/board/makomo/board.c
@@ -87,7 +87,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/malefor/board.c b/board/malefor/board.c
index 697ee909b9..394aec8ee7 100644
--- a/board/malefor/board.c
+++ b/board/malefor/board.c
@@ -45,7 +45,7 @@
#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
@@ -76,7 +76,7 @@ static void board_init(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_EC_IMU_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/marzipan/board.c b/board/marzipan/board.c
index 135e333b55..98716991cc 100644
--- a/board/marzipan/board.c
+++ b/board/marzipan/board.c
@@ -84,7 +84,7 @@ void board_connect_c0_sbu(enum gpio_signal s)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/marzipan/board.h b/board/marzipan/board.h
index 54054456eb..3ef8952ee5 100644
--- a/board/marzipan/board.h
+++ b/board/marzipan/board.h
@@ -15,7 +15,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* Battery */
diff --git a/board/meep/board.h b/board/meep/board.h
index 10fecc874b..013237e2d7 100644
--- a/board/meep/board.h
+++ b/board/meep/board.h
@@ -113,11 +113,6 @@ enum ppc_type {
PPC_TYPE_COUNT,
};
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
int board_is_convertible(void);
#endif /* !__ASSEMBLER__ */
diff --git a/board/morphius/board.h b/board/morphius/board.h
index 45fae888aa..603bcec69b 100644
--- a/board/morphius/board.h
+++ b/board/morphius/board.h
@@ -217,11 +217,6 @@ extern const struct usb_mux usbc1_ps8802;
extern const struct usb_mux usbc1_ps8818;
extern struct usb_mux usbc1_amd_fp5_usb_mux;
-#ifdef CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-#endif
-
#endif /* !__ASSEMBLER__ */
diff --git a/board/mrbland/base_detect.c b/board/mrbland/base_detect.c
index 5527018160..2bd115ea2a 100644
--- a/board/mrbland/base_detect.c
+++ b/board/mrbland/base_detect.c
@@ -86,7 +86,7 @@ static void base_detect_change(enum base_status status)
return;
gpio_set_level(GPIO_EN_BASE, connected);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
base_set_state(connected);
current_base_status = status;
}
diff --git a/board/munna/board.c b/board/munna/board.c
index 21def7d917..8a81ed5966 100644
--- a/board/munna/board.c
+++ b/board/munna/board.c
@@ -37,7 +37,6 @@
#include "registers.h"
#include "spi.h"
#include "system.h"
-#include "tablet_mode.h"
#include "task.h"
#include "tcpm/tcpm.h"
#include "timer.h"
@@ -89,7 +88,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/munna/board.h b/board/munna/board.h
index 50cd6111ca..f530c45781 100644
--- a/board/munna/board.h
+++ b/board/munna/board.h
@@ -120,6 +120,11 @@
(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |\
EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON))
+#undef CONFIG_GMR_TABLET_MODE
+#undef GMR_TABLET_MODE_GPIO_L
+#undef CONFIG_TABLET_MODE
+#undef CONFIG_TABLET_MODE_SWITCH
+
#ifndef __ASSEMBLER__
enum adc_channel {
diff --git a/board/munna/gpio.inc b/board/munna/gpio.inc
index ad71f60b36..50e5ee3a47 100644
--- a/board/munna/gpio.inc
+++ b/board/munna/gpio.inc
@@ -37,11 +37,10 @@ GPIO_INT(IT8801_SMB_INT, PIN(A, 8), GPIO_INT_FALLING | GPIO_PULL_UP,
io_expander_it8801_interrupt) /* KB_INT_ODL */
GPIO_INT(AP_EC_WATCHDOG_L, PIN(D, 2), GPIO_INT_FALLING,
chipset_watchdog_interrupt)
-GPIO_INT(TABLET_MODE_L, PIN(B, 11), GPIO_INT_BOTH,
- gmr_tablet_switch_isr)
/* Unimplemented interrupts */
GPIO(ALS_RGB_INT_ODL, PIN(C, 10), GPIO_INPUT)
+GPIO(TABLET_MODE_L, PIN(B, 11), GPIO_INPUT)
/* Reset pins */
GPIO(AP_SYS_RST_L, PIN(C, 11), GPIO_OUT_LOW)
diff --git a/board/mushu/board.h b/board/mushu/board.h
index fe47cc0acd..1bd58abbba 100644
--- a/board/mushu/board.h
+++ b/board/mushu/board.h
@@ -11,6 +11,12 @@
/* Baseboard features */
#include "baseboard.h"
+/* Reduce flash usage */
+#define CONFIG_USB_PD_DEBUG_LEVEL 2
+#undef CONFIG_CMD_ACCELSPOOF
+#undef CONFIG_CMD_CHARGER_DUMP
+#undef CONFIG_CMD_PPC_DUMP
+
#define CONFIG_POWER_BUTTON
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_LED_COMMON
diff --git a/board/nami/board.c b/board/nami/board.c
index 2526cab319..27df3a1fe7 100644
--- a/board/nami/board.c
+++ b/board/nami/board.c
@@ -963,7 +963,7 @@ static void cbi_init(void)
DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_INIT_I2C + 1);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/nami/board.h b/board/nami/board.h
index b2bb4c5dae..6d340af1df 100644
--- a/board/nami/board.h
+++ b/board/nami/board.h
@@ -28,7 +28,7 @@
#define CONFIG_FPU
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_KEYPAD
@@ -214,8 +214,6 @@
/* support factory keyboard test */
#define CONFIG_KEYBOARD_FACTORY_TEST
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
#include "gpio_signal.h"
#include "registers.h"
diff --git a/board/nightfury/board.c b/board/nightfury/board.c
index 9e73ca19e8..604e406c40 100644
--- a/board/nightfury/board.c
+++ b/board/nightfury/board.c
@@ -305,7 +305,7 @@ const struct motion_sensor_t *motion_als_sensors[] = {
};
BUILD_ASSERT(ARRAY_SIZE(motion_als_sensors) == ALS_COUNT);
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 80,
.debounce_down_us = 30 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/nightfury/board.h b/board/nightfury/board.h
index 687fc910f4..31207b2a52 100644
--- a/board/nightfury/board.h
+++ b/board/nightfury/board.h
@@ -16,7 +16,7 @@
#define CONFIG_POWER_BUTTON
#define CONFIG_KEYBOARD_PROTOCOL_8042
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_LED_COMMON
#define CONFIG_LOW_POWER_IDLE
diff --git a/board/npcx7_evb/board.c b/board/npcx7_evb/board.c
index 5fa421d917..42514c2432 100644
--- a/board/npcx7_evb/board.c
+++ b/board/npcx7_evb/board.c
@@ -109,7 +109,7 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 40,
.debounce_down_us = 6 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/npcx7_evb/board.h b/board/npcx7_evb/board.h
index 3b75680eb3..4bad61b152 100644
--- a/board/npcx7_evb/board.h
+++ b/board/npcx7_evb/board.h
@@ -37,7 +37,7 @@
#define CONFIG_BOARD_VERSION_GPIO
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#undef CONFIG_LOW_POWER_IDLE /* Deep Sleep Support */
#define CONFIG_POWER_BUTTON
diff --git a/board/npcx9_evb/board.c b/board/npcx9_evb/board.c
index 2a7b1e2945..876ca7bd10 100644
--- a/board/npcx9_evb/board.c
+++ b/board/npcx9_evb/board.c
@@ -123,7 +123,7 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 40,
.debounce_down_us = 6 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/npcx9_evb/board.h b/board/npcx9_evb/board.h
index 345f601e91..e7e1190480 100644
--- a/board/npcx9_evb/board.h
+++ b/board/npcx9_evb/board.h
@@ -23,7 +23,7 @@
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_HIBERNATE_PSL_COMPENSATE_RTC
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#undef CONFIG_LOW_POWER_IDLE /* Deep Sleep Support */
#define CONFIG_POWER_BUTTON
diff --git a/board/npcx_evb/board.c b/board/npcx_evb/board.c
index cee9acfeef..c86f35f487 100644
--- a/board/npcx_evb/board.c
+++ b/board/npcx_evb/board.c
@@ -126,7 +126,7 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 40,
.debounce_down_us = 6 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/npcx_evb/board.h b/board/npcx_evb/board.h
index b97bf43047..fc12b6d80a 100644
--- a/board/npcx_evb/board.h
+++ b/board/npcx_evb/board.h
@@ -24,7 +24,7 @@
#define CONFIG_SPI_FLASH_W25Q64
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_POWER_BUTTON
#define CONFIG_VBOOT_HASH
diff --git a/board/npcx_evb_arm/board.c b/board/npcx_evb_arm/board.c
index f99ab2e0f6..8c4f9c7668 100644
--- a/board/npcx_evb_arm/board.c
+++ b/board/npcx_evb_arm/board.c
@@ -97,7 +97,7 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
/******************************************************************************/
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 40,
.debounce_down_us = 6 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/npcx_evb_arm/board.h b/board/npcx_evb_arm/board.h
index 582807a1b2..3598457a5e 100644
--- a/board/npcx_evb_arm/board.h
+++ b/board/npcx_evb_arm/board.h
@@ -20,7 +20,7 @@
#define CONFIG_SPI_FLASH_W25Q64
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_MKBP /* Instead of 8042 protocol of keyboard */
#define CONFIG_MKBP_USE_GPIO
#define CONFIG_POWER_BUTTON
diff --git a/board/nuwani/board.c b/board/nuwani/board.c
index 5d5f5f842d..8004e25b37 100644
--- a/board/nuwani/board.c
+++ b/board/nuwani/board.c
@@ -172,7 +172,7 @@ void board_update_sensor_config_from_sku(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L,
GPIO_INPUT | GPIO_PULL_DOWN);
diff --git a/board/pazquel/board.c b/board/pazquel/board.c
index 7406d8cc2e..edcc8e008b 100644
--- a/board/pazquel/board.c
+++ b/board/pazquel/board.c
@@ -118,7 +118,7 @@ static void board_connect_c0_sbu(enum gpio_signal s)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/pazquel/board.h b/board/pazquel/board.h
index 08a8f161f1..121158f231 100644
--- a/board/pazquel/board.h
+++ b/board/pazquel/board.h
@@ -23,7 +23,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* BC 1.2 Charger */
diff --git a/board/pirika/board.c b/board/pirika/board.c
index 0c754b2f4a..f780931107 100644
--- a/board/pirika/board.c
+++ b/board/pirika/board.c
@@ -49,7 +49,7 @@ static void check_c0_line(void);
DECLARE_DEFERRED(check_c0_line);
/* Use default keyboard scan config, because board didn't supply one */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* CONFIG_KEYBOARD_COL2_INVERTED is defined for passing the column 2
* to H1 which inverts the signal. The signal passing through H1
diff --git a/board/pirika/board.h b/board/pirika/board.h
index 0330449c17..db119d5191 100644
--- a/board/pirika/board.h
+++ b/board/pirika/board.h
@@ -90,7 +90,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_VIVALDI
#define CONFIG_KEYBOARD_REFRESH_ROW3
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#ifndef __ASSEMBLER__
diff --git a/board/pompom/board.c b/board/pompom/board.c
index c4e4f02a63..ae9af4e596 100644
--- a/board/pompom/board.c
+++ b/board/pompom/board.c
@@ -107,7 +107,7 @@ static void board_connect_c0_sbu(enum gpio_signal s)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/pompom/board.h b/board/pompom/board.h
index c8c9476b25..3f35d7ceab 100644
--- a/board/pompom/board.h
+++ b/board/pompom/board.h
@@ -16,7 +16,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_REFRESH_ROW3
#define CONFIG_PWM_KBLIGHT
diff --git a/board/poppy/base_detect_lux.c b/board/poppy/base_detect_lux.c
index 14a937a7fd..37ed3304fe 100644
--- a/board/poppy/base_detect_lux.c
+++ b/board/poppy/base_detect_lux.c
@@ -128,7 +128,7 @@ static void base_detect_change(enum base_status status)
*/
task_wake(TASK_ID_CHARGER);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
}
static void print_base_detect_value(const char *str, int v)
diff --git a/board/poppy/base_detect_poppy.c b/board/poppy/base_detect_poppy.c
index 8a202a21d9..9638894cb8 100644
--- a/board/poppy/base_detect_poppy.c
+++ b/board/poppy/base_detect_poppy.c
@@ -95,7 +95,7 @@ static void base_detect_change(enum base_status status)
CPRINTS("Base %sconnected", connected ? "" : "not ");
gpio_set_level(GPIO_PP3300_DX_BASE, connected);
- tablet_set_mode(!connected);
+ tablet_set_mode(!connected, TABLET_TRIGGER_BASE);
current_base_status = status;
if (connected)
diff --git a/board/primus/board.h b/board/primus/board.h
index 5f0a8cace5..15b567b92d 100644
--- a/board/primus/board.h
+++ b/board/primus/board.h
@@ -18,6 +18,9 @@
/* Baseboard features */
#include "baseboard.h"
+#define CONFIG_BRINGUP
+#define CONFIG_SYSTEM_UNLOCKED
+
/*
* This will happen automatically on NPCX9 ES2 and later. Do not remove
* until we can confirm all earlier chips are out of service.
@@ -26,18 +29,6 @@
#define CONFIG_MP2964
-/* LED */
-#define CONFIG_LED_PWM
-#define CONFIG_LED_PWM_COUNT 2
-#undef CONFIG_LED_PWM_NEAR_FULL_COLOR
-#undef CONFIG_LED_PWM_SOC_ON_COLOR
-#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR
-#undef CONFIG_LED_PWM_LOW_BATT_COLOR
-#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE
-#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE
-#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE
-#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER
-
/* Sensors */
#undef CONFIG_TABLET_MODE
#undef CONFIG_TABLET_MODE_SWITCH
@@ -198,9 +189,9 @@ enum battery_type {
};
enum pwm_channel {
- PWM_CH_LED2 = 0, /* PWM0 (white charger) */
+ PWM_CH_LED2_WHITE = 0, /* PWM0 (white charger) */
PWM_CH_TKP_A_LED_N, /* PWM1 (LOGO led on A cover) */
- PWM_CH_LED1, /* PWM2 (orange charger) */
+ PWM_CH_LED1_AMBER, /* PWM2 (orange charger) */
PWM_CH_KBLIGHT, /* PWM3 */
PWM_CH_FAN, /* PWM5 */
PWM_CH_LED4, /* PWM7 (power) */
diff --git a/board/primus/ec.tasklist b/board/primus/ec.tasklist
index 89511238c0..c0a5194e89 100644
--- a/board/primus/ec.tasklist
+++ b/board/primus/ec.tasklist
@@ -25,4 +25,5 @@
TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, TASK_STACK_SIZE) \
- TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, TASK_STACK_SIZE)
+ TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, TASK_STACK_SIZE) \
+ TASK_NOTEST(LOGOLED, logoled_task, NULL, LARGER_TASK_STACK_SIZE)
diff --git a/board/primus/gpio.inc b/board/primus/gpio.inc
index 8d9ae44b80..e6bc7f1a02 100644
--- a/board/primus/gpio.inc
+++ b/board/primus/gpio.inc
@@ -69,7 +69,7 @@ GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
GPIO(USB_C0_RT_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
GPIO(PDEV_STP_N, PIN(9, 6), GPIO_ODR_HIGH)
GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW)
-GPIO(USB_C1_RT_RST_ODL, PIN(3, 2), GPIO_ODR_LOW)
+GPIO(USB_C1_RT_RST_ODL, PIN(5, 0), GPIO_ODR_LOW)
GPIO(PAD_FW_RW_EN_N, PIN(B, 5), GPIO_ODR_LOW)
GPIO(TP4_FW_RW_EN_N, PIN(B, 4), GPIO_ODR_LOW)
GPIO(USB_C0_FRS_EN, PIN(3, 5), GPIO_OUT_LOW)
@@ -125,7 +125,7 @@ ALTERNATE(PIN_MASK(6, 0x0C), 0, MODULE_PS2, 0) /* PS2_CLK1/GPIO62,
/* Unused Pins */
UNUSED(PIN(D, 6)) /* GPOD6/CR_SOUT3/SHDF_ESPI_L */
UNUSED(PIN(8, 1)) /* GPIO81/PECI_DATA */
-UNUSED(PIN(5, 0)) /* GPIO50 */
+UNUSED(PIN(3, 2)) /* GPO32/TRIS# */
/* Pre-configured PSL balls: J8 K6 */
diff --git a/board/primus/keyboard.c b/board/primus/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/primus/keyboard.c
+++ b/board/primus/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/primus/led.c b/board/primus/led.c
index f1bad8d68e..dec67263ab 100644
--- a/board/primus/led.c
+++ b/board/primus/led.c
@@ -9,84 +9,214 @@
#include "common.h"
#include "compile_time_macros.h"
+#include "battery.h"
+#include "charge_manager.h"
+#include "charge_state.h"
+#include "chipset.h"
+#include "common.h"
+#include "console.h"
#include "ec_commands.h"
-#include "led_pwm.h"
+#include "extpower.h"
+#include "hooks.h"
+#include "led_common.h"
+#include "power.h"
#include "pwm.h"
+#include "task.h"
+#include "timer.h"
#include "util.h"
+#define CPRINTS(format, args...) cprints(CC_LOGOLED, format, ## args)
+
+#define LED_ON_LVL 100
+#define LED_OFF_LVL 0
+#define LED_BAT_S3_OFF_TIME_MS 3000
+#define LED_BAT_S3_TICK_MS 50
+#define LED_BAT_S3_PWM_RESCALE 5
+#define LED_TOTAL_TICKS 6
+#define TICKS_STEP1_BRIGHTER 0
+#define TICKS_STEP2_DIMMER (1000 / LED_BAT_S3_TICK_MS)
+#define TICKS_STEP3_OFF (2 * TICKS_STEP2_DIMMER)
+#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS)
+#define LED_LOGO_TICK_SEC (LED_ONE_SEC / 4)
+/* Total on/off duration in a period */
+#define PERIOD (LED_LOGO_TICK_SEC * 2)
+#define LED_ON 1
+#define LED_OFF EC_LED_COLOR_COUNT
+#define LED_EVENT_SUSPEND TASK_EVENT_CUSTOM_BIT(0)
+#define LED_EVENT_200MS_TICK TASK_EVENT_CUSTOM_BIT(1)
+
+static int tick;
-/* TODO(b/190637023)
- * Need to implement specific LED feature for Primus.
- */
const enum ec_led_id supported_led_ids[] = {
- EC_LED_ID_LEFT_LED,
- EC_LED_ID_RIGHT_LED,
+ EC_LED_ID_BATTERY_LED,
+ EC_LED_ID_POWER_LED
};
-
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
-/*
- * We only have a white and an amber LED, so setting any other colour results in
- * both LEDs being off.
- */
-struct pwm_led led_color_map[EC_LED_COLOR_COUNT] = {
- /* Amber, White */
- [EC_LED_COLOR_RED] = { 0, 0 },
- [EC_LED_COLOR_GREEN] = { 0, 0 },
- [EC_LED_COLOR_BLUE] = { 0, 0 },
- [EC_LED_COLOR_YELLOW] = { 0, 0 },
- [EC_LED_COLOR_WHITE] = { 0, 100 },
- [EC_LED_COLOR_AMBER] = { 100, 0 },
-};
+static void led_set_color_battery(enum ec_led_colors color)
+{
+ switch (color) {
+ case EC_LED_COLOR_AMBER:
+ pwm_set_duty(PWM_CH_LED1_AMBER, LED_ON_LVL);
+ pwm_set_duty(PWM_CH_LED2_WHITE, LED_OFF_LVL);
+ break;
+ case EC_LED_COLOR_WHITE:
+ pwm_set_duty(PWM_CH_LED2_WHITE, LED_ON_LVL);
+ pwm_set_duty(PWM_CH_LED1_AMBER, LED_OFF_LVL);
+ break;
+ default: /* LED_OFF and other unsupported colors */
+ pwm_set_duty(PWM_CH_LED1_AMBER, LED_OFF_LVL);
+ pwm_set_duty(PWM_CH_LED2_WHITE, LED_OFF_LVL);
+ break;
+ }
+}
-/* Two logical LEDs with amber and white channels. */
-struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = {
- {
- .ch0 = PWM_CH_LED1,
- .ch1 = PWM_CH_LED2,
- .ch2 = PWM_LED_NO_CHANNEL,
- .enable = &pwm_enable,
- .set_duty = &pwm_set_duty,
- },
- {
- .ch0 = PWM_CH_TKP_A_LED_N,
- .ch1 = PWM_CH_LED4,
- .ch2 = PWM_LED_NO_CHANNEL,
- .enable = &pwm_enable,
- .set_duty = &pwm_set_duty,
- },
-};
+static void led_set_battery(void)
+{
+ switch (charge_get_state()) {
+ case PWR_STATE_CHARGE:
+ /* Always indicate when charging, even in suspend. */
+ led_set_color_battery(EC_LED_COLOR_AMBER);
+ break;
+ case PWR_STATE_DISCHARGE:
+ led_set_color_battery(LED_OFF);
+ break;
+ case PWR_STATE_CHARGE_NEAR_FULL:
+ led_set_color_battery(EC_LED_COLOR_WHITE);
+ break;
+ default:
+ /* Other states don't alter LED behavior */
+ break;
+ }
+}
+
+void led_set_color_power(int onoff_status)
+{
+ /* primus logo led and power led have same behavior. */
+ if (onoff_status == LED_ON) {
+ pwm_set_duty(PWM_CH_TKP_A_LED_N, LED_ON_LVL);
+ pwm_set_duty(PWM_CH_LED4, LED_ON_LVL);
+ } else {
+ /* LED_OFF and unsupported colors */
+ pwm_set_duty(PWM_CH_TKP_A_LED_N, LED_OFF_LVL);
+ pwm_set_duty(PWM_CH_LED4, LED_OFF_LVL);
+ }
+}
+
+#define AC_DISCONNECTED (-1)
+
+static void led_set_power(void)
+{
+ static int plug_ac_countdown;
+ static int ticks;
+
+ if (plug_ac_countdown > 0) {
+ ticks = (ticks + 1) % PERIOD;
+ plug_ac_countdown--;
+ if (ticks < LED_LOGO_TICK_SEC)
+ led_set_color_power(LED_OFF);
+ else
+ led_set_color_power(LED_ON);
+ } else if (chipset_in_state(CHIPSET_STATE_ON))
+ led_set_color_power(LED_ON);
+ else if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ led_set_color_power(LED_OFF);
+
+ /* Check AC_PRESENT */
+ if (!extpower_is_present())
+ plug_ac_countdown = AC_DISCONNECTED;
+ else if (plug_ac_countdown == AC_DISCONNECTED)
+ /* AC power was plugged in (previous state was "disconnected"),
+ * set plug_ac_countdown for amount of ticks left
+ */
+ plug_ac_countdown = LED_TOTAL_TICKS;
+}
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_AMBER] = 100;
- brightness_range[EC_LED_COLOR_WHITE] = 100;
+ if (led_id == EC_LED_ID_BATTERY_LED) {
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
+ } else if (led_id == EC_LED_ID_POWER_LED) {
+ brightness_range[EC_LED_COLOR_RED] = 1;
+ }
}
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
{
- enum pwm_led_id pwm_id;
+ if (led_id == EC_LED_ID_BATTERY_LED) {
+ if (brightness[EC_LED_COLOR_AMBER] != 0)
+ led_set_color_battery(EC_LED_COLOR_AMBER);
+ else if (brightness[EC_LED_COLOR_WHITE] != 0)
+ led_set_color_battery(EC_LED_COLOR_WHITE);
+ else
+ led_set_color_battery(LED_OFF);
+ } else if (led_id == EC_LED_ID_POWER_LED) {
+ if (brightness[EC_LED_COLOR_RED] != 0)
+ led_set_color_power(LED_ON);
+ else
+ led_set_color_power(LED_OFF);
+ }
- /* Convert ec_led_id to pwm_led_id. */
- switch (led_id) {
- case EC_LED_ID_LEFT_LED:
- pwm_id = PWM_LED0;
- break;
- case EC_LED_ID_RIGHT_LED:
- pwm_id = PWM_LED1;
- break;
- default:
- return EC_ERROR_UNKNOWN;
+ return EC_SUCCESS;
+}
+
+/* Called by hook task every 200 ms */
+static void led_tick(void)
+{
+ task_set_event(TASK_ID_LOGOLED, LED_EVENT_200MS_TICK);
+}
+DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
+
+static void suspend_led_update(void)
+{
+ while (1) {
+ tick++;
+ if (chipset_in_state(CHIPSET_STATE_ON))
+ break;
+
+ /* 1s gradual on, 1s gradual off, 3s off */
+ if (tick <= TICKS_STEP2_DIMMER) {
+ /* increase 5 duty every 50ms until PWM=100 */
+ /* enter here 20 times, total duartion is 1sec */
+ pwm_set_duty(PWM_CH_TKP_A_LED_N,
+ tick * LED_BAT_S3_PWM_RESCALE);
+ msleep(LED_BAT_S3_TICK_MS);
+ } else if (tick <= TICKS_STEP3_OFF) {
+ /* decrease 5 duty every 50ms until PWM=0 */
+ /* enter here 20 times, total duartion is 1sec */
+ pwm_set_duty(PWM_CH_TKP_A_LED_N, (TICKS_STEP3_OFF
+ - tick) * LED_BAT_S3_PWM_RESCALE);
+ msleep(LED_BAT_S3_TICK_MS);
+ } else {
+ tick = TICKS_STEP1_BRIGHTER;
+ msleep(LED_BAT_S3_OFF_TIME_MS);
+ }
}
+}
- 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);
+static void suspend_led_init(void)
+{
+ task_set_event(TASK_ID_LOGOLED, LED_EVENT_SUSPEND);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, suspend_led_init, HOOK_PRIO_DEFAULT);
- return EC_SUCCESS;
+void logoled_task(void *u)
+{
+ uint32_t evt;
+
+ while (1) {
+ evt = task_wait_event(-1);
+
+ if (evt & LED_EVENT_SUSPEND) {
+ tick = TICKS_STEP2_DIMMER;
+ suspend_led_update();
+ }
+
+ if (evt & LED_EVENT_200MS_TICK) {
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ led_set_power();
+ if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
+ led_set_battery();
+ }
+ }
}
diff --git a/board/primus/pwm.c b/board/primus/pwm.c
index 767c380979..a946071159 100644
--- a/board/primus/pwm.c
+++ b/board/primus/pwm.c
@@ -10,7 +10,7 @@
#include "pwm_chip.h"
const struct pwm_t pwm_channels[] = {
- [PWM_CH_LED2] = {
+ [PWM_CH_LED2_WHITE] = {
.channel = 0,
.flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
.freq = 4800,
@@ -20,7 +20,7 @@ const struct pwm_t pwm_channels[] = {
.flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
.freq = 4800,
},
- [PWM_CH_LED1] = {
+ [PWM_CH_LED1_AMBER] = {
.channel = 2,
.flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
.freq = 4800,
@@ -52,16 +52,16 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
static void board_pwm_init(void)
{
/*
- * Turn on all the LED at 50%.
+ * Turn on LOGO led and turn off battery/power led
*/
- pwm_enable(PWM_CH_LED1, 1);
- pwm_set_duty(PWM_CH_LED1, 50);
- pwm_enable(PWM_CH_LED2, 1);
- pwm_set_duty(PWM_CH_LED2, 50);
+ pwm_enable(PWM_CH_LED1_AMBER, 1);
+ pwm_set_duty(PWM_CH_LED1_AMBER, 0);
+ pwm_enable(PWM_CH_LED2_WHITE, 1);
+ pwm_set_duty(PWM_CH_LED2_WHITE, 0);
pwm_enable(PWM_CH_TKP_A_LED_N, 1);
- pwm_set_duty(PWM_CH_TKP_A_LED_N, 50);
+ pwm_set_duty(PWM_CH_TKP_A_LED_N, 100);
pwm_enable(PWM_CH_LED4, 1);
- pwm_set_duty(PWM_CH_LED4, 50);
+ pwm_set_duty(PWM_CH_LED4, 0);
pwm_enable(PWM_CH_KBLIGHT, 1);
/* TODO(b/190518315)
diff --git a/board/primus/sensors.c b/board/primus/sensors.c
index c96e32dee0..50fe62c198 100644
--- a/board/primus/sensors.c
+++ b/board/primus/sensors.c
@@ -59,7 +59,7 @@ const struct temp_sensor_t temp_sensors[] = {
.idx = ADC_TEMP_SENSOR_1_DDR_SOC
},
[TEMP_SENSOR_2_SSD] = {
- .name = "Charger",
+ .name = "SSD",
.type = TEMP_SENSOR_TYPE_BOARD,
.read = get_temp_3v3_30k9_47k_4050b,
.idx = ADC_TEMP_SENSOR_2_SSD
@@ -71,13 +71,13 @@ const struct temp_sensor_t temp_sensors[] = {
.idx = ADC_TEMP_SENSOR_3_CHARGER
},
[TEMP_SENSOR_4_MEMORY] = {
- .name = "Charger",
+ .name = "MEMORY",
.type = TEMP_SENSOR_TYPE_BOARD,
.read = get_temp_3v3_30k9_47k_4050b,
.idx = ADC_TEMP_SENSOR_4_MEMORY
},
[TEMP_SENSOR_5_USBC] = {
- .name = "Charger",
+ .name = "USBC",
.type = TEMP_SENSOR_TYPE_BOARD,
.read = get_temp_3v3_30k9_47k_4050b,
.idx = ADC_TEMP_SENSOR_5_USBC
diff --git a/board/redrix/keyboard.c b/board/redrix/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/redrix/keyboard.c
+++ b/board/redrix/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/redrix/usbc_config.c b/board/redrix/usbc_config.c
index 768e6b88cd..906147a696 100644
--- a/board/redrix/usbc_config.c
+++ b/board/redrix/usbc_config.c
@@ -182,25 +182,23 @@ __override int bb_retimer_power_enable(const struct usb_mux *me, bool enable)
void board_reset_pd_mcu(void)
{
- /*
- * TODO(b/193461268): figure out correct timing
- */
-
gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 0);
gpio_set_level(GPIO_USB_C1_TCPC_RST_ODL, 0);
/*
* delay for power-on to reset-off and min. assertion time
*/
-
- msleep(20);
+ msleep(NCT38XX_RESET_HOLD_DELAY_MS);
gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 1);
gpio_set_level(GPIO_USB_C1_TCPC_RST_ODL, 1);
- /* wait for chips to come up */
+ nct38xx_reset_notify(USBC_PORT_C0);
+ nct38xx_reset_notify(USBC_PORT_C1);
- msleep(50);
+ /* wait for chips to come up */
+ if (NCT38XX_RESET_POST_DELAY_MS != 0)
+ msleep(NCT38XX_RESET_POST_DELAY_MS);
}
static void board_tcpc_init(void)
diff --git a/board/reef/board.c b/board/reef/board.c
index de0e093860..26f5b8dceb 100644
--- a/board/reef/board.c
+++ b/board/reef/board.c
@@ -445,7 +445,8 @@ void chipset_pre_init_callback(void)
static void board_set_tablet_mode(void)
{
- tablet_set_mode(!gpio_get_level(GPIO_TABLET_MODE_L));
+ tablet_set_mode(!gpio_get_level(GPIO_TABLET_MODE_L),
+ TABLET_TRIGGER_LID);
}
/* Initialize board. */
@@ -913,7 +914,7 @@ int board_get_version(void)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/reef/board.h b/board/reef/board.h
index 3afcc77907..cc599ce1ba 100644
--- a/board/reef/board.h
+++ b/board/reef/board.h
@@ -120,7 +120,7 @@
#define CONFIG_HOSTCMD_FLASH_SPI_INFO
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/board/reef_it8320/board.c b/board/reef_it8320/board.c
index cdcd88b910..83106698f0 100644
--- a/board/reef_it8320/board.c
+++ b/board/reef_it8320/board.c
@@ -208,7 +208,7 @@ static void board_set_tablet_mode(void)
* Always report device isn't in tablet mode because
* our id is clamshell and no TABLET_MODE_L pin
*/
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
}
/* Initialize board. */
@@ -472,7 +472,7 @@ int board_get_version(void)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/reef_it8320/board.h b/board/reef_it8320/board.h
index 20d18ae3bf..510aff4792 100644
--- a/board/reef_it8320/board.h
+++ b/board/reef_it8320/board.h
@@ -116,7 +116,7 @@
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
#define CONFIG_IT83XX_VCC_3P3V
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_LED_COMMON
diff --git a/board/reef_mchp/board.c b/board/reef_mchp/board.c
index b308b10b65..d5212ca931 100644
--- a/board/reef_mchp/board.c
+++ b/board/reef_mchp/board.c
@@ -639,7 +639,8 @@ void chipset_pre_init_callback(void)
static void board_set_tablet_mode(void)
{
- tablet_set_mode(!gpio_get_level(GPIO_TABLET_MODE_L));
+ tablet_set_mode(!gpio_get_level(GPIO_TABLET_MODE_L),
+ TABLET_TRIGGER_LID);
}
/* Initialize board. */
@@ -1153,7 +1154,7 @@ int board_get_version(void)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/reef_mchp/board.h b/board/reef_mchp/board.h
index b12c4e5d71..c9b2704530 100644
--- a/board/reef_mchp/board.h
+++ b/board/reef_mchp/board.h
@@ -122,7 +122,7 @@
#define CONFIG_HOSTCMD_FLASH_SPI_INFO
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2
diff --git a/board/samus/board.c b/board/samus/board.c
index 211d000e86..0a25107960 100644
--- a/board/samus/board.c
+++ b/board/samus/board.c
@@ -223,7 +223,7 @@ struct ec_thermal_config thermal_params[] = {
};
BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
.output_settle_us = 40,
.debounce_down_us = 6 * MSEC,
.debounce_up_us = 30 * MSEC,
diff --git a/board/samus/board.h b/board/samus/board.h
index dc72ea9944..ed79e9876f 100644
--- a/board/samus/board.h
+++ b/board/samus/board.h
@@ -30,7 +30,7 @@
#define CONFIG_CHIPSET_CAN_THROTTLE
#define CONFIG_I2C
#define CONFIG_I2C_CONTROLLER
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_SCANCODE_CALLBACK
diff --git a/board/shuboz/board.c b/board/shuboz/board.c
index e14c69b893..114bae6ac8 100644
--- a/board/shuboz/board.c
+++ b/board/shuboz/board.c
@@ -585,7 +585,7 @@ static void setup_fw_config(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/stern/board.c b/board/stern/board.c
index 5963d53ab4..7b92262c93 100644
--- a/board/stern/board.c
+++ b/board/stern/board.c
@@ -88,7 +88,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/board/taeko/keyboard.c b/board/taeko/keyboard.c
index b2f1c9f10c..a9f033130d 100644
--- a/board/taeko/keyboard.c
+++ b/board/taeko/keyboard.c
@@ -9,7 +9,7 @@
#include "timer.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/terrador/board.c b/board/terrador/board.c
index 7fc4694048..e13b376c3f 100644
--- a/board/terrador/board.c
+++ b/board/terrador/board.c
@@ -47,7 +47,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/todor/board.c b/board/todor/board.c
index 466aa58b68..06c030dea6 100644
--- a/board/todor/board.c
+++ b/board/todor/board.c
@@ -47,7 +47,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/treeya/board.c b/board/treeya/board.c
index 504d171c33..4583d89d7c 100644
--- a/board/treeya/board.c
+++ b/board/treeya/board.c
@@ -172,7 +172,7 @@ void board_update_sensor_config_from_sku(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L,
GPIO_INPUT | GPIO_PULL_DOWN);
diff --git a/board/trogdor/board.c b/board/trogdor/board.c
index 0d7eccdc57..a9b72a560d 100644
--- a/board/trogdor/board.c
+++ b/board/trogdor/board.c
@@ -32,7 +32,7 @@
#include "gpio_list.h"
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/* Use 80 us, because KSO_02 passes through the H1. */
.output_settle_us = 80,
/*
diff --git a/board/trogdor/board.h b/board/trogdor/board.h
index 16bc508b2d..346b135ea4 100644
--- a/board/trogdor/board.h
+++ b/board/trogdor/board.h
@@ -23,7 +23,7 @@
/* Keyboard */
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_PWM_KBLIGHT
/* Battery */
diff --git a/board/trondo/board.c b/board/trondo/board.c
index 6a4ba84c51..d6e68b35a7 100644
--- a/board/trondo/board.c
+++ b/board/trondo/board.c
@@ -48,7 +48,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/vilboz/board.c b/board/vilboz/board.c
index ef0135d374..8351834b78 100644
--- a/board/vilboz/board.c
+++ b/board/vilboz/board.c
@@ -409,7 +409,7 @@ static void setup_fw_config(void)
} else {
motion_sensor_count = 0;
/* Device is clamshell only */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Gyro is not present, don't allow line to float */
gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
}
diff --git a/board/voema/board.c b/board/voema/board.c
index 876f8c9ef7..91dd9f144a 100644
--- a/board/voema/board.c
+++ b/board/voema/board.c
@@ -45,7 +45,7 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/voema/board.h b/board/voema/board.h
index 86f5a61bdc..c0bee73682 100644
--- a/board/voema/board.h
+++ b/board/voema/board.h
@@ -191,9 +191,6 @@ void board_reset_pd_mcu(void);
void motion_interrupt(enum gpio_signal signal);
#endif
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/volet/board.c b/board/volet/board.c
index 716c4c5481..603536fd68 100644
--- a/board/volet/board.c
+++ b/board/volet/board.c
@@ -90,7 +90,7 @@ __override const struct ec_response_keybd_config
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/volet/board.h b/board/volet/board.h
index bf755f5212..09e30337c1 100644
--- a/board/volet/board.h
+++ b/board/volet/board.h
@@ -195,9 +195,6 @@ void board_reset_pd_mcu(void);
void motion_interrupt(enum gpio_signal signal);
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/volteer/board.c b/board/volteer/board.c
index a47bee1747..1112b4b4f3 100644
--- a/board/volteer/board.c
+++ b/board/volteer/board.c
@@ -20,6 +20,7 @@
#include "fan_chip.h"
#include "gpio.h"
#include "hooks.h"
+#include "keyboard_scan.h"
#include "lid_switch.h"
#include "power.h"
#include "power_button.h"
@@ -30,6 +31,7 @@
#include "task.h"
#include "tablet_mode.h"
#include "throttle_ap.h"
+#include "timer.h"
#include "uart.h"
#include "usb_pd.h"
#include "usb_pd_tbt.h"
@@ -41,6 +43,23 @@
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
/******************************************************************************/
+/* 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 = {
+ 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,
+ 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
+ },
+};
+
+/******************************************************************************/
/* Physical fans. These are logically separate from pwm_channels. */
const struct fan_conf fan_conf_0 = {
diff --git a/board/volteer/build.mk b/board/volteer/build.mk
index abd41ab0a4..5adcffff56 100644
--- a/board/volteer/build.mk
+++ b/board/volteer/build.mk
@@ -21,6 +21,5 @@ board-y=board.o
board-y+=battery.o
board-y+=cbi.o
board-y+=led.o
-board-y+=keyboard.o
board-y+=sensors.o
board-y+=usbc_config.o
diff --git a/board/volteer/keyboard.c b/board/volteer/keyboard.c
deleted file mode 100644
index aeed7d7c63..0000000000
--- a/board/volteer/keyboard.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Keyboard config common to ECOS and zephyr */
-
-#include "keyboard_raw.h"
-#include "keyboard_scan.h"
-#include "timer.h"
-
-/* Keyboard scan setting */
-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 = {
- 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,
- 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
- },
-};
diff --git a/board/voxel/board.c b/board/voxel/board.c
index b5715969b4..2c7f7feac5 100644
--- a/board/voxel/board.c
+++ b/board/voxel/board.c
@@ -91,7 +91,7 @@ const struct ec_response_keybd_config *board_vivaldi_keybd_config(void)
}
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__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. */
diff --git a/board/voxel/board.h b/board/voxel/board.h
index 54369a9ac8..b02716088e 100644
--- a/board/voxel/board.h
+++ b/board/voxel/board.h
@@ -195,9 +195,6 @@ void board_reset_pd_mcu(void);
void motion_interrupt(enum gpio_signal signal);
-extern const int keyboard_factory_scan_pins[][2];
-extern const int keyboard_factory_scan_pins_used;
-
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/waddledoo2/board.c b/board/waddledoo2/board.c
index c0e5e9013e..6cd66a2b97 100644
--- a/board/waddledoo2/board.c
+++ b/board/waddledoo2/board.c
@@ -72,7 +72,7 @@ const int usb_port_enable[USB_PORT_COUNT] = {
};
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* F3 key scan cycle completed but scan input is not
* charging to logic high when EC start scan next
diff --git a/board/waddledoo2/board.h b/board/waddledoo2/board.h
index c4ded0559e..aefad9b213 100644
--- a/board/waddledoo2/board.h
+++ b/board/waddledoo2/board.h
@@ -35,7 +35,7 @@
#define GPIO_USB_C1_INT_ODL GPIO_SUB_USB_C1_INT_ODL
/* Keyboard */
-#define CONFIG_KEYBOARD_BOARD_CONFIG
+
#define CONFIG_KEYBOARD_KEYPAD
#define CONFIG_PWM_KBLIGHT
diff --git a/board/willow/board.c b/board/willow/board.c
index fbdc4e10bd..6d036a1526 100644
--- a/board/willow/board.c
+++ b/board/willow/board.c
@@ -85,7 +85,7 @@ const struct power_signal_info power_signal_list[] = {
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
/* Keyboard scan setting */
-struct keyboard_scan_config keyscan_config = {
+__override struct keyboard_scan_config keyscan_config = {
/*
* TODO(b/133200075): Tune this once we have the final performance
* out of the driver and the i2c bus.
diff --git a/chip/mt_scp/mt8192/intc.h b/chip/mt_scp/mt8192/intc.h
index b2035a9025..63eb1243b3 100644
--- a/chip/mt_scp/mt8192/intc.h
+++ b/chip/mt_scp/mt8192/intc.h
@@ -7,6 +7,9 @@
#define __CROS_EC_INTC_H
/* INTC */
+#define SCP_INTC_IRQ_POL0 0xef001f20
+#define SCP_INTC_IRQ_POL1 0x0800001d
+#define SCP_INTC_IRQ_POL2 0x00000020
#define SCP_INTC_GRP_LEN 3
#define SCP_INTC_IRQ_COUNT 96
diff --git a/chip/mt_scp/mt8195/intc.h b/chip/mt_scp/mt8195/intc.h
index f098229e8c..87181c46ca 100644
--- a/chip/mt_scp/mt8195/intc.h
+++ b/chip/mt_scp/mt8195/intc.h
@@ -7,6 +7,9 @@
#define __CROS_EC_INTC_H
/* INTC */
+#define SCP_INTC_IRQ_POL0 0xef001f20
+#define SCP_INTC_IRQ_POL1 0x044001dd
+#define SCP_INTC_IRQ_POL2 0xffffdfe0
#define SCP_INTC_IRQ_POL3 0xfffffff3
#define SCP_INTC_GRP_LEN 4
#define SCP_INTC_IRQ_COUNT 127
diff --git a/chip/mt_scp/rv32i_common/intc.c b/chip/mt_scp/rv32i_common/intc.c
index 9555dbf2f2..7e6b39e1f2 100644
--- a/chip/mt_scp/rv32i_common/intc.c
+++ b/chip/mt_scp/rv32i_common/intc.c
@@ -201,12 +201,12 @@ static struct {
[SCP_IRQ_GCE] = { INTC_GRP_0 },
[SCP_IRQ_MDP_GCE] = { INTC_GRP_0 },
/* 36 */
- [SCP_IRQ_VDEC] = { INTC_GRP_0 },
+ [SCP_IRQ_VDEC] = { INTC_GRP_8 },
[SCP_IRQ_WDT] = { INTC_GRP_0 },
- [SCP_IRQ_VDEC_LAT] = { INTC_GRP_0 },
- [SCP_IRQ_VDEC1] = { INTC_GRP_0 },
+ [SCP_IRQ_VDEC_LAT] = { INTC_GRP_8 },
+ [SCP_IRQ_VDEC1] = { INTC_GRP_8 },
/* 40 */
- [SCP_IRQ_VDEC1_LAT] = { INTC_GRP_0 },
+ [SCP_IRQ_VDEC1_LAT] = { INTC_GRP_8 },
[SCP_IRQ_INFRA] = { INTC_GRP_0 },
[SCP_IRQ_CLK_CTRL_CORE] = { INTC_GRP_0 },
[SCP_IRQ_CLK_CTRL2_CORE] = { INTC_GRP_0 },
@@ -228,7 +228,7 @@ static struct {
/* 56 */
[SCP_IRQ_I3C0_IBI_WAKE] = { INTC_GRP_0 },
[SCP_IRQ_I3C1_IBI_WAKE] = { INTC_GRP_0 },
- [SCP_IRQ_VENC] = { INTC_GRP_0 },
+ [SCP_IRQ_VENC] = { INTC_GRP_8 },
[SCP_IRQ_APU_ENGINE] = { INTC_GRP_0 },
/* 60 */
[SCP_IRQ_MBOX0] = { INTC_GRP_0 },
@@ -264,7 +264,7 @@ static struct {
[SCP_IRQ_JPEGENC] = { INTC_GRP_0 },
[SCP_IRQ_JPEGDEC] = { INTC_GRP_0 },
[SCP_IRQ_JPEGDEC_C2] = { INTC_GRP_0 },
- [SCP_IRQ_VENC_C1] = { INTC_GRP_0 },
+ [SCP_IRQ_VENC_C1] = { INTC_GRP_8 },
/* 88 */
[SCP_IRQ_JPEGENC_C1] = { INTC_GRP_0 },
[SCP_IRQ_JPEGDEC_C1] = { INTC_GRP_0 },
diff --git a/chip/mt_scp/rv32i_common/registers.h b/chip/mt_scp/rv32i_common/registers.h
index 82450be169..adbef5f98b 100644
--- a/chip/mt_scp/rv32i_common/registers.h
+++ b/chip/mt_scp/rv32i_common/registers.h
@@ -142,9 +142,6 @@
#define SCP_CORE0_WDT_CUR_VAL REG32(SCP_REG_BASE + 0x3003C)
/* INTC */
-#define SCP_INTC_IRQ_POL0 0xef001f20
-#define SCP_INTC_IRQ_POL1 0x0800001d
-#define SCP_INTC_IRQ_POL2 0x00000020
#define SCP_INTC_WORD(irq) ((irq) >> 5) /* word length = 2^5 */
#define SCP_INTC_BIT(irq) ((irq) & 0x1F) /* bit shift =LSB[0:4] */
#define SCP_INTC_GRP_COUNT 15
diff --git a/chip/npcx/config_chip-npcx5.h b/chip/npcx/config_chip-npcx5.h
index 331b5e5474..434caba1d8 100644
--- a/chip/npcx/config_chip-npcx5.h
+++ b/chip/npcx/config_chip-npcx5.h
@@ -26,6 +26,12 @@
#define UART_MODULE_COUNT 1
/*
+ * For NPCX5, PS2_3 pins also support other alternate functions (e.g., TA2).
+ * PS2_3 should be Explicit defined.
+ */
+#undef NPCX_PS2_MODULE_3
+
+/*
* Number of I2C controllers. Controller 0 has 2 ports, so the chip has one
* additional port.
*/
diff --git a/chip/npcx/config_chip-npcx7.h b/chip/npcx/config_chip-npcx7.h
index 5919f69af8..434c3a7889 100644
--- a/chip/npcx/config_chip-npcx7.h
+++ b/chip/npcx/config_chip-npcx7.h
@@ -43,6 +43,13 @@
#define NPCX_SECOND_UART
#define UART_MODULE_COUNT 2
+/*
+ * For NPCX7, PS2_2 & PS2_3 pins also support other alternate functions
+ * (e.g., ADC5, ADC6, TA2). PS2_2 & PS2_3 should be Explicit defined.
+ */
+#undef NPCX_PS2_MODULE_2
+#undef NPCX_PS2_MODULE_3
+
/* 64-bit timer support */
#define NPCX_ITIM64_SUPPORT
#else
diff --git a/chip/npcx/config_chip-npcx9.h b/chip/npcx/config_chip-npcx9.h
index da17cc76ae..0248c40f86 100644
--- a/chip/npcx/config_chip-npcx9.h
+++ b/chip/npcx/config_chip-npcx9.h
@@ -33,6 +33,13 @@
#define UART_MODULE_COUNT 2
/*
+ * For NPCX9, PS2_2 & PS2_3 pins also support other alternate functions
+ * (e.g., ADC5, ADC6, TA2). PS2_2 & PS2_3 should be Explicit defined.
+ */
+#undef NPCX_PS2_MODULE_2
+#undef NPCX_PS2_MODULE_3
+
+/*
* Number of I2C controllers. Controller 5/6 has 2 ports, so the chip has
* two additional ports.
*/
diff --git a/chip/npcx/gpio_chip-npcx5.h b/chip/npcx/gpio_chip-npcx5.h
index ee113aea44..83916a421b 100644
--- a/chip/npcx/gpio_chip-npcx5.h
+++ b/chip/npcx/gpio_chip-npcx5.h
@@ -206,7 +206,7 @@
/* MFT Module */
#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */
#else
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */
@@ -255,7 +255,11 @@
#define NPCX_ALT_GPIO_6_3 ALT(6, 3, NPCX_ALT(3, PS2_1_SL)) /* PS2_DATA1 */
#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */
#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */
+#else
+#define NPCX_ALT_GPIO_A_7
+#endif
#define NPCX_ALT_TABLE { \
NPCX_ALT_GPIO_0_3 /* KSO16 */ \
diff --git a/chip/npcx/gpio_chip-npcx7.h b/chip/npcx/gpio_chip-npcx7.h
index 2f6337d896..7f815e6d30 100644
--- a/chip/npcx/gpio_chip-npcx7.h
+++ b/chip/npcx/gpio_chip-npcx7.h
@@ -230,7 +230,7 @@
#define NPCX_ALT_GPIO_4_3 ALT(4, 3, NPCX_ALT(6, ADC2_SL)) /* ADC2 */
#define NPCX_ALT_GPIO_4_2 ALT(4, 2, NPCX_ALT(6, ADC3_SL)) /* ADC3 */
#define NPCX_ALT_GPIO_4_1 ALT(4, 1, NPCX_ALT(6, ADC4_SL)) /* ADC4 */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_2)
#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */
#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */
#else
@@ -264,7 +264,7 @@
#define NPCX_ALT_GPIO_4_0 ALT(4, 0, NPCX_ALT(3, TA1_SL1)) /* TA1_SEL1 */
#define NPCX_ALT_GPIO_7_3 ALT(7, 3, NPCX_ALT(3, TA2_SL1)) /* TA2_SEL1 */
#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */
#else
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */
@@ -346,7 +346,7 @@
#define NPCX_ALT_GPIO_A_3 ALT(A, 3, NPCX_ALT(0, SPIP_SL)) /* SPIP_MOSI */
#define NPCX_ALT_GPIO_A_1 ALT(A, 1, NPCX_ALT(0, SPIP_SL)) /* SPIP_SCLK */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */
#else
#define NPCX_ALT_GPIO_A_7
diff --git a/chip/npcx/gpio_chip-npcx9.h b/chip/npcx/gpio_chip-npcx9.h
index f07618317c..005a03d83e 100644
--- a/chip/npcx/gpio_chip-npcx9.h
+++ b/chip/npcx/gpio_chip-npcx9.h
@@ -212,7 +212,7 @@
#define NPCX_ALT_GPIO_4_3 ALT(4, 3, NPCX_ALT(6, ADC2_SL)) /* ADC2 */
#define NPCX_ALT_GPIO_4_2 ALT(4, 2, NPCX_ALT(6, ADC3_SL)) /* ADC3 */
#define NPCX_ALT_GPIO_4_1 ALT(4, 1, NPCX_ALT(6, ADC4_SL)) /* ADC4 */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_2)
#define NPCX_ALT_GPIO_3_7 ALT(3, 7, NPCX_ALT(3, PS2_2_SL)) /* PS2_CLK2 */
#define NPCX_ALT_GPIO_3_4 ALT(3, 4, NPCX_ALT(3, PS2_2_SL)) /* PS2_DATA2 */
#else
@@ -230,7 +230,11 @@
#define NPCX_ALT_GPIO_7_0 ALT(7, 0, NPCX_ALT(3, PS2_0_SL)) /* PS2_DATA0 */
#define NPCX_ALT_GPIO_6_2 ALT(6, 2, NPCX_ALT(3, PS2_1_SL)) /* PS2_CLK1 */
#define NPCX_ALT_GPIO_6_3 ALT(6, 3, NPCX_ALT(3, PS2_1_SL)) /* PS2_DATA1 */
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_7 ALT(A, 7, NPCX_ALT(C, PS2_3_SL2)) /* PS2_DAT3 */
+#else
+#define NPCX_ALT_GPIO_A_7
+#endif
/* UART Module */
#define NPCX_ALT_GPIO_6_4 ALT(6, 4, NPCX_ALT(J, CR_SIN1_SL2)) /* CR_SIN1_SL2 */
@@ -253,7 +257,7 @@
#define NPCX_ALT_GPIO_4_0 ALT(4, 0, NPCX_ALT(3, TA1_SL1)) /* TA1_SEL1 */
#define NPCX_ALT_GPIO_7_3 ALT(7, 3, NPCX_ALT(3, TA2_SL1)) /* TA2_SEL1 */
#define NPCX_ALT_GPIO_9_3 ALT(9, 3, NPCX_ALT(C, TA1_SL2)) /* TA1_SEL2 */
-#ifdef CONFIG_PS2
+#if defined(CONFIG_PS2) && defined(NPCX_PS2_MODULE_3)
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, PS2_3_SL2)) /* PS2_CLK3 */
#else
#define NPCX_ALT_GPIO_A_6 ALT(A, 6, NPCX_ALT(C, TA2_SL2)) /* TA2_SEL2 */
diff --git a/common/i2c_controller.c b/common/i2c_controller.c
index 10ea4081cd..0596ddc422 100644
--- a/common/i2c_controller.c
+++ b/common/i2c_controller.c
@@ -83,6 +83,16 @@ static int i2c_port_is_locked(int port)
if (port < 0)
return 0;
+ if (IS_ENABLED(CONFIG_ZEPHYR)) {
+ /*
+ * For Zephyr: to convert an i2c port enum value to a port
+ * number in mutex_lock(), this number should be soc's i2c port
+ * where the i2 device is connected to.
+ */
+ if (i2c_get_physical_port(port) >= 0)
+ port = i2c_get_physical_port(port);
+ }
+
return (i2c_port_active_list >> port) & 1;
}
@@ -287,6 +297,16 @@ void i2c_lock(int port, int lock)
if (port < 0 || port >= ARRAY_SIZE(port_mutex))
return;
+ if (IS_ENABLED(CONFIG_ZEPHYR)) {
+ /*
+ * For Zephyr: to convert an i2c port enum value to a port
+ * number in mutex_lock(), this number should be soc's i2c port
+ * where the i2 device is connected to.
+ */
+ if (i2c_get_physical_port(port) >= 0)
+ port = i2c_get_physical_port(port);
+ }
+
if (lock) {
uint32_t irq_lock_key;
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c
index 3349566b55..a1e17bc61d 100644
--- a/common/keyboard_scan.c
+++ b/common/keyboard_scan.c
@@ -53,9 +53,7 @@
#define CONFIG_KEYBOARD_POST_SCAN_CLOCKS 16000
#endif
-#ifndef CONFIG_KEYBOARD_BOARD_CONFIG
-/* Use default keyboard scan config, because board didn't supply one */
-struct keyboard_scan_config keyscan_config = {
+__overridable struct keyboard_scan_config keyscan_config = {
#ifdef CONFIG_KEYBOARD_COL2_INVERTED
/*
* CONFIG_KEYBOARD_COL2_INVERTED is defined for passing the column 2
@@ -78,7 +76,6 @@ struct keyboard_scan_config keyscan_config = {
0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
},
};
-#endif
/* Boot key list. Must be in same order as enum boot_key. */
struct boot_key_entry {
@@ -499,6 +496,16 @@ static int has_ghosting(const uint8_t *state)
return 0;
}
+/* Inform keyboard module if scanning is enabled */
+static void key_state_changed(int row, int col, uint8_t state)
+{
+ if (!keyboard_scan_is_enabled())
+ return;
+
+ /* No-op for protocols that require full keyboard matrix (e.g. MKBP). */
+ keyboard_state_changed(row, col, !!(state & BIT(row)));
+}
+
/**
* Update keyboard state using low-level interface to read keyboard.
*
@@ -528,7 +535,7 @@ static int check_keys_changed(uint8_t *state)
/* Check for changes between previous scan and this one */
for (c = 0; c < keyboard_cols; c++) {
- int diff;
+ int diff = new_state[c] ^ state[c];
/* Clear debouncing flag, if sufficient time has elapsed. */
for (i = 0; i < KEYBOARD_ROWS && debouncing[c]; i++) {
@@ -539,6 +546,20 @@ static int check_keys_changed(uint8_t *state)
keyscan_config.debounce_up_us))
continue; /* Not done debouncing */
debouncing[c] &= ~BIT(i);
+
+ if (!IS_ENABLED(CONFIG_KEYBOARD_STRICT_DEBOUNCE))
+ continue;
+ if (!(diff & BIT(i)))
+ /* Debounced but no difference. */
+ continue;
+ any_change = 1;
+ key_state_changed(i, c, new_state[c]);
+ /*
+ * This makes state[c] == new_state[c] for row i.
+ * Thus, when diff is calculated below, it won't
+ * be asserted (for row i).
+ */
+ state[c] ^= diff & BIT(i);
}
/* Recognize change in state, unless debounce in effect. */
@@ -549,15 +570,10 @@ static int check_keys_changed(uint8_t *state)
if (!(diff & BIT(i)))
continue;
scan_edge_index[c][i] = scan_time_index;
- any_change = 1;
- /* Inform keyboard module if scanning is enabled */
- if (keyboard_scan_is_enabled()) {
- /* This is no-op for protocols that require a
- * full keyboard matrix (e.g., MKBP).
- */
- keyboard_state_changed(
- i, c, !!(new_state[c] & BIT(i)));
+ if (!IS_ENABLED(CONFIG_KEYBOARD_STRICT_DEBOUNCE)) {
+ any_change = 1;
+ key_state_changed(i, c, new_state[c]);
}
}
@@ -568,7 +584,8 @@ static int check_keys_changed(uint8_t *state)
* (up or down), the state bits are only updated if the
* edge was not suppressed due to debouncing.
*/
- state[c] ^= diff;
+ if (!IS_ENABLED(CONFIG_KEYBOARD_STRICT_DEBOUNCE))
+ state[c] ^= diff;
}
if (any_change) {
@@ -726,6 +743,15 @@ const uint8_t *keyboard_scan_get_state(void)
void keyboard_scan_init(void)
{
+ if (IS_ENABLED(CONFIG_KEYBOARD_STRICT_DEBOUNCE) &&
+ keyscan_config.debounce_down_us != keyscan_config.debounce_up_us) {
+ /*
+ * Strict debouncer is prone to keypress reordering if debounce
+ * durations for down and up are not equal. crbug.com/547131
+ */
+ CPRINTS("KB WARN: Debounce durations not equal");
+ }
+
/* Configure refresh key matrix */
keyboard_mask_refresh = KEYBOARD_ROW_TO_MASK(
board_keyboard_row_refresh());
diff --git a/common/motion_lid.c b/common/motion_lid.c
index 1d84c17eff..eb0297aefa 100644
--- a/common/motion_lid.c
+++ b/common/motion_lid.c
@@ -176,7 +176,7 @@ static void motion_lid_set_tablet_mode(int reliable)
/* Alright, we're convinced. */
tablet_mode_debounce_cnt =
TABLET_MODE_DEBOUNCE_COUNT;
- tablet_set_mode(new_mode);
+ tablet_set_mode(new_mode, TABLET_TRIGGER_LID);
return;
}
tablet_mode_debounce_cnt--;
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 92690d7aea..114f240fba 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -416,7 +416,7 @@ static void motion_sense_switch_sensor_rate(void)
(ret != EC_SUCCESS) &&
(i == CONFIG_LID_ANGLE_SENSOR_BASE ||
i == CONFIG_LID_ANGLE_SENSOR_LID))
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
}
} else {
/* The sensors are being powered off */
diff --git a/common/tablet_mode.c b/common/tablet_mode.c
index 68d90ae772..3a5616ec3f 100644
--- a/common/tablet_mode.c
+++ b/common/tablet_mode.c
@@ -17,10 +17,10 @@
#define CPRINTF(format, args...) cprintf(CC_MOTION_LID, format, ## args)
/*
- * Other code modules assume that notebook mode (i.e. tablet_mode = false) at
+ * Other code modules assume that notebook mode (i.e. tablet_mode = 0) at
* startup
*/
-static bool tablet_mode;
+static uint32_t tablet_mode;
/*
* Console command can force the value of tablet_mode. If tablet_mode_force is
@@ -39,7 +39,7 @@ static bool disabled;
int tablet_get_mode(void)
{
- return tablet_mode;
+ return !!tablet_mode;
}
static inline void print_tablet_mode(void)
@@ -61,13 +61,21 @@ static void notify_tablet_mode_change(void)
}
-void tablet_set_mode(int mode)
+void tablet_set_mode(int mode, uint32_t trigger)
{
+ uint32_t old_mode = tablet_mode;
+
/* If tablet_mode is forced via a console command, ignore set. */
if (tablet_mode_forced)
return;
- if (tablet_mode == !!mode)
+ if (mode)
+ tablet_mode |= trigger;
+ else
+ tablet_mode &= ~trigger;
+
+ /* Boolean comparison */
+ if (!tablet_mode == !old_mode)
return;
if (disabled) {
@@ -81,14 +89,12 @@ void tablet_set_mode(int mode)
return;
}
- tablet_mode = !!mode;
-
notify_tablet_mode_change();
}
void tablet_disable(void)
{
- tablet_mode = false;
+ tablet_mode = 0;
disabled = true;
}
@@ -131,7 +137,7 @@ static void gmr_tablet_switch_interrupt_debounce(void)
*/
if (!IS_ENABLED(CONFIG_LID_ANGLE) || gmr_sensor_at_360)
- tablet_set_mode(gmr_sensor_at_360);
+ tablet_set_mode(gmr_sensor_at_360, TABLET_TRIGGER_LID);
if (IS_ENABLED(CONFIG_LID_ANGLE_UPDATE) && gmr_sensor_at_360)
lid_angle_peripheral_enable(0);
@@ -182,10 +188,10 @@ static int command_settabletmode(int argc, char **argv)
return EC_ERROR_PARAM_COUNT;
if (argv[1][0] == 'o' && argv[1][1] == 'n') {
- tablet_mode = true;
+ tablet_mode = TABLET_TRIGGER_LID;
tablet_mode_forced = true;
} else if (argv[1][0] == 'o' && argv[1][1] == 'f') {
- tablet_mode = false;
+ tablet_mode = 0;
tablet_mode_forced = true;
} else if (argv[1][0] == 'r') {
tablet_mode_forced = false;
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 0230e0bbb2..05d498f0d9 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -642,7 +642,7 @@ static struct policy_engine {
/* Last received source cap */
uint32_t src_caps[PDO_MAX_OBJECTS];
- int src_cap_cnt;
+ int src_cap_cnt; /* -1 on error retrieving source caps */
/* Last received sink cap */
uint32_t snk_caps[PDO_MAX_OBJECTS];
@@ -926,7 +926,8 @@ static void pe_set_frs_enable(int port, int enable)
int current = PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED);
/* This should only be called from the PD task */
- assert(port == TASK_ID_TO_PD_PORT(task_get_current()));
+ if (!IS_ENABLED(TEST_BUILD))
+ assert(port == TASK_ID_TO_PD_PORT(task_get_current()));
if (!IS_ENABLED(CONFIG_USB_PD_FRS) || !IS_ENABLED(CONFIG_USB_PD_REV30))
return;
@@ -1339,10 +1340,16 @@ void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data,
task_wake(PD_PORT_TO_TASK_ID(port));
}
-static void pe_handle_detach(void)
+#ifdef TEST_BUILD
+/*
+ * Allow unit tests to access this function to clear internal state data between
+ * runs
+ */
+void pe_clear_port_data(int port)
+#else
+static void pe_clear_port_data(int port)
+#endif /* TEST_BUILD */
{
- const int port = TASK_ID_TO_PD_PORT(task_get_current());
-
/*
* PD 3.0 Section 8.3.3.3.8
* Note: The HardResetCounter is reset on a power cycle or Detach.
@@ -1370,6 +1377,13 @@ static void pe_handle_detach(void)
/* Exit BIST Test mode, in case the TCPC entered it. */
tcpc_set_bist_test_mode(port, false);
}
+
+static void pe_handle_detach(void)
+{
+ const int port = TASK_ID_TO_PD_PORT(task_get_current());
+
+ pe_clear_port_data(port);
+}
DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, pe_handle_detach, HOOK_PRIO_DEFAULT);
#ifdef CONFIG_USB_PD_RESET_MIN_BATT_SOC
@@ -2512,9 +2526,11 @@ static void pe_src_transition_supply_run(int port)
/*
* Setup to get Device Policy Manager to request
* Source Capabilities, if needed, for possible
- * PR_Swap
+ * PR_Swap. Get the number directly to avoid re-probing
+ * if the partner generated an error and left -1 for the
+ * count.
*/
- if (pd_get_src_cap_cnt(port) == 0)
+ if (pe[port].src_cap_cnt == 0)
pd_dpm_request(port, DPM_REQUEST_GET_SRC_CAPS);
set_state_pe(port, PE_SRC_READY);
@@ -6902,13 +6918,23 @@ static void pe_dr_src_get_source_cap_run(int port)
CAP_DUALROLE);
set_state_pe(port, PE_SRC_READY);
- } else if (type == PD_CTRL_REJECT ||
- type == PD_CTRL_NOT_SUPPORTED) {
+ } else if ((cnt == 0) && (type == PD_CTRL_REJECT ||
+ type == PD_CTRL_NOT_SUPPORTED)) {
+ pd_set_src_caps(port, -1, NULL);
set_state_pe(port, PE_SRC_READY);
} else {
+ /*
+ * On protocol error, consider source cap
+ * retrieval a failure
+ */
+ pd_set_src_caps(port, -1, NULL);
set_state_pe(port, PE_SEND_SOFT_RESET);
}
return;
+ } else {
+ pd_set_src_caps(port, -1, NULL);
+ set_state_pe(port, PE_SEND_SOFT_RESET);
+ return;
}
}
@@ -6944,7 +6970,10 @@ void pd_set_src_caps(int port, int cnt, uint32_t *src_caps)
uint8_t pd_get_src_cap_cnt(int port)
{
- return pe[port].src_cap_cnt;
+ if (pe[port].src_cap_cnt > 0)
+ return pe[port].src_cap_cnt;
+
+ return 0;
}
/* Track access to the PD discovery structures during HC execution */
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index ea32bbe680..33172e7c74 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -14,6 +14,7 @@
#include "sha256.h"
#include "shared_mem.h"
#include "stdbool.h"
+#include "stdint.h"
#include "system.h"
#include "task.h"
#include "timer.h"
@@ -116,8 +117,9 @@ static void hash_next_chunk(size_t size)
{
#ifdef CONFIG_MAPPED_STORAGE
crec_flash_lock_mapped_storage(1);
- SHA256_update(&ctx, (const uint8_t *)(CONFIG_MAPPED_STORAGE_BASE +
- data_offset + curr_pos), size);
+ SHA256_update(&ctx, (const uint8_t *)
+ ((uintptr_t)CONFIG_MAPPED_STORAGE_BASE +
+ data_offset + curr_pos), size);
crec_flash_lock_mapped_storage(0);
#else
if (read_and_hash_chunk(data_offset + curr_pos, size) != EC_SUCCESS)
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index c2c3ea12a3..7b08be81a6 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -500,7 +500,18 @@ SECTIONS
*/
__flash_used = FLASH_USED_END - ORIGIN(EC_IMAGE_LMA_MEM_REGION);
#ifndef CONFIG_CHIP_INIT_ROM_REGION
+#if !(defined(SECTION_IS_RW) && (CONFIG_FLASH_WRITE_SIZE > 4))
__image_size = __flash_used;
+#else
+ .rw_image_size_alignment :
+ {
+ . = ORIGIN(FLASH) + __flash_used;
+ BYTE(0xFF);
+ . = ALIGN (CONFIG_FLASH_WRITE_SIZE);
+ } > FLASH = 0xFF
+
+ __image_size = __flash_used + SIZEOF(.rw_image_size_alignment);
+#endif
#endif /* CONFIG_CHIP_INIT_ROM_REGION */
#ifdef CONFIG_FLASH_CROS
diff --git a/docs/configuration/keyboard.md b/docs/configuration/keyboard.md
index c04e8eddbd..8398fefbde 100644
--- a/docs/configuration/keyboard.md
+++ b/docs/configuration/keyboard.md
@@ -42,8 +42,8 @@ macros.
## Data structures
-- `struct keyboard_scan_config keyscan_config` - This must be defined if the
- `CONFIG_KEYBOARD_BOARD_CONFIG` option is defined.
+- `struct keyboard_scan_config keyscan_config` - This can be used to customize
+ the keyboard scanner (e.g. scan frequency, debounce duration, etc.).
## Tasks
diff --git a/docs/fingerprint/fingerprint-debugging.md b/docs/fingerprint/fingerprint-debugging.md
index ed16d9e232..c77874e7bb 100644
--- a/docs/fingerprint/fingerprint-debugging.md
+++ b/docs/fingerprint/fingerprint-debugging.md
@@ -110,7 +110,9 @@ sensor runs at 1.8V. The pin is also not connected on the current designs.
```
```bash
-(outside) $ ./JLink_Linux_V684a_x86_64/JLinkRemoteServerCLExe -Port 2551 -select USB
+# JLinkRemoteServerCLExe will listen on port 19020 (among others) by default.
+# This can be overridden with the -Port argument.
+(outside) $ ./JLink_Linux_V684a_x86_64/JLinkRemoteServerCLExe -select USB
```
You should see the following:
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
index dd19cdb567..a3d59b1e55 100644
--- a/driver/charger/sm5803.c
+++ b/driver/charger/sm5803.c
@@ -177,6 +177,16 @@ static enum ec_error_list sm5803_flow2_update(int chgnum, const uint8_t mask,
return rv;
}
+static bool is_platform_id_2s(uint32_t platform_id)
+{
+ return platform_id >= 0x06 && platform_id <= 0x0D;
+}
+
+static bool is_platform_id_3s(uint32_t platform_id)
+{
+ return platform_id >= 0x0E && platform_id <= 0x16;
+}
+
int sm5803_is_vbus_present(int chgnum)
{
return charger_vbus[chgnum];
@@ -490,8 +500,14 @@ static void sm5803_init(int chgnum)
}
platform_id &= SM5803_PLATFORM_ID;
- if (platform_id >= 0x0E && platform_id <= 0x16) {
+ if (is_platform_id_3s(platform_id)) {
/* 3S Battery inits */
+ /* set 13.3V VBAT_SNSP TH GPADC THRESHOLD*/
+ rv |= meas_write8(chgnum, 0x26,
+ SM5803_VBAT_SNSP_MAXTH_3S_LEVEL);
+ /* OV_VBAT HW second level (14.1V) */
+ rv |= chg_write8(chgnum, 0x21,
+ SM5803_VBAT_PWR_MINTH_3S_LEVEL);
rv |= main_write8(chgnum, 0x30, 0xC0);
rv |= main_write8(chgnum, 0x80, 0x01);
rv |= main_write8(chgnum, 0x1A, 0x08);
@@ -529,8 +545,20 @@ static void sm5803_init(int chgnum)
rv |= chg_write8(chgnum, 0x33, 0x3C);
rv |= chg_write8(chgnum, 0x5C, 0x7A);
- } else if (platform_id >= 0x06 && platform_id <= 0x0D) {
+ } else if (is_platform_id_2s(platform_id)) {
/* 2S Battery inits */
+
+ /*
+ * Set 9V as higher threshold for VBATSNSP_MAX_TH GPADC
+ * threshold for interrupt generation.
+ */
+ rv |= meas_write8(chgnum, 0x26,
+ SM5803_VBAT_SNSP_MAXTH_2S_LEVEL);
+
+ /* Set OV_VBAT HW second level threshold as 9.4V */
+ rv |= chg_write8(chgnum, 0x21,
+ SM5803_VBAT_PWR_MINTH_2S_LEVEL);
+
rv |= main_write8(chgnum, 0x30, 0xC0);
rv |= main_write8(chgnum, 0x80, 0x01);
rv |= main_write8(chgnum, 0x1A, 0x08);
@@ -653,12 +681,20 @@ static void sm5803_init(int chgnum)
rv |= meas_write8(chgnum, SM5803_REG_TINT_LOW_TH,
SM5803_TINT_MIN_LEVEL);
+ /*
+ * Configure VBAT_SNSP high interrupt to fire after thresholds are set.
+ */
+ rv |= main_read8(chgnum, SM5803_REG_INT2_EN, &reg);
+ reg |= SM5803_INT2_VBATSNSP;
+ rv |= main_write8(chgnum, SM5803_REG_INT2_EN, reg);
+
/*
- * Configure TINT & VCHGPWR interrupts to fire after thresholds are set
+ * Configure TINT & VCHGPWR interrupts to fire after thresholds are set.
*/
- rv |= main_write8(chgnum, SM5803_REG_INT2_EN, SM5803_INT2_TINT |
- SM5803_INT2_VCHGPWR);
+ rv |= main_read8(chgnum, SM5803_REG_INT2_EN, &reg);
+ reg |= SM5803_INT2_TINT | SM5803_INT2_VCHGPWR;
+ rv |= main_write8(chgnum, SM5803_REG_INT2_EN, reg);
/*
* Configure CHG_ENABLE to only be set through I2C by setting
@@ -1082,6 +1118,77 @@ void sm5803_handle_interrupt(int chgnum)
if (int_reg & SM5803_INT2_VCHGPWR)
board_check_extpower();
+ if (int_reg & SM5803_INT2_VBATSNSP) {
+ int meas_volt;
+ uint32_t platform_id;
+
+ rv = main_read8(chgnum, SM5803_REG_PLATFORM, &platform_id);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read platform in interrupt",
+ CHARGER_NAME, chgnum);
+ return;
+ }
+ platform_id &= SM5803_PLATFORM_ID;
+ act_chg = charge_manager_get_active_charge_port();
+ rv = meas_read8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MEAS_MSB,
+ &meas_reg);
+ if (rv)
+ return;
+ meas_volt = meas_reg << 2;
+ rv = meas_read8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MEAS_LSB,
+ &meas_reg);
+ if (rv)
+ return;
+ meas_volt |= meas_reg & 0x03;
+ rv = meas_read8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MAX_TH, &meas_reg);
+ if (rv)
+ return;
+
+ if (is_platform_id_2s(platform_id)) {
+ /* 2S Battery */
+ CPRINTS("%s %d : VBAT_SNSP_HIGH_TH: %d mV ! - "
+ "VBAT %d mV",
+ CHARGER_NAME, CHARGER_PRIMARY,
+ meas_reg * 408/10,
+ meas_volt * 102/10);
+ }
+
+ if (is_platform_id_3s(platform_id)) {
+ /* 3S Battery */
+ CPRINTS("%s %d : VBAT_SNSP_HIGH_TH: %d mV ! "
+ "- VBAT %d mV",
+ CHARGER_NAME, CHARGER_PRIMARY,
+ meas_reg * 616/10,
+ meas_volt * 154/10);
+ }
+
+ /* Set Vbat Threshold to Max value to re-arm the interrupt */
+ rv = meas_write8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MAX_TH, 0xFF);
+
+ /* Disable battery charge */
+ rv |= sm5803_flow1_update(chgnum, CHARGER_MODE_DISABLED,
+ MASK_CLR);
+ if (is_platform_id_2s(platform_id)) {
+ /* 2S battery: set VBAT_SENSP TH 9V */
+ rv |= meas_write8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MAX_TH,
+ SM5803_VBAT_SNSP_MAXTH_2S_LEVEL);
+ }
+ if (is_platform_id_3s(platform_id)) {
+ /* 3S battery: set VBAT_SENSP TH 13.3V */
+ rv |= meas_write8(CHARGER_PRIMARY,
+ SM5803_REG_VBATSNSP_MAX_TH,
+ SM5803_VBAT_SNSP_MAXTH_3S_LEVEL);
+ }
+
+ active_restart_port = act_chg;
+ hook_call_deferred(&sm5803_restart_charging_data, 1 * SECOND);
+ }
+
/* TODO(b/159376384): Take action on fatal BFET power alert. */
rv = main_read8(chgnum, SM5803_REG_INT3_REQ, &int_reg);
if (rv) {
@@ -1169,6 +1276,7 @@ void sm5803_handle_interrupt(int chgnum)
SM5803_FLOW1_DIRECTCHG_SRC_EN,
MASK_CLR);
}
+
}
static void sm5803_irq_deferred(void)
diff --git a/driver/charger/sm5803.h b/driver/charger/sm5803.h
index e1a3e10560..b7638411e4 100644
--- a/driver/charger/sm5803.h
+++ b/driver/charger/sm5803.h
@@ -95,6 +95,9 @@
#define SM5803_GPIO0_OPEN_DRAIN_EN BIT(6)
#define SM5803_CHG_DET_OPEN_DRAIN_EN BIT(7)
+#define SM5803_REG_VBATSNSP_MEAS_MSB 0x40
+#define SM5803_REG_VBATSNSP_MEAS_LSB 0x41
+
enum sm5803_gpio0_modes {
GPIO0_MODE_PROCHOT,
GPIO0_MODE_OUTPUT,
@@ -133,6 +136,7 @@ enum sm5803_gpio0_modes {
/* Note: Threshold registers all assume lower 2 bits are 0 */
#define SM5803_REG_VBUS_LOW_TH 0x1A
+#define SM5803_REG_VBATSNSP_MAX_TH 0x26
#define SM5803_REG_VBUS_HIGH_TH 0x2A
#define SM5803_REG_VCHG_PWR_LOW_TH 0x1B
#define SM5803_REG_VCHG_PWR_HIGH_TH 0x2B
@@ -146,6 +150,8 @@ enum sm5803_gpio0_modes {
#define SM5803_VBUS_LOW_LEVEL 0x25
#define SM5803_VBUS_HIGH_LEVEL 0x2C
+
+
/*
* TINT thresholds. TINT steps are in 0.43 K with the upper threshold set to
* 360 K and lower threshold to de-assert PROCHOT at 330 K.
@@ -156,6 +162,22 @@ enum sm5803_gpio0_modes {
#define SM5803_TINT_MAX_LEVEL 0xFF
#define SM5803_TINT_MIN_LEVEL 0x00
+/*
+ * Set minimum thresholds for VBUS_PWR_LOW_TH interrupt generation
+ * 2S battery 9.4v
+ * 3S battery 14.1V VBUS_PWR MIN TH
+ */
+#define SM5803_VBAT_PWR_MINTH_3S_LEVEL 0x9B
+#define SM5803_VBAT_PWR_MINTH_2S_LEVEL 0x9B
+
+/*
+ * Set thresholds for VBATSNSP_MAX_TH GPADC interrupt generation
+ * 2S battery 9v
+ * 3S battery 13.3V
+ */
+#define SM5803_VBAT_SNSP_MAXTH_3S_LEVEL 0xD8
+#define SM5803_VBAT_SNSP_MAXTH_2S_LEVEL 0xDC
+
/* IBAT levels - The IBAT levels increment in 7.32mA */
#define SM5803_REG_IBAT_CHG_MEAS_MSB 0x44
#define SM5803_REG_IBAT_CHG_MEAS_LSB 0x45
diff --git a/driver/fingerprint/fpc/bep/fpc_private.c b/driver/fingerprint/fpc/bep/fpc_private.c
index ae4b8d834b..a94ba2ab06 100644
--- a/driver/fingerprint/fpc/bep/fpc_private.c
+++ b/driver/fingerprint/fpc/bep/fpc_private.c
@@ -143,12 +143,6 @@ int fp_sensor_init(void)
{
int rc;
- /* The dragonclaw development board needs this enabled to enable the
- * AND gate (U10) to CS. Production boards could disable this to save
- * power since it's only needed for initial detection on those boards.
- */
- gpio_set_level(GPIO_DIVIDER_HIGHSIDE, 1);
-
/* Print the binary libfpbep.a library version */
CPRINTS("FPC libfpbep.a %s", fp_sensor_get_version());
diff --git a/driver/ppc/nx20p348x.c b/driver/ppc/nx20p348x.c
index 024e0906bd..497fdb21d5 100644
--- a/driver/ppc/nx20p348x.c
+++ b/driver/ppc/nx20p348x.c
@@ -402,7 +402,7 @@ static void nx20p348x_handle_interrupt(int port)
}
}
read_reg(port, NX20P348X_DEVICE_CONTROL_REG, &control_reg);
- reg |= NX20P348X_CTRL_DB_EXIT;
+ control_reg |= NX20P348X_CTRL_DB_EXIT;
write_reg(port, NX20P348X_DEVICE_CONTROL_REG, control_reg);
/*
* If DB exit mode failed, then the OVP limit setting done in
diff --git a/include/config.h b/include/config.h
index 3136dd18fe..11733d38df 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2718,12 +2718,6 @@
#undef CONFIG_KEYBOARD_FACTORY_TEST
/*
- * Keyboard config (struct keyboard_scan_config) is in board.c. If this is
- * not defined, default values from common/keyboard_scan.c will be used.
- */
-#undef CONFIG_KEYBOARD_BOARD_CONFIG
-
-/*
* Support for boot key combinations (e.g. refresh key being held on boot to
* trigger recovery).
*/
@@ -2807,6 +2801,21 @@
#undef CONFIG_KEYBOARD_KEYPAD
/*
+ * Enable strict debouncer. A strict debouncer waits until debounce is done
+ * before registering key up/down while a non-strict debouncer registers a key
+ * up/down as soon as a key is pressed or released.
+ *
+ * A strict debouncer is robust against unintentional key presses, caused by a
+ * device drop, for example. However, its latency isn't as fast as a non-strict
+ * debouncer.
+ *
+ * If a strict debouncer is used, it's recommended to set debounce_down_us and
+ * debounce_up_us to an equal value. This guarantees key events are registered
+ * in the order the keys are pressed.
+ */
+#undef CONFIG_KEYBOARD_STRICT_DEBOUNCE
+
+/*
* Enable the 8042 AUX port. This is typically used for PS/2 mouse devices.
* You will need to implement send_aux_data_to_device and lpc_aux_put_char.
*/
diff --git a/include/console_channel.inc b/include/console_channel.inc
index 01658a0eaa..0a6d84509c 100644
--- a/include/console_channel.inc
+++ b/include/console_channel.inc
@@ -56,6 +56,9 @@ CONSOLE_CHANNEL(CC_KEYSCAN, "keyscan")
#ifdef CONFIG_LID_ANGLE_UPDATE
CONSOLE_CHANNEL(CC_LIDANGLE, "lidangle")
#endif
+#ifdef HAS_TASK_LOGOLED
+CONSOLE_CHANNEL(CC_LOGOLED, "logoled")
+#endif
#ifdef HAS_TASK_LIGHTBAR
CONSOLE_CHANNEL(CC_LIGHTBAR, "lightbar")
#endif
diff --git a/driver/als_tcs3400.h b/include/driver/als_tcs3400.h
index 0078b90442..0078b90442 100644
--- a/driver/als_tcs3400.h
+++ b/include/driver/als_tcs3400.h
diff --git a/include/i2c.h b/include/i2c.h
index 231561caea..4d49ec96e8 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -590,4 +590,18 @@ enum i2c_freq i2c_get_freq(int port);
/* Find the matching port in i2c_ports[] table. */
const struct i2c_port_t *get_i2c_port(const int port);
+/**
+ * @brief Get soc's i2c port number where i2c device is connected to.
+ *
+ * This function translate a i2c port enum value (enum-name property listed in
+ * named-i2c-ports) to soc's i2c port. Devices which are connected to the
+ * same port of soc should have the same number.
+ *
+ * @param enum_port i2c port enum value.
+ * @return i2c port of soc used in mutex_lock().
+ * -1 if physical port is not defined or i2c port number is out of
+ * port_mutex space.
+ */
+int i2c_get_physical_port(int enum_port);
+
#endif /* __CROS_EC_I2C_H */
diff --git a/include/keyboard_scan.h b/include/keyboard_scan.h
index e74bfcea33..b3a7bed587 100644
--- a/include/keyboard_scan.h
+++ b/include/keyboard_scan.h
@@ -46,7 +46,7 @@ struct keyboard_scan_config *keyboard_scan_get_config(void);
/*
* Which is probably this.
*/
-extern struct keyboard_scan_config keyscan_config;
+__override_proto extern struct keyboard_scan_config keyscan_config;
/* Key held down at keyboard-controlled reset boot time. */
enum boot_key {
@@ -135,4 +135,14 @@ void set_vol_up_key(uint8_t row, uint8_t col);
static inline void set_vol_up_key(uint8_t row, uint8_t col) {}
#endif
+#ifdef CONFIG_KEYBOARD_FACTORY_TEST
+/*
+ * Map keyboard connector pins to EC GPIO pins for factory test.
+ * Pins mapped to {-1, -1} are skipped.
+ */
+extern const int keyboard_factory_scan_pins[][2];
+extern const int keyboard_factory_scan_pins_used;
+#endif
+
+
#endif /* __CROS_EC_KEYBOARD_SCAN_H */
diff --git a/include/led_onoff_states.h b/include/led_onoff_states.h
index 7eb8b312f7..63955e590a 100644
--- a/include/led_onoff_states.h
+++ b/include/led_onoff_states.h
@@ -53,6 +53,9 @@ struct led_descriptor {
uint8_t time;
};
+extern const int led_charge_lvl_1;
+extern const int led_charge_lvl_2;
+
enum pwr_led_states {
PWR_LED_STATE_ON,
PWR_LED_STATE_SUSPEND_AC,
diff --git a/include/tablet_mode.h b/include/tablet_mode.h
index b5a2f2f562..3e03d77f6a 100644
--- a/include/tablet_mode.h
+++ b/include/tablet_mode.h
@@ -13,12 +13,17 @@
*/
int tablet_get_mode(void);
+/* Bit mask of tablet mode trigger */
+#define TABLET_TRIGGER_LID BIT(0)
+#define TABLET_TRIGGER_BASE BIT(1)
+
/**
* Set tablet mode state
*
* @param mode 1: tablet mode. 0 clamshell mode.
+ * @param trigger: bitmask of the trigger, TABLET_TRIGGER_*.
*/
-void tablet_set_mode(int mode);
+void tablet_set_mode(int mode, uint32_t trigger);
/**
* Disable tablet mode
diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h
index b3ba56d95d..3da1e9fae6 100644
--- a/include/usb_pe_sm.h
+++ b/include/usb_pe_sm.h
@@ -176,5 +176,14 @@ const char *pe_get_current_state(int port);
*/
uint32_t pe_get_flags(int port);
+#ifdef TEST_BUILD
+/**
+ * Clears all internal port data, as we would on a detach event
+ *
+ * @param port USB-C port number
+ */
+void pe_clear_port_data(int port);
+#endif /* TEST_BUILD */
+
#endif /* __CROS_EC_USB_PE_H */
diff --git a/test/build.mk b/test/build.mk
index 8ff9caa3d4..6b156ccaf0 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -48,7 +48,8 @@ test-list-host += is_enabled_error
test-list-host += kasa
test-list-host += kb_8042
test-list-host += kb_mkbp
-#test-list-host += kb_scan # crbug.com/976974
+test-list-host += kb_scan
+test-list-host += kb_scan_strict
test-list-host += lid_sw
test-list-host += lightbar
test-list-host += mag_cal
@@ -159,6 +160,7 @@ is_enabled-y=is_enabled.o
kb_8042-y=kb_8042.o
kb_mkbp-y=kb_mkbp.o
kb_scan-y=kb_scan.o
+kb_scan_strict-y=kb_scan.o
lid_sw-y=lid_sw.o
lightbar-y=lightbar.o
mag_cal-y=mag_cal.o
diff --git a/test/kb_scan.c b/test/kb_scan.c
index a4fb6f9841..b3b42813e4 100644
--- a/test/kb_scan.c
+++ b/test/kb_scan.c
@@ -31,7 +31,16 @@
old = fifo_add_count; \
} while (0)
+/* Emulated physical key state */
static uint8_t mock_state[KEYBOARD_COLS_MAX];
+
+/* Snapshot of last known key state */
+static uint8_t key_state[KEYBOARD_COLS_MAX];
+
+/* Counters for key state changes (UP/DOWN) */
+static int key_state_change[KEYBOARD_COLS_MAX][KEYBOARD_ROWS];
+static int total_key_state_change;
+
static int column_driven;
static int fifo_add_count;
static int lid_open;
@@ -79,7 +88,24 @@ int keyboard_raw_read_rows(void)
int mkbp_keyboard_add(const uint8_t *buffp)
{
+ int c, r;
+
fifo_add_count++;
+
+ for (c = 0; c < KEYBOARD_COLS_MAX; c++) {
+ uint8_t diff = key_state[c] ^ buffp[c];
+
+ for (r = 0; r < KEYBOARD_ROWS; r++) {
+ if (diff & BIT(r)) {
+ key_state_change[c][r]++;
+ total_key_state_change++;
+ }
+ }
+ }
+
+ /* Save a snapshot. */
+ memcpy(key_state, buffp, sizeof(key_state));
+
return EC_SUCCESS;
}
@@ -99,15 +125,29 @@ void chipset_reset(void)
KEYBOARD_COL_ ## k, \
p)
+#define mock_default_key(k, p) mock_key(KEYBOARD_DEFAULT_ROW_ ## k, \
+ KEYBOARD_DEFAULT_COL_ ## k, \
+ p)
+
static void mock_key(int r, int c, int keydown)
{
- ccprintf("%s (%d, %d)\n", keydown ? "Pressing" : "Releasing", r, c);
+ ccprintf(" %s (%d, %d)\n", keydown ? "Pressing" : "Releasing", r, c);
if (keydown)
mock_state[c] |= (1 << r);
else
mock_state[c] &= ~(1 << r);
}
+static void reset_key_state(void)
+{
+ memset(mock_state, 0, sizeof(mock_state));
+ memset(key_state, 0, sizeof(key_state));
+ memset(key_state_change, 0, sizeof(key_state_change));
+ task_wake(TASK_ID_KEYSCAN);
+ msleep(NO_KEYDOWN_DELAY_MS);
+ total_key_state_change = 0;
+}
+
static int expect_keychange(void)
{
int old_count = fifo_add_count;
@@ -160,6 +200,8 @@ static int verify_key_presses(int old, int expected)
static int deghost_test(void)
{
+ reset_key_state();
+
/* Test we can detect a keypress */
mock_key(1, 1, 1);
TEST_ASSERT(expect_keychange() == EC_SUCCESS);
@@ -201,11 +243,118 @@ static int deghost_test(void)
return EC_SUCCESS;
}
+static int strict_debounce_test(void)
+{
+ reset_key_state();
+
+ ccprintf("Test key press & hold.\n");
+ mock_key(1, 1, 1);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 1, "%d");
+ TEST_EQ(total_key_state_change, 1, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test a short stroke.\n");
+ mock_key(1, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 0);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_no_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 0, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test ripples being suppressed.\n");
+ /* DOWN */
+ mock_key(1, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 0);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 1, "%d");
+ TEST_EQ(total_key_state_change, 1, "%d");
+ /* UP */
+ mock_key(1, 1, 0);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 0);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 2, "%d");
+ TEST_EQ(total_key_state_change, 2, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test simultaneous strokes.\n");
+ mock_key(1, 1, 1);
+ mock_key(2, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 1, "%d");
+ TEST_EQ(key_state_change[1][2], 1, "%d");
+ TEST_EQ(total_key_state_change, 2, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test simultaneous strokes in two columns.\n");
+ mock_key(1, 1, 1);
+ mock_key(1, 2, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 1, "%d");
+ TEST_EQ(key_state_change[2][1], 1, "%d");
+ TEST_EQ(total_key_state_change, 2, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test normal & short simultaneous strokes.\n");
+ mock_key(1, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(2, 1, 1);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 0);
+ task_wake_then_sleep_1ms(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 0, "%d");
+ TEST_EQ(key_state_change[1][2], 1, "%d");
+ TEST_EQ(total_key_state_change, 1, "%d");
+ ccprintf("Pass.\n");
+
+ reset_key_state();
+
+ ccprintf("Test normal & short simultaneous strokes in two columns.\n");
+ reset_key_state();
+ mock_key(1, 1, 1);
+ task_wake(TASK_ID_KEYSCAN);
+ mock_key(1, 2, 1);
+ task_wake(TASK_ID_KEYSCAN);
+ mock_key(1, 1, 0);
+ task_wake(TASK_ID_KEYSCAN);
+ TEST_EQ(expect_keychange(), EC_SUCCESS, "%d");
+ TEST_EQ(key_state_change[1][1], 0, "%d");
+ TEST_EQ(key_state_change[2][1], 1, "%d");
+ TEST_EQ(total_key_state_change, 1, "%d");
+ ccprintf("Pass.\n");
+
+ return EC_SUCCESS;
+}
+
static int debounce_test(void)
{
int old_count = fifo_add_count;
int i;
+ reset_key_state();
+
/* One brief keypress is detected. */
msleep(40);
mock_key(1, 1, 1);
@@ -289,6 +438,8 @@ static int simulate_key_test(void)
{
int old_count;
+ reset_key_state();
+
task_wake(TASK_ID_KEYSCAN);
msleep(40); /* Wait for debouncing to settle */
@@ -328,23 +479,25 @@ static int verify_variable_not_set(int *var)
static int runtime_key_test(void)
{
+ reset_key_state();
+
/* Alt-VolUp-H triggers system hibernation */
mock_defined_key(LEFT_ALT, 1);
- mock_defined_key(VOL_UP, 1);
+ mock_default_key(VOL_UP, 1);
mock_defined_key(KEY_H, 1);
TEST_ASSERT(wait_variable_set(&hibernated) == EC_SUCCESS);
mock_defined_key(LEFT_ALT, 0);
- mock_defined_key(VOL_UP, 0);
+ mock_default_key(VOL_UP, 0);
mock_defined_key(KEY_H, 0);
TEST_ASSERT(expect_keychange() == EC_SUCCESS);
/* Alt-VolUp-R triggers chipset reset */
mock_defined_key(RIGHT_ALT, 1);
- mock_defined_key(VOL_UP, 1);
+ mock_default_key(VOL_UP, 1);
mock_defined_key(KEY_R, 1);
TEST_ASSERT(wait_variable_set(&reset_called) == EC_SUCCESS);
mock_defined_key(RIGHT_ALT, 0);
- mock_defined_key(VOL_UP, 0);
+ mock_default_key(VOL_UP, 0);
mock_defined_key(KEY_R, 0);
TEST_ASSERT(expect_keychange() == EC_SUCCESS);
@@ -352,10 +505,10 @@ static int runtime_key_test(void)
mock_defined_key(LEFT_ALT, 1);
mock_defined_key(KEY_H, 1);
mock_defined_key(KEY_R, 1);
- mock_defined_key(VOL_UP, 1);
+ mock_default_key(VOL_UP, 1);
TEST_ASSERT(verify_variable_not_set(&hibernated) == EC_SUCCESS);
TEST_ASSERT(verify_variable_not_set(&reset_called) == EC_SUCCESS);
- mock_defined_key(VOL_UP, 0);
+ mock_default_key(VOL_UP, 0);
mock_defined_key(KEY_R, 0);
mock_defined_key(KEY_H, 0);
mock_defined_key(LEFT_ALT, 0);
@@ -368,6 +521,8 @@ static int runtime_key_test(void)
#ifdef CONFIG_LID_SWITCH
static int lid_test(void)
{
+ reset_key_state();
+
msleep(40); /* Allow debounce to settle */
lid_open = 0;
@@ -408,7 +563,7 @@ void test_init(void)
/* Power-F3-ESC */
system_set_reset_flags(system_get_reset_flags() |
EC_RESET_FLAG_RESET_PIN);
- mock_key(1, 1, 1);
+ mock_key(KEYBOARD_ROW_ESC, KEYBOARD_COL_ESC, 1);
} else if (state & TEST_STATE_MASK(TEST_STATE_STEP_3)) {
/* Power-F3-Down */
system_set_reset_flags(system_get_reset_flags() |
@@ -424,8 +579,14 @@ static void run_test_step1(void)
test_reset();
RUN_TEST(deghost_test);
- RUN_TEST(debounce_test);
- RUN_TEST(simulate_key_test);
+
+ if (IS_ENABLED(CONFIG_KEYBOARD_STRICT_DEBOUNCE))
+ RUN_TEST(strict_debounce_test);
+ else
+ RUN_TEST(debounce_test);
+
+ if (0) /* crbug.com/976974 */
+ RUN_TEST(simulate_key_test);
#ifdef EMU_BUILD
RUN_TEST(runtime_key_test);
#endif
diff --git a/test/kb_scan_strict.tasklist b/test/kb_scan_strict.tasklist
new file mode 120000
index 0000000000..d4d4fa1efb
--- /dev/null
+++ b/test/kb_scan_strict.tasklist
@@ -0,0 +1 @@
+kb_scan.tasklist \ No newline at end of file
diff --git a/test/motion_angle_tablet.c b/test/motion_angle_tablet.c
index 3cf496ac5b..8eea053405 100644
--- a/test/motion_angle_tablet.c
+++ b/test/motion_angle_tablet.c
@@ -57,7 +57,7 @@ static int test_lid_angle_less180(void)
cprints(CC_ACCEL, "start loop");
/* Force clamshell mode, to be sure we go in tablet mode ASAP. */
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
/* Check we stay in tablet mode, even when hinge is vertical. */
while (index < kAccelerometerVerticalHingeTestDataLength) {
@@ -79,7 +79,7 @@ static int test_lid_angle_less180(void)
* Check we stay in tablet mode, even when hinge is vertical and
* shaked.
*/
- tablet_set_mode(0);
+ tablet_set_mode(0, TABLET_TRIGGER_LID);
while (index < kAccelerometerVerticalHingeUnstableTestDataLength) {
feed_accel_data(kAccelerometerVerticalHingeUnstableTestData,
&index, filler);
diff --git a/test/run_device_tests.py b/test/run_device_tests.py
index 9e7f384cb2..43b597bcf1 100755
--- a/test/run_device_tests.py
+++ b/test/run_device_tests.py
@@ -267,23 +267,25 @@ def build(test_name: str, board_name: str) -> None:
subprocess.run(cmd).check_returncode()
-def flash(test_name: str, board: str, flasher: str) -> bool:
+def flash(test_name: str, board: str, flasher: str, remote: str) -> bool:
"""Flash specified test to specified board."""
logging.info("Flashing test")
+ cmd = []
if flasher == JTRACE:
- flash_script = JTRACE_FLASH_SCRIPT
+ cmd.append(JTRACE_FLASH_SCRIPT)
+ if remote:
+ cmd.extend(['--remote', remote])
elif flasher == SERVO_MICRO:
- flash_script = SERVO_MICRO_FLASH_SCRIPT
+ cmd.append(SERVO_MICRO_FLASH_SCRIPT)
else:
logging.error('Unknown flasher: "%s"', flasher)
return False
- cmd = [
- flash_script,
+ cmd.extend([
'--board', board,
'--image', os.path.join(EC_DIR, 'build', board, test_name,
test_name + '.bin'),
- ]
+ ])
logging.debug('Running command: "%s"', ' '.join(cmd))
completed_process = subprocess.run(cmd)
return completed_process.returncode == 0
@@ -429,6 +431,14 @@ def main():
default=JTRACE
)
+ # This might be expanded to serve as a "remote" for flash_ec also, so
+ # we will leave it generic.
+ parser.add_argument(
+ '--remote', '-n',
+ help='The remote host:ip to connect to J-Link. '
+ 'This is passed to flash_jlink.py.',
+ )
+
args = parser.parse_args()
logging.basicConfig(level=args.log_level)
@@ -453,7 +463,7 @@ def main():
flash_succeeded = False
for i in range(0, test.num_flash_attempts):
logging.debug('Flash attempt %d', i + 1)
- if flash(test.name, args.board, args.flasher):
+ if flash(test.name, args.board, args.flasher, args.remote):
flash_succeeded = True
break
time.sleep(1)
diff --git a/test/stm32f_rtc.c b/test/stm32f_rtc.c
index 4a09085e4f..0e60fcb73f 100644
--- a/test/stm32f_rtc.c
+++ b/test/stm32f_rtc.c
@@ -10,6 +10,12 @@ static uint32_t rtc_fired;
static struct rtc_time_reg rtc_irq;
static const int rtc_delay_ms = 500;
+/*
+ * We will be testing that the RTC interrupt timestamp occurs
+ * within +/- delay_tol_us (tolerance) of the above rtc_delay_ms.
+ */
+static const int delay_tol_us = MSEC / 2;
+
/* Override default RTC interrupt handler */
void __rtc_alarm_irq(void)
{
@@ -21,7 +27,6 @@ test_static int test_rtc_alarm(void)
{
struct rtc_time_reg rtc;
uint32_t rtc_diff_us;
- uint32_t rtc_diff_ms;
const int delay_us = rtc_delay_ms * MSEC;
set_rtc_alarm(0, delay_us, &rtc, 0);
@@ -33,19 +38,25 @@ test_static int test_rtc_alarm(void)
rtc_diff_us = get_rtc_diff(&rtc, &rtc_irq);
- ccprintf("rtc_diff_us: %d\n", rtc_diff_us);
+ ccprintf("Target delay was %dus\n", delay_us);
+ ccprintf("Actual delay was %dus\n", rtc_diff_us);
+ ccprintf("The delays are expected to be within +/- %dus\n", MSEC / 2);
- /* Assume we'll always fire within 1 ms. May need to be adjusted if
+ /* Assume we'll always fire within 500us. May need to be adjusted if
* this doesn't hold.
+ *
+ * delay_us-delay_tol_us < rtc_diff_us < delay_us+delay_tol_us
*/
- rtc_diff_ms = rtc_diff_us / MSEC;
- TEST_EQ(rtc_diff_ms, rtc_delay_ms, "%d");
+ TEST_LT(delay_us - delay_tol_us, rtc_diff_us, "%dus");
+ TEST_LT(rtc_diff_us, delay_us + delay_tol_us, "%dus");
return EC_SUCCESS;
}
void run_test(int argc, char **argv)
{
+ test_reset();
+
RUN_TEST(test_rtc_alarm);
test_print_result();
diff --git a/test/test_config.h b/test/test_config.h
index 9e74a8646b..8b98dc1087 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -59,10 +59,13 @@
#define CONFIG_MKBP_USE_GPIO
#endif
-#ifdef TEST_KB_SCAN
+#if defined(TEST_KB_SCAN) || defined(TEST_KB_SCAN_STRICT)
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
#define CONFIG_MKBP_EVENT
#define CONFIG_MKBP_USE_GPIO
+#ifdef TEST_KB_SCAN_STRICT
+#define CONFIG_KEYBOARD_STRICT_DEBOUNCE
+#endif
#endif
#ifdef TEST_MATH_UTIL
diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c
index 086e2263a5..85f2bb7358 100644
--- a/test/usb_pe_drp.c
+++ b/test/usb_pe_drp.c
@@ -42,6 +42,7 @@ void before_test(void)
mock_dpm_reset();
mock_dp_alt_mode_reset();
mock_prl_reset();
+ pe_clear_port_data(PORT0);
/* Restart the PD task and let it settle */
task_set_event(TASK_ID_PD_C0, TASK_EVENT_RESET_DONE);
diff --git a/util/config_allowed.txt b/util/config_allowed.txt
index 8e2edb9c69..2843696cc9 100644
--- a/util/config_allowed.txt
+++ b/util/config_allowed.txt
@@ -451,7 +451,6 @@ CONFIG_FW_INCLUDE_RO
CONFIG_FW_LIMITED_IMAGE
CONFIG_FW_PSTATE_OFF
CONFIG_FW_PSTATE_SIZE
-CONFIG_FW_RESET_VECTOR
CONFIG_GESTURE_DETECTION
CONFIG_GESTURE_DETECTION_MASK
CONFIG_GESTURE_HOST_DETECTION
@@ -517,7 +516,6 @@ CONFIG_HOSTCMD_PD_PANIC
CONFIG_HOSTCMD_RATE_LIMITING_MIN_REST
CONFIG_HOSTCMD_RATE_LIMITING_PERIOD
CONFIG_HOSTCMD_RATE_LIMITING_RECESS
-CONFIG_HOSTCMD_REGULATOR
CONFIG_HOSTCMD_RWHASHPD
CONFIG_HOSTCMD_SECTION_SORTED
CONFIG_HOSTCMD_SKUID
@@ -835,7 +833,6 @@ CONFIG_SHAREDMEM_MINIMUM_SIZE_RWSIG
CONFIG_SIMULATED_BUTTON
CONFIG_SLEEP_TIMEOUT_MS
CONFIG_SMBUS
-CONFIG_SMBUS_PEC
CONFIG_SOFTWARE_CLZ
CONFIG_SOFTWARE_CTZ
CONFIG_SOMETHING
diff --git a/util/ec_parse_panicinfo.c b/util/ec_parse_panicinfo.c
index a3fefcf7b5..3a2da4590a 100644
--- a/util/ec_parse_panicinfo.c
+++ b/util/ec_parse_panicinfo.c
@@ -22,6 +22,19 @@ int main(int argc, char *argv[])
BUILD_ASSERT(sizeof(pdata) > sizeof(struct panic_data)*2);
+ /*
+ * Provide a minimal help message.
+ */
+ if (argc > 1) {
+ printf("Usage: cat <PANIC_BLOB_PATH> | ec_parse_panicinfo\n");
+ printf("Print the plain text panic info from a raw EC panic "
+ "data blob.\n\n");
+ printf("Example:\n");
+ printf("ec_parse_panicinfo "
+ "</sys/kernel/debug/cros_ec/panicinfo\n");
+ return 1;
+ }
+
while (1) {
read = fread(&pdata[size], 1, sizeof(pdata)-size, stdin);
if (read < 0) {
diff --git a/util/flash_jlink.py b/util/flash_jlink.py
index b8422880a9..d2fd4dec15 100755
--- a/util/flash_jlink.py
+++ b/util/flash_jlink.py
@@ -17,9 +17,14 @@ import argparse
import logging
import os
import shutil
+import socket
import subprocess
import sys
import tempfile
+import time
+
+
+DEFAULT_SEGGER_REMOTE_PORT = 19020
# Commands are documented here: https://wiki.segger.com/J-Link_Commander
JLINK_COMMANDS = '''
@@ -57,6 +62,32 @@ BOARD_CONFIGS = {
}
+def is_tcp_port_open(host: str, tcp_port: int) -> bool:
+ """Checks if the TCP host port is open."""
+
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.settimeout(2) # 2 Second Timeout
+ try:
+ sock.connect((host, tcp_port))
+ sock.shutdown(socket.SHUT_RDWR)
+ except ConnectionRefusedError:
+ return False
+ except socket.timeout:
+ return False
+ finally:
+ sock.close()
+ # Other errors are propagated as odd exceptions.
+
+ # We shutdown and closed the connection, but the server may need a second
+ # to start listening again. If the following error is seen, this timeout
+ # should be increased. 300ms seems to be the minimum.
+ #
+ # Connecting to J-Link via IP...FAILED: Can not connect to J-Link via \
+ # TCP/IP (127.0.0.1, port 19020)
+ time.sleep(0.5)
+ return True
+
+
def create_jlink_command_file(firmware_file, config):
tmp = tempfile.NamedTemporaryFile()
tmp.write(JLINK_COMMANDS.format(FIRMWARE=firmware_file,
@@ -66,13 +97,44 @@ def create_jlink_command_file(firmware_file, config):
return tmp
-def flash(jlink_exe, ip, device, interface, cmd_file):
+def flash(jlink_exe, remote, device, interface, cmd_file):
cmd = [
jlink_exe,
]
- if ip:
- cmd.extend(['-ip', ip])
+ if remote:
+ logging.debug(f'Connecting to J-Link over TCP/IP {remote}.')
+ remote_components = remote.split(':')
+ if len(remote_components) not in [1, 2]:
+ logging.debug(f'Given remote "{remote}" is malformed.')
+ return 1
+
+ host = remote_components[0]
+ try:
+ ip = socket.gethostbyname(host)
+ except socket.gaierror as e:
+ logging.error(f'Failed to resolve host "{host}": {e}.')
+ return 1
+ logging.debug(f'Resolved {host} as {ip}.')
+ port = DEFAULT_SEGGER_REMOTE_PORT
+
+ if len(remote_components) == 2:
+ try:
+ port = int(remote_components[1])
+ except ValueError:
+ logging.error(
+ f'Given remote port "{remote_components[1]}" is malformed.')
+ return 1
+
+ remote = f'{ip}:{port}'
+
+ logging.debug(f'Checking connection to {remote}.')
+ if not is_tcp_port_open(ip, port):
+ logging.error(
+ f'JLink server doesn\'t seem to be listening on {remote}.')
+ logging.error('Ensure that JLinkRemoteServerCLExe is running.')
+ return 1
+ cmd.extend(['-ip', remote])
cmd.extend([
'-device', device,
@@ -99,12 +161,10 @@ def main(argv: list):
help='JLinkExe path (default: ' + default_jlink + ')',
default=default_jlink)
- default_ip = '127.0.0.1:2551'
parser.add_argument(
- '--ip', '-n',
- help='IP address of J-Link or machine running JLinkRemoteServerCLExe '
- '(default: ' + default_ip + ')',
- default=default_ip)
+ '--remote', '-n',
+ help='Use TCP/IP host[:port] to connect to a J-Link or '
+ 'JLinkRemoteServerCLExe. If unspecified, connect over USB.')
default_board = 'bloonchipper'
parser.add_argument(
@@ -138,7 +198,7 @@ def main(argv: list):
args.jlink = args.jlink
cmd_file = create_jlink_command_file(args.image, config)
- ret_code = flash(args.jlink, args.ip, config.device, config.interface,
+ ret_code = flash(args.jlink, args.remote, config.device, config.interface,
cmd_file.name)
cmd_file.close()
return ret_code
diff --git a/util/stm32mon.c b/util/stm32mon.c
index ff72e2f75e..7be802b1ed 100644
--- a/util/stm32mon.c
+++ b/util/stm32mon.c
@@ -87,7 +87,7 @@ const struct {
CMD_LOOKUP_ENTRY(RU),
};
-const char *cmd_lookup_name(char cmd)
+const char *cmd_lookup_name(uint8_t cmd)
{
int i;
for (i = 0; i < ARRAY_SIZE(cmd_lookup_table); i++) {
@@ -904,7 +904,7 @@ int command_get_commands(int fd, struct stm32_def *chip)
if (name)
printf("%s ", name);
else
- printf("%02x ", cmds[i]);
+ printf("0x%02x ", cmds[i]);
}
if (mode == MODE_I2C)
@@ -1117,7 +1117,7 @@ int command_erase(int fd, uint16_t count, uint16_t start)
int command_read_unprotect(int fd)
{
int res;
- int retries = MAX_RETRY_COUNT;
+ int retries = MAX_ACK_RETRY_COUNT;
printf("Unprotecting flash read...\n");
@@ -1672,6 +1672,12 @@ int main(int argc, char **argv)
if (!chip)
goto terminate;
+ if (command_get_commands(ser, chip) < 0)
+ goto terminate;
+
+ if (flags & FLAG_READ_UNPROTECT)
+ command_read_unprotect(ser);
+
/*
* Use the actual size if we were able to read it since some chips
* have the same chip ID, but different flash sizes based on the
@@ -1693,11 +1699,6 @@ int main(int argc, char **argv)
*/
(void)read_package_data_register(ser, chip, &package_data_reg);
- if (command_get_commands(ser, chip) < 0)
- goto terminate;
-
- if (flags & FLAG_READ_UNPROTECT)
- command_read_unprotect(ser);
if (flags & FLAG_UNPROTECT)
command_write_unprotect(ser);
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index 51c1b8b7da..a9c33790dd 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -217,6 +217,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE
"${PLATFORM_EC}/common/uart_hostcmd.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOSTCMD_GET_UPTIME_INFO
"${PLATFORM_EC}/common/uptime.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOSTCMD_REGULATOR
+ "${PLATFORM_EC}/common/regulator.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C
"${PLATFORM_EC}/common/i2c_controller.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C_VIRTUAL_BATTERY
diff --git a/zephyr/Kconfig b/zephyr/Kconfig
index ea437bda40..2440fd3773 100644
--- a/zephyr/Kconfig
+++ b/zephyr/Kconfig
@@ -376,6 +376,13 @@ config PLATFORM_EC_HOSTCMD_GET_UPTIME_INFO
the EC has been powered up, the number of AP resets, an optional log
of AP-reset events and some flags.
+config PLATFORM_EC_HOSTCMD_REGULATOR
+ bool "Host command of voltage regulator control"
+ help
+ Enable host commands (EC_CMD_REGULATOR_) for controlling voltage
+ regulator. The board should also implement board functions defined in
+ include/regulator.h.
+
config PLATFORM_EC_I2C
bool "I2C shim"
default n if ARCH_POSIX
@@ -388,6 +395,18 @@ config PLATFORM_EC_I2C
should make shimming other platform/ec modules which rely on i2c
communication "just work" without requiring any further code changes.
+config PLATFORM_EC_SMBUS_PEC
+ bool "Packet error checking support for SMBus"
+ help
+ If enabled, adds error checking support for i2c_readN, i2c_writeN,
+ i2c_read_string and i2c_write_block. Where
+ - write operation appends an error checking byte at end of transfer, and
+ - read operatoin verifies the correctness of error checking byte from the
+ slave.
+ Set I2C_FLAG on addr_flags parameter to use this feature.
+
+ This option also enables error checking function on smart batteries.
+
config PLATFORM_EC_LID_SWITCH
bool "Lid switch"
help
diff --git a/zephyr/Kconfig.keyboard b/zephyr/Kconfig.keyboard
index 14514427dc..fc303c737d 100644
--- a/zephyr/Kconfig.keyboard
+++ b/zephyr/Kconfig.keyboard
@@ -48,16 +48,6 @@ config PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP
endchoice # PLATFORM_EC_KEYBOARD
-config PLATFORM_EC_KEYBOARD_BOARD_CONFIG
- bool "Use custom keyboard config"
- help
- Enable support for custom keyboard config. in which case
- keyscan_config must be defined by the board, using
- struct keyboard_scan_config.
-
- If this is not enabled, default values in common/keyboard_scan.c are
- used.
-
config PLATFORM_EC_KEYBOARD_KEYPAD
bool "Support a numeric keypad"
help
diff --git a/zephyr/Kconfig.system b/zephyr/Kconfig.system
index bac96beb20..be7dae8e6f 100644
--- a/zephyr/Kconfig.system
+++ b/zephyr/Kconfig.system
@@ -30,4 +30,13 @@ config PLATFORM_EC_SYSTEM_PRE_INIT_PRIORITY
those critical to determining the reset type, should be initialized at
lower priority so that the system reset flags are valid.
+config PLATFORM_EC_FW_RESET_VECTOR
+ bool "Firmware Reset Vector chip specific retrieval"
+ default y if SOC_FAMILY_RISCV_ITE
+ help
+ This defines if there is a chip specific machanism for
+ retrieving the firmware reset vector. The function that
+ needs to be provided is system_get_fw_reset_vector that
+ will return the address of the reset vector.
+
endif # PLATFORM_EC
diff --git a/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx7 b/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx7
index 26b36509ad..3c59d5405e 100644
--- a/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx7
+++ b/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx7
@@ -8,54 +8,16 @@
if SOC_SERIES_NPCX7
-if SOC_NPCX7M6FC
-
#
+# NPCX796FB: 1024 KiB Flash, 192 KiB code RAM, 62 KiB data RAM
# NPCX796FC: 512 KiB Flash, 192 KiB code RAM, 62 KiB data RAM
-#
-
-# Code RAM base for NPCX796FC
-config CROS_EC_PROGRAM_MEMORY_BASE
- default 0x10090000
-
-config CROS_EC_RAM_BASE
- default 0x200c0000
-
-config CROS_EC_DATA_RAM_SIZE
- default 0x00010000
-
-config CROS_EC_RAM_SIZE
- default 0x0000f800
-
-config FLASH_SIZE
- default 512
-
-config CROS_EC_RO_MEM_OFF
- default 0x0
-
-# Image size limited by code RAM size (192 KiB)
-config CROS_EC_RO_SIZE
- default 0x30000
-
-# RW firmware in program memory - Identical to RO, only one image loaded at a
-# time.
-config CROS_EC_RW_MEM_OFF
- default 0x0
-
-config CROS_EC_RW_SIZE
- default 0x30000
-
-endif # SOC_NPCX7M6FC
-
-if SOC_NPCX7M7FC
-
-#
# NPCX797FC: 512 KiB Flash, 320 KiB code RAM, 62 KiB data RAM
#
-# Code RAM base for NPCX797FC
+# Code RAM base for NPCX7 series
config CROS_EC_PROGRAM_MEMORY_BASE
- default 0x10070000
+ default 0x10090000 if SOC_NPCX7M6FB || SOC_NPCX7M6FC
+ default 0x10070000 if SOC_NPCX7M7FC
config CROS_EC_RAM_BASE
default 0x200c0000
@@ -67,14 +29,17 @@ config CROS_EC_RAM_SIZE
default 0x0000f800
config FLASH_SIZE
- default 512
+ default 1024 if SOC_NPCX7M6FB
+ default 512 if SOC_NPCX7M6FC || SOC_NPCX7M7FC
config CROS_EC_RO_MEM_OFF
default 0x0
-# Image size limited by 1/2 Flash size (256 KiB)
+# NPCX796FB/NPCX796FC: Image size limited by code RAM size (192 KiB)
+# NPCX797FC: Image size limited by 1/2 Flash size (256 KiB)
config CROS_EC_RO_SIZE
- default 0x40000
+ default 0x30000 if SOC_NPCX7M6FB || SOC_NPCX7M6FC
+ default 0x40000 if SOC_NPCX7M7FC
# RW firmware in program memory - Identical to RO, only one image loaded at a
# time.
@@ -82,8 +47,7 @@ config CROS_EC_RW_MEM_OFF
default 0x0
config CROS_EC_RW_SIZE
- default 0x40000
-
-endif # SOC_NPCX7M7FC
+ default 0x30000 if SOC_NPCX7M6FB || SOC_NPCX7M6FC
+ default 0x40000 if SOC_NPCX7M7FC
endif # SOC_SERIES_NPCX7
diff --git a/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx9 b/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx9
index cc41bb408f..5fd1fbd308 100644
--- a/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx9
+++ b/zephyr/app/ec/chip/arm/nuvoton_npcx/Kconfig.npcx9
@@ -8,15 +8,15 @@
if SOC_SERIES_NPCX9
-if SOC_NPCX9M3F
-
#
# NPCX993F: 512 KiB Flash, 256 KiB code RAM, 64 KiB data RAM
+# NPCX996F: 512 KiB Flash, 192 KiB code RAM, 64 KiB data RAM
#
-# Code RAM base for NPCX993F
+# Code RAM base for NPCX9 series
config CROS_EC_PROGRAM_MEMORY_BASE
- default 0x10080000
+ default 0x10080000 if SOC_NPCX9M3F
+ default 0x10090000 if SOC_NPCX9M6F
config CROS_EC_RAM_BASE
default 0x200c0000
@@ -33,16 +33,19 @@ config FLASH_SIZE
config CROS_EC_RO_MEM_OFF
default 0x0
-# Image size limited by 1/2 Flash size (256 KiB) and code RAM size (256 KiB)
+# NPCX993F: Image size limited by 1/2 Flash size (256 KiB) and
+# code RAM size (256 KiB)
+# NPCX996F: Image size limited by code RAM size (192 KiB)
+
config CROS_EC_RO_SIZE
- default 0x40000
+ default 0x40000 if SOC_NPCX9M3F
+ default 0x30000 if SOC_NPCX9M6F
config CROS_EC_RW_MEM_OFF
- default 0x40000
+ default 0x0
config CROS_EC_RW_SIZE
- default 0x40000
-
-endif # SOC_NPCX9M3F
+ default 0x40000 if SOC_NPCX9M3F
+ default 0x30000 if SOC_NPCX9M6F
endif # SOC_SERIES_NPCX9
diff --git a/zephyr/boards/arm/npcx_evb/Kconfig.board b/zephyr/boards/arm/npcx_evb/Kconfig.board
new file mode 100644
index 0000000000..0ac4a80833
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/Kconfig.board
@@ -0,0 +1,18 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Note: this Zephyr board more closely represents the Chrome OS
+# concept of a baseboard. Zephyr boards and Chrome OS boards do not
+# have a 1:1 mapping.
+config BOARD_NPCX7_EVB
+ bool "NPCX7 Evaluation Board"
+ depends on SOC_NPCX7M6FB || SOC_NPCX7M6FC || SOC_NPCX7M7FC
+ # Allow generating initial 0 line coverage.
+ select HAS_COVERAGE_SUPPORT
+
+config BOARD_NPCX9_EVB
+ bool "NPCX9 Evaluation Board"
+ depends on SOC_NPCX9M3F || SOC_NPCX9M6F
+ # Allow generating initial 0 line coverage.
+ select HAS_COVERAGE_SUPPORT
diff --git a/zephyr/boards/arm/npcx_evb/Kconfig.defconfig b/zephyr/boards/arm/npcx_evb/Kconfig.defconfig
new file mode 100644
index 0000000000..c0c874ad26
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/Kconfig.defconfig
@@ -0,0 +1,7 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config BOARD
+ default "npcx7_evb" if BOARD_NPCX7_EVB
+ default "npcx9_evb" if BOARD_NPCX9_EVB
diff --git a/zephyr/boards/arm/npcx_evb/npcx7_evb.dts b/zephyr/boards/arm/npcx_evb/npcx7_evb.dts
new file mode 100644
index 0000000000..c20589d637
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/npcx7_evb.dts
@@ -0,0 +1,22 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/dts-v1/;
+
+#include <cros/nuvoton/npcx7.dtsi>
+
+/*
+ * #include <nuvoton/npcx7m6fb.dtsi>
+ * #include <nuvoton/npcx7m6fc.dtsi>
+ * #include <nuvoton/npcx7m7fc.dtsi>
+ */
+#include <nuvoton/npcx7m6fc.dtsi>
+#include "npcx_evb.dtsi"
+
+&uart1 {
+ status = "okay";
+ current-speed = <115200>;
+ pinctrl-0 = <&altc_uart1_sl2>; /* Use UART1_SL2 ie. PIN64.65 */
+};
diff --git a/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
new file mode 100644
index 0000000000..7491ae09df
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
@@ -0,0 +1,34 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Zephyr Kernel Configuration
+CONFIG_SOC_SERIES_NPCX7=y
+# NPCX7 soc list
+# CONFIG_SOC_NPCX7M6FB
+# CONFIG_SOC_NPCX7M6FC
+# CONFIG_SOC_NPCX7M7FC
+CONFIG_SOC_NPCX7M6FC=y
+
+# Platform Configuration
+CONFIG_BOARD_NPCX7_EVB=y
+
+# Serial Drivers
+CONFIG_SERIAL=y
+CONFIG_UART_INTERRUPT_DRIVEN=y
+
+# Enable console
+CONFIG_CONSOLE=y
+CONFIG_UART_CONSOLE=y
+
+# Pinmux Driver
+CONFIG_PINMUX=y
+
+# GPIO Controller
+CONFIG_GPIO=y
+
+# Clock configuration
+CONFIG_CLOCK_CONTROL=y
+
+# WATCHDOG configuration
+CONFIG_WATCHDOG=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx9_evb.dts b/zephyr/boards/arm/npcx_evb/npcx9_evb.dts
new file mode 100644
index 0000000000..4ab68cdde1
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/npcx9_evb.dts
@@ -0,0 +1,21 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/dts-v1/;
+
+#include <cros/nuvoton/npcx9.dtsi>
+
+/*
+ * #include <nuvoton/npcx9m3f.dtsi>
+ * #include <nuvoton/npcx9m6f.dtsi>
+ */
+#include <nuvoton/npcx9m6f.dtsi>
+#include "npcx_evb.dtsi"
+
+&uart1 {
+ status = "okay";
+ current-speed = <115200>;
+ pinctrl-0 = <&altj_cr_sin1_sl2 &altj_cr_sout1_sl2>;
+};
diff --git a/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
new file mode 100644
index 0000000000..cfb3a263e8
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
@@ -0,0 +1,33 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Zephyr Kernel Configuration
+CONFIG_SOC_SERIES_NPCX9=y
+# NPCX9 soc list
+# CONFIG_SOC_NPCX9M3F
+# CONFIG_SOC_NPCX9M6F
+CONFIG_SOC_NPCX9M6F=y
+
+# Platform Configuration
+CONFIG_BOARD_NPCX9_EVB=y
+
+# Serial Drivers
+CONFIG_SERIAL=y
+CONFIG_UART_INTERRUPT_DRIVEN=y
+
+# Enable console
+CONFIG_CONSOLE=y
+CONFIG_UART_CONSOLE=y
+
+# Pinmux Driver
+CONFIG_PINMUX=y
+
+# GPIO Controller
+CONFIG_GPIO=y
+
+# Clock configuration
+CONFIG_CLOCK_CONTROL=y
+
+# WATCHDOG configuration
+CONFIG_WATCHDOG=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi
new file mode 100644
index 0000000000..65c1ab7e68
--- /dev/null
+++ b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi
@@ -0,0 +1,17 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <dt-bindings/gpio_defines.h>
+
+/ {
+ model = "Nuvoton NPCX Evaluation Board";
+
+ chosen {
+ zephyr,sram = &sram0;
+ zephyr,console = &uart1;
+ zephyr,shell-uart = &uart1;
+ zephyr,flash = &flash0;
+ };
+};
diff --git a/zephyr/boards/arm/trogdor/trogdor.dts b/zephyr/boards/arm/trogdor/trogdor.dts
index 4bfbaca14d..f5e50d9466 100644
--- a/zephyr/boards/arm/trogdor/trogdor.dts
+++ b/zephyr/boards/arm/trogdor/trogdor.dts
@@ -39,20 +39,21 @@
ec-mkbp-host-event-wakeup-mask {
compatible = "ec-wake-mask-event";
- wakeup-mask = <(HOST_EVENT_LID_OPEN | \
- HOST_EVENT_POWER_BUTTON | \
- HOST_EVENT_AC_CONNECTED | \
- HOST_EVENT_AC_DISCONNECTED | \
- HOST_EVENT_HANG_DETECT | \
- HOST_EVENT_RTC | \
- HOST_EVENT_MODE_CHANGE | \
- HOST_EVENT_DEVICE)>;
+ wakeup-mask = <(
+ HOST_EVENT_MASK(HOST_EVENT_LID_OPEN) |
+ HOST_EVENT_MASK(HOST_EVENT_POWER_BUTTON) |
+ HOST_EVENT_MASK(HOST_EVENT_AC_CONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_AC_DISCONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_HANG_DETECT) |
+ HOST_EVENT_MASK(HOST_EVENT_RTC) |
+ HOST_EVENT_MASK(HOST_EVENT_MODE_CHANGE) |
+ HOST_EVENT_MASK(HOST_EVENT_DEVICE))>;
};
ec-mkbp-event-wakeup-mask {
compatible = "ec-wake-mask-event";
- wakeup-mask = <(MKBP_EVENT_KEY_MATRIX | \
- MKBP_EVENT_HOST_EVENT | \
+ wakeup-mask = <(MKBP_EVENT_KEY_MATRIX |
+ MKBP_EVENT_HOST_EVENT |
MKBP_EVENT_SENSOR_FIFO)>;
};
diff --git a/zephyr/boards/riscv/asurada/asurada.dts b/zephyr/boards/riscv/asurada/asurada.dts
index f5c4cc3cfe..2ad8fbbc14 100644
--- a/zephyr/boards/riscv/asurada/asurada.dts
+++ b/zephyr/boards/riscv/asurada/asurada.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/adc/adc.h>
#include <dt-bindings/gpio_defines.h>
#include <it8xxx2.dtsi>
+#include <dt-bindings/wake_mask_event_defines.h>
/ {
model = "Google Asurada Baseboard";
@@ -21,6 +22,23 @@
zephyr,flash-controller = &flashctrl;
};
+ ec-mkbp-host-event-wakeup-mask {
+ compatible = "ec-wake-mask-event";
+ wakeup-mask = <(
+ HOST_EVENT_MASK(HOST_EVENT_AC_CONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_AC_DISCONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_LID_OPEN) |
+ HOST_EVENT_MASK(HOST_EVENT_POWER_BUTTON) |
+ HOST_EVENT_MASK(HOST_EVENT_HANG_DETECT) |
+ HOST_EVENT_MASK(HOST_EVENT_MODE_CHANGE))>;
+ };
+
+ ec-mkbp-event-wakeup-mask {
+ compatible = "ec-wake-mask-event";
+ wakeup-mask = <(MKBP_EVENT_KEY_MATRIX |
+ MKBP_EVENT_HOST_EVENT)>;
+ };
+
named-adc-channels {
compatible = "named-adc-channels";
@@ -72,62 +90,74 @@
i2c-port = <&i2c0>;
enum-name = "I2C_PORT_POWER";
label = "POWER";
+ physical-port = <0>;
};
battery {
i2c-port = <&i2c0>;
remote-port = <0>;
enum-name = "I2C_PORT_BATTERY";
label = "BATTERY";
+ physical-port = <0>;
};
eeprom {
i2c-port = <&i2c0>;
enum-name = "I2C_PORT_EEPROM";
label = "EEPROM";
+ physical-port = <0>;
};
charger {
i2c-port = <&i2c0>;
enum-name = "I2C_PORT_CHARGER";
label = "CHARGER";
+ physical-port = <0>;
};
i2c_sensor: sensor {
i2c-port = <&i2c1>;
enum-name = "I2C_PORT_SENSOR";
label = "SENSOR";
+ physical-port = <1>;
};
i2c-accel {
i2c-port = <&i2c1>;
enum-name = "I2C_PORT_ACCEL";
label = "ACCEL";
+ physical-port = <1>;
};
ppc0 {
i2c-port = <&i2c2>;
enum-name = "I2C_PORT_PPC0";
label = "PPC0";
+ physical-port = <2>;
};
ppc1 {
i2c-port = <&i2c4>;
enum-name = "I2C_PORT_PPC1";
label = "PPC1";
+ physical-port = <4>;
};
usb-c0 {
i2c-port = <&i2c2>;
enum-name = "I2C_PORT_USB_C0";
label = "USB_C0";
+ physical-port = <2>;
};
usb-c1 {
i2c-port = <&i2c4>;
enum-name = "I2C_PORT_USB_C1";
label = "USB_C1";
+ physical-port = <4>;
};
usb-mux0 {
i2c-port = <&i2c2>;
enum-name = "I2C_PORT_USB_MUX0";
label = "USB_MUX0";
+ physical-port = <2>;
};
usb-mux1 {
i2c-port = <&i2c4>;
enum-name = "I2C_PORT_USB_MUX1";
label = "USB_MUX1";
+ physical-port = <4>;
};
};
diff --git a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts
index 89ef56bc4c..de7d41abe7 100644
--- a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts
+++ b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts
@@ -119,6 +119,11 @@
label = "I2C_E_SDA";
};
+ spi0_cs {
+ gpios = <&gpiom 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>;
+ enum-name = "GPIO_SPI0_CS";
+ label = "SPI0_CS";
+ };
};
named-adc-channels {
diff --git a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
index 0c0391afe7..49184cb6fd 100644
--- a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
+++ b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
@@ -14,6 +14,7 @@
#include <drivers/pinmux.h>
#include <dt-bindings/pinctrl/it8xxx2-pinctrl.h>
+#include "chipset.h"
#include "console.h"
#include "host_command.h"
@@ -105,25 +106,36 @@ static void spi_bad_received_data(int count)
static void spi_response_host_data(uint8_t *out_msg_addr, int tx_size)
{
- /* Tx FIFO reset and count monitor reset */
- IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR;
- /* CPU Tx FIFO1 and FIFO2 access */
- IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA;
-
- for (int i = 0; i < tx_size; i += 4) {
- /* Write response data from out_msg buffer to Tx FIFO */
- IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i);
- }
-
/*
- * After writing data to Tx FIFO is finished, this bit will
- * be to indicate the SPI slave controller.
+ * Protect sequence of filling response packet for host.
+ * This will ensure CPU access FIFO is disabled at SPI end interrupt no
+ * matter the interrupt is triggered before or after the sequence.
*/
- IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS;
- /* End Tx FIFO access */
- IT83XX_SPI_TXRXFAR = 0;
- /* SPI slave read Tx FIFO */
- IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF;
+ unsigned int key = irq_lock();
+
+ if (shi_state == SPI_STATE_PROCESSING) {
+ /* Tx FIFO reset and count monitor reset */
+ IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR;
+ /* CPU Tx FIFO1 and FIFO2 access */
+ IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA;
+
+ for (int i = 0; i < tx_size; i += 4) {
+ /* Write response data from out_msg buffer to Tx FIFO */
+ IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i);
+ }
+
+ /*
+ * After writing data to Tx FIFO is finished, this bit will
+ * be to indicate the SPI slave controller.
+ */
+ IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS;
+ /* End Tx FIFO access */
+ IT83XX_SPI_TXRXFAR = 0;
+ /* SPI slave read Tx FIFO */
+ IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF;
+ }
+
+ irq_unlock(key);
}
/*
@@ -213,9 +225,6 @@ static void spi_parse_header(void)
spi_packet.response_size = 0;
spi_packet.driver_result = EC_RES_SUCCESS;
- /* Move to processing state */
- spi_set_state(SPI_STATE_PROCESSING);
-
/* Go to common-layer to handle request */
host_packet_receive(&spi_packet);
} else {
@@ -234,6 +243,8 @@ static void shi_ite_int_handler(const void *arg)
* EC responded data, then AP ended the transaction.
*/
if (IT83XX_SPI_ISR & IT83XX_SPI_ENDDETECTINT) {
+ /* Disable CPU access Rx FIFO to clock in data from AP again */
+ IT83XX_SPI_TXRXFAR = 0;
/* Ready to receive */
spi_set_state(SPI_STATE_READY_TO_RECV);
/*
@@ -254,10 +265,21 @@ static void shi_ite_int_handler(const void *arg)
if (IT83XX_SPI_RX_VLISR & IT83XX_SPI_RVLI) {
/* write clear slave status */
IT83XX_SPI_RX_VLISR = IT83XX_SPI_RVLI;
+ /* Move to processing state */
+ spi_set_state(SPI_STATE_PROCESSING);
/* Parse header for version of spi-protocol */
spi_parse_header();
}
+}
+void spi_event(enum gpio_signal signal)
+{
+ if (chipset_in_state(CHIPSET_STATE_ON)) {
+ /* Move to processing state */
+ spi_set_state(SPI_STATE_PROCESSING);
+ /* Disable idle task deep sleep bit of SPI in S0. */
+ /* TODO(b:185176098): disable_sleep(SLEEP_MASK_SPI); */
+ }
}
/*
@@ -331,6 +353,9 @@ static int cros_shi_ite_init(const struct device *dev)
IRQ_CONNECT(DT_INST_IRQN(0), 0, shi_ite_int_handler, 0, 0);
irq_enable(DT_INST_IRQN(0));
+ /* Enable SPI chip select pin interrupt */
+ gpio_enable_interrupt(GPIO_SPI0_CS);
+
return 0;
}
SYS_INIT(cros_shi_ite_init, POST_KERNEL, 52);
diff --git a/zephyr/dts/bindings/cros_mkbp_event/ec-mkbp-event.yaml b/zephyr/dts/bindings/cros_mkbp_event/ec-mkbp-event.yaml
index c8f5a0c376..73f0e8fdca 100644
--- a/zephyr/dts/bindings/cros_mkbp_event/ec-mkbp-event.yaml
+++ b/zephyr/dts/bindings/cros_mkbp_event/ec-mkbp-event.yaml
@@ -14,3 +14,16 @@ properties:
description:
Define the MKBP or host events that will wake up the application
processor from suspend mode.
+ HOST_EVENT_MASK should be used for ec-mkbp-host-event-wakeup-mask e.g.
+ ec-mkbp-host-event-wakeup-mask {
+ compatible = "ec-wake-mask-event";
+ wakeup-mask = <(
+ HOST_EVENT_MASK(HOST_EVENT_LID_OPEN) |
+ HOST_EVENT_MASK(HOST_EVENT_POWER_BUTTON) |
+ HOST_EVENT_MASK(HOST_EVENT_AC_CONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_AC_DISCONNECTED) |
+ HOST_EVENT_MASK(HOST_EVENT_HANG_DETECT) |
+ HOST_EVENT_MASK(HOST_EVENT_RTC) |
+ HOST_EVENT_MASK(HOST_EVENT_MODE_CHANGE) |
+ HOST_EVENT_MASK(HOST_EVENT_DEVICE))>;
+ };
diff --git a/zephyr/dts/bindings/emul/zephyr,tcs3400.yaml b/zephyr/dts/bindings/emul/zephyr,tcs3400.yaml
new file mode 100644
index 0000000000..a4474ec279
--- /dev/null
+++ b/zephyr/dts/bindings/emul/zephyr,tcs3400.yaml
@@ -0,0 +1,44 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description: Zephyr ALS TCS3400 light sensor i2c emulator
+
+compatible: "zephyr,tcs3400"
+
+include: base.yaml
+
+properties:
+ device-id:
+ type: string
+ required: false
+ enum:
+ - TCS340015_DEVICE_ID
+ - TCS340037_DEVICE_ID
+ default: TCS340015_DEVICE_ID
+ description: Device ID that is set in the register.
+
+ revision:
+ type: int
+ required: false
+ default: 0
+ description: Wafer die revision level that is set in the register.
+
+ error-on-ro-write:
+ type: boolean
+ description:
+ Flag indicating if error should be generated when read only register
+ is being written.
+
+ error-on-reserved-bit-write:
+ type: boolean
+ description:
+ Flag indicating if error should be generated when reserved bit
+ is being written.
+
+ error-on-msb-first-access:
+ type: boolean
+ description:
+ Flag indicating if error should be generated when MSB register of
+ accelerometer value is accessed before LSB and shadowing is enabled
+ at the same time.
diff --git a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
index 3838ca6fc9..a7d5232599 100644
--- a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
+++ b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
@@ -51,3 +51,11 @@ properties:
description:
Human readable string describing the device (used as device_get_binding()
argument).
+ physical-port:
+ type: int
+ # TODO: Change the field to true once all boards' named-i2c-ports support
+ # this property.
+ required: false
+ description:
+ In the named-i2c-ports, it's a number indicated an i2c device
+ (eg. battery, charger, etc.) connected to which soc's i2c port.
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt
index d0d4bce0f1..500d1e8b2f 100644
--- a/zephyr/emul/CMakeLists.txt
+++ b/zephyr/emul/CMakeLists.txt
@@ -9,3 +9,4 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_PPC_SYV682X emul_syv682x.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi160.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_BMI emul_bmi260.c)
+zephyr_library_sources_ifdef(CONFIG_EMUL_TCS3400 emul_tcs3400.c)
diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig
index 76b4cb5566..b4461213be 100644
--- a/zephyr/emul/Kconfig
+++ b/zephyr/emul/Kconfig
@@ -33,3 +33,15 @@ config EMUL_BMI
Enable the BMI emulator. This driver use emulated I2C bus.
It is used to test bmi 160 and 260 drivers. Emulators API is
available in zephyr/include/emul/emul_bmi.h
+
+config EMUL_TCS3400
+ bool "TCS3400 emulator"
+ help
+ Enable the TCS3400 light sensor. This driver use emulated I2C bus.
+ It is used to test als_tcs3400 driver. It supports reading sensor
+ values which are correctly scaled using current gain and integration
+ time configuration, switching between IR and clear sensor and
+ clearing status register using clear interrupt registers. Other
+ TCS3400 registers support read and write with optional checking
+ of proper access to reserved bits. Emulators API is available in
+ zephyr/include/emul/emul_tcs3400.h
diff --git a/zephyr/emul/emul_tcs3400.c b/zephyr/emul/emul_tcs3400.c
new file mode 100644
index 0000000000..ea2e2e7690
--- /dev/null
+++ b/zephyr/emul/emul_tcs3400.c
@@ -0,0 +1,858 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#define DT_DRV_COMPAT zephyr_tcs3400
+
+#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
+#include <logging/log.h>
+LOG_MODULE_REGISTER(emul_tcs);
+
+#include <device.h>
+#include <emul.h>
+#include <drivers/i2c.h>
+#include <drivers/i2c_emul.h>
+
+#include "emul/emul_tcs3400.h"
+
+#include "driver/als_tcs3400.h"
+
+/**
+ * Describe if there is no ongoing I2C message or if there is message handled
+ * at the moment (last message doesn't ended with stop or write is not followed
+ * by read).
+ */
+enum tcs_emul_msg_state {
+ TCS_EMUL_NONE_MSG,
+ TCS_EMUL_IN_WRITE,
+ TCS_EMUL_IN_READ
+};
+
+/** Run-time data used by the emulator */
+struct tcs_emul_data {
+ /** I2C emulator detail */
+ struct i2c_emul emul;
+ /** TCS3400 device being emulated */
+ const struct device *i2c;
+ /** Configuration information */
+ const struct tcs_emul_cfg *cfg;
+
+ /** Current state of emulated TCS3400 registers */
+ uint8_t reg[TCS_EMUL_REG_COUNT];
+ /** Return IR value instead of clear */
+ bool ir_select;
+ /** Internal values of light sensor registers */
+ int red;
+ int green;
+ int blue;
+ int clear;
+ int ir;
+
+ /** ID registers value */
+ uint8_t revision;
+ uint8_t id;
+
+ /** Return error when trying to write to RO register */
+ bool error_on_ro_write;
+ /** Return error when trying to write 1 to reserved bit */
+ bool error_on_rsvd_write;
+ /** Return error when trying to access MSB before LSB */
+ bool error_on_msb_first;
+ /**
+ * Flag set when LSB register is accessed and cleared when MSB is
+ * accessed. Allows to track order of accessing data registers
+ */
+ bool lsb_r_read;
+ bool lsb_g_read;
+ bool lsb_b_read;
+ bool lsb_c_ir_read;
+
+ /** Current state of I2C bus (if emulator is handling message) */
+ enum tcs_emul_msg_state msg_state;
+ /** Number of already handled bytes in ongoing message */
+ int msg_byte;
+ /** Register selected in last write command */
+ uint8_t cur_reg;
+ /** Value of data byte in ongoing write message */
+ uint8_t write_byte;
+
+ /** Custom write function called on I2C write opperation */
+ tcs_emul_write_func write_func;
+ /** Data passed to custom write function */
+ void *write_func_data;
+ /** Custom read function called on I2C read opperation */
+ tcs_emul_read_func read_func;
+ /** Data passed to custom read function */
+ void *read_func_data;
+
+ /** Control if read should fail on given register */
+ int read_fail_reg;
+ /** Control if write should fail on given register */
+ int write_fail_reg;
+
+ /** Mutex used to control access to emulator data */
+ struct k_mutex data_mtx;
+};
+
+/** Static configuration for the emulator */
+struct tcs_emul_cfg {
+ /** Label of the I2C bus this emulator connects to */
+ const char *i2c_label;
+ /** Pointer to run-time data */
+ struct tcs_emul_data *data;
+ /** Address of TCS3400 on i2c bus */
+ uint16_t addr;
+};
+
+/** Check description in emul_tcs3400.h */
+int tcs_emul_lock_data(struct i2c_emul *emul, k_timeout_t timeout)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ return k_mutex_lock(&data->data_mtx, timeout);
+}
+
+/** Check description in emul_tcs3400.h */
+int tcs_emul_unlock_data(struct i2c_emul *emul)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ return k_mutex_unlock(&data->data_mtx);
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_write_func(struct i2c_emul *emul,
+ tcs_emul_write_func func, void *data)
+{
+ struct tcs_emul_data *emul_data;
+
+ emul_data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ emul_data->write_func = func;
+ emul_data->write_func_data = data;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_read_func(struct i2c_emul *emul,
+ tcs_emul_read_func func, void *data)
+{
+ struct tcs_emul_data *emul_data;
+
+ emul_data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ emul_data->read_func = func;
+ emul_data->read_func_data = data;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_reg(struct i2c_emul *emul, int reg, uint8_t val)
+{
+ struct tcs_emul_data *data;
+
+ if (reg < TCS_EMUL_FIRST_REG || reg > TCS_EMUL_LAST_REG) {
+ return;
+ }
+
+ reg -= TCS_EMUL_FIRST_REG;
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->reg[reg] = val;
+}
+
+/** Check description in emul_tcs3400.h */
+uint8_t tcs_emul_get_reg(struct i2c_emul *emul, int reg)
+{
+ struct tcs_emul_data *data;
+
+ if (reg < TCS_EMUL_FIRST_REG || reg > TCS_EMUL_LAST_REG) {
+ return 0;
+ }
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ reg -= TCS_EMUL_FIRST_REG;
+
+ return data->reg[reg];
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_read_fail_reg(struct i2c_emul *emul, int reg)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->read_fail_reg = reg;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_write_fail_reg(struct i2c_emul *emul, int reg)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->write_fail_reg = reg;
+}
+
+/** Check description in emul_tcs3400.h */
+int tcs_emul_get_val(struct i2c_emul *emul, enum tcs_emul_axis axis)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ switch (axis) {
+ case TCS_EMUL_R:
+ return data->red;
+ case TCS_EMUL_G:
+ return data->green;
+ case TCS_EMUL_B:
+ return data->blue;
+ case TCS_EMUL_C:
+ return data->clear;
+ case TCS_EMUL_IR:
+ return data->ir;
+ }
+
+ return 0;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_val(struct i2c_emul *emul, enum tcs_emul_axis axis, int val)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ switch (axis) {
+ case TCS_EMUL_R:
+ data->red = val;
+ break;
+ case TCS_EMUL_G:
+ data->green = val;
+ break;
+ case TCS_EMUL_B:
+ data->blue = val;
+ break;
+ case TCS_EMUL_C:
+ data->clear = val;
+ break;
+ case TCS_EMUL_IR:
+ data->ir = val;
+ break;
+ }
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_err_on_ro_write(struct i2c_emul *emul, bool set)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->error_on_ro_write = set;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_err_on_rsvd_write(struct i2c_emul *emul, bool set)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->error_on_rsvd_write = set;
+}
+
+/** Check description in emul_tcs3400.h */
+void tcs_emul_set_err_on_msb_first(struct i2c_emul *emul, bool set)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ data->error_on_msb_first = set;
+}
+
+/** Mask reserved bits in registers of TCS3400 */
+static const uint8_t tcs_emul_rsvd_mask[] = {
+ [TCS_I2C_ENABLE - TCS_EMUL_FIRST_REG] = 0xa4,
+ [TCS_I2C_ATIME - TCS_EMUL_FIRST_REG] = 0x00,
+ [0x2] = 0xff, /* Reserved */
+ [TCS_I2C_WTIME - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_AILTL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_AILTH - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_AIHTL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_AIHTH - TCS_EMUL_FIRST_REG] = 0x00,
+ [0x8 ... 0xb] = 0xff, /* Reserved */
+ [TCS_I2C_PERS - TCS_EMUL_FIRST_REG] = 0xf0,
+ [TCS_I2C_CONFIG - TCS_EMUL_FIRST_REG] = 0x81,
+ [0xe] = 0xff, /* Reserved */
+ [TCS_I2C_CONTROL - TCS_EMUL_FIRST_REG] = 0xfc,
+ [TCS_I2C_AUX - TCS_EMUL_FIRST_REG] = 0xdf,
+ [TCS_I2C_REVID - TCS_EMUL_FIRST_REG] = 0xf0,
+ [TCS_I2C_ID - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_STATUS - TCS_EMUL_FIRST_REG] = 0x6e,
+ [TCS_I2C_CDATAL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_CDATAH - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_RDATAL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_RDATAH - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_GDATAL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_GDATAH - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_BDATAL - TCS_EMUL_FIRST_REG] = 0x00,
+ [TCS_I2C_BDATAH - TCS_EMUL_FIRST_REG] = 0x00,
+};
+
+/**
+ * @brief Reset registers to default values
+ *
+ * @param emul Pointer to TCS3400 emulator
+ */
+static void tcs_emul_reset(struct i2c_emul *emul)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ data->reg[TCS_I2C_ENABLE - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_ATIME - TCS_EMUL_FIRST_REG] = 0xff;
+ data->reg[TCS_I2C_WTIME - TCS_EMUL_FIRST_REG] = 0xff;
+ data->reg[TCS_I2C_AILTL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_AILTH - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_AIHTL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_AIHTH - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_PERS - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_CONFIG - TCS_EMUL_FIRST_REG] = 0x40;
+ data->reg[TCS_I2C_CONTROL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_AUX - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_REVID - TCS_EMUL_FIRST_REG] = data->revision;
+ data->reg[TCS_I2C_ID - TCS_EMUL_FIRST_REG] = data->id;
+ data->reg[TCS_I2C_STATUS - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_CDATAL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_CDATAH - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_RDATAL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_RDATAH - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_GDATAL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_GDATAH - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_BDATAL - TCS_EMUL_FIRST_REG] = 0x00;
+ data->reg[TCS_I2C_BDATAH - TCS_EMUL_FIRST_REG] = 0x00;
+
+ data->ir_select = false;
+}
+
+/**
+ * @brief Convert gain in format of CONTROL register to multiplyer
+ *
+ * @param control Value of CONTROL register
+ *
+ * @return gain by which messured value should be multiplied
+ */
+static int tcs_emul_get_gain(uint8_t control)
+{
+ switch (control & TCS_I2C_CONTROL_MASK) {
+ case 0:
+ return 1;
+ case 1:
+ return 4;
+ case 2:
+ return 16;
+ case 3:
+ return 64;
+ default:
+ return -1;
+ }
+}
+
+/**
+ * @brief Convert number of cycles in format of ATIME register
+ *
+ * @param atime Value of ATIME register
+ *
+ * @return cycles count that should be used to obtain light sensor values
+ */
+static int tcs_emul_get_cycles(uint8_t atime)
+{
+ return TCS_EMUL_MAX_CYCLES - (int)atime;
+}
+
+/**
+ * @brief Clear all interrupt registers
+ *
+ * @param emul Pointer to TCS3400 emulator
+ */
+static void tcs_emul_clear_int(struct i2c_emul *emul)
+{
+ struct tcs_emul_data *data;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ data->reg[TCS_I2C_STATUS - TCS_EMUL_FIRST_REG] = 0x00;
+}
+
+/**
+ * @brief Handle I2C write message. It is checked if accessed register isn't RO
+ * and reserved bits are set to 0. Write set value of reg field of TCS
+ * emulator data ignoring reserved bits and write only bits. Some
+ * commands are handled specialy. Before any handling, custom function
+ * is called if provided.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register which is written
+ * @param val Value being written to @p reg
+ *
+ * @return 0 on success
+ * @return -EIO on error
+ */
+static int tcs_emul_handle_write(struct i2c_emul *emul, int reg, uint8_t val)
+{
+ struct tcs_emul_data *data;
+ int ret;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ if (data->write_func) {
+ ret = data->write_func(emul, reg, val, data->write_func_data);
+ if (ret < 0) {
+ return -EIO;
+ } else if (ret == 0) {
+ return 0;
+ }
+ }
+
+ if (data->write_fail_reg == reg ||
+ data->write_fail_reg == TCS_EMUL_FAIL_ALL_REG) {
+ return -EIO;
+ }
+
+ /* Register is in data->reg */
+ if (reg >= TCS_EMUL_FIRST_REG && reg <= TCS_EMUL_LAST_REG) {
+ if (reg >= TCS_I2C_REVID && reg <= TCS_I2C_BDATAH) {
+ if (data->error_on_ro_write) {
+ LOG_ERR("Writing to reg 0x%x which is RO", reg);
+ return -EIO;
+ }
+
+ return 0;
+ }
+
+ if (reg == TCS_I2C_CONFIG && data->error_on_rsvd_write &&
+ !(BIT(6) & val)) {
+ LOG_ERR("CONFIG reg bit 6 is write as 6 (writing 0x%x)",
+ val);
+ return -EIO;
+ }
+
+ reg -= TCS_EMUL_FIRST_REG;
+ if (data->error_on_rsvd_write &&
+ tcs_emul_rsvd_mask[reg] & val) {
+ LOG_ERR("Writing 0x%x to reg 0x%x with rsvd mask 0x%x",
+ val, reg + TCS_EMUL_FIRST_REG,
+ tcs_emul_rsvd_mask[reg]);
+ return -EIO;
+ }
+
+ /* Ignore all reserved bits */
+ val &= ~tcs_emul_rsvd_mask[reg];
+ val |= data->reg[reg] & tcs_emul_rsvd_mask[reg];
+
+ data->reg[reg] = val;
+
+ return 0;
+ }
+
+ switch (reg) {
+ case TCS_I2C_IR:
+ if (data->error_on_rsvd_write && 0x7f & val) {
+ LOG_ERR("Writing 0x%x to reg 0x%x with rsvd mask 0x7f",
+ val, reg);
+ return -EIO;
+ }
+ data->ir_select = !!(val & BIT(7));
+ break;
+ case TCS_I2C_IFORCE:
+ /* Interrupt generate is not supported */
+ break;
+ case TCS_I2C_CICLEAR:
+ case TCS_I2C_AICLEAR:
+ tcs_emul_clear_int(emul);
+ break;
+ default:
+ /* Assume that other registers are RO */
+ if (data->error_on_ro_write) {
+ LOG_ERR("Writing to reg 0x%x which is RO (unknown)",
+ reg);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Get set light sensor value for given register using internal
+ * state @p val. In case of accessing MSB check if LSB was accessed first
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg LSB or MSB register address. LSB has to be aligned to 2
+ * @param lsb_read Pointer to variable which represent if last access to this
+ * accelerometer value was through LSB register
+ * @param lsb True if now accessing LSB, Flase if now accessing MSB
+ * @param val Internal value of accessed light sensor
+ *
+ * @return 0 on success
+ * @return -EIO when accessing MSB before LSB
+ */
+static int tcs_emul_get_reg_val(struct i2c_emul *emul, int reg,
+ bool *lsb_read, bool lsb, unsigned int val)
+{
+ struct tcs_emul_data *data;
+ uint64_t reg_val;
+ int msb_reg;
+ int lsb_reg;
+ int cycles;
+ int gain;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ if (lsb) {
+ *lsb_read = 1;
+ } else {
+ /*
+ * If error on first accessing MSB is set and LSB wasn't
+ * accessed before, then return error.
+ */
+ if (data->error_on_msb_first && !(*lsb_read)) {
+ return -EIO;
+ }
+ *lsb_read = 0;
+ /* LSB read should set correct value */
+ return 0;
+ }
+
+ lsb_reg = (reg - TCS_EMUL_FIRST_REG) & ~(0x1);
+ msb_reg = (reg - TCS_EMUL_FIRST_REG) | 0x1;
+
+ gain = tcs_emul_get_gain(data->reg[TCS_I2C_CONTROL -
+ TCS_EMUL_FIRST_REG]);
+ cycles = tcs_emul_get_cycles(data->reg[TCS_I2C_ATIME -
+ TCS_EMUL_FIRST_REG]);
+ /*
+ * Internal value is with 256 cycles and x64 gain, so divide it to get
+ * registers value
+ */
+ reg_val = (uint64_t)val * cycles * gain / TCS_EMUL_MAX_CYCLES /
+ TCS_EMUL_MAX_GAIN;
+
+ if (reg_val > UINT16_MAX) {
+ reg_val = UINT16_MAX;
+ }
+
+ data->reg[lsb_reg] = reg_val & 0xff;
+ data->reg[msb_reg] = (reg_val >> 8) & 0xff;
+
+ return 0;
+}
+
+/**
+ * @brief Handle I2C read message. Response is obtained from reg field of TCS
+ * emul data. When accessing light sensor value, register data is first
+ * computed using internal emulator state. Before default handler, custom
+ * user read function is called if provided.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register address to read
+ * @param buf Pointer where resultat should be stored
+ *
+ * @return 0 on success
+ * @return -EIO on error
+ */
+static int tcs_emul_handle_read(struct i2c_emul *emul, int reg, char *buf)
+{
+ struct tcs_emul_data *data;
+ unsigned int c_ir;
+ int ret;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+
+ if (data->read_func) {
+ ret = data->read_func(emul, reg, data->read_func_data);
+ if (ret < 0) {
+ return -EIO;
+ } else if (ret == 0) {
+ /* Immediately return value set by custom function */
+ *buf = data->reg[reg - TCS_EMUL_FIRST_REG];
+
+ return 0;
+ }
+ }
+
+ if (data->read_fail_reg == reg ||
+ data->read_fail_reg == TCS_EMUL_FAIL_ALL_REG) {
+ return -EIO;
+ }
+
+ if ((reg < TCS_EMUL_FIRST_REG || reg > TCS_EMUL_LAST_REG) &&
+ reg != TCS_I2C_IR) {
+ LOG_ERR("Accessing register 0x%x which cannot be read", reg);
+ return -EIO;
+ }
+
+ switch (reg) {
+ case TCS_I2C_CDATAL:
+ /* Shouldn't fail for LSB */
+ c_ir = data->ir_select ? data->ir : data->clear;
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_c_ir_read,
+ true, c_ir);
+ break;
+ case TCS_I2C_CDATAH:
+ c_ir = data->ir_select ? data->ir : data->clear;
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_c_ir_read,
+ false, c_ir);
+ if (ret) {
+ LOG_ERR("MSB C read before LSB C");
+ return -EIO;
+ }
+ break;
+ case TCS_I2C_RDATAL:
+ /* Shouldn't fail for LSB */
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_r_read,
+ true, data->red);
+ break;
+ case TCS_I2C_RDATAH:
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_r_read,
+ false, data->red);
+ if (ret) {
+ LOG_ERR("MSB R read before LSB R");
+ return -EIO;
+ }
+ break;
+ case TCS_I2C_GDATAL:
+ /* Shouldn't fail for LSB */
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_g_read,
+ true, data->green);
+ break;
+ case TCS_I2C_GDATAH:
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_g_read,
+ false, data->green);
+ if (ret) {
+ LOG_ERR("MSB G read before LSB G");
+ return -EIO;
+ }
+ break;
+ case TCS_I2C_BDATAL:
+ /* Shouldn't fail for LSB */
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_b_read,
+ true, data->blue);
+ break;
+ case TCS_I2C_BDATAH:
+ ret = tcs_emul_get_reg_val(emul, reg, &data->lsb_b_read,
+ false, data->blue);
+ if (ret) {
+ LOG_ERR("MSB B read before LSB B");
+ return -EIO;
+ }
+ break;
+ case TCS_I2C_IR:
+ *buf = data->ir_select ? BIT(7) : 0;
+
+ return 0;
+ }
+
+ *buf = data->reg[reg - TCS_EMUL_FIRST_REG];
+
+ return 0;
+}
+
+/**
+ * @biref Emulate an I2C transfer to a TCS3400 light sensor
+ *
+ * This handles simple reads and writes
+ *
+ * @param emul I2C emulation information
+ * @param msgs List of messages to process
+ * @param num_msgs Number of messages to process
+ * @param addr Address of the I2C target device
+ *
+ * @retval 0 If successful
+ * @retval -EIO General input / output error
+ */
+static int tcs_emul_transfer(struct i2c_emul *emul, struct i2c_msg *msgs,
+ int num_msgs, int addr)
+{
+ const struct tcs_emul_cfg *cfg;
+ struct tcs_emul_data *data;
+ unsigned int len;
+ int ret, i, reg;
+ bool read;
+
+ data = CONTAINER_OF(emul, struct tcs_emul_data, emul);
+ cfg = data->cfg;
+
+ if (cfg->addr != addr) {
+ LOG_ERR("Address mismatch, expected %02x, got %02x", cfg->addr,
+ addr);
+ return -EIO;
+ }
+
+ i2c_dump_msgs("emul", msgs, num_msgs, addr);
+
+ for (; num_msgs > 0; num_msgs--, msgs++) {
+ read = msgs->flags & I2C_MSG_READ;
+
+ switch (data->msg_state) {
+ case TCS_EMUL_NONE_MSG:
+ data->msg_byte = 0;
+ break;
+ case TCS_EMUL_IN_WRITE:
+ if (read) {
+ /* Finish write command */
+ if (data->msg_byte == 2) {
+ k_mutex_lock(&data->data_mtx,
+ K_FOREVER);
+ ret = tcs_emul_handle_write(emul,
+ data->cur_reg,
+ data->write_byte);
+ k_mutex_unlock(&data->data_mtx);
+ if (ret) {
+ return -EIO;
+ }
+ }
+ data->msg_byte = 0;
+ }
+ break;
+ case TCS_EMUL_IN_READ:
+ if (!read) {
+ data->msg_byte = 0;
+ }
+ break;
+ }
+ data->msg_state = read ? TCS_EMUL_IN_READ : TCS_EMUL_IN_WRITE;
+
+ if (msgs->flags & I2C_MSG_STOP) {
+ data->msg_state = TCS_EMUL_NONE_MSG;
+ }
+
+ if (!read) {
+ /* Dispatch write command */
+ for (i = 0; i < msgs->len; i++) {
+ switch (data->msg_byte) {
+ case 0:
+ data->cur_reg = msgs->buf[i];
+ break;
+ case 1:
+ data->write_byte = msgs->buf[i];
+ break;
+ default:
+ data->msg_state = TCS_EMUL_NONE_MSG;
+ LOG_ERR("Too long write command");
+ return -EIO;
+ }
+ data->msg_byte++;
+ }
+
+ /* Execute write command */
+ if (msgs->flags & I2C_MSG_STOP && data->msg_byte == 2) {
+ k_mutex_lock(&data->data_mtx, K_FOREVER);
+ ret = tcs_emul_handle_write(emul, data->cur_reg,
+ data->write_byte);
+ k_mutex_unlock(&data->data_mtx);
+ if (ret) {
+ return -EIO;
+ }
+ }
+ } else {
+ /* Dispatch read command */
+ for (i = 0; i < msgs->len; i++) {
+ reg = data->cur_reg + data->msg_byte;
+ data->msg_byte++;
+
+ k_mutex_lock(&data->data_mtx, K_FOREVER);
+ ret = tcs_emul_handle_read(emul, reg,
+ &(msgs->buf[i]));
+ k_mutex_unlock(&data->data_mtx);
+ if (ret) {
+ return -EIO;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Device instantiation */
+
+static struct i2c_emul_api tcs_emul_api = {
+ .transfer = tcs_emul_transfer,
+};
+
+/**
+ * @brief Set up a new TCS3400 emulator
+ *
+ * This should be called for each TCS3400 device that needs to be
+ * emulated. It registers it with the I2C emulation controller.
+ *
+ * @param emul Emulation information
+ * @param parent Device to emulate
+ *
+ * @return 0 indicating success (always)
+ */
+static int tcs_emul_init(const struct emul *emul,
+ const struct device *parent)
+{
+ const struct tcs_emul_cfg *cfg = emul->cfg;
+ struct tcs_emul_data *data = cfg->data;
+ int ret;
+
+ data->emul.api = &tcs_emul_api;
+ data->emul.addr = cfg->addr;
+ data->i2c = parent;
+ data->cfg = cfg;
+ k_mutex_init(&data->data_mtx);
+
+ ret = i2c_emul_register(parent, emul->dev_label, &data->emul);
+
+ tcs_emul_reset(&data->emul);
+
+ return ret;
+}
+
+#define TCS3400_EMUL(n) \
+ static struct tcs_emul_data tcs_emul_data_##n = { \
+ .revision = DT_INST_PROP(n, revision), \
+ .id = DT_ENUM_TOKEN(DT_DRV_INST(n), device_id), \
+ .error_on_ro_write = DT_INST_PROP(n, error_on_ro_write),\
+ .error_on_rsvd_write = DT_INST_PROP(n, \
+ error_on_reserved_bit_write), \
+ .error_on_msb_first = DT_INST_PROP(n, \
+ error_on_msb_first_access), \
+ .lsb_c_ir_read = 0, \
+ .lsb_r_read = 0, \
+ .lsb_g_read = 0, \
+ .lsb_b_read = 0, \
+ .msg_state = TCS_EMUL_NONE_MSG, \
+ .cur_reg = 0, \
+ .write_func = NULL, \
+ .read_func = NULL, \
+ .write_fail_reg = TCS_EMUL_NO_FAIL_REG, \
+ .read_fail_reg = TCS_EMUL_NO_FAIL_REG, \
+ }; \
+ \
+ static const struct tcs_emul_cfg tcs_emul_cfg_##n = { \
+ .i2c_label = DT_INST_BUS_LABEL(n), \
+ .data = &tcs_emul_data_##n, \
+ .addr = DT_INST_REG_ADDR(n), \
+ }; \
+ EMUL_DEFINE(tcs_emul_init, DT_DRV_INST(n), &tcs_emul_cfg_##n)
+
+DT_INST_FOREACH_STATUS_OKAY(TCS3400_EMUL)
+
+#define TCS3400_EMUL_CASE(n) \
+ case DT_INST_DEP_ORD(n): return &tcs_emul_data_##n.emul;
+
+/** Check description in emul_tcs3400.h */
+struct i2c_emul *tcs_emul_get(int ord)
+{
+ switch (ord) {
+ DT_INST_FOREACH_STATUS_OKAY(TCS3400_EMUL_CASE)
+
+ default:
+ return NULL;
+ }
+}
diff --git a/zephyr/include/dt-bindings/wake_mask_event_defines.h b/zephyr/include/dt-bindings/wake_mask_event_defines.h
index 80be063279..0413fa249c 100644
--- a/zephyr/include/dt-bindings/wake_mask_event_defines.h
+++ b/zephyr/include/dt-bindings/wake_mask_event_defines.h
@@ -33,6 +33,8 @@
#define MKBP_EVENT_ONLINE_CALIBRATION BIT(11)
#define MKBP_EVENT_PCHG BIT(12)
+#define HOST_EVENT_MASK(event) ((event) >> 1)
+
#define HOST_EVENT_NONE BIT(0)
#define HOST_EVENT_LID_CLOSED BIT(1)
#define HOST_EVENT_LID_OPEN BIT(2)
diff --git a/zephyr/include/emul/emul_tcs3400.h b/zephyr/include/emul/emul_tcs3400.h
new file mode 100644
index 0000000000..41f3577658
--- /dev/null
+++ b/zephyr/include/emul/emul_tcs3400.h
@@ -0,0 +1,255 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for TCS3400 emulator
+ */
+
+#ifndef __EMUL_TCS3400_H
+#define __EMUL_TCS3400_H
+
+#include <emul.h>
+#include <drivers/i2c.h>
+#include <drivers/i2c_emul.h>
+
+/**
+ * @brief TCS3400 emulator backend API
+ * @defgroup tcs_emul TCS3400 emulator
+ * @{
+ *
+ * TCS3400 emulator supports responses to all write and read I2C messages.
+ * Light sensor data registers are obtained from internal emulator state, gain
+ * and acquisition time. Application may alter emulator state:
+ *
+ * - define a devicetree overlay file to set which inadvisable driver behaviour
+ * should be treated as error and emulated device ID and revision
+ * - call @ref tcs_emul_set_read_func and @ref tcs_emul_set_write_func to setup
+ * custom handlers for I2C messages
+ * - call @ref tcs_emul_set_reg and @ref tcs_emul_get_reg to set and get value
+ * of TCS3400 registers
+ * - call @ref tcs_emul_set_val and @ref tcs_emul_set_val to set and get
+ * light sensor value
+ * - call tcs_emul_set_err_* to change emulator behaviour on inadvisable driver
+ * behaviour
+ * - call @ref tcs_emul_set_read_fail_reg and @ref tcs_emul_set_write_fail_reg
+ * to configure emulator to fail on given register read or write
+ */
+
+/**
+ * Maximum number of integration cycles (when ATIME is zero). Value read from
+ * sensor is proportional to number of integration cycles, e.g. with constant
+ * light, value obtainded with 128 cycles will be two times smaller than value
+ * obtained with 256 cycles.
+ */
+#define TCS_EMUL_MAX_CYCLES 256
+/**
+ * Maximum gain supported by TCS3400. Value read from sensor is multiplied by
+ * gain selected in CONTROL register.
+ */
+#define TCS_EMUL_MAX_GAIN 64
+
+/**
+ * Emulator units are value returned with gain x64 and 256 integration cycles.
+ * Max value is 1024 returned when gain is x1 and 1 integration cycle. Max value
+ * represented in emulator units is 1024 * 64 * 256
+ */
+#define TCS_EMUL_MAX_VALUE (1024 * TCS_EMUL_MAX_GAIN * TCS_EMUL_MAX_CYCLES)
+
+/** Axis argument used in @ref tcs_emul_set_val @ref tcs_emul_get_val */
+enum tcs_emul_axis {
+ TCS_EMUL_R,
+ TCS_EMUL_G,
+ TCS_EMUL_B,
+ TCS_EMUL_C,
+ TCS_EMUL_IR,
+};
+
+/**
+ * Emulator saves only those registers in memory. IR select is stored sparately
+ * and other registers are write only.
+ */
+#define TCS_EMUL_FIRST_REG TCS_I2C_ENABLE
+#define TCS_EMUL_LAST_REG TCS_I2C_BDATAH
+#define TCS_EMUL_REG_COUNT (TCS_EMUL_LAST_REG - TCS_EMUL_FIRST_REG + 1)
+
+/**
+ * Special register values used in @ref tcs_emul_set_read_fail_reg and
+ * @ref tcs_emul_set_write_fail_reg
+ */
+#define TCS_EMUL_FAIL_ALL_REG (-1)
+#define TCS_EMUL_NO_FAIL_REG (-2)
+
+/**
+ * @brief Get pointer to TCS3400 emulator using device tree order number.
+ *
+ * @param ord Device tree order number obtained from DT_DEP_ORD macro
+ *
+ * @return Pointer to TCS3400 emulator
+ */
+struct i2c_emul *tcs_emul_get(int ord);
+
+/**
+ * @brief Custom function type that is used as user-defined callback in read
+ * I2C messages handling.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Address which is now accessed by read command
+ * @param data Pointer to custom user data
+ *
+ * @return 0 on success. Value of @p reg should be set by @ref tcs_emul_set_reg
+ * @return 1 continue with normal TCS3400 emulator handler
+ * @return negative on error
+ */
+typedef int (*tcs_emul_read_func)(struct i2c_emul *emul, int reg, void *data);
+
+/**
+ * @brief Custom function type that is used as user-defined callback in write
+ * I2C messages handling.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Address which is now accessed by write command
+ * @param val Value which is being written to @p reg
+ * @param data Pointer to custom user data
+ *
+ * @return 0 on success
+ * @return 1 continue with normal TCS3400 emulator handler
+ * @return negative on error
+ */
+typedef int (*tcs_emul_write_func)(struct i2c_emul *emul, int reg, uint8_t val,
+ void *data);
+
+/**
+ * @brief Lock access to TCS3400 properties. After acquiring lock, user
+ * may change emulator behaviour in multi-thread setup.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param timeout Timeout in getting lock
+ *
+ * @return k_mutex_lock return code
+ */
+int tcs_emul_lock_data(struct i2c_emul *emul, k_timeout_t timeout);
+
+/**
+ * @brief Unlock access to TCS3400 properties.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ *
+ * @return k_mutex_unlock return code
+ */
+int tcs_emul_unlock_data(struct i2c_emul *emul);
+
+/**
+ * @brief Set write handler for I2C messages. This function is called before
+ * generic handler.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param func Pointer to custom function
+ * @param data User data passed on call of custom function
+ */
+void tcs_emul_set_write_func(struct i2c_emul *emul, tcs_emul_write_func func,
+ void *data);
+
+/**
+ * @brief Set read handler for I2C messages. This function is called before
+ * generic handler.
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param func Pointer to custom function
+ * @param data User data passed on call of custom function
+ */
+void tcs_emul_set_read_func(struct i2c_emul *emul, tcs_emul_read_func func,
+ void *data);
+
+/**
+ * @brief Set value of given register of TCS3400
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register address which value will be changed
+ * @param val New value of the register
+ */
+void tcs_emul_set_reg(struct i2c_emul *emul, int reg, uint8_t val);
+
+/**
+ * @brief Get value of given register of TCS3400
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register address
+ *
+ * @return Value of the register
+ */
+uint8_t tcs_emul_get_reg(struct i2c_emul *emul, int reg);
+
+/**
+ * @brief Setup fail on read of given register of TCS3400
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register address or one of special values (TCS_EMUL_FAIL_ALL_REG,
+ * TCS_EMUL_NO_FAIL_REG)
+ */
+void tcs_emul_set_read_fail_reg(struct i2c_emul *emul, int reg);
+
+/**
+ * @brief Setup fail on write of given register of TCS3400
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param reg Register address or one of special values (TCS_EMUL_FAIL_ALL_REG,
+ * TCS_EMUL_NO_FAIL_REG)
+ */
+void tcs_emul_set_write_fail_reg(struct i2c_emul *emul, int reg);
+
+/**
+ * @brief Get internal value of light sensor for given axis
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param axis Axis to access
+ *
+ * @return Value of given axis with gain x64 and 256 integration cycles
+ */
+int tcs_emul_get_val(struct i2c_emul *emul, enum tcs_emul_axis axis);
+
+/**
+ * @brief Set internal value of light sensor for given axis
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param axis Axis to access
+ * @param val New value of light sensor for given axis with gain x64 and
+ * 256 integration cycles
+ */
+void tcs_emul_set_val(struct i2c_emul *emul, enum tcs_emul_axis axis, int val);
+
+/**
+ * @brief Set if error should be generated when read only register is being
+ * written
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param set Check for this error
+ */
+void tcs_emul_set_err_on_ro_write(struct i2c_emul *emul, bool set);
+
+/**
+ * @brief Set if error should be generated when reserved bits of register are
+ * not set to 0 on write I2C message
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param set Check for this error
+ */
+void tcs_emul_set_err_on_rsvd_write(struct i2c_emul *emul, bool set);
+
+/**
+ * @brief Set if error should be generated when MSB register is accessed before
+ * LSB register
+ *
+ * @param emul Pointer to TCS3400 emulator
+ * @param set Check for this error
+ */
+void tcs_emul_set_err_on_msb_first(struct i2c_emul *emul, bool set);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_TCS3400_H */
diff --git a/zephyr/projects/asurada/hayato/CMakeLists.txt b/zephyr/projects/asurada/hayato/CMakeLists.txt
index f82b2be970..c4703e4024 100644
--- a/zephyr/projects/asurada/hayato/CMakeLists.txt
+++ b/zephyr/projects/asurada/hayato/CMakeLists.txt
@@ -18,6 +18,7 @@ set(PLATFORM_EC_BOARD "${PLATFORM_EC}/board/hayato" CACHE PATH
zephyr_library_sources(
"${PLATFORM_EC_BASEBOARD}/board_chipset.c"
"${PLATFORM_EC_BASEBOARD}/board_id.c"
+ "${PLATFORM_EC_BASEBOARD}/regulator.c"
"${PLATFORM_EC_BASEBOARD}/usbc_config.c"
"${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c")
diff --git a/zephyr/projects/asurada/hayato/include/gpio_map.h b/zephyr/projects/asurada/hayato/include/gpio_map.h
index 8e29b7268c..5f01f290d2 100644
--- a/zephyr/projects/asurada/hayato/include/gpio_map.h
+++ b/zephyr/projects/asurada/hayato/include/gpio_map.h
@@ -66,7 +66,9 @@
GPIO_INT(GPIO_PMIC_EC_PWRGD, \
GPIO_INT_EDGE_BOTH, power_signal_interrupt) \
GPIO_INT(GPIO_AP_EC_WARM_RST_REQ, \
- GPIO_INT_EDGE_RISING, chipset_reset_request_interrupt)
+ GPIO_INT_EDGE_RISING, chipset_reset_request_interrupt) \
+ GPIO_INT(GPIO_SPI0_CS, \
+ GPIO_INT_EDGE_FALLING, spi_event)
#define GPIO_EN_PP5000 GPIO_EN_PP5000_A
diff --git a/zephyr/projects/asurada/hayato/prj.conf b/zephyr/projects/asurada/hayato/prj.conf
index 1101bfe2d9..82a3d5a926 100644
--- a/zephyr/projects/asurada/hayato/prj.conf
+++ b/zephyr/projects/asurada/hayato/prj.conf
@@ -10,36 +10,6 @@ CONFIG_SHIMMED_TASKS=y
CONFIG_KERNEL_SHELL=y
CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y
-# Sensors
-CONFIG_PLATFORM_EC_MOTIONSENSE=y
-CONFIG_PLATFORM_EC_ACCEL_FIFO=y
-CONFIG_PLATFORM_EC_ACCEL_INTERRUPTS=y
-CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y
-CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y
-CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y
-CONFIG_PLATFORM_EC_LID_ANGLE=y
-CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y
-CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
-CONFIG_PLATFORM_EC_TABLET_MODE=y
-CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y
-
-# Sensor Drivers
-CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y
-CONFIG_PLATFORM_EC_ACCEL_LIS2DW12_AS_BASE=y
-CONFIG_PLATFORM_EC_ACCELGYRO_BMI160=y
-CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
-
-# TODO(b/180980668): bring these features up
-CONFIG_LTO=n
-CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
-CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n
-CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n
-CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=n
-CONFIG_PLATFORM_EC_HOSTCMD=y
-CONFIG_PLATFORM_EC_SWITCH=y
-CONFIG_PLATFORM_EC_VBOOT=n
-CONFIG_PLATFORM_EC_VBOOT_HASH=n
-
# Battery
CONFIG_HAS_TASK_USB_CHG_P1=y
CONFIG_PLATFORM_EC_BATTERY=y
@@ -65,7 +35,36 @@ CONFIG_PLATFORM_EC_CHARGER_PSYS_READ=y
CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10
# BOARD_RS1
CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=20
+
+# Host Commands
+CONFIG_PLATFORM_EC_HOSTCMD=y
+CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y
+CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y
CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=y
+CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y
+CONFIG_PLATFORM_EC_HOSTCMD_REGULATOR=y
+
+# MKBP event mask
+CONFIG_PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK=y
+CONFIG_PLATFORM_EC_MKBP_HOST_EVENT_WAKEUP_MASK=y
+
+# Sensors
+CONFIG_PLATFORM_EC_MOTIONSENSE=y
+CONFIG_PLATFORM_EC_ACCEL_FIFO=y
+CONFIG_PLATFORM_EC_ACCEL_INTERRUPTS=y
+CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y
+CONFIG_PLATFORM_EC_LID_ANGLE=y
+CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y
+CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
+CONFIG_PLATFORM_EC_SWITCH=y
+CONFIG_PLATFORM_EC_TABLET_MODE=y
+CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y
+
+# Sensor Drivers
+CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y
+CONFIG_PLATFORM_EC_ACCEL_LIS2DW12_AS_BASE=y
+CONFIG_PLATFORM_EC_ACCELGYRO_BMI160=y
+CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
# USB-A
CONFIG_PLATFORM_EC_USB_A_PORT_COUNT=1
@@ -78,6 +77,7 @@ CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y
CONFIG_PLATFORM_EC_BC12_DETECT_MT6360=y
CONFIG_PLATFORM_EC_BC12_SINGLE_DRIVER=n
CONFIG_PLATFORM_EC_MT6360_BC12_GPIO=y
+CONFIG_PLATFORM_EC_SMBUS_PEC=y
CONFIG_PLATFORM_EC_USBC_PPC_DEDICATED_INT=y
CONFIG_PLATFORM_EC_USBC_PPC_SYV682C=y
CONFIG_PLATFORM_EC_USBC_PPC_SYV682X=y
@@ -98,9 +98,23 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_TCPCI=y
CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_PPC=y
CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_ADC_EACH_PORT=y
CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB_CUSTOM_HOOK=y
+CONFIG_PLATFORM_EC_USB_PD_DUAL_ROLE_AUTO_TOGGLE=n
+CONFIG_PLATFORM_EC_USB_PD_USB32_DRD=n
+CONFIG_PLATFORM_EC_USB_PD_USB4=n
+CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n
# USB ID
# This is allocated for Asurada
# http://google3/hardware/standards/usb/
# TODO(b/183608112): Move to device tree
CONFIG_PLATFORM_EC_USB_PID=0x5053
+
+# VBoot without EFS2
+CONFIG_PLATFORM_EC_VBOOT=n
+CONFIG_PLATFORM_EC_VBOOT_HASH=y
+
+# TODO(b/180980668): bring these features up
+CONFIG_LTO=n
+CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
+CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n
+CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt b/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt
index fa503185af..9dcd46db31 100644
--- a/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt
+++ b/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt
@@ -9,25 +9,17 @@ project(herobrine_npcx9)
zephyr_library_include_directories(include)
-set(PLATFORM_EC_BASEBOARD "${PLATFORM_EC}/baseboard/herobrine" CACHE PATH
- "Path to the platform/ec baseboard directory")
-set(PLATFORM_EC_BOARD "${PLATFORM_EC}/board/herobrine_npcx9" CACHE PATH
- "Path to the platform/ec board directory")
-
+# Board specific implementation
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC
- "${PLATFORM_EC_BASEBOARD}/usbc_config.c"
- "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c")
-
+ "src/usbc_config.c"
+ "src/usb_pd_policy.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON
- "${PLATFORM_EC_BOARD}/led.c")
-
-zephyr_library_sources(
- "${PLATFORM_EC_BOARD}/battery.c"
- "${PLATFORM_EC_BOARD}/switchcap.c"
- "${PLATFORM_EC_BOARD}/usbc_config.c")
-
-# Board specific implementation
+ "src/led.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_MOTIONSENSE
"src/sensors.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C
"src/i2c.c")
+
+zephyr_library_sources(
+ "src/battery.c"
+ "src/switchcap.c")
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts b/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts
index e72010af3e..fb8c0d8778 100644
--- a/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts
+++ b/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts
@@ -305,4 +305,33 @@
&gpio_rtc_ec_wake_odl
>;
};
+
+ unused-pins {
+ compatible = "unused-gpios";
+ unused-gpios =
+ <&gpio5 2 0>,
+ <&gpio5 4 0>,
+ <&gpio7 6 0>,
+ <&gpioc 5 0>,
+ <&gpiod 1 0>,
+ <&gpiod 0 0>,
+ <&gpioe 3 0>,
+ <&gpioc 1 0>,
+ <&gpio0 4 0>,
+ <&gpiod 6 0>,
+ <&gpio3 2 0>,
+ <&gpio3 5 0>,
+ <&gpiod 7 0>,
+ <&gpio8 6 0>,
+ <&gpiod 4 0>,
+ <&gpio4 1 0>,
+ <&gpio3 4 0>,
+ <&gpioc 7 0>,
+ <&gpioa 4 0>,
+ <&gpio9 6 0>,
+ <&gpio9 3 0>,
+ <&gpioa 7 0>,
+ <&gpio5 0 0>,
+ <&gpio8 1 0>;
+ };
};
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/battery.c b/zephyr/projects/herobrine/herobrine_npcx9/src/battery.c
new file mode 100644
index 0000000000..f6622f11ee
--- /dev/null
+++ b/zephyr/projects/herobrine/herobrine_npcx9/src/battery.c
@@ -0,0 +1,68 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Battery pack vendor provided charging profile
+ */
+
+#include "battery_fuel_gauge.h"
+#include "common.h"
+#include "util.h"
+
+/*
+ * Battery info for all herobrine_npcx9 battery types. Note that the fields
+ * start_charging_min/max and charging_min/max are not used for the charger.
+ * The effective temperature limits are given by discharging_min/max_c.
+ *
+ * Fuel Gauge (FG) parameters which are used for determining if the battery
+ * is connected, the appropriate ship mode (battery cutoff) command, and the
+ * charge/discharge FETs status.
+ *
+ * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery
+ * register. For some batteries, the charge/discharge FET bits are set when
+ * charging/discharging is active, in other types, these bits set mean that
+ * charging/discharging is disabled. Therefore, in addition to the mask for
+ * these bits, a disconnect value must be specified. Note that for TI fuel
+ * gauge, the charge/discharge FET status is found in Operation Status (0x54),
+ * but a read of Manufacturer Access (0x00) will return the lower 16 bits of
+ * Operation status which contains the FET status bits.
+ *
+ * The assumption for battery types supported is that the charge/discharge FET
+ * status can be read with a sb_read() command and therefore, only the register
+ * address, mask, and disconnect value need to be provided.
+ */
+
+const struct board_batt_params board_battery_info[] = {
+ /* AP16L5J */
+ [BATTERY_AP16L5J] = {
+ .fuel_gauge = {
+ .manuf_name = "PANASONIC",
+ .device_name = "AP16L5J",
+ .ship_mode = {
+ .reg_addr = 0x3A,
+ .reg_data = { 0xC574, 0xC574 },
+ },
+ .fet = {
+ .mfgacc_support = 0,
+ .reg_addr = 0x0,
+ .reg_mask = 0x4000,
+ .disconnect_val = 0x0,
+ }
+ },
+ .batt_info = {
+ .voltage_max = 8800,
+ .voltage_normal = 7700, /* mV */
+ .voltage_min = 6000, /* mV */
+ .precharge_current = 256, /* mA */
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 50,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = -20,
+ .discharging_max_c = 75,
+ },
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT);
+
+const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_AP16L5J;
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/led.c b/zephyr/projects/herobrine/herobrine_npcx9/src/led.c
new file mode 100644
index 0000000000..295c8effeb
--- /dev/null
+++ b/zephyr/projects/herobrine/herobrine_npcx9/src/led.c
@@ -0,0 +1,163 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Power and battery LED control.
+ */
+
+#include "battery.h"
+#include "charge_manager.h"
+#include "charge_state.h"
+#include "chipset.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "led_common.h"
+#include "system.h"
+#include "util.h"
+
+#define BAT_LED_ON 1
+#define BAT_LED_OFF 0
+
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_RIGHT_LED,
+ EC_LED_ID_LEFT_LED,
+};
+
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+
+enum led_color {
+ LED_OFF = 0,
+ LED_AMBER,
+ LED_WHITE,
+ LED_COLOR_COUNT /* Number of colors, not a color itself */
+};
+
+static void side_led_set_color(int port, enum led_color color)
+{
+ gpio_set_level(port ? GPIO_EC_CHG_LED_Y_C1 : GPIO_EC_CHG_LED_Y_C0,
+ (color == LED_AMBER) ? BAT_LED_ON : BAT_LED_OFF);
+ gpio_set_level(port ? GPIO_EC_CHG_LED_W_C1 : GPIO_EC_CHG_LED_W_C0,
+ (color == LED_WHITE) ? BAT_LED_ON : BAT_LED_OFF);
+}
+
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
+}
+
+int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+{
+ int port;
+
+ switch (led_id) {
+ case EC_LED_ID_RIGHT_LED:
+ port = 0;
+ break;
+ case EC_LED_ID_LEFT_LED:
+ port = 1;
+ break;
+ default:
+ return EC_ERROR_PARAM1;
+ }
+
+ if (brightness[EC_LED_COLOR_WHITE] != 0)
+ side_led_set_color(port, LED_WHITE);
+ else if (brightness[EC_LED_COLOR_AMBER] != 0)
+ side_led_set_color(port, LED_AMBER);
+ else
+ side_led_set_color(port, LED_OFF);
+
+ return EC_SUCCESS;
+}
+
+/*
+ * Set active charge port color to the parameter, turn off all others.
+ * If no port is active (-1), turn off all LEDs.
+ */
+static void set_active_port_color(enum led_color color)
+{
+ int port = charge_manager_get_active_charge_port();
+
+ if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED))
+ side_led_set_color(0, (port == 0) ? color : LED_OFF);
+ if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED))
+ side_led_set_color(1, (port == 1) ? color : LED_OFF);
+}
+
+static void board_led_set_battery(void)
+{
+ static int battery_ticks;
+ uint32_t chflags = charge_get_flags();
+
+ battery_ticks++;
+
+ switch (charge_get_state()) {
+ case PWR_STATE_CHARGE:
+ /* Always indicate when charging, even in suspend. */
+ set_active_port_color(LED_AMBER);
+ break;
+ case PWR_STATE_DISCHARGE:
+ if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) {
+ if (charge_get_percent() <= 10)
+ side_led_set_color(0,
+ (battery_ticks & 0x4) ? LED_WHITE : LED_OFF);
+ else
+ side_led_set_color(0, LED_OFF);
+ }
+
+ if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED))
+ side_led_set_color(1, LED_OFF);
+ break;
+ case PWR_STATE_ERROR:
+ set_active_port_color((battery_ticks & 0x2) ?
+ LED_WHITE : LED_OFF);
+ break;
+ case PWR_STATE_CHARGE_NEAR_FULL:
+ set_active_port_color(LED_WHITE);
+ break;
+ case PWR_STATE_IDLE: /* External power connected in IDLE */
+ if (chflags & CHARGE_FLAG_FORCE_IDLE)
+ set_active_port_color((battery_ticks & 0x4) ?
+ LED_AMBER : LED_OFF);
+ else
+ set_active_port_color(LED_WHITE);
+ break;
+ default:
+ /* Other states don't alter LED behavior */
+ break;
+ }
+}
+
+/* Called by hook task every TICK */
+static void led_tick(void)
+{
+ board_led_set_battery();
+}
+DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
+
+void led_control(enum ec_led_id led_id, enum ec_led_state state)
+{
+ enum led_color color;
+
+ if ((led_id != EC_LED_ID_RECOVERY_HW_REINIT_LED) &&
+ (led_id != EC_LED_ID_SYSRQ_DEBUG_LED))
+ return;
+
+ if (state == LED_STATE_RESET) {
+ led_auto_control(EC_LED_ID_LEFT_LED, 1);
+ led_auto_control(EC_LED_ID_RIGHT_LED, 1);
+ board_led_set_battery();
+ return;
+ }
+
+ color = state ? LED_WHITE : LED_OFF;
+
+ led_auto_control(EC_LED_ID_LEFT_LED, 0);
+ led_auto_control(EC_LED_ID_RIGHT_LED, 0);
+
+ side_led_set_color(0, color);
+ side_led_set_color(1, color);
+}
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/switchcap.c b/zephyr/projects/herobrine/herobrine_npcx9/src/switchcap.c
new file mode 100644
index 0000000000..16b0db6ef6
--- /dev/null
+++ b/zephyr/projects/herobrine/herobrine_npcx9/src/switchcap.c
@@ -0,0 +1,22 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gpio.h"
+#include "power/qcom.h"
+
+void board_set_switchcap_power(int enable)
+{
+ gpio_set_level(GPIO_SWITCHCAP_ON, enable);
+}
+
+int board_is_switchcap_enabled(void)
+{
+ return gpio_get_level(GPIO_SWITCHCAP_ON);
+}
+
+int board_is_switchcap_power_good(void)
+{
+ return gpio_get_level(GPIO_SWITCHCAP_PG);
+}
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/usb_pd_policy.c b/zephyr/projects/herobrine/herobrine_npcx9/src/usb_pd_policy.c
new file mode 100644
index 0000000000..87d47c32e2
--- /dev/null
+++ b/zephyr/projects/herobrine/herobrine_npcx9/src/usb_pd_policy.c
@@ -0,0 +1,258 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "charge_manager.h"
+#include "chipset.h"
+#include "console.h"
+#include "gpio.h"
+#include "system.h"
+#include "usb_mux.h"
+#include "usbc_ppc.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+
+int pd_check_vconn_swap(int port)
+{
+ /* In G3, do not allow vconn swap since PP5000 rail is off */
+ return gpio_get_level(GPIO_EN_PP5000);
+}
+
+static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT];
+#if CONFIG_USB_PD_PORT_MAX_COUNT == 1
+static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5};
+#else
+static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5,
+ TYPEC_RP_1A5};
+#endif
+
+static void board_vbus_update_source_current(int port)
+{
+ /* Both port are controlled by PPC SN5S330. */
+ ppc_set_vbus_source_current_limit(port, vbus_rp[port]);
+ ppc_vbus_source_enable(port, vbus_en[port]);
+}
+
+void pd_power_supply_reset(int port)
+{
+ int prev_en;
+
+ prev_en = vbus_en[port];
+
+ /* Disable VBUS */
+ vbus_en[port] = 0;
+ board_vbus_update_source_current(port);
+
+ /* Enable discharge if we were previously sourcing 5V */
+ if (prev_en)
+ pd_set_vbus_discharge(port, 1);
+
+ /* notify host of power info change */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+}
+
+int pd_set_power_supply_ready(int port)
+{
+ /* Disable charging */
+ board_vbus_sink_enable(port, 0);
+
+ pd_set_vbus_discharge(port, 0);
+
+ /* Provide VBUS */
+ vbus_en[port] = 1;
+ board_vbus_update_source_current(port);
+
+ /* notify host of power info change */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+
+ return EC_SUCCESS; /* we are ready */
+}
+
+int board_vbus_source_enabled(int port)
+{
+ return vbus_en[port];
+}
+
+__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
+{
+ vbus_rp[port] = rp;
+ board_vbus_update_source_current(port);
+}
+
+int pd_snk_is_vbus_provided(int port)
+{
+ return tcpm_check_vbus_level(port, VBUS_PRESENT);
+}
+
+/* ----------------- Vendor Defined Messages ------------------ */
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+__override int svdm_dp_config(int port, uint32_t *payload)
+{
+ int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT);
+ uint8_t pin_mode = get_dp_pin_mode(port);
+
+ if (!pin_mode)
+ return 0;
+
+ /*
+ * Defer setting the usb_mux until HPD goes high, svdm_dp_attention().
+ * The AP only supports one DP phy. An external DP mux switches between
+ * the two ports. Should switch those muxes when it is really used,
+ * i.e. HPD high; otherwise, the real use case is preempted, like:
+ * (1) plug a dongle without monitor connected to port-0,
+ * (2) plug a dongle without monitor connected to port-1,
+ * (3) plug a monitor to the port-1 dongle.
+ */
+
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_DP_CONFIG | VDO_OPOS(opos));
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
+ 1, /* DPv1.3 signaling */
+ 2); /* UFP connected */
+ return 2;
+};
+
+__override void svdm_dp_post_config(int port)
+{
+ dp_flags[port] |= DP_FLAGS_DP_ON;
+}
+
+/**
+ * Is the port fine to be muxed its DisplayPort lines?
+ *
+ * Only one port can be muxed to DisplayPort at a time.
+ *
+ * @param port Port number of TCPC.
+ * @return 1 is fine; 0 is bad as other port is already muxed;
+ */
+static int is_dp_muxable(int port)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++)
+ if (i != port) {
+ if (usb_mux_get(i) & USB_PD_MUX_DP_ENABLED)
+ return 0;
+ }
+
+ return 1;
+}
+
+__override int svdm_dp_attention(int port, uint32_t *payload)
+{
+ enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET;
+ int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
+ int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+ int cur_lvl = gpio_get_level(hpd);
+
+ dp_status[port] = payload[1];
+
+ if (!is_dp_muxable(port)) {
+ /* TODO(waihong): Info user? */
+ CPRINTS("p%d: The other port is already muxed.", port);
+ return 0;
+ }
+
+ /*
+ * Initial implementation to handle HPD. Only the first-plugged port
+ * works, i.e. sending HPD signal to AP. The second-plugged port
+ * will be ignored.
+ *
+ * TODO(waihong): Continue the above case, if the first-plugged port
+ * is then unplugged, switch to the second-plugged port and signal AP?
+ */
+ if (lvl) {
+ /*
+ * Enable and switch the DP port selection mux to the
+ * correct port.
+ *
+ * TODO(waihong): Better to move switching DP mux to
+ * the usb_mux abstraction.
+ */
+ gpio_set_level(GPIO_DP_MUX_SEL, port == 1);
+ gpio_set_level(GPIO_DP_MUX_OE_L, 0);
+
+ /* Connect the SBU lines in PPC chip. */
+ if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
+ ppc_set_sbu(port, 1);
+
+ /*
+ * Connect the USB SS/DP lines in TCPC chip.
+ *
+ * When mf_pref not true, still use the dock muxing
+ * because of the board USB-C topology (limited to 2
+ * lanes DP).
+ */
+ usb_mux_set(port, USB_PD_MUX_DOCK,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
+ } else {
+ /* Disconnect the DP port selection mux. */
+ gpio_set_level(GPIO_DP_MUX_OE_L, 1);
+ gpio_set_level(GPIO_DP_MUX_SEL, 0);
+
+ /* Disconnect the SBU lines in PPC chip. */
+ if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
+ ppc_set_sbu(port, 0);
+
+ /* Disconnect the DP but keep the USB SS lines in TCPC chip. */
+ usb_mux_set(port, USB_PD_MUX_USB_ENABLED,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
+ }
+
+ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
+ (irq || lvl))
+ /*
+ * Wake up the AP. IRQ or level high indicates a DP sink is now
+ * present.
+ */
+ pd_notify_dp_alt_mode_entry(port);
+
+ /* Configure TCPC for the HPD event, for proper muxing */
+ usb_mux_hpd_update(port, lvl, irq);
+
+ /* Signal AP for the HPD event, through GPIO to AP */
+ if (irq & cur_lvl) {
+ uint64_t now = get_time().val;
+ /* Wait for the minimum spacing between IRQ_HPD if needed */
+ if (now < svdm_hpd_deadline[port])
+ usleep(svdm_hpd_deadline[port] - now);
+
+ /* Generate IRQ_HPD pulse */
+ gpio_set_level(hpd, 0);
+ usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
+ gpio_set_level(hpd, 1);
+
+ /* Set the minimum time delay (2ms) for the next HPD IRQ */
+ svdm_hpd_deadline[port] = get_time().val +
+ HPD_USTREAM_DEBOUNCE_LVL;
+ } else if (irq & !lvl) {
+ CPRINTF("ERR:HPD:IRQ&LOW\n");
+ return 0;
+ } else {
+ gpio_set_level(hpd, lvl);
+ /* Set the minimum time delay (2ms) for the next HPD IRQ */
+ svdm_hpd_deadline[port] = get_time().val +
+ HPD_USTREAM_DEBOUNCE_LVL;
+ }
+
+ return 1;
+}
+
+__override void svdm_exit_dp_mode(int port)
+{
+ if (is_dp_muxable(port)) {
+ /* Disconnect the DP port selection mux. */
+ gpio_set_level(GPIO_DP_MUX_OE_L, 1);
+ gpio_set_level(GPIO_DP_MUX_SEL, 0);
+
+ /* Signal AP for the HPD low event */
+ usb_mux_hpd_update(port, 0, 0);
+ gpio_set_level(GPIO_DP_HOT_PLUG_DET, 0);
+ }
+}
+#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c b/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c
new file mode 100644
index 0000000000..a3da4b5592
--- /dev/null
+++ b/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c
@@ -0,0 +1,364 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Herobrine board-specific USB-C configuration */
+
+#include "bc12/pi3usb9201_public.h"
+#include "charger.h"
+#include "charger/isl923x_public.h"
+#include "charge_manager.h"
+#include "charge_state.h"
+#include "common.h"
+#include "config.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "ppc/sn5s330_public.h"
+#include "system.h"
+#include "tcpm/ps8xxx_public.h"
+#include "tcpm/tcpci.h"
+#include "timer.h"
+#include "usb_pd.h"
+#include "usb_mux.h"
+#include "usbc_ocp.h"
+#include "usbc_ppc.h"
+
+#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+
+
+/* GPIO Interrupt Handlers */
+void tcpc_alert_event(enum gpio_signal signal)
+{
+ int port = -1;
+
+ switch (signal) {
+ case GPIO_USB_C0_PD_INT_ODL:
+ port = 0;
+ break;
+ case GPIO_USB_C1_PD_INT_ODL:
+ port = 1;
+ break;
+ default:
+ return;
+ }
+
+ schedule_deferred_pd_interrupt(port);
+}
+
+void usb0_evt(enum gpio_signal signal)
+{
+ task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12);
+}
+
+void usb1_evt(enum gpio_signal signal)
+{
+ task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12);
+}
+
+static void usba_oc_deferred(void)
+{
+ /* Use next number after all USB-C ports to indicate the USB-A port */
+ board_overcurrent_event(CONFIG_USB_PD_PORT_MAX_COUNT,
+ !gpio_get_level(GPIO_USB_A0_OC_ODL));
+}
+DECLARE_DEFERRED(usba_oc_deferred);
+
+void usba_oc_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&usba_oc_deferred_data, 0);
+}
+
+void ppc_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_SWCTL_INT_ODL:
+ sn5s330_interrupt(0);
+ break;
+ case GPIO_USB_C1_SWCTL_INT_ODL:
+ sn5s330_interrupt(1);
+ break;
+ default:
+ break;
+ }
+}
+
+const struct charger_config_t chg_chips[] = {
+ {
+ .i2c_port = I2C_PORT_CHARGER,
+ .i2c_addr_flags = ISL923X_ADDR_FLAGS,
+ .drv = &isl923x_drv,
+ },
+};
+
+int charger_profile_override(struct charge_state_data *curr)
+{
+ int usb_mv;
+ int port;
+
+ if (curr->state != ST_CHARGE)
+ return 0;
+
+ /* Lower the max requested voltage to 5V when battery is full. */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF) &&
+ !(curr->batt.flags & BATT_FLAG_BAD_STATUS) &&
+ !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) &&
+ (curr->batt.status & STATUS_FULLY_CHARGED))
+ usb_mv = 5000;
+ else
+ usb_mv = PD_MAX_VOLTAGE_MV;
+
+ if (pd_get_max_voltage() != usb_mv) {
+ CPRINTS("VBUS limited to %dmV", usb_mv);
+ for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++)
+ pd_set_external_voltage_limit(port, usb_mv);
+ }
+
+ return 0;
+}
+
+enum ec_status charger_profile_override_get_param(uint32_t param,
+ uint32_t *value)
+{
+ return EC_RES_INVALID_PARAM;
+}
+
+enum ec_status charger_profile_override_set_param(uint32_t param,
+ uint32_t value)
+{
+ return EC_RES_INVALID_PARAM;
+}/* Power Path Controller */
+struct ppc_config_t ppc_chips[] = {
+ {
+ .i2c_port = I2C_PORT_TCPC0,
+ .i2c_addr_flags = SN5S330_ADDR0_FLAGS,
+ .drv = &sn5s330_drv
+ },
+ {
+ .i2c_port = I2C_PORT_TCPC1,
+ .i2c_addr_flags = SN5S330_ADDR0_FLAGS,
+ .drv = &sn5s330_drv
+ },
+};
+unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+
+/* TCPC mux configuration */
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_TCPC0,
+ .addr_flags = PS8751_I2C_ADDR1_FLAGS,
+ },
+ .drv = &ps8xxx_tcpm_drv,
+ },
+ {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_TCPC1,
+ .addr_flags = PS8751_I2C_ADDR1_FLAGS,
+ },
+ .drv = &ps8xxx_tcpm_drv,
+ },
+};
+
+/*
+ * Port-0/1 USB mux driver.
+ *
+ * The USB mux is handled by TCPC chip and the HPD update is through a GPIO
+ * to AP. But the TCPC chip is also needed to know the HPD status; otherwise,
+ * the mux misbehaves.
+ */
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ {
+ .usb_port = 0,
+ .driver = &tcpci_tcpm_usb_mux_driver,
+ .hpd_update = &ps8xxx_tcpc_update_hpd_status,
+ },
+ {
+ .usb_port = 1,
+ .driver = &tcpci_tcpm_usb_mux_driver,
+ .hpd_update = &ps8xxx_tcpc_update_hpd_status,
+ }
+};
+
+const int usb_port_enable[USB_PORT_COUNT] = {
+ GPIO_EN_USB_A_5V,
+};
+
+/* BC1.2 */
+const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
+ {
+ .i2c_port = I2C_PORT_POWER,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+ {
+ .i2c_port = I2C_PORT_EEPROM,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+};
+
+/* Initialize board USC-C things */
+static void board_init_usbc(void)
+{
+ /* Enable BC1.2 interrupts */
+ gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_L);
+ gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_L);
+
+ /* Enable USB-A overcurrent interrupt */
+ gpio_enable_interrupt(GPIO_USB_A0_OC_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_init_usbc, HOOK_PRIO_DEFAULT);
+
+void board_tcpc_init(void)
+{
+ /* Only reset TCPC if not sysjump */
+ if (!system_jumped_late()) {
+ /* TODO(crosbug.com/p/61098): How long do we need to wait? */
+ board_reset_pd_mcu();
+ }
+
+ /* Enable PPC interrupts */
+ gpio_enable_interrupt(GPIO_USB_C0_SWCTL_INT_ODL);
+
+ /* Enable TCPC interrupts */
+ gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL);
+
+ /*
+ * Initialize HPD to low; after sysjump SOC needs to see
+ * HPD pulse to enable video path
+ */
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
+}
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
+
+void board_reset_pd_mcu(void)
+{
+ cprints(CC_USB, "Resetting TCPCs...");
+ cflush();
+
+ gpio_set_level(GPIO_USB_C0_PD_RST_L, 0);
+ gpio_set_level(GPIO_USB_C1_PD_RST_L, 0);
+ msleep(PS8XXX_RESET_DELAY_MS);
+ gpio_set_level(GPIO_USB_C0_PD_RST_L, 1);
+ gpio_set_level(GPIO_USB_C1_PD_RST_L, 1);
+ msleep(PS8805_FW_INIT_DELAY_MS);
+}
+
+void board_set_tcpc_power_mode(int port, int mode)
+{
+ /* Ignore the "mode" to turn the chip on. We can only do a reset. */
+ if (mode)
+ return;
+
+ board_reset_pd_mcu();
+}
+
+int board_vbus_sink_enable(int port, int enable)
+{
+ /* Both ports are controlled by PPC SN5S330 */
+ return ppc_vbus_sink_enable(port, enable);
+}
+
+int board_is_sourcing_vbus(int port)
+{
+ /* Both ports are controlled by PPC SN5S330 */
+ return ppc_is_sourcing_vbus(port);
+}
+
+void board_overcurrent_event(int port, int is_overcurrented)
+{
+ /* TODO(b/120231371): Notify AP */
+ CPRINTS("p%d: overcurrent!", port);
+}
+
+int board_set_active_charge_port(int port)
+{
+ int is_real_port = (port >= 0 &&
+ port < CONFIG_USB_PD_PORT_MAX_COUNT);
+ int i;
+
+ if (!is_real_port && port != CHARGE_PORT_NONE)
+ return EC_ERROR_INVAL;
+
+ if (port == CHARGE_PORT_NONE) {
+ CPRINTS("Disabling all charging port");
+
+ /* Disable all ports. */
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ /*
+ * Do not return early if one fails otherwise we can
+ * get into a boot loop assertion failure.
+ */
+ if (board_vbus_sink_enable(i, 0))
+ CPRINTS("Disabling p%d sink path failed.", i);
+ }
+
+ return EC_SUCCESS;
+ }
+
+ /* Check if the port is sourcing VBUS. */
+ if (board_is_sourcing_vbus(port)) {
+ CPRINTS("Skip enable p%d", port);
+ return EC_ERROR_INVAL;
+ }
+
+
+ CPRINTS("New charge port: p%d", port);
+
+ /*
+ * Turn off the other ports' sink path FETs, before enabling the
+ * requested charge port.
+ */
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ if (i == port)
+ continue;
+
+ if (board_vbus_sink_enable(i, 0))
+ CPRINTS("p%d: sink path disable failed.", i);
+ }
+
+ /* Enable requested charge port. */
+ if (board_vbus_sink_enable(port, 1)) {
+ CPRINTS("p%d: sink path enable failed.", port);
+ return EC_ERROR_UNKNOWN;
+ }
+
+ return EC_SUCCESS;
+}
+
+void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ /*
+ * Ignore lower charge ceiling on PD transition if our battery is
+ * critical, as we may brownout.
+ */
+ if (supplier == CHARGE_SUPPLIER_PD &&
+ charge_ma < 1500 &&
+ charge_get_percent() < CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON) {
+ CPRINTS("Using max ilim %d", max_ma);
+ charge_ma = max_ma;
+ }
+
+ charge_set_input_current_limit(MAX(charge_ma,
+ CONFIG_CHARGER_INPUT_CURRENT),
+ charge_mv);
+}
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL))
+ if (gpio_get_level(GPIO_USB_C0_PD_RST_L))
+ status |= PD_STATUS_TCPC_ALERT_0;
+ if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL))
+ if (gpio_get_level(GPIO_USB_C1_PD_RST_L))
+ status |= PD_STATUS_TCPC_ALERT_1;
+
+ return status;
+}
diff --git a/zephyr/projects/it8xxx2_evb/include/gpio_map.h b/zephyr/projects/it8xxx2_evb/include/gpio_map.h
index b5b5d22500..c92b71d523 100644
--- a/zephyr/projects/it8xxx2_evb/include/gpio_map.h
+++ b/zephyr/projects/it8xxx2_evb/include/gpio_map.h
@@ -30,6 +30,8 @@
#define EC_CROS_GPIO_INTERRUPTS \
GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \
GPIO_INT(GPIO_POWER_BUTTON_L, \
- GPIO_INT_EDGE_BOTH, power_button_interrupt)
+ GPIO_INT_EDGE_BOTH, power_button_interrupt) \
+ GPIO_INT(GPIO_SPI0_CS, \
+ GPIO_INT_EDGE_FALLING, spi_event)
#endif /* __ZEPHYR_GPIO_MAP_H */
diff --git a/zephyr/projects/it8xxx2_evb/zmake.yaml b/zephyr/projects/it8xxx2_evb/zmake.yaml
index 4cec35bde8..ba536537a5 100644
--- a/zephyr/projects/it8xxx2_evb/zmake.yaml
+++ b/zephyr/projects/it8xxx2_evb/zmake.yaml
@@ -4,6 +4,6 @@
board: it8xxx2_evb
supported-zephyr-versions:
- - v2.5
+ - v2.6
toolchain: coreboot-sdk
output-type: raw
diff --git a/zephyr/projects/npcx_evb/npcx7/CMakeLists.txt b/zephyr/projects/npcx_evb/npcx7/CMakeLists.txt
new file mode 100644
index 0000000000..b48b5d795d
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx7/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+cmake_minimum_required(VERSION 3.13.1)
+set(BOARD_ROOT "${CMAKE_CURRENT_LIST_DIR}/..")
+
+find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
+project(npcx7)
+
+zephyr_include_directories(include)
diff --git a/zephyr/projects/npcx_evb/npcx7/gpio.dts b/zephyr/projects/npcx_evb/npcx7/gpio.dts
new file mode 100644
index 0000000000..3f10215613
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx7/gpio.dts
@@ -0,0 +1,107 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/ {
+ named-gpios {
+ compatible = "named-gpios";
+
+ recovery_l {
+ gpios = <&gpio0 3 (GPIO_INPUT | GPIO_PULL_UP)>;
+ label = "RECOVERY_L";
+ };
+ wp_l {
+ gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_WP_L";
+ label = "WP_L";
+ };
+ ac_present {
+ gpios = <&gpio7 4 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_AC_PRESENT";
+ label = "AC_PRESENT";
+ };
+ power_button_l {
+ gpios = <&gpio7 5 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_POWER_BUTTON_L";
+ label = "POWER_BUTTON_L";
+ };
+ lid_open {
+ gpios = <&gpioa 6 (GPIO_INPUT | GPIO_PULL_DOWN)>;
+ enum-name = "GPIO_LID_OPEN";
+ label = "LID_OPEN";
+ };
+ entering_rw {
+ gpios = <&gpio3 6 GPIO_OUT_LOW>;
+ enum-name = "GPIO_ENTERING_RW";
+ label = "ENTERING_RW";
+ };
+ pch_wake_l {
+ gpios = <&gpio5 0 GPIO_OUT_HIGH>;
+ label = "PCH_WAKE_L";
+ };
+ pgood_fan {
+ gpios = <&gpioc 7 (GPIO_INPUT | GPIO_PULL_UP)>;
+ label = "PGOOD_FAN";
+ };
+ spi_cs_l {
+ gpios = <&gpioa 5 GPIO_OUT_HIGH>;
+ label = "SPI_CS_L";
+ };
+ i2c0_scl0 {
+ gpios = <&gpiob 5 GPIO_ODR_HIGH>;
+ label = "I2C0_SCL0";
+ };
+ i2c0_sda0 {
+ gpios = <&gpiob 4 GPIO_ODR_HIGH>;
+ label = "I2C0_SDA0";
+ };
+ i2c1_scl0 {
+ gpios = <&gpio9 0 GPIO_ODR_HIGH>;
+ label = "I2C1_SCL0";
+ };
+ i2c1_sda0 {
+ gpios = <&gpio8 7 GPIO_ODR_HIGH>;
+ label = "I2C1_SDA0";
+ };
+ i2c2_scl0 {
+ gpios = <&gpio9 2 GPIO_ODR_HIGH>;
+ label = "I2C2_SCL0";
+ };
+ i2c2_sda0 {
+ gpios = <&gpio9 1 GPIO_ODR_HIGH>;
+ label = "I2C2_SDA0";
+ };
+ i2c3_scl0 {
+ gpios = <&gpiod 1 GPIO_ODR_HIGH>;
+ label = "I2C3_SCL0";
+ };
+ i2c3_sda0 {
+ gpios = <&gpiod 0 GPIO_ODR_HIGH>;
+ label = "I2C3_SDA0";
+ };
+ i2c7_sda0 {
+ gpios = <&gpiob 2 GPIO_ODR_HIGH>;
+ label = "I2C7_SDA0";
+ };
+ i2c7_scl0 {
+ gpios = <&gpiob 3 GPIO_ODR_HIGH>;
+ label = "I2C7_SCL0";
+ };
+ board_version1 {
+ gpios = <&gpio6 4 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION1";
+ label = "BOARD_VERSION1";
+ };
+ board_version2 {
+ gpios = <&gpio6 5 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION2";
+ label = "BOARD_VERSION2";
+ };
+ board_version3 {
+ gpios = <&gpio6 6 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION3";
+ label = "BOARD_VERSION3";
+ };
+ };
+};
diff --git a/zephyr/projects/npcx_evb/npcx7/include/gpio_map.h b/zephyr/projects/npcx_evb/npcx7/include/gpio_map.h
new file mode 100644
index 0000000000..8073daad90
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx7/include/gpio_map.h
@@ -0,0 +1,33 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __ZEPHYR_GPIO_MAP_H
+#define __ZEPHYR_GPIO_MAP_H
+
+#include <devicetree.h>
+#include <gpio_signal.h>
+
+/*
+ * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items.
+ *
+ * Each GPIO_INT requires three parameters:
+ * gpio_signal - The enum gpio_signal for the interrupt gpio
+ * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH)
+ * handler - The platform/ec interrupt handler.
+ *
+ * Ensure that this files includes all necessary headers to declare all
+ * referenced handler functions.
+ *
+ * For example, one could use the follow definition:
+ * #define EC_CROS_GPIO_INTERRUPTS \
+ * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print)
+ */
+#define EC_CROS_GPIO_INTERRUPTS \
+ GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \
+ GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \
+ GPIO_INT(GPIO_POWER_BUTTON_L, GPIO_INT_EDGE_BOTH, \
+ power_button_interrupt)
+
+#endif /* __ZEPHYR_GPIO_MAP_H */
diff --git a/zephyr/projects/npcx_evb/npcx7/prj.conf b/zephyr/projects/npcx_evb/npcx7/prj.conf
new file mode 100644
index 0000000000..5bc2922e47
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx7/prj.conf
@@ -0,0 +1,29 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+CONFIG_CROS_EC=y
+CONFIG_PLATFORM_EC=y
+CONFIG_PLATFORM_EC_BRINGUP=y
+CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y
+CONFIG_PLATFORM_EC_LID_SWITCH=y
+CONFIG_PLATFORM_EC_POWER_BUTTON=y
+CONFIG_SHIMMED_TASKS=y
+
+CONFIG_CROS_KB_RAW_NPCX=n
+
+CONFIG_PLATFORM_EC_ADC=n
+CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
+CONFIG_PLATFORM_EC_I2C=n
+CONFIG_PLATFORM_EC_KEYBOARD=n
+CONFIG_PLATFORM_EC_SWITCH=n
+CONFIG_PLATFORM_EC_VBOOT=n
+CONFIG_PLATFORM_EC_VSTORE=n
+
+# Board version is selected over GPIO board ID pins.
+CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=y
+
+# Zephyr feature
+CONFIG_ASSERT=y
+CONFIG_SHELL_MINIMAL=n
+CONFIG_LOG=y
diff --git a/zephyr/projects/npcx_evb/npcx7/zmake.yaml b/zephyr/projects/npcx_evb/npcx7/zmake.yaml
new file mode 100644
index 0000000000..10cb8dffb7
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx7/zmake.yaml
@@ -0,0 +1,11 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+board: npcx7_evb
+dts-overlays:
+ - gpio.dts
+supported-zephyr-versions:
+ - v2.6
+toolchain: coreboot-sdk
+output-type: npcx
diff --git a/zephyr/projects/npcx_evb/npcx9/CMakeLists.txt b/zephyr/projects/npcx_evb/npcx9/CMakeLists.txt
new file mode 100644
index 0000000000..8d605a001c
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx9/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+cmake_minimum_required(VERSION 3.13.1)
+set(BOARD_ROOT "${CMAKE_CURRENT_LIST_DIR}/..")
+
+find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
+project(npcx9)
+
+zephyr_include_directories(include)
diff --git a/zephyr/projects/npcx_evb/npcx9/gpio.dts b/zephyr/projects/npcx_evb/npcx9/gpio.dts
new file mode 100644
index 0000000000..3f10215613
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx9/gpio.dts
@@ -0,0 +1,107 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/ {
+ named-gpios {
+ compatible = "named-gpios";
+
+ recovery_l {
+ gpios = <&gpio0 3 (GPIO_INPUT | GPIO_PULL_UP)>;
+ label = "RECOVERY_L";
+ };
+ wp_l {
+ gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_WP_L";
+ label = "WP_L";
+ };
+ ac_present {
+ gpios = <&gpio7 4 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_AC_PRESENT";
+ label = "AC_PRESENT";
+ };
+ power_button_l {
+ gpios = <&gpio7 5 (GPIO_INPUT | GPIO_PULL_UP)>;
+ enum-name = "GPIO_POWER_BUTTON_L";
+ label = "POWER_BUTTON_L";
+ };
+ lid_open {
+ gpios = <&gpioa 6 (GPIO_INPUT | GPIO_PULL_DOWN)>;
+ enum-name = "GPIO_LID_OPEN";
+ label = "LID_OPEN";
+ };
+ entering_rw {
+ gpios = <&gpio3 6 GPIO_OUT_LOW>;
+ enum-name = "GPIO_ENTERING_RW";
+ label = "ENTERING_RW";
+ };
+ pch_wake_l {
+ gpios = <&gpio5 0 GPIO_OUT_HIGH>;
+ label = "PCH_WAKE_L";
+ };
+ pgood_fan {
+ gpios = <&gpioc 7 (GPIO_INPUT | GPIO_PULL_UP)>;
+ label = "PGOOD_FAN";
+ };
+ spi_cs_l {
+ gpios = <&gpioa 5 GPIO_OUT_HIGH>;
+ label = "SPI_CS_L";
+ };
+ i2c0_scl0 {
+ gpios = <&gpiob 5 GPIO_ODR_HIGH>;
+ label = "I2C0_SCL0";
+ };
+ i2c0_sda0 {
+ gpios = <&gpiob 4 GPIO_ODR_HIGH>;
+ label = "I2C0_SDA0";
+ };
+ i2c1_scl0 {
+ gpios = <&gpio9 0 GPIO_ODR_HIGH>;
+ label = "I2C1_SCL0";
+ };
+ i2c1_sda0 {
+ gpios = <&gpio8 7 GPIO_ODR_HIGH>;
+ label = "I2C1_SDA0";
+ };
+ i2c2_scl0 {
+ gpios = <&gpio9 2 GPIO_ODR_HIGH>;
+ label = "I2C2_SCL0";
+ };
+ i2c2_sda0 {
+ gpios = <&gpio9 1 GPIO_ODR_HIGH>;
+ label = "I2C2_SDA0";
+ };
+ i2c3_scl0 {
+ gpios = <&gpiod 1 GPIO_ODR_HIGH>;
+ label = "I2C3_SCL0";
+ };
+ i2c3_sda0 {
+ gpios = <&gpiod 0 GPIO_ODR_HIGH>;
+ label = "I2C3_SDA0";
+ };
+ i2c7_sda0 {
+ gpios = <&gpiob 2 GPIO_ODR_HIGH>;
+ label = "I2C7_SDA0";
+ };
+ i2c7_scl0 {
+ gpios = <&gpiob 3 GPIO_ODR_HIGH>;
+ label = "I2C7_SCL0";
+ };
+ board_version1 {
+ gpios = <&gpio6 4 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION1";
+ label = "BOARD_VERSION1";
+ };
+ board_version2 {
+ gpios = <&gpio6 5 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION2";
+ label = "BOARD_VERSION2";
+ };
+ board_version3 {
+ gpios = <&gpio6 6 GPIO_INPUT>;
+ enum-name = "GPIO_BOARD_VERSION3";
+ label = "BOARD_VERSION3";
+ };
+ };
+};
diff --git a/zephyr/projects/npcx_evb/npcx9/include/gpio_map.h b/zephyr/projects/npcx_evb/npcx9/include/gpio_map.h
new file mode 100644
index 0000000000..8073daad90
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx9/include/gpio_map.h
@@ -0,0 +1,33 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __ZEPHYR_GPIO_MAP_H
+#define __ZEPHYR_GPIO_MAP_H
+
+#include <devicetree.h>
+#include <gpio_signal.h>
+
+/*
+ * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items.
+ *
+ * Each GPIO_INT requires three parameters:
+ * gpio_signal - The enum gpio_signal for the interrupt gpio
+ * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH)
+ * handler - The platform/ec interrupt handler.
+ *
+ * Ensure that this files includes all necessary headers to declare all
+ * referenced handler functions.
+ *
+ * For example, one could use the follow definition:
+ * #define EC_CROS_GPIO_INTERRUPTS \
+ * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print)
+ */
+#define EC_CROS_GPIO_INTERRUPTS \
+ GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \
+ GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \
+ GPIO_INT(GPIO_POWER_BUTTON_L, GPIO_INT_EDGE_BOTH, \
+ power_button_interrupt)
+
+#endif /* __ZEPHYR_GPIO_MAP_H */
diff --git a/zephyr/projects/npcx_evb/npcx9/prj.conf b/zephyr/projects/npcx_evb/npcx9/prj.conf
new file mode 100644
index 0000000000..a901b00adc
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx9/prj.conf
@@ -0,0 +1,33 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+CONFIG_CROS_EC=y
+CONFIG_PLATFORM_EC=y
+CONFIG_PLATFORM_EC_BRINGUP=y
+CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y
+CONFIG_PLATFORM_EC_LID_SWITCH=y
+CONFIG_PLATFORM_EC_POWER_BUTTON=y
+CONFIG_SHIMMED_TASKS=y
+
+CONFIG_CROS_KB_RAW_NPCX=n
+
+CONFIG_PLATFORM_EC_ADC=n
+CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
+CONFIG_PLATFORM_EC_I2C=n
+CONFIG_PLATFORM_EC_KEYBOARD=n
+CONFIG_PLATFORM_EC_SWITCH=n
+CONFIG_PLATFORM_EC_VBOOT=n
+CONFIG_PLATFORM_EC_VSTORE=n
+
+# Workaround npcx9 A1 chip's bug for download_from_flash API in th booter.
+# This can be removed when A2 chip is available.
+CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y
+
+# Board version is selected over GPIO board ID pins.
+CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=y
+
+# Zephyr feature
+CONFIG_ASSERT=y
+CONFIG_SHELL_MINIMAL=n
+CONFIG_LOG=y
diff --git a/zephyr/projects/npcx_evb/npcx9/zmake.yaml b/zephyr/projects/npcx_evb/npcx9/zmake.yaml
new file mode 100644
index 0000000000..5aaa630542
--- /dev/null
+++ b/zephyr/projects/npcx_evb/npcx9/zmake.yaml
@@ -0,0 +1,11 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+board: npcx9_evb
+dts-overlays:
+ - gpio.dts
+supported-zephyr-versions:
+ - v2.6
+toolchain: coreboot-sdk
+output-type: npcx
diff --git a/zephyr/projects/trogdor/herobrine_npcx7/gpio.dts b/zephyr/projects/trogdor/herobrine_npcx7/gpio.dts
index b4b716d0d7..956db72960 100644
--- a/zephyr/projects/trogdor/herobrine_npcx7/gpio.dts
+++ b/zephyr/projects/trogdor/herobrine_npcx7/gpio.dts
@@ -338,4 +338,33 @@
&gpio_ec_rst_odl
>;
};
+
+ unused-pins {
+ compatible = "unused-gpios";
+ unused-gpios =
+ <&gpio5 1 0>,
+ <&gpiod 0 0>,
+ <&gpiof 3 0>,
+ <&gpio9 4 0>,
+ <&gpio9 7 0>,
+ <&gpioa 7 0>,
+ <&gpiob 0 0>,
+ <&gpioa 5 0>,
+ <&gpio3 5 0>,
+ <&gpio7 2 0>,
+ <&gpio8 1 0>,
+ <&gpio3 7 0>,
+ <&gpio7 6 0>,
+ <&gpio3 4 0>,
+ <&gpioc 5 0>,
+ <&gpio7 3 0>,
+ <&gpiod 7 0>,
+ <&gpioa 3 0>,
+ <&gpio6 2 0>,
+ <&gpio0 4 0>,
+ <&gpio8 3 0>,
+ <&gpiob 1 0>,
+ <&gpio5 0 0>,
+ <&gpiod 3 0>;
+ };
};
diff --git a/zephyr/projects/trogdor/lazor/gpio.dts b/zephyr/projects/trogdor/lazor/gpio.dts
index ff71cea8b6..767ed11969 100644
--- a/zephyr/projects/trogdor/lazor/gpio.dts
+++ b/zephyr/projects/trogdor/lazor/gpio.dts
@@ -390,4 +390,33 @@
&gpio_ec_rst_odl
>;
};
+
+ unused-pins {
+ compatible = "unused-gpios";
+ unused-gpios =
+ <&gpio5 1 0>,
+ <&gpiod 0 0>,
+ <&gpiof 3 0>,
+ <&gpio0 4 0>,
+ <&gpioc 0 0>,
+ <&gpioa 7 0>,
+ <&gpio8 3 0>,
+ <&gpio8 1 0>,
+ <&gpio3 7 0>,
+ <&gpio7 6 0>,
+ <&gpio3 4 0>,
+ <&gpioc 5 0>,
+ <&gpioa 3 0>,
+ <&gpio7 3 0>,
+ <&gpiod 7 0>,
+ <&gpioa 5 0>,
+ <&gpiob 0 0>,
+ <&gpio9 4 0>,
+ <&gpiob 1 0>,
+ <&gpio6 2 0>,
+ <&gpio3 5 0>,
+ <&gpio9 7 0>,
+ <&gpio6 0 0>,
+ <&gpio7 2 0>;
+ };
};
diff --git a/zephyr/projects/trogdor/trogdor/gpio.dts b/zephyr/projects/trogdor/trogdor/gpio.dts
index b4b716d0d7..956db72960 100644
--- a/zephyr/projects/trogdor/trogdor/gpio.dts
+++ b/zephyr/projects/trogdor/trogdor/gpio.dts
@@ -338,4 +338,33 @@
&gpio_ec_rst_odl
>;
};
+
+ unused-pins {
+ compatible = "unused-gpios";
+ unused-gpios =
+ <&gpio5 1 0>,
+ <&gpiod 0 0>,
+ <&gpiof 3 0>,
+ <&gpio9 4 0>,
+ <&gpio9 7 0>,
+ <&gpioa 7 0>,
+ <&gpiob 0 0>,
+ <&gpioa 5 0>,
+ <&gpio3 5 0>,
+ <&gpio7 2 0>,
+ <&gpio8 1 0>,
+ <&gpio3 7 0>,
+ <&gpio7 6 0>,
+ <&gpio3 4 0>,
+ <&gpioc 5 0>,
+ <&gpio7 3 0>,
+ <&gpiod 7 0>,
+ <&gpioa 3 0>,
+ <&gpio6 2 0>,
+ <&gpio0 4 0>,
+ <&gpio8 3 0>,
+ <&gpiob 1 0>,
+ <&gpio5 0 0>,
+ <&gpiod 3 0>;
+ };
};
diff --git a/zephyr/projects/volteer/volteer/CMakeLists.txt b/zephyr/projects/volteer/volteer/CMakeLists.txt
index fddf517597..c749cfc340 100644
--- a/zephyr/projects/volteer/volteer/CMakeLists.txt
+++ b/zephyr/projects/volteer/volteer/CMakeLists.txt
@@ -39,8 +39,6 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_BATTERY
"${PLATFORM_EC_BOARD}/battery.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_EEPROM
"${PLATFORM_EC_BOARD}/cbi.c")
-zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_KEYBOARD_BOARD_CONFIG
- "${PLATFORM_EC_BOARD}/keyboard.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON
"${PLATFORM_EC_BOARD}/led.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC
diff --git a/zephyr/projects/volteer/volteer/prj.conf b/zephyr/projects/volteer/volteer/prj.conf
index 2a0cd5cc44..ac39a72846 100644
--- a/zephyr/projects/volteer/volteer/prj.conf
+++ b/zephyr/projects/volteer/volteer/prj.conf
@@ -29,7 +29,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_CHGRAMP=n
# Keyboard
CONFIG_PLATFORM_EC_KEYBOARD=y
CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y
-CONFIG_PLATFORM_EC_KEYBOARD_BOARD_CONFIG=y
CONFIG_PLATFORM_EC_KEYBOARD_KEYPAD=y
CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI2=y
CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y
diff --git a/zephyr/shim/chip/CMakeLists.txt b/zephyr/shim/chip/CMakeLists.txt
index 59b5a6c739..5c76a4163a 100644
--- a/zephyr/shim/chip/CMakeLists.txt
+++ b/zephyr/shim/chip/CMakeLists.txt
@@ -6,5 +6,7 @@ if (DEFINED CONFIG_SOC_FAMILY_NPCX)
add_subdirectory(npcx)
elseif (DEFINED CONFIG_SOC_FAMILY_RISCV_ITE)
add_subdirectory(it8xxx2)
+elseif (DEFINED CONFIG_SOC_POSIX)
+ add_subdirectory(posix)
endif()
diff --git a/zephyr/shim/chip/it8xxx2/system.c b/zephyr/shim/chip/it8xxx2/system.c
index 0ec138a415..e40c49d137 100644
--- a/zephyr/shim/chip/it8xxx2/system.c
+++ b/zephyr/shim/chip/it8xxx2/system.c
@@ -83,3 +83,13 @@ static int chip_system_init(const struct device *unused)
return 0;
}
SYS_INIT(chip_system_init, PRE_KERNEL_1, 15);
+
+uintptr_t system_get_fw_reset_vector(uintptr_t base)
+{
+ /*
+ * Because our reset vector is at the beginning of image copy
+ * (see init.S). So I just need to return 'base' here and EC will jump
+ * to the reset vector.
+ */
+ return base;
+}
diff --git a/zephyr/shim/chip/npcx/CMakeLists.txt b/zephyr/shim/chip/npcx/CMakeLists.txt
index c7cca9939a..a184d678f6 100644
--- a/zephyr/shim/chip/npcx/CMakeLists.txt
+++ b/zephyr/shim/chip/npcx/CMakeLists.txt
@@ -6,6 +6,7 @@ zephyr_library_include_directories(include)
zephyr_library_sources(clock.c)
zephyr_library_sources(gpio.c)
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI espi.c)
zephyr_library_sources_ifdef(CONFIG_CROS_KB_RAW_NPCX keyboard_raw.c)
zephyr_library_sources_ifdef(CONFIG_CROS_SHI_NPCX shi.c)
zephyr_library_sources_ifdef(CONFIG_CROS_EC system.c)
diff --git a/zephyr/shim/chip/npcx/espi.c b/zephyr/shim/chip/npcx/espi.c
new file mode 100644
index 0000000000..163db6007f
--- /dev/null
+++ b/zephyr/shim/chip/npcx/espi.c
@@ -0,0 +1,40 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <device.h>
+#include <sys/util.h>
+
+#include "soc_espi.h"
+#include "zephyr_espi_shim.h"
+
+bool is_acpi_command(uint32_t data)
+{
+ return (data >> NPCX_ACPI_TYPE_POS) & 0x01;
+}
+
+uint32_t get_acpi_value(uint32_t data)
+{
+ return (data >> NPCX_ACPI_DATA_POS) & 0xff;
+}
+
+bool is_8042_ibf(uint32_t data)
+{
+ return (data >> NPCX_8042_EVT_POS) & NPCX_8042_EVT_IBF;
+}
+
+bool is_8042_obe(uint32_t data)
+{
+ return (data >> NPCX_8042_EVT_POS) & NPCX_8042_EVT_OBE;
+}
+
+uint32_t get_8042_type(uint32_t data)
+{
+ return (data >> NPCX_8042_TYPE_POS) & 0xFF;
+}
+
+uint32_t get_8042_data(uint32_t data)
+{
+ return (data >> NPCX_8042_DATA_POS) & 0xFF;
+}
diff --git a/zephyr/shim/chip/posix/CMakeLists.txt b/zephyr/shim/chip/posix/CMakeLists.txt
new file mode 100644
index 0000000000..70e8b6269a
--- /dev/null
+++ b/zephyr/shim/chip/posix/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI espi.c) \ No newline at end of file
diff --git a/zephyr/shim/chip/posix/espi.c b/zephyr/shim/chip/posix/espi.c
new file mode 100644
index 0000000000..cf348744d7
--- /dev/null
+++ b/zephyr/shim/chip/posix/espi.c
@@ -0,0 +1,49 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <sys/util.h>
+#include "zephyr_espi_shim.h"
+
+#define ACPI_TYPE_POS 0U
+#define ACPI_DATA_POS 8U
+
+/* 8042 event data format */
+#define POSIX_8042_EVT_POS 16U
+#define POSIX_8042_DATA_POS 8U
+#define POSIX_8042_TYPE_POS 0U
+
+/* 8042 event type format */
+#define POSIX_8042_EVT_IBF BIT(0)
+#define POSIX_8042_EVT_OBE BIT(1)
+
+bool is_acpi_command(uint32_t data)
+{
+ return (data >> ACPI_TYPE_POS) & 0x01;
+}
+
+uint32_t get_acpi_value(uint32_t data)
+{
+ return (data >> ACPI_TYPE_POS) & 0xff;
+}
+
+bool is_POSIX_8042_ibf(uint32_t data)
+{
+ return (data >> POSIX_8042_EVT_POS) & POSIX_8042_EVT_IBF;
+}
+
+bool is_POSIX_8042_obe(uint32_t data)
+{
+ return (data >> POSIX_8042_EVT_POS) & POSIX_8042_EVT_OBE;
+}
+
+uint32_t get_POSIX_8042_type(uint32_t data)
+{
+ return (data >> POSIX_8042_TYPE_POS) & 0xFF;
+}
+
+uint32_t get_POSIX_8042_data(uint32_t data)
+{
+ return (data >> POSIX_8042_DATA_POS) & 0xFF;
+}
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 0cfd9de4d7..b81ff93eeb 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -425,6 +425,11 @@
#define CONFIG_I2C_CONTROLLER
#endif
+#undef CONFIG_SMBUS_PEC
+#ifdef CONFIG_PLATFORM_EC_SMBUS_PEC
+#define CONFIG_SMBUS_PEC
+#endif
+
#undef CONFIG_KEYBOARD_PROTOCOL_8042
#ifdef CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_PROTOCOL_8042
@@ -464,11 +469,6 @@
#define CONFIG_KEYBOARD_COL2_INVERTED
#endif /* CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED */
-#undef CONFIG_KEYBOARD_BOARD_CONFIG
-#ifdef CONFIG_PLATFORM_EC_KEYBOARD_BOARD_CONFIG
-#define CONFIG_KEYBOARD_BOARD_CONFIG
-#endif
-
#undef CONFIG_KEYBOARD_KEYPAD
#ifdef CONFIG_PLATFORM_EC_KEYBOARD_KEYPAD
#define CONFIG_KEYBOARD_KEYPAD
@@ -779,6 +779,11 @@
#define CONFIG_MT6360_BC12_GPIO
#endif
+#undef CONFIG_HOSTCMD_REGULATOR
+#ifdef CONFIG_PLATFORM_EC_HOSTCMD_REGULATOR
+#define CONFIG_HOSTCMD_REGULATOR
+#endif
+
#undef CONFIG_USB_PD_DUAL_ROLE
#ifdef CONFIG_PLATFORM_EC_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_DUAL_ROLE
@@ -1723,4 +1728,9 @@
#define CONFIG_CMD_S5_TIMEOUT
#endif
+#undef CONFIG_FW_RESET_VECTOR
+#ifdef CONFIG_PLATFORM_EC_FW_RESET_VECTOR
+#define CONFIG_FW_RESET_VECTOR
+#endif
+
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/zephyr/shim/include/zephyr_espi_shim.h b/zephyr/shim/include/zephyr_espi_shim.h
index c8172e8653..a7b151cec8 100644
--- a/zephyr/shim/include/zephyr_espi_shim.h
+++ b/zephyr/shim/include/zephyr_espi_shim.h
@@ -6,6 +6,9 @@
#ifndef __CROS_EC_ZEPHYR_ESPI_SHIM_H
#define __CROS_EC_ZEPHYR_ESPI_SHIM_H
+#include <stdbool.h>
+#include <stdint.h>
+
/**
* zephyr_shim_setup_espi() - initialize eSPI device
*
@@ -13,4 +16,52 @@
*/
int zephyr_shim_setup_espi(void);
+/**
+ * Check if the message is an ACPI command.
+ *
+ * @param data The full ACPI event data.
+ * @return True if the message is a command.
+ */
+bool is_acpi_command(uint32_t data);
+
+/**
+ * Get the value component of the ACPI message.
+ *
+ * @param data The full ACPI event data.
+ * @return The value component of the ACPI message.
+ */
+uint32_t get_acpi_value(uint32_t data);
+
+/**
+ * Check if the 8042 event data contains an input-buffer-full (IBF) event.
+ *
+ * @param data The full 8042 event data.
+ * @return True if the data contains an IBF event.
+ */
+bool is_8042_ibf(uint32_t data);
+
+/**
+ * Check if the 8042 event data contains an output-buffer-empty (OBE) event.
+ *
+ * @param data The full 8042 event data.
+ * @return True if the data contains an OBE event.
+ */
+bool is_8042_obe(uint32_t data);
+
+/**
+ * Get the type of 8042 message.
+ *
+ * @param data The full 8042 event data.
+ * @return The type component of the message.
+ */
+uint32_t get_8042_type(uint32_t data);
+
+/**
+ * Get the data from an 8042 message.
+ *
+ * @param data The full 8042 event data.
+ * @return The data component of the message.
+ */
+uint32_t get_8042_data(uint32_t data);
+
#endif /* __CROS_EC_ZEPHYR_ESPI_SHIM_H */
diff --git a/zephyr/shim/include/zephyr_host_command.h b/zephyr/shim/include/zephyr_host_command.h
index 377578311c..6535bb8876 100644
--- a/zephyr/shim/include/zephyr_host_command.h
+++ b/zephyr/shim/include/zephyr_host_command.h
@@ -53,6 +53,11 @@ void zshim_setup_host_command(
} \
SYS_INIT(_setup_host_command_##line, APPLICATION, 1)
#else /* !CONFIG_PLATFORM_EC_HOSTCMD */
-#define DECLARE_HOST_COMMAND(command, routine, version_mask) \
- enum ec_status (routine)(struct host_cmd_handler_args *args)
+#ifdef __clang__
+#define DECLARE_HOST_COMMAND(command, routine, version_mask)
+#else
+#define DECLARE_HOST_COMMAND(command, routine, version_mask) \
+ enum ec_status (routine)(struct host_cmd_handler_args *args) \
+ __attribute__((unused))
+#endif /* __clang__ */
#endif /* CONFIG_PLATFORM_EC_HOSTCMD */
diff --git a/zephyr/shim/src/espi.c b/zephyr/shim/src/espi.c
index ee53c6a66e..e8ca1fcd0d 100644
--- a/zephyr/shim/src/espi.c
+++ b/zephyr/shim/src/espi.c
@@ -22,7 +22,6 @@
#include "lpc.h"
#include "port80.h"
#include "power.h"
-#include "soc_espi.h"
#include "task.h"
#include "timer.h"
#include "zephyr_espi_shim.h"
@@ -320,10 +319,10 @@ DECLARE_HOOK(HOOK_INIT, host_command_init, HOOK_PRIO_INIT_LPC);
static void handle_acpi_write(uint32_t data)
{
uint8_t value, result;
- uint8_t is_cmd = (data >> NPCX_ACPI_TYPE_POS) & 0x01;
+ uint8_t is_cmd = is_acpi_command(data);
uint32_t status;
- value = (data >> NPCX_ACPI_DATA_POS) & 0xff;
+ value = get_acpi_value(data);
/* Handle whatever this was. */
if (acpi_ap_to_ec(is_cmd, value, &result)) {
@@ -461,12 +460,12 @@ void lpc_aux_put_char(uint8_t chr, int send_irq)
static void kbc_ibf_obe_handler(uint32_t data)
{
#ifdef HAS_TASK_KEYPROTO
- uint8_t is_ibf = (data >> NPCX_8042_EVT_POS) & NPCX_8042_EVT_IBF;
+ uint8_t is_ibf = is_8042_ibf(data);
uint32_t status = I8042_AUX_DATA;
if (is_ibf) {
- keyboard_host_write((data >> NPCX_8042_DATA_POS) & 0xFF,
- (data >> NPCX_8042_TYPE_POS) & 0xFF);
+ keyboard_host_write(get_8042_data(data),
+ get_8042_type(data));
} else if (IS_ENABLED(CONFIG_8042_AUX)) {
espi_write_lpc_request(espi_dev, E8042_CLEAR_FLAG, &status);
}
diff --git a/zephyr/shim/src/i2c.c b/zephyr/shim/src/i2c.c
index cc4af85021..ae82db1a0a 100644
--- a/zephyr/shim/src/i2c.c
+++ b/zephyr/shim/src/i2c.c
@@ -18,6 +18,9 @@
#define INIT_REMOTE_PORTS(id) \
i2c_remote_ports[I2C_PORT(id)] = DT_PROP_OR(id, remote_port, -1);
+#define INIT_PHYSICAL_PORTS(id) \
+ i2c_physical_ports[I2C_PORT(id)] = DT_PROP_OR(id, physical_port, -1);
+
#define I2C_CONFIG_GPIO(id, type) \
DT_ENUM_UPPER_TOKEN(DT_CHILD(DT_CHILD(id, config), type), enum_name)
@@ -41,6 +44,7 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
static int i2c_remote_ports[I2C_PORT_COUNT];
+static int i2c_physical_ports[I2C_PORT_COUNT];
int i2c_get_line_levels(int port)
{
@@ -54,6 +58,7 @@ static int init_device_bindings(const struct device *device)
ARG_UNUSED(device);
DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_DEV_BINDING)
DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_REMOTE_PORTS)
+ DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_PHYSICAL_PORTS)
return 0;
}
SYS_INIT(init_device_bindings, POST_KERNEL, 51);
@@ -75,3 +80,15 @@ int i2c_get_port_from_remote_port(int remote_port)
/* Remote port is not defined, return -1 to signal the problem */
return -1;
}
+
+int i2c_get_physical_port(int enum_port)
+{
+ int i2c_port = i2c_physical_ports[enum_port];
+
+ /*
+ * Return -1 for caller if physical port is not defined or the
+ * port number is out of port_mutex space.
+ * Please ensure the caller won't change anything if -1 received.
+ */
+ return (i2c_port < I2C_PORT_COUNT) ? i2c_port : -1;
+}
diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts
index 47662890aa..f0413746d3 100644
--- a/zephyr/test/drivers/overlay.dts
+++ b/zephyr/test/drivers/overlay.dts
@@ -9,6 +9,7 @@
aliases {
bmi260-int = &ms_bmi260_accel;
bmi160-int = &ms_bmi160_accel;
+ tcs3400-int = &tcs3400_clear;
};
named-gpios {
compatible = "named-gpios";
@@ -200,6 +201,70 @@
compatible = "cros-ec,drvdata-bmi160";
status = "okay";
};
+
+ tcs_clear_data: tcs3400-clear-drv-data {
+ compatible = "cros-ec,drvdata-tcs3400-clear";
+ status = "okay";
+
+ als-drv-data {
+ compatible = "cros-ec,accelgyro-als-drv-data";
+ als-cal {
+ scale = <1>;
+ uscale = <0>;
+ offset = <0>;
+ als-channel-scale {
+ compatible =
+ "cros-ec,accelgyro-als-channel-scale";
+ k-channel-scale = <1>;
+ cover-scale = <1>;
+ };
+ };
+ };
+ };
+
+ tcs_rgb_data: tcs3400-rgb-drv-data {
+ compatible = "cros-ec,drvdata-tcs3400-rgb";
+ status = "okay";
+
+ /* node for rgb_calibration_t defined in accelgyro.h */
+ rgb_calibration {
+ compatible =
+ "cros-ec,accelgyro-rgb-calibration";
+
+ irt = <1>;
+
+ rgb-cal-x {
+ offset = <0>;
+ coeff = <0 1 0 0>;
+ als-channel-scale {
+ compatible =
+ "cros-ec,accelgyro-als-channel-scale";
+ k-channel-scale = <1>;
+ cover-scale = <1>;
+ };
+ };
+ rgb-cal-y {
+ offset = <0>;
+ coeff = <0 0 1 0>;
+ als-channel-scale {
+ compatible =
+ "cros-ec,accelgyro-als-channel-scale";
+ k-channel-scale = <1>;
+ cover-scale = <1>;
+ };
+ };
+ rgb-cal-z {
+ offset = <0>;
+ coeff = <0 0 0 1>;
+ als-channel-scale {
+ compatible =
+ "cros-ec,accelgyro-als-channel-scale";
+ k-channel-scale = <1>;
+ cover-scale = <1>;
+ };
+ };
+ };
+ };
};
/*
@@ -259,6 +324,37 @@
default-range = <1000>; /* dps */
i2c-spi-addr-flags = "BMI160_ADDR0_FLAGS";
};
+
+ tcs3400_clear: tcs3400-clear {
+ compatible = "cros-ec,tcs3400-clear";
+ status = "okay";
+
+ label = "Clear Light";
+ location = "MOTIONSENSE_LOC_BASE";
+ port = <&i2c_sensor>;
+ default-range = <0x10000>;
+ drv-data = <&tcs_clear_data>;
+ i2c-spi-addr-flags = "TCS3400_I2C_ADDR_FLAGS";
+ configs {
+ compatible =
+ "cros-ec,motionsense-sensor-config";
+ ec-s0 {
+ /* Run ALS sensor in S0 */
+ label = "SENSOR_CONFIG_EC_S0";
+ odr = <1000>;
+ };
+ };
+ };
+
+ tcs3400_rgb: tcs3400-rgb {
+ compatible = "cros-ec,tcs3400-rgb";
+ status = "okay";
+
+ label = "RGB Light";
+ location = "MOTIONSENSE_LOC_BASE";
+ default-range = <0x10000>; /* scale = 1x, uscale = 0 */
+ drv-data = <&tcs_rgb_data>;
+ };
};
/*
@@ -284,6 +380,15 @@
error-on-reserved-bit-write;
simulate-command-exec-time;
};
+
+ tcs_emul: tcs@39 {
+ compatible = "zephyr,tcs3400";
+ reg = <0x39>;
+ label = "TCS_EMUL";
+ error-on-ro-write;
+ error-on-reserved-bit-write;
+ error-on-msb-first-access;
+ };
};
};
diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf
index 87700ec8c6..3fd3636946 100644
--- a/zephyr/test/drivers/prj.conf
+++ b/zephyr/test/drivers/prj.conf
@@ -20,6 +20,7 @@ CONFIG_ADC_EMUL=y
CONFIG_HEAP_MEM_POOL_SIZE=1024
CONFIG_EMUL_BMA255=y
CONFIG_EMUL_BMI=y
+CONFIG_EMUL_TCS3400=y
CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y
CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y
@@ -58,6 +59,7 @@ CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
CONFIG_PLATFORM_EC_ACCEL_INTERRUPTS=y
CONFIG_PLATFORM_EC_ACCEL_FIFO=y
CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
+CONFIG_PLATFORM_EC_ALS_TCS3400=y
# Things that default to on, but aren't working yet
CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
diff --git a/zephyr/test/drivers/src/main.c b/zephyr/test/drivers/src/main.c
index 3c2c6856d7..ca573b98fd 100644
--- a/zephyr/test/drivers/src/main.c
+++ b/zephyr/test/drivers/src/main.c
@@ -17,6 +17,7 @@ extern void test_suite_bc12(void);
extern void test_suite_ppc(void);
extern void test_suite_bmi260(void);
extern void test_suite_bmi160(void);
+extern void test_suite_tcs3400(void);
void test_main(void)
{
@@ -35,4 +36,5 @@ void test_main(void)
test_suite_ppc();
test_suite_bmi260();
test_suite_bmi160();
+ test_suite_tcs3400();
}
diff --git a/zephyr/test/drivers/src/tcs3400.c b/zephyr/test/drivers/src/tcs3400.c
new file mode 100644
index 0000000000..7f9ce38351
--- /dev/null
+++ b/zephyr/test/drivers/src/tcs3400.c
@@ -0,0 +1,622 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr.h>
+#include <ztest.h>
+
+#include "common.h"
+#include "i2c.h"
+#include "emul/emul_tcs3400.h"
+
+#include "motion_sense.h"
+#include "motion_sense_fifo.h"
+#include "driver/als_tcs3400.h"
+
+#define TCS_ORD DT_DEP_ORD(DT_NODELABEL(tcs_emul))
+#define TCS_CLR_SENSOR_ID SENSOR_ID(DT_NODELABEL(tcs3400_clear))
+#define TCS_RGB_SENSOR_ID SENSOR_ID(DT_NODELABEL(tcs3400_rgb))
+#define TCS_INT_EVENT \
+ TASK_EVENT_MOTION_SENSOR_INTERRUPT(SENSOR_ID(DT_ALIAS(tcs3400_int)))
+
+/** How accurate comparision of rgb sensors should be */
+#define V_EPS 8
+
+/** Test initialization of light sensor driver and device */
+static void test_tcs_init(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* RGB sensor initialization is always successful */
+ zassert_equal(EC_SUCCESS, ms_rgb->drv->init(ms_rgb), NULL);
+
+ /* Fail init on communication errors */
+ tcs_emul_set_read_fail_reg(emul, TCS_EMUL_FAIL_ALL_REG);
+ zassert_equal(-EIO, ms->drv->init(ms), NULL);
+ tcs_emul_set_read_fail_reg(emul, TCS_EMUL_NO_FAIL_REG);
+
+ /* Fail on bad ID */
+ tcs_emul_set_reg(emul, TCS_I2C_ID, 0);
+ zassert_equal(EC_ERROR_ACCESS_DENIED, ms->drv->init(ms), NULL);
+ /* Restore ID */
+ tcs_emul_set_reg(emul, TCS_I2C_ID, DT_ENUM_TOKEN(DT_NODELABEL(tcs_emul),
+ device_id));
+
+ /* Test successful init. ATIME and AGAIN should be changed on init */
+ zassert_equal(EC_SUCCESS, ms->drv->init(ms), NULL);
+ zassert_equal(TCS_DEFAULT_ATIME,
+ tcs_emul_get_reg(emul, TCS_I2C_ATIME), NULL);
+ zassert_equal(TCS_DEFAULT_AGAIN,
+ tcs_emul_get_reg(emul, TCS_I2C_CONTROL), NULL);
+}
+
+/** Test if read function leaves device in correct mode to accuire data */
+static void test_tcs_read(void)
+{
+ struct motion_sensor_t *ms;
+ struct i2c_emul *emul;
+ uint8_t enable;
+ intv3_t v;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+
+ /* Test error on writing registers */
+ tcs_emul_set_write_fail_reg(emul, TCS_I2C_ATIME);
+ zassert_equal(-EIO, ms->drv->read(ms, v), NULL);
+ tcs_emul_set_write_fail_reg(emul, TCS_I2C_CONTROL);
+ zassert_equal(-EIO, ms->drv->read(ms, v), NULL);
+ tcs_emul_set_write_fail_reg(emul, TCS_I2C_ENABLE);
+ zassert_equal(-EIO, ms->drv->read(ms, v), NULL);
+ tcs_emul_set_write_fail_reg(emul, TCS_EMUL_NO_FAIL_REG);
+
+ /* Test starting read with calibration */
+ tcs_emul_set_reg(emul, TCS_I2C_ATIME, 0);
+ tcs_emul_set_reg(emul, TCS_I2C_CONTROL, 0);
+ tcs_emul_set_reg(emul, TCS_I2C_ENABLE, 0);
+ zassert_equal(EC_SUCCESS, ms->drv->perform_calib(ms, 1), NULL);
+ zassert_equal(EC_RES_IN_PROGRESS, ms->drv->read(ms, v), NULL);
+ zassert_equal(TCS_CALIBRATION_ATIME,
+ tcs_emul_get_reg(emul, TCS_I2C_ATIME), NULL);
+ zassert_equal(TCS_CALIBRATION_AGAIN,
+ tcs_emul_get_reg(emul, TCS_I2C_CONTROL), NULL);
+ enable = tcs_emul_get_reg(emul, TCS_I2C_ENABLE);
+ zassert_true(enable & TCS_I2C_ENABLE_POWER_ON, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_ADC_ENABLE, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_INT_ENABLE, NULL);
+
+ /* Test starting read without calibration */
+ tcs_emul_set_reg(emul, TCS_I2C_ATIME, 0);
+ tcs_emul_set_reg(emul, TCS_I2C_CONTROL, 0);
+ tcs_emul_set_reg(emul, TCS_I2C_ENABLE, 0);
+ zassert_equal(EC_SUCCESS, ms->drv->perform_calib(ms, 0), NULL);
+ zassert_equal(EC_RES_IN_PROGRESS, ms->drv->read(ms, v), NULL);
+ enable = tcs_emul_get_reg(emul, TCS_I2C_ENABLE);
+ zassert_true(enable & TCS_I2C_ENABLE_POWER_ON, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_ADC_ENABLE, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_INT_ENABLE, NULL);
+}
+
+/** Check if FIFO for RGB and clear sensor is empty */
+static void check_fifo_empty_f(struct motion_sensor_t *ms,
+ struct motion_sensor_t *ms_rgb, int line)
+{
+ struct ec_response_motion_sensor_data vector;
+ uint16_t size;
+
+ /* Read all data committed to FIFO */
+ while (motion_sense_fifo_read(sizeof(vector), 1, &vector, &size)) {
+ /* Ignore timestamp frames */
+ if (vector.flags == MOTIONSENSE_SENSOR_FLAG_TIMESTAMP) {
+ continue;
+ }
+
+ if (ms - motion_sensors == vector.sensor_num) {
+ zassert_unreachable(
+ "Unexpected frame for clear sensor");
+ }
+
+ if (ms_rgb - motion_sensors == vector.sensor_num) {
+ zassert_unreachable("Unexpected frame for rgb sensor");
+ }
+ }
+}
+#define check_fifo_empty(ms, ms_rgb) \
+ check_fifo_empty_f(ms, ms_rgb, __LINE__)
+
+/**
+ * Test different conditions where irq handler fail or commit no data
+ * to fifo
+ */
+static void test_tcs_irq_handler_fail(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+ uint32_t event;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* Fail on wrong event */
+ event = 0x1234 & ~TCS_INT_EVENT;
+ zassert_equal(EC_ERROR_NOT_HANDLED, ms->drv->irq_handler(ms, &event),
+ NULL);
+ check_fifo_empty(ms, ms_rgb);
+
+ event = TCS_INT_EVENT;
+ /* Test error on reading status */
+ tcs_emul_set_read_fail_reg(emul, TCS_I2C_STATUS);
+ zassert_equal(-EIO, ms->drv->irq_handler(ms, &event), NULL);
+ tcs_emul_set_read_fail_reg(emul, TCS_EMUL_NO_FAIL_REG);
+ check_fifo_empty(ms, ms_rgb);
+
+ /* Test fail on changing device power state */
+ tcs_emul_set_write_fail_reg(emul, TCS_I2C_ENABLE);
+ zassert_equal(-EIO, ms->drv->irq_handler(ms, &event), NULL);
+ tcs_emul_set_write_fail_reg(emul, TCS_EMUL_NO_FAIL_REG);
+ check_fifo_empty(ms, ms_rgb);
+
+ /* Test that no data is committed when status is 0 */
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS, 0);
+ zassert_equal(EC_SUCCESS, ms->drv->irq_handler(ms, &event), NULL);
+ check_fifo_empty(ms, ms_rgb);
+}
+
+/**
+ * Check if last data committed to FIFO for RGB and clear sensor equals to
+ * expected value.
+ */
+static void check_fifo_f(struct motion_sensor_t *ms,
+ struct motion_sensor_t *ms_rgb,
+ int *exp_v, int eps, int line)
+{
+ struct ec_response_motion_sensor_data vector;
+ uint16_t size;
+ int ret_v[4] = {-1, -1, -1, -1};
+ int i;
+
+ /* Read all data committed to FIFO */
+ while (motion_sense_fifo_read(sizeof(vector), 1, &vector, &size)) {
+ /* Ignore timestamp frames */
+ if (vector.flags == MOTIONSENSE_SENSOR_FLAG_TIMESTAMP) {
+ continue;
+ }
+
+ /* Get clear frame */
+ if (ms - motion_sensors == vector.sensor_num) {
+ ret_v[0] = vector.udata[0];
+ }
+
+ /* Get rgb frame */
+ if (ms_rgb - motion_sensors == vector.sensor_num) {
+ ret_v[1] = vector.udata[0];
+ ret_v[2] = vector.udata[1];
+ ret_v[3] = vector.udata[2];
+ }
+ }
+
+ if (ret_v[0] == -1) {
+ zassert_unreachable("No frame for clear sensor, line %d", line);
+ }
+
+ if (ret_v[1] == -1) {
+ zassert_unreachable("No frame for rgb sensor, line %d", line);
+ }
+
+ /* Compare with last committed data */
+ for (i = 0; i < 4; i++) {
+ zassert_within(exp_v[i], ret_v[i], eps,
+ "Expected [%d; %d; %d; %d], got [%d; %d; %d; %d]; line: %d",
+ exp_v[0], exp_v[1], exp_v[2], exp_v[3],
+ ret_v[0], ret_v[1], ret_v[2], ret_v[3], line);
+ }
+}
+#define check_fifo(ms, ms_rgb, exp_v, eps) \
+ check_fifo_f(ms, ms_rgb, exp_v, eps, __LINE__)
+
+/** Test calibration mode reading of light sensor values */
+static void test_tcs_read_calibration(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+ uint32_t event = TCS_INT_EVENT;
+ int emul_v[4];
+ int exp_v[4];
+ int ret;
+ intv3_t v;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* Need to be set to collect all data in FIFO */
+ ms->oversampling_ratio = 1;
+ ms_rgb->oversampling_ratio = 1;
+ /* Enable calibration mode */
+ zassert_equal(EC_SUCCESS, ms->drv->perform_calib(ms, 1), NULL);
+ /* Setup AGAIN and ATIME for calibration */
+ zassert_equal(EC_RES_IN_PROGRESS, ms->drv->read(ms, v), NULL);
+
+ /* Test data that are in calibration range */
+ exp_v[0] = 12;
+ exp_v[1] = 123;
+ exp_v[2] = 1234;
+ exp_v[3] = 12345;
+ /*
+ * Emulator value is with gain 64, while expected value is
+ * with gain 16
+ */
+ emul_v[0] = exp_v[0] * 64 / 16;
+ emul_v[1] = exp_v[1] * 64 / 16;
+ emul_v[2] = exp_v[2] * 64 / 16;
+ emul_v[3] = exp_v[3] * 64 / 16;
+ tcs_emul_set_val(emul, TCS_EMUL_C, emul_v[0]);
+ tcs_emul_set_val(emul, TCS_EMUL_R, emul_v[1]);
+ tcs_emul_set_val(emul, TCS_EMUL_G, emul_v[2]);
+ tcs_emul_set_val(emul, TCS_EMUL_B, emul_v[3]);
+ /* Set status to show valid data */
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS, TCS_I2C_STATUS_RGBC_VALID);
+
+ zassert_equal(EC_SUCCESS, ms->drv->irq_handler(ms, &event), NULL);
+ /* In calibration mode check for exact match */
+ check_fifo(ms, ms_rgb, exp_v, 1);
+
+ /* Test data that are outside of calibration range */
+ exp_v[0] = 0;
+ exp_v[1] = UINT16_MAX;
+ exp_v[2] = UINT16_MAX;
+ exp_v[3] = 213;
+ /*
+ * Emulator value is with gain 64, while expected value is
+ * with gain 16
+ */
+ emul_v[0] = 0;
+ emul_v[1] = exp_v[1] * 64 / 16;
+ emul_v[2] = (UINT16_MAX + 23) * 64 / 16;
+ emul_v[3] = exp_v[3] * 64 / 16;
+ tcs_emul_set_val(emul, TCS_EMUL_C, emul_v[0]);
+ tcs_emul_set_val(emul, TCS_EMUL_R, emul_v[1]);
+ tcs_emul_set_val(emul, TCS_EMUL_G, emul_v[2]);
+ tcs_emul_set_val(emul, TCS_EMUL_B, emul_v[3]);
+ /* Set status to show valid data */
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS, TCS_I2C_STATUS_RGBC_VALID);
+
+ zassert_equal(EC_SUCCESS, ms->drv->irq_handler(ms, &event), NULL);
+ /* In calibration mode check for exact match */
+ check_fifo(ms, ms_rgb, exp_v, 1);
+}
+
+/**
+ * Set emulator internal value using expected output value returned by
+ * the driver. First element of expected vector is IR value used in
+ * calculations. Based on that clear light value is calculated.
+ * First element of expected vector is updated by this function.
+ */
+static void set_emul_val_from_exp(int *exp_v, uint16_t *scale,
+ struct i2c_emul *emul)
+{
+ int emul_v[4];
+ int ir;
+
+ /* We use exp_v[0] as IR value */
+ ir = exp_v[0];
+ /* Driver will return lux value as calculated blue light value */
+ exp_v[0] = exp_v[2];
+
+ /*
+ * Driver takes care of different ATIME and AGAIN value, so expected
+ * value is always normalized to ATIME 256 and AGAIN 16. Convert it
+ * to internal emulator value (ATIME 256, AGAIN 64) and add expected IR
+ * value. Clear light is the sum of rgb light and IR component.
+ */
+ emul_v[1] = (exp_v[1] + ir) * 64 / 16;
+ emul_v[2] = (exp_v[2] + ir) * 64 / 16;
+ emul_v[3] = (exp_v[3] + ir) * 64 / 16;
+ emul_v[0] = (exp_v[1] + exp_v[2] + exp_v[3] + ir) * 64 / 16;
+
+ /* Apply scale, driver should divide by this value */
+ emul_v[0] = SENSOR_APPLY_SCALE(emul_v[0], scale[0]);
+ emul_v[1] = SENSOR_APPLY_SCALE(emul_v[1], scale[1]);
+ emul_v[2] = SENSOR_APPLY_SCALE(emul_v[2], scale[2]);
+ emul_v[3] = SENSOR_APPLY_SCALE(emul_v[3], scale[3]);
+
+ /* Set emulator values */
+ tcs_emul_set_val(emul, TCS_EMUL_C, emul_v[0]);
+ tcs_emul_set_val(emul, TCS_EMUL_R, emul_v[1]);
+ tcs_emul_set_val(emul, TCS_EMUL_G, emul_v[2]);
+ tcs_emul_set_val(emul, TCS_EMUL_B, emul_v[3]);
+}
+
+/** Test normal mode reading of light sensor values */
+static void test_tcs_read_xyz(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+ uint32_t event = TCS_INT_EVENT;
+ /* Expected data to test: IR, R, G, B */
+ int exp_v[][4] = {
+ {200, 1110, 870, 850},
+ {300, 1110, 10000, 8500},
+ {600, 50000, 40000, 30000},
+ {1000, 3000, 40000, 2000},
+ {1000, 65000, 65000, 65000},
+ {100, 214, 541, 516},
+ {143, 2141, 5414, 5163},
+ {100, 50000, 40000, 30000},
+ {1430, 2141, 5414, 5163},
+ {10000, 50000, 40000, 30000},
+ {10000, 214, 541, 516},
+ {15000, 50000, 40000, 30000},
+ };
+ uint16_t scale[4] = {
+ MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE,
+ MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE
+ };
+ int ret, i, test;
+ intv3_t v;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* Need to be set to collect all data in FIFO */
+ ms->oversampling_ratio = 1;
+ ms_rgb->oversampling_ratio = 1;
+ /* Disable calibration mode */
+ zassert_equal(EC_SUCCESS, ms->drv->perform_calib(ms, 0), NULL);
+ /* Setup AGAIN and ATIME for normal mode */
+ zassert_equal(EC_RES_IN_PROGRESS, ms->drv->read(ms, v), NULL);
+
+ /* Test different data in supported range */
+ for (test = 0; test < ARRAY_SIZE(exp_v); test++) {
+ set_emul_val_from_exp(exp_v[test], scale, emul);
+
+ /* Run few times to allow driver change gain */
+ for (i = 0; i < 5; i++) {
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS,
+ TCS_I2C_STATUS_RGBC_VALID);
+ zassert_equal(EC_SUCCESS,
+ ms->drv->irq_handler(ms, &event), NULL);
+ }
+ check_fifo(ms, ms_rgb, exp_v[test], V_EPS);
+ }
+
+ /* Test data that are outside of supported range */
+ exp_v[0][0] = 3000;
+ exp_v[0][1] = UINT16_MAX;
+ exp_v[0][2] = UINT16_MAX * 32;
+ exp_v[0][3] = 200;
+ set_emul_val_from_exp(exp_v[0], scale, emul);
+
+ /* Run few times to allow driver change gain */
+ for (i = 0; i < 10; i++) {
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS,
+ TCS_I2C_STATUS_RGBC_VALID);
+ zassert_equal(EC_SUCCESS, ms->drv->irq_handler(ms, &event),
+ NULL);
+ }
+ /*
+ * If saturation value is exceeded on any rgb sensor, than data
+ * shouldn't be committed to FIFO.
+ */
+ check_fifo_empty(ms, ms_rgb);
+}
+
+/**
+ * Test getting and setting scale of light sensor. Checks if collected values
+ * are scaled properly.
+ */
+static void test_tcs_scale(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+ uint32_t event = TCS_INT_EVENT;
+ /* Expected data to test: IR, R, G, B */
+ int exp_v[][4] = {
+ {200, 1110, 870, 850},
+ {300, 1110, 10000, 8500},
+ {600, 5000, 4000, 3000},
+ {100, 3000, 4000, 2000},
+ {100, 1000, 1000, 1000},
+ };
+ /* Scale for each test */
+ uint16_t exp_scale[][4] = {
+ {MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE,
+ MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE},
+ {MOTION_SENSE_DEFAULT_SCALE + 300,
+ MOTION_SENSE_DEFAULT_SCALE + 300,
+ MOTION_SENSE_DEFAULT_SCALE + 300,
+ MOTION_SENSE_DEFAULT_SCALE + 300},
+ {MOTION_SENSE_DEFAULT_SCALE - 300,
+ MOTION_SENSE_DEFAULT_SCALE - 300,
+ MOTION_SENSE_DEFAULT_SCALE - 300,
+ MOTION_SENSE_DEFAULT_SCALE - 300},
+ {MOTION_SENSE_DEFAULT_SCALE + 345,
+ MOTION_SENSE_DEFAULT_SCALE - 5423,
+ MOTION_SENSE_DEFAULT_SCALE - 30,
+ MOTION_SENSE_DEFAULT_SCALE + 400},
+ {MOTION_SENSE_DEFAULT_SCALE - 345,
+ MOTION_SENSE_DEFAULT_SCALE + 5423,
+ MOTION_SENSE_DEFAULT_SCALE + 30,
+ MOTION_SENSE_DEFAULT_SCALE - 400},
+ {MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE,
+ MOTION_SENSE_DEFAULT_SCALE, MOTION_SENSE_DEFAULT_SCALE}
+ };
+ uint16_t scale[3];
+ int16_t temp;
+ int ret, i, test;
+ intv3_t v;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* Need to be set to collect all data in FIFO */
+ ms->oversampling_ratio = 1;
+ ms_rgb->oversampling_ratio = 1;
+ /* Disable calibration mode */
+ zassert_equal(EC_SUCCESS, ms->drv->perform_calib(ms, 0), NULL);
+ /* Setup AGAIN and ATIME for normal mode */
+ zassert_equal(EC_RES_IN_PROGRESS, ms->drv->read(ms, v), NULL);
+
+ /* Test different data in supported range */
+ for (test = 0; test < ARRAY_SIZE(exp_v); test++) {
+ /* Set and test clear sensor scale */
+ zassert_equal(EC_SUCCESS,
+ ms->drv->set_scale(ms, exp_scale[test], 0),
+ "test %d", test);
+ zassert_equal(EC_SUCCESS,
+ ms->drv->get_scale(ms, scale, &temp),
+ "test %d", test);
+ zassert_equal((int16_t)EC_MOTION_SENSE_INVALID_CALIB_TEMP, temp,
+ "test %d, %d", test, temp);
+ zassert_equal(exp_scale[test][0], scale[0], "test %d", test);
+
+ /* Set and test RGB sensor scale */
+ zassert_equal(EC_SUCCESS, ms_rgb->drv->set_scale(ms_rgb,
+ &(exp_scale[test][1]), 0),
+ "test %d", test);
+ zassert_equal(EC_SUCCESS,
+ ms_rgb->drv->get_scale(ms_rgb, scale, &temp),
+ "test %d", test);
+ zassert_equal((int16_t)EC_MOTION_SENSE_INVALID_CALIB_TEMP, temp,
+ "test %d", test);
+ zassert_equal(exp_scale[test][1], scale[0], "test %d", test);
+ zassert_equal(exp_scale[test][2], scale[1], "test %d", test);
+ zassert_equal(exp_scale[test][3], scale[2], "test %d", test);
+
+ set_emul_val_from_exp(exp_v[test], exp_scale[test], emul);
+
+ /* Run few times to allow driver change gain */
+ for (i = 0; i < 5; i++) {
+ tcs_emul_set_reg(emul, TCS_I2C_STATUS,
+ TCS_I2C_STATUS_RGBC_VALID);
+ zassert_equal(EC_SUCCESS,
+ ms->drv->irq_handler(ms, &event), NULL);
+ }
+ check_fifo(ms, ms_rgb, exp_v[test], V_EPS);
+ }
+
+ /* Test fail if scale equals 0 */
+ scale[0] = 0;
+ scale[1] = MOTION_SENSE_DEFAULT_SCALE;
+ scale[2] = MOTION_SENSE_DEFAULT_SCALE;
+ zassert_equal(EC_ERROR_INVAL, ms->drv->set_scale(ms, scale, 0), NULL);
+
+ zassert_equal(EC_ERROR_INVAL, ms_rgb->drv->set_scale(ms_rgb, scale, 0),
+ NULL);
+ scale[0] = MOTION_SENSE_DEFAULT_SCALE;
+ scale[1] = 0;
+ scale[2] = MOTION_SENSE_DEFAULT_SCALE;
+ zassert_equal(EC_ERROR_INVAL, ms_rgb->drv->set_scale(ms_rgb, scale, 0),
+ NULL);
+ scale[0] = MOTION_SENSE_DEFAULT_SCALE;
+ scale[1] = MOTION_SENSE_DEFAULT_SCALE;
+ scale[2] = 0;
+ zassert_equal(EC_ERROR_INVAL, ms_rgb->drv->set_scale(ms_rgb, scale, 0),
+ NULL);
+}
+
+/** Test setting and getting data rate of light sensor */
+static void test_tcs_data_rate(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+ uint8_t enable;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ /* RGB sensor doesn't set rate, but return rate of clear sesnor */
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* Test fail on reading device power state */
+ tcs_emul_set_read_fail_reg(emul, TCS_I2C_ENABLE);
+ zassert_equal(-EIO, ms->drv->set_data_rate(ms, 0, 0), NULL);
+ zassert_equal(-EIO, ms->drv->set_data_rate(ms, 0, 1), NULL);
+ zassert_equal(-EIO, ms->drv->set_data_rate(ms, 100, 0), NULL);
+ zassert_equal(-EIO, ms->drv->set_data_rate(ms, 100, 1), NULL);
+ tcs_emul_set_read_fail_reg(emul, TCS_EMUL_NO_FAIL_REG);
+
+ /* Test setting 0 rate disables device */
+ zassert_equal(EC_SUCCESS, ms->drv->set_data_rate(ms, 0, 0), NULL);
+ zassert_equal(0, tcs_emul_get_reg(emul, TCS_I2C_ENABLE), NULL);
+ zassert_equal(0, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(0, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+
+ zassert_equal(EC_SUCCESS, ms->drv->set_data_rate(ms, 0, 1), NULL);
+ zassert_equal(0, tcs_emul_get_reg(emul, TCS_I2C_ENABLE), NULL);
+ zassert_equal(0, tcs_emul_get_reg(emul, TCS_I2C_ENABLE), NULL);
+ zassert_equal(0, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(0, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+
+
+ /* Test setting non-zero rate enables device */
+ zassert_equal(EC_SUCCESS, ms->drv->set_data_rate(ms, 100, 0), NULL);
+ enable = tcs_emul_get_reg(emul, TCS_I2C_ENABLE);
+ zassert_true(enable & TCS_I2C_ENABLE_POWER_ON, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_ADC_ENABLE, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_INT_ENABLE, NULL);
+ zassert_equal(100, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(100, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+
+ zassert_equal(EC_SUCCESS, ms->drv->set_data_rate(ms, 100, 1), NULL);
+ enable = tcs_emul_get_reg(emul, TCS_I2C_ENABLE);
+ zassert_true(enable & TCS_I2C_ENABLE_POWER_ON, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_ADC_ENABLE, NULL);
+ zassert_true(enable & TCS_I2C_ENABLE_INT_ENABLE, NULL);
+ zassert_equal(100, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(100, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+
+ /* Test RGB sensor doesn't change data rate */
+ zassert_equal(EC_SUCCESS, ms_rgb->drv->set_data_rate(ms_rgb, 300, 0),
+ NULL);
+ zassert_equal(100, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(100, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+
+ zassert_equal(EC_SUCCESS, ms_rgb->drv->set_data_rate(ms_rgb, 300, 1),
+ NULL);
+ zassert_equal(100, ms->drv->get_data_rate(ms), NULL);
+ zassert_equal(100, ms_rgb->drv->get_data_rate(ms_rgb), NULL);
+}
+
+/** Test set range function of clear and RGB sensors */
+static void test_tcs_set_range(void)
+{
+ struct motion_sensor_t *ms, *ms_rgb;
+ struct i2c_emul *emul;
+
+ emul = tcs_emul_get(TCS_ORD);
+ ms = &motion_sensors[TCS_CLR_SENSOR_ID];
+ ms_rgb = &motion_sensors[TCS_RGB_SENSOR_ID];
+
+ /* RGB sensor doesn't set anything */
+ zassert_equal(EC_SUCCESS, ms_rgb->drv->set_range(ms_rgb, 1, 0), NULL);
+
+ /* Clear sensor doesn't change anything on device to set range */
+ zassert_equal(EC_SUCCESS, ms->drv->set_range(ms, 0x12300, 1), NULL);
+ zassert_equal(0x12300, ms->current_range, NULL);
+
+ zassert_equal(EC_SUCCESS, ms->drv->set_range(ms, 0x10000, 0), NULL);
+ zassert_equal(0x10000, ms->current_range, NULL);
+}
+
+void test_suite_tcs3400(void)
+{
+ ztest_test_suite(tcs3400,
+ ztest_user_unit_test(test_tcs_init),
+ ztest_user_unit_test(test_tcs_read),
+ ztest_user_unit_test(test_tcs_irq_handler_fail),
+ ztest_user_unit_test(test_tcs_read_calibration),
+ ztest_user_unit_test(test_tcs_read_xyz),
+ ztest_user_unit_test(test_tcs_scale),
+ ztest_user_unit_test(test_tcs_data_rate),
+ ztest_user_unit_test(test_tcs_set_range));
+ ztest_run_test_suite(tcs3400);
+}
diff --git a/zephyr/test/drivers/src/temp_sensor.c b/zephyr/test/drivers/src/temp_sensor.c
index 7cfc40b9d5..83a343e572 100644
--- a/zephyr/test/drivers/src/temp_sensor.c
+++ b/zephyr/test/drivers/src/temp_sensor.c
@@ -112,6 +112,13 @@ static void test_temp_sensor_read(void)
check_valid_temperature(adc_dev, TEMP_SENSOR_DDR_SOC);
check_valid_temperature(adc_dev, TEMP_SENSOR_FAN);
check_valid_temperature(adc_dev, TEMP_SENSOR_PP3300_REGULATOR);
+
+ /* Return correct value on all ADC channels */
+ for (chan = 0; chan < ADC_CHANNELS_NUM; chan++) {
+ zassert_ok(adc_emul_const_value_set(adc_dev, chan, 1000),
+ "channel %d adc_emul_const_value_set() failed",
+ chan);
+ }
}
void test_suite_temp_sensor(void)