summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Mittelberg <bmbm@google.com>2022-04-13 13:14:06 -0700
committerBoris Mittelberg <bmbm@google.com>2022-04-13 13:14:06 -0700
commit59ede6b1714c313de3e003c0497c70725bf625d5 (patch)
treecd524275223d5a5681888a5d1692bff2db688f3f
parent10cb14ae7b35f4ad9eb37f58ba3c48d20649e35b (diff)
parentfb9f61782d452b106b9d9c4325fd473dcb4a7d8c (diff)
downloadchrome-ec-59ede6b1714c313de3e003c0497c70725bf625d5.tar.gz
Merge remote-tracking branch cros/main into firmware-brya-14505.B-main
Generated by: util/update_release_branch.py --baseboard brya --relevant_paths_file baseboard/brya/relevant-paths.txt firmware-brya-14505.B-main Relevant changes: git log --oneline 10cb14ae7..fb9f61782 -- baseboard/brya board/agah board/anahera board/banshee board/brya board/crota board/felwinter board/gimble board/kano board/primus board/redrix board/taeko board/taniks board/vell board/volmar driver/bc12/pi3usb9201_public.* driver/charger/bq25710.* driver/ppc/nx20p348x.* driver/ppc/syv682x_public.* driver/retimer/bb_retimer_public.* driver/tcpm/nct38xx.* driver/tcpm/ps8xxx_public.* driver/tcpm/tcpci.* include/power/alderlake* include/intel_x86.h power/alderlake* power/intel_x86.c util/getversion.sh e4309526a Taniks: Support keyboard backlight control c0333e1cb vell: Fix C3 TCPPC i2c address 61e177e69 anahera: Update fan table version 6-4 302a665c8 anahera: Update thermal high/halt point version 6-4 70016156d kano: Update keyboard backlight pwm frequency 82b4173c6 vell: Raise usbc ports i2c speed to 1Mhz fd753e96c tarlo: undef configuration for clamshell device 3e3ef8f7a vell: Update thermal high/halt point version 3 76f3e5ad3 vell: Update fan table version 3 73502f93b taniks: add RGB mapping table BRANCH=None BUG=b:216026302 b:227522597 b:228410337 b:228525798 b:226215987 BUG=b:222125478 b:199246802 b:220196847 b:229039902 TEST=`make -j buildall` Signed-off-by: Boris Mittelberg <bmbm@google.com> Change-Id: Idfb129023ae067f927a89e2abc67c2286f17fd19
-rw-r--r--CPPLINT.cfg4
-rw-r--r--PRESUBMIT.cfg1
-rw-r--r--board/anahera/sensors.c8
-rw-r--r--board/anahera/thermal.c22
-rw-r--r--board/kano/pwm.c2
-rw-r--r--board/quackingstick/board.c8
-rw-r--r--board/scout/board.c4
-rw-r--r--board/scout/board.h2
-rw-r--r--board/taeko/board.h1
-rw-r--r--board/taniks/board.h4
-rw-r--r--board/taniks/keyboard.c41
-rw-r--r--board/taniks/pwm.c19
-rw-r--r--board/vell/i2c.c10
-rw-r--r--board/vell/sensors.c10
-rw-r--r--board/vell/thermal.c49
-rw-r--r--board/vell/usbc_config.c11
-rw-r--r--common/keyboard_backlight.c9
-rw-r--r--common/motion_sense.c2
-rw-r--r--common/pwm.c37
-rw-r--r--common/rgb_keyboard.c175
-rw-r--r--common/usbc/usb_pe_drp_sm.c10
-rw-r--r--core/cortex-m/irq_handler.h18
-rw-r--r--docs/ec_terms.md18
-rw-r--r--docs/zephyr/zephyr_ap_power.md58
-rw-r--r--docs/zephyr/zephyr_battery.md92
-rw-r--r--docs/zephyr/zephyr_gpio.md13
-rw-r--r--docs/zephyr/zephyr_i2c.md3
-rw-r--r--docs/zephyr/zephyr_new_board_checklist.md7
-rw-r--r--docs/zephyr/zephyr_template.md25
-rw-r--r--docs/zephyr/zephyr_usba.md78
-rw-r--r--driver/charger/isl923x.c37
-rw-r--r--driver/charger/isl9241.c51
-rw-r--r--driver/charger/rt9490.c2
-rw-r--r--driver/charger/rt9490.h4
-rw-r--r--driver/led/aw20198.c5
-rw-r--r--driver/led/is31fl3743b.c5
-rw-r--r--extra/usb_updater/usb_updater2.c2
-rwxr-xr-xfirmware_builder.py8
-rw-r--r--include/ec_commands.h2
-rw-r--r--include/rgb_keyboard.h18
-rw-r--r--include/task.h12
-rw-r--r--power/amd_x86.c12
-rw-r--r--test/motion_sense_fifo.c53
-rwxr-xr-xtest/run_device_tests.py194
-rwxr-xr-xutil/build_with_clang.py46
-rw-r--r--util/ectool.c9
-rw-r--r--zephyr/CMakeLists.txt3
-rw-r--r--zephyr/Kconfig.stacks4
-rw-r--r--zephyr/Kconfig.usba3
-rw-r--r--zephyr/boards/arm/npcx7/npcx7_defconfig2
-rw-r--r--zephyr/boards/arm/npcx9/npcx9_defconfig2
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig1
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig1
-rw-r--r--zephyr/boards/riscv/it8xxx2/it8xxx2.dts7
-rw-r--r--zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c103
-rw-r--r--zephyr/drivers/cros_system/cros_system_npcx.c2
-rw-r--r--zephyr/dts/bindings/battery/battery-smart.yaml1
-rw-r--r--zephyr/dts/bindings/battery/ganfeng,7c01.yaml54
-rw-r--r--zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml24
-rw-r--r--zephyr/dts/bindings/usbc/richtek,rt9490-bc12.yaml6
-rw-r--r--zephyr/dts/bindings/vendor-prefixes.txt1
-rw-r--r--zephyr/include/cros/ite/it8xxx2.dtsi10
-rw-r--r--zephyr/projects/.pylintrc21
-rw-r--r--zephyr/projects/brya/BUILD.py3
-rw-r--r--zephyr/projects/brya/prj.conf1
-rw-r--r--zephyr/projects/corsola/BUILD.py3
-rw-r--r--zephyr/projects/corsola/interrupts_krabby.dts2
-rw-r--r--zephyr/projects/corsola/prj_kingler.conf1
-rw-r--r--zephyr/projects/corsola/prj_krabby.conf1
-rw-r--r--zephyr/projects/corsola/src/kingler/button.c3
-rw-r--r--zephyr/projects/corsola/src/kingler/usb_pd_policy.c15
-rw-r--r--zephyr/projects/corsola/src/kingler/usbc_config.c28
-rw-r--r--zephyr/projects/corsola/src/krabby/charger_workaround.c3
-rw-r--r--zephyr/projects/corsola/src/krabby/hooks.c17
-rw-r--r--zephyr/projects/corsola/src/krabby/led.c12
-rw-r--r--zephyr/projects/corsola/src/krabby/usb_pd_policy.c17
-rw-r--r--zephyr/projects/corsola/src/krabby/usbc_config.c39
-rw-r--r--zephyr/projects/corsola/src/usb_pd_policy.c21
-rw-r--r--zephyr/projects/corsola/src/usbc_config.c34
-rw-r--r--zephyr/projects/corsola/src/variant_db_detection.c8
-rw-r--r--zephyr/projects/corsola/usbc_krabby.dts1
-rw-r--r--zephyr/projects/herobrine/BUILD.py5
-rw-r--r--zephyr/projects/herobrine/battery_hoglin.dts12
-rw-r--r--zephyr/projects/herobrine/prj.conf2
-rw-r--r--zephyr/projects/intelrvp/BUILD.py3
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/gpio.dts62
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts4
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/prj.conf6
-rw-r--r--zephyr/projects/it8xxx2_evb/BUILD.py2
-rw-r--r--zephyr/projects/nissa/BUILD.py3
-rw-r--r--zephyr/projects/nissa/nereid_overlay.dts4
-rw-r--r--zephyr/projects/nissa/nivviks_overlay.dts4
-rw-r--r--zephyr/projects/nissa/prj.conf1
-rw-r--r--zephyr/projects/nissa/src/sub_board.c61
-rw-r--r--zephyr/projects/npcx_evb/npcx7/BUILD.py2
-rw-r--r--zephyr/projects/npcx_evb/npcx7/prj.conf3
-rw-r--r--zephyr/projects/npcx_evb/npcx9/BUILD.py2
-rw-r--r--zephyr/projects/npcx_evb/npcx9/prj.conf3
-rw-r--r--zephyr/projects/posix-ec/BUILD.py2
-rw-r--r--zephyr/projects/skyrim/BUILD.py3
-rw-r--r--zephyr/projects/skyrim/gpio.dts11
-rw-r--r--zephyr/projects/skyrim/prj.conf6
-rw-r--r--zephyr/projects/trogdor/lazor/BUILD.py2
-rw-r--r--zephyr/projects/trogdor/lazor/prj.conf2
-rw-r--r--zephyr/shim/include/config_chip.h6
-rw-r--r--zephyr/shim/include/power_host_sleep.h71
-rw-r--r--zephyr/shim/include/usbc/ppc.h4
-rw-r--r--zephyr/shim/include/usbc/utils.h36
-rw-r--r--zephyr/shim/src/CMakeLists.txt4
-rw-r--r--zephyr/shim/src/bc12.c3
-rw-r--r--zephyr/shim/src/bc12_pi3usb9201.c7
-rw-r--r--zephyr/shim/src/bc12_rt9490.c41
-rw-r--r--zephyr/shim/src/espi.c37
-rw-r--r--zephyr/shim/src/led_driver/led.h21
-rw-r--r--zephyr/shim/src/led_driver/led_gpio.c1
-rw-r--r--zephyr/shim/src/led_driver/led_pwm.c1
-rw-r--r--zephyr/shim/src/power_host_sleep_api.c45
-rw-r--r--zephyr/shim/src/ppc.c2
-rw-r--r--zephyr/shim/src/tasks.c104
-rw-r--r--zephyr/shim/src/tcpc.c3
-rw-r--r--zephyr/subsys/ap_pwrseq/CMakeLists.txt1
-rw-r--r--zephyr/subsys/ap_pwrseq/Kconfig13
-rw-r--r--zephyr/subsys/ap_pwrseq/include/ap_power_host_sleep.h52
-rw-r--r--zephyr/subsys/ap_pwrseq/include/power_signals.h35
-rw-r--r--zephyr/subsys/ap_pwrseq/include/signal_adc.h24
-rw-r--r--zephyr/subsys/ap_pwrseq/include/signal_gpio.h4
-rw-r--r--zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h5
-rw-r--r--zephyr/subsys/ap_pwrseq/power_host_sleep.c231
-rw-r--r--zephyr/subsys/ap_pwrseq/power_signals.c16
-rw-r--r--zephyr/subsys/ap_pwrseq/signal_adc.c118
-rw-r--r--zephyr/subsys/ap_pwrseq/signal_gpio.c6
-rw-r--r--zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c103
-rw-r--r--zephyr/test/.pylintrc21
-rw-r--r--zephyr/test/accel_cal/BUILD.py2
-rw-r--r--zephyr/test/ap_power/BUILD.py2
-rw-r--r--zephyr/test/ap_power/prj.conf1
-rw-r--r--zephyr/test/ap_power/src/signals.c16
-rw-r--r--zephyr/test/base32/BUILD.py2
-rw-r--r--zephyr/test/crc/BUILD.py2
-rw-r--r--zephyr/test/drivers/BUILD.py2
-rw-r--r--zephyr/test/drivers/include/test/drivers/utils.h36
-rw-r--r--zephyr/test/drivers/src/host_cmd/motion_sense.c130
-rw-r--r--zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c3
-rw-r--r--zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c4
-rw-r--r--zephyr/test/drivers/src/utils.c47
-rw-r--r--zephyr/test/ec_app/BUILD.py2
-rw-r--r--zephyr/test/hooks/BUILD.py2
-rw-r--r--zephyr/test/i2c/BUILD.py2
-rw-r--r--zephyr/test/i2c_dts/BUILD.py2
-rw-r--r--zephyr/test/math/BUILD.py2
-rw-r--r--zephyr/test/system/BUILD.py2
-rw-r--r--zephyr/test/tasks/BUILD.py2
-rw-r--r--zephyr/zmake/.pylintrc4
-rw-r--r--zephyr/zmake/README.md4
-rw-r--r--zephyr/zmake/tests/test_build_config.py58
-rw-r--r--zephyr/zmake/tests/test_modules.py2
-rw-r--r--zephyr/zmake/tests/test_multiproc_executor.py30
-rw-r--r--zephyr/zmake/tests/test_multiproc_logging.py23
-rw-r--r--zephyr/zmake/tests/test_packers.py64
-rw-r--r--zephyr/zmake/tests/test_project.py4
-rw-r--r--zephyr/zmake/tests/test_util.py17
-rw-r--r--zephyr/zmake/tests/test_version.py12
-rw-r--r--zephyr/zmake/tests/test_zmake.py29
-rw-r--r--zephyr/zmake/zmake/__main__.py3
-rw-r--r--zephyr/zmake/zmake/build_config.py18
-rw-r--r--zephyr/zmake/zmake/configlib.py5
-rw-r--r--zephyr/zmake/zmake/generate_readme.py11
-rw-r--r--zephyr/zmake/zmake/jobserver.py37
-rw-r--r--zephyr/zmake/zmake/modules.py3
-rw-r--r--zephyr/zmake/zmake/multiproc.py319
-rw-r--r--zephyr/zmake/zmake/output_packers.py100
-rw-r--r--zephyr/zmake/zmake/project.py51
-rw-r--r--zephyr/zmake/zmake/toolchains.py3
-rw-r--r--zephyr/zmake/zmake/util.py25
-rw-r--r--zephyr/zmake/zmake/version.py2
-rw-r--r--zephyr/zmake/zmake/zmake.py121
176 files changed, 3052 insertions, 1029 deletions
diff --git a/CPPLINT.cfg b/CPPLINT.cfg
new file mode 100644
index 0000000000..d260909910
--- /dev/null
+++ b/CPPLINT.cfg
@@ -0,0 +1,4 @@
+set noparent
+# Disable cpplint, since EC is a C project that follows Linux kernel style.
+# cpplint is called by "cros lint".
+exclude_files=.*
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index c726f14214..eac83bb0c5 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -23,6 +23,7 @@ cros_license_check :
--exclude_regex=^third_party/unacl-curve25519/
[Hook Scripts]
+cros lint = cros lint ${PRESUBMIT_FILES}
presubmit_check = util/presubmit_check.sh
config_option_check = util/config_option_check.py
host_command_check = util/host_command_check.sh
diff --git a/board/anahera/sensors.c b/board/anahera/sensors.c
index 1ebfa7b97b..851930d1d3 100644
--- a/board/anahera/sensors.c
+++ b/board/anahera/sensors.c
@@ -77,11 +77,11 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
#define THERMAL_FAN \
{ \
.temp_host = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(73), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(65), \
[EC_TEMP_THRESH_HALT] = C_TO_K(80), \
}, \
.temp_host_release = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(65), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(73), \
}, \
}
__maybe_unused static const struct ec_thermal_config thermal_fan = THERMAL_FAN;
@@ -128,8 +128,8 @@ __maybe_unused static const struct ec_thermal_config thermal_charger =
#define THERMAL_REGULATOR \
{ \
.temp_host = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(53), \
- [EC_TEMP_THRESH_HALT] = C_TO_K(56), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(55), \
+ [EC_TEMP_THRESH_HALT] = C_TO_K(60), \
}, \
.temp_host_release = { \
[EC_TEMP_THRESH_HIGH] = C_TO_K(48), \
diff --git a/board/anahera/thermal.c b/board/anahera/thermal.c
index 8d9059bd09..8bd670c22a 100644
--- a/board/anahera/thermal.c
+++ b/board/anahera/thermal.c
@@ -37,38 +37,38 @@ struct fan_step {
static const struct fan_step fan_table[] = {
{
/* level 0 */
- .on = {53, 54, 0, -1},
+ .on = {53, 51, 0, -1},
.off = {99, 99, 99, -1},
.rpm = {0},
},
{
/* level 1 */
- .on = {54, 55, 0, -1},
- .off = {52, 53, 99, -1},
+ .on = {54, 52, 0, -1},
+ .off = {52, 50, 99, -1},
.rpm = {3000},
},
{
/* level 2 */
- .on = {55, 56, 0, -1},
- .off = {53, 54, 99, -1},
+ .on = {55, 53, 0, -1},
+ .off = {53, 51, 99, -1},
.rpm = {3400},
},
{
/* level 3 */
- .on = {56, 57, 0, -1},
- .off = {54, 55, 99, -1},
+ .on = {56, 54, 0, -1},
+ .off = {54, 52, 99, -1},
.rpm = {3800},
},
{
/* level 4 */
- .on = {57, 59, 54, -1},
- .off = {55, 56, 51, -1},
+ .on = {57, 55, 54, -1},
+ .off = {55, 53, 51, -1},
.rpm = {4100},
},
{
/* level 5 */
- .on = {58, 60, 60, -1},
- .off = {56, 58, 52, -1},
+ .on = {58, 56, 60, -1},
+ .off = {56, 54, 52, -1},
.rpm = {4400},
},
{
diff --git a/board/kano/pwm.c b/board/kano/pwm.c
index dc09a2bed5..f2c0d0db7d 100644
--- a/board/kano/pwm.c
+++ b/board/kano/pwm.c
@@ -20,7 +20,7 @@ const struct pwm_t pwm_channels[] = {
* lower PWM frequencies, but higher frequencies record a much
* lower maximum power.
*/
- .freq = 2400,
+ .freq = 25000,
},
[PWM_CH_FAN] = {
.channel = 5,
diff --git a/board/quackingstick/board.c b/board/quackingstick/board.c
index 8806e8c845..48414a2d0c 100644
--- a/board/quackingstick/board.c
+++ b/board/quackingstick/board.c
@@ -20,6 +20,7 @@
#include "driver/tcpm/tcpci.h"
#include "gpio.h"
#include "hooks.h"
+#include "led_common.h"
#include "lid_switch.h"
#include "mkbp_input_devices.h"
#include "peripheral_charger.h"
@@ -450,6 +451,13 @@ DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
void board_hibernate(void)
{
int i;
+ uint8_t brightness_range[EC_LED_COLOR_COUNT] = { 0 };
+
+ /*
+ * Turn off LED.
+ */
+ led_set_brightness(EC_LED_ID_BATTERY_LED, brightness_range);
+ led_auto_control(EC_LED_ID_BATTERY_LED, 0);
/*
* Sensors are unpowered in hibernate. Apply PD to the
diff --git a/board/scout/board.c b/board/scout/board.c
index 6e2b2d1e4e..ce0ee8ceae 100644
--- a/board/scout/board.c
+++ b/board/scout/board.c
@@ -98,7 +98,7 @@ static struct tcs3400_rgb_drv_data_t g_tcs3400_rgb_data = {
struct motion_sensor_t motion_sensors[] = {
[CLEAR_ALS] = {
.name = "Clear Light",
- .active_mask = SENSOR_ACTIVE_S0_S3,
+ .active_mask = SENSOR_ACTIVE_S0,
.chip = MOTIONSENSE_CHIP_TCS3400,
.type = MOTIONSENSE_TYPE_LIGHT,
.location = MOTIONSENSE_LOC_BASE,
@@ -119,7 +119,7 @@ struct motion_sensor_t motion_sensors[] = {
},
[RGB_ALS] = {
.name = "RGB Light",
- .active_mask = SENSOR_ACTIVE_S0_S3,
+ .active_mask = SENSOR_ACTIVE_S0,
.chip = MOTIONSENSE_CHIP_TCS3400,
.type = MOTIONSENSE_TYPE_LIGHT_RGB,
.location = MOTIONSENSE_LOC_BASE,
diff --git a/board/scout/board.h b/board/scout/board.h
index 67b9c3bdeb..6985742439 100644
--- a/board/scout/board.h
+++ b/board/scout/board.h
@@ -50,6 +50,8 @@
#define CONFIG_SHA256
/* Sensor */
+#undef CONFIG_MOTION_SENSE_RESUME_DELAY_US
+#define CONFIG_MOTION_SENSE_RESUME_DELAY_US (1000 * MSEC)
#define CONFIG_ACCEL_INTERRUPTS
#define CONFIG_CMD_ACCEL_INFO
/* Enable sensor fifo, must also define the _SIZE and _THRES */
diff --git a/board/taeko/board.h b/board/taeko/board.h
index 406749f8b8..77dbdbe637 100644
--- a/board/taeko/board.h
+++ b/board/taeko/board.h
@@ -152,6 +152,7 @@
/* System has back-lit keyboard */
#define CONFIG_PWM_KBLIGHT
+#undef CONFIG_MKBP_INPUT_DEVICES
/* I2C Bus Configuration */
#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0
diff --git a/board/taniks/board.h b/board/taniks/board.h
index b9016cdbbb..07780d90f2 100644
--- a/board/taniks/board.h
+++ b/board/taniks/board.h
@@ -179,7 +179,8 @@
#define GPIO_WP_L GPIO_EC_WP_ODL
/* System has back-lit keyboard */
-#define CONFIG_PWM_KBLIGHT
+#define CONFIG_PWM
+#define CONFIG_KEYBOARD_BACKLIGHT
/* I2C Bus Configuration */
#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0
@@ -294,7 +295,6 @@ enum battery_type {
};
enum pwm_channel {
- PWM_CH_KBLIGHT = 0, /* PWM3 */
PWM_CH_FAN, /* PWM5 */
PWM_CH_COUNT
};
diff --git a/board/taniks/keyboard.c b/board/taniks/keyboard.c
index 963453d3e6..e906275d1b 100644
--- a/board/taniks/keyboard.c
+++ b/board/taniks/keyboard.c
@@ -68,6 +68,47 @@ const uint8_t rgbkbd_vsize = RGB_GRID0_ROW;
const uint8_t rgbkbd_map[] = {
RGBKBD_DELM,
+ RGBKBD_COORD( 0, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 1, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 2, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 3, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 4, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 5, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 6, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 7, 0), RGBKBD_DELM,
+ RGBKBD_COORD( 0, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 1, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 2, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 3, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 4, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 5, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 6, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 7, 1), RGBKBD_DELM,
+ RGBKBD_COORD( 0, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 1, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 2, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 3, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 4, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 5, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 6, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 7, 2), RGBKBD_DELM,
+ RGBKBD_COORD( 0, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 1, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 2, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 3, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 4, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 5, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 6, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 7, 3), RGBKBD_DELM,
+ RGBKBD_COORD( 0, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 1, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 2, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 3, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 4, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 5, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 6, 4), RGBKBD_DELM,
+ RGBKBD_COORD( 7, 4), RGBKBD_DELM,
+ RGBKBD_DELM,
};
const size_t rgbkbd_map_size = ARRAY_SIZE(rgbkbd_map);
diff --git a/board/taniks/pwm.c b/board/taniks/pwm.c
index b5fef384f9..7e834385bf 100644
--- a/board/taniks/pwm.c
+++ b/board/taniks/pwm.c
@@ -11,17 +11,6 @@
#include "pwm_chip.h"
const struct pwm_t pwm_channels[] = {
- [PWM_CH_KBLIGHT] = {
- .channel = 3,
- .flags = 0,
- /*
- * Set PWM frequency to multiple of 50 Hz and 60 Hz to prevent
- * flicker. Higher frequencies consume similar average power to
- * lower PWM frequencies, but higher frequencies record a much
- * lower maximum power.
- */
- .freq = 2400,
- },
[PWM_CH_FAN] = {
.channel = 5,
.flags = PWM_CONFIG_OPEN_DRAIN,
@@ -29,11 +18,3 @@ const struct pwm_t pwm_channels[] = {
},
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
-
-static void board_pwm_init(void)
-{
-
- pwm_enable(PWM_CH_KBLIGHT, 1);
- pwm_set_duty(PWM_CH_KBLIGHT, 50);
-}
-DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT);
diff --git a/board/vell/i2c.c b/board/vell/i2c.c
index def6bff688..4f505d74c7 100644
--- a/board/vell/i2c.c
+++ b/board/vell/i2c.c
@@ -22,7 +22,7 @@ const struct i2c_port_t i2c_ports[] = {
/* I2C1 */
.name = "tcpc0,1",
.port = I2C_PORT_USB_C0_C1_TCPC,
- .kbps = 400,
+ .kbps = 1000,
.scl = GPIO_EC_I2C_USB_C0_C1_TCPC_SCL,
.sda = GPIO_EC_I2C_USB_C0_C1_TCPC_SDA,
},
@@ -30,7 +30,7 @@ const struct i2c_port_t i2c_ports[] = {
/* I2C2 */
.name = "ppc0,1",
.port = I2C_PORT_USB_C0_C1_PPC,
- .kbps = 400,
+ .kbps = 1000,
.scl = GPIO_EC_I2C_USB_C0_C1_PPC_BC_SCL,
.sda = GPIO_EC_I2C_USB_C0_C1_PPC_BC_SDA,
},
@@ -38,7 +38,7 @@ const struct i2c_port_t i2c_ports[] = {
/* I2C3 */
.name = "retimer0,1,2,3",
.port = I2C_PORT_USB_C0_C1_MUX,
- .kbps = 400,
+ .kbps = 1000,
.scl = GPIO_EC_I2C_USB_RT_SCL,
.sda = GPIO_EC_I2C_USB_RT_SDA,
},
@@ -46,7 +46,7 @@ const struct i2c_port_t i2c_ports[] = {
/* I2C4 */
.name = "tcpc2,3",
.port = I2C_PORT_USB_C2_C3_TCPC,
- .kbps = 400,
+ .kbps = 1000,
.scl = GPIO_EC_I2C_USB_C2_C3_TCPC_SCL,
.sda = GPIO_EC_I2C_USB_C2_C3_TCPC_SDA,
},
@@ -62,7 +62,7 @@ const struct i2c_port_t i2c_ports[] = {
/* I2C6 */
.name = "ppc2,3",
.port = I2C_PORT_USB_C2_C3_PPC,
- .kbps = 400,
+ .kbps = 1000,
.scl = GPIO_EC_I2C_USB_C2_C3_PPC_BC_RT_SCL,
.sda = GPIO_EC_I2C_USB_C2_C3_PPC_BC_RT_SDA,
},
diff --git a/board/vell/sensors.c b/board/vell/sensors.c
index aad7fc4ae4..3a4ceb2dc9 100644
--- a/board/vell/sensors.c
+++ b/board/vell/sensors.c
@@ -211,10 +211,10 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
{ \
.temp_host = { \
[EC_TEMP_THRESH_HIGH] = C_TO_K(85), \
- [EC_TEMP_THRESH_HALT] = C_TO_K(90), \
+ [EC_TEMP_THRESH_HALT] = C_TO_K(95), \
}, \
.temp_host_release = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \
}, \
}
__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU;
@@ -228,11 +228,11 @@ __maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU;
#define THERMAL_CHARGER \
{ \
.temp_host = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \
- [EC_TEMP_THRESH_HALT] = C_TO_K(80), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \
+ [EC_TEMP_THRESH_HALT] = C_TO_K(95), \
}, \
.temp_host_release = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(65), \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \
}, \
}
__maybe_unused static const struct ec_thermal_config thermal_charger =
diff --git a/board/vell/thermal.c b/board/vell/thermal.c
index 00b3e2ae9a..e72b86e3b1 100644
--- a/board/vell/thermal.c
+++ b/board/vell/thermal.c
@@ -19,13 +19,13 @@
struct fan_step {
/*
- * Sensor 1~4 trigger point, set -1 if we're not using this
+ * Sensor 1~5 trigger point, set -1 if we're not using this
* sensor to determine fan speed.
*/
int8_t on[TEMP_SENSOR_COUNT];
/*
- * Sensor 1~4 trigger point, set -1 if we're not using this
+ * Sensor 1~5 trigger point, set -1 if we're not using this
* sensor to determine fan speed.
*/
int8_t off[TEMP_SENSOR_COUNT];
@@ -37,32 +37,26 @@ struct fan_step {
static const struct fan_step fan_table[] = {
{
/* level 0 */
- .on = {49, 60, -1, 50, -1},
- .off = {99, 99, -1, 99, -1},
+ .on = {48, 60, 48, 47, -1},
+ .off = {99, 99, 99, 99, -1},
.rpm = {0},
},
{
/* level 1 */
- .on = {50, 60, -1, 51, -1},
- .off = {48, 99, -1, 49, -1},
- .rpm = {3400},
+ .on = {50, 60, 50, 49, -1},
+ .off = {47, 99, 47, 46, -1},
+ .rpm = {3600},
},
{
/* level 2 */
- .on = {52, 60, -1, 53, -1},
- .off = {49, 99, -1, 50, -1},
- .rpm = {4000},
+ .on = {53, 60, 53, 52, -1},
+ .off = {49, 99, 49, 48, -1},
+ .rpm = {4100},
},
{
/* level 3 */
- .on = {54, 64, -1, 55, -1},
- .off = {51, 59, -1, 52, -1},
- .rpm = {4450},
- },
- {
- /* level 4 */
- .on = {100, 100, -1, 100, -1},
- .off = {53, 63, -1, 54, -1},
+ .on = {100, 100, 100, 100, -1},
+ .off = {51, 59, 51, 50, -1},
.rpm = {5500},
},
};
@@ -84,14 +78,17 @@ static int fan_table_to_rpm(int fan, int *temp)
*/
if (temp[TEMP_SENSOR_1_SOC] < prev_tmp[TEMP_SENSOR_1_SOC] ||
temp[TEMP_SENSOR_2_CHARGER] < prev_tmp[TEMP_SENSOR_2_CHARGER] ||
+ temp[TEMP_SENSOR_3_WWAN] < prev_tmp[TEMP_SENSOR_3_WWAN] ||
temp[TEMP_SENSOR_4_DDR] < prev_tmp[TEMP_SENSOR_4_DDR]) {
for (i = current_level; i > 0; i--) {
if (temp[TEMP_SENSOR_1_SOC] <
fan_table[i].off[TEMP_SENSOR_1_SOC] &&
- temp[TEMP_SENSOR_4_DDR] <
- fan_table[i].off[TEMP_SENSOR_4_DDR] &&
temp[TEMP_SENSOR_2_CHARGER] <
- fan_table[i].off[TEMP_SENSOR_2_CHARGER])
+ fan_table[i].off[TEMP_SENSOR_2_CHARGER] &&
+ temp[TEMP_SENSOR_3_WWAN] <
+ fan_table[i].off[TEMP_SENSOR_3_WWAN] &&
+ temp[TEMP_SENSOR_4_DDR] <
+ fan_table[i].off[TEMP_SENSOR_4_DDR])
current_level = i - 1;
else
break;
@@ -99,15 +96,19 @@ static int fan_table_to_rpm(int fan, int *temp)
} else if (temp[TEMP_SENSOR_1_SOC] > prev_tmp[TEMP_SENSOR_1_SOC] ||
temp[TEMP_SENSOR_2_CHARGER] >
prev_tmp[TEMP_SENSOR_2_CHARGER] ||
+ temp[TEMP_SENSOR_3_WWAN] >
+ prev_tmp[TEMP_SENSOR_3_WWAN] ||
temp[TEMP_SENSOR_4_DDR] >
prev_tmp[TEMP_SENSOR_4_DDR]) {
for (i = current_level; i < NUM_FAN_LEVELS; i++) {
if (temp[TEMP_SENSOR_1_SOC] >
fan_table[i].on[TEMP_SENSOR_1_SOC] ||
+ (temp[TEMP_SENSOR_2_CHARGER] >
+ fan_table[i].on[TEMP_SENSOR_2_CHARGER] &&
+ temp[TEMP_SENSOR_3_WWAN] >
+ fan_table[i].on[TEMP_SENSOR_3_WWAN]) ||
temp[TEMP_SENSOR_4_DDR] >
- fan_table[i].on[TEMP_SENSOR_4_DDR] ||
- temp[TEMP_SENSOR_2_CHARGER] >
- fan_table[i].on[TEMP_SENSOR_2_CHARGER])
+ fan_table[i].on[TEMP_SENSOR_4_DDR])
current_level = i + 1;
else
break;
diff --git a/board/vell/usbc_config.c b/board/vell/usbc_config.c
index ee61614361..3831b13884 100644
--- a/board/vell/usbc_config.c
+++ b/board/vell/usbc_config.c
@@ -99,7 +99,7 @@ struct ppc_config_t ppc_chips[] = {
},
[USBC_PORT_C3] = {
.i2c_port = I2C_PORT_USB_C2_C3_PPC,
- .i2c_addr_flags = SYV682X_ADDR3_FLAGS,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
.drv = &syv682x_drv,
},
};
@@ -107,6 +107,12 @@ BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+struct ppc_config_t ppc_chips_old_c3 = {
+ .i2c_port = I2C_PORT_USB_C2_C3_PPC,
+ .i2c_addr_flags = SYV682X_ADDR3_FLAGS,
+ .drv = &syv682x_drv,
+};
+
/* USBC mux configuration - Alder Lake includes internal mux */
static const struct usb_mux usbc0_tcss_usb_mux = {
.usb_port = USBC_PORT_C0,
@@ -336,6 +342,9 @@ static void board_tcpc_init(void)
for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i)
ioex_init(i);
+ if (get_board_id() < 2)
+ ppc_chips[USBC_PORT_C3] = ppc_chips_old_c3;
+
/* Enable PPC interrupts. */
gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
diff --git a/common/keyboard_backlight.c b/common/keyboard_backlight.c
index 24a8ae56dd..4940d9a97e 100644
--- a/common/keyboard_backlight.c
+++ b/common/keyboard_backlight.c
@@ -10,6 +10,7 @@
#include "host_command.h"
#include "keyboard_backlight.h"
#include "lid_switch.h"
+#include "rgb_keyboard.h"
#include "timer.h"
#include "util.h"
@@ -90,9 +91,11 @@ int kblight_register(const struct kblight_drv *drv)
static void keyboard_backlight_init(void)
{
/* Uses PWM by default. Can be customized by board_kblight_init */
-#ifdef CONFIG_PWM_KBLIGHT
- kblight_register(&kblight_pwm);
-#endif
+ if (IS_ENABLED(CONFIG_PWM_KBLIGHT))
+ kblight_register(&kblight_pwm);
+ else if (IS_ENABLED(CONFIG_RGB_KEYBOARD))
+ kblight_register(&kblight_rgbkbd);
+
board_kblight_init();
if (kblight_init())
CPRINTS("kblight init failed");
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 46972de886..41e52cd10b 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -1154,7 +1154,7 @@ static enum ec_status host_cmd_motion_sense(struct host_cmd_handler_args *args)
case MOTIONSENSE_CMD_EC_RATE:
sensor = host_sensor_id_to_real_sensor(
- in->sensor_odr.sensor_num);
+ in->ec_rate.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
diff --git a/common/pwm.c b/common/pwm.c
index 74c079bbfd..7699405f3d 100644
--- a/common/pwm.c
+++ b/common/pwm.c
@@ -9,6 +9,7 @@
#include "hooks.h"
#include "host_command.h"
#include "pwm.h"
+#include "rgb_keyboard.h"
#include "util.h"
#ifdef CONFIG_PWM
@@ -64,11 +65,18 @@ host_command_pwm_set_duty(struct host_cmd_handler_args *args)
const struct ec_params_pwm_set_duty *p = args->params;
enum pwm_channel channel;
- if (get_target_channel(&channel, p->pwm_type, p->index))
- return EC_RES_INVALID_PARAM;
-
- pwm_set_raw_duty(channel, p->duty);
- pwm_enable(channel, p->duty > 0);
+ if (IS_ENABLED(CONFIG_RGB_KEYBOARD) &&
+ (p->pwm_type == EC_PWM_TYPE_KB_LIGHT)) {
+ uint8_t gcc = DIV_ROUND_NEAREST(p->duty * RGBKBD_MAX_GCC_LEVEL,
+ EC_PWM_MAX_DUTY);
+ if (rgbkbd_set_global_brightness(gcc))
+ return EC_RES_ERROR;
+ } else {
+ if (get_target_channel(&channel, p->pwm_type, p->index))
+ return EC_RES_INVALID_PARAM;
+ pwm_set_raw_duty(channel, p->duty);
+ pwm_enable(channel, p->duty > 0);
+ }
return EC_RES_SUCCESS;
}
@@ -82,12 +90,23 @@ host_command_pwm_get_duty(struct host_cmd_handler_args *args)
const struct ec_params_pwm_get_duty *p = args->params;
struct ec_response_pwm_get_duty *r = args->response;
- enum pwm_channel channel;
+ if (IS_ENABLED(CONFIG_RGB_KEYBOARD) &&
+ (p->pwm_type == EC_PWM_TYPE_KB_LIGHT)) {
+ uint8_t gcc;
- if (get_target_channel(&channel, p->pwm_type, p->index))
- return EC_RES_INVALID_PARAM;
+ if (rgbkbd_get_global_brightness(&gcc))
+ return EC_RES_ERROR;
+ r->duty = DIV_ROUND_NEAREST(gcc * EC_PWM_MAX_DUTY,
+ RGBKBD_MAX_GCC_LEVEL);
+ } else {
+ enum pwm_channel channel;
+
+ if (get_target_channel(&channel, p->pwm_type, p->index))
+ return EC_RES_INVALID_PARAM;
+
+ r->duty = pwm_get_raw_duty(channel);
+ }
- r->duty = pwm_get_raw_duty(channel);
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
diff --git a/common/rgb_keyboard.c b/common/rgb_keyboard.c
index 4edbcac3a8..c9987c5e5b 100644
--- a/common/rgb_keyboard.c
+++ b/common/rgb_keyboard.c
@@ -11,6 +11,7 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "keyboard_backlight.h"
#include "registers.h"
#include "rgb_keyboard.h"
#include "task.h"
@@ -38,16 +39,17 @@ uint8_t rgbkbd_table[EC_RGBKBD_MAX_KEY_COUNT];
static int set_color_single(struct rgb_s color, int x, int y)
{
struct rgbkbd *ctx = &rgbkbds[0];
- uint8_t gid;
+ uint8_t grid;
uint8_t col = 0;
uint8_t offset;
+ int rv;
if (rgbkbd_hsize <= x || rgbkbd_vsize <= y) {
return EC_ERROR_OVERFLOW;
}
/* Search the grid where x belongs to. */
- for (gid = 0; gid < rgbkbd_count; gid++, ctx++) {
+ for (grid = 0; grid < rgbkbd_count; grid++, ctx++) {
if (x < col + ctx->cfg->col_len)
break;
col += ctx->cfg->col_len;
@@ -56,9 +58,13 @@ static int set_color_single(struct rgb_s color, int x, int y)
offset = ctx->cfg->row_len * (x - col) + y;
ctx->buf[offset] = color;
- CPRINTS("Set [%d,%d] to color=[%d,%d,%d] (gid=%u offset=%u)",
- x, y, color.r, color.g, color.b, gid, offset);
- return ctx->cfg->drv->set_color(ctx, offset, &ctx->buf[offset], 1);
+ rv = ctx->cfg->drv->set_color(ctx, offset, &ctx->buf[offset], 1);
+
+ CPRINTS("%set (%d,%d) to color=(%d,%d,%d) grid=%u offset=%u (%d)",
+ rv ? "Failed to s" : "S",
+ x, y, color.r, color.g, color.b, grid, offset, rv);
+
+ return rv;
}
test_export_static uint8_t get_grid_size(const struct rgbkbd *ctx)
@@ -228,29 +234,154 @@ void rgbkbd_init_lookup_table(void)
*/
}
+int rgbkbd_set_global_brightness(uint8_t gcc)
+{
+ int e, grid;
+ int rv = EC_SUCCESS;
+
+ for (grid = 0; grid < rgbkbd_count; grid++) {
+ struct rgbkbd *ctx = &rgbkbds[grid];
+
+ e = ctx->cfg->drv->set_gcc(ctx, gcc);
+ if (e) {
+ CPRINTS("Failed to set GCC to %u for grid=%d (%d)",
+ gcc, grid, e);
+ rv = e;
+ continue;
+ }
+
+ ctx->gcc = gcc;
+ }
+
+ CPRINTS("Set GCC to %u", gcc);
+
+ /* Return EC_SUCCESS or the last error. */
+ return rv;
+}
+
+int rgbkbd_get_global_brightness(uint8_t *gcc)
+{
+ *gcc = rgbkbds[0].gcc;
+
+ return EC_SUCCESS;
+}
+
__overridable void board_enable_rgb_keyboard(bool enable) {}
-void rgbkbd_task(void *u)
+static int rgbkbd_init(void)
{
- uint32_t event;
- int i, rv;
+ int rv = EC_SUCCESS;
+ int e, i;
+ bool updated = false;
- board_enable_rgb_keyboard(true);
+ for (i = 0; i < rgbkbd_count; i++) {
+ struct rgbkbd *ctx = &rgbkbds[i];
- rgbkbd_init_lookup_table();
+ if (ctx->state >= RGBKBD_STATE_INITIALIZED)
+ continue;
+
+ e = ctx->cfg->drv->init(ctx);
+ if (e) {
+ CPRINTS("Failed to init GRID%d (%d)", i, e);
+ rv = e;
+ continue;
+ }
+
+ ctx->state = RGBKBD_STATE_INITIALIZED;
+ updated = true;
+
+ e = ctx->cfg->drv->set_scale(ctx, 0, 0x80, get_grid_size(ctx));
+ if (e) {
+ CPRINTS("Failed to set scale of GRID%d (%d)", i, e);
+ rv = e;
+ }
+ }
+
+ if (updated)
+ CPRINTS("Initialized (%d)", rv);
+
+ /* Return EC_SUCCESS or the last error. */
+ return rv;
+}
+
+static int rgbkbd_enable(int enable)
+{
+ int rv = EC_SUCCESS;
+ int e, i;
+ bool updated = false;
for (i = 0; i < rgbkbd_count; i++) {
struct rgbkbd *ctx = &rgbkbds[i];
- rv = ctx->cfg->drv->init(ctx);
- if (rv)
- CPRINTS("Failed to init GRID%d (%d)", i, rv);
- rv = ctx->cfg->drv->set_gcc(ctx, 0x80);
- rv |= ctx->cfg->drv->set_scale(ctx, 0, 0x80,
- get_grid_size(ctx));
- if (rv)
- CPRINTS("Failed to set GCC or scale (%d)", rv);
+
+ if (ctx->state >= RGBKBD_STATE_ENABLED && enable)
+ continue;
+
+ e = ctx->cfg->drv->enable(ctx, enable);
+ if (e) {
+ CPRINTS("Failed to %s GRID%d (%d)",
+ enable ? "enable" : "disable", i, e);
+ rv = e;
+ continue;
+ }
+
+ ctx->state = enable ?
+ RGBKBD_STATE_ENABLED : RGBKBD_STATE_DISABLED;
+ updated = true;
}
+ if (updated)
+ CPRINTS("%s (%d)", enable ? "Enabled" : "Disabled", rv);
+
+ /* Return EC_SUCCESS or the last error. */
+ return rv;
+}
+
+static int rgbkbd_kblight_set(int percent)
+{
+ uint8_t gcc = DIV_ROUND_NEAREST(percent * RGBKBD_MAX_GCC_LEVEL, 100);
+ return rgbkbd_set_global_brightness(gcc);
+}
+
+static int rgbkbd_kblight_get(void)
+{
+ uint8_t gcc;
+
+ if (rgbkbd_get_global_brightness(&gcc))
+ return 0;
+
+ return DIV_ROUND_NEAREST(gcc * 100, RGBKBD_MAX_GCC_LEVEL);
+}
+
+static int rgbkbd_get_enabled(void)
+{
+ return rgbkbds[0].state >= RGBKBD_STATE_ENABLED;
+}
+
+const struct kblight_drv kblight_rgbkbd = {
+ .init = rgbkbd_init,
+ .set = rgbkbd_kblight_set,
+ .get = rgbkbd_kblight_get,
+ /*
+ * We need to let RGBKBD manage enable/disable the backlight to keep
+ * the LEDs under the control of RGBKBD. Registering NULL also avoids
+ * ASSERT(!in_interrupt_context()) failure in task.c called from
+ * rgbkbd_enable API.
+ */
+ .enable = NULL,
+ .get_enabled = rgbkbd_get_enabled,
+};
+
+void rgbkbd_task(void *u)
+{
+ uint32_t event;
+
+ board_enable_rgb_keyboard(true);
+
+ rgbkbd_init_lookup_table();
+ rgbkbd_init();
+ rgbkbd_enable(1);
+ rgbkbd_set_global_brightness(0x80);
+
while (1) {
event = task_wait_event(100 * MSEC);
if (IS_ENABLED(CONFIG_RGB_KEYBOARD_DEBUG))
@@ -310,7 +441,6 @@ DECLARE_HOST_COMMAND(EC_CMD_RGBKBD, hc_rgbkbd, EC_VER_MASK(0));
test_export_static int cc_rgbk(int argc, char **argv)
{
- struct rgbkbd *ctx;
char *end, *comma;
struct rgb_s color;
int gcc, x, y, val;
@@ -351,12 +481,7 @@ test_export_static int cc_rgbk(int argc, char **argv)
gcc = strtoi(argv[1], &end, 0);
if (*end || gcc < 0 || gcc > UINT8_MAX)
return EC_ERROR_PARAM1;
- demo = RGBKBD_DEMO_OFF;
- for (i = 0; i < rgbkbd_count; i++) {
- ctx = &rgbkbds[i];
- ctx->cfg->drv->set_gcc(ctx, gcc);
- }
- return EC_SUCCESS;
+ return rgbkbd_set_global_brightness(gcc);
}
if (argc != 5)
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index aa7812bbed..defeebecfa 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -5020,14 +5020,18 @@ __maybe_unused static void pe_frs_snk_src_start_ams_entry(int port)
print_current_state(port);
- /* Contract is invalid now */
- pe_invalidate_explicit_contract(port);
-
/* Inform Protocol Layer this is start of AMS */
PE_SET_FLAG(port, PE_FLAGS_LOCALLY_INITIATED_AMS);
/* Shared PRS/FRS code, indicate FRS path */
PE_SET_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_PATH);
+
+ /*
+ * Invalidate the contract after the FRS flags set so the
+ * flags can be propagated to this function.
+ */
+ pe_invalidate_explicit_contract(port);
+
set_state_pe(port, PE_PRS_SNK_SRC_SEND_SWAP);
}
diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h
index 89be593eee..dceda73958 100644
--- a/core/cortex-m/irq_handler.h
+++ b/core/cortex-m/irq_handler.h
@@ -9,9 +9,10 @@
#define __CROS_EC_IRQ_HANDLER_H
#ifdef CONFIG_TASK_PROFILING
-#define bl_task_start_irq_handler "bl task_start_irq_handler\n"
+#define TASK_START_IRQ_HANDLER(excep_return) \
+ task_start_irq_handler(excep_return)
#else
-#define bl_task_start_irq_handler ""
+#define TASK_START_IRQ_HANDLER(excep_return)
#endif
/* Helper macros to build the IRQ handler and priority struct names */
@@ -23,20 +24,17 @@
*/
#define DECLARE_IRQ(irq, routine, priority) DECLARE_IRQ_(irq, routine, priority)
#define DECLARE_IRQ_(irq, routine, priority) \
- void IRQ_HANDLER(irq)(void) __attribute__((naked)); \
+ void IRQ_HANDLER(irq)(void); \
typedef struct { \
int fake[irq >= CONFIG_IRQ_COUNT ? -1 : 1]; \
} irq_num_check_##irq; \
static void __keep routine(void); \
void IRQ_HANDLER(irq)(void) \
{ \
- asm volatile("mov r0, lr\n" \
- "push {r0, lr}\n" \
- bl_task_start_irq_handler \
- "bl "#routine"\n" \
- "pop {r0, lr}\n" \
- "b task_resched_if_needed\n" \
- ); \
+ void *ret = __builtin_return_address(0); \
+ TASK_START_IRQ_HANDLER(ret); \
+ routine(); \
+ task_resched_if_needed(ret); \
} \
const struct irq_priority __keep IRQ_PRIORITY(irq) \
__attribute__((section(".rodata.irqprio"))) \
diff --git a/docs/ec_terms.md b/docs/ec_terms.md
index d5f3690615..b865df0078 100644
--- a/docs/ec_terms.md
+++ b/docs/ec_terms.md
@@ -65,6 +65,11 @@
switching, sensor management, and other functions, offloading these tasks
from the [AP](#ap).
+* **ectool** {#ectool}
+
+ The [ectool] is the [AP](#ap) console's CLI for sending commands to the
+ [EC](#ec).
+
* **EC-3PO** {#ec-3po}
A replacement of the current UART-based console which moves much of the code
@@ -232,17 +237,22 @@
second). Typical use is to provide a debug console to the EC. [RS-232] is
the protocol standard used by UARTs.
+* **USBA - USB Type-A** {#usba}
+
+ Traditional USB Host port.
+
* **VCONN - Connector Voltage** {#vconn}
See the [USB-C documentation](./usb-c.md#vconn) for more details.
[BC 1.2 Specification]: <https://www.usb.org/document-library/battery-charging-v12-spec-and-adopters-agreement>
-[CrOS Board Info]: <https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md>
[CEC Wikipedia page]: <https://en.wikipedia.org/wiki/Consumer_Electronics_Control>
+[CrOS Board Info]: <https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md>
[DPTF Readme]: <https://github.com/intel/dptf/blob/HEAD/README.txt>
-[eSPI Specification]: <https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0.pdf>
+[EC MKBP driver]: <https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/common/keyboard_mkbp.c>
[FAFT design doc]: <https://chromium.googlesource.com/chromiumos/third_party/autotest/+/HEAD/docs/faft-design-doc.md>
[I2C Specification]: <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>
-[RS-232]: <https://en.wikipedia.org/wiki/RS-232>
-[EC MKBP driver]: <https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/common/keyboard_mkbp.c>
[Low Pin Count bus]: https://en.wikipedia.org/wiki/Low_Pin_Count
+[RS-232]: <https://en.wikipedia.org/wiki/RS-232>
+[eSPI Specification]: <https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0.pdf>
+[ectool]: ../docs/ap-ec-comm.md
diff --git a/docs/zephyr/zephyr_ap_power.md b/docs/zephyr/zephyr_ap_power.md
new file mode 100644
index 0000000000..0b95e375d6
--- /dev/null
+++ b/docs/zephyr/zephyr_ap_power.md
@@ -0,0 +1,58 @@
+# Zephyr EC AP Power Requirements
+
+[TOC]
+
+## Overview
+
+[AP] power configures the minimum amount of power needed to boot the Application
+Processor.
+
+## Kconfig Options
+
+The Kconfig option `CONFIG_PLATFORM_EC_BOOT_AP_POWER_REQUIREMENTS` enables checking power
+thresholds before booting the AP. See the file [Kconfig.ap_power] for all Kconfig
+options related to this feature.
+
+## Devicetree Nodes
+
+None required.
+
+## Board Specific Code
+
+None required.
+
+## Threads
+
+AP_POWER support does not enable any threads.
+
+## Testing and Debugging
+
+Use the battfake command to force the battery level, independent of the actual battery charge.
+To verify the AP power thresholds, force the battery level below the
+`CONFIG_PLATFORM_EC_CHARGER_MIN_BAT_PCT_FOR_POWER_ON` setting and reboot the EC.
+The EC should prevent the AP from powering up.
+
+`battfake` usage: battfake <percent> (-1 = use real level)
+
+```
+battfake 2
+reboot
+/* Verify that AP does ot boot */
+battfak3 3
+/* Verify that AP boots */
+/* Restore normal operation */
+battfake -1
+```
+## Example
+
+For Herobrine, the minimum battery level to boot the AP without AC is 2 percent
+of the battery capacity and the minimum AC power to boot the AP with a battery
+is set to 10000 milliwats.
+
+```
+CONFIG_PLATFORM_EC_CHARGER_MIN_BAT_PCT_FOR_POWER_ON=2
+CONFIG_PLATFORM_EC_CHARGER_MIN_POWER_MW_FOR_POWER_ON=10000
+```
+
+[AP]: ../ec_terms.md#ap
+[Kconfig.ap_power]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig.ap_power
diff --git a/docs/zephyr/zephyr_battery.md b/docs/zephyr/zephyr_battery.md
index 6b084bf95f..c84bcc3b8e 100644
--- a/docs/zephyr/zephyr_battery.md
+++ b/docs/zephyr/zephyr_battery.md
@@ -50,7 +50,7 @@ Example:
```
-Here `vendor_part` will be the default battery type. If this node label is
+Here `vendor_part` will be the default battery type. If this [*node label*] is
present in the overlay, the [DEFAULT_BATTERY_TYPE] is set in the battery shim
code with the labeled battery type. The `vendor` and `part` references must
match an existing battery defined in [battery bindings directory].
@@ -137,6 +137,10 @@ requires the battery module for correct operation.
## Testing and Debugging
+### EC Console Commands
+
+#### battery
+
The `battery` [EC console command] may be invoked to check battery information
on a flashed board.
@@ -169,17 +173,101 @@ full_factor:0.97
shutdown_soc:4 %
```
+#### pwr_avg
+
+The `pwr_avg` [EC console command] logs the battery charging rate by querying
+the battery fuel gauge driver.
+
+Example output of `uart:~$ pwr_avg`:
+
+Charging
+
+```
+mv = 13073
+ma = 439
+mw = 573
+```
+
+Discharging
+
+```
+mv = 12824
+ma = -146
+mw = -1872
+```
+
+Note: A fully charged board may report `ma = 0` and `mw = 0` average rates.
+
+#### chgstate
+
+The `chgstate` [EC console command] may be invoked to debug and manipulate machine
+charging state.
+
+Example output of `uart:~$ chgstate`:
+
+```
+state = charge
+ac = 1
+batt_is_charging = 1
+chg.*:
+ voltage = 13200mV
+ current = 0mA
+ input_current = 3000mA
+ status = 0xc010
+ option = 0x2830004
+ flags = 0x0
+batt.*:
+ temperature = 26C
+ state_of_charge = 100%
+ voltage = 13037mV
+ current = 0mA
+ desired_voltage = 0mV
+ desired_current = 0mA
+ flags = 0x2
+ remaining_capacity = 4436mAh
+ full_capacity = 4436mAh
+ is_present = YES
+requested_voltage = 0mV
+requested_current = 0mA
+chg_ctl_mode = 0
+manual_voltage = -1
+manual_current = -1
+user_current_limit = -1mA
+battery_seems_to_be_dead = 0
+battery_seems_to_be_disconnected = 0
+battery_was_removed = 0
+debug output = off
+```
+
+### AP Console Commands (ectool)
+
+#### chargestate
+
+The `chargestate` [ectool] command may be invoked to debug and manipulate
+machine charging state.
+
+Usage output of `uart: # ectool chargestate`:
+
+```
+Usage:
+ chargestate show - show current state
+ chargestate param NUM [VALUE] - get/set param NUM
+ chargestate param help - show known param NUMs
+```
+
<!-- Reference Links -->
+[CONFIG_PLATFORM_EC_BATTERY_PRESENT_CUSTOM]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig.battery?q=%22PLATFORM_EC_BATTERY_PRESENT_CUSTOM%22&ss=chromiumos
[DEFAULT_BATTERY_TYPE]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/shim/src/battery.c?q=%22DEFAULT_BATTERY_TYPE%22&ss=chromiumos
[EC console command]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/README.md#useful-ec-console-commands
[Example CL adding a new battery]: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3312506/
[Example CL enabling batteries on a board]: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3200068/
[Kconfig.battery]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig.battery
-[CONFIG_PLATFORM_EC_BATTERY_PRESENT_CUSTOM]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig.battery?q=%22PLATFORM_EC_BATTERY_PRESENT_CUSTOM%22&ss=chromiumos
[Zephyr I2C]: zephyr_i2c.md#Mapping-legacy-I2C-port-numbers-to-Zephyr-devicetree-nodes
[Zephyr gpios]: zephyr_gpio.md#Devicetree-Nodes
[battery bindings directory]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/battery/
[battery-smart enum]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/battery/battery-smart.yaml?q=%22enum:%22&ss=chromiumos
[cros-ec-i2c-port-base.yaml]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
+[ectool]: ../ap-ec-comm.md
[task]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/shim/include/shimmed_task_id.h
+[*node label*]: https://docs.zephyrproject.org/latest/build/dts/intro.html#dt-node-labels
diff --git a/docs/zephyr/zephyr_gpio.md b/docs/zephyr/zephyr_gpio.md
index 1d563513cd..5e70562ab9 100644
--- a/docs/zephyr/zephyr_gpio.md
+++ b/docs/zephyr/zephyr_gpio.md
@@ -24,7 +24,7 @@ the devicetree node with
all GPIOs from this node (unless the `no-auto-init` property is present).
Legacy C source code accesses GPIOs using the specified
`enum-name` property as an enum name of the GPIO.
-Zephyr based code uses the node label, an alias, or other node reference
+Zephyr based code uses the [*node label*], an alias, or other node reference
to identify the GPIO.
Named GPIO properties:
@@ -41,7 +41,7 @@ initialization time, and selectively enabled by code at some later time.
The file [gpio-enum-name.yaml] defines the list of valid `enum-name` values.
In the GPIO declaration use the lowercase net name from the schematic as the
-*node name*, and the same net name prefixed with `gpio_` as *node label*.
+*node name*, and the same net name prefixed with `gpio_` as [*node label*].
For example:
```
@@ -87,7 +87,7 @@ GPIOs references that are not in legacy common code should use the
to access the GPIO.
GPIOs are referenced in the `named-gpios` child nodes using the
-node label (if one exists), an alias to a node label, or
+[*node label*] (if one exists), an alias to a [*node label*], or
indirectly as a node reference via as a `phandle` in another node.
To facilitate this, all GPIO child nodes in `named-gpios`
@@ -97,7 +97,7 @@ These pointers are accessible via the following macros:
Macro | Argument | Description
:------- | :---------- | :-------
-`GPIO_DT_FROM_NODELABEL` | nodelabel | Uses a node label to reference the GPIO node.
+`GPIO_DT_FROM_NODELABEL` | nodelabel | Uses a [*node label*] to reference the GPIO node.
`GPIO_DT_FROM_NODE` | node | Uses a node id (referenced as a `phandle` in another node).
`GPIO_DT_FROM_ALIAS` | alias | Uses an alias to a label on the GPIO node.
@@ -279,7 +279,7 @@ Child nodes of this single node contain the following properties:
Property | Description | Settings
:------- | :---------- | :-------
-`irq-pin` | A reference via a node label to the named-gpio that is associated with this interrupt. | `<&gpio_label>`
+`irq-pin` | A reference via a [*node label*] to the named-gpio that is associated with this interrupt. | `<&gpio_label>`
`flags` | The GPIO [interrupt flags](https://docs.zephyrproject.org/latest/reference/peripherals/gpio.html) that define how the interrupt is generated. | `GPIO_INT_<flags>`
`handler` | The C name of the interrupt handler that handles the interrupt. | C function name.
@@ -431,7 +431,7 @@ property `GPIO_ENTERING_RW`.
val = gpio_get_level(GPIO_ENTERING_RW);
```
-Use the `node label` to reference the GPIO in other devicetree nodes:
+Use the [*node label*] to reference the GPIO in other devicetree nodes:
```
my_node: my-node {
@@ -456,3 +456,4 @@ project.
[gpio.dts]: ../../zephyr/projects/volteer/volteer/gpio.dts
[interrupts.dts]: ../../zephyr/projects/volteer/volteer/interrupts.dts
[BUILD.py]: ../../zephyr/projects/volteer/volteer/BUILD.py
+[*node label*]: https://docs.zephyrproject.org/latest/build/dts/intro.html#dt-node-labels \ No newline at end of file
diff --git a/docs/zephyr/zephyr_i2c.md b/docs/zephyr/zephyr_i2c.md
index 4f001e4408..da54a373a5 100644
--- a/docs/zephyr/zephyr_i2c.md
+++ b/docs/zephyr/zephyr_i2c.md
@@ -47,7 +47,7 @@ Example enabling I2C0 and I2C3 at 100 KHz and 1 MHz, respectively.
Nuvoton ECs use two devicetree nodes to describe the I2C buses used, an I2C
controller and an I2C port.
-Nuvoton I2C node labels use the following pattern:
+Nuvoton I2C [*node labels*] use the following pattern:
- I2C controller: `&i2c_ctrl<controller>`
- I2C port: `&i2c<controller>_<port>`
@@ -352,3 +352,4 @@ below:
[`CONFIG_I2C_SHELL`]: https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_I2C_SHELL
[cros-ec-i2c-port-base.yaml]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml
[volteer.dts]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/boards/arm/volteer/volteer.dts;
+[*node labels*]: https://docs.zephyrproject.org/latest/build/dts/intro.html#dt-node-labels \ No newline at end of file
diff --git a/docs/zephyr/zephyr_new_board_checklist.md b/docs/zephyr/zephyr_new_board_checklist.md
index f83aa3a188..eb4584af2c 100644
--- a/docs/zephyr/zephyr_new_board_checklist.md
+++ b/docs/zephyr/zephyr_new_board_checklist.md
@@ -25,7 +25,8 @@ Each feature includes the following sub-tasks:
the feature. `Kconfig` options are enabled in one of the [project
configuration files].
- **Devicetree Nodes** - This section details the devicetree nodes and
- properties required by the feature.
+ properties required by the feature. The [Zephyr Introduction to Devicetree]
+ provides a conceptual overview of devicetree and how Zephyr uses it.
- **Board Specific Code** - When present, this section details any C code that
your project must implement.
- **Threads** - This section details the threads created by the feature and
@@ -53,7 +54,9 @@ EC Feature | Ne
:-------------------------------------------------------------------------- | :-----------------:
[Configure EC Chipset (TODO)](./zephyr_template.md) | yes
[Configure AP to EC Communication](./zephyr_ap_ec_comm.md) | yes
+[Configure AP Power Thresholds](./zephyr_ap_power.md) | yes
[Configure AP Power Sequencing (TODO)](./zephyr_template.md) | yes
+[Configure USB-A](./zephyr_usba.md) | no
[Configure USB-C (TODO)](./zephyr_template.md) | yes
[Configure Charger (TODO)](./zephyr_template.md) | yes
[Configure I2C Buses](./zephyr_i2c.md) | yes
@@ -66,3 +69,5 @@ EC Feature | Ne
[Configure BC1.2 Charger Detector (TODO)](./zephyr_template.md) | no
[Configure ADC](./zephyr_adc.md) | no
[Configure Temperature Sensors](./zephyr_temperature_sensor.md) | no
+
+[Zephyr Introduction to Devicetree]: https://docs.zephyrproject.org/latest/build/dts/intro.html
diff --git a/docs/zephyr/zephyr_template.md b/docs/zephyr/zephyr_template.md
index f75883eec9..f36c9f90da 100644
--- a/docs/zephyr/zephyr_template.md
+++ b/docs/zephyr/zephyr_template.md
@@ -8,21 +8,19 @@
## Kconfig Options
-*List the Kconfig options that enable the feature and list any sub-configuration
-options that control the behavior of the feature.*
-
-Kconfig Option | Default | Documentation
-:------------------------------------- | :-----: | :------------
-`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig)
-
-Kconfig sub-option | Default | Documentation
-:------------------------------------- | :-----: | :------------
-`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig)
+*Link to the file providing all the Kconfig options related to the feature. If
+the Kconfig options are not currently in a standalone file, consider moving the
+related Kconfigs into their own file.*
+*Example CL moving I2C related configs into a new file: https://crrev.com/c/3575081*
*Note - Avoid documenting `CONFIG_` options in the markdown as the relevant
-`Kconfig*` contains the authoritative definition. Link directly to the Kconfig
-option in source like this: [I2C Passthru Restricted].*
+`Kconfig*` contains the authoritative definition. If there is one main Kconfig
+that must be enabled for the feature, mention it in this section. See the [I2C
+documentation](zephyr_i2c.md#kconfig-options) for an example.*
+
+*If the `Kconfig` file does not provide sufficient help descriptions, please fix
+them.*
## Devicetree Nodes
@@ -44,6 +42,9 @@ compile and run. For many features, this can section can be empty.*
*Provide any tips for testing and debugging the EC feature.*
+*It's especially helpful to document EC console commands and `ectool` commands
+from the AP in this section. Please provide example output.*
+
## Example
*Provide code snippets from a working board to walk the user through
diff --git a/docs/zephyr/zephyr_usba.md b/docs/zephyr/zephyr_usba.md
new file mode 100644
index 0000000000..ce66125905
--- /dev/null
+++ b/docs/zephyr/zephyr_usba.md
@@ -0,0 +1,78 @@
+# Zephyr USBA Configuration
+
+[TOC]
+
+## Overview
+
+[USBA] is used to configure the number of USB Type-A ports in the system and
+optional control of the power supplied by said ports.
+
+## Kconfig Options
+
+`CONFIG_PLATFORM_EC_USBA` enables support for USB-A ports in the EC application.
+Refer to [Kconfig.usba] for all sub-options controlling USB-A ports.
+
+## Devicetree Nodes
+
+By default, for each USB Type-A port, a GPIO pin is required to control when power
+is supplied to the port. The GPIO pins are described in Device Tree nodes.
+
+Refer to the [named-gpios.yaml] and [cros-ec,usba-port-enable-pins.yaml] child-binding
+files for details about gpio properties.
+
+## Board Specific Code
+
+none
+
+## Threads
+
+When `CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y`, then the EC application automatically
+powers up USB-A ports when the AP chipset starts up and powers off the USB-A ports
+when the AP chipset shuts down.
+
+## Testing and Debugging
+
+Use the gpioset console command to manually enable and disable the USB Type-A port power.
+
+`gpioset` usage: gpioset <pin_name> <0 | 1>
+
+The `usbchargemode` console command is used to enable and disable charging
+from the USB Type-A port.
+
+* For dumb power ports: `usbchargemode` <port> <on | off>
+* For smart power ports: `usbchargemode` <port> <0 | 1 | 2 | 3> <0 | 1>
+
+Charging from USB Type-A ports can be controlled from the AP using ectool `usbchargemode`.
+
+`ectool usbchargemode` <port> <disabled | SDP | CDP | DCP> [inhibit_charge]
+
+Refer to the Application Processor to EC communication for more information about using[ ectool].
+
+## Example
+
+The Herobrine board has one USB Type-A port:
+
+The following configures the project for one port.
+
+```
+`CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y`
+```
+
+The following device tree node configures the gpio pin.
+
+```
+gpio_en_usb_a_5v: en_usb_a_5v {
+ gpios = <&gpiof 0 GPIO_OUT_LOW>;
+};
+
+usba-port-enable-list {
+ compatible = "cros-ec,usba-port-enable-pins";
+ enable-pins = <&gpio_en_usb_a_5v>;
+};
+```
+
+[USBA]: ../ec_terms.md#usba
+[Kconfig.usba]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig.usba
+[named-gpios.yaml]: ../../zephyr/dts/bindings/gpio/named-gpios.yaml
+[cros-ec,usba-port-enable-pins.yaml]: ../../zephyr/dts/bindings/gpio/cros-ec,usba-port-enable-pins.yaml
+[ectool]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/util/ectool.c;?q=function:ms_help&ss=chromiumos
diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c
index 7861ec95bc..c1e4f203fd 100644
--- a/driver/charger/isl923x.c
+++ b/driver/charger/isl923x.c
@@ -98,6 +98,7 @@ static int learn_mode;
K_MUTEX_DEFINE(control1_mutex_isl923x);
static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable);
+static enum ec_error_list isl923x_discharge_on_ac_weak_disable(int chgnum);
/* Charger parameters */
static const struct charger_info isl9237_charger_info = {
@@ -395,8 +396,7 @@ static enum ec_error_list isl923x_set_mode(int chgnum, int mode)
* See crosbug.com/p/51196. Always disable learn mode unless it was set
* explicitly.
*/
- if (!learn_mode)
- rv = isl923x_discharge_on_ac(chgnum, 0);
+ rv = isl923x_discharge_on_ac_weak_disable(chgnum);
/* ISL923X does not support inhibit mode setting. */
return rv;
@@ -763,13 +763,15 @@ init_fail:
CPRINTS("%s init failed!", CHARGER_NAME);
}
-static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable)
+/*
+ * Writes to ISL923X_REG_CONTROL1, unsafe as it does not lock
+ * control1_mutex_isl923x.
+ */
+static enum ec_error_list isl923x_discharge_on_ac_unsafe(int chgnum, int enable)
{
int rv;
int control1;
- mutex_lock(&control1_mutex_isl923x);
-
rv = raw_read16(chgnum, ISL923X_REG_CONTROL1, &control1);
if (rv)
goto out;
@@ -782,9 +784,32 @@ static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable)
rv = raw_write16(chgnum, ISL923X_REG_CONTROL1, control1);
- learn_mode = !rv && enable;
+ if (!rv)
+ learn_mode = enable;
out:
+ return rv;
+}
+
+static enum ec_error_list isl923x_discharge_on_ac(int chgnum, int enable)
+{
+ int rv;
+
+ mutex_lock(&control1_mutex_isl923x);
+ rv = isl923x_discharge_on_ac_unsafe(chgnum, enable);
+ mutex_unlock(&control1_mutex_isl923x);
+ return rv;
+}
+
+/* Disables discharge on ac only if it wasn't explicitly enabled. */
+static enum ec_error_list isl923x_discharge_on_ac_weak_disable(int chgnum)
+{
+ int rv = 0;
+
+ mutex_lock(&control1_mutex_isl923x);
+ if (!learn_mode)
+ rv = isl923x_discharge_on_ac_unsafe(chgnum, 0);
+
mutex_unlock(&control1_mutex_isl923x);
return rv;
}
diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c
index 4fbb137871..b2a061d696 100644
--- a/driver/charger/isl9241.c
+++ b/driver/charger/isl9241.c
@@ -63,6 +63,9 @@ static const struct charger_info isl9241_charger_info = {
};
static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable);
+static enum ec_error_list isl9241_discharge_on_ac_unsafe(int chgnum,
+ int enable);
+static enum ec_error_list isl9241_discharge_on_ac_weak_disable(int chgnum);
static inline enum ec_error_list isl9241_read(int chgnum, int offset,
int *value)
@@ -199,14 +202,12 @@ static enum ec_error_list isl9241_set_mode(int chgnum, int mode)
int rv;
/*
- * See crosbug.com/p/51196. Always disable learn mode unless it was set
- * explicitly.
+ * See crosbug.com/p/51196.
+ * Disable learn mode if it wasn't explicitly enabled.
*/
- if (!learn_mode) {
- rv = isl9241_discharge_on_ac(chgnum, 0);
- if (rv)
- return rv;
- }
+ rv = isl9241_discharge_on_ac_weak_disable(chgnum);
+ if (rv)
+ return rv;
/*
* Charger inhibit
@@ -308,18 +309,42 @@ static enum ec_error_list isl9241_post_init(int chgnum)
return EC_SUCCESS;
}
-static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable)
+/*
+ * Writes to ISL9241_REG_CONTROL1, unsafe as it does not lock
+ * control1_mutex_isl9241.
+ */
+static enum ec_error_list isl9241_discharge_on_ac_unsafe(int chgnum,
+ int enable)
{
- int rv;
-
- mutex_lock(&control1_mutex_isl9241);
-
- rv = isl9241_update(chgnum, ISL9241_REG_CONTROL1,
+ int rv = isl9241_update(chgnum, ISL9241_REG_CONTROL1,
ISL9241_CONTROL1_LEARN_MODE,
(enable) ? MASK_SET : MASK_CLR);
if (!rv)
learn_mode = enable;
+ return rv;
+}
+
+/* Disables discharge on ac only if it wasn't explicitly enabled. */
+static enum ec_error_list isl9241_discharge_on_ac_weak_disable(int chgnum)
+{
+ int rv = 0;
+
+ mutex_lock(&control1_mutex_isl9241);
+ if (!learn_mode) {
+ rv = isl9241_discharge_on_ac_unsafe(chgnum, 0);
+ }
+
+ mutex_unlock(&control1_mutex_isl9241);
+ return rv;
+}
+
+static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable)
+{
+ int rv = 0;
+
+ mutex_lock(&control1_mutex_isl9241);
+ rv = isl9241_discharge_on_ac_unsafe(chgnum, enable);
mutex_unlock(&control1_mutex_isl9241);
return rv;
}
diff --git a/driver/charger/rt9490.c b/driver/charger/rt9490.c
index e2d2b76b0b..e3eee4ebad 100644
--- a/driver/charger/rt9490.c
+++ b/driver/charger/rt9490.c
@@ -264,7 +264,7 @@ static inline int rt9490_enable_jeita(int chgnum, bool en)
en ? MASK_CLR : MASK_SET);
}
-static inline int rt9490_enable_adc(int chgnum, bool en)
+int rt9490_enable_adc(int chgnum, bool en)
{
return rt9490_update8(chgnum, RT9490_REG_ADC_CTRL, RT9490_ADC_EN,
en ? MASK_SET : MASK_CLR);
diff --git a/driver/charger/rt9490.h b/driver/charger/rt9490.h
index 0ea7746d8e..a6ace8c1eb 100644
--- a/driver/charger/rt9490.h
+++ b/driver/charger/rt9490.h
@@ -4,6 +4,8 @@
*
* Richtek 5A 1-4 cell buck-boost switching battery charger driver.
*/
+#include <stdbool.h>
+
#ifndef __CROS_EC_RT9490_H
#define __CROS_EC_RT9490_H
@@ -241,4 +243,6 @@ extern const struct bc12_drv rt9490_bc12_drv;
void rt9490_interrupt(int port);
+int rt9490_enable_adc(int chgnum, bool en);
+
#endif /* __CROS_EC_RT9490_H */
diff --git a/driver/led/aw20198.c b/driver/led/aw20198.c
index 5537556ffa..1c6bc4933c 100644
--- a/driver/led/aw20198.c
+++ b/driver/led/aw20198.c
@@ -143,11 +143,6 @@ static int aw20198_init(struct rgbkbd *ctx)
rv = aw20198_reset(ctx);
msleep(3);
- rv |= aw20198_enable(ctx, true);
- if (rv) {
- CPRINTS("Failed to enable or reset (%d)", rv);
- return rv;
- }
/* Read chip ID, assuming page is still 0. */
rv = aw20198_read(ctx, AW20198_REG_RSTN, &id);
diff --git a/driver/led/is31fl3743b.c b/driver/led/is31fl3743b.c
index f1a8833318..5539eee9b0 100644
--- a/driver/led/is31fl3743b.c
+++ b/driver/led/is31fl3743b.c
@@ -164,11 +164,6 @@ static int is31fl3743b_init(struct rgbkbd *ctx)
rv = is31fl3743b_reset(ctx);
msleep(3);
- rv |= is31fl3743b_enable(ctx, true);
- if (rv) {
- CPRINTS("Failed to enable or reset (%d)", rv);
- return rv;
- }
if (IS_ENABLED(CONFIG_RGB_KEYBOARD_DEBUG)) {
uint8_t val;
diff --git a/extra/usb_updater/usb_updater2.c b/extra/usb_updater/usb_updater2.c
index 12ee1615fc..81cf48a680 100644
--- a/extra/usb_updater/usb_updater2.c
+++ b/extra/usb_updater/usb_updater2.c
@@ -354,7 +354,7 @@ static int find_interface(struct usb_endpoint *uep)
for (j = 0; j < iface0->num_altsetting; j++) {
iface = &iface0->altsetting[j];
if (find_endpoint(iface, uep)) {
- iface_num = i;
+ iface_num = iface->bInterfaceNumber;
goto out;
}
}
diff --git a/firmware_builder.py b/firmware_builder.py
index 6229e87539..625cb5166a 100755
--- a/firmware_builder.py
+++ b/firmware_builder.py
@@ -78,6 +78,14 @@ def build(opts):
with open(opts.metrics, 'w') as f:
f.write(json_format.MessageToJson(metric_list))
+ # Ensure that there are no regressions for boards that build successfully
+ # with clang: b/172020503.
+ cmd = ['./util/build_with_clang.py']
+ print(f'# Running {" ".join(cmd)}.')
+ subprocess.run(cmd,
+ cwd=os.path.dirname(__file__),
+ check=True)
+
UNITS = {
'B': 1,
diff --git a/include/ec_commands.h b/include/ec_commands.h
index df5fee3250..1aff487bbe 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -7094,6 +7094,8 @@ enum rgbkbd_state {
RGBKBD_STATE_RESET = 0,
/* RGB keyboard is initialized but not enabled. */
RGBKBD_STATE_INITIALIZED,
+ /* RGB keyboard is disabled. */
+ RGBKBD_STATE_DISABLED,
/* RGB keyboard is enabled and ready to receive a command. */
RGBKBD_STATE_ENABLED,
diff --git a/include/rgb_keyboard.h b/include/rgb_keyboard.h
index 0500ce859f..2c6a550e7b 100644
--- a/include/rgb_keyboard.h
+++ b/include/rgb_keyboard.h
@@ -12,6 +12,8 @@
/* Use this instead of '3' for readability where applicable. */
#define SIZE_OF_RGB sizeof(struct rgb_s)
+#define RGBKBD_MAX_GCC_LEVEL 0xff
+
enum rgbkbd_demo {
RGBKBD_DEMO_OFF = 0,
RGBKBD_DEMO_FLOW = 1,
@@ -37,6 +39,8 @@ struct rgbkbd {
const struct rgbkbd_cfg * const cfg;
/* Current state of the port */
enum rgbkbd_state state;
+ /* Global current control (a.k.a. backlight brightness) */
+ uint8_t gcc;
/* Buffer containing color info for each dot. */
struct rgb_s *buf;
};
@@ -173,3 +177,17 @@ __override_proto void board_enable_rgb_keyboard(bool enable);
*/
extern const uint8_t rgbkbd_map[];
extern const size_t rgbkbd_map_size;
+
+/**
+ * Set/get global brightness of the RGB keyboard.
+ *
+ * @param gcc Brightness level 0 ~ RGBKBD_MAX_GCC_LEVEL.
+ * @return enum ec_error_list;
+ */
+int rgbkbd_set_global_brightness(uint8_t gcc);
+int rgbkbd_get_global_brightness(uint8_t *gcc);
+
+/*
+ * Driver for keyboard_backlight.
+ */
+extern const struct kblight_drv kblight_rgbkbd;
diff --git a/include/task.h b/include/task.h
index b23fe869b1..4e0ff04697 100644
--- a/include/task.h
+++ b/include/task.h
@@ -469,16 +469,4 @@ struct irq_def {
#endif /* CONFIG_COMMON_RUNTIME */
#endif /* !CONFIG_ZEPHYR */
-#if defined(CONFIG_ZEPHYR) && defined(TEST_BUILD)
-#include <kernel.h>
-
-/**
- * @brief Get the Zephyr thread ID for the given task
- *
- * @param cros_tid A valid cros TASK_ID_* entry
- * @return The Zephyr thread ID
- */
-k_tid_t task_get_zephyr_tid(size_t cros_tid);
-#endif /* CONFIG_ZEPHYR && TEST_BUILD */
-
#endif /* __CROS_EC_TASK_H */
diff --git a/power/amd_x86.c b/power/amd_x86.c
index c3698bde5d..2a35849039 100644
--- a/power/amd_x86.c
+++ b/power/amd_x86.c
@@ -252,13 +252,6 @@ __override void power_chipset_handle_sleep_hang(
host_set_single_event(EC_HOST_EVENT_HANG_DETECT);
}
-static void handle_chipset_suspend(void)
-{
- /* Clear masks before any hooks are run for suspend. */
- lpc_s0ix_suspend_clear_masks();
-}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, handle_chipset_suspend, HOOK_PRIO_FIRST);
-
static void handle_chipset_reset(void)
{
if (chipset_in_state(CHIPSET_STATE_STANDBY)) {
@@ -296,6 +289,11 @@ __override void power_chipset_handle_host_sleep_event(
#ifdef CONFIG_POWER_S0IX
if (state == HOST_SLEEP_EVENT_S0IX_SUSPEND) {
/*
+ * Clear event mask for SMI and SCI first to avoid host being
+ * interrupted while suspending.
+ */
+ lpc_s0ix_suspend_clear_masks();
+ /*
* Indicate to power state machine that a new host event for
* s0ix/s3 suspend has been received and so chipset suspend
* notification needs to be sent to listeners.
diff --git a/test/motion_sense_fifo.c b/test/motion_sense_fifo.c
index 1d6602650c..afa9a4f5cf 100644
--- a/test/motion_sense_fifo.c
+++ b/test/motion_sense_fifo.c
@@ -293,6 +293,58 @@ static int test_spread_data_in_window(void)
return EC_SUCCESS;
}
+static int test_spread_data_on_overflow(void)
+{
+ const uint32_t now = __hw_clock_source_read();
+ const int fill_count = (CONFIG_ACCEL_FIFO_SIZE / 2) - 1;
+ int i, read_count;
+
+ /* Set up the sensors */
+ motion_sensors[0].collection_rate = 20; /* us */
+ motion_sensors[0].oversampling_ratio = 1;
+ motion_sensors[1].oversampling_ratio = 1;
+
+ /* Add 1 sample for sensor [1]. This will be evicted. */
+ data->sensor_num = 1;
+ motion_sense_fifo_stage_data(data, motion_sensors + 1, 3, 0);
+
+ /*
+ * Fill the rest of the fifo, every 2 entries will have the same
+ * timestamp simulating have 2 entries on the hardware FIFO per read.
+ */
+ data->sensor_num = 0;
+ for (i = 0; i < fill_count; i++) {
+ int ts = now - ((fill_count - i) / 2) * 10;
+
+ motion_sense_fifo_stage_data(data, motion_sensors, 3, ts);
+ }
+
+ /* Insert an async event which also causes a commit */
+ motion_sense_fifo_insert_async_event(motion_sensors, ASYNC_EVENT_FLUSH);
+
+ read_count =
+ motion_sense_fifo_read(sizeof(data), 4, data, &data_bytes_read);
+
+ /* Verify that we read 4 entries */
+ TEST_EQ(read_count, 4, "%d");
+
+ /* Verify that entries 0 and 2 are timestamps (1 and 3 are data) */
+ TEST_BITS_SET(data[0].flags, MOTIONSENSE_SENSOR_FLAG_TIMESTAMP);
+ TEST_BITS_SET(data[2].flags, MOTIONSENSE_SENSOR_FLAG_TIMESTAMP);
+
+ /*
+ * Verify that the first read entry is the first one added in the for
+ * loop above.
+ */
+ TEST_EQ(data[0].sensor_num, 0, "%u");
+ TEST_EQ(data[0].timestamp, now - ((fill_count - 1) / 2) * 10, "%u");
+
+ /* Verify that the timestamp was spread */
+ TEST_NE(data[0].timestamp, data[2].timestamp, "%u");
+
+ return EC_SUCCESS;
+}
+
static int test_spread_data_by_collection_rate(void)
{
const uint32_t now = __hw_clock_source_read();
@@ -411,6 +463,7 @@ void run_test(int argc, char **argv)
RUN_TEST(test_add_data_no_spreading_when_different_sensors);
RUN_TEST(test_add_data_no_spreading_different_timestamps);
RUN_TEST(test_spread_data_in_window);
+ RUN_TEST(test_spread_data_on_overflow);
RUN_TEST(test_spread_data_by_collection_rate);
RUN_TEST(test_spread_double_commit_same_timestamp);
RUN_TEST(test_commit_non_data_or_timestamp_entries);
diff --git a/test/run_device_tests.py b/test/run_device_tests.py
index fbe2ed31a5..f7c8ae2725 100755
--- a/test/run_device_tests.py
+++ b/test/run_device_tests.py
@@ -26,7 +26,7 @@ import time
from concurrent.futures.thread import ThreadPoolExecutor
from enum import Enum
from pathlib import Path
-from typing import Optional, BinaryIO, List, Dict
+from typing import Optional, BinaryIO, List
# pylint: disable=import-error
import colorama # type: ignore[import]
@@ -104,11 +104,11 @@ class BoardConfig:
class TestConfig:
"""Configuration for a given test."""
- def __init__(self, name, image_to_use=ImageType.RW, finish_regexes=None,
- fail_regexes=None, toggle_power=False, test_args=None,
- num_flash_attempts=2, timeout_secs=10,
- enable_hw_write_protect=False, ro_image=None,
- build_board=None):
+ def __init__(self, test_name, image_to_use=ImageType.RW,
+ finish_regexes=None, fail_regexes=None, toggle_power=False,
+ test_args=None, num_flash_attempts=2, timeout_secs=10,
+ enable_hw_write_protect=False, ro_image=None, build_board=None,
+ config_name=None):
if test_args is None:
test_args = []
if finish_regexes is None:
@@ -116,8 +116,11 @@ class TestConfig:
if fail_regexes is None:
fail_regexes = [SINGLE_CHECK_FAILED_REGEX, ALL_TESTS_FAILED_REGEX,
ASSERTION_FAILURE_REGEX]
+ if config_name is None:
+ config_name = test_name
- self.name = name
+ self.test_name = test_name
+ self.config_name = config_name
self.image_to_use = image_to_use
self.finish_regexes = finish_regexes
self.fail_regexes = fail_regexes
@@ -139,105 +142,72 @@ class AllTests:
"""All possible tests."""
@staticmethod
- def get(board_config: BoardConfig) -> Dict[str, TestConfig]:
+ def get(board_config: BoardConfig) -> List[TestConfig]:
public_tests = AllTests.get_public_tests(board_config)
private_tests = AllTests.get_private_tests()
- # Make sure there are no conflicts
- # pylint: disable=dict-keys-not-iterating
- overwritten_tests = public_tests.keys() & private_tests.keys()
- # pylint: enable=dict-keys-not-iterating
- if overwritten_tests:
- err = 'Public test overwritten by private one with the same name: '
- err += str(overwritten_tests)
- raise RuntimeError(err)
-
- return {**public_tests, **private_tests}
+ return public_tests + private_tests
@staticmethod
- def get_public_tests(board_config: BoardConfig) -> Dict[str, TestConfig]:
- tests = {
- 'aes':
- TestConfig(name='aes'),
- 'cec':
- TestConfig(name='cec'),
- 'cortexm_fpu':
- TestConfig(name='cortexm_fpu'),
- 'crc':
- TestConfig(name='crc'),
- 'flash_physical':
- TestConfig(name='flash_physical', image_to_use=ImageType.RO,
- toggle_power=True),
- 'flash_write_protect':
- TestConfig(name='flash_write_protect',
- image_to_use=ImageType.RO,
- toggle_power=True, enable_hw_write_protect=True),
- 'fpsensor_hw':
- TestConfig(name='fpsensor_hw'),
- 'fpsensor_spi_ro':
- TestConfig(name='fpsensor', image_to_use=ImageType.RO,
- test_args=['spi']),
- 'fpsensor_spi_rw':
- TestConfig(name='fpsensor', test_args=['spi']),
- 'fpsensor_uart_ro':
- TestConfig(name='fpsensor', image_to_use=ImageType.RO,
- test_args=['uart']),
- 'fpsensor_uart_rw':
- TestConfig(name='fpsensor', test_args=['uart']),
- 'mpu_ro':
- TestConfig(name='mpu',
- image_to_use=ImageType.RO,
- finish_regexes=[board_config.mpu_regex]),
- 'mpu_rw':
- TestConfig(name='mpu',
- finish_regexes=[board_config.mpu_regex]),
- 'mutex':
- TestConfig(name='mutex'),
- 'pingpong':
- TestConfig(name='pingpong'),
- 'printf':
- TestConfig(name='printf'),
- 'queue':
- TestConfig(name='queue'),
- 'rollback_region0':
- TestConfig(name='rollback', finish_regexes=[
- board_config.rollback_region0_regex],
- test_args=['region0']),
- 'rollback_region1':
- TestConfig(name='rollback', finish_regexes=[
- board_config.rollback_region1_regex],
- test_args=['region1']),
- 'rollback_entropy':
- TestConfig(name='rollback_entropy', image_to_use=ImageType.RO),
- 'rtc':
- TestConfig(name='rtc'),
- 'sha256':
- TestConfig(name='sha256'),
- 'sha256_unrolled':
- TestConfig(name='sha256_unrolled'),
- 'static_if':
- TestConfig(name='static_if'),
- 'system_is_locked_wp_on':
- TestConfig(name='system_is_locked', test_args=['wp_on'],
- toggle_power=True, enable_hw_write_protect=True),
- 'system_is_locked_wp_off':
- TestConfig(name='system_is_locked', test_args=['wp_off'],
- toggle_power=True, enable_hw_write_protect=False),
- 'timer_dos':
- TestConfig(name='timer_dos'),
- 'utils':
- TestConfig(name='utils', timeout_secs=20),
- 'utils_str':
- TestConfig(name='utils_str'),
- }
+ def get_public_tests(board_config: BoardConfig) -> List[TestConfig]:
+ tests = [
+ TestConfig(test_name='aes'),
+ TestConfig(test_name='cec'),
+ TestConfig(test_name='cortexm_fpu'),
+ TestConfig(test_name='crc'),
+ TestConfig(test_name='flash_physical', image_to_use=ImageType.RO,
+ toggle_power=True),
+ TestConfig(test_name='flash_write_protect',
+ image_to_use=ImageType.RO,
+ toggle_power=True, enable_hw_write_protect=True),
+ TestConfig(test_name='fpsensor_hw'),
+ TestConfig(config_name='fpsensor_spi_ro', test_name='fpsensor',
+ image_to_use=ImageType.RO, test_args=['spi']),
+ TestConfig(config_name='fpsensor_spi_rw', test_name='fpsensor',
+ test_args=['spi']),
+ TestConfig(config_name='fpsensor_uart_ro', test_name='fpsensor',
+ image_to_use=ImageType.RO, test_args=['uart']),
+ TestConfig(config_name='fpsensor_uart_rw', test_name='fpsensor',
+ test_args=['uart']),
+ TestConfig(config_name='mpu_ro', test_name='mpu',
+ image_to_use=ImageType.RO,
+ finish_regexes=[board_config.mpu_regex]),
+ TestConfig(config_name='mpu_rw', test_name='mpu',
+ finish_regexes=[board_config.mpu_regex]),
+ TestConfig(test_name='mutex'),
+ TestConfig(test_name='pingpong'),
+ TestConfig(test_name='printf'),
+ TestConfig(test_name='queue'),
+ TestConfig(config_name='rollback_region0', test_name='rollback',
+ finish_regexes=[board_config.rollback_region0_regex],
+ test_args=['region0']),
+ TestConfig(config_name='rollback_region1', test_name='rollback',
+ finish_regexes=[board_config.rollback_region1_regex],
+ test_args=['region1']),
+ TestConfig(test_name='rollback_entropy', image_to_use=ImageType.RO),
+ TestConfig(test_name='rtc'),
+ TestConfig(test_name='sha256'),
+ TestConfig(test_name='sha256_unrolled'),
+ TestConfig(test_name='static_if'),
+ TestConfig(config_name='system_is_locked_wp_on',
+ test_name='system_is_locked', test_args=['wp_on'],
+ toggle_power=True, enable_hw_write_protect=True),
+ TestConfig(config_name='system_is_locked_wp_off',
+ test_name='system_is_locked', test_args=['wp_off'],
+ toggle_power=True, enable_hw_write_protect=False),
+ TestConfig(test_name='timer_dos'),
+ TestConfig(test_name='utils', timeout_secs=20),
+ TestConfig(test_name='utils_str'),
+ ]
if board_config.name == BLOONCHIPPER:
- tests['stm32f_rtc'] = TestConfig(name='stm32f_rtc')
+ tests.append(TestConfig(test_name='stm32f_rtc'))
# Run panic data tests for all boards and RO versions.
for variant_name, variant_info in board_config.variants.items():
- tests['panic_data_' + variant_name] = (
- TestConfig(name='panic_data',
+ tests.append(
+ TestConfig(config_name='panic_data_' + variant_name,
+ test_name='panic_data',
fail_regexes=[SINGLE_CHECK_FAILED_REGEX,
ALL_TESTS_FAILED_REGEX],
ro_image=variant_info.get('ro_image_path'),
@@ -246,24 +216,24 @@ class AllTests:
return tests
@staticmethod
- def get_private_tests() -> Dict[str, TestConfig]:
+ def get_private_tests() -> List[TestConfig]:
# Return all private tests, if the folder exists
- tests = {}
+ tests = []
try:
current_dir = os.path.dirname(__file__)
private_dir = os.path.join(current_dir, os.pardir, 'private/test')
have_private = os.path.isdir(private_dir)
if not have_private:
- return {}
+ return []
sys.path.append(private_dir)
import private_tests # pylint: disable=import-error
- for test_id, test_args in private_tests.tests.items():
- tests[test_id] = TestConfig(**test_args)
+ for test_args in private_tests.tests:
+ tests.append(TestConfig(**test_args))
# Catch all exceptions to avoid disruptions in public repo
except BaseException as e:
logging.debug('Failed to get list of private tests: %s', str(e))
logging.debug('Ignore error and continue.')
- return {}
+ return []
return tests
@@ -572,14 +542,14 @@ def run_test(test: TestConfig, console: str, executor: ThreadPoolExecutor) ->\
def get_test_list(config: BoardConfig, test_args) -> List[TestConfig]:
"""Get a list of tests to run."""
if test_args == 'all':
- return list(AllTests.get(config).values())
+ return AllTests.get(config)
test_list = []
for t in test_args:
logging.debug('test: %s', t)
test_regex = re.compile(t)
- tests = [v for k, v in AllTests.get(config).items()
- if test_regex.fullmatch(k)]
+ tests = [test for test in AllTests.get(config)
+ if test_regex.fullmatch(test.config_name)]
if not tests:
logging.error('Unable to find test config for "%s"', t)
sys.exit(1)
@@ -643,7 +613,9 @@ def main():
e = ThreadPoolExecutor(max_workers=1)
test_list = get_test_list(board_config, args.tests)
- logging.debug('Running tests: %s', [t.name for t in test_list])
+ logging.debug(
+ 'Running tests: %s', [
+ test.config_name for test in test_list])
for test in test_list:
build_board = args.board
@@ -653,10 +625,10 @@ def main():
build_board = test.build_board
# build test binary
- build(test.name, build_board, args.compiler)
+ build(test.test_name, build_board, args.compiler)
- image_path = os.path.join(EC_DIR, 'build', build_board, test.name,
- test.name + '.bin')
+ image_path = os.path.join(EC_DIR, 'build', build_board, test.test_name,
+ test.test_name + '.bin')
if test.ro_image is not None:
try:
@@ -692,7 +664,7 @@ def main():
hw_write_protect(test.enable_hw_write_protect)
# run the test
- logging.info('Running test: "%s"', test.name)
+ logging.info('Running test: "%s"', test.config_name)
console = get_console(board_config)
test.passed = run_test(test, console, executor=e)
@@ -700,7 +672,7 @@ def main():
exit_code = 0
for test in test_list:
# print results
- print('Test "' + test.name + '": ', end='')
+ print('Test "' + test.config_name + '": ', end='')
if test.passed:
print(colorama.Fore.GREEN + 'PASSED')
else:
diff --git a/util/build_with_clang.py b/util/build_with_clang.py
new file mode 100755
index 0000000000..5cc23d1012
--- /dev/null
+++ b/util/build_with_clang.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+# 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.
+
+"""Build firmware with clang instead of gcc."""
+import logging
+import os
+import subprocess
+import sys
+
+
+# Add to this list as compilation errors are fixed for boards.
+BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [
+ 'dartmonkey',
+ 'bloonchipper',
+ 'nucleo-f412zg',
+ 'nucleo-h743zi',
+]
+
+
+def build(board_name: str) -> None:
+ """Build with clang for specified board."""
+ logging.debug('Building board: "%s"', board_name)
+
+ cmd = [
+ 'make',
+ 'BOARD=' + board_name,
+ '-j',
+ ]
+
+ logging.debug('Running command: "%s"', ' '.join(cmd))
+ subprocess.run(cmd, env=dict(os.environ, CC='clang'), check=True)
+
+
+def main() -> int:
+ logging.basicConfig(level='DEBUG')
+ for board in BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG:
+ build(board)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/util/ectool.c b/util/ectool.c
index af116160e5..31e0f07631 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -7957,6 +7957,7 @@ int cmd_battery(int argc, char *argv[])
int rv, val;
char *e;
int index = 0;
+ uint8_t flags;
if (argc > 2) {
fprintf(stderr, "Usage: %s [index]\n", argv[0]);
@@ -7983,6 +7984,8 @@ int cmd_battery(int argc, char *argv[])
return -1;
}
+ flags = read_mapped_mem8(EC_MEMMAP_BATT_FLAG);
+
printf("Battery info:\n");
rv = read_mapped_string(EC_MEMMAP_BATT_MFGR, batt_text,
@@ -8035,15 +8038,15 @@ int cmd_battery(int argc, char *argv[])
val = read_mapped_mem32(EC_MEMMAP_BATT_RATE);
if (!is_battery_range(val))
goto cmd_error;
- printf(" Present current %u mA\n", val);
+ printf(" Present current %u mA%s\n", val,
+ flags & EC_BATT_FLAG_DISCHARGING ? " (discharging)" : "");
val = read_mapped_mem32(EC_MEMMAP_BATT_CAP);
if (!is_battery_range(val))
goto cmd_error;
printf(" Remaining capacity %u mAh\n", val);
- val = read_mapped_mem8(EC_MEMMAP_BATT_FLAG);
- print_battery_flags(val);
+ print_battery_flags(flags);
return 0;
cmd_error:
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index df54406fa2..9a14c93731 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -516,7 +516,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_RTC
"${PLATFORM_EC}/common/rtc.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_MATH_UTIL
"${PLATFORM_EC}/common/math_util.c")
-
+zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_HOST_SLEEP
+ "${PLATFORM_EC}/power/host_sleep.c")
# Switch to ec_shim library for all Zephyr sources
set(ZEPHYR_CURRENT_LIBRARY ec_shim)
diff --git a/zephyr/Kconfig.stacks b/zephyr/Kconfig.stacks
index 6e6c336de9..88e00bb112 100644
--- a/zephyr/Kconfig.stacks
+++ b/zephyr/Kconfig.stacks
@@ -78,8 +78,8 @@ config TASK_PD_STACK_SIZE
config TASK_PD_INT_STACK_SIZE
default 1152 if SOC_SERIES_RISCV32_IT8XXX2
- default 736 if SOC_SERIES_NPCX7
- default 736 if SOC_SERIES_NPCX9
+ default 880 if SOC_SERIES_NPCX7
+ default 880 if SOC_SERIES_NPCX9
config TASK_USB_CHG_STACK_SIZE
default 1152 if SOC_SERIES_RISCV32_IT8XXX2
diff --git a/zephyr/Kconfig.usba b/zephyr/Kconfig.usba
index cca91ef787..c0cbdacdfe 100644
--- a/zephyr/Kconfig.usba
+++ b/zephyr/Kconfig.usba
@@ -15,8 +15,9 @@ menuconfig PLATFORM_EC_USBA
if PLATFORM_EC_USBA
-choice
+choice PLATFORM_EC_USBA_PORT_POWER_TYPE
prompt "Port power control mode"
+ default PLATFORM_EC_USB_PORT_POWER_DUMB
config PLATFORM_EC_USB_PORT_POWER_DUMB
bool "Dumb"
diff --git a/zephyr/boards/arm/npcx7/npcx7_defconfig b/zephyr/boards/arm/npcx7/npcx7_defconfig
index afebc2383d..cc1cd1eb6d 100644
--- a/zephyr/boards/arm/npcx7/npcx7_defconfig
+++ b/zephyr/boards/arm/npcx7/npcx7_defconfig
@@ -4,7 +4,6 @@
# Zephyr Kernel Configuration
CONFIG_SOC_SERIES_NPCX7=y
-CONFIG_SOC_LOG_LEVEL_ERR=y
# Platform Configuration
CONFIG_BOARD_NPCX7=y
@@ -34,7 +33,6 @@ CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_UART_CONSOLE_INPUT_EXPIRED=y
-CONFIG_NPCX_PM_TRACE=y
# BBRAM
CONFIG_BBRAM=y
diff --git a/zephyr/boards/arm/npcx9/npcx9_defconfig b/zephyr/boards/arm/npcx9/npcx9_defconfig
index ed1a44764b..18790143b0 100644
--- a/zephyr/boards/arm/npcx9/npcx9_defconfig
+++ b/zephyr/boards/arm/npcx9/npcx9_defconfig
@@ -5,7 +5,6 @@
# Zephyr Kernel Configuration
CONFIG_SOC_SERIES_NPCX9=y
CONFIG_SOC_NPCX9M3F=y
-CONFIG_SOC_LOG_LEVEL_ERR=y
# Platform Configuration
CONFIG_BOARD_NPCX9=y
@@ -35,7 +34,6 @@ CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_UART_CONSOLE_INPUT_EXPIRED=y
-CONFIG_NPCX_PM_TRACE=y
# BBRAM
CONFIG_BBRAM=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
index 828304e5c9..5f79c4ce8a 100644
--- a/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
+++ b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
@@ -49,7 +49,6 @@ CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_UART_CONSOLE_INPUT_EXPIRED=y
-CONFIG_NPCX_PM_TRACE=y
# BBRAM
CONFIG_BBRAM=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
index ef0737a059..d4473b0f64 100644
--- a/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
+++ b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
@@ -49,7 +49,6 @@ CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_UART_CONSOLE_INPUT_EXPIRED=y
-CONFIG_NPCX_PM_TRACE=y
# BBRAM
CONFIG_BBRAM=y
diff --git a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
index dcc3f4a970..aeeda0a2fe 100644
--- a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
+++ b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
@@ -23,13 +23,6 @@
/* Override keyboard scanning */
soc {
/delete-node/ kscan@f01d00;
-
- cros_kb_raw: cros-kb-raw@f01d00 {
- compatible = "ite,it8xxx2-cros-kb-raw";
- reg = <0x00f01d00 0x29>;
- interrupt-parent = <&intc>;
- interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
- };
};
};
diff --git a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
index 61b1adcf3f..d5b84cb0fd 100644
--- a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
+++ b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
@@ -9,8 +9,11 @@
#include <drivers/cros_kb_raw.h>
#include <drivers/clock_control.h>
#include <drivers/gpio.h>
+#include <drivers/interrupt_controller/wuc_ite_it8xxx2.h>
+#include <dt-bindings/interrupt-controller/it8xxx2-wuc.h>
#include <kernel.h>
#include <soc.h>
+#include <soc_dt.h>
#include <soc/ite_it8xxx2/reg_def_cros.h>
#include "ec_tasks.h"
@@ -20,14 +23,29 @@
#include <logging/log.h>
LOG_MODULE_REGISTER(cros_kb_raw, LOG_LEVEL_ERR);
+#define KEYBOARD_KSI_PIN_COUNT IT8XXX2_DT_INST_WUCCTRL_LEN(0)
#define KSOH_PIN_MASK (((1 << (KEYBOARD_COLS_MAX - 8)) - 1) & 0xff)
/* Device config */
+struct cros_kb_raw_wuc_map_cfg {
+ /* WUC control device structure */
+ const struct device *wucs;
+ /* WUC pin mask */
+ uint8_t mask;
+};
+
struct cros_kb_raw_ite_config {
/* keyboard scan controller base address */
- uintptr_t base;
+ struct kscan_it8xxx2_regs *base;
/* Keyboard scan input (KSI) wake-up irq */
int irq;
+ /* KSI[7:0] wake-up input source configuration list */
+ const struct cros_kb_raw_wuc_map_cfg *wuc_map_list;
+};
+
+struct cros_kb_raw_ite_data {
+ /* KSI[7:0] wake-up interrupt status mask */
+ uint8_t ksi_pin_mask;
};
static int kb_raw_ite_init(const struct device *dev)
@@ -43,9 +61,17 @@ static int cros_kb_raw_ite_enable_interrupt(const struct device *dev,
int enable)
{
const struct cros_kb_raw_ite_config *config = dev->config;
+ struct cros_kb_raw_ite_data *data = dev->data;
if (enable) {
- ECREG(IT8XXX2_WUC_WUESR3) = 0xFF;
+ /*
+ * W/C wakeup interrupt status of KSI[7:0] pins
+ *
+ * NOTE: We want to clear the status as soon as possible,
+ * so clear KSI[7:0] pins at a time.
+ */
+ it8xxx2_wuc_clear_status(config->wuc_map_list[0].wucs,
+ data->ksi_pin_mask);
ite_intc_isr_clear(config->irq);
irq_enable(config->irq);
} else {
@@ -58,8 +84,7 @@ static int cros_kb_raw_ite_enable_interrupt(const struct device *dev,
static int cros_kb_raw_ite_read_row(const struct device *dev)
{
const struct cros_kb_raw_ite_config *config = dev->config;
- struct kscan_it8xxx2_regs *const inst =
- (struct kscan_it8xxx2_regs *) config->base;
+ struct kscan_it8xxx2_regs *const inst = config->base;
/* Bits are active-low, so invert returned levels */
return ((inst->KBS_KSI) ^ 0xff);
@@ -70,8 +95,7 @@ static int cros_kb_raw_ite_drive_column(const struct device *dev, int col)
int mask;
unsigned int key;
const struct cros_kb_raw_ite_config *config = dev->config;
- struct kscan_it8xxx2_regs *const inst =
- (struct kscan_it8xxx2_regs *) config->base;
+ struct kscan_it8xxx2_regs *const inst = config->base;
/* Tri-state all outputs */
if (col == KEYBOARD_COLUMN_NONE)
@@ -105,14 +129,21 @@ static int cros_kb_raw_ite_drive_column(const struct device *dev, int col)
static void cros_kb_raw_ite_ksi_isr(const struct device *dev)
{
- ARG_UNUSED(dev);
+ const struct cros_kb_raw_ite_config *config = dev->config;
+ struct cros_kb_raw_ite_data *data = dev->data;
/*
* We clear IT8XXX2_IRQ_WKINTC irq status in
* ite_intc_irq_handler(), after interrupt was fired.
*/
- /* W/C wakeup interrupt status for KSI[0-7] */
- ECREG(IT8XXX2_WUC_WUESR3) = 0xFF;
+ /*
+ * W/C wakeup interrupt status of KSI[7:0] pins
+ *
+ * NOTE: We want to clear the status as soon as possible,
+ * so clear KSI[7:0] pins at a time.
+ */
+ it8xxx2_wuc_clear_status(config->wuc_map_list[0].wucs,
+ data->ksi_pin_mask);
/* Wake-up keyboard scan task */
task_wake(TASK_ID_KEYSCAN);
@@ -122,8 +153,8 @@ static int cros_kb_raw_ite_init(const struct device *dev)
{
unsigned int key;
const struct cros_kb_raw_ite_config *config = dev->config;
- struct kscan_it8xxx2_regs *const inst =
- (struct kscan_it8xxx2_regs *) config->base;
+ struct cros_kb_raw_ite_data *data = dev->data;
+ struct kscan_it8xxx2_regs *const inst = config->base;
/* Ensure top-level interrupt is disabled */
cros_kb_raw_ite_enable_interrupt(dev, 0);
@@ -158,15 +189,38 @@ static int cros_kb_raw_ite_init(const struct device *dev)
inst->KBS_KSOH1 &= ~KSOH_PIN_MASK;
/* restore interrupts */
irq_unlock(key);
- /* Select falling-edge triggered of wakeup interrupt for KSI[0-7] */
- ECREG(IT8XXX2_WUC_WUEMR3) = 0xFF;
- /* W/C wakeup interrupt status for KSI[0-7] */
- ECREG(IT8XXX2_WUC_WUESR3) = 0xFF;
+
+ for (int i = 0; i < KEYBOARD_KSI_PIN_COUNT; i++) {
+ /* Select wakeup interrupt falling-edge triggered of KSI[7:0] */
+ it8xxx2_wuc_set_polarity(config->wuc_map_list[i].wucs,
+ config->wuc_map_list[i].mask,
+ WUC_TYPE_EDGE_FALLING);
+ /* W/C wakeup interrupt status of KSI[7:0] pins */
+ it8xxx2_wuc_clear_status(config->wuc_map_list[i].wucs,
+ config->wuc_map_list[i].mask);
+ /* Enable wakeup interrupt of KSI[7:0] pins */
+ it8xxx2_wuc_enable(config->wuc_map_list[i].wucs,
+ config->wuc_map_list[i].mask);
+
+ /*
+ * We want to clear KSI[7:0] pins status at a time when wakeup
+ * interrupt fire, so gather the KSI[7:0] pin mask value here.
+ */
+ if (IS_ENABLED(CONFIG_LOG)) {
+ if (config->wuc_map_list[i].wucs !=
+ config->wuc_map_list[0].wucs) {
+ LOG_ERR("KSI%d isn't in the same wuc node!", i);
+ }
+ }
+ data->ksi_pin_mask |= config->wuc_map_list[i].mask;
+ }
+
+ /* W/C interrupt status of KSI[7:0] pins */
ite_intc_isr_clear(config->irq);
- /* Enable wakeup interrupt for KSI[0-7] */
- ECREG(IT8XXX2_WUC_WUENR3) = 0xFF;
- IRQ_CONNECT(DT_INST_IRQN(0), 0, cros_kb_raw_ite_ksi_isr, NULL, 0);
+ irq_connect_dynamic(config->irq, 0,
+ (void (*)(const void *))cros_kb_raw_ite_ksi_isr,
+ (const void *)dev, 0);
return 0;
}
@@ -177,12 +231,19 @@ static const struct cros_kb_raw_driver_api cros_kb_raw_ite_driver_api = {
.read_rows = cros_kb_raw_ite_read_row,
.enable_interrupt = cros_kb_raw_ite_enable_interrupt,
};
+static const struct cros_kb_raw_wuc_map_cfg
+ cros_kb_raw_wuc_0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] =
+ IT8XXX2_DT_WUC_ITEMS_LIST(0);
static const struct cros_kb_raw_ite_config cros_kb_raw_cfg = {
- .base = DT_INST_REG_ADDR(0),
+ .base = (struct kscan_it8xxx2_regs *)DT_INST_REG_ADDR(0),
.irq = DT_INST_IRQN(0),
+ .wuc_map_list = cros_kb_raw_wuc_0,
};
-DEVICE_DT_INST_DEFINE(0, kb_raw_ite_init, NULL, NULL, &cros_kb_raw_cfg,
- PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+static struct cros_kb_raw_ite_data cros_kb_raw_data;
+
+DEVICE_DT_INST_DEFINE(0, kb_raw_ite_init, NULL, &cros_kb_raw_data,
+ &cros_kb_raw_cfg, PRE_KERNEL_1,
+ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&cros_kb_raw_ite_driver_api);
diff --git a/zephyr/drivers/cros_system/cros_system_npcx.c b/zephyr/drivers/cros_system/cros_system_npcx.c
index 038ca89ec0..879b792ee1 100644
--- a/zephyr/drivers/cros_system/cros_system_npcx.c
+++ b/zephyr/drivers/cros_system/cros_system_npcx.c
@@ -572,7 +572,7 @@ static const struct cros_system_driver_api cros_system_driver_npcx_api = {
.chip_vendor = cros_system_npcx_get_chip_vendor,
.chip_name = cros_system_npcx_get_chip_name,
.chip_revision = cros_system_npcx_get_chip_revision,
-#ifdef CONFIG_NPCX_PM_TRACE
+#ifdef CONFIG_PM
.deep_sleep_ticks = cros_system_npcx_deep_sleep_ticks,
#endif
};
diff --git a/zephyr/dts/bindings/battery/battery-smart.yaml b/zephyr/dts/bindings/battery/battery-smart.yaml
index 8e97d010e0..c2c6d28175 100644
--- a/zephyr/dts/bindings/battery/battery-smart.yaml
+++ b/zephyr/dts/bindings/battery/battery-smart.yaml
@@ -13,6 +13,7 @@ properties:
enum:
- "aec,5477109"
- "as3gwrc3ka,c235-41"
+ - "ganfeng,7c01"
- "getac,bq40z50-R3-S3"
- "getac,bq40z50-R3-S2"
- "lgc,ac17a8m"
diff --git a/zephyr/dts/bindings/battery/ganfeng,7c01.yaml b/zephyr/dts/bindings/battery/ganfeng,7c01.yaml
new file mode 100644
index 0000000000..6601761bea
--- /dev/null
+++ b/zephyr/dts/bindings/battery/ganfeng,7c01.yaml
@@ -0,0 +1,54 @@
+description: "Ganfeng 7C01"
+compatible: "ganfeng,7c01"
+
+include: battery-smart.yaml
+
+properties:
+ enum-name:
+ type: string
+ default: "ganfeng,7c01"
+
+ # Fuel gauge
+ manuf_name:
+ default: "Ganfeng"
+ device_name:
+ default: "7C01"
+ ship_mode_reg_addr:
+ default: 0x00
+ ship_mode_reg_data:
+ default: [ 0x0010, 0x0010 ]
+ # Documentation: b/226820234
+ fet_mfgacc_support:
+ default: 0
+ fet_reg_addr:
+ default: 0x43
+ fet_reg_mask:
+ default: 0x0001
+ fet_disconnect_val:
+ default: 0x0000
+ fet_cfet_mask:
+ default: 0x0002
+ fet_cfet_off_val:
+ default: 0x0000
+
+ # Battery info
+ voltage_max:
+ default: 8700
+ voltage_normal:
+ default: 7600
+ voltage_min:
+ default: 6000
+ precharge_current:
+ default: 256
+ start_charging_min_c:
+ default: -20
+ start_charging_max_c:
+ default: 60
+ charging_min_c:
+ default: 0
+ charging_max_c:
+ default: 60
+ discharging_min_c:
+ default: -20
+ discharging_max_c:
+ default: 60
diff --git a/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml
new file mode 100644
index 0000000000..9c1d635b61
--- /dev/null
+++ b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml
@@ -0,0 +1,24 @@
+# Copyright 2022 Google LLC
+# SPDX-License-Identifier: Apache-2.0
+
+description: ITE, it8xxx2-cros-kb-raw node
+
+compatible: "ite,it8xxx2-cros-kb-raw"
+
+include: cros-kb-raw-controller.yaml
+
+properties:
+ reg:
+ required: true
+
+ interrupts:
+ required: true
+
+ wucctrl:
+ type: phandles
+ description: |
+ Configure wakeup controller, this controller is used to set that
+ when the interrupt is triggered in EC low power mode, it can wakeup
+ EC or not. Via this controller, we set the wakeup trigger edge,
+ enable, disable, and clear wakeup status for the specific pin which
+ may be gpio pins or alternate pins.
diff --git a/zephyr/dts/bindings/usbc/richtek,rt9490-bc12.yaml b/zephyr/dts/bindings/usbc/richtek,rt9490-bc12.yaml
index c228669fc7..94496455a3 100644
--- a/zephyr/dts/bindings/usbc/richtek,rt9490-bc12.yaml
+++ b/zephyr/dts/bindings/usbc/richtek,rt9490-bc12.yaml
@@ -5,3 +5,9 @@
description: USBC BC1.2
compatible: "richtek,rt9490-bc12"
+
+properties:
+ irq:
+ type: phandles
+ description: |
+ GPIO interrupt from BC1.2
diff --git a/zephyr/dts/bindings/vendor-prefixes.txt b/zephyr/dts/bindings/vendor-prefixes.txt
index 4095b8f300..403b0ba1ea 100644
--- a/zephyr/dts/bindings/vendor-prefixes.txt
+++ b/zephyr/dts/bindings/vendor-prefixes.txt
@@ -14,3 +14,4 @@ smp Battery vendor
aec Battery vendor
powertech Battery vendor
getac Battery vendor
+ganfeng Battery vendor
diff --git a/zephyr/include/cros/ite/it8xxx2.dtsi b/zephyr/include/cros/ite/it8xxx2.dtsi
index 38224b9fd4..abb3e6bbae 100644
--- a/zephyr/include/cros/ite/it8xxx2.dtsi
+++ b/zephyr/include/cros/ite/it8xxx2.dtsi
@@ -78,14 +78,20 @@
label = "FLASH";
};
- /delete-node/ kscan@f01d00;
-
cros_kb_raw: cros-kb-raw@f01d00 {
compatible = "ite,it8xxx2-cros-kb-raw";
reg = <0x00f01d00 0x29>;
label = "CROS_KB_RAW_0";
interrupt-parent = <&intc>;
interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
+ wucctrl = <&wuc_wu30 /* KSI[0] */
+ &wuc_wu31 /* KSI[1] */
+ &wuc_wu32 /* KSI[2] */
+ &wuc_wu33 /* KSI[3] */
+ &wuc_wu34 /* KSI[4] */
+ &wuc_wu35 /* KSI[5] */
+ &wuc_wu36 /* KSI[6] */
+ &wuc_wu37>; /* KSI[7] */
status = "disabled";
};
};
diff --git a/zephyr/projects/.pylintrc b/zephyr/projects/.pylintrc
new file mode 100644
index 0000000000..9ca0b5f8c9
--- /dev/null
+++ b/zephyr/projects/.pylintrc
@@ -0,0 +1,21 @@
+[MASTER]
+init-hook='import sys; sys.path.append("/usr/lib64/python3.6/site-packages")'
+
+[MESSAGES CONTROL]
+
+disable=bad-continuation,bad-whitespace,format,fixme
+
+[format]
+
+max-line-length=88
+string-quote=double
+
+[BASIC]
+additional-builtins=
+ here,
+ register_binman_project,
+ register_host_project,
+ register_host_test,
+ register_npcx_project,
+ register_raw_project,
+good-names=BUILD
diff --git a/zephyr/projects/brya/BUILD.py b/zephyr/projects/brya/BUILD.py
index da7e8b1d49..ead03c459f 100644
--- a/zephyr/projects/brya/BUILD.py
+++ b/zephyr/projects/brya/BUILD.py
@@ -2,8 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for brya."""
+
def register_npcx9_variant(project_name, extra_dts_overlays=(), extra_kconfig_files=()):
+ """Register a variant of a brya, even though this is not named as such."""
return register_npcx_project(
project_name=project_name,
zephyr_board="npcx9",
diff --git a/zephyr/projects/brya/prj.conf b/zephyr/projects/brya/prj.conf
index f4f7569458..a824bd1b91 100644
--- a/zephyr/projects/brya/prj.conf
+++ b/zephyr/projects/brya/prj.conf
@@ -160,7 +160,6 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_MUX=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_TCPCI=y
CONFIG_PLATFORM_EC_USBC_PPC_DEDICATED_INT=y
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
CONFIG_PLATFORM_EC_CONSOLE_CMD_PPC_DUMP=n
CONFIG_PLATFORM_EC_CONSOLE_CMD_TCPC_DUMP=n
CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n
diff --git a/zephyr/projects/corsola/BUILD.py b/zephyr/projects/corsola/BUILD.py
index af0e0edf4b..6a8ed60c09 100644
--- a/zephyr/projects/corsola/BUILD.py
+++ b/zephyr/projects/corsola/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for corsola."""
+
# Default chip is it8xxx2, some variants will use NPCX9X.
@@ -11,6 +13,7 @@ def register_corsola_project(
extra_dts_overlays=(),
extra_kconfig_files=(),
):
+ """Register a variant of corsola."""
register_func = register_binman_project
if chip.startswith("npcx9"):
register_func = register_npcx_project
diff --git a/zephyr/projects/corsola/interrupts_krabby.dts b/zephyr/projects/corsola/interrupts_krabby.dts
index 2245c98c66..ddc9639d2b 100644
--- a/zephyr/projects/corsola/interrupts_krabby.dts
+++ b/zephyr/projects/corsola/interrupts_krabby.dts
@@ -104,7 +104,7 @@
int_usb_c1_bc12_charger: usb_c1_bc12_charger {
irq-pin = <&usb_c1_bc12_charger_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
- handler = "c1_bc12_interrupt";
+ handler = "rt9490_bc12_dt_interrupt";
};
};
};
diff --git a/zephyr/projects/corsola/prj_kingler.conf b/zephyr/projects/corsola/prj_kingler.conf
index 8cdc8f7261..fd28664a57 100644
--- a/zephyr/projects/corsola/prj_kingler.conf
+++ b/zephyr/projects/corsola/prj_kingler.conf
@@ -102,7 +102,6 @@ CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
# USBA
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USBC
CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y
diff --git a/zephyr/projects/corsola/prj_krabby.conf b/zephyr/projects/corsola/prj_krabby.conf
index ebab7ce3bd..5dd1561898 100644
--- a/zephyr/projects/corsola/prj_krabby.conf
+++ b/zephyr/projects/corsola/prj_krabby.conf
@@ -108,7 +108,6 @@ CONFIG_TASK_PD_STACK_SIZE=1280
# USB-A
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USB-C
CONFIG_PLATFORM_EC_BC12_SINGLE_DRIVER=n
diff --git a/zephyr/projects/corsola/src/kingler/button.c b/zephyr/projects/corsola/src/kingler/button.c
index 0df87c7750..d10d771950 100644
--- a/zephyr/projects/corsola/src/kingler/button.c
+++ b/zephyr/projects/corsola/src/kingler/button.c
@@ -14,8 +14,9 @@ static void buttons_hook(void)
{
int version;
- if (cbi_get_board_version(&version))
+ if (cbi_get_board_version(&version)) {
return;
+ }
/* b:219891339: drop this workaround when we deprecate rev0 */
if (version == 0) {
diff --git a/zephyr/projects/corsola/src/kingler/usb_pd_policy.c b/zephyr/projects/corsola/src/kingler/usb_pd_policy.c
index c06f817ba1..51a05598b9 100644
--- a/zephyr/projects/corsola/src/kingler/usb_pd_policy.c
+++ b/zephyr/projects/corsola/src/kingler/usb_pd_policy.c
@@ -23,15 +23,17 @@ void pd_power_supply_reset(int port)
prev_en = ppc_is_sourcing_vbus(port);
- if (port == USBC_PORT_C1)
+ if (port == USBC_PORT_C1) {
rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 0);
+ }
/* Disable VBUS. */
ppc_vbus_source_enable(port, 0);
/* Enable discharge if we were previously sourcing 5V */
- if (prev_en)
+ if (prev_en) {
pd_set_vbus_discharge(port, 1);
+ }
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -44,18 +46,21 @@ int pd_set_power_supply_ready(int port)
/* Disable charging. */
rv = ppc_vbus_sink_enable(port, 0);
- if (rv)
+ if (rv) {
return rv;
+ }
pd_set_vbus_discharge(port, 0);
/* Provide Vbus. */
- if (port == USBC_PORT_C1)
+ if (port == USBC_PORT_C1) {
rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SOURCE, 1);
+ }
rv = ppc_vbus_source_enable(port, 1);
- if (rv)
+ if (rv) {
return rv;
+ }
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
diff --git a/zephyr/projects/corsola/src/kingler/usbc_config.c b/zephyr/projects/corsola/src/kingler/usbc_config.c
index 0fd22c0dba..bcb1bf70d5 100644
--- a/zephyr/projects/corsola/src/kingler/usbc_config.c
+++ b/zephyr/projects/corsola/src/kingler/usbc_config.c
@@ -150,9 +150,10 @@ void board_tcpc_init(void)
/* Enable TCPC interrupts */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_tcpc));
- if (corsola_get_db_type() == CORSOLA_DB_TYPEC)
+ if (corsola_get_db_type() == CORSOLA_DB_TYPEC) {
gpio_enable_dt_interrupt(
GPIO_INT_FROM_NODELABEL(int_usb_c1_tcpc));
+ }
/* Enable BC1.2 interrupts. */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_bc12));
@@ -161,9 +162,10 @@ void board_tcpc_init(void)
* 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)
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port) {
usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL_DEASSERTED |
USB_PD_MUX_HPD_IRQ_DEASSERTED);
+ }
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_POST_I2C);
@@ -230,8 +232,9 @@ int board_vbus_source_enabled(int port)
__override int board_rt1718s_set_snk_enable(int port, int enable)
{
- if (port == USBC_PORT_C1)
+ if (port == USBC_PORT_C1) {
rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_SINK, enable);
+ }
return EC_SUCCESS;
}
@@ -242,8 +245,9 @@ int board_set_active_charge_port(int port)
bool is_valid_port =
(port >= 0 && port < board_get_usb_pd_port_count());
- if (!is_valid_port && port != CHARGE_PORT_NONE)
+ if (!is_valid_port && port != CHARGE_PORT_NONE) {
return EC_ERROR_INVAL;
+ }
if (port == CHARGE_PORT_NONE) {
CPRINTS("Disabling all charger ports");
@@ -254,8 +258,9 @@ int board_set_active_charge_port(int port)
* Do not return early if one fails otherwise we can
* get into a boot loop assertion failure.
*/
- if (ppc_vbus_sink_enable(i, 0))
+ if (ppc_vbus_sink_enable(i, 0)) {
CPRINTS("Disabling C%d as sink failed.", i);
+ }
}
return EC_SUCCESS;
@@ -274,11 +279,13 @@ int board_set_active_charge_port(int port)
* requested charge port.
*/
for (i = 0; i < board_get_usb_pd_port_count(); i++) {
- if (i == port)
+ if (i == port) {
continue;
+ }
- if (ppc_vbus_sink_enable(i, 0))
+ if (ppc_vbus_sink_enable(i, 0)) {
CPRINTS("C%d: sink path disable failed.", i);
+ }
}
/* Enable requested charge port. */
@@ -297,12 +304,15 @@ uint16_t tcpc_get_alert_status(void)
if (!gpio_pin_get_dt(
GPIO_DT_FROM_NODELABEL(gpio_usb_c0_tcpc_int_odl))) {
if (!gpio_pin_get_dt(
- GPIO_DT_FROM_NODELABEL(gpio_usb_c0_tcpc_rst)))
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_tcpc_rst))) {
status |= PD_STATUS_TCPC_ALERT_0;
+ }
}
- if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c1_tcpc_int_odl)))
+ if (!gpio_pin_get_dt(
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c1_tcpc_int_odl))) {
return status |= PD_STATUS_TCPC_ALERT_1;
+ }
return status;
}
diff --git a/zephyr/projects/corsola/src/krabby/charger_workaround.c b/zephyr/projects/corsola/src/krabby/charger_workaround.c
index 48cd541146..26bfac1bea 100644
--- a/zephyr/projects/corsola/src/krabby/charger_workaround.c
+++ b/zephyr/projects/corsola/src/krabby/charger_workaround.c
@@ -22,8 +22,9 @@ static void enter_hidden_mode(void)
/* b/194967754#comment5: work around for IBUS ADC unstable issue */
static void ibus_adc_workaround(void)
{
- if (system_get_board_version() != 0)
+ if (system_get_board_version() != 0) {
return;
+ }
i2c_update8(chg_chips[CHARGER_SOLO].i2c_port,
chg_chips[CHARGER_SOLO].i2c_addr_flags,
diff --git a/zephyr/projects/corsola/src/krabby/hooks.c b/zephyr/projects/corsola/src/krabby/hooks.c
index 70f3efe8e1..e91993be10 100644
--- a/zephyr/projects/corsola/src/krabby/hooks.c
+++ b/zephyr/projects/corsola/src/krabby/hooks.c
@@ -7,6 +7,9 @@
#include <drivers/gpio.h>
#include <ap_power/ap_power.h>
+#include "charger.h"
+#include "driver/charger/rt9490.h"
+#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
@@ -22,10 +25,11 @@ static void board_i2c3_ctrl(bool enable)
(struct gctrl_it8xxx2_regs *)
DT_REG_ADDR(DT_NODELABEL(gctrl));
- if (enable)
+ if (enable) {
gctrl_base->GCTRL_PMER3 |= IT8XXX2_GCTRL_SMB3PSEL;
- else
+ } else {
gctrl_base->GCTRL_PMER3 &= ~IT8XXX2_GCTRL_SMB3PSEL;
+ }
}
}
@@ -75,3 +79,12 @@ static int install_suspend_handler(const struct device *unused)
}
SYS_INIT(install_suspend_handler, APPLICATION, 1);
+
+static void board_hook_ac_change(void)
+{
+ if (system_get_board_version() >= 1) {
+ rt9490_enable_adc(CHARGER_SOLO, extpower_is_present());
+ }
+}
+DECLARE_HOOK(HOOK_AC_CHANGE, board_hook_ac_change, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_INIT, board_hook_ac_change, HOOK_PRIO_LAST);
diff --git a/zephyr/projects/corsola/src/krabby/led.c b/zephyr/projects/corsola/src/krabby/led.c
index 812d693626..8e2cf10cd9 100644
--- a/zephyr/projects/corsola/src/krabby/led.c
+++ b/zephyr/projects/corsola/src/krabby/led.c
@@ -128,17 +128,19 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
{
if (led_id == EC_LED_ID_BATTERY_LED) {
- if (brightness[EC_LED_COLOR_AMBER] != 0)
+ if (brightness[EC_LED_COLOR_AMBER] != 0) {
led_set_color_battery(EC_LED_COLOR_AMBER);
- else if (brightness[EC_LED_COLOR_WHITE] != 0)
+ } else if (brightness[EC_LED_COLOR_WHITE] != 0) {
led_set_color_battery(EC_LED_COLOR_WHITE);
- else
+ } else {
led_set_color_battery(LED_OFF);
+ }
} else if (led_id == EC_LED_ID_POWER_LED) {
- if (brightness[EC_LED_COLOR_WHITE] != 0)
+ if (brightness[EC_LED_COLOR_WHITE] != 0) {
led_set_color_power(EC_LED_COLOR_WHITE);
- else
+ } else {
led_set_color_power(LED_OFF);
+ }
}
return EC_SUCCESS;
diff --git a/zephyr/projects/corsola/src/krabby/usb_pd_policy.c b/zephyr/projects/corsola/src/krabby/usb_pd_policy.c
index fbdeda89bc..5f9ae83a19 100644
--- a/zephyr/projects/corsola/src/krabby/usb_pd_policy.c
+++ b/zephyr/projects/corsola/src/krabby/usb_pd_policy.c
@@ -27,13 +27,15 @@ int pd_snk_is_vbus_provided(int port)
* There's no PPC to inform VBUS change for usb_charger, so inform
* the usb_charger now.
*/
- if (!!(vbus_prev[port] != vbus))
+ if (!!(vbus_prev[port] != vbus)) {
usb_charger_vbus_change(port, vbus);
+ }
- if (vbus)
+ if (vbus) {
atomic_or(&vbus_prev[port], 1);
- else
+ } else {
atomic_clear(&vbus_prev[port]);
+ }
#endif
return vbus;
}
@@ -48,8 +50,9 @@ void pd_power_supply_reset(int port)
ppc_vbus_source_enable(port, 0);
/* Enable discharge if we were previously sourcing 5V */
- if (prev_en)
+ if (prev_en) {
pd_set_vbus_discharge(port, 1);
+ }
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -61,15 +64,17 @@ int pd_set_power_supply_ready(int port)
/* Disable charging. */
rv = ppc_vbus_sink_enable(port, 0);
- if (rv)
+ if (rv) {
return rv;
+ }
pd_set_vbus_discharge(port, 0);
/* Provide Vbus. */
rv = ppc_vbus_source_enable(port, 1);
- if (rv)
+ if (rv) {
return rv;
+ }
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
diff --git a/zephyr/projects/corsola/src/krabby/usbc_config.c b/zephyr/projects/corsola/src/krabby/usbc_config.c
index b46a9edf8f..7ba0ca9e50 100644
--- a/zephyr/projects/corsola/src/krabby/usbc_config.c
+++ b/zephyr/projects/corsola/src/krabby/usbc_config.c
@@ -41,20 +41,12 @@ void c0_bc12_interrupt(enum gpio_signal signal)
rt1739_interrupt(0);
}
-void c1_bc12_interrupt(enum gpio_signal signal)
-{
- rt9490_interrupt(1);
-}
-
-
static void board_sub_bc12_init(void)
{
- if (corsola_get_db_type() == CORSOLA_DB_TYPEC)
- gpio_enable_dt_interrupt(
- GPIO_INT_FROM_NODELABEL(int_usb_c1_bc12_charger));
- else
+ if (corsola_get_db_type() == CORSOLA_DB_HDMI) {
/* If this is not a Type-C subboard, disable the task. */
task_disable_task(TASK_ID_USB_CHG_P1);
+ }
}
/* Must be done after I2C and subboard */
DECLARE_HOOK(HOOK_INIT, board_sub_bc12_init, HOOK_PRIO_POST_I2C);
@@ -67,18 +59,21 @@ DECLARE_HOOK(HOOK_INIT, board_usbc_init, HOOK_PRIO_POST_DEFAULT);
void ppc_interrupt(enum gpio_signal signal)
{
- if (signal == GPIO_SIGNAL(DT_ALIAS(gpio_usb_c1_ppc_int_odl)))
+ if (signal == GPIO_SIGNAL(DT_ALIAS(gpio_usb_c1_ppc_int_odl))) {
syv682x_interrupt(1);
+ }
}
int ppc_get_alert_status(int port)
{
- if (port == 0)
+ if (port == 0) {
return gpio_pin_get_dt(
GPIO_DT_FROM_NODELABEL(usb_c0_ppc_bc12_int_odl)) == 0;
- if (port == 1 && corsola_get_db_type() == CORSOLA_DB_TYPEC)
+ }
+ if (port == 1 && corsola_get_db_type() == CORSOLA_DB_TYPEC) {
return gpio_pin_get_dt(
GPIO_DT_FROM_ALIAS(gpio_usb_c1_ppc_int_odl)) == 0;
+ }
return 0;
}
@@ -127,8 +122,9 @@ int board_set_active_charge_port(int port)
int i;
int is_valid_port = (port >= 0 && port < board_get_usb_pd_port_count());
- if (!is_valid_port && port != CHARGE_PORT_NONE)
+ if (!is_valid_port && port != CHARGE_PORT_NONE) {
return EC_ERROR_INVAL;
+ }
if (port == CHARGE_PORT_NONE) {
CPRINTS("Disabling all charger ports");
@@ -139,8 +135,9 @@ int board_set_active_charge_port(int port)
* Do not return early if one fails otherwise we can
* get into a boot loop assertion failure.
*/
- if (ppc_vbus_sink_enable(i, 0))
+ if (ppc_vbus_sink_enable(i, 0)) {
CPRINTS("Disabling C%d as sink failed.", i);
+ }
}
return EC_SUCCESS;
@@ -159,11 +156,13 @@ int board_set_active_charge_port(int port)
* requested charge port.
*/
for (i = 0; i < ppc_cnt; i++) {
- if (i == port)
+ if (i == port) {
continue;
+ }
- if (ppc_vbus_sink_enable(i, 0))
+ if (ppc_vbus_sink_enable(i, 0)) {
CPRINTS("C%d: sink path disable failed.", i);
+ }
}
/* Enable requested charge port. */
@@ -207,10 +206,12 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
#ifdef CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT
enum adc_channel board_get_vbus_adc(int port)
{
- if (port == 0)
+ if (port == 0) {
return ADC_VBUS_C0;
- if (port == 1)
+ }
+ if (port == 1) {
return ADC_VBUS_C1;
+ }
CPRINTSUSB("Unknown vbus adc port id: %d", port);
return ADC_VBUS_C0;
}
diff --git a/zephyr/projects/corsola/src/usb_pd_policy.c b/zephyr/projects/corsola/src/usb_pd_policy.c
index c8169e3877..f8795143ee 100644
--- a/zephyr/projects/corsola/src/usb_pd_policy.c
+++ b/zephyr/projects/corsola/src/usb_pd_policy.c
@@ -69,8 +69,9 @@ __override int svdm_dp_config(int port, uint32_t *payload)
mux_state_t mux_mode = svdm_dp_get_mux_mode(port);
int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]);
- if (!pin_mode)
+ if (!pin_mode) {
return 0;
+ }
CPRINTS("pin_mode: %x, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode);
/*
@@ -102,8 +103,9 @@ int corsola_is_dp_muxable(int port)
for (i = 0; i < board_get_usb_pd_port_count(); i++) {
if (i != port) {
- if (usb_mux_get(i) & USB_PD_MUX_DP_ENABLED)
+ if (usb_mux_get(i) & USB_PD_MUX_DP_ENABLED) {
return 0;
+ }
}
}
@@ -140,18 +142,21 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
}
if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
- (irq || lvl))
+ (irq || lvl)) {
/*
* Wake up the AP. IRQ or level high indicates a DP sink is now
* present.
*/
- if (IS_ENABLED(CONFIG_MKBP_EVENT))
+ if (IS_ENABLED(CONFIG_MKBP_EVENT)) {
pd_notify_dp_alt_mode_entry(port);
+ }
+ }
/* Its initial DP status message prior to config */
if (!(dp_flags[port] & DP_FLAGS_DP_ON)) {
- if (lvl)
+ if (lvl) {
dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING;
+ }
return 1;
}
@@ -168,8 +173,9 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
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])
+ if (now < svdm_hpd_deadline[port]) {
usleep(svdm_hpd_deadline[port] - now);
+ }
/* generate IRQ_HPD pulse */
svdm_set_hpd_gpio(port, 0);
@@ -193,8 +199,9 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
usb_mux_hpd_update(port, mux_state);
#ifdef USB_PD_PORT_TCPC_MST
- if (port == USB_PD_PORT_TCPC_MST)
+ if (port == USB_PD_PORT_TCPC_MST) {
baseboard_mst_enable_control(port, lvl);
+ }
#endif
/* ack */
diff --git a/zephyr/projects/corsola/src/usbc_config.c b/zephyr/projects/corsola/src/usbc_config.c
index 54e5f48b25..5506e7fbe9 100644
--- a/zephyr/projects/corsola/src/usbc_config.c
+++ b/zephyr/projects/corsola/src/usbc_config.c
@@ -54,10 +54,11 @@ DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_PRE_DEFAULT);
__override uint8_t board_get_usb_pd_port_count(void)
{
if (corsola_get_db_type() == CORSOLA_DB_HDMI) {
- if (tasks_inited)
+ if (tasks_inited) {
return CONFIG_USB_PD_PORT_MAX_COUNT;
- else
+ } else {
return CONFIG_USB_PD_PORT_MAX_COUNT - 1;
+ }
}
return CONFIG_USB_PD_PORT_MAX_COUNT;
@@ -70,8 +71,9 @@ void usb_a0_interrupt(enum gpio_signal signal)
GPIO_DT_FROM_NODELABEL(gpio_ap_xhci_init_done)) ?
USB_CHARGE_MODE_ENABLED : USB_CHARGE_MODE_DISABLED;
- for (int i = 0; i < USB_PORT_COUNT; i++)
+ for (int i = 0; i < USB_PORT_COUNT; i++) {
usb_charge_set_mode(i, mode, USB_ALLOW_SUSPEND_CHARGE);
+ }
/*
* Trigger hard reset to cycle Vbus on Type-C ports, recommended by
@@ -79,8 +81,9 @@ void usb_a0_interrupt(enum gpio_signal signal)
*/
if (gpio_get_level(signal)) {
for (int i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
- if (tc_is_attached_src(i))
+ if (tc_is_attached_src(i)) {
pd_dpm_request(i, DPM_REQUEST_HARD_RESET_SEND);
+ }
}
}
}
@@ -112,14 +115,16 @@ static void ps185_hdmi_hpd_deferred(void)
GPIO_DT_FROM_ALIAS(gpio_ps185_ec_dp_hpd));
/* HPD status not changed, probably a glitch, just return. */
- if (debounced_hpd == new_hpd)
+ if (debounced_hpd == new_hpd) {
return;
+ }
debounced_hpd = new_hpd;
if (!corsola_is_dp_muxable(USBC_PORT_C1)) {
- if (debounced_hpd)
+ if (debounced_hpd) {
CPRINTS("C0 port is already muxed.");
+ }
return;
}
@@ -178,12 +183,13 @@ static void hdmi_hpd_interrupt(enum gpio_signal signal)
{
hook_call_deferred(&ps185_hdmi_hpd_deferred_data, PS185_HPD_DEBOUCE);
- if (!gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_ps185_ec_dp_hpd)))
+ if (!gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_ps185_ec_dp_hpd))) {
hook_call_deferred(&ps185_hdmi_hpd_disconnect_deferred_data,
HPD_SINK_ABSENCE_DEBOUNCE);
- else
+ } else {
hook_call_deferred(&ps185_hdmi_hpd_disconnect_deferred_data,
-1);
+ }
}
/* HDMI/TYPE-C function shared subboard interrupt */
@@ -191,13 +197,14 @@ void x_ec_interrupt(enum gpio_signal signal)
{
int sub = corsola_get_db_type();
- if (sub == CORSOLA_DB_TYPEC)
+ if (sub == CORSOLA_DB_TYPEC) {
/* C1: PPC interrupt */
ppc_interrupt(signal);
- else if (sub == CORSOLA_DB_HDMI)
+ } else if (sub == CORSOLA_DB_HDMI) {
hdmi_hpd_interrupt(signal);
- else
+ } else {
CPRINTS("Undetected subboard interrupt.");
+ }
}
static void board_hdmi_handler(struct ap_power_ev_callback *cb,
@@ -278,10 +285,11 @@ DECLARE_HOOK(HOOK_INIT, baseboard_x_ec_gpio2_init, HOOK_PRIO_DEFAULT);
__override uint8_t get_dp_pin_mode(int port)
{
if (corsola_get_db_type() == CORSOLA_DB_HDMI && port == USBC_PORT_C1) {
- if (usb_mux_get(USBC_PORT_C1) & USB_PD_MUX_DP_ENABLED)
+ if (usb_mux_get(USBC_PORT_C1) & USB_PD_MUX_DP_ENABLED) {
return MODE_DP_PIN_E;
- else
+ } else {
return 0;
+ }
}
return pd_dfp_dp_get_pin_mode(port, dp_status[port]);
diff --git a/zephyr/projects/corsola/src/variant_db_detection.c b/zephyr/projects/corsola/src/variant_db_detection.c
index 89741cce18..fc8427fbc7 100644
--- a/zephyr/projects/corsola/src/variant_db_detection.c
+++ b/zephyr/projects/corsola/src/variant_db_detection.c
@@ -55,13 +55,15 @@ enum corsola_db_type corsola_get_db_type(void)
{
static enum corsola_db_type db = CORSOLA_DB_NONE;
- if (db != CORSOLA_DB_NONE)
+ if (db != CORSOLA_DB_NONE) {
return db;
+ }
- if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_hdmi_prsnt_odl)))
+ if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_hdmi_prsnt_odl))) {
db = CORSOLA_DB_HDMI;
- else
+ } else {
db = CORSOLA_DB_TYPEC;
+ }
corsola_db_config(db);
diff --git a/zephyr/projects/corsola/usbc_krabby.dts b/zephyr/projects/corsola/usbc_krabby.dts
index 7ee4d2b8a5..8970ebc845 100644
--- a/zephyr/projects/corsola/usbc_krabby.dts
+++ b/zephyr/projects/corsola/usbc_krabby.dts
@@ -32,6 +32,7 @@
bc12 {
compatible = "richtek,rt9490-bc12";
status = "okay";
+ irq = <&int_usb_c1_bc12_charger>;
};
ppc {
compatible = "silergy,syv682x";
diff --git a/zephyr/projects/herobrine/BUILD.py b/zephyr/projects/herobrine/BUILD.py
index f2c86014ab..3bf790e0a7 100644
--- a/zephyr/projects/herobrine/BUILD.py
+++ b/zephyr/projects/herobrine/BUILD.py
@@ -2,8 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for herobrine."""
+
def register_variant(project_name, extra_dts_overlays=(), extra_kconfig_files=()):
+ """Register a variant of herobrine."""
register_npcx_project(
project_name=project_name,
zephyr_board="npcx9",
@@ -43,7 +46,7 @@ register_variant(
register_variant(
project_name="hoglin",
extra_dts_overlays=[
- here / "battery_herobrine.dts",
+ here / "battery_hoglin.dts",
here / "gpio_hoglin.dts",
here / "motionsense_hoglin.dts",
here / "switchcap_hoglin.dts",
diff --git a/zephyr/projects/herobrine/battery_hoglin.dts b/zephyr/projects/herobrine/battery_hoglin.dts
new file mode 100644
index 0000000000..79fc6ca296
--- /dev/null
+++ b/zephyr/projects/herobrine/battery_hoglin.dts
@@ -0,0 +1,12 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/ {
+ batteries {
+ default_battery: 7c01 {
+ compatible = "ganfeng,7c01", "battery-smart";
+ };
+ };
+};
diff --git a/zephyr/projects/herobrine/prj.conf b/zephyr/projects/herobrine/prj.conf
index 99d2d8c067..d61a8f7d32 100644
--- a/zephyr/projects/herobrine/prj.conf
+++ b/zephyr/projects/herobrine/prj.conf
@@ -100,7 +100,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=y
# USB-A
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USB-C
CONFIG_PLATFORM_EC_USB_PD_FRS=y
@@ -122,7 +121,6 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8805=y
CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n
CONFIG_PLATFORM_EC_USB_MUX_RUNTIME_CONFIG=n
CONFIG_PLATFORM_EC_USB_PD_LOGGING=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
CONFIG_PLATFORM_EC_CONFIG_USB_PD_3A_PORTS=2
# USB ID
diff --git a/zephyr/projects/intelrvp/BUILD.py b/zephyr/projects/intelrvp/BUILD.py
index 89ddd46970..1d052f2b55 100644
--- a/zephyr/projects/intelrvp/BUILD.py
+++ b/zephyr/projects/intelrvp/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for intelrvp."""
+
# intelrvp has adlrvp_npcx, adlrvpp_ite, adlrvpp_mchp etc
@@ -11,6 +13,7 @@ def register_intelrvp_project(
extra_dts_overlays=(),
extra_kconfig_files=(),
):
+ """Register a variant of intelrvp."""
register_func = register_binman_project
if chip.startswith("npcx9"):
register_func = register_npcx_project
diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/gpio.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/gpio.dts
index fc2a7448c3..fbe42b2303 100644
--- a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/gpio.dts
+++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/gpio.dts
@@ -258,6 +258,28 @@
tp-gpiof4 {
gpios = <&gpiof 4 GPIO_INPUT>;
};
+ /* USB C IOEX configuration */
+ usb-c0-hbr-ls-en {
+ gpios = <&ioex_c0 2 GPIO_OUTPUT_LOW>;
+ };
+ usb-c0-hbr-rst {
+ gpios = <&ioex_c0 3 GPIO_OUTPUT_LOW>;
+ };
+ usb-c1-hbr-ls-en {
+ gpios = <&ioex_c1 2 GPIO_OUTPUT_LOW>;
+ };
+ usb-c1-hbr-rst {
+ gpios = <&ioex_c1 3 GPIO_OUTPUT_LOW>;
+ };
+ usb-c0-mux-oe-n {
+ gpios = <&ioex_c0 4 GPIO_OUTPUT_LOW>;
+ };
+ usb-c0-mux-sbu-sel-0 {
+ gpios = <&ioex_c0 6 GPIO_OUTPUT_HIGH>;
+ };
+ usb-c0-mux-sbu-sel-1 {
+ gpios = <&ioex_c1 4 GPIO_OUTPUT_LOW>;
+ };
};
def-lvol-io-list {
@@ -274,3 +296,43 @@
>;
};
};
+
+&i2c0_0 {
+ nct38xx_C0:nct38xx_C0@70 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nuvoton,nct38xx-gpio";
+ reg = <0x70>;
+ label = "NCT38XX_C0";
+
+ ioex_c0:gpio@0 {
+ compatible = "nuvoton,nct38xx-gpio-port";
+ reg = <0x0>;
+ label = "NCT38XX_C0_GPIO0";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ pin_mask = <0xff>;
+ pinmux_mask = <0xf7>;
+ };
+ };
+
+ nct38xx_C1:nct38xx_C1@70 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nuvoton,nct38xx-gpio";
+ reg = <0x70>;
+ label = "NCT38XX_C1";
+
+ ioex_c1:gpio@0 {
+ compatible = "nuvoton,nct38xx-gpio-port";
+ reg = <0x0>;
+ label = "NCT38XX_C1_GPIO0";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <8>;
+ pin_mask = <0xff>;
+ pinmux_mask = <0xf7>;
+ };
+ };
+};
diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts
index e50330c6d4..9bddcb88ec 100644
--- a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts
+++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts
@@ -15,11 +15,11 @@
i2c-port = <&i2c7_0>;
enum-name = "I2C_PORT_CHARGER";
};
- typec_aic1 {
+ typec_aic1: typec-aic1{
i2c-port = <&i2c0_0>;
enum-name = "I2C_PORT_TYPEC_AIC_1";
};
- typec_aic2 {
+ typec_aic2: typec-aic2{
i2c-port = <&i2c2_0>;
enum-name = "I2C_PORT_TYPEC_AIC_2";
};
diff --git a/zephyr/projects/intelrvp/mtlrvp/prj.conf b/zephyr/projects/intelrvp/mtlrvp/prj.conf
index fde700735e..badcb562ec 100644
--- a/zephyr/projects/intelrvp/mtlrvp/prj.conf
+++ b/zephyr/projects/intelrvp/mtlrvp/prj.conf
@@ -18,7 +18,13 @@ CONFIG_PLATFORM_EC_USBC=n
CONFIG_PLATFORM_EC_CHARGER=n
# IOEX
+CONFIG_PLATFORM_EC_IOEX=y
CONFIG_GPIO_PCA95XX=y
+CONFIG_GPIO_NCT38XX=y
+
+# USB CONFIG
+CONFIG_PLATFORM_EC_USB_PD_TCPM_NCT38XX=y
+CONFIG_PLATFORM_EC_USB_PD_TCPM_MUX=y
# TODO: Enable these in follow on CLs
CONFIG_PLATFORM_EC_KEYBOARD=n
diff --git a/zephyr/projects/it8xxx2_evb/BUILD.py b/zephyr/projects/it8xxx2_evb/BUILD.py
index 9d488776be..3dea4d9c20 100644
--- a/zephyr/projects/it8xxx2_evb/BUILD.py
+++ b/zephyr/projects/it8xxx2_evb/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for it8xxx2_evb."""
+
register_raw_project(
project_name="it8xxx2_evb",
zephyr_board="it8xxx2_evb",
diff --git a/zephyr/projects/nissa/BUILD.py b/zephyr/projects/nissa/BUILD.py
index 618b6401b1..6b8cc39dbf 100644
--- a/zephyr/projects/nissa/BUILD.py
+++ b/zephyr/projects/nissa/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for nissa."""
+
# Nivviks has NPCX993F, Nereid has ITE81302
@@ -11,6 +13,7 @@ def register_nissa_project(
extra_dts_overlays=(),
extra_kconfig_files=(),
):
+ """Register a variant of nissa."""
register_func = register_binman_project
if chip.startswith("npcx9"):
register_func = register_npcx_project
diff --git a/zephyr/projects/nissa/nereid_overlay.dts b/zephyr/projects/nissa/nereid_overlay.dts
index 534f9ff010..08b796d0fe 100644
--- a/zephyr/projects/nissa/nereid_overlay.dts
+++ b/zephyr/projects/nissa/nereid_overlay.dts
@@ -127,6 +127,10 @@
gpio-en-rails-odl = &gpio_sb_1;
gpio-hdmi-en-odl = &gpio_sb_4;
gpio-hpd-odl = &gpio_sb_3;
+ /*
+ * Enable S5 rails for LTE sub-board
+ */
+ gpio-en-sub-s5-rails = &gpio_sb_2;
};
named-temp-sensors {
diff --git a/zephyr/projects/nissa/nivviks_overlay.dts b/zephyr/projects/nissa/nivviks_overlay.dts
index ab34f1c985..63c857cf6d 100644
--- a/zephyr/projects/nissa/nivviks_overlay.dts
+++ b/zephyr/projects/nissa/nivviks_overlay.dts
@@ -126,6 +126,10 @@
*/
gpio-hdmi-en-odl = &gpio_sb_3;
gpio-hpd-odl = &gpio_sb_4;
+ /*
+ * Enable S5 rails for LTE sub-board
+ */
+ gpio-en-sub-s5-rails = &gpio_sb_2;
};
named-temp-sensors {
diff --git a/zephyr/projects/nissa/prj.conf b/zephyr/projects/nissa/prj.conf
index 7ba18ccc6d..6e870398a6 100644
--- a/zephyr/projects/nissa/prj.conf
+++ b/zephyr/projects/nissa/prj.conf
@@ -140,6 +140,7 @@ CONFIG_PLATFORM_EC_BATTERY_CUT_OFF=y
CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y
CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y
CONFIG_PLATFORM_EC_BATTERY_SMART=y
+CONFIG_PLATFORM_EC_BATTERY_REVIVE_DISCONNECT=y
# Charger support
CONFIG_PLATFORM_EC_CHARGER=y
diff --git a/zephyr/projects/nissa/src/sub_board.c b/zephyr/projects/nissa/src/sub_board.c
index a42e0c3b64..7dd5a6208d 100644
--- a/zephyr/projects/nissa/src/sub_board.c
+++ b/zephyr/projects/nissa/src/sub_board.c
@@ -69,6 +69,27 @@ static void hdmi_hpd_interrupt(const struct device *device,
LOG_DBG("HDMI HPD changed state to %d", state);
}
+static void lte_power_handler(struct ap_power_ev_callback *cb,
+ struct ap_power_ev_data data)
+{
+ /* Enable rails for S5 */
+ const struct gpio_dt_spec *s5_rail =
+ GPIO_DT_FROM_ALIAS(gpio_en_sub_s5_rails);
+ switch (data.event) {
+ case AP_POWER_PRE_INIT:
+ LOG_DBG("Enabling LTE sub-board power rails");
+ gpio_pin_set_dt(s5_rail, 1);
+ break;
+ case AP_POWER_SHUTDOWN:
+ LOG_DBG("Disabling LTE sub-board power rails");
+ gpio_pin_set_dt(s5_rail, 0);
+ break;
+ default:
+ LOG_ERR("Unhandled LTE power event %d", data.event);
+ break;
+ }
+}
+
/**
* Configure GPIOs (and other pin functions) that vary with present sub-board.
*
@@ -79,6 +100,7 @@ static void hdmi_hpd_interrupt(const struct device *device,
static void nereid_subboard_config(void)
{
enum nissa_sub_board_type sb = nissa_get_sb_type();
+ static struct ap_power_ev_callback power_cb;
/*
* USB-A port: current limit output is configured by default and unused
@@ -114,15 +136,16 @@ static void nereid_subboard_config(void)
/* Disable the port 1 charger task */
task_disable_task(TASK_ID_USB_CHG_P1);
}
- /*
- * HDMI: two outputs control power which must be configured to
- * non-default settings, and HPD must be forwarded to the AP on
- * another output pin.
- */
- if (sb == NISSA_SB_HDMI_A) {
+
+ switch (sb) {
+ case NISSA_SB_HDMI_A:
+ /*
+ * HDMI: two outputs control power which must be configured to
+ * non-default settings, and HPD must be forwarded to the AP
+ * on another output pin.
+ */
const struct gpio_dt_spec *hpd_gpio =
GPIO_DT_FROM_ALIAS(gpio_hpd_odl);
- static struct ap_power_ev_callback hdmi_power_cb;
static struct gpio_callback hdmi_hpd_cb;
int rv, irq_key;
@@ -135,10 +158,10 @@ static void nereid_subboard_config(void)
GPIO_ACTIVE_LOW);
/* Control HDMI power in concert with AP */
ap_power_ev_init_callback(
- &hdmi_power_cb, hdmi_power_handler,
+ &power_cb, hdmi_power_handler,
AP_POWER_PRE_INIT | AP_POWER_HARD_OFF |
AP_POWER_STARTUP | AP_POWER_SHUTDOWN);
- ap_power_ev_add_callback(&hdmi_power_cb);
+ ap_power_ev_add_callback(&power_cb);
/*
* Configure HPD input from sub-board; it's inverted by a buffer
@@ -163,6 +186,26 @@ static void nereid_subboard_config(void)
hdmi_hpd_interrupt(hpd_gpio->port, &hdmi_hpd_cb,
BIT(hpd_gpio->pin));
irq_unlock(irq_key);
+ break;
+
+ case NISSA_SB_C_LTE:
+ /*
+ * LTE: Set up callbacks for enabling/disabling
+ * sub-board power on S5 state.
+ */
+ gpio_pin_configure_dt(GPIO_DT_FROM_ALIAS(gpio_en_sub_s5_rails),
+ GPIO_OUTPUT_INACTIVE);
+ /* Control LTE power when CPU entering or
+ * exiting S5 state.
+ */
+ ap_power_ev_init_callback(
+ &power_cb, lte_power_handler,
+ AP_POWER_SHUTDOWN | AP_POWER_PRE_INIT);
+ ap_power_ev_add_callback(&power_cb);
+ break;
+
+ default:
+ break;
}
}
DECLARE_HOOK(HOOK_INIT, nereid_subboard_config, HOOK_PRIO_POST_FIRST);
diff --git a/zephyr/projects/npcx_evb/npcx7/BUILD.py b/zephyr/projects/npcx_evb/npcx7/BUILD.py
index a8e671609c..89afed0fc1 100644
--- a/zephyr/projects/npcx_evb/npcx7/BUILD.py
+++ b/zephyr/projects/npcx_evb/npcx7/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for npcx7_evb."""
+
register_npcx_project(
project_name="npcx7",
zephyr_board="npcx7_evb",
diff --git a/zephyr/projects/npcx_evb/npcx7/prj.conf b/zephyr/projects/npcx_evb/npcx7/prj.conf
index 2e8fa83cf8..0b858a3a82 100644
--- a/zephyr/projects/npcx_evb/npcx7/prj.conf
+++ b/zephyr/projects/npcx_evb/npcx7/prj.conf
@@ -54,7 +54,4 @@ CONFIG_LOG=y
# Avoid underflow info from tachometer
CONFIG_SENSOR_LOG_LEVEL_ERR=y
-# Avoid info storm from power management
-CONFIG_SOC_LOG_LEVEL_ERR=y
-
CONFIG_SYSCON=y
diff --git a/zephyr/projects/npcx_evb/npcx9/BUILD.py b/zephyr/projects/npcx_evb/npcx9/BUILD.py
index fb1b2707d8..efd96c9020 100644
--- a/zephyr/projects/npcx_evb/npcx9/BUILD.py
+++ b/zephyr/projects/npcx_evb/npcx9/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for npcx9_evb."""
+
register_npcx_project(
project_name="npcx9",
zephyr_board="npcx9_evb",
diff --git a/zephyr/projects/npcx_evb/npcx9/prj.conf b/zephyr/projects/npcx_evb/npcx9/prj.conf
index c025e32ec5..becb9ed228 100644
--- a/zephyr/projects/npcx_evb/npcx9/prj.conf
+++ b/zephyr/projects/npcx_evb/npcx9/prj.conf
@@ -58,7 +58,4 @@ CONFIG_LOG=y
# Avoid underflow info from tachometer
CONFIG_SENSOR_LOG_LEVEL_ERR=y
-# Avoid info storm from power management
-CONFIG_SOC_LOG_LEVEL_ERR=y
-
CONFIG_SYSCON=y
diff --git a/zephyr/projects/posix-ec/BUILD.py b/zephyr/projects/posix-ec/BUILD.py
index b94d087642..a324f2ad39 100644
--- a/zephyr/projects/posix-ec/BUILD.py
+++ b/zephyr/projects/posix-ec/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for posix-ec."""
+
register_host_project(project_name="posix-ec")
diff --git a/zephyr/projects/skyrim/BUILD.py b/zephyr/projects/skyrim/BUILD.py
index e206bdd0d5..708109590d 100644
--- a/zephyr/projects/skyrim/BUILD.py
+++ b/zephyr/projects/skyrim/BUILD.py
@@ -2,8 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for skyrim."""
+
def register_variant(project_name):
+ """Register a variant of skyrim."""
register_npcx_project(
project_name=project_name,
zephyr_board="npcx9",
diff --git a/zephyr/projects/skyrim/gpio.dts b/zephyr/projects/skyrim/gpio.dts
index 9c1896265d..4e717482eb 100644
--- a/zephyr/projects/skyrim/gpio.dts
+++ b/zephyr/projects/skyrim/gpio.dts
@@ -174,8 +174,9 @@
gpio_ec_kso_02_inv: ec_kso_02_inv {
gpios = <&gpio1 7 (GPIO_OUTPUT_LOW | GPIO_ACTIVE_LOW)>;
};
- tablet_mode {
+ tablet_mode_l {
gpios = <&gpioc 1 GPIO_INPUT>;
+ enum-name = "GPIO_TABLET_MODE_L";
};
ec_gpio56 {
gpios = <&gpio5 6 GPIO_INPUT_PULL_UP>;
@@ -201,7 +202,7 @@
gpios = <&ioex_c0_port1 2 GPIO_INPUT>;
enum-name = "IOEX_USB_C0_FAULT_ODL";
};
- ioex_en_pp5500_usb_a0_vbus: en_pp5500_usb_a0_vbus {
+ ioex_en_pp5000_usb_a0_vbus: en_pp5000_usb_a0_vbus {
gpios = <&ioex_c0_port1 5 GPIO_OUTPUT_LOW>;
enum-name = "IOEX_EN_PP5000_USB_A0_VBUS";
};
@@ -244,7 +245,7 @@
gpios = <&ioex_c1_port1 2 GPIO_INPUT>;
enum-name = "IOEX_USB_C1_FAULT_ODL";
};
- ioex_en_pp5500_usb_a1_vbus: en_pp5500_usb_a1_vbus {
+ ioex_en_pp5000_usb_a1_vbus: en_pp5000_usb_a1_vbus {
gpios = <&ioex_c1_port1 5 GPIO_OUTPUT_LOW>;
enum-name = "IOEX_EN_PP5000_USB_A1_VBUS_DB";
};
@@ -261,8 +262,8 @@
usba-port-enable-list {
compatible = "cros-ec,usba-port-enable-pins";
- enable-pins = <&ioex_en_pp5500_usb_a0_vbus
- &ioex_en_pp5500_usb_a1_vbus>;
+ enable-pins = <&ioex_en_pp5000_usb_a0_vbus
+ &ioex_en_pp5000_usb_a1_vbus>;
};
vsby-psl-in-list {
diff --git a/zephyr/projects/skyrim/prj.conf b/zephyr/projects/skyrim/prj.conf
index a9be70454b..c69ede5cfd 100644
--- a/zephyr/projects/skyrim/prj.conf
+++ b/zephyr/projects/skyrim/prj.conf
@@ -96,7 +96,6 @@ CONFIG_PLATFORM_EC_CHARGER_MIN_POWER_MW_FOR_POWER_ON=50000
# USB-A
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USB-C
CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y
@@ -124,6 +123,8 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_NCT38XX=y
CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n
CONFIG_PLATFORM_EC_USB_PD_USB4=n
CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y
+# Give ourselves enough task space to use i2ctrace
+CONFIG_TASK_PD_STACK_SIZE=1280
# IOEX
CONFIG_GPIO_NCT38XX=y
@@ -143,6 +144,9 @@ 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_GMR_TABLET_MODE=y
+
CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y
CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
diff --git a/zephyr/projects/trogdor/lazor/BUILD.py b/zephyr/projects/trogdor/lazor/BUILD.py
index dabaddc236..13446cb702 100644
--- a/zephyr/projects/trogdor/lazor/BUILD.py
+++ b/zephyr/projects/trogdor/lazor/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Define zmake projects for lazor."""
+
register_npcx_project(
project_name="lazor",
zephyr_board="npcx7",
diff --git a/zephyr/projects/trogdor/lazor/prj.conf b/zephyr/projects/trogdor/lazor/prj.conf
index f95d5a4153..2a61f5854f 100644
--- a/zephyr/projects/trogdor/lazor/prj.conf
+++ b/zephyr/projects/trogdor/lazor/prj.conf
@@ -96,7 +96,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=y
# USB-A
CONFIG_PLATFORM_EC_USBA=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USB-C
CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y
@@ -116,7 +115,6 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8805=y
CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n
CONFIG_PLATFORM_EC_USB_MUX_RUNTIME_CONFIG=n
CONFIG_PLATFORM_EC_USB_PD_LOGGING=y
-CONFIG_PLATFORM_EC_USB_PORT_POWER_DUMB=y
# USB ID
# This is allocated specifically for Trogdor
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 2900acd9aa..5f865c3fa7 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -804,7 +804,8 @@ extern struct jump_data mock_jump_data;
#endif
#undef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
-#ifdef CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP
+#if defined(CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP) || \
+ defined(CONFIG_AP_PWRSEQ_HOST_SLEEP)
#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE
#endif
@@ -840,7 +841,8 @@ extern struct jump_data mock_jump_data;
#endif
#undef CONFIG_POWER_S0IX
-#ifdef CONFIG_PLATFORM_EC_POWERSEQ_S0IX
+#if defined(CONFIG_PLATFORM_EC_POWERSEQ_S0IX) || \
+ defined(CONFIG_AP_PWRSEQ_S0IX)
#define CONFIG_POWER_S0IX
#endif
diff --git a/zephyr/shim/include/power_host_sleep.h b/zephyr/shim/include/power_host_sleep.h
new file mode 100644
index 0000000000..e4f24b7d88
--- /dev/null
+++ b/zephyr/shim/include/power_host_sleep.h
@@ -0,0 +1,71 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __POWER_HOST_SLEEP_H
+#define __POWER_HOST_SLEEP_H
+
+/*
+ * This file is for Zephyr ap_pwrseq to reuse legacy EC code.
+ * Eventually this file should be removed.
+ *
+ * TODO: Declaration in this file should be removed once it can be replaced
+ * by implementation in Zephyr code.
+ */
+#if CONFIG_AP_PWRSEQ
+
+#include "ec_commands.h"
+#include "host_command.h"
+#include "lpc.h"
+#include "system.h"
+
+/********************************************************************/
+/* power.h */
+enum power_state {
+ /* Steady states */
+ POWER_G3 = 0, /*
+ * System is off (not technically all the way into G3,
+ * which means totally unpowered...)
+ */
+ POWER_S5, /* System is soft-off */
+ POWER_S4, /* System is suspended to disk */
+ POWER_S3, /* Suspend; RAM on, processor is asleep */
+ POWER_S0, /* System is on */
+#if CONFIG_AP_PWRSEQ_S0IX
+ POWER_S0ix,
+#endif
+ /* Transitions */
+ POWER_G3S5, /* G3 -> S5 (at system init time) */
+ POWER_S5S3, /* S5 -> S3 (skips S4 on non-Intel systems) */
+ POWER_S3S0, /* S3 -> S0 */
+ POWER_S0S3, /* S0 -> S3 */
+ POWER_S3S5, /* S3 -> S5 (skips S4 on non-Intel systems) */
+ POWER_S5G3, /* S5 -> G3 */
+ POWER_S3S4, /* S3 -> S4 */
+ POWER_S4S3, /* S4 -> S3 */
+ POWER_S4S5, /* S4 -> S5 */
+ POWER_S5S4, /* S5 -> S4 */
+#if CONFIG_AP_PWRSEQ_S0IX
+ POWER_S0ixS0, /* S0ix -> S0 */
+ POWER_S0S0ix, /* S0 -> S0ix */
+#endif
+};
+
+#if CONFIG_AP_PWRSEQ_HOST_SLEEP
+/* Context to pass to a host sleep command handler. */
+struct host_sleep_event_context {
+ uint32_t sleep_transitions; /* Number of sleep transitions observed */
+ uint16_t sleep_timeout_ms; /* Timeout in milliseconds */
+};
+
+void ap_power_chipset_handle_host_sleep_event(
+ enum host_sleep_event state,
+ struct host_sleep_event_context *ctx);
+enum host_sleep_event power_get_host_sleep_state(void);
+void power_set_host_sleep_state(enum host_sleep_event state);
+#endif /* CONFIG_AP_PWRSEQ_HOST_SLEEP */
+
+#endif /* CONFIG_AP_PWRSEQ */
+
+#endif /* __POWER_HOST_SLEEP_H */
diff --git a/zephyr/shim/include/usbc/ppc.h b/zephyr/shim/include/usbc/ppc.h
index cc989d7816..00c7c36c41 100644
--- a/zephyr/shim/include/usbc/ppc.h
+++ b/zephyr/shim/include/usbc/ppc.h
@@ -11,12 +11,12 @@
#include "usbc/ppc_rt1739.h"
#include "usbc/ppc_sn5s330.h"
#include "usbc/ppc_syv682x.h"
+#include "usbc/utils.h"
#include "usbc_ppc.h"
#define PPC_ID(id) DT_CAT(PPC_, id)
#define PPC_ID_WITH_COMMA(id) PPC_ID(id),
-#define PPC_USBC_PORT(id) DT_REG_ADDR(DT_PARENT(id))
-#define PPC_ALT_FOR(alt_id) PPC_USBC_PORT(DT_PHANDLE(alt_id, alternate_for))
+#define PPC_ALT_FOR(alt_id) USBC_PORT(DT_PHANDLE(alt_id, alternate_for))
#define PPC_ALT_ENUM(id) \
COND_CODE_1(DT_NODE_HAS_PROP(id, alternate_for), \
diff --git a/zephyr/shim/include/usbc/utils.h b/zephyr/shim/include/usbc/utils.h
new file mode 100644
index 0000000000..49b9aa4b71
--- /dev/null
+++ b/zephyr/shim/include/usbc/utils.h
@@ -0,0 +1,36 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_ZEPHYR_SHIM_USBC_UTIL
+
+
+/*
+ * Enable interrupt from the `irq` property of an instance's node.
+ *
+ * @param inst: instance number
+ */
+#define BC12_GPIO_ENABLE_INTERRUPT(inst) \
+ IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, irq), \
+ (gpio_enable_dt_interrupt( \
+ GPIO_INT_FROM_NODE(DT_INST_PHANDLE(inst, irq)));\
+ ) \
+ )
+
+/*
+ * Get the port number from a child of `named-usbc-port` node.
+ *
+ * @param id: node id
+ */
+#define USBC_PORT(id) DT_REG_ADDR(DT_PARENT(id))
+
+/*
+ * Get the port number from a child of `named-usbc-port` node.
+ *
+ * @param inst: instance number of the node
+ */
+#define USBC_PORT_FROM_INST(inst) USBC_PORT(DT_DRV_INST(inst))
+
+
+#endif /* __CROS_EC_ZEPHYR_SHIM_USBC_UTIL */
diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt
index 4afacd396e..bc9729abae 100644
--- a/zephyr/shim/src/CMakeLists.txt
+++ b/zephyr/shim/src/CMakeLists.txt
@@ -24,6 +24,8 @@ zephyr_library_sources_ifdef(no_libgcc libgcc_${ARCH}.S)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ADC adc.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_BATTERY
battery.c)
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_RT9490
+ bc12_rt9490.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI
espi.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN fan.c)
@@ -65,4 +67,4 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_TCPCI
tcpc.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBA usba.c)
-
+zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ power_host_sleep_api.c)
diff --git a/zephyr/shim/src/bc12.c b/zephyr/shim/src/bc12.c
index 408458365f..fc6dfb6aa9 100644
--- a/zephyr/shim/src/bc12.c
+++ b/zephyr/shim/src/bc12.c
@@ -7,14 +7,13 @@
#include "usbc/bc12_pi3usb9201.h"
#include "usbc/bc12_rt1739.h"
#include "usbc/bc12_rt9490.h"
+#include "usbc/utils.h"
#include "usb_charge.h"
#if DT_HAS_COMPAT_STATUS_OKAY(RT1739_BC12_COMPAT) || \
DT_HAS_COMPAT_STATUS_OKAY(RT9490_BC12_COMPAT) || \
DT_HAS_COMPAT_STATUS_OKAY(PI3USB9201_COMPAT)
-#define USBC_PORT(id) DT_REG_ADDR(DT_PARENT(id))
-
#define BC12_CHIP(id, fn) [USBC_PORT(id)] = fn(id)
/* Power Path Controller */
diff --git a/zephyr/shim/src/bc12_pi3usb9201.c b/zephyr/shim/src/bc12_pi3usb9201.c
index 49e6902e74..57e4ed7b61 100644
--- a/zephyr/shim/src/bc12_pi3usb9201.c
+++ b/zephyr/shim/src/bc12_pi3usb9201.c
@@ -12,6 +12,7 @@
#include "task.h"
#include "usb_charge.h"
#include "usb_pd.h"
+#include "usbc/utils.h"
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
@@ -30,12 +31,6 @@ const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
DT_INST_FOREACH_STATUS_OKAY(USBC_PORT_BC12)
};
-#define BC12_GPIO_ENABLE_INTERRUPT(inst) \
- IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, irq), \
- (gpio_enable_dt_interrupt( \
- GPIO_INT_FROM_NODE(DT_INST_PHANDLE(inst, irq)))) \
- );
-
static void bc12_enable_irqs(void)
{
DT_INST_FOREACH_STATUS_OKAY(BC12_GPIO_ENABLE_INTERRUPT)
diff --git a/zephyr/shim/src/bc12_rt9490.c b/zephyr/shim/src/bc12_rt9490.c
new file mode 100644
index 0000000000..68798241d5
--- /dev/null
+++ b/zephyr/shim/src/bc12_rt9490.c
@@ -0,0 +1,41 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#define DT_DRV_COMPAT richtek_rt9490_bc12
+
+#include <devicetree.h>
+#include "driver/charger/rt9490.h"
+#include "gpio/gpio_int.h"
+#include "hooks.h"
+#include "usbc/utils.h"
+
+#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
+
+static void rt9490_bc12_enable_irqs(void)
+{
+ DT_INST_FOREACH_STATUS_OKAY(BC12_GPIO_ENABLE_INTERRUPT);
+}
+DECLARE_HOOK(HOOK_INIT, rt9490_bc12_enable_irqs, HOOK_PRIO_DEFAULT);
+
+#define GPIO_SIGNAL_FROM_INST(inst) \
+ GPIO_SIGNAL(DT_PHANDLE(DT_INST_PHANDLE(inst, irq), irq_pin))
+
+#define RT9490_DISPATCH_INTERRUPT(inst) \
+ IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, irq), \
+ (case GPIO_SIGNAL_FROM_INST(inst): \
+ rt9490_interrupt(USBC_PORT_FROM_INST(inst)); \
+ break; \
+ ))
+
+void rt9490_bc12_dt_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ DT_INST_FOREACH_STATUS_OKAY(RT9490_DISPATCH_INTERRUPT);
+ default:
+ break;
+ }
+}
+
+#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/zephyr/shim/src/espi.c b/zephyr/shim/src/espi.c
index 37a051e57c..31cc51f9fc 100644
--- a/zephyr/shim/src/espi.c
+++ b/zephyr/shim/src/espi.c
@@ -83,6 +83,7 @@ static bool init_done;
return B;
#define CASE_ZEPHYR_TO_CROS(A, B) CASE_CROS_TO_ZEPHYR(B, A)
+#if !defined(CONFIG_AP_PWRSEQ)
/* Translate a platform/ec signal to a Zephyr signal */
static enum espi_vwire_signal signal_to_zephyr_vwire(enum espi_vw_signal signal)
{
@@ -138,6 +139,8 @@ static void espi_vwire_handler(const struct device *dev,
}
}
+#endif /* !defined(CONFIG_AP_PWRSEQ) */
+
#ifdef CONFIG_PLATFORM_EC_CHIPSET_RESET_HOOK
static void espi_chipset_reset(void)
{
@@ -161,6 +164,7 @@ static void espi_reset_handler(const struct device *dev,
#define espi_dev DEVICE_DT_GET(DT_CHOSEN(cros_ec_espi))
+#if !defined(CONFIG_AP_PWRSEQ)
int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level)
{
@@ -198,6 +202,8 @@ int espi_vw_disable_wire_int(enum espi_vw_signal signal)
return 0;
}
+#endif /* !defined(CONFIG_AP_PWRSEQ) */
+
uint8_t *lpc_get_memmap_range(void)
{
uint32_t lpc_memmap = 0;
@@ -228,6 +234,8 @@ static void lpc_update_wake(host_event_t wake_events)
!wake_events);
}
+#if !defined(CONFIG_AP_PWRSEQ)
+
static void lpc_generate_smi(void)
{
/* Enforce signal-high for long enough to debounce high */
@@ -248,6 +256,33 @@ static void lpc_generate_sci(void)
espi_vw_set_wire(VW_SCI_L, 1);
}
+#else
+
+/*
+ * Use Zephyr API.
+ */
+static void lpc_generate_signal(enum espi_vwire_signal signal)
+{
+ /* Enforce signal-high for long enough to debounce high */
+ espi_send_vwire(espi_dev, signal, 1);
+ udelay(VWIRE_PULSE_TRIGGER_TIME);
+ espi_send_vwire(espi_dev, signal, 0);
+ udelay(VWIRE_PULSE_TRIGGER_TIME);
+ espi_send_vwire(espi_dev, signal, 1);
+}
+
+static void lpc_generate_sci(void)
+{
+ lpc_generate_signal(ESPI_VWIRE_SIGNAL_SCI);
+}
+
+static void lpc_generate_smi(void)
+{
+ lpc_generate_signal(ESPI_VWIRE_SIGNAL_SMI);
+}
+
+#endif /* !defined(CONFIG_AP_PWRSEQ) */
+
void lpc_update_host_event_status(void)
{
uint32_t enable;
@@ -523,10 +558,12 @@ static int zephyr_shim_setup_espi(const struct device *unused)
espi_callback_handler_t handler;
enum espi_bus_event event_type;
} callbacks[] = {
+#if !defined(CONFIG_AP_PWRSEQ)
{
.handler = espi_vwire_handler,
.event_type = ESPI_BUS_EVENT_VWIRE_RECEIVED,
},
+#endif
{
.handler = espi_peripheral_handler,
.event_type = ESPI_BUS_PERIPHERAL_NOTIFICATION,
diff --git a/zephyr/shim/src/led_driver/led.h b/zephyr/shim/src/led_driver/led.h
index 53728609ed..086d2312b5 100644
--- a/zephyr/shim/src/led_driver/led.h
+++ b/zephyr/shim/src/led_driver/led.h
@@ -6,6 +6,8 @@
#ifndef __CROS_EC_LED_H__
#define __CROS_EC_LED_H__
+#include <devicetree.h>
+
#define COMPAT_GPIO_LED cros_ec_gpio_led_pins
#define COMPAT_PWM_LED cros_ec_pwm_led_pins
@@ -19,11 +21,22 @@
(DT_STRING_UPPER_TOKEN(id, prop)), \
(-1))
-/* TODO(b/227798487): Use DT to generate this enum instead of hardcoding */
+#define LED_ENUM(id, enum_name) DT_STRING_TOKEN(id, enum_name)
+#define LED_ENUM_WITH_COMMA(id, enum_name) \
+ COND_CODE_1(DT_NODE_HAS_PROP(id, enum_name), \
+ (LED_ENUM(id, enum_name),), ())
+
+#define GPIO_LED_PINS_NODE DT_PATH(gpio_led_pins)
+#define PWM_LED_PINS_NODE DT_PATH(pwm_led_pins)
+
enum led_color {
- LED_OFF = 0,
- LED_AMBER,
- LED_BLUE,
+#if DT_NODE_EXISTS(GPIO_LED_PINS_NODE)
+ DT_FOREACH_CHILD_VARGS(GPIO_LED_PINS_NODE,
+ LED_ENUM_WITH_COMMA, led_color)
+#elif DT_NODE_EXISTS(PWM_LED_PINS_NODE)
+ DT_FOREACH_CHILD_VARGS(PWM_LED_PINS_NODE,
+ LED_ENUM_WITH_COMMA, led_color)
+#endif
LED_COLOR_COUNT /* Number of colors, not a color itself */
};
diff --git a/zephyr/shim/src/led_driver/led_gpio.c b/zephyr/shim/src/led_driver/led_gpio.c
index 85bdc2dd71..9107aad579 100644
--- a/zephyr/shim/src/led_driver/led_gpio.c
+++ b/zephyr/shim/src/led_driver/led_gpio.c
@@ -17,7 +17,6 @@
LOG_MODULE_REGISTER(gpio_led, LOG_LEVEL_ERR);
-#define GPIO_LED_PINS_NODE DT_PATH(gpio_led_pins)
#define LED_PIN_COUNT (LED_COLOR_COUNT - 1)
/*
diff --git a/zephyr/shim/src/led_driver/led_pwm.c b/zephyr/shim/src/led_driver/led_pwm.c
index d2605256a5..d2466e0d60 100644
--- a/zephyr/shim/src/led_driver/led_pwm.c
+++ b/zephyr/shim/src/led_driver/led_pwm.c
@@ -17,7 +17,6 @@
LOG_MODULE_REGISTER(pwm_led, LOG_LEVEL_ERR);
-#define PWM_LED_PINS_NODE DT_PATH(pwm_led_pins)
#define LED_PIN_COUNT (LED_COLOR_COUNT - 1)
/*
diff --git a/zephyr/shim/src/power_host_sleep_api.c b/zephyr/shim/src/power_host_sleep_api.c
new file mode 100644
index 0000000000..d22f4fe4c4
--- /dev/null
+++ b/zephyr/shim/src/power_host_sleep_api.c
@@ -0,0 +1,45 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <kernel.h>
+
+#include <ap_power/ap_power_interface.h>
+#include <power_host_sleep.h>
+
+static enum power_state translate_ap_power_state(
+ enum power_states_ndsx ap_power_state)
+{
+ switch (ap_power_state) {
+ case SYS_POWER_STATE_S5:
+ return POWER_S5;
+ case SYS_POWER_STATE_S3:
+ return POWER_S3;
+#if CONFIG_AP_PWRSEQ_S0IX
+ case SYS_POWER_STATE_S0ix:
+ return POWER_S0ix;
+#endif
+ default:
+ return 0;
+ }
+}
+
+int ap_power_get_lazy_wake_mask(
+ enum power_states_ndsx state, host_event_t *mask)
+{
+ enum power_state st;
+
+ st = translate_ap_power_state(state);
+ if (!st)
+ return -EINVAL;
+ return get_lazy_wake_mask(st, mask);
+}
+
+#if CONFIG_AP_PWRSEQ_HOST_SLEEP
+void power_chipset_handle_host_sleep_event(
+ enum host_sleep_event state,
+ struct host_sleep_event_context *ctx)
+{
+ ap_power_chipset_handle_host_sleep_event(state, ctx);
+}
+#endif
diff --git a/zephyr/shim/src/ppc.c b/zephyr/shim/src/ppc.c
index b8c50f7a24..a77f7aa656 100644
--- a/zephyr/shim/src/ppc.c
+++ b/zephyr/shim/src/ppc.c
@@ -22,7 +22,7 @@
COND_CODE_1(DT_NODE_HAS_PROP(id, alternate_for), \
(PPC_CHIP_ELE_ALT(id, fn)), ())
-#define PPC_CHIP_ELE_PRIM(id, fn) [PPC_USBC_PORT(id)] = fn(id)
+#define PPC_CHIP_ELE_PRIM(id, fn) [USBC_PORT(id)] = fn(id)
#define PPC_CHIP_ELE_ALT(id, fn) [PPC_ID(id)] = fn(id)
diff --git a/zephyr/shim/src/tasks.c b/zephyr/shim/src/tasks.c
index 5b8fb502be..7c0d758d66 100644
--- a/zephyr/shim/src/tasks.c
+++ b/zephyr/shim/src/tasks.c
@@ -48,20 +48,20 @@ struct task_ctx_cfg {
intptr_t parameter;
};
+struct task_ctx_base_data {
+ /** A wait-able event that is raised when a new task event is posted */
+ struct k_poll_signal new_event;
+ /** The current platform/ec events set for this task/thread */
+ atomic_t event_mask;
+};
+
struct task_ctx_data {
/** Zephyr thread structure that hosts EC tasks */
struct k_thread zephyr_thread;
/** Zephyr thread id for above thread */
k_tid_t zephyr_tid;
- /** A wait-able event that is raised when a new task event is posted */
- struct k_poll_signal new_event;
- /** The current platform/ec events set for this task/thread */
- atomic_t event_mask;
- /**
- * The timer associated with this task, which can be set using
- * timer_arm().
- */
- struct k_timer timer;
+ /** Base context data */
+ struct task_ctx_base_data base;
};
#define CROS_EC_TASK(_name, _entry, _parameter, _size) \
@@ -74,7 +74,6 @@ struct task_ctx_data {
},
#define TASK_TEST(_name, _entry, _parameter, _size) \
CROS_EC_TASK(_name, _entry, _parameter, _size)
-/* Note: no static entry is required for sysworkq, as it isn't started here */
const static struct task_ctx_cfg shimmed_tasks_cfg[TASK_ID_COUNT] = {
CROS_EC_TASK_LIST
#ifdef TEST_BUILD
@@ -82,8 +81,13 @@ const static struct task_ctx_cfg shimmed_tasks_cfg[TASK_ID_COUNT] = {
#endif
};
-/* In tasks data, allocate one extra spot for the sysworkq */
-static struct task_ctx_data shimmed_tasks_data[TASK_ID_COUNT + 1];
+static struct task_ctx_data shimmed_tasks_data[TASK_ID_COUNT];
+static struct task_ctx_base_data sysworkq_task_data;
+/* Task timer structures, one extra for TASK_ID_SYSWORKQ. Keep separate from
+ * the context ones to avoid memory holes due to int64_t fields in struct
+ * _timeout.
+ */
+static struct k_timer shimmed_tasks_timers[TASK_ID_COUNT + 1];
#define TASK_ID_SYSWORKQ TASK_ID_COUNT
@@ -91,10 +95,22 @@ static int tasks_started;
#undef CROS_EC_TASK
#undef TASK_TEST
+static struct task_ctx_base_data *task_get_base_data(task_id_t cros_task_id)
+{
+ if (cros_task_id == TASK_ID_SYSWORKQ) {
+ return &sysworkq_task_data;
+ }
+
+ return &shimmed_tasks_data[cros_task_id].base;
+}
+
task_id_t task_get_current(void)
{
- /* Include sysworkq entry in search for the task ID */
- for (size_t i = 0; i < TASK_ID_COUNT + 1; ++i) {
+ if (in_deferred_context()) {
+ return TASK_ID_SYSWORKQ;
+ }
+
+ for (size_t i = 0; i < TASK_ID_COUNT; ++i) {
if (shimmed_tasks_data[i].zephyr_tid == k_current_get())
return i;
}
@@ -103,21 +119,20 @@ task_id_t task_get_current(void)
return 0;
}
-__test_only k_tid_t task_get_zephyr_tid(size_t cros_tid)
-{
- return shimmed_tasks_data[cros_tid].zephyr_tid;
-}
-
atomic_t *task_get_event_bitmap(task_id_t cros_task_id)
{
- struct task_ctx_data *const data = &shimmed_tasks_data[cros_task_id];
+ struct task_ctx_base_data *data;
+
+ data = task_get_base_data(cros_task_id);
return &data->event_mask;
}
uint32_t task_set_event(task_id_t cros_task_id, uint32_t event)
{
- struct task_ctx_data *const data = &shimmed_tasks_data[cros_task_id];
+ struct task_ctx_base_data *data;
+
+ data = task_get_base_data(cros_task_id);
atomic_or(&data->event_mask, event);
k_poll_signal_raise(&data->new_event, 0);
@@ -127,8 +142,10 @@ uint32_t task_set_event(task_id_t cros_task_id, uint32_t event)
uint32_t task_wait_event(int timeout_us)
{
- struct task_ctx_data *const data =
- &shimmed_tasks_data[task_get_current()];
+ struct task_ctx_base_data *data;
+
+ data = task_get_base_data(task_get_current());
+
const k_timeout_t timeout = (timeout_us == -1) ? K_FOREVER :
K_USEC(timeout_us);
const int64_t tick_deadline =
@@ -170,8 +187,10 @@ uint32_t task_wait_event(int timeout_us)
uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us)
{
- struct task_ctx_data *const data =
- &shimmed_tasks_data[task_get_current()];
+ struct task_ctx_base_data *data;
+
+ data = task_get_base_data(task_get_current());
+
uint32_t events = 0;
const int64_t tick_deadline =
k_uptime_ticks() + k_us_to_ticks_near64(timeout_us);
@@ -228,17 +247,17 @@ static void task_entry(void *task_context_cfg,
*/
static void timer_expire(struct k_timer *timer_id)
{
- struct task_ctx_data *const data =
- CONTAINER_OF(timer_id, struct task_ctx_data, timer);
- task_id_t cros_ec_task_id = data - shimmed_tasks_data;
+ task_id_t cros_ec_task_id = timer_id - shimmed_tasks_timers;
task_set_event(cros_ec_task_id, TASK_EVENT_TIMER);
}
int timer_arm(timestamp_t event, task_id_t cros_ec_task_id)
{
+ struct k_timer *timer;
timestamp_t now = get_time();
- struct task_ctx_data *const data = &shimmed_tasks_data[cros_ec_task_id];
+
+ timer = &shimmed_tasks_timers[cros_ec_task_id];
if (event.val <= now.val) {
/* Timer requested for now or in the past, fire right away */
@@ -247,18 +266,20 @@ int timer_arm(timestamp_t event, task_id_t cros_ec_task_id)
}
/* Check for a running timer */
- if (k_timer_remaining_get(&data->timer))
+ if (k_timer_remaining_get(timer))
return EC_ERROR_BUSY;
- k_timer_start(&data->timer, K_USEC(event.val - now.val), K_NO_WAIT);
+ k_timer_start(timer, K_USEC(event.val - now.val), K_NO_WAIT);
return EC_SUCCESS;
}
void timer_cancel(task_id_t cros_ec_task_id)
{
- struct task_ctx_data *const data = &shimmed_tasks_data[cros_ec_task_id];
+ struct k_timer *timer;
+
+ timer = &shimmed_tasks_timers[cros_ec_task_id];
- k_timer_stop(&data->timer);
+ k_timer_stop(timer);
}
#ifdef TEST_BUILD
@@ -288,13 +309,14 @@ void start_ec_tasks(void)
{
int priority;
- /* Initialize all EC tasks, which does not include the sysworkq entry */
+ for (size_t i = 0; i < TASK_ID_COUNT + 1; ++i) {
+ k_timer_init(&shimmed_tasks_timers[i], timer_expire, NULL);
+ }
+
for (size_t i = 0; i < TASK_ID_COUNT; ++i) {
struct task_ctx_data *const data = &shimmed_tasks_data[i];
const struct task_ctx_cfg *const cfg = &shimmed_tasks_cfg[i];
- k_timer_init(&data->timer, timer_expire, NULL);
-
priority = K_PRIO_PREEMPT(TASK_ID_COUNT - i - 1);
#ifdef TEST_BUILD
@@ -342,9 +364,6 @@ void start_ec_tasks(void)
#endif
}
- /* Create an entry for sysworkq we can send events to */
- shimmed_tasks_data[TASK_ID_COUNT].zephyr_tid = &k_sys_work_q.thread;
-
tasks_started = 1;
}
@@ -357,13 +376,14 @@ int init_signals(const struct device *unused)
{
ARG_UNUSED(unused);
- /* Initialize event structures for all entries, including sysworkq */
- for (size_t i = 0; i < TASK_ID_COUNT + 1; ++i) {
+ for (size_t i = 0; i < TASK_ID_COUNT; ++i) {
struct task_ctx_data *const data = &shimmed_tasks_data[i];
- k_poll_signal_init(&data->new_event);
+ k_poll_signal_init(&data->base.new_event);
}
+ k_poll_signal_init(&sysworkq_task_data.new_event);
+
return 0;
}
SYS_INIT(init_signals, POST_KERNEL, 50);
diff --git a/zephyr/shim/src/tcpc.c b/zephyr/shim/src/tcpc.c
index 98f631757c..82f53d70d9 100644
--- a/zephyr/shim/src/tcpc.c
+++ b/zephyr/shim/src/tcpc.c
@@ -11,14 +11,13 @@
#include "usbc/tcpc_it8xxx2.h"
#include "usbc/tcpc_ps8xxx.h"
#include "usbc/tcpci.h"
+#include "usbc/utils.h"
#if DT_HAS_COMPAT_STATUS_OKAY(FUSB302_TCPC_COMPAT) || \
DT_HAS_COMPAT_STATUS_OKAY(IT8XXX2_TCPC_COMPAT) || \
DT_HAS_COMPAT_STATUS_OKAY(PS8XXX_COMPAT) || \
DT_HAS_COMPAT_STATUS_OKAY(TCPCI_COMPAT) \
-#define USBC_PORT(id) DT_REG_ADDR(DT_PARENT(id))
-
#define TCPC_CONFIG(id, fn) [USBC_PORT(id)] = fn(id)
#define MAYBE_CONST COND_CODE_1(CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG, \
diff --git a/zephyr/subsys/ap_pwrseq/CMakeLists.txt b/zephyr/subsys/ap_pwrseq/CMakeLists.txt
index 2eba5ae67a..2cea0a992a 100644
--- a/zephyr/subsys/ap_pwrseq/CMakeLists.txt
+++ b/zephyr/subsys/ap_pwrseq/CMakeLists.txt
@@ -6,6 +6,7 @@ zephyr_library_sources(
)
zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ
ap_power_interface.c
+ power_host_sleep.c
power_signals.c
signal_gpio.c
signal_vw.c
diff --git a/zephyr/subsys/ap_pwrseq/Kconfig b/zephyr/subsys/ap_pwrseq/Kconfig
index 1de6d7251d..99ad4c819d 100644
--- a/zephyr/subsys/ap_pwrseq/Kconfig
+++ b/zephyr/subsys/ap_pwrseq/Kconfig
@@ -64,10 +64,19 @@ config X86_NON_DSX_PWRSEQ_CONSOLE
This option enables Non Deep Sleep Well power sequencing shell
console commands to debug.
+config AP_PWRSEQ_HOST_SLEEP
+ bool "Handle host sleep state changes"
+ help
+ Enable AP power sequencing to receive and process host command
+ host sleep state changes.
+
config AP_PWRSEQ_S0IX
- bool "Enable S0ix power state"
+ bool "Enable power state S0ix for Intel x86 chipset"
+ select AP_PWRSEQ_HOST_SLEEP
default n
help
- This option enables power state S0ix for Intel x86 chipset.
+ This option enables power state S0ix for Intel x86 chipset. As
+ required, AP_PWRSEQ_HOST_SLEEP for host sleep event handling is
+ enabled.
endif
diff --git a/zephyr/subsys/ap_pwrseq/include/ap_power_host_sleep.h b/zephyr/subsys/ap_pwrseq/include/ap_power_host_sleep.h
new file mode 100644
index 0000000000..d3cbc8c15f
--- /dev/null
+++ b/zephyr/subsys/ap_pwrseq/include/ap_power_host_sleep.h
@@ -0,0 +1,52 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __AP_POWER_HOST_SLEEP_H
+#define __AP_POWER_HOST_SLEEP_H
+
+#include <ap_power/ap_power_interface.h>
+#include <power_host_sleep.h>
+
+/*
+ * Deferred call to set active mask according to current power state
+ */
+void ap_power_set_active_wake_mask(void);
+
+/*
+ * Get lazy wake masks for the sleep state provided
+ *
+ * @param state Power state
+ * @param mask Lazy wake mask.
+ *
+ * @return 0 for success; -EINVAL if power state is not S3/S5/S0ix
+ */
+int ap_power_get_lazy_wake_mask(
+ enum power_states_ndsx state, host_event_t *mask);
+
+#if CONFIG_AP_PWRSEQ_S0IX
+/* For S0ix path, flag to notify sleep change */
+enum ap_power_sleep_type {
+ AP_POWER_SLEEP_NONE,
+ AP_POWER_SLEEP_SUSPEND,
+ AP_POWER_SLEEP_RESUME,
+};
+
+/*
+ * Reset host sleep state and clean up
+ */
+void ap_power_reset_host_sleep_state(void);
+
+/*
+ * Check if the sleep type current power transition indicates is the same
+ * as what is notified. If same, means host sleep event notified by AP
+ * through Host Command and SLP_S0 are consistent. Process
+ * the transition. Otherwise, no action.
+ *
+ * @param check_state Sleep type which is going to transit to.
+ */
+void ap_power_sleep_notify_transition(enum ap_power_sleep_type check_state);
+#endif /* CONFIG_AP_PWRSEQ_S0IX */
+
+#endif /* __AP_PWRSEQ_HOST_SLEEP_H */
diff --git a/zephyr/subsys/ap_pwrseq/include/power_signals.h b/zephyr/subsys/ap_pwrseq/include/power_signals.h
index cdeb9ec783..bc2d79bd1e 100644
--- a/zephyr/subsys/ap_pwrseq/include/power_signals.h
+++ b/zephyr/subsys/ap_pwrseq/include/power_signals.h
@@ -160,28 +160,36 @@ int power_signal_get(enum power_signal signal);
int power_signal_set(enum power_signal signal, int value);
/**
- * @brief Enable interrupts for this power signal
+ * @brief Enable this power signal
*
- * For signals that allow an interrupt to be used,
- * enable the interrupt.
+ * Enable this signal to be used as a power_signal.
+ * Typically this means the interrupt associated with this
+ * signal is enabled.
*
- * @param signal The power_signal to enable interrupts for.
+ * Power signals are enabled by default at startup, and if
+ * a power signal is disabled via power_signal_disable(), it will
+ * need to be re-enabled before the signal is included in the
+ * input handling again.
+ *
+ * @param signal The power_signal to enable.
* @return 0 is successful
- * @return negative If interrupt cannot be enabled.
+ * @return negative If unsuccessful
*/
-int power_signal_enable_interrupt(enum power_signal signal);
+int power_signal_enable(enum power_signal signal);
/**
- * @brief Disable interrupts for this power signal
+ * @brief Disable this power signal
*
- * For signals that allow an interrupt to be used,
- * disable the interrupt.
+ * Disable the signal so that it does not update the
+ * input handling (i.e does not call power_signal_interrupt() etc.)
+ * Once disabled, a signal must be re-enabled using
+ * power_signal_enable() to allow the signal to be used again.
*
- * @param signal The power_signal to disable interrupts for.
+ * @param signal The power_signal to disable.
* @return 0 is successful
- * @return negative If interrupt are not available on this signal.
+ * @return negative If unsuccessful
*/
-int power_signal_disable_interrupt(enum power_signal signal);
+int power_signal_disable(enum power_signal signal);
/**
* @brief Get the debug name associated with this signal.
@@ -202,7 +210,8 @@ void power_signal_init(void);
/**
* @brief Power signal interrupt handler
*
- * Called when an input signal causes an interrupt.
+ * Called when an input signal has changed.
+ * May be called from interrupt context.
*
* @param signal The power_signal that has changed.
* @param value The new value of the signal
diff --git a/zephyr/subsys/ap_pwrseq/include/signal_adc.h b/zephyr/subsys/ap_pwrseq/include/signal_adc.h
index 92570beef1..e43e73e1a7 100644
--- a/zephyr/subsys/ap_pwrseq/include/signal_adc.h
+++ b/zephyr/subsys/ap_pwrseq/include/signal_adc.h
@@ -41,6 +41,30 @@ DT_FOREACH_STATUS_OKAY(intel_ap_pwrseq_adc, PWR_ADC_ENUM)
int power_signal_adc_get(enum pwr_sig_adc adc);
/**
+ * @brief Enable the ADC signal.
+ *
+ * This will not only enable the interrupt driven update
+ * of this signal, but will also enable the ADC itself.
+ *
+ * @param signal The pwr_sig_adc to enable.
+ * @return 0 if successful
+ * @return -error if failed
+ */
+int power_signal_adc_enable(enum pwr_sig_adc adc);
+
+/**
+ * @brief Disable the ADC signal.
+ *
+ * This will disable the interrupt updating of this signal, and will
+ * also disable the ADC from running.
+ *
+ * @param signal The pwr_sig_adc to disable.
+ * @return 0 if successful
+ * @return -error if failed
+ */
+int power_signal_adc_disable(enum pwr_sig_adc adc);
+
+/**
* @brief Initialize the ADCs for the power signals.
*/
void power_signal_adc_init(void);
diff --git a/zephyr/subsys/ap_pwrseq/include/signal_gpio.h b/zephyr/subsys/ap_pwrseq/include/signal_gpio.h
index 04d45b8b1d..e797f0c21f 100644
--- a/zephyr/subsys/ap_pwrseq/include/signal_gpio.h
+++ b/zephyr/subsys/ap_pwrseq/include/signal_gpio.h
@@ -54,7 +54,7 @@ int power_signal_gpio_set(enum pwr_sig_gpio gpio, int value);
* @return 0 if successful
* @return -error if failed
*/
-int power_signal_gpio_enable_int(enum pwr_sig_gpio gpio);
+int power_signal_gpio_enable(enum pwr_sig_gpio gpio);
/**
* @brief Disable the GPIO interrupt
@@ -63,7 +63,7 @@ int power_signal_gpio_enable_int(enum pwr_sig_gpio gpio);
* @return 0 if successful
* @return -error if failed
*/
-int power_signal_gpio_disable_int(enum pwr_sig_gpio gpio);
+int power_signal_gpio_disable(enum pwr_sig_gpio gpio);
/**
* @brief Initialize the GPIOs for the power signals.
diff --git a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h
index b2ce4f74e1..cd7aa87b1d 100644
--- a/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h
+++ b/zephyr/subsys/ap_pwrseq/include/x86_non_dsx_common_pwrseq_sm_handler.h
@@ -9,9 +9,10 @@
#include <init.h>
#include <kernel.h>
#include <zephyr/types.h>
+
#include <ap_power/ap_power.h>
#include <ap_power/ap_power_events.h>
-
+#include <ap_power_host_sleep.h>
#include <x86_common_pwrseq.h>
#define DT_DRV_COMPAT intel_ap_pwrseq
@@ -24,7 +25,7 @@ void init_chipset_pwr_seq_state(void);
void request_exit_hardoff(bool should_exit);
enum power_states_ndsx pwr_sm_get_state(void);
void apshutdown(void);
-
+void ap_pwrseq_handle_chipset_reset(void);
extern const char pwrsm_dbg[][25];
#endif /* __X86_NON_DSX_COMMON_PWRSEQ_SM_HANDLER_H__ */
diff --git a/zephyr/subsys/ap_pwrseq/power_host_sleep.c b/zephyr/subsys/ap_pwrseq/power_host_sleep.c
new file mode 100644
index 0000000000..13e6aba765
--- /dev/null
+++ b/zephyr/subsys/ap_pwrseq/power_host_sleep.c
@@ -0,0 +1,231 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <ap_power/ap_power_interface.h>
+#include <x86_non_dsx_common_pwrseq_sm_handler.h>
+
+LOG_MODULE_DECLARE(ap_pwrseq, CONFIG_AP_PWRSEQ_LOG_LEVEL);
+
+#if CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI
+
+/* If host doesn't program S0ix lazy wake mask, use default S0ix mask */
+#define DEFAULT_WAKE_MASK_S0IX (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE))
+
+/*
+ * Set the wake mask according to the current power state:
+ * 1. On transition to S0, wake mask is reset.
+ * 2. In non-S0 states, active mask set by host gets a higher preference.
+ * 3. If host has not set any active mask, then check if a lazy mask exists
+ * for the current power state.
+ * 4. If state is S0ix and no lazy or active wake mask is set, then use default
+ * S0ix mask to be compatible with older BIOS versions.
+ */
+void power_update_wake_mask(void)
+{
+ host_event_t wake_mask;
+ enum power_states_ndsx state;
+
+ state = pwr_sm_get_state();
+
+ if (state == SYS_POWER_STATE_S0)
+ wake_mask = 0;
+ else if (lpc_is_active_wm_set_by_host() ||
+ ap_power_get_lazy_wake_mask(state, &wake_mask))
+ return;
+#if CONFIG_AP_PWRSEQ_S0IX
+ if ((state == SYS_POWER_STATE_S0ix) && (wake_mask == 0))
+ wake_mask = DEFAULT_WAKE_MASK_S0IX;
+#endif
+
+ lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, wake_mask);
+}
+
+static void power_update_wake_mask_deferred(struct k_work *work)
+{
+ power_update_wake_mask();
+}
+
+static K_WORK_DELAYABLE_DEFINE(
+ power_update_wake_mask_deferred_data, power_update_wake_mask_deferred);
+
+void ap_power_set_active_wake_mask(void)
+{
+ int rv;
+
+ /*
+ * Allow state machine to stabilize and update wake mask after 5msec. It
+ * was observed that on platforms where host wakes up periodically from
+ * S0ix for hardware book-keeping activities, there is a small window
+ * where host is not really up and running software, but still SLP_S0#
+ * is de-asserted and hence setting wake mask right away can cause user
+ * wake events to be missed.
+ *
+ * Time for deferred callback was chosen to be 5msec based on the fact
+ * that it takes ~2msec for the periodic wake cycle to complete on the
+ * host for KBL.
+ */
+ rv = k_work_schedule(&power_update_wake_mask_deferred_data, K_MSEC(5));
+ if (rv == 0) {
+ /*
+ * A work is already scheduled or submitted, since power state
+ * has changed again and the work is not processed, we should
+ * reschedule it.
+ */
+ rv = k_work_reschedule(
+ &power_update_wake_mask_deferred_data, K_MSEC(5));
+ }
+ __ASSERT(rv >= 0, "Set wake mask work queue error");
+}
+
+#else /* CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI */
+static void ap_power_set_active_wake_mask(void) { }
+#endif /* CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI */
+
+#if CONFIG_AP_PWRSEQ_S0IX
+/*
+ * Backup copies of SCI and SMI mask to preserve across S0ix suspend/resume
+ * cycle. If the host uses S0ix, BIOS is not involved during suspend and resume
+ * operations and hence SCI/SMI masks are programmed only once during boot-up.
+ *
+ * These backup variables are set whenever host expresses its interest to
+ * enter S0ix and then lpc_host_event_mask for SCI and SMI are cleared. When
+ * host resumes from S0ix, masks from backup variables are copied over to
+ * lpc_host_event_mask for SCI and SMI.
+ */
+static host_event_t backup_sci_mask;
+static host_event_t backup_smi_mask;
+
+/* Flag to notify listeners about suspend/resume events. */
+enum ap_power_sleep_type sleep_state = AP_POWER_SLEEP_NONE;
+
+/*
+ * Clear host event masks for SMI and SCI when host is entering S0ix. This is
+ * done to prevent any SCI/SMI interrupts when the host is in suspend. Since
+ * BIOS is not involved in the suspend path, EC needs to take care of clearing
+ * these masks.
+ */
+static void power_s0ix_suspend_clear_masks(void)
+{
+ backup_sci_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
+ backup_smi_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
+}
+
+/*
+ * Restore host event masks for SMI and SCI when host exits S0ix. This is done
+ * because BIOS is not involved in the resume path and so EC needs to restore
+ * the masks from backup variables.
+ */
+static void power_s0ix_resume_restore_masks(void)
+{
+ /*
+ * No need to restore SCI/SMI masks if both backup_sci_mask and
+ * backup_smi_mask are zero. This indicates that there was a failure to
+ * enter S0ix(SLP_S0# assertion) and hence SCI/SMI masks were never
+ * backed up.
+ */
+ if (!backup_sci_mask && !backup_smi_mask)
+ return;
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, backup_sci_mask);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, backup_smi_mask);
+ backup_sci_mask = backup_smi_mask = 0;
+}
+
+/*
+ * Following functions are called in the S0ix path, not S3 path.
+ */
+
+/*
+ * Notify the sleep type that is going to transit to; this is a token to
+ * ensure both host sleep event passed by Host Command and SLP_S0 satisfy
+ * the conditions to suspend or resume.
+ *
+ * @param new_state Notified sleep type
+ */
+static void ap_power_sleep_set_notify(enum ap_power_sleep_type new_state)
+{
+ sleep_state = new_state;
+}
+
+void ap_power_sleep_notify_transition(enum ap_power_sleep_type check_state)
+{
+ if (sleep_state != check_state)
+ return;
+
+ if (check_state == AP_POWER_SLEEP_SUSPEND) {
+ /*
+ * Transition to S0ix;
+ * clear mask before others running suspend.
+ */
+ power_s0ix_suspend_clear_masks();
+ ap_power_ev_send_callbacks(AP_POWER_SUSPEND);
+ } else if (check_state == AP_POWER_SLEEP_RESUME) {
+ ap_power_ev_send_callbacks(AP_POWER_RESUME);
+ }
+
+ /* Transition is done; reset sleep state. */
+ ap_power_sleep_set_notify(AP_POWER_SLEEP_NONE);
+}
+#endif /* CONFIG_AP_PWRSEQ_S0IX */
+
+#if CONFIG_AP_PWRSEQ_HOST_SLEEP
+#define HOST_SLEEP_EVENT_DEFAULT_RESET 0
+
+void ap_power_reset_host_sleep_state(void)
+{
+ power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET);
+ ap_power_chipset_handle_host_sleep_event(
+ HOST_SLEEP_EVENT_DEFAULT_RESET, NULL);
+}
+
+/* TODO: hook to reset event */
+void ap_power_handle_chipset_reset(void)
+{
+ if (ap_power_in_state(AP_POWER_STATE_STANDBY))
+ ap_power_reset_host_sleep_state();
+}
+
+void ap_power_chipset_handle_host_sleep_event(
+ enum host_sleep_event state,
+ struct host_sleep_event_context *ctx)
+{
+ LOG_DBG("host sleep event = %d!", state);
+#if CONFIG_AP_PWRSEQ_S0IX
+ if (state == HOST_SLEEP_EVENT_S0IX_SUSPEND) {
+
+ /*
+ * Indicate to power state machine that a new host event for
+ * s0ix/s3 suspend has been received and so chipset suspend
+ * notification needs to be sent to listeners.
+ */
+ ap_power_sleep_set_notify(AP_POWER_SLEEP_SUSPEND);
+ power_signal_enable_interrupt(PWR_SLP_S0);
+
+ } else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) {
+ /*
+ * Set sleep state to resume; restore SCI/SMI masks;
+ * SLP_S0 should be de-asserted already, disable interrupt.
+ */
+ ap_power_sleep_set_notify(AP_POWER_SLEEP_RESUME);
+ power_s0ix_resume_restore_masks();
+ power_signal_disable_interrupt(PWR_SLP_S0);
+
+ /*
+ * If the sleep signal timed out and never transitioned, then
+ * the wake mask was modified to its suspend state (S0ix), so
+ * that the event wakes the system. Explicitly restore the wake
+ * mask to its S0 state now.
+ */
+ power_update_wake_mask();
+
+ } else if (state == HOST_SLEEP_EVENT_DEFAULT_RESET) {
+ power_signal_disable_interrupt(PWR_SLP_S0);
+ }
+#endif /* CONFIG_AP_PWRSEQ_S0IX */
+}
+
+#endif /* CONFIG_AP_PWRSEQ_HOST_SLEEP */
diff --git a/zephyr/subsys/ap_pwrseq/power_signals.c b/zephyr/subsys/ap_pwrseq/power_signals.c
index e6bdb05954..c463e8e82e 100644
--- a/zephyr/subsys/ap_pwrseq/power_signals.c
+++ b/zephyr/subsys/ap_pwrseq/power_signals.c
@@ -226,7 +226,7 @@ int power_signal_set(enum power_signal signal, int value)
return ret;
}
-int power_signal_enable_interrupt(enum power_signal signal)
+int power_signal_enable(enum power_signal signal)
{
const struct ps_config *cp;
@@ -244,12 +244,16 @@ int power_signal_enable_interrupt(enum power_signal signal)
#if HAS_GPIO_SIGNALS
case PWR_SIG_SRC_GPIO:
- return power_signal_gpio_enable_int(cp->src_enum);
+ return power_signal_gpio_enable(cp->src_enum);
+#endif
+#if HAS_ADC_SIGNALS
+ case PWR_SIG_SRC_ADC:
+ return power_signal_adc_enable(cp->src_enum);
#endif
}
}
-int power_signal_disable_interrupt(enum power_signal signal)
+int power_signal_disable(enum power_signal signal)
{
const struct ps_config *cp;
@@ -263,7 +267,11 @@ int power_signal_disable_interrupt(enum power_signal signal)
#if HAS_GPIO_SIGNALS
case PWR_SIG_SRC_GPIO:
- return power_signal_gpio_disable_int(cp->src_enum);
+ return power_signal_gpio_disable(cp->src_enum);
+#endif
+#if HAS_ADC_SIGNALS
+ case PWR_SIG_SRC_ADC:
+ return power_signal_adc_disable(cp->src_enum);
#endif
}
}
diff --git a/zephyr/subsys/ap_pwrseq/signal_adc.c b/zephyr/subsys/ap_pwrseq/signal_adc.c
index 9f07b73964..9898c8e4bd 100644
--- a/zephyr/subsys/ap_pwrseq/signal_adc.c
+++ b/zephyr/subsys/ap_pwrseq/signal_adc.c
@@ -33,42 +33,70 @@ static const struct adc_config config[] = {
DT_FOREACH_STATUS_OKAY(MY_COMPAT, INIT_ADC_CONFIG)
};
-static atomic_t value[ARRAY_SIZE(config)];
+/*
+ * Bit allocations for atomic state
+ */
+enum {
+ ADC_BIT_VALUE = 0,
+ ADC_BIT_LOW_ENABLED = 1,
+ ADC_BIT_HIGH_ENABLED = 2
+};
+
+atomic_t adc_state[ARRAY_SIZE(config)];
+
+static void set_trigger(const struct device *dev,
+ atomic_t *state,
+ int bit,
+ bool enable)
+{
+ /*
+ * Only enable or disable if the trigger is not
+ * already enabled or disabled.
+ */
+ if (enable
+ ? !atomic_test_and_set_bit(state, bit)
+ : atomic_test_and_clear_bit(state, bit)) {
+ struct sensor_value val;
+
+ val.val1 = enable;
+ sensor_attr_set(dev,
+ SENSOR_CHAN_VOLTAGE,
+ SENSOR_ATTR_ALERT,
+ &val);
+ }
+}
+
+static void set_low_trigger(enum pwr_sig_adc adc, bool enable)
+{
+ set_trigger(config[adc].dev_trig_low,
+ &adc_state[adc],
+ ADC_BIT_LOW_ENABLED,
+ enable);
+
+}
+
+static void set_high_trigger(enum pwr_sig_adc adc, bool enable)
+{
+ set_trigger(config[adc].dev_trig_high,
+ &adc_state[adc],
+ ADC_BIT_HIGH_ENABLED,
+ enable);
+}
static void trigger_high(enum pwr_sig_adc adc)
{
- struct sensor_value val;
-
- atomic_set_bit(&value[adc], 0);
- val.val1 = false;
- sensor_attr_set(config[adc].dev_trig_high,
- SENSOR_CHAN_VOLTAGE,
- SENSOR_ATTR_ALERT,
- &val);
- val.val1 = true;
- sensor_attr_set(config[adc].dev_trig_low,
- SENSOR_CHAN_VOLTAGE,
- SENSOR_ATTR_ALERT,
- &val);
+ atomic_set_bit(&adc_state[adc], ADC_BIT_VALUE);
+ set_low_trigger(adc, true);
+ set_high_trigger(adc, false);
LOG_DBG("power signal adc%d is HIGH", adc);
power_signal_interrupt(config[adc].signal, 1);
}
static void trigger_low(enum pwr_sig_adc adc)
{
- struct sensor_value val;
-
- atomic_clear_bit(&value[adc], 0);
- val.val1 = false;
- sensor_attr_set(config[adc].dev_trig_low,
- SENSOR_CHAN_VOLTAGE,
- SENSOR_ATTR_ALERT,
- &val);
- val.val1 = true;
- sensor_attr_set(config[adc].dev_trig_high,
- SENSOR_CHAN_VOLTAGE,
- SENSOR_ATTR_ALERT,
- &val);
+ atomic_clear_bit(&adc_state[adc], ADC_BIT_VALUE);
+ set_low_trigger(adc, false);
+ set_high_trigger(adc, true);
LOG_DBG("power signal adc%d is LOW", adc);
power_signal_interrupt(config[adc].signal, 0);
}
@@ -78,7 +106,32 @@ int power_signal_adc_get(enum pwr_sig_adc adc)
if (adc < 0 || adc >= ARRAY_SIZE(config)) {
return -EINVAL;
}
- return !!value[adc];
+ return atomic_test_bit(&adc_state[adc], ADC_BIT_VALUE);
+}
+
+int power_signal_adc_enable(enum pwr_sig_adc adc)
+{
+ if (adc < 0 || adc >= ARRAY_SIZE(config)) {
+ return -EINVAL;
+ }
+
+ /* Only need to enable relevant trigger depending on current state */
+ if (atomic_test_bit(&adc_state[adc], ADC_BIT_VALUE)) {
+ set_low_trigger(adc, true);
+ } else {
+ set_high_trigger(adc, true);
+ }
+ return 0;
+}
+
+int power_signal_adc_disable(enum pwr_sig_adc adc)
+{
+ if (adc < 0 || adc >= ARRAY_SIZE(config)) {
+ return -EINVAL;
+ }
+ set_low_trigger(adc, false);
+ set_high_trigger(adc, false);
+ return 0;
}
/*
@@ -110,7 +163,6 @@ void power_signal_adc_init(void)
.type = SENSOR_TRIG_THRESHOLD,
.chan = SENSOR_CHAN_VOLTAGE
};
- struct sensor_value val;
sensor_trigger_handler_t low_cb[] = {
DT_FOREACH_STATUS_OKAY_VARGS(MY_COMPAT, ADC_CB_COMMA, low)
};
@@ -123,13 +175,7 @@ void power_signal_adc_init(void)
/* Set high and low trigger callbacks */
sensor_trigger_set(config[i].dev_trig_high, &trig, high_cb[i]);
sensor_trigger_set(config[i].dev_trig_low, &trig, low_cb[i]);
-
- /* Enable high trigger callback only */
- val.val1 = true;
- sensor_attr_set(config[i].dev_trig_high,
- SENSOR_CHAN_VOLTAGE,
- SENSOR_ATTR_ALERT,
- &val);
+ power_signal_adc_enable(i);
}
}
diff --git a/zephyr/subsys/ap_pwrseq/signal_gpio.c b/zephyr/subsys/ap_pwrseq/signal_gpio.c
index 3e940bacfd..b4888f8cff 100644
--- a/zephyr/subsys/ap_pwrseq/signal_gpio.c
+++ b/zephyr/subsys/ap_pwrseq/signal_gpio.c
@@ -43,7 +43,7 @@ DT_FOREACH_STATUS_OKAY(MY_COMPAT, INIT_GPIO_CONFIG)
static struct gpio_callback int_cb[ARRAY_SIZE(gpio_config)];
-int power_signal_gpio_enable_int(enum pwr_sig_gpio index)
+int power_signal_gpio_enable(enum pwr_sig_gpio index)
{
gpio_flags_t flags;
@@ -65,7 +65,7 @@ int power_signal_gpio_enable_int(enum pwr_sig_gpio index)
return -EINVAL;
}
-int power_signal_gpio_disable_int(enum pwr_sig_gpio index)
+int power_signal_gpio_disable(enum pwr_sig_gpio index)
{
gpio_flags_t flags;
@@ -141,7 +141,7 @@ void power_signal_gpio_init(void)
* startup, enable the interrupt.
*/
if (!gpio_config[i].no_enable) {
- power_signal_gpio_enable_int(i);
+ power_signal_gpio_enable(i);
}
}
}
diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c
index 648b46807b..34c3d5df18 100644
--- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c
+++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_common_pwrseq_sm_handler.c
@@ -4,6 +4,7 @@
*/
#include <init.h>
+
#include <x86_non_dsx_common_pwrseq_sm_handler.h>
static K_KERNEL_STACK_DEFINE(pwrseq_thread_stack,
@@ -261,11 +262,13 @@ static int common_pwr_sm_run(int state)
/* Notify power event that rails are up */
ap_power_ev_send_callbacks(AP_POWER_STARTUP);
- /* TODO: S0ix
+#if CONFIG_AP_PWRSEQ_S0IX
+ /*
* Clearing the S0ix flag on the path to S0
* to handle any reset conditions.
*/
-
+ ap_power_reset_host_sleep_state();
+#endif
return SYS_POWER_STATE_S3;
case SYS_POWER_STATE_S3:
@@ -289,7 +292,7 @@ static int common_pwr_sm_run(int state)
/* All the power rails must be stable */
if (power_signal_get(PWR_ALL_SYS_PWRGD)) {
-#if defined(CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK)
+#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
/* Notify power event before resume */
ap_power_ev_send_callbacks(AP_POWER_RESUME_INIT);
#endif
@@ -299,13 +302,82 @@ static int common_pwr_sm_run(int state)
}
break;
+#if CONFIG_AP_PWRSEQ_S0IX
+ case SYS_POWER_STATE_S0ix:
+ /* System in S0 only if SLP_S0 and SLP_S3 are de-asserted */
+ if (power_signals_off(IN_PCH_SLP_S0) &&
+ signals_valid_and_off(IN_PCH_SLP_S3)) {
+ /* TODO: Make sure ap reset handling is done
+ * before leaving S0ix.
+ */
+ return SYS_POWER_STATE_S0ixS0;
+ } else if (!power_signals_on(IN_PGOOD_ALL_CORE))
+ return SYS_POWER_STATE_S0;
+
+ break;
+
+ case SYS_POWER_STATE_S0S0ix:
+ /*
+ * Check sleep state and notify listeners of S0ix suspend if
+ * HC already set sleep suspend state.
+ */
+ ap_power_sleep_notify_transition(AP_POWER_SLEEP_SUSPEND);
+
+ /*
+ * Enable idle task deep sleep. Allow the low power idle task
+ * to go into deep sleep in S0ix.
+ */
+ enable_sleep(SLEEP_MASK_AP_RUN);
+
+#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
+ ap_power_ev_send_callbacks(AP_POWER_SUSPEND_COMPLETE);
+#endif
+
+ return SYS_POWER_STATE_S0ix;
+
+ case SYS_POWER_STATE_S0ixS0:
+ if (power_get_host_sleep_state() !=
+ HOST_SLEEP_EVENT_S0IX_RESUME)
+ break;
+
+ /*
+ * Disable idle task deep sleep. This means that the low
+ * power idle task will not go into deep sleep while in S0.
+ */
+ disable_sleep(SLEEP_MASK_AP_RUN);
+
+#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
+ ap_power_ev_send_callbacks(AP_POWER_RESUME_INIT);
+#endif
+
+ return SYS_POWER_STATE_S0;
+
+#endif /* CONFIG_AP_PWRSEQ_S0IX */
+
case SYS_POWER_STATE_S0:
if (!power_signals_on(IN_PGOOD_ALL_CORE)) {
ap_power_force_shutdown(AP_POWER_SHUTDOWN_POWERFAIL);
return SYS_POWER_STATE_G3;
- } else if (signals_valid_and_on(IN_PCH_SLP_S3))
+ } else if (signals_valid_and_on(IN_PCH_SLP_S3)) {
return SYS_POWER_STATE_S0S3;
- /* TODO: S0ix */
+
+#if CONFIG_AP_PWRSEQ_S0IX
+ /*
+ * SLP_S0 may assert in system idle scenario without a kernel
+ * freeze call. This may cause interrupt storm since there is
+ * no freeze/unfreeze of threads/process in the idle scenario.
+ * Ignore the SLP_S0 assertions in idle scenario by checking
+ * the host sleep state.
+ */
+ } else if (power_get_host_sleep_state()
+ == HOST_SLEEP_EVENT_S0IX_SUSPEND &&
+ power_signals_on(IN_PCH_SLP_S0)) {
+
+ return SYS_POWER_STATE_S0S0ix;
+ } else {
+ ap_power_sleep_notify_transition(AP_POWER_SLEEP_RESUME);
+#endif /* CONFIG_AP_PWRSEQ_S0IX */
+ }
break;
@@ -325,6 +397,9 @@ static int common_pwr_sm_run(int state)
* correctly handle global resets which have a bit of delay
* while the SLP_Sx_L signals are asserted then deasserted.
*/
+ /* TODO */
+ /* power_s5_up = 0; */
+
return SYS_POWER_STATE_S5;
case SYS_POWER_STATE_S3S4:
@@ -333,10 +408,22 @@ static int common_pwr_sm_run(int state)
case SYS_POWER_STATE_S0S3:
/* Notify power event before we remove power rails */
ap_power_ev_send_callbacks(AP_POWER_SUSPEND);
-#if defined(CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK)
+#if CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
/* Notify power event after suspend */
ap_power_ev_send_callbacks(AP_POWER_SUSPEND_COMPLETE);
#endif
+
+ /*
+ * Enable idle task deep sleep. Allow the low power idle task
+ * to go into deep sleep in S3 or lower.
+ */
+ enable_sleep(SLEEP_MASK_AP_RUN);
+
+#if CONFIG_AP_PWRSEQ_S0IX
+ /* Re-initialize S0ix flag */
+ ap_power_reset_host_sleep_state();
+#endif
+
return SYS_POWER_STATE_S3;
default:
@@ -386,8 +473,10 @@ static void pwrseq_loop_thread(void *p1, void *p2, void *p3)
if (curr_state == new_state)
new_state = common_pwr_sm_run(curr_state);
- if (curr_state != new_state)
+ if (curr_state != new_state) {
pwr_sm_set_state(new_state);
+ ap_power_set_active_wake_mask();
+ }
k_msleep(t_wait_ms);
}
diff --git a/zephyr/test/.pylintrc b/zephyr/test/.pylintrc
new file mode 100644
index 0000000000..9ca0b5f8c9
--- /dev/null
+++ b/zephyr/test/.pylintrc
@@ -0,0 +1,21 @@
+[MASTER]
+init-hook='import sys; sys.path.append("/usr/lib64/python3.6/site-packages")'
+
+[MESSAGES CONTROL]
+
+disable=bad-continuation,bad-whitespace,format,fixme
+
+[format]
+
+max-line-length=88
+string-quote=double
+
+[BASIC]
+additional-builtins=
+ here,
+ register_binman_project,
+ register_host_project,
+ register_host_test,
+ register_npcx_project,
+ register_raw_project,
+good-names=BUILD
diff --git a/zephyr/test/accel_cal/BUILD.py b/zephyr/test/accel_cal/BUILD.py
index bb50fd4301..8c743bf48b 100644
--- a/zephyr/test/accel_cal/BUILD.py
+++ b/zephyr/test/accel_cal/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for accel_cal test."""
+
register_host_test("accel_cal")
diff --git a/zephyr/test/ap_power/BUILD.py b/zephyr/test/ap_power/BUILD.py
index f511b313ef..e3dac8c77e 100644
--- a/zephyr/test/ap_power/BUILD.py
+++ b/zephyr/test/ap_power/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for ap_power test."""
+
register_host_test("ap_power", dts_overlays=["overlay.dts"])
diff --git a/zephyr/test/ap_power/prj.conf b/zephyr/test/ap_power/prj.conf
index 0cc677e3e7..86c3f5082d 100644
--- a/zephyr/test/ap_power/prj.conf
+++ b/zephyr/test/ap_power/prj.conf
@@ -45,6 +45,7 @@ CONFIG_X86_NON_DSX_PWRSEQ_ADL=y
CONFIG_AP_X86_INTEL_ADL=y
CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4=y
CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5=y
+CONFIG_AP_PWRSEQ_STACK_SIZE=1024
CONFIG_ESPI=y
CONFIG_ESPI_EMUL=y
diff --git a/zephyr/test/ap_power/src/signals.c b/zephyr/test/ap_power/src/signals.c
index 432b28042b..debd459807 100644
--- a/zephyr/test/ap_power/src/signals.c
+++ b/zephyr/test/ap_power/src/signals.c
@@ -97,26 +97,26 @@ ZTEST(signals, test_validate_request)
zassert_equal(-EINVAL, power_signal_set(PWR_SLP_S0, 1),
"power_signal_set on input pin should not succeed");
/* Can't enable interrupt on output */
- zassert_equal(-EINVAL, power_signal_enable_interrupt(PWR_VCCST_PWRGD),
+ zassert_equal(-EINVAL, power_signal_enable(PWR_VCCST_PWRGD),
"enable interrupt on output pin should not succeed");
/* Can't disable interrupt on output */
- zassert_equal(-EINVAL, power_signal_disable_interrupt(PWR_VCCST_PWRGD),
+ zassert_equal(-EINVAL, power_signal_disable(PWR_VCCST_PWRGD),
"disable interrupt on output pin should not succeed");
/* Can't enable interrupt on input with no interrupt flags */
- zassert_equal(-EINVAL, power_signal_enable_interrupt(PWR_IMVP9_VRRDY),
+ zassert_equal(-EINVAL, power_signal_enable(PWR_IMVP9_VRRDY),
"enable interrupt on input pin without interrupt config");
/* Can't disable interrupt on input with no interrupt flags */
zassert_equal(-EINVAL,
- power_signal_disable_interrupt(PWR_IMVP9_VRRDY),
+ power_signal_disable(PWR_IMVP9_VRRDY),
"disable interrupt on input pin without interrupt config");
/* Invalid signal - should be rejectde */
zassert_equal(-EINVAL, power_signal_get(-1),
"power_signal_get with -1 signal should fail");
zassert_equal(-EINVAL, power_signal_set(-1, 1),
"power_signal_set with -1 signal should fail");
- zassert_equal(-EINVAL, power_signal_enable_interrupt(-1),
+ zassert_equal(-EINVAL, power_signal_enable(-1),
"enable interrupt with -1 signal should fail");
- zassert_equal(-EINVAL, power_signal_disable_interrupt(-1),
+ zassert_equal(-EINVAL, power_signal_disable(-1),
"disable interrupt with -1 signal should fail");
}
@@ -359,7 +359,7 @@ ZTEST(signals, test_gpio_interrupts)
zassert_equal(false, power_signals_on(s0),
"SLP_S0 should not have updated");
- power_signal_enable_interrupt(PWR_SLP_S0);
+ power_signal_enable(PWR_SLP_S0);
emul_set(PWR_SLP_S0, 0);
zassert_equal(true, power_signals_on(s0),
"SLP_S0 should have updated the mask");
@@ -370,7 +370,7 @@ ZTEST(signals, test_gpio_interrupts)
/*
* Disable the GPIO interrupt again.
*/
- power_signal_disable_interrupt(PWR_SLP_S0);
+ power_signal_disable(PWR_SLP_S0);
emul_set(PWR_SLP_S0, 0);
zassert_equal(false, power_signals_on(s0),
"SLP_S0 should not have updated the mask");
diff --git a/zephyr/test/base32/BUILD.py b/zephyr/test/base32/BUILD.py
index 67e7c50089..28023ccdc9 100644
--- a/zephyr/test/base32/BUILD.py
+++ b/zephyr/test/base32/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for base32 test."""
+
register_host_test("base32")
diff --git a/zephyr/test/crc/BUILD.py b/zephyr/test/crc/BUILD.py
index 17136be0ce..8ca9c04936 100644
--- a/zephyr/test/crc/BUILD.py
+++ b/zephyr/test/crc/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for crc test."""
+
register_host_test("crc")
diff --git a/zephyr/test/drivers/BUILD.py b/zephyr/test/drivers/BUILD.py
index 1653103526..04449e2f8e 100644
--- a/zephyr/test/drivers/BUILD.py
+++ b/zephyr/test/drivers/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for drivers test."""
+
register_host_test("drivers", dts_overlays=["overlay.dts"])
diff --git a/zephyr/test/drivers/include/test/drivers/utils.h b/zephyr/test/drivers/include/test/drivers/utils.h
index 6d5d0c33bf..c8258af6f7 100644
--- a/zephyr/test/drivers/include/test/drivers/utils.h
+++ b/zephyr/test/drivers/include/test/drivers/utils.h
@@ -227,6 +227,42 @@ void host_cmd_motion_sense_dump(int max_sensor_count,
struct ec_response_motion_sense *response);
/**
+ * @brief Call the host command MOTION_SENSE with the data sub-command
+ *
+ * @param sensor_num The sensor index in the motion_sensors array to query
+ * @param response Pointer to the response data structure to fill on success
+ * @return The result code from the host command
+ */
+int host_cmd_motion_sense_data(uint8_t sensor_num,
+ struct ec_response_motion_sense *response);
+
+/**
+ * @brief Call the host command MOTION_SENSE with the info sub-command
+ *
+ * @param cmd_version The command version
+ * @param sensor_num The sensor index in the motion_sensors array to query
+ * @param response Pointer to the response data structure to fill on success
+ * @return The result code from the host command
+ */
+int host_cmd_motion_sense_info(uint8_t cmd_version, uint8_t sensor_num,
+ struct ec_response_motion_sense *response);
+
+/**
+ * @brief Call the host command MOTION_SENSE with the ec_rate sub-command
+ *
+ * This function performs a read of the current rate by passing
+ * EC_MOTION_SENSE_NO_VALUE as the data rate. Otherwise, the data rate should be
+ * updated.
+ *
+ * @param sensor_num The sensor index in the motion_sensors array to query
+ * @param data_rate_ms The new data rate or EC_MOTION_SENSE_NO_VALUE to read
+ * @param response Pointer to the response data structure to fill on success
+ * @return The result code from the host command
+ */
+int host_cmd_motion_sense_ec_rate(uint8_t sensor_num, int data_rate_ms,
+ struct ec_response_motion_sense *response);
+
+/**
* Run the host command to get the PD discovery responses.
*
* @param port The USB-C port number
diff --git a/zephyr/test/drivers/src/host_cmd/motion_sense.c b/zephyr/test/drivers/src/host_cmd/motion_sense.c
index 3e4c8e0336..4063007401 100644
--- a/zephyr/test/drivers/src/host_cmd/motion_sense.c
+++ b/zephyr/test/drivers/src/host_cmd/motion_sense.c
@@ -16,8 +16,13 @@
(sizeof(struct ec_response_motion_sense) + \
n * sizeof(struct ec_response_motion_sensor_data))
-ZTEST_SUITE(host_cmd_motion_sense, drivers_predicate_post_main, NULL, NULL,
- NULL, NULL);
+static void host_cmd_motion_sense_before(void *state)
+{
+ motion_sensors[0].config[SENSOR_CONFIG_AP].ec_rate = 1000 * MSEC;
+}
+
+ZTEST_SUITE(host_cmd_motion_sense, drivers_predicate_post_main, NULL,
+ host_cmd_motion_sense_before, NULL, NULL);
ZTEST_USER(host_cmd_motion_sense, test_dump)
{
@@ -64,3 +69,124 @@ ZTEST_USER(host_cmd_motion_sense, test_dump__large_max_sensor_count)
zassert_equal(result->dump.sensor_count, ALL_MOTION_SENSORS, NULL);
}
+
+ZTEST_USER(host_cmd_motion_sense, test_read_data__invalid_sensor_num)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_equal(host_cmd_motion_sense_data(UINT8_MAX, &response),
+ EC_RES_INVALID_PARAM, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_read_data)
+{
+ struct ec_response_motion_sense response;
+
+ motion_sensors[0].xyz[0] = 1;
+ motion_sensors[0].xyz[1] = 2;
+ motion_sensors[0].xyz[2] = 3;
+
+ zassert_ok(host_cmd_motion_sense_data(0, &response), NULL);
+ zassert_equal(response.data.flags, 0, NULL);
+ zassert_equal(response.data.data[0], 1, NULL);
+ zassert_equal(response.data.data[1], 2, NULL);
+ zassert_equal(response.data.data[2], 3, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_info__invalid_sensor_num)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_equal(host_cmd_motion_sense_info(/*cmd_version=*/1,
+ /*sensor_num=*/UINT8_MAX,
+ &response),
+ EC_RES_INVALID_PARAM, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_info_v1)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_ok(host_cmd_motion_sense_info(/*cmd_version=*/1,
+ /*sensor_num=*/0, &response),
+ NULL);
+ zassert_equal(response.info.type, motion_sensors[0].type, NULL);
+ zassert_equal(response.info.location, motion_sensors[0].location, NULL);
+ zassert_equal(response.info.chip, motion_sensors[0].chip, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_info_v3)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_ok(host_cmd_motion_sense_info(/*cmd_version=*/3,
+ /*sensor_num=*/0, &response),
+ NULL);
+ zassert_equal(response.info.type, motion_sensors[0].type, NULL);
+ zassert_equal(response.info.location, motion_sensors[0].location, NULL);
+ zassert_equal(response.info.chip, motion_sensors[0].chip, NULL);
+ zassert_equal(response.info_3.min_frequency,
+ motion_sensors[0].min_frequency, NULL);
+ zassert_equal(response.info_3.max_frequency,
+ motion_sensors[0].max_frequency, NULL);
+ zassert_equal(response.info_3.fifo_max_event_count,
+ CONFIG_ACCEL_FIFO_SIZE, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_info_v4__no_read_temp)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_ok(host_cmd_motion_sense_info(/*cmd_version=*/4,
+ /*sensor_num=*/0, &response),
+ NULL);
+ zassert_equal(response.info.type, motion_sensors[0].type, NULL);
+ zassert_equal(response.info.location, motion_sensors[0].location, NULL);
+ zassert_equal(response.info.chip, motion_sensors[0].chip, NULL);
+ if (IS_ENABLED(CONFIG_ONLINE_CALIB)) {
+ zassert_true(response.info_4.flags &
+ MOTION_SENSE_CMD_INFO_FLAG_ONLINE_CALIB,
+ NULL);
+ } else {
+ zassert_false(response.info_4.flags &
+ MOTION_SENSE_CMD_INFO_FLAG_ONLINE_CALIB,
+ NULL);
+ }
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_ec_rate__invalid_sensor_num)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_equal(host_cmd_motion_sense_ec_rate(
+ /*sensor_num=*/0xff,
+ /*data_rate_ms=*/EC_MOTION_SENSE_NO_VALUE,
+ &response),
+ EC_RES_INVALID_PARAM, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_get_ec_rate)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_ok(host_cmd_motion_sense_ec_rate(
+ /*sensor_num=*/0,
+ /*data_rate_ms=*/EC_MOTION_SENSE_NO_VALUE,
+ &response),
+ NULL);
+ zassert_equal(response.ec_rate.ret, 1000, NULL);
+}
+
+ZTEST_USER(host_cmd_motion_sense, test_set_ec_rate)
+{
+ struct ec_response_motion_sense response;
+
+ zassert_ok(host_cmd_motion_sense_ec_rate(
+ /*sensor_num=*/0, /*data_rate_ms=*/2000, &response),
+ NULL);
+ /* The command should return the previous rate */
+ zassert_equal(response.ec_rate.ret, 1000, NULL);
+ /* The sensor's AP config value should be updated */
+ zassert_equal(motion_sensors[0].config[SENSOR_CONFIG_AP].ec_rate,
+ 2000 * MSEC, NULL);
+}
diff --git a/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c b/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c
index 9541f20dd3..9a4df7d11e 100644
--- a/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c
+++ b/zephyr/test/drivers/src/integration/usbc/usb_5v_3a_pd_sink.c
@@ -34,7 +34,10 @@ connect_sink_to_port(struct usb_attach_5v_3a_pd_sink_fixture *fixture)
TCPC_REG_POWER_STATUS_VBUS_DET);
tcpci_emul_set_reg(fixture->tcpci_emul, TCPC_REG_EXT_STATUS,
TCPC_REG_EXT_STATUS_SAFE0V);
+
tcpci_tcpc_alert(0);
+ k_sleep(K_SECONDS(1));
+
zassume_ok(tcpci_snk_emul_connect_to_tcpci(
&fixture->sink_5v_3a.data,
&fixture->sink_5v_3a.common_data,
diff --git a/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c b/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c
index 4ed9dcb8d1..54598c4685 100644
--- a/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c
+++ b/zephyr/test/drivers/src/integration/usbc/usb_attach_src_snk.c
@@ -769,13 +769,13 @@ ZTEST_F(usb_detach_test, verify_detach_sink)
ZTEST_F(usb_detach_test, verify_detach_source)
{
struct emul_state *fixture = &this->fixture;
- struct ec_response_usb_pd_power_info pd_power_info = { 0 };
+ struct ec_response_usb_pd_power_info pd_power_info = { SNK_PORT };
integration_usb_test_source_detach(fixture);
k_sleep(K_SECONDS(10));
isl923x_emul_set_adc_vbus(fixture->charger_isl923x_emul, 0);
- pd_power_info = host_cmd_power_info(SRC_PORT);
+ pd_power_info = host_cmd_power_info(SNK_PORT);
/* Assert */
zassert_equal(pd_power_info.role, USB_PD_PORT_POWER_DISCONNECTED,
diff --git a/zephyr/test/drivers/src/utils.c b/zephyr/test/drivers/src/utils.c
index ef2084ab07..a639b63d17 100644
--- a/zephyr/test/drivers/src/utils.c
+++ b/zephyr/test/drivers/src/utils.c
@@ -112,6 +112,53 @@ void host_cmd_motion_sense_dump(int max_sensor_count,
"Failed to get motion_sense dump");
}
+int host_cmd_motion_sense_data(uint8_t sensor_num,
+ struct ec_response_motion_sense *response)
+{
+ struct ec_params_motion_sense params = {
+ .cmd = MOTIONSENSE_CMD_DATA,
+ .sensor_odr = {
+ .sensor_num = sensor_num,
+ },
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_MOTION_SENSE_CMD, 4, *response, params);
+
+ return host_command_process(&args);
+}
+
+int host_cmd_motion_sense_info(uint8_t cmd_version, uint8_t sensor_num,
+ struct ec_response_motion_sense *response)
+{
+ struct ec_params_motion_sense params = {
+ .cmd = MOTIONSENSE_CMD_INFO,
+ .sensor_odr = {
+ .sensor_num = sensor_num,
+ },
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_MOTION_SENSE_CMD, cmd_version, *response, params);
+
+ return host_command_process(&args);
+}
+
+int host_cmd_motion_sense_ec_rate(uint8_t sensor_num, int data_rate_ms,
+ struct ec_response_motion_sense *response)
+{
+ struct ec_params_motion_sense params = {
+ .cmd = MOTIONSENSE_CMD_EC_RATE,
+ .ec_rate = {
+ .sensor_num = sensor_num,
+ .data = data_rate_ms,
+ },
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_MOTION_SENSE_CMD, 1, *response, params);
+
+ printk("sensor_num=%u/%u\n", params.sensor_odr.sensor_num, sensor_num);
+ return host_command_process(&args);
+}
+
void host_cmd_typec_discovery(int port, enum typec_partner_type partner_type,
void *response, size_t response_size)
{
diff --git a/zephyr/test/ec_app/BUILD.py b/zephyr/test/ec_app/BUILD.py
index 48d072fe19..eeb85c0e46 100644
--- a/zephyr/test/ec_app/BUILD.py
+++ b/zephyr/test/ec_app/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for ec_app test."""
+
register_host_test("ec_app")
diff --git a/zephyr/test/hooks/BUILD.py b/zephyr/test/hooks/BUILD.py
index 6b20daea30..ee25ae52bc 100644
--- a/zephyr/test/hooks/BUILD.py
+++ b/zephyr/test/hooks/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for hooks test."""
+
register_host_test("hooks")
diff --git a/zephyr/test/i2c/BUILD.py b/zephyr/test/i2c/BUILD.py
index 150926dc69..86d9da537a 100644
--- a/zephyr/test/i2c/BUILD.py
+++ b/zephyr/test/i2c/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for i2c test."""
+
register_host_test("i2c", dts_overlays=["overlay.dts"])
diff --git a/zephyr/test/i2c_dts/BUILD.py b/zephyr/test/i2c_dts/BUILD.py
index ec93d8b6f7..e0e97be121 100644
--- a/zephyr/test/i2c_dts/BUILD.py
+++ b/zephyr/test/i2c_dts/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for i2c_dts test."""
+
register_host_test("i2c_dts", dts_overlays=["overlay.dts"])
diff --git a/zephyr/test/math/BUILD.py b/zephyr/test/math/BUILD.py
index 2b624b1bdd..8f6b28ce1a 100644
--- a/zephyr/test/math/BUILD.py
+++ b/zephyr/test/math/BUILD.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for math tests."""
+
register_host_test(
"math_fixed", kconfig_files=[here / "prj.conf", here / "fixed_point.conf"]
)
diff --git a/zephyr/test/system/BUILD.py b/zephyr/test/system/BUILD.py
index 1aecdeb37d..b9f14c2fcf 100644
--- a/zephyr/test/system/BUILD.py
+++ b/zephyr/test/system/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for system test."""
+
register_host_test("system", dts_overlays=["overlay.dts"])
diff --git a/zephyr/test/tasks/BUILD.py b/zephyr/test/tasks/BUILD.py
index 1f49d4b41d..9280101836 100644
--- a/zephyr/test/tasks/BUILD.py
+++ b/zephyr/test/tasks/BUILD.py
@@ -2,4 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Register zmake project for tasks test."""
+
register_host_test("tasks")
diff --git a/zephyr/zmake/.pylintrc b/zephyr/zmake/.pylintrc
index 341cb4d687..fd798870dd 100644
--- a/zephyr/zmake/.pylintrc
+++ b/zephyr/zmake/.pylintrc
@@ -1,9 +1,9 @@
[MASTER]
-init-hook='import sys; sys.path.append("/usr/lib64/python3.6/site-packages")'
+init-hook='import sys; sys.path.extend(["zephyr/zmake", "/usr/lib64/python3.6/site-packages"])'
[MESSAGES CONTROL]
-disable=bad-continuation,bad-whitespace,format,fixme
+disable=bad-continuation,bad-whitespace,format,fixme,wrong-import-order
[format]
diff --git a/zephyr/zmake/README.md b/zephyr/zmake/README.md
index 12125d8213..6e2690959b 100644
--- a/zephyr/zmake/README.md
+++ b/zephyr/zmake/README.md
@@ -85,7 +85,7 @@ Chromium OS's meta-build tool for Zephyr
### zmake list-projects
-**Usage:** `zmake list-projects [-h] [--format FORMAT] [search_dir]`
+**Usage:** `zmake list-projects [-h] [--format FMT] [search_dir]`
#### Positional Arguments
@@ -98,7 +98,7 @@ Chromium OS's meta-build tool for Zephyr
| | |
|---|---|
| `-h`, `--help` | show this help message and exit |
-| `--format FORMAT` | Output format to print projects (str.format(config=project.config) is called on this for each project). |
+| `--format FMT` | Output format to print projects (str.format(config=project.config) is called on this for each project). |
### zmake test
diff --git a/zephyr/zmake/tests/test_build_config.py b/zephyr/zmake/tests/test_build_config.py
index aab41b84ef..76cc0a2028 100644
--- a/zephyr/zmake/tests/test_build_config.py
+++ b/zephyr/zmake/tests/test_build_config.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Tests of zmake's build config system."""
+
import argparse
import os
import pathlib
@@ -16,6 +18,8 @@ import zmake.jobserver
import zmake.util as util
from zmake.build_config import BuildConfig
+# pylint:disable=redefined-outer-name,unused-argument
+
# Strategies for use with hypothesis
filenames = st.text(
alphabet=set(string.printable) - {"/", ";"}, min_size=1, max_size=254
@@ -71,13 +75,13 @@ def test_merge(coins, combined):
kconf1, kconf2 = split(combined.kconfig_defs.items())
files1, files2 = split(combined.kconfig_files)
- c1 = BuildConfig(
+ config1 = BuildConfig(
environ_defs=dict(env1),
cmake_defs=dict(cmake1),
kconfig_defs=dict(kconf1),
kconfig_files=files1,
)
- c2 = BuildConfig(
+ config2 = BuildConfig(
environ_defs=dict(env2),
cmake_defs=dict(cmake2),
kconfig_defs=dict(kconf2),
@@ -85,7 +89,7 @@ def test_merge(coins, combined):
)
# Merge the split configs
- merged = c1 | c2
+ merged = config1 | config2
# Assert that the merged split configs is the original config
assert merged.environ_defs == combined.environ_defs
@@ -104,9 +108,10 @@ class FakeJobClient(zmake.jobserver.JobClient):
def get_job(self):
return zmake.jobserver.JobHandle(lambda: None)
- def popen(self, argv, env={}, **kwargs):
+ def popen(self, argv, **kwargs):
+ kwargs.setdefault("env", {})
self.captured_argv = [str(arg) for arg in argv]
- self.captured_env = {str(k): str(v) for k, v in env.items()}
+ self.captured_env = {str(k): str(v) for k, v in kwargs["env"].items()}
def parse_cmake_args(argv):
@@ -145,12 +150,12 @@ def parse_cmake_args(argv):
@hypothesis.given(build_configs_no_kconfig, paths, paths)
@hypothesis.settings(deadline=60000)
-def test_popen_cmake_no_kconfig(conf, project_dir, build_dir):
+def test_popen_cmake_no_kconfig(conf: BuildConfig, project_dir, build_dir):
"""Test popen_cmake for a config with no kconfig definitions."""
job_client = FakeJobClient()
conf.popen_cmake(job_client, project_dir, build_dir)
- args, cmake_defs = parse_cmake_args(job_client.captured_argv)
+ _, cmake_defs = parse_cmake_args(job_client.captured_argv)
assert cmake_defs == conf.cmake_defs
assert job_client.captured_env == conf.environ_defs
@@ -158,7 +163,7 @@ def test_popen_cmake_no_kconfig(conf, project_dir, build_dir):
@hypothesis.given(build_configs_with_at_least_one_kconfig, paths, paths)
@hypothesis.settings(deadline=60000)
-def test_popen_cmake_kconfig_but_no_file(conf, project_dir, build_dir):
+def test_popen_cmake_kconfig_but_no_file(conf: BuildConfig, project_dir, build_dir):
"""Test that running popen_cmake with Kconfig definitions to write
out, but no path to do so, should raise an error.
"""
@@ -170,18 +175,19 @@ def test_popen_cmake_kconfig_but_no_file(conf, project_dir, build_dir):
@hypothesis.given(build_configs, paths, paths)
@hypothesis.settings(deadline=60000)
-def test_popen_cmake_kconfig(conf, project_dir, build_dir):
+def test_popen_cmake_kconfig(conf: BuildConfig, project_dir, build_dir):
+ """Test calling popen_cmake and verifying the kconfig_files."""
job_client = FakeJobClient()
- with tempfile.NamedTemporaryFile("w", delete=False) as f:
- temp_path = f.name
+ with tempfile.NamedTemporaryFile("w", delete=False) as file:
+ temp_path = file.name
try:
conf.popen_cmake(
job_client, project_dir, build_dir, kconfig_path=pathlib.Path(temp_path)
)
- args, cmake_defs = parse_cmake_args(job_client.captured_argv)
+ _, cmake_defs = parse_cmake_args(job_client.captured_argv)
expected_kconfig_files = set(str(f) for f in conf.kconfig_files)
expected_kconfig_files.add(temp_path)
@@ -215,9 +221,10 @@ def fake_kconfig_files(tmp_path):
def test_build_config_json_stability(fake_kconfig_files):
- # as_json() should return equivalent strings for two equivalent
- # build configs.
- a = BuildConfig(
+ """as_json() should return equivalent strings for two equivalent
+ build configs.
+ """
+ config_a = BuildConfig(
environ_defs={
"A": "B",
"B": "C",
@@ -234,7 +241,7 @@ def test_build_config_json_stability(fake_kconfig_files):
)
# Dict ordering is intentionally reversed in b.
- b = BuildConfig(
+ config_b = BuildConfig(
environ_defs={
"B": "C",
"A": "B",
@@ -250,20 +257,21 @@ def test_build_config_json_stability(fake_kconfig_files):
kconfig_files=list(fake_kconfig_files),
)
- assert a.as_json() == b.as_json()
+ assert config_a.as_json() == config_b.as_json()
def test_build_config_json_inequality():
- # Two differing build configs should not have the same json
- # representation.
- a = BuildConfig(cmake_defs={"A": "B"})
- b = BuildConfig(environ_defs={"A": "B"})
+ """Two differing build configs should not have the same json
+ representation.
+ """
+ config_a = BuildConfig(cmake_defs={"A": "B"})
+ config_b = BuildConfig(environ_defs={"A": "B"})
- assert a.as_json() != b.as_json()
+ assert config_a.as_json() != config_b.as_json()
def test_build_config_json_inequality_dtc_changes(tmp_path):
- # When DTC overlay files change, so should the JSON.
+ """When DTC overlay files change, so should the JSON."""
dts_file_1 = tmp_path / "overlay1.dts"
dts_file_1.write_text("/* blah */\n")
@@ -287,8 +295,8 @@ def test_build_config_json_inequality_dtc_changes(tmp_path):
def test_kconfig_file_duplicates(fake_kconfig_files):
- # Kconfig files should be like the "uniq" command. Repeats should
- # be removed, but not duplicates.
+ """Kconfig files should be like the "uniq" command. Repeats should
+ be removed, but not duplicates."""
cfg = BuildConfig(
kconfig_files=[
fake_kconfig_files[0],
diff --git a/zephyr/zmake/tests/test_modules.py b/zephyr/zmake/tests/test_modules.py
index 87e5d7bfc9..600544d2e7 100644
--- a/zephyr/zmake/tests/test_modules.py
+++ b/zephyr/zmake/tests/test_modules.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Test zmake modules module."""
+
import pathlib
import tempfile
diff --git a/zephyr/zmake/tests/test_multiproc_executor.py b/zephyr/zmake/tests/test_multiproc_executor.py
index ebc2be5e4f..c905ef03ec 100644
--- a/zephyr/zmake/tests/test_multiproc_executor.py
+++ b/zephyr/zmake/tests/test_multiproc_executor.py
@@ -1,52 +1,62 @@
# 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.
+
+"""Tests for zmake multiproc."""
+
import threading
import zmake.multiproc
def test_single_function_executor_success():
+ """Test single function success."""
executor = zmake.multiproc.Executor()
executor.append(lambda: 0)
assert executor.wait() == 0
def test_single_function_executor_fail():
+ """Test single function fail."""
executor = zmake.multiproc.Executor()
executor.append(lambda: -2)
assert executor.wait() == -2
def test_single_function_executor_raise():
+ """Test single function raising an exception."""
executor = zmake.multiproc.Executor()
executor.append(lambda: 1 / 0)
assert executor.wait() != 0
-def _lock_step(cv, predicate, step, return_value=0):
- with cv:
- cv.wait_for(predicate=lambda: step[0] == predicate)
+def _lock_step(cond, predicate, step, return_value=0):
+ with cond:
+ cond.wait_for(predicate=lambda: step[0] == predicate)
step[0] += 1
- cv.notify_all()
+ cond.notify_all()
return return_value
def test_two_function_executor_wait_for_both():
- cv = threading.Condition()
+ """Test two functions in executor."""
+ cond = threading.Condition()
step = [0]
executor = zmake.multiproc.Executor()
- executor.append(lambda: _lock_step(cv=cv, predicate=0, step=step))
- executor.append(lambda: _lock_step(cv=cv, predicate=1, step=step))
+ executor.append(lambda: _lock_step(cond=cond, predicate=0, step=step))
+ executor.append(lambda: _lock_step(cond=cond, predicate=1, step=step))
assert executor.wait() == 0
assert step[0] == 2
def test_two_function_executor_one_fails():
- cv = threading.Condition()
+ """Test two functions in executor, when one fails."""
+ cond = threading.Condition()
step = [0]
executor = zmake.multiproc.Executor()
- executor.append(lambda: _lock_step(cv=cv, predicate=0, step=step, return_value=-1))
- executor.append(lambda: _lock_step(cv=cv, predicate=1, step=step))
+ executor.append(
+ lambda: _lock_step(cond=cond, predicate=0, step=step, return_value=-1)
+ )
+ executor.append(lambda: _lock_step(cond=cond, predicate=1, step=step))
assert executor.wait() == -1
assert step[0] == 2
diff --git a/zephyr/zmake/tests/test_multiproc_logging.py b/zephyr/zmake/tests/test_multiproc_logging.py
index 2eac9326d3..2694b6451e 100644
--- a/zephyr/zmake/tests/test_multiproc_logging.py
+++ b/zephyr/zmake/tests/test_multiproc_logging.py
@@ -1,6 +1,9 @@
# 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.
+
+"""Tests for zmake multiproc logging code."""
+
import io
import logging
import os
@@ -11,30 +14,32 @@ import zmake.multiproc
def test_read_output_from_pipe():
+ """Test reading output from a pipe."""
semaphore = threading.Semaphore(0)
pipe = os.pipe()
- fd = io.TextIOWrapper(os.fdopen(pipe[0], "rb"), encoding="utf-8")
+ file_desc = io.TextIOWrapper(os.fdopen(pipe[0], "rb"), encoding="utf-8")
logger = mock.Mock(spec=logging.Logger)
logger.log.side_effect = lambda log_lvl, line: semaphore.release()
- zmake.multiproc.log_output(logger, logging.DEBUG, fd, job_id="")
+ zmake.multiproc.LogWriter.log_output(logger, logging.DEBUG, file_desc, job_id="")
os.write(pipe[1], "Hello\n".encode("utf-8"))
semaphore.acquire()
logger.log.assert_called_with(logging.DEBUG, "Hello")
def test_read_output_change_log_level():
+ """Test changing the log level."""
semaphore = threading.Semaphore(0)
pipe = os.pipe()
- fd = io.TextIOWrapper(os.fdopen(pipe[0], "rb"), encoding="utf-8")
+ file_desc = io.TextIOWrapper(os.fdopen(pipe[0], "rb"), encoding="utf-8")
logger = mock.Mock(spec=logging.Logger)
logger.log.side_effect = lambda log_lvl, line: semaphore.release()
# This call will log output from fd (the file descriptor) to DEBUG, though
# when the line starts with 'World', the logging level will be switched to
# CRITICAL (see the content of the log_lvl_override_func).
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
logger=logger,
log_level=logging.DEBUG,
- file_descriptor=fd,
+ file_descriptor=file_desc,
log_level_override_func=lambda line, lvl: logging.CRITICAL
if line.startswith("World")
else lvl,
@@ -72,8 +77,8 @@ def test_read_output_from_second_pipe():
logger = mock.Mock(spec=logging.Logger)
logger.log.side_effect = lambda log_lvl, fmt, id, line: semaphore.release()
- zmake.multiproc.log_output(logger, logging.DEBUG, fds[0], job_id="0")
- zmake.multiproc.log_output(logger, logging.ERROR, fds[1], job_id="1")
+ zmake.multiproc.LogWriter.log_output(logger, logging.DEBUG, fds[0], job_id="0")
+ zmake.multiproc.LogWriter.log_output(logger, logging.ERROR, fds[1], job_id="1")
os.write(pipes[1][1], "Hello\n".encode("utf-8"))
semaphore.acquire()
@@ -97,8 +102,8 @@ def test_read_output_after_another_pipe_closed():
logger = mock.Mock(spec=logging.Logger)
logger.log.side_effect = lambda log_lvl, fmt, id, line: semaphore.release()
- zmake.multiproc.log_output(logger, logging.DEBUG, fds[0], job_id="0")
- zmake.multiproc.log_output(logger, logging.ERROR, fds[1], job_id="1")
+ zmake.multiproc.LogWriter.log_output(logger, logging.DEBUG, fds[0], job_id="0")
+ zmake.multiproc.LogWriter.log_output(logger, logging.ERROR, fds[1], job_id="1")
fds[0].close()
os.write(pipes[1][1], "Hello\n".encode("utf-8"))
diff --git a/zephyr/zmake/tests/test_packers.py b/zephyr/zmake/tests/test_packers.py
index 1709c68098..43b63a908f 100644
--- a/zephyr/zmake/tests/test_packers.py
+++ b/zephyr/zmake/tests/test_packers.py
@@ -2,9 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Tests for zmake packers."""
+
import pathlib
import tempfile
-import unittest.mock as mock
import hypothesis
import hypothesis.strategies as st
@@ -16,42 +17,57 @@ import zmake.output_packers as packers
absolute_path = st.from_regex(regex=r"\A/[\w/]*\Z")
-@hypothesis.given(absolute_path)
+class FakePacker(packers.BasePacker):
+ """Fake packer to expose protected methods."""
+
+ def __init__(self, max_size):
+ super().__init__(project=None)
+ self.max_size = max_size
+
+ def check_packed_file_size(self, file, dir_map):
+ """Expose the _check_packed_file_size method."""
+ return self._check_packed_file_size(file, dir_map)
+
+ def _get_max_image_bytes(self, dir_map):
+ return self.max_size
+
+ def pack_firmware(self, work_dir, jobclient, dir_map, version_string=""):
+ del version_string
+ assert False
+
+
+@hypothesis.given(st.binary(min_size=101, max_size=200))
@hypothesis.settings(deadline=60000)
-def test_file_size_unbounded(path):
- packer = packers.BasePacker(project=None)
- packer._is_size_bound = mock.Mock(name="_is_size_bound", return_value=False)
- file = pathlib.Path(path) / "zephyr.bin"
- assert packer._check_packed_file_size(file=file, dirs={}) == file
- packer._is_size_bound.assert_called_once_with(file)
+def test_file_size_unbounded(data):
+ """Test with file size unbounded."""
+ packer = FakePacker(None)
+ with tempfile.TemporaryDirectory() as temp_dir_name:
+ file = pathlib.Path(temp_dir_name) / "zephyr.elf"
+ with open(file, "wb") as outfile:
+ outfile.write(data)
+ assert packer.check_packed_file_size(file=file, dir_map={}) == file
@hypothesis.given(st.binary(min_size=5, max_size=100))
@hypothesis.settings(deadline=60000)
def test_file_size_in_bounds(data):
- packer = packers.BasePacker(project=None)
- packer._is_size_bound = mock.Mock(name="_is_size_bound", return_value=True)
- packer._get_max_image_bytes = mock.Mock(
- name="_get_max_image_bytes", return_value=100
- )
+ """Test with file size limited."""
+ packer = FakePacker(100)
with tempfile.TemporaryDirectory() as temp_dir_name:
file = pathlib.Path(temp_dir_name) / "zephyr.bin"
- with open(file, "wb") as f:
- f.write(data)
- assert packer._check_packed_file_size(file=file, dirs={}) == file
+ with open(file, "wb") as outfile:
+ outfile.write(data)
+ assert packer.check_packed_file_size(file=file, dir_map={}) == file
@hypothesis.given(st.binary(min_size=101, max_size=200))
@hypothesis.settings(deadline=60000)
def test_file_size_out_of_bounds(data):
- packer = packers.BasePacker(project=None)
- packer._is_size_bound = mock.Mock(name="_is_size_bound", return_value=True)
- packer._get_max_image_bytes = mock.Mock(
- name="_get_max_image_bytes", return_value=100
- )
+ """Test with file size limited, and file exceeds limit."""
+ packer = FakePacker(100)
with tempfile.TemporaryDirectory() as temp_dir_name:
file = pathlib.Path(temp_dir_name) / "zephyr.bin"
- with open(file, "wb") as f:
- f.write(data)
+ with open(file, "wb") as outfile:
+ outfile.write(data)
with pytest.raises(RuntimeError):
- packer._check_packed_file_size(file=file, dirs={})
+ packer.check_packed_file_size(file=file, dir_map={})
diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py
index f4808d14d5..b5facbc331 100644
--- a/zephyr/zmake/tests/test_project.py
+++ b/zephyr/zmake/tests/test_project.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Test zmake project module."""
+
import pathlib
import string
import tempfile
@@ -193,6 +195,7 @@ def test_find_projects_name_conflict(tmp_path):
def test_register_variant(tmp_path):
+ """Test registering a variant."""
(tmp_path / "BUILD.py").write_text(
"""
some = register_raw_project(
@@ -236,6 +239,7 @@ another = some_variant.variant(
],
)
def test_kconfig_files(tmp_path, actual_files, config_files, expected_files):
+ """Test for setting kconfig_files property."""
for name in actual_files:
(tmp_path / name).write_text("")
diff --git a/zephyr/zmake/tests/test_util.py b/zephyr/zmake/tests/test_util.py
index 438c5efcf0..1ec0076162 100644
--- a/zephyr/zmake/tests/test_util.py
+++ b/zephyr/zmake/tests/test_util.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Tests for zmake util."""
+
import pathlib
import tempfile
@@ -19,12 +21,13 @@ version_tuples = st.tuples(version_integers, version_integers, version_integers)
@hypothesis.given(version_tuples)
@hypothesis.settings(deadline=60000)
def test_read_zephyr_version(version_tuple):
+ """Test reading the zephyr version."""
with tempfile.TemporaryDirectory() as zephyr_base:
- with open(pathlib.Path(zephyr_base) / "VERSION", "w") as f:
+ with open(pathlib.Path(zephyr_base) / "VERSION", "w") as file:
for name, value in zip(
("VERSION_MAJOR", "VERSION_MINOR", "PATCHLEVEL"), version_tuple
):
- f.write("{} = {}\n".format(name, value))
+ file.write("{} = {}\n".format(name, value))
assert util.read_zephyr_version(zephyr_base) == version_tuple
@@ -32,10 +35,11 @@ def test_read_zephyr_version(version_tuple):
@hypothesis.given(st.integers())
@hypothesis.settings(deadline=60000)
def test_read_kconfig_autoconf_value(value):
- with tempfile.TemporaryDirectory() as dir:
- path = pathlib.Path(dir)
- with open(path / "autoconf.h", "w") as f:
- f.write("#define TEST {}".format(value))
+ """Test reading the kconfig autoconf."""
+ with tempfile.TemporaryDirectory() as temp_dir:
+ path = pathlib.Path(temp_dir)
+ with open(path / "autoconf.h", "w") as file:
+ file.write("#define TEST {}".format(value))
read_value = util.read_kconfig_autoconf_value(path, "TEST")
assert int(read_value) == value
@@ -52,4 +56,5 @@ def test_read_kconfig_autoconf_value(value):
],
)
def test_c_str(input_str, expected_result):
+ """Test the util.c_str function."""
assert util.c_str(input_str) == expected_result
diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py
index b2c6b43fec..e56e13a519 100644
--- a/zephyr/zmake/tests/test_version.py
+++ b/zephyr/zmake/tests/test_version.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Tests for zmake version code."""
+
import datetime
import subprocess
import unittest.mock as mock
@@ -12,6 +14,8 @@ import zmake.output_packers
import zmake.project
import zmake.version as version
+# pylint:disable=redefined-outer-name,unused-argument
+
def _git_init(repo):
"""Create a new git repository."""
@@ -88,6 +92,7 @@ def _setup_example_repos(tmp_path):
def test_version_string(tmp_path):
+ """Test a that version string is as expected."""
project, zephyr_base, modules = _setup_example_repos(tmp_path)
assert (
version.get_version_string(project, zephyr_base, modules)
@@ -96,6 +101,7 @@ def test_version_string(tmp_path):
def test_version_string_static(tmp_path):
+ """Test a that version string with no git hashes."""
project, zephyr_base, modules = _setup_example_repos(tmp_path)
assert (
version.get_version_string(project, zephyr_base, modules, static=True)
@@ -105,6 +111,7 @@ def test_version_string_static(tmp_path):
@pytest.fixture
def fake_user_hostname():
+ """Fixture to provide a fake user and hostname."""
with mock.patch("getpass.getuser", return_value="toukmond", autospec=True):
with mock.patch("platform.node", return_value="pokey", autospec=True):
yield
@@ -112,6 +119,7 @@ def fake_user_hostname():
@pytest.fixture
def fake_date():
+ """Fixture to provide a fake date."""
fixed_date = datetime.datetime(2021, 6, 28, 3, 18, 53)
with mock.patch("datetime.datetime") as mock_datetime:
mock_datetime.now.return_value = fixed_date
@@ -141,6 +149,7 @@ EXPECTED_HEADER_STATIC = (
def test_header_gen(fake_user_hostname, fake_date, tmp_path):
+ """Test generating the version header."""
# Test the simple case (static=False, no existing header).
output_file = tmp_path / "ec_version.h"
version.write_version_header(HEADER_VERSION_STR, output_file)
@@ -148,6 +157,7 @@ def test_header_gen(fake_user_hostname, fake_date, tmp_path):
def test_header_gen_reproducible_build(tmp_path):
+ """Test that reproducible builds produce the right header."""
# With static=True this time.
output_file = tmp_path / "ec_version.h"
version.write_version_header(HEADER_VERSION_STR_STATIC, output_file, static=True)
@@ -155,6 +165,7 @@ def test_header_gen_reproducible_build(tmp_path):
def test_header_gen_exists_not_changed(fake_user_hostname, fake_date, tmp_path):
+ """Test that the version file is not changed."""
# Test we don't overwrite if no changes needed.
output_file = tmp_path / "ec_version.h"
@@ -170,6 +181,7 @@ def test_header_gen_exists_not_changed(fake_user_hostname, fake_date, tmp_path):
def test_header_gen_exists_needs_changes(fake_user_hostname, fake_date, tmp_path):
+ """Test that the version file is changed, when needed."""
# Test we overwrite when it exists already and changes are needed.
output_file = tmp_path / "ec_version.h"
diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py
index ee00330c27..4ca1d7f077 100644
--- a/zephyr/zmake/tests/test_zmake.py
+++ b/zephyr/zmake/tests/test_zmake.py
@@ -26,7 +26,7 @@ OUR_PATH = os.path.dirname(os.path.realpath(__file__))
class FakeProject:
"""A fake project which requests two builds and does no packing"""
- # pylint: disable=too-few-public-methods,no-self-use
+ # pylint: disable=too-few-public-methods
def __init__(self):
self.packer = unittest.mock.Mock()
@@ -46,15 +46,18 @@ class FakeProject:
yield "ro", zmake.build_config.BuildConfig()
yield "rw", zmake.build_config.BuildConfig()
- def prune_modules(self, _):
+ @staticmethod
+ def prune_modules(_):
"""Fake implementation of prune_modules."""
return {} # pathlib.Path('path')]
- def find_dts_overlays(self, _):
+ @staticmethod
+ def find_dts_overlays(_):
"""Fake implementation of find_dts_overlays."""
return zmake.build_config.BuildConfig()
- def get_toolchain(self, module_paths, override=None):
+ @staticmethod
+ def get_toolchain(module_paths, override=None):
"""Fake implementation of get_toolchain."""
return zmake.toolchains.GenericToolchain(
override or "foo",
@@ -141,7 +144,7 @@ def do_test_with_log_level(zmake_factory_from_dir, log_level, fnames=None):
["fakeproject"],
clobber=True,
)
- multiproc.wait_for_log_end()
+ multiproc.LogWriter.wait_for_log_end()
recs = [rec.getMessage() for rec in cap.records]
return recs
@@ -150,14 +153,14 @@ def do_test_with_log_level(zmake_factory_from_dir, log_level, fnames=None):
class TestFilters:
"""Test filtering of stdout and stderr"""
- # pylint: disable=no-self-use
-
- def test_filter_normal(self, zmake_factory_from_dir):
+ @staticmethod
+ def test_filter_normal(zmake_factory_from_dir):
"""Test filtering of a normal build (with no errors)"""
recs = do_test_with_log_level(zmake_factory_from_dir, logging.ERROR)
assert not recs
- def test_filter_info(self, zmake_factory_from_dir, tmp_path):
+ @staticmethod
+ def test_filter_info(zmake_factory_from_dir, tmp_path):
"""Test what appears on the INFO level"""
recs = do_test_with_log_level(zmake_factory_from_dir, logging.INFO)
# TODO: Remove sets and figure out how to check the lines are in the
@@ -180,7 +183,8 @@ class TestFilters:
# This produces an easy-to-read diff if there is a difference
assert expected == set(recs)
- def test_filter_debug(self, zmake_factory_from_dir, tmp_path):
+ @staticmethod
+ def test_filter_debug(zmake_factory_from_dir, tmp_path):
"""Test what appears on the DEBUG level"""
recs = do_test_with_log_level(zmake_factory_from_dir, logging.DEBUG)
# TODO: Remove sets and figure out how to check the lines are in the
@@ -205,7 +209,8 @@ class TestFilters:
# This produces an easy-to-read diff if there is a difference
assert expected == set(recs)
- def test_filter_devicetree_error(self, zmake_factory_from_dir):
+ @staticmethod
+ def test_filter_devicetree_error(zmake_factory_from_dir):
"""Test that devicetree errors appear"""
recs = do_test_with_log_level(
zmake_factory_from_dir,
@@ -278,7 +283,7 @@ def test_list_projects(
autospec=True,
return_value=fake_projects,
):
- zmake_from_dir.list_projects(format=fmt, search_dir=search_dir)
+ zmake_from_dir.list_projects(fmt=fmt, search_dir=search_dir)
captured = capsys.readouterr()
assert captured.out == expected_output
diff --git a/zephyr/zmake/zmake/__main__.py b/zephyr/zmake/zmake/__main__.py
index 9ad509dfc5..fd1dfec13a 100644
--- a/zephyr/zmake/zmake/__main__.py
+++ b/zephyr/zmake/zmake/__main__.py
@@ -195,6 +195,7 @@ def get_argparser():
list_projects.add_argument(
"--format",
default="{config.project_name}\n",
+ dest="fmt",
help=(
"Output format to print projects (str.format(config=project.config) is "
"called on this for each project)."
@@ -351,7 +352,7 @@ def main(argv=None):
wait_rv = zmake.executor.wait()
return result or wait_rv
finally:
- multiproc.wait_for_log_end()
+ multiproc.LogWriter.wait_for_log_end()
if __name__ == "__main__":
diff --git a/zephyr/zmake/zmake/build_config.py b/zephyr/zmake/zmake/build_config.py
index ced2c9085c..0d03e22a45 100644
--- a/zephyr/zmake/zmake/build_config.py
+++ b/zephyr/zmake/zmake/build_config.py
@@ -7,6 +7,7 @@ import hashlib
import json
import pathlib
+import zmake.jobserver
import zmake.util as util
@@ -18,11 +19,11 @@ class BuildConfig:
"""
def __init__(
- self, environ_defs={}, cmake_defs={}, kconfig_defs={}, kconfig_files=[]
+ self, environ_defs=None, cmake_defs=None, kconfig_defs=None, kconfig_files=None
):
- self.environ_defs = dict(environ_defs)
- self.cmake_defs = dict(cmake_defs)
- self.kconfig_defs = dict(kconfig_defs)
+ self.environ_defs = dict(environ_defs or {})
+ self.cmake_defs = dict(cmake_defs or {})
+ self.kconfig_defs = dict(kconfig_defs or {})
def _remove_duplicate_paths(files):
# Remove multiple of the same kconfig file in a row.
@@ -32,10 +33,15 @@ class BuildConfig:
result.append(path)
return result
- self.kconfig_files = _remove_duplicate_paths(kconfig_files)
+ self.kconfig_files = _remove_duplicate_paths(kconfig_files or [])
def popen_cmake(
- self, jobclient, project_dir, build_dir, kconfig_path=None, **kwargs
+ self,
+ jobclient: zmake.jobserver.JobClient,
+ project_dir,
+ build_dir,
+ kconfig_path=None,
+ **kwargs
):
"""Run Cmake with this config using a jobclient.
diff --git a/zephyr/zmake/zmake/configlib.py b/zephyr/zmake/zmake/configlib.py
index a0463f1a86..a5c78ad22d 100644
--- a/zephyr/zmake/zmake/configlib.py
+++ b/zephyr/zmake/zmake/configlib.py
@@ -15,6 +15,7 @@ def _register_project(**kwargs):
def register_host_project(**kwargs):
+ """Register a project that runs on a posix host."""
kwargs.setdefault("zephyr_board", "native_posix")
kwargs.setdefault("supported_toolchains", ["llvm", "host"])
kwargs.setdefault("output_packer", zmake.output_packers.ElfPacker)
@@ -22,21 +23,25 @@ def register_host_project(**kwargs):
def register_host_test(test_name, **kwargs):
+ """Register a test project that runs on the host."""
kwargs.setdefault("is_test", True)
return register_host_project(project_name="test-{}".format(test_name), **kwargs)
def register_raw_project(**kwargs):
+ """Register a project that uses RawBinPacker."""
kwargs.setdefault("supported_toolchains", ["coreboot-sdk", "zephyr"])
kwargs.setdefault("output_packer", zmake.output_packers.RawBinPacker)
return _register_project(**kwargs)
def register_binman_project(**kwargs):
+ """Register a project that uses BinmanPacker."""
kwargs.setdefault("output_packer", zmake.output_packers.BinmanPacker)
return register_raw_project(**kwargs)
def register_npcx_project(**kwargs):
+ """Register a project that uses NpcxPacker."""
kwargs.setdefault("output_packer", zmake.output_packers.NpcxPacker)
return register_binman_project(**kwargs)
diff --git a/zephyr/zmake/zmake/generate_readme.py b/zephyr/zmake/zmake/generate_readme.py
index d21fd19f7c..9008f0f45d 100644
--- a/zephyr/zmake/zmake/generate_readme.py
+++ b/zephyr/zmake/zmake/generate_readme.py
@@ -25,8 +25,8 @@ class MarkdownHelpFormatter(argparse.HelpFormatter):
lst = self._section_contents
lst.append(text)
- def start_section(self, title):
- self._section_title = title.title()
+ def start_section(self, heading):
+ self._section_title = heading.title()
self._section_contents = []
def end_section(self):
@@ -35,7 +35,7 @@ class MarkdownHelpFormatter(argparse.HelpFormatter):
self._paragraphs.extend(self._section_contents)
self._section_title = None
- def add_usage(self, usage, actions, groups):
+ def add_usage(self, usage, actions, groups, prefix=None):
if not usage:
usage = self._prog
self.add_text(
@@ -55,8 +55,7 @@ class MarkdownHelpFormatter(argparse.HelpFormatter):
else:
parts.append(f"{option_string} {_get_metavar(action).upper()}")
return ", ".join(f"`{part}`" for part in parts)
- else:
- return f"`{_get_metavar(action)}`"
+ return f"`{_get_metavar(action)}`"
def _get_table_line(action):
return f"| {_format_invocation(action)} | {action.help} |"
@@ -89,7 +88,7 @@ def generate_readme():
# Normally, this would not be required, since we don't use from
# imports. But runpy's import machinery essentially does the
# equivalent of a from import on __main__.py.
- import zmake.__main__
+ import zmake.__main__ # pylint: disable=import-outside-toplevel
output = io.StringIO()
parser, sub_action = zmake.__main__.get_argparser()
diff --git a/zephyr/zmake/zmake/jobserver.py b/zephyr/zmake/zmake/jobserver.py
index 0d02a2c8d6..16f856e607 100644
--- a/zephyr/zmake/zmake/jobserver.py
+++ b/zephyr/zmake/zmake/jobserver.py
@@ -35,7 +35,8 @@ class JobClient:
"""Claim a job."""
raise NotImplementedError("Abstract method not implemented")
- def env(self):
+ @staticmethod
+ def env():
"""Get the environment variables necessary to share the job server."""
return {}
@@ -54,35 +55,10 @@ class JobClient:
logger.debug("Running %s", zmake.util.repr_command(argv))
return subprocess.Popen(argv, **kwargs)
- def run(self, *args, claim_job=True, **kwargs):
- """Run a process using subprocess.run, optionally claiming a job.
-
- Args:
- claim_job: True if a job should be claimed.
-
- All other arguments are passed to subprocess.run.
-
- Returns:
- A CompletedProcess object.
- """
- if claim_job:
- with self.get_job():
- return self.run(*args, claim_job=False, **kwargs)
-
- kwargs.setdefault("env", os.environ)
- kwargs["env"].update(self.env())
-
- return subprocess.run(*args, **kwargs)
-
-
-class JobServer(JobClient):
- """Abstract Job Server."""
-
- def __init__(self, jobs=0):
- raise NotImplementedError("Abstract method not implemented")
-
class GNUMakeJobClient(JobClient):
+ """A job client for GNU make."""
+
def __init__(self, read_fd, write_fd):
self._pipe = [read_fd, write_fd]
@@ -127,7 +103,7 @@ class GNUMakeJobClient(JobClient):
return {"MAKEFLAGS": "--jobserver-auth={},{}".format(*self._pipe)}
-class GNUMakeJobServer(JobServer, GNUMakeJobClient):
+class GNUMakeJobServer(GNUMakeJobClient):
"""Implements a GNU Make POSIX Job Server.
See https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html
@@ -135,10 +111,11 @@ class GNUMakeJobServer(JobServer, GNUMakeJobClient):
"""
def __init__(self, jobs=0):
+ [read_fd, write_fd] = os.pipe()
+ super().__init__(read_fd, write_fd)
if not jobs:
jobs = multiprocessing.cpu_count()
elif jobs > select.PIPE_BUF:
jobs = select.PIPE_BUF
- self._pipe = os.pipe()
os.write(self._pipe[1], b"+" * jobs)
diff --git a/zephyr/zmake/zmake/modules.py b/zephyr/zmake/zmake/modules.py
index 5ba0ef73f8..91f0dd50b9 100644
--- a/zephyr/zmake/zmake/modules.py
+++ b/zephyr/zmake/zmake/modules.py
@@ -95,5 +95,4 @@ def setup_module_symlinks(output_dir, modules):
return build_config.BuildConfig(
cmake_defs={"ZEPHYR_MODULES": ";".join(map(str, module_links))}
)
- else:
- return build_config.BuildConfig()
+ return build_config.BuildConfig()
diff --git a/zephyr/zmake/zmake/multiproc.py b/zephyr/zmake/zmake/multiproc.py
index 94f5f5b69d..7d9a88de5a 100644
--- a/zephyr/zmake/zmake/multiproc.py
+++ b/zephyr/zmake/zmake/multiproc.py
@@ -1,11 +1,6 @@
# Copyright 2020 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.
-import collections
-import logging
-import os
-import select
-import threading
"""Zmake multiprocessing utility module.
@@ -15,22 +10,16 @@ process does not need to finish before the output is available to the developer
on the screen.
"""
-# A local pipe use to signal the look that a new file descriptor was added and
-# should be included in the select statement.
-_logging_interrupt_pipe = os.pipe()
-# A condition variable used to synchronize logging operations.
-_logging_cv = threading.Condition()
-# A map of file descriptors to their LogWriter
-_logging_map = {}
-# Should we log job names or not
-log_job_names = True
-
-
-def reset():
- """Reset this module to its starting state (useful for tests)"""
- global _logging_map
+import collections
+import io
+import logging
+import os
+import select
+import threading
+from typing import Any, ClassVar, Dict, List
- _logging_map = {}
+# Should we log job names or not
+LOG_JOB_NAMES = True
class LogWriter:
@@ -52,7 +41,22 @@ class LogWriter:
_file_descriptor: The file descriptor being logged.
"""
- def __init__(
+ # A local pipe use to signal the look that a new file descriptor was added and
+ # should be included in the select statement.
+ _logging_interrupt_pipe = os.pipe()
+ # A condition variable used to synchronize logging operations.
+ _logging_cv = threading.Condition()
+ # A map of file descriptors to their LogWriter
+ _logging_map: ClassVar[Dict[io.TextIOBase, "LogWriter"]] = {}
+ # The thread that handles the reading from pipes and writing to log.
+ _logging_thread = None
+
+ @classmethod
+ def reset(cls):
+ """Reset this module to its starting state (useful for tests)"""
+ LogWriter._logging_map.clear()
+
+ def __init__( # pylint: disable=too-many-arguments
self,
logger,
log_level,
@@ -89,7 +93,7 @@ class LogWriter:
# greatly simplifies the logic that is needed to update the log
# level.
self._log_level = self._override_func(line, self._log_level)
- if self._job_id and log_job_names:
+ if self._job_id and LOG_JOB_NAMES:
self._logger.log(self._log_level, "[%s]%s", self._job_id, line)
else:
self._logger.log(self._log_level, line)
@@ -111,141 +115,150 @@ class LogWriter:
This method will block execution until all the logs have been flushed out.
"""
- with _logging_cv:
- _logging_cv.wait_for(lambda: self._file_descriptor not in _logging_map)
+ with LogWriter._logging_cv:
+ LogWriter._logging_cv.wait_for(
+ lambda: self._file_descriptor not in LogWriter._logging_map
+ )
if self._tee_output:
self._tee_output.close()
self._tee_output = None
+ @classmethod
+ def _log_fd(cls, file_descriptor: io.TextIOBase):
+ """Log information from a single file descriptor.
-def _log_fd(fd):
- """Log information from a single file descriptor.
+ This function is BLOCKING. It will read from the given file descriptor until
+ either the end of line is read or EOF. Once EOF is read it will remove the
+ file descriptor from _logging_map so it will no longer be used.
+ Additionally, in some cases, the file descriptor will be closed (caused by
+ a call to Popen.wait()). In these cases, the file descriptor will also be
+ removed from the map as it is no longer valid.
+ """
+ with LogWriter._logging_cv:
+ writer = LogWriter._logging_map[file_descriptor]
+ if file_descriptor.closed:
+ del LogWriter._logging_map[file_descriptor]
+ LogWriter._logging_cv.notify_all()
+ return
+ line = file_descriptor.readline()
+ if not line:
+ # EOF
+ del LogWriter._logging_map[file_descriptor]
+ LogWriter._logging_cv.notify_all()
+ return
+ line = line.rstrip("\n")
+ if line:
+ writer.log_line(line)
+
+ @classmethod
+ def _prune_logging_fds(cls):
+ """Prune the current file descriptors under _logging_map.
+
+ This function will iterate over the logging map and check for closed file
+ descriptors. Every closed file descriptor will be removed.
+ """
+ with LogWriter._logging_cv:
+ remove = [
+ file_descriptor
+ for file_descriptor in LogWriter._logging_map
+ if file_descriptor.closed
+ ]
+ for file_descriptor in remove:
+ del LogWriter._logging_map[file_descriptor]
+ if remove:
+ LogWriter._logging_cv.notify_all()
+
+ @classmethod
+ def _logging_loop(cls):
+ """The primary logging thread loop.
+
+ This is the entry point of the logging thread. It will listen for (1) any
+ new data on the output file descriptors that were added via log_output() and
+ (2) any new file descriptors being added by log_output(). Once a file
+ descriptor is ready to be read, this function will call _log_fd to perform
+ the actual read and logging.
+ """
+ while True:
+ with LogWriter._logging_cv:
+ LogWriter._logging_cv.wait_for(lambda: LogWriter._logging_map)
+ keys: List[Any] = list(LogWriter._logging_map.keys())
+ keys.append(LogWriter._logging_interrupt_pipe[0])
+ try:
+ fds, _, _ = select.select(keys, [], [])
+ except ValueError:
+ # One of the file descriptors must be closed, prune them and try
+ # again.
+ LogWriter._prune_logging_fds()
+ continue
+ if LogWriter._logging_interrupt_pipe[0] in fds:
+ # We got a sentinel byte sent by log_output(), this is a signal used to
+ # break out of the blocking select.select call to tell us that the
+ # file descriptor set has changed. We just need to read the byte and
+ # remove this descriptor from the list. If we actually have data
+ # that should be read it will be read in the for loop below.
+ os.read(LogWriter._logging_interrupt_pipe[0], 1)
+ fds.remove(LogWriter._logging_interrupt_pipe[0])
+ for file in fds:
+ LogWriter._log_fd(file)
+
+ @classmethod
+ def log_output( # pylint: disable=too-many-arguments
+ cls,
+ logger,
+ log_level,
+ file_descriptor,
+ log_level_override_func=None,
+ job_id=None,
+ tee_output=None,
+ ):
+ """Log the output from the given file descriptor.
- This function is BLOCKING. It will read from the given file descriptor until
- either the end of line is read or EOF. Once EOF is read it will remove the
- file descriptor from _logging_map so it will no longer be used.
- Additionally, in some cases, the file descriptor will be closed (caused by
- a call to Popen.wait()). In these cases, the file descriptor will also be
- removed from the map as it is no longer valid.
- """
- with _logging_cv:
- writer = _logging_map[fd]
- if fd.closed:
- del _logging_map[fd]
- _logging_cv.notify_all()
- return
- line = fd.readline()
- if not line:
- # EOF
- del _logging_map[fd]
- _logging_cv.notify_all()
- return
- line = line.rstrip("\n")
- if line:
- writer.log_line(line)
-
-
-def _prune_logging_fds():
- """Prune the current file descriptors under _logging_map.
-
- This function will iterate over the logging map and check for closed file
- descriptors. Every closed file descriptor will be removed.
- """
- with _logging_cv:
- remove = [fd for fd in _logging_map.keys() if fd.closed]
- for fd in remove:
- del _logging_map[fd]
- if remove:
- _logging_cv.notify_all()
-
-
-def _logging_loop():
- """The primary logging thread loop.
-
- This is the entry point of the logging thread. It will listen for (1) any
- new data on the output file descriptors that were added via log_output() and
- (2) any new file descriptors being added by log_output(). Once a file
- descriptor is ready to be read, this function will call _log_fd to perform
- the actual read and logging.
- """
- while True:
- with _logging_cv:
- _logging_cv.wait_for(lambda: _logging_map)
- keys = list(_logging_map.keys()) + [_logging_interrupt_pipe[0]]
- try:
- fds, _, _ = select.select(keys, [], [])
- except ValueError:
- # One of the file descriptors must be closed, prune them and try
- # again.
- _prune_logging_fds()
- continue
- if _logging_interrupt_pipe[0] in fds:
- # We got a dummy byte sent by log_output(), this is a signal used to
- # break out of the blocking select.select call to tell us that the
- # file descriptor set has changed. We just need to read the byte and
- # remove this descriptor from the list. If we actually have data
- # that should be read it will be read in the for loop below.
- os.read(_logging_interrupt_pipe[0], 1)
- fds.remove(_logging_interrupt_pipe[0])
- for fd in fds:
- _log_fd(fd)
-
-
-_logging_thread = None
-
-
-def log_output(
- logger,
- log_level,
- file_descriptor,
- log_level_override_func=None,
- job_id=None,
- tee_output=None,
-):
- """Log the output from the given file descriptor.
-
- Args:
- logger: The logger object to use.
- log_level: The logging level to use.
- file_descriptor: The file descriptor to read from.
- log_level_override_func: A function used to override the log level. The
- function will be called once per line prior to logging and will be
- passed the arguments of the line and the default log level.
-
- Returns:
- LogWriter object for the resulting output
- """
- with _logging_cv:
- global _logging_thread
- if _logging_thread is None or not _logging_thread.is_alive():
- # First pass or thread must have died, create a new one.
- _logging_thread = threading.Thread(target=_logging_loop, daemon=True)
- _logging_thread.start()
-
- writer = LogWriter(
- logger,
- log_level,
- log_level_override_func,
- job_id,
- file_descriptor,
- tee_output=tee_output,
- )
- _logging_map[file_descriptor] = writer
- # Write a dummy byte to the pipe to break the select so we can add the
- # new fd.
- os.write(_logging_interrupt_pipe[1], b"x")
- # Notify the condition so we can run the select on the current fds.
- _logging_cv.notify_all()
- return writer
-
-
-def wait_for_log_end():
- """Wait for all the logs to be printed.
-
- This method will block execution until all the logs have been flushed out.
- """
- with _logging_cv:
- _logging_cv.wait_for(lambda: not _logging_map)
+ Args:
+ logger: The logger object to use.
+ log_level: The logging level to use.
+ file_descriptor: The file descriptor to read from.
+ log_level_override_func: A function used to override the log level. The
+ function will be called once per line prior to logging and will be
+ passed the arguments of the line and the default log level.
+
+ Returns:
+ LogWriter object for the resulting output
+ """
+ with LogWriter._logging_cv:
+ if (
+ LogWriter._logging_thread is None
+ or not LogWriter._logging_thread.is_alive()
+ ):
+ # First pass or thread must have died, create a new one.
+ LogWriter._logging_thread = threading.Thread(
+ target=LogWriter._logging_loop, daemon=True
+ )
+ LogWriter._logging_thread.start()
+
+ writer = LogWriter(
+ logger,
+ log_level,
+ log_level_override_func,
+ job_id,
+ file_descriptor,
+ tee_output=tee_output,
+ )
+ LogWriter._logging_map[file_descriptor] = writer
+ # Write a sentinel byte to the pipe to break the select so we can add the
+ # new fd.
+ os.write(LogWriter._logging_interrupt_pipe[1], b"x")
+ # Notify the condition so we can run the select on the current fds.
+ LogWriter._logging_cv.notify_all()
+ return writer
+
+ @classmethod
+ def wait_for_log_end(cls):
+ """Wait for all the logs to be printed.
+
+ This method will block execution until all the logs have been flushed out.
+ """
+ with LogWriter._logging_cv:
+ LogWriter._logging_cv.wait_for(lambda: not LogWriter._logging_map)
class Executor:
@@ -315,8 +328,8 @@ class Executor:
"""
try:
result = func()
- except Exception as ex:
- self.logger.exception(ex)
+ except Exception as e: # pylint: disable=broad-except
+ self.logger.exception(e)
result = -1
with self.lock:
self.results.append(result)
diff --git a/zephyr/zmake/zmake/output_packers.py b/zephyr/zmake/zmake/output_packers.py
index eae7358157..24a72425d6 100644
--- a/zephyr/zmake/zmake/output_packers.py
+++ b/zephyr/zmake/zmake/output_packers.py
@@ -5,8 +5,11 @@
import logging
import shutil
import subprocess
+from pathlib import Path
+from typing import Dict, Optional
import zmake.build_config as build_config
+import zmake.jobserver
import zmake.multiproc
import zmake.util as util
@@ -17,7 +20,8 @@ class BasePacker:
def __init__(self, project):
self.project = project
- def configs(self):
+ @staticmethod
+ def configs():
"""Get all of the build configurations necessary.
Yields:
@@ -25,7 +29,13 @@ class BasePacker:
"""
yield "singleimage", build_config.BuildConfig()
- def pack_firmware(self, work_dir, jobclient, version_string=""):
+ def pack_firmware(
+ self,
+ work_dir,
+ jobclient: zmake.jobserver.JobClient,
+ dir_map: Dict[str, Path],
+ version_string="",
+ ):
"""Pack a firmware image.
Config names from the configs generator are passed as keyword
@@ -36,6 +46,7 @@ class BasePacker:
work_dir: A directory to write outputs and temporary files
into.
jobclient: A JobClient object to use.
+ dir_map: A dict of build dirs such as {'ro': path_to_ro_dir}.
version_string: The version string, which may end up in
certain parts of the outputs.
@@ -46,44 +57,38 @@ class BasePacker:
"""
raise NotImplementedError("Abstract method not implemented")
- def _get_max_image_bytes(self):
+ @staticmethod
+ def _get_max_image_bytes(dir_map) -> Optional[int]:
"""Get the maximum allowed image size (in bytes).
This value will generally be found in CONFIG_FLASH_SIZE but may vary
depending on the specific way things are being packed.
- Returns:
- The maximum allowed size of the image in bytes.
- """
- raise NotImplementedError("Abstract method not implemented")
-
- def _is_size_bound(self, path):
- """Check whether the given path should be constrained by size.
-
- Generally, .elf files will be unconstrained while .bin files will be
- constrained.
-
Args:
- path: A file's path to test.
+ file: A file to test.
+ dir_map: A dict of build dirs such as {'ro': path_to_ro_dir}.
Returns:
- True if the file size should be checked. False otherwise.
+ The maximum allowed size of the image in bytes, or None if the size
+ is not limited.
"""
- return path.suffix == ".bin"
+ del dir_map
- def _check_packed_file_size(self, file, dirs):
+ def _check_packed_file_size(self, file, dir_map):
"""Check that a packed file passes size constraints.
Args:
file: A file to test.
- dirs: A map of the arguments to pass to _get_max_image_bytes
+ dir_map: A dict of build dirs such as {'ro': path_to_ro_dir}.
+
Returns:
The file if it passes the test.
"""
- if not self._is_size_bound(
- file
- ) or file.stat().st_size <= self._get_max_image_bytes(**dirs):
+ max_size = self._get_max_image_bytes( # pylint: disable=assignment-from-none
+ dir_map
+ )
+ if max_size is None or file.stat().st_size <= max_size:
return file
raise RuntimeError("Output file ({}) too large".format(file))
@@ -91,15 +96,17 @@ class BasePacker:
class ElfPacker(BasePacker):
"""Raw proxy for ELF output of a single build."""
- def pack_firmware(self, work_dir, jobclient, singleimage, version_string=""):
- yield singleimage / "zephyr" / "zephyr.elf", "zephyr.elf"
+ def pack_firmware(self, work_dir, jobclient, dir_map, version_string=""):
+ del version_string
+ yield dir_map["singleimage"] / "zephyr" / "zephyr.elf", "zephyr.elf"
class RawBinPacker(BasePacker):
"""Raw proxy for zephyr.bin output of a single build."""
- def pack_firmware(self, work_dir, jobclient, singleimage, version_string=""):
- yield singleimage / "zephyr" / "zephyr.bin", "zephyr.bin"
+ def pack_firmware(self, work_dir, jobclient, dir_map, version_string=""):
+ del version_string
+ yield dir_map["singleimage"] / "zephyr" / "zephyr.bin", "zephyr.bin"
class BinmanPacker(BasePacker):
@@ -116,7 +123,9 @@ class BinmanPacker(BasePacker):
yield "ro", build_config.BuildConfig(kconfig_defs={"CONFIG_CROS_EC_RO": "y"})
yield "rw", build_config.BuildConfig(kconfig_defs={"CONFIG_CROS_EC_RW": "y"})
- def pack_firmware(self, work_dir, jobclient, ro, rw, version_string=""):
+ def pack_firmware(
+ self, work_dir, jobclient: zmake.jobserver.JobClient, dir_map, version_string=""
+ ):
"""Pack RO and RW sections using Binman.
Binman configuration is expected to be found in the RO build
@@ -125,8 +134,7 @@ class BinmanPacker(BasePacker):
Args:
work_dir: The directory used for packing.
jobclient: The client used to run subprocesses.
- ro: Directory containing the RO image build.
- rw: Directory containing the RW image build.
+ dir_map: A dict of build dirs such as {'ro': path_to_ro_dir}.
version_string: The version string to use in FRID/FWID.
Yields:
@@ -134,12 +142,14 @@ class BinmanPacker(BasePacker):
should be copied into the output directory, and the output
filename.
"""
- dts_file_path = ro / "zephyr" / "zephyr.dts"
+ ro_dir = dir_map["ro"]
+ rw_dir = dir_map["rw"]
+ dts_file_path = ro_dir / "zephyr" / "zephyr.dts"
# Copy the inputs into the work directory so that Binman can
# find them under a hard-coded name.
- shutil.copy2(ro / "zephyr" / self.ro_file, work_dir / "zephyr_ro.bin")
- shutil.copy2(rw / "zephyr" / self.rw_file, work_dir / "zephyr_rw.bin")
+ shutil.copy2(ro_dir / "zephyr" / self.ro_file, work_dir / "zephyr_ro.bin")
+ shutil.copy2(rw_dir / "zephyr" / self.rw_file, work_dir / "zephyr_rw.bin")
# Version in FRID/FWID can be at most 31 bytes long (32, minus
# one for null character).
@@ -166,14 +176,14 @@ class BinmanPacker(BasePacker):
encoding="utf-8",
)
- zmake.multiproc.log_output(self.logger, logging.DEBUG, proc.stdout)
- zmake.multiproc.log_output(self.logger, logging.ERROR, proc.stderr)
+ zmake.multiproc.LogWriter.log_output(self.logger, logging.DEBUG, proc.stdout)
+ zmake.multiproc.LogWriter.log_output(self.logger, logging.ERROR, proc.stderr)
if proc.wait(timeout=60):
raise OSError("Failed to run binman")
yield work_dir / "zephyr.bin", "zephyr.bin"
- yield ro / "zephyr" / "zephyr.elf", "zephyr.ro.elf"
- yield rw / "zephyr" / "zephyr.elf", "zephyr.rw.elf"
+ yield ro_dir / "zephyr" / "zephyr.elf", "zephyr.ro.elf"
+ yield rw_dir / "zephyr" / "zephyr.elf", "zephyr.rw.elf"
class NpcxPacker(BinmanPacker):
@@ -187,37 +197,39 @@ class NpcxPacker(BinmanPacker):
ro_file = "zephyr.npcx.bin"
npcx_monitor = "npcx_monitor.bin"
- def _get_max_image_bytes(self, ro, rw):
+ def _get_max_image_bytes(self, dir_map):
+ ro_dir = dir_map["ro"]
+ rw_dir = dir_map["rw"]
ro_size = util.read_kconfig_autoconf_value(
- ro / "zephyr" / "include" / "generated",
+ ro_dir / "zephyr" / "include" / "generated",
"CONFIG_PLATFORM_EC_FLASH_SIZE_BYTES",
)
rw_size = util.read_kconfig_autoconf_value(
- ro / "zephyr" / "include" / "generated",
+ rw_dir / "zephyr" / "include" / "generated",
"CONFIG_PLATFORM_EC_FLASH_SIZE_BYTES",
)
return max(int(ro_size, 0), int(rw_size, 0))
# This can probably be removed too and just rely on binman to
# check the sizes... see the comment above.
- def pack_firmware(self, work_dir, jobclient, ro, rw, version_string=""):
+ def pack_firmware(self, work_dir, jobclient, dir_map, version_string=""):
+ ro_dir = dir_map["ro"]
for path, output_file in super().pack_firmware(
work_dir,
jobclient,
- ro,
- rw,
+ dir_map,
version_string=version_string,
):
if output_file == "zephyr.bin":
yield (
- self._check_packed_file_size(path, {"ro": ro, "rw": rw}),
+ self._check_packed_file_size(path, dir_map),
"zephyr.bin",
)
else:
yield path, output_file
# Include the NPCX monitor file as an output artifact.
- yield ro / self.npcx_monitor, self.npcx_monitor
+ yield ro_dir / self.npcx_monitor, self.npcx_monitor
# A dictionary mapping packer config names to classes.
diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py
index b2232bb263..f52caa921d 100644
--- a/zephyr/zmake/zmake/project.py
+++ b/zephyr/zmake/zmake/project.py
@@ -6,11 +6,12 @@
import dataclasses
import logging
import pathlib
-from typing import Callable, Dict, List
+import typing
import zmake.build_config as build_config
import zmake.configlib as configlib
import zmake.modules
+import zmake.output_packers
import zmake.toolchains as toolchains
@@ -29,11 +30,14 @@ def module_dts_overlay_name(modpath, board_name):
@dataclasses.dataclass
class ProjectConfig:
+ """All the information needed to define a project."""
+
+ # pylint: disable=too-many-instance-attributes
project_name: str
zephyr_board: str
supported_toolchains: "list[str]"
output_packer: type
- modules: "list[str]" = dataclasses.field(
+ modules: "dict[str, typing.Any]" = dataclasses.field(
default_factory=lambda: zmake.modules.known_modules,
)
is_test: bool = dataclasses.field(default=False)
@@ -48,7 +52,7 @@ class Project:
def __init__(self, config: ProjectConfig):
self.config = config
- self.packer = self.config.output_packer(self)
+ self.packer: zmake.output_packers.BasePacker = self.config.output_packer(self)
def iter_builds(self):
"""Iterate thru the build combinations provided by the project's packer.
@@ -94,8 +98,7 @@ class Project:
return build_config.BuildConfig(
cmake_defs={"DTC_OVERLAY_FILE": ";".join(map(str, overlays))}
)
- else:
- return build_config.BuildConfig()
+ return build_config.BuildConfig()
def prune_modules(self, module_paths):
"""Reduce a modules dict to the ones required by this project.
@@ -129,6 +132,7 @@ class Project:
return result
def get_toolchain(self, module_paths, override=None):
+ """Get the first supported toolchain that is actually available."""
if override:
if override not in self.config.supported_toolchains:
logging.warning(
@@ -139,19 +143,18 @@ class Project:
override, toolchains.GenericToolchain
)
return support_class(name=override, modules=module_paths)
- else:
- for name in self.config.supported_toolchains:
- support_class = toolchains.support_classes[name]
- toolchain = support_class(name=name, modules=module_paths)
- if toolchain.probe():
- logging.info("Toolchain %r selected by probe function.", toolchain)
- return toolchain
- raise OSError(
- "No supported toolchains could be found on your system. If you see "
- "this message in the chroot, it indicates a bug. Otherwise, you'll "
- "either want to setup your system with a supported toolchain, or "
- "manually select an unsupported toolchain with the -t flag."
- )
+ for name in self.config.supported_toolchains:
+ support_class = toolchains.support_classes[name]
+ toolchain = support_class(name=name, modules=module_paths)
+ if toolchain.probe():
+ logging.info("Toolchain %r selected by probe function.", toolchain)
+ return toolchain
+ raise OSError(
+ "No supported toolchains could be found on your system. If you see "
+ "this message in the chroot, it indicates a bug. Otherwise, you'll "
+ "either want to setup your system with a supported toolchain, or "
+ "manually select an unsupported toolchain with the -t flag."
+ )
@dataclasses.dataclass
@@ -167,7 +170,7 @@ class ProjectRegistrationHandler:
"""
base_config: ProjectConfig
- register_func: Callable[[], "ProjectRegistrationHandler"]
+ register_func: typing.Callable[[], "ProjectRegistrationHandler"]
def variant(self, **kwargs) -> "ProjectRegistrationHandler":
"""Register a new variant based on the base config.
@@ -189,7 +192,7 @@ class ProjectRegistrationHandler:
return self.register_func(**new_config)
-def load_config_file(path) -> List[Project]:
+def load_config_file(path) -> typing.List[Project]:
"""Load a BUILD.py config file and create associated projects.
Args:
@@ -198,7 +201,7 @@ def load_config_file(path) -> List[Project]:
Returns:
A list of Project objects specified by the file.
"""
- projects: List[Project] = []
+ projects: typing.List[Project] = []
def register_project(**kwargs) -> ProjectRegistrationHandler:
config = ProjectConfig(**kwargs)
@@ -220,17 +223,17 @@ def load_config_file(path) -> List[Project]:
configlib.__file__,
"exec",
)
- exec(code, config_globals)
+ exec(code, config_globals) # pylint: disable=exec-used
# Next, load the BUILD.py
logging.debug("Loading config file %s", path)
code = compile(path.read_bytes(), str(path), "exec")
- exec(code, config_globals)
+ exec(code, config_globals) # pylint: disable=exec-used
logging.debug("Config file %s defines %s projects", path, len(projects))
return projects
-def find_projects(root_dir) -> Dict[str, Project]:
+def find_projects(root_dir) -> typing.Dict[str, Project]:
"""Finds all zmake projects in root_dir.
Args:
diff --git a/zephyr/zmake/zmake/toolchains.py b/zephyr/zmake/zmake/toolchains.py
index 13ee30de08..8ed1112e25 100644
--- a/zephyr/zmake/zmake/toolchains.py
+++ b/zephyr/zmake/zmake/toolchains.py
@@ -20,7 +20,8 @@ class GenericToolchain:
self.name = name
self.modules = modules or {}
- def probe(self): # pylint:disable=no-self-use
+ @staticmethod
+ def probe():
"""Probe if the toolchain is available on the system."""
# Since the toolchain is not known to zmake, we have no way to
# know if it's installed. Simply return False to indicate not
diff --git a/zephyr/zmake/zmake/util.py b/zephyr/zmake/zmake/util.py
index ee3b245b78..22d45d7deb 100644
--- a/zephyr/zmake/zmake/util.py
+++ b/zephyr/zmake/zmake/util.py
@@ -74,8 +74,8 @@ def read_kconfig_file(path):
A dictionary of kconfig items to their values.
"""
result = {}
- with open(path) as f:
- for line in f:
+ with open(path) as file:
+ for line in file:
line, _, _ = line.partition("#")
line = line.strip()
if line:
@@ -95,11 +95,12 @@ def read_kconfig_autoconf_value(path, key):
The value associated with the key or nothing if the key wasn't found.
"""
prog = re.compile(r"^#define\s{}\s(\S+)$".format(key))
- with open(path / "autoconf.h") as f:
- for line in f:
- m = prog.match(line)
- if m:
- return m.group(1)
+ with open(path / "autoconf.h") as file:
+ for line in file:
+ match = prog.match(line)
+ if match:
+ return match.group(1)
+ return None
def write_kconfig_file(path, config, only_if_changed=True):
@@ -114,9 +115,9 @@ def write_kconfig_file(path, config, only_if_changed=True):
if only_if_changed:
if path.exists() and read_kconfig_file(path) == config:
return
- with open(path, "w") as f:
+ with open(path, "w") as file:
for name, value in config.items():
- f.write("{}={}\n".format(name, value))
+ file.write("{}={}\n".format(name, value))
def read_zephyr_version(zephyr_base):
@@ -131,9 +132,9 @@ def read_zephyr_version(zephyr_base):
version_file = pathlib.Path(zephyr_base) / "VERSION"
file_vars = {}
- with open(version_file) as f:
- for line in f:
- key, sep, value = line.partition("=")
+ with open(version_file) as file:
+ for line in file:
+ key, _, value = line.partition("=")
file_vars[key.strip()] = value.strip()
return (
diff --git a/zephyr/zmake/zmake/version.py b/zephyr/zmake/zmake/version.py
index b2b897cf5b..2333ad46df 100644
--- a/zephyr/zmake/zmake/version.py
+++ b/zephyr/zmake/zmake/version.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Code to generate the ec_version.h file."""
+
import datetime
import getpass
import io
diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py
index 9b9a709aa9..53dd6575c8 100644
--- a/zephyr/zmake/zmake/zmake.py
+++ b/zephyr/zmake/zmake/zmake.py
@@ -11,7 +11,7 @@ import pathlib
import re
import shutil
import subprocess
-from typing import Dict, List
+from typing import Dict, List, Optional, Union
import zmake.build_config
import zmake.generate_readme
@@ -37,6 +37,7 @@ def ninja_stdout_log_level_override(line, current_log_level):
current_log_level: The active logging level that would be used for the
line.
"""
+ # pylint: disable=too-many-return-statements
# Output lines from Zephyr that are not normally useful
# Send any lines that start with these strings to INFO
cmake_suppress = [
@@ -105,7 +106,7 @@ def cmake_log_level_override(line, default_log_level):
# Strange output from Zephyr that we normally ignore
if line.startswith("Including boilerplate"):
return logging.DEBUG
- elif line.startswith("devicetree error:"):
+ if line.startswith("devicetree error:"):
return logging.ERROR
if ninja_warnings.match(line):
return logging.WARNING
@@ -149,17 +150,19 @@ class Zmake:
before launching more, False to just do this after all jobs complete
"""
- def __init__(
+ # pylint: disable=too-many-instance-attributes
+
+ def __init__( # pylint: disable=too-many-arguments
self,
checkout=None,
- jobserver=None,
+ jobserver: Optional[zmake.jobserver.JobClient] = None,
jobs=0,
goma=False,
gomacc="/mnt/host/depot_tools/.cipd_bin/gomacc",
modules_dir=None,
zephyr_base=None,
):
- zmake.multiproc.reset()
+ zmake.multiproc.LogWriter.reset()
self.logger = logging.getLogger(self.__class__.__name__)
self._checkout = checkout
self.goma = goma
@@ -187,6 +190,7 @@ class Zmake:
@property
def checkout(self):
+ """Returns the location of the cros checkout."""
if not self._checkout:
self._checkout = util.locate_cros_checkout()
return self._checkout.resolve()
@@ -200,7 +204,7 @@ class Zmake:
"""
found_projects = zmake.project.find_projects(self.module_paths["ec"] / "zephyr")
if all_projects:
- projects = found_projects.values()
+ projects = list(found_projects.values())
elif host_tests_only:
projects = [p for p in found_projects.values() if p.config.is_test]
else:
@@ -212,7 +216,7 @@ class Zmake:
raise KeyError("No project named {}".format(project_name)) from e
return projects
- def configure(
+ def configure( # pylint: disable=too-many-arguments,too-many-locals
self,
project_names,
build_dir=None,
@@ -253,33 +257,33 @@ class Zmake:
)
)
if self._sequential:
- rv = self.executor.wait()
- if rv:
- return rv
- rv = self.executor.wait()
- if rv:
- return rv
+ result = self.executor.wait()
+ if result:
+ return result
+ result = self.executor.wait()
+ if result:
+ return result
test_projects = [p for p in projects if p.config.is_test]
if len(test_projects) > 1 and coverage and test_after_configure:
- rv = self._merge_lcov_files(
+ result = self._merge_lcov_files(
projects=test_projects,
build_dir=build_dir,
output_file=build_dir / "all_tests.info",
)
- if rv:
- return rv
+ if result:
+ return result
non_test_projects = [p for p in projects if not p.config.is_test]
if len(non_test_projects) > 1 and coverage and build_after_configure:
- rv = self._merge_lcov_files(
+ result = self._merge_lcov_files(
projects=non_test_projects,
build_dir=build_dir,
output_file=build_dir / "all_builds.info",
)
- if rv:
- return rv
+ if result:
+ return result
return 0
- def build(
+ def build( # pylint: disable=too-many-arguments
self,
project_names,
build_dir=None,
@@ -307,7 +311,7 @@ class Zmake:
build_after_configure=True,
)
- def test(
+ def test( # pylint: disable=too-many-arguments,too-many-locals
self,
project_names,
build_dir=None,
@@ -362,23 +366,23 @@ class Zmake:
)
)
if self._sequential:
- rv = self.executor.wait()
- if rv:
- return rv
- rv = self.executor.wait()
- if rv:
- return rv
+ result = self.executor.wait()
+ if result:
+ return result
+ result = self.executor.wait()
+ if result:
+ return result
if len(test_projects) > 1 and coverage:
- rv = self._merge_lcov_files(
+ result = self._merge_lcov_files(
projects=test_projects,
build_dir=build_dir,
output_file=build_dir / "all_tests.info",
)
- if rv:
- return rv
+ if result:
+ return result
return 0
- def testall(
+ def testall( # pylint: disable=too-many-arguments
self,
build_dir=None,
toolchain=None,
@@ -387,6 +391,7 @@ class Zmake:
coverage=False,
allow_warnings=False,
):
+ """Locate and build all the projects."""
return self.test(
[],
build_dir=build_dir,
@@ -411,6 +416,8 @@ class Zmake:
allow_warnings=False,
extra_cflags=None,
):
+ # pylint: disable=too-many-arguments,too-many-locals,too-many-branches
+ # pylint: disable=too-many-statements
"""Set up a build directory to later be built by "zmake build"."""
# Resolve build_dir if needed.
if not build_dir:
@@ -487,7 +494,7 @@ class Zmake:
files_to_write = []
self.logger.info("Building %s in %s.", project.config.project_name, build_dir)
for build_name, build_config in project.iter_builds():
- config = (
+ config: zmake.build_config.BuildConfig = (
base_config
| toolchain_config
| module_config
@@ -507,8 +514,7 @@ class Zmake:
build_name,
)
continue
- else:
- config_json_file.unlink()
+ config_json_file.unlink()
files_to_write.append((config_json_file, config_json))
@@ -534,14 +540,14 @@ class Zmake:
errors="replace",
)
job_id = "{}:{}".format(project.config.project_name, build_name)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger,
logging.DEBUG,
proc.stdout,
log_level_override_func=cmake_log_level_override,
job_id=job_id,
)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger,
logging.ERROR,
proc.stderr,
@@ -567,14 +573,14 @@ class Zmake:
output_files = []
if build_after_configure or test_after_configure:
- rv = self._build(
+ result = self._build(
build_dir=build_dir,
project=project,
coverage=coverage,
output_files_out=output_files,
)
- if rv:
- return rv
+ if result:
+ return result
if test_after_configure and project.config.is_test:
gcov = "gcov.sh-not-found"
for build_name, _ in project.iter_builds():
@@ -601,6 +607,7 @@ class Zmake:
output_files_out=None,
coverage=False,
):
+ # pylint: disable=too-many-locals,too-many-branches
"""Build a pre-configured build directory."""
def wait_and_check_success(procs, writers):
@@ -668,7 +675,7 @@ class Zmake:
"Building %s:%s: %s",
project.config.project_name,
build_name,
- zmake.util.repr_command(cmd),
+ util.repr_command(cmd),
)
proc = self.jobserver.popen(
cmd,
@@ -680,7 +687,7 @@ class Zmake:
job_id = "{}:{}".format(project.config.project_name, build_name)
dirs[build_name].mkdir(parents=True, exist_ok=True)
build_log = open(dirs[build_name] / "build.log", "w")
- out = zmake.multiproc.log_output(
+ out = zmake.multiproc.LogWriter.log_output(
logger=self.logger,
log_level=logging.INFO,
file_descriptor=proc.stdout,
@@ -688,7 +695,7 @@ class Zmake:
job_id=job_id,
tee_output=build_log,
)
- err = zmake.multiproc.log_output(
+ err = zmake.multiproc.LogWriter.log_output(
self.logger,
logging.ERROR,
proc.stderr,
@@ -708,9 +715,9 @@ class Zmake:
# Run the packer.
packer_work_dir = build_dir / "packer"
output_dir = build_dir / "output"
- for d in output_dir, packer_work_dir:
- if not d.exists():
- d.mkdir()
+ for newdir in output_dir, packer_work_dir:
+ if not newdir.exists():
+ newdir.mkdir()
if output_files_out is None:
output_files_out = []
@@ -723,7 +730,7 @@ class Zmake:
)
else:
for output_file, output_name in project.packer.pack_firmware(
- packer_work_dir, self.jobserver, version_string=version_string, **dirs
+ packer_work_dir, self.jobserver, dirs, version_string=version_string
):
shutil.copy2(output_file, output_dir / output_name)
self.logger.debug("Output file '%s' created.", output_file)
@@ -731,7 +738,7 @@ class Zmake:
return 0
- def _run_test(
+ def _run_test( # pylint: disable=too-many-arguments
self, elf_file: pathlib.Path, coverage, gcov, build_dir, lcov_file, timeout=None
):
"""Run a single test, with goma if enabled.
@@ -760,13 +767,13 @@ class Zmake:
errors="replace",
)
job_id = "test {}".format(elf_file)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger,
logging.DEBUG,
proc.stdout,
job_id=job_id,
)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger,
logging.ERROR,
proc.stderr,
@@ -791,7 +798,9 @@ class Zmake:
with self.jobserver.get_job():
_run()
- def _run_lcov(self, build_dir, lcov_file, initial=False, gcov=""):
+ def _run_lcov(
+ self, build_dir, lcov_file, initial=False, gcov: Union[os.PathLike, str] = ""
+ ):
gcov = os.path.abspath(gcov)
if initial:
self.logger.info("Running (initial) lcov on %s.", build_dir)
@@ -821,7 +830,7 @@ class Zmake:
encoding="utf-8",
errors="replace",
)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger,
logging.WARNING,
proc.stderr,
@@ -864,21 +873,21 @@ class Zmake:
encoding="utf-8",
errors="replace",
)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger, logging.ERROR, proc.stderr, job_id="lcov"
)
- zmake.multiproc.log_output(
+ zmake.multiproc.LogWriter.log_output(
self.logger, logging.DEBUG, proc.stdout, job_id="lcov"
)
if proc.wait():
raise OSError(get_process_failure_msg(proc))
return 0
- def list_projects(self, format, search_dir):
+ def list_projects(self, fmt, search_dir):
"""List project names known to zmake on stdout.
Args:
- format: The formatting string to print projects with.
+ fmt: The formatting string to print projects with.
search_dir: Directory to start the search for
BUILD.py files at.
"""
@@ -886,7 +895,7 @@ class Zmake:
search_dir = self.module_paths["ec"] / "zephyr"
for project in zmake.project.find_projects(search_dir).values():
- print(format.format(config=project.config), end="")
+ print(fmt.format(config=project.config), end="")
return 0