diff options
author | Commit Bot <commit-bot@chromium.org> | 2021-08-03 03:00:00 +0000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-08-03 03:00:00 +0000 |
commit | 1de9be8601ef4699173427bfb974256d77c0518b (patch) | |
tree | 1835aaabfe9f11a62b8aa31369cff949326ef5d5 | |
parent | ad375f6d147a639dc7e1c4f803ec8ccd68cbcd1b (diff) | |
parent | 1c05115a1965036eb2212958daae574ec0ba00a9 (diff) | |
download | chrome-ec-1de9be8601ef4699173427bfb974256d77c0518b.tar.gz |
Merge "Merge remote-tracking branch cros/main into firmware-volteer-13672.B-main" into firmware-volteer-13672.B-main
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 |= 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 |= 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) |