summaryrefslogtreecommitdiff
path: root/zephyr
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr')
-rw-r--r--zephyr/CMakeLists.txt2
-rw-r--r--zephyr/Kconfig.ap_power9
-rw-r--r--zephyr/Kconfig.cbi1
-rw-r--r--zephyr/Kconfig.defaults3
-rw-r--r--zephyr/Kconfig.header2
-rw-r--r--zephyr/Kconfig.led1
-rw-r--r--zephyr/Kconfig.motionsense6
-rw-r--r--zephyr/Kconfig.pd_vbus_detection6
-rw-r--r--zephyr/Kconfig.powerseq17
-rw-r--r--zephyr/Kconfig.watchdog2
-rw-r--r--zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x15
-rw-r--r--zephyr/app/ec/soc/Kconfig2
-rw-r--r--zephyr/boards/arm/mec1727/mec1727.dts3
-rw-r--r--zephyr/boards/arm/npcx9/npcx9.dtsi29
-rwxr-xr-xzephyr/firmware_builder.py14
-rw-r--r--zephyr/include/cros/microchip/mec1727.dtsi69
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_common.h2
-rw-r--r--zephyr/projects/brya/keyboard.dts28
-rw-r--r--zephyr/projects/brya/prj.conf2
-rw-r--r--zephyr/projects/corsola/BUILD.py3
-rw-r--r--zephyr/projects/corsola/gpio_kingler.dts2
-rw-r--r--zephyr/projects/corsola/gpio_steelix.dts2
-rw-r--r--zephyr/projects/corsola/i2c_kingler.dts1
-rw-r--r--zephyr/projects/corsola/interrupts_kingler.dts5
-rw-r--r--zephyr/projects/corsola/interrupts_krabby.dts7
-rw-r--r--zephyr/projects/corsola/led_steelix.dts39
-rw-r--r--zephyr/projects/corsola/motionsense_krabby.dts4
-rw-r--r--zephyr/projects/corsola/motionsense_steelix.dts17
-rw-r--r--zephyr/projects/corsola/npcx_keyboard.dts32
-rw-r--r--zephyr/projects/corsola/prj.conf2
-rw-r--r--zephyr/projects/corsola/prj_kingler.conf7
-rw-r--r--zephyr/projects/corsola/prj_steelix.conf8
-rw-r--r--zephyr/projects/corsola/src/kingler/led_steelix.c118
-rw-r--r--zephyr/projects/corsola/src/kingler/usbc_config.c6
-rw-r--r--zephyr/projects/corsola/src/usb_pd_policy.c3
-rw-r--r--zephyr/projects/herobrine/BUILD.py6
-rw-r--r--zephyr/projects/herobrine/CMakeLists.txt2
-rw-r--r--zephyr/projects/herobrine/gpio_hoglin.dts10
-rw-r--r--zephyr/projects/herobrine/keyboard.dts28
-rw-r--r--zephyr/projects/herobrine/led_pins_hoglin.dts33
-rw-r--r--zephyr/projects/herobrine/led_pins_villager.dts (renamed from zephyr/projects/herobrine/gpio_led_villager.dts)0
-rw-r--r--zephyr/projects/herobrine/led_policy_hoglin.dts97
-rw-r--r--zephyr/projects/herobrine/led_policy_villager.dts (renamed from zephyr/projects/herobrine/led_villager.dts)5
-rw-r--r--zephyr/projects/herobrine/prj.conf6
-rw-r--r--zephyr/projects/herobrine/prj_herobrine.conf4
-rw-r--r--zephyr/projects/herobrine/prj_hoglin.conf1
-rw-r--r--zephyr/projects/herobrine/prj_villager.conf3
-rw-r--r--zephyr/projects/herobrine/src/led.c175
-rw-r--r--zephyr/projects/intelrvp/BUILD.py3
-rw-r--r--zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/keyboard.dts28
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/battery.dts15
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/keyboard.dts59
-rw-r--r--zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx_power_signals.dts9
-rw-r--r--zephyr/projects/nissa/BUILD.py25
-rw-r--r--zephyr/projects/nissa/CMakeLists.txt12
-rw-r--r--zephyr/projects/nissa/Kconfig6
-rw-r--r--zephyr/projects/nissa/craask_keyboard.dts32
-rw-r--r--zephyr/projects/nissa/nivviks_keyboard.dts30
-rw-r--r--zephyr/projects/nissa/nivviks_overlay.dts9
-rw-r--r--zephyr/projects/nissa/prj.conf1
-rw-r--r--zephyr/projects/nissa/prj_nereid.conf4
-rw-r--r--zephyr/projects/nissa/prj_pujjo.conf40
-rw-r--r--zephyr/projects/nissa/pujjo_generated.dts290
-rw-r--r--zephyr/projects/nissa/pujjo_keyboard.dts48
-rw-r--r--zephyr/projects/nissa/pujjo_motionsense.dts163
-rw-r--r--zephyr/projects/nissa/pujjo_overlay.dts347
-rw-r--r--zephyr/projects/nissa/pujjo_power_signals.dts220
-rw-r--r--zephyr/projects/nissa/pujjo_pwm_leds.dts63
-rw-r--r--zephyr/projects/nissa/src/craask/led.c1
-rw-r--r--zephyr/projects/nissa/src/craask/usbc.c13
-rw-r--r--zephyr/projects/nissa/src/led.c2
-rw-r--r--zephyr/projects/nissa/src/nereid/usbc.c27
-rw-r--r--zephyr/projects/nissa/src/nivviks/usbc.c13
-rw-r--r--zephyr/projects/nissa/src/pujjo/charger.c56
-rw-r--r--zephyr/projects/nissa/src/pujjo/fan.c45
-rw-r--r--zephyr/projects/nissa/src/pujjo/keyboard.c29
-rw-r--r--zephyr/projects/nissa/src/pujjo/usbc.c281
-rw-r--r--zephyr/projects/npcx_evb/npcx9/keyboard.dts28
-rw-r--r--zephyr/projects/skyrim/include/gpio_map.h1
-rw-r--r--zephyr/projects/skyrim/keyboard.dts28
-rw-r--r--zephyr/projects/skyrim/prj.conf2
-rw-r--r--zephyr/projects/skyrim/usbc_config.c72
-rw-r--r--zephyr/shim/chip/mchp/include/flash_chip.h16
-rw-r--r--zephyr/shim/chip/mchp/system.c23
-rw-r--r--zephyr/shim/chip/mchp/system_download_from_flash.c18
-rw-r--r--zephyr/shim/chip/mchp/system_external_storage.c89
-rw-r--r--zephyr/shim/include/config_chip.h5
-rw-r--r--zephyr/shim/src/CMakeLists.txt2
-rw-r--r--zephyr/shim/src/chipset_api.c32
-rw-r--r--zephyr/shim/src/console.c3
-rw-r--r--zephyr/shim/src/led_driver/led.h5
-rw-r--r--zephyr/shim/src/led_driver/led_gpio.c19
-rw-r--r--zephyr/shim/src/watchdog.c5
-rw-r--r--zephyr/subsys/ap_pwrseq/power_signals.c2
-rw-r--r--zephyr/subsys/ap_pwrseq/x86_non_dsx_mtl_pwrseq_sm.c33
-rw-r--r--zephyr/test/drivers/BUILD.py9
-rw-r--r--zephyr/test/drivers/CMakeLists.txt3
-rw-r--r--zephyr/test/drivers/led_driver/CMakeLists.txt20
-rw-r--r--zephyr/test/drivers/led_driver/led_pins.dts54
-rw-r--r--zephyr/test/drivers/led_driver/led_policy.dts215
-rw-r--r--zephyr/test/drivers/led_driver/prj.conf6
-rw-r--r--zephyr/test/drivers/led_driver/src/led.c69
-rw-r--r--zephyr/test/drivers/overlay.dts18
-rw-r--r--zephyr/test/drivers/src/espi.c21
-rw-r--r--zephyr/test/drivers/src/integration/usbc/usb_alt_mode.c6
-rw-r--r--zephyr/test/drivers/src/ppc_syv682c.c717
-rw-r--r--zephyr/test/drivers/src/ppc_syv682x.c804
-rw-r--r--zephyr/test/drivers/src/watchdog.c18
-rw-r--r--zephyr/zmake/tests/test_version.py2
-rw-r--r--zephyr/zmake/zmake/output_packers.py2
-rw-r--r--zephyr/zmake/zmake/version.py1
111 files changed, 3867 insertions, 1191 deletions
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index cf2a9645ce..451406c8b3 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -533,6 +533,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_MATH_UTIL
"${PLATFORM_EC}/common/math_util.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_MAX695X_SEVEN_SEGMENT_DISPLAY
"${PLATFORM_EC}/driver/led/max695x.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_DRIVER_TLC59116F
+ "${PLATFORM_EC}/driver/led/tlc59116f.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
diff --git a/zephyr/Kconfig.ap_power b/zephyr/Kconfig.ap_power
index 3db5a1fef8..03c92759f0 100644
--- a/zephyr/Kconfig.ap_power
+++ b/zephyr/Kconfig.ap_power
@@ -2,6 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+config AP_POWER_CONTROL
+ bool
+ default y if PLATFORM_EC_POWERSEQ || AP_PWRSEQ
+ help
+ Whether the EC has control over AP power states.
+
+ This is automatically enabled if an implementation of AP power
+ sequencing is enabled.
+
menuconfig PLATFORM_EC_BOOT_AP_POWER_REQUIREMENTS
bool "Power requirements to boot AP"
default y
diff --git a/zephyr/Kconfig.cbi b/zephyr/Kconfig.cbi
index 0ab5025a97..962392e56c 100644
--- a/zephyr/Kconfig.cbi
+++ b/zephyr/Kconfig.cbi
@@ -18,7 +18,6 @@ config PLATFORM_EC_EEPROM_CBI_WP
Define this if the EC can independently set the CBI EEPROM WP
signal. The accompanying hardware must ensure that the CBI WP gets
latched and is only reset when EC_RST_ODL is asserted.
- select PLATFORM_EC_BYPASS_CBI_EEPROM_WP_CHECK
choice PLATFORM_EC_CBI_STORAGE_TYPE
prompt "Select CBI storage Type"
diff --git a/zephyr/Kconfig.defaults b/zephyr/Kconfig.defaults
index faea48adef..a92971b3c7 100644
--- a/zephyr/Kconfig.defaults
+++ b/zephyr/Kconfig.defaults
@@ -21,7 +21,4 @@ config THREAD_MAX_NAME_LEN
config SHELL_PROMPT_UART
default "ec:~$ "
-config LEGACY_INCLUDE_PATH
- default n
-
orsource "Kconfig.defaults-$(ARCH)"
diff --git a/zephyr/Kconfig.header b/zephyr/Kconfig.header
index e5c137b99e..931d7dbaf1 100644
--- a/zephyr/Kconfig.header
+++ b/zephyr/Kconfig.header
@@ -16,6 +16,7 @@ config PLATFORM_EC_RO_HEADER
config PLATFORM_EC_RO_HEADER_OFFSET
hex "Offset in memory for the location of the header"
+ default 0x1000 if SOC_SERIES_MEC172X
default 0x0
help
The offset (in bytes) of the header relative to the start address of
@@ -24,7 +25,6 @@ config PLATFORM_EC_RO_HEADER_OFFSET
config PLATFORM_EC_RO_HEADER_SIZE
hex "Size of the RO header"
default 0x40 if SOC_FAMILY_NPCX
- default 0x140 if SOC_SERIES_MEC172X
default 0x0
help
The size of the RO header in bytes. This values should come from the
diff --git a/zephyr/Kconfig.led b/zephyr/Kconfig.led
index 785aa64f89..03f2ebed56 100644
--- a/zephyr/Kconfig.led
+++ b/zephyr/Kconfig.led
@@ -3,6 +3,7 @@
# found in the LICENSE file.
menuconfig PLATFORM_EC_LED_COMMON
+ depends on !PLATFORM_EC_LED_DT
bool "LED Support"
help
Enable the common LED module supporting automatic control of the
diff --git a/zephyr/Kconfig.motionsense b/zephyr/Kconfig.motionsense
index f76e11dbc0..abfdacc5be 100644
--- a/zephyr/Kconfig.motionsense
+++ b/zephyr/Kconfig.motionsense
@@ -61,6 +61,12 @@ config PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS
# if PLATFORM_EC_MOTION_FILL_LPC_SENSE_DATA
#endif # PLATFORM_EC_MOTION_FILL_LPC_SENSE_DATA
+config PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ
+ int "Maximal EC sampling rate"
+ default 250000
+ help
+ Lower this limit for slower EC (in mHz).
+
config PLATFORM_EC_ALS
bool "Ambient Light Sensor(ALS)"
help
diff --git a/zephyr/Kconfig.pd_vbus_detection b/zephyr/Kconfig.pd_vbus_detection
index f3f410c9dc..019eca654a 100644
--- a/zephyr/Kconfig.pd_vbus_detection
+++ b/zephyr/Kconfig.pd_vbus_detection
@@ -5,10 +5,6 @@
if PLATFORM_EC_USBC
if PLATFORM_EC_USB_POWER_DELIVERY
-choice PLATFORM_EC_USB_PD_VBUS_DETECTION_TYPE
- prompt "Select the method to detect VBUS"
- default PLATFORM_EC_USB_PD_VBUS_DETECT_NONE
-
config PLATFORM_EC_USB_PD_VBUS_DETECT_NONE
bool "No way to detect VBUS"
help
@@ -32,7 +28,5 @@ config PLATFORM_EC_USB_PD_VBUS_DETECT_PPC
Choose this option if the Power-Path Controller (PPC) can detect the
presence of VBUS
-endchoice # PLATFORM_EC_USB_PD_VBUS_DETECTION_TYPE
-
endif # PLATFORM_EC_USB_POWER_DELIVERY
endif # PLATFORM_EC_USBC
diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq
index cee5be53a4..f0db496082 100644
--- a/zephyr/Kconfig.powerseq
+++ b/zephyr/Kconfig.powerseq
@@ -5,6 +5,7 @@
menuconfig PLATFORM_EC_POWERSEQ
bool "Power sequencing"
depends on AP
+ depends on !AP_PWRSEQ
select HAS_TASK_CHIPSET
help
Enable shimming the platform/ec AP power sequencing code. This
@@ -15,6 +16,14 @@ menuconfig PLATFORM_EC_POWERSEQ
if PLATFORM_EC_POWERSEQ
+config PLATFORM_EC_POWERSEQ_S0IX
+ bool "Enable S0ix sleep states"
+ select PLATFORM_EC_POWERSEQ_HOST_SLEEP
+ help
+ Enable the CONFIG_POWER_S0IX platform/ec configuration
+ option, Intel's low-power idle sleep state, also known as
+ "modern sleep".
+
config PLATFORM_EC_POWERSEQ_HOST_SLEEP
bool "Track host sleep states"
help
@@ -120,14 +129,6 @@ config PLATFORM_EC_POWERSEQ_RTC_RESET
gpio_map.h, which can be used to reset the AP's RTC when set
high.
-config PLATFORM_EC_POWERSEQ_S0IX
- bool "Enable S0ix sleep states"
- select PLATFORM_EC_POWERSEQ_HOST_SLEEP
- help
- Enable the CONFIG_POWER_S0IX platform/ec configuration
- option, Intel's low-power idle sleep state, also known as
- "modern sleep".
-
config PLATFORM_EC_POWERSEQ_S4
bool "Advertise S4 residency"
depends on PLATFORM_EC_ESPI_VW_SLP_S5
diff --git a/zephyr/Kconfig.watchdog b/zephyr/Kconfig.watchdog
index e1a51c29eb..57d93d7c39 100644
--- a/zephyr/Kconfig.watchdog
+++ b/zephyr/Kconfig.watchdog
@@ -14,7 +14,7 @@ config PLATFORM_EC_WATCHDOG_PERIOD_MS
config PLATFORM_EC_WATCHDOG_WARNING_LEADING_TIME_MS
int "Leading time of the watchdog warning timer in ms"
default 500
- depends on !WDT_NPCX && !WDT_ITE_IT8XXX2 && !WDT_XEC
+ depends on !WDT_NPCX && !WDT_ITE_IT8XXX2
help
Set the leading time of the watchdog warning timer. Chromium EC system
uses an auxiliary timer to handle the system warning event. The
diff --git a/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x b/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x
index 998116c243..9e37b6a534 100644
--- a/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x
+++ b/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x
@@ -20,16 +20,18 @@ if SOC_SERIES_MEC172X
config CROS_EC_PROGRAM_MEMORY_BASE
default 0xc0000
+# Data SRAM base
config CROS_EC_RAM_BASE
- default 0xc0000
+ default 0x118000
-# Data size: 64K - 2K, top 1KB is persistent
+# Total data SRAM size
config CROS_EC_DATA_RAM_SIZE
- default 0x00F800
+ default 0x010000
-# Code + Data: Top 1KB is peristent
+# Top 2KB reserved for PUF leaving 62KB
+# 61KB for data + 1KB persistent across chip reset.
config CROS_EC_RAM_SIZE
- default 0x067800
+ default 0x00f800
config FLASH_SIZE
default 512
@@ -37,8 +39,9 @@ config FLASH_SIZE
config CROS_EC_RO_MEM_OFF
default 0x0
+# was 0x40000
config CROS_EC_RO_SIZE
- default 0x40000
+ default 0x3F000
# RW firmware in program memory - Identical to RO, only one image loaded at a
# time.
diff --git a/zephyr/app/ec/soc/Kconfig b/zephyr/app/ec/soc/Kconfig
index 7789ad7866..9d3c851a36 100644
--- a/zephyr/app/ec/soc/Kconfig
+++ b/zephyr/app/ec/soc/Kconfig
@@ -34,7 +34,7 @@ config AP_X86_INTEL_ADL
config AP_X86_AMD
bool "AP is an AMD chipset"
- select AP_x86
+ select AP_X86
help
The application processor is a product of AMD.
diff --git a/zephyr/boards/arm/mec1727/mec1727.dts b/zephyr/boards/arm/mec1727/mec1727.dts
index c88e61b692..d371f8a2dc 100644
--- a/zephyr/boards/arm/mec1727/mec1727.dts
+++ b/zephyr/boards/arm/mec1727/mec1727.dts
@@ -8,8 +8,7 @@
#include <cros/microchip/mec1727.dtsi>
#include <cros/thermistor/thermistor.dtsi>
#include <dt-bindings/gpio_defines.h>
-#include <microchip/mec172xnsz.dtsi>
-#include <microchip/mec172x/mec172xnsz-pinctrl.dtsi>
+#include <microchip/mec1727nsz.dtsi>
/ {
model = "MEC1727";
diff --git a/zephyr/boards/arm/npcx9/npcx9.dtsi b/zephyr/boards/arm/npcx9/npcx9.dtsi
index 4b43bda08a..27ece8cdd6 100644
--- a/zephyr/boards/arm/npcx9/npcx9.dtsi
+++ b/zephyr/boards/arm/npcx9/npcx9.dtsi
@@ -56,32 +56,3 @@
pinmux-gpio;
};
};
-
-&cros_kb_raw {
- status = "okay";
- /* No KSO2 (it's inverted and implemented by GPIO) */
- pinctrl-0 = <&ksi0_gp31
- &ksi1_gp30
- &ksi2_gp27
- &ksi3_gp26
- &ksi4_gp25
- &ksi5_gp24
- &ksi6_gp23
- &ksi7_gp22
- &kso00_gp21
- &kso01_gp20
- &kso03_gp16
- &kso04_gp15
- &kso05_gp14
- &kso06_gp13
- &kso07_gp12
- &kso08_gp11
- &kso09_gp10
- &kso10_gp07
- &kso11_gp06
- &kso12_gp05
- &kso13_gp04
- &kso14_gp82
- >;
- pinctrl-names = "default";
-};
diff --git a/zephyr/firmware_builder.py b/zephyr/firmware_builder.py
index 1a8ce32469..21767d635a 100755
--- a/zephyr/firmware_builder.py
+++ b/zephyr/firmware_builder.py
@@ -193,7 +193,7 @@ def test(opts):
cmd = [
'/usr/bin/lcov',
'-o',
- build_dir / 'fullpaths.info',
+ build_dir / 'lcov.info',
'--rc',
'lcov_branch_coverage=1',
'-a',
@@ -211,18 +211,6 @@ def test(opts):
cwd=pathlib.Path(__file__).parent, check=True,
stdout=subprocess.PIPE, universal_newlines=True).stdout
_extract_lcov_summary('EC_ZEPHYR_TESTS', metrics, output)
- # Make filenames relative to platform/ec
- cmd = ['sed', '-e', 's|^SF:.*/platform/ec/|SF:|']
- with open(build_dir / 'fullpaths.info') as infile, open(
- build_dir / 'lcov.info', 'w'
- ) as outfile:
- subprocess.run(
- cmd,
- cwd=pathlib.Path(__file__).parent,
- stdin=infile,
- stdout=outfile,
- check=True,
- )
with open(opts.metrics, 'w') as file:
file.write(json_format.MessageToJson(metrics))
diff --git a/zephyr/include/cros/microchip/mec1727.dtsi b/zephyr/include/cros/microchip/mec1727.dtsi
index b388f456d2..340cff1956 100644
--- a/zephyr/include/cros/microchip/mec1727.dtsi
+++ b/zephyr/include/cros/microchip/mec1727.dtsi
@@ -5,13 +5,76 @@
/dts-v1/;
-#include <cros/microchip/mec172x.dtsi>
+#include <cros/binman.dtsi>
+#include <microchip/mec1727nsz.dtsi>
/ {
+ chosen {
+ cros-ec,adc = &adc0;
+ cros-ec,bbram = &bbram;
+ cros-ec,espi = &espi0;
+ cros-ec,flash = &flash1;
+ cros-ec,flash-controller = &fiu0;
+ cros-ec,raw-kb = &cros_kb_raw;
+ cros-ec,watchdog = &wdog;
+ cros,rtc = &crtc;
+ };
- soc {
+ named-bbram-regions {
+ compatible = "named-bbram-regions";
+ scratchpad {
+ offset = <0x00>;
+ size = <0x04>;
+ };
+ saved-reset-flags {
+ offset = <0x04>;
+ size = <0x04>;
+ };
+ wake {
+ offset = <0x08>;
+ size = <0x04>;
+ };
+ pd0 {
+ offset = <0x0c>;
+ size = <0x01>;
+ };
+ pd1 {
+ offset = <0x0d>;
+ size = <0x01>;
+ };
+ try_slot {
+ offset = <0x0e>;
+ size = <0x01>;
+ };
+ pd2 {
+ offset = <0x0f>;
+ size = <0x01>;
+ };
+ ramlog {
+ offset = <0x20>;
+ size = <0x01>;
+ };
+ panic_flags {
+ offset = <0x23>;
+ size = <0x01>;
+ };
+ panic_bkup {
+ offset = <0x24>;
+ size = <0x1c>;
+ };
+ lct_time {
+ offset = <0x40>;
+ size = <0x04>;
+ };
+ ec_img_load {
+ offset = <0x44>;
+ size = <0x01>;
+ };
};
+ fiu0: cros-flash {
+ compatible = "microchip,xec-cros-flash";
+ label = "INTERNAL_FLASH";
+ };
};
-
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
index 0c74f4b4ce..4988c48576 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
@@ -347,7 +347,7 @@ int tcpci_partner_send_control_msg(struct tcpci_partner_data *data,
* @param type Type of message
* @param data_obj Pointer to array of data objects
* @param data_obj_num Number of data objects
- * @param delay Optional delay
+ * @param delay Optional delay in milliseconds
*
* @return TCPCI_EMUL_TX_SUCCESS on success
* @return TCPCI_EMUL_TX_FAILED when TCPCI is configured to not handle
diff --git a/zephyr/projects/brya/keyboard.dts b/zephyr/projects/brya/keyboard.dts
index 88b8ba8c65..4f06764810 100644
--- a/zephyr/projects/brya/keyboard.dts
+++ b/zephyr/projects/brya/keyboard.dts
@@ -16,3 +16,31 @@
pinctrl-0 = <&pwm3_gp80>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/brya/prj.conf b/zephyr/projects/brya/prj.conf
index 931053c5f2..7ce897ae5f 100644
--- a/zephyr/projects/brya/prj.conf
+++ b/zephyr/projects/brya/prj.conf
@@ -92,7 +92,7 @@ CONFIG_PLATFORM_EC_HIBERNATE_PSL=y
# MKBP event
CONFIG_PLATFORM_EC_MKBP_EVENT=y
CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y
-CONFIG_PLATFORM_EC_MKBP_USE_HOST_EVENT=y
+CONFIG_PLATFORM_EC_MKBP_USE_GPIO_AND_HOST_EVENT=y
# PMIC
CONFIG_PLATFORM_EC_PMIC=y
diff --git a/zephyr/projects/corsola/BUILD.py b/zephyr/projects/corsola/BUILD.py
index c75418f294..83ad865cb1 100644
--- a/zephyr/projects/corsola/BUILD.py
+++ b/zephyr/projects/corsola/BUILD.py
@@ -58,6 +58,7 @@ register_corsola_project(
here / "interrupts_kingler.dts",
here / "cbi_eeprom.dts",
here / "gpio_kingler.dts",
+ here / "npcx_keyboard.dts",
here / "led_kingler.dts",
here / "motionsense_kingler.dts",
here / "usbc_kingler.dts",
@@ -77,8 +78,10 @@ register_corsola_project(
here / "interrupts_kingler.dts",
here / "cbi_eeprom.dts",
here / "gpio_steelix.dts",
+ here / "npcx_keyboard.dts",
here / "led_steelix.dts",
here / "motionsense_kingler.dts",
+ here / "motionsense_steelix.dts",
here / "usba_steelix.dts",
here / "usbc_kingler.dts",
here / "default_gpio_pinctrl_kingler.dts",
diff --git a/zephyr/projects/corsola/gpio_kingler.dts b/zephyr/projects/corsola/gpio_kingler.dts
index 6ef6f02e03..0199f985fa 100644
--- a/zephyr/projects/corsola/gpio_kingler.dts
+++ b/zephyr/projects/corsola/gpio_kingler.dts
@@ -91,7 +91,7 @@
lid_accel_int_l {
gpios = <&gpiob 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>;
};
- tablet_mode_l {
+ gpio_tablet_mode_l: tablet_mode_l {
gpios = <&gpiob 2 GPIO_INPUT>;
enum-name = "GPIO_TABLET_MODE_L";
};
diff --git a/zephyr/projects/corsola/gpio_steelix.dts b/zephyr/projects/corsola/gpio_steelix.dts
index 29c1bbe75a..3e0375564f 100644
--- a/zephyr/projects/corsola/gpio_steelix.dts
+++ b/zephyr/projects/corsola/gpio_steelix.dts
@@ -98,7 +98,7 @@
lid_accel_int_l {
gpios = <&gpiob 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>;
};
- tablet_mode_l {
+ gpio_tablet_mode_l: tablet_mode_l {
gpios = <&gpiob 2 GPIO_INPUT>;
enum-name = "GPIO_TABLET_MODE_L";
};
diff --git a/zephyr/projects/corsola/i2c_kingler.dts b/zephyr/projects/corsola/i2c_kingler.dts
index 843367668e..c832e55d2e 100644
--- a/zephyr/projects/corsola/i2c_kingler.dts
+++ b/zephyr/projects/corsola/i2c_kingler.dts
@@ -17,6 +17,7 @@
};
i2c_usb_c0: usb-c0 {
i2c-port = <&i2c1_0>;
+ remote-port = <7>;
enum-name = "I2C_PORT_USB_C0";
};
i2c_usb_c1: usb-c1 {
diff --git a/zephyr/projects/corsola/interrupts_kingler.dts b/zephyr/projects/corsola/interrupts_kingler.dts
index ac7da13e75..b33251624d 100644
--- a/zephyr/projects/corsola/interrupts_kingler.dts
+++ b/zephyr/projects/corsola/interrupts_kingler.dts
@@ -100,5 +100,10 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "bmi3xx_interrupt";
};
+ int_tablet_mode: tablet_mode {
+ irq-pin = <&gpio_tablet_mode_l>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "gmr_tablet_switch_isr";
+ };
};
};
diff --git a/zephyr/projects/corsola/interrupts_krabby.dts b/zephyr/projects/corsola/interrupts_krabby.dts
index ddc9639d2b..900ce1611e 100644
--- a/zephyr/projects/corsola/interrupts_krabby.dts
+++ b/zephyr/projects/corsola/interrupts_krabby.dts
@@ -61,7 +61,7 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "icm42607_interrupt";
};
- int_accel: accel {
+ int_lid_imu: lid_imu {
irq-pin = <&lid_accel_int_l>;
flags = <GPIO_INT_EDGE_FALLING>;
handler = "lis2dw12_interrupt";
@@ -91,11 +91,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "x_ec_interrupt";
};
- int_base_imu: base_imu {
- irq-pin = <&base_imu_int_l>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "icm42607_interrupt";
- };
int_usb_c0_ppc_bc12: usb_c0_ppc_bc12 {
irq-pin = <&usb_c0_ppc_bc12_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/projects/corsola/led_steelix.dts b/zephyr/projects/corsola/led_steelix.dts
index 56a54862e6..31d17958d4 100644
--- a/zephyr/projects/corsola/led_steelix.dts
+++ b/zephyr/projects/corsola/led_steelix.dts
@@ -6,31 +6,14 @@
/ {
pwmleds {
compatible = "pwm-leds";
- pwm_led0: pwm_led_0 {
- pwms = <&pwm0 0 PWM_HZ(100) PWM_POLARITY_INVERTED
- &pwm1 0 PWM_HZ(100) PWM_POLARITY_INVERTED
- &pwm2 0 PWM_HZ(100) PWM_POLARITY_INVERTED>;
+ led_battery_red: ec_led1_odl {
+ pwms = <&pwm0 0 PWM_HZ(100) PWM_POLARITY_INVERTED>;
};
- };
-
- cros-pwmleds {
- compatible = "cros-ec,pwm-leds";
-
- leds = <&pwm_led0>;
- frequency = <100>;
-
- color-map-red = <100 0 0>;
- color-map-green = < 0 100 0>;
- color-map-amber = <100 20 0>;
-
- brightness-range = <255 255 0 0 0 255>;
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- pwm_led_0@0 {
- reg = <0>;
- ec-led-name = "EC_LED_ID_BATTERY_LED";
+ led_battery_green: ec_led2_odl {
+ pwms = <&pwm1 0 PWM_HZ(100) PWM_POLARITY_INVERTED>;
+ };
+ led_power_white: ec_led3_odl {
+ pwms = <&pwm4 0 PWM_HZ(100) PWM_POLARITY_INVERTED>;
};
};
};
@@ -59,14 +42,14 @@
pinctrl-names = "default";
};
-/* Blue LED */
-&pwm2_gpc4 {
+/* White LED */
+&pwm4_gpb6 {
drive-open-drain;
};
-&pwm2 {
+&pwm4 {
status = "okay";
clock-bus = "NPCX_CLOCK_BUS_LFCLK";
- pinctrl-0 = <&pwm2_gpc4>;
+ pinctrl-0 = <&pwm4_gpb6>;
pinctrl-names = "default";
};
diff --git a/zephyr/projects/corsola/motionsense_krabby.dts b/zephyr/projects/corsola/motionsense_krabby.dts
index 730f1a938e..d369db460a 100644
--- a/zephyr/projects/corsola/motionsense_krabby.dts
+++ b/zephyr/projects/corsola/motionsense_krabby.dts
@@ -150,8 +150,6 @@
* list of GPIO interrupts that have to
* be enabled at initial stage
*/
- sensor-irqs = <&int_base_imu>;
- /* list of sensors in force mode */
- accel-force-mode-sensors = <&lid_accel>;
+ sensor-irqs = <&int_base_imu &int_lid_imu>;
};
};
diff --git a/zephyr/projects/corsola/motionsense_steelix.dts b/zephyr/projects/corsola/motionsense_steelix.dts
new file mode 100644
index 0000000000..70aa3679fb
--- /dev/null
+++ b/zephyr/projects/corsola/motionsense_steelix.dts
@@ -0,0 +1,17 @@
+/* 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.
+ */
+
+&lid_rot_ref {
+ mat33 = <0 1 0
+ 1 0 0
+ 0 0 (-1)>;
+};
+
+&base_rot_ref {
+ mat33 = <1 0 0
+ 0 (-1) 0
+ 0 0 (-1)>;
+};
+
diff --git a/zephyr/projects/corsola/npcx_keyboard.dts b/zephyr/projects/corsola/npcx_keyboard.dts
new file mode 100644
index 0000000000..d3fd354b8f
--- /dev/null
+++ b/zephyr/projects/corsola/npcx_keyboard.dts
@@ -0,0 +1,32 @@
+/* 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.
+ */
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/corsola/prj.conf b/zephyr/projects/corsola/prj.conf
index b9d07a7227..b26c01461e 100644
--- a/zephyr/projects/corsola/prj.conf
+++ b/zephyr/projects/corsola/prj.conf
@@ -15,7 +15,6 @@ CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=y
CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y
# MKBP
-CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=y
CONFIG_PLATFORM_EC_MKBP_EVENT=y
CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y
CONFIG_PLATFORM_EC_MKBP_USE_GPIO=y
@@ -30,6 +29,7 @@ CONFIG_PLATFORM_EC_USB_PD_USB4=n
CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK=n
# Power Seq
+CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK=y
CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y
CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y
diff --git a/zephyr/projects/corsola/prj_kingler.conf b/zephyr/projects/corsola/prj_kingler.conf
index 191a104cde..525d94a886 100644
--- a/zephyr/projects/corsola/prj_kingler.conf
+++ b/zephyr/projects/corsola/prj_kingler.conf
@@ -74,9 +74,6 @@ CONFIG_PLATFORM_EC_MATH_UTIL=y
CONFIG_AP=y
CONFIG_AP_ARM_MTK_MT8186=y
CONFIG_PLATFORM_EC_POWERSEQ_MT8186=y
-
-# Treat 2nd reset from H1 as Power-On
-CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y
CONFIG_PLATFORM_EC_POWERSEQ=y
CONFIG_PLATFORM_EC_POWERSEQ_S4=n
CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n
@@ -93,11 +90,14 @@ CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y
CONFIG_PLATFORM_EC_ACCEL_FIFO=y
CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y
CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y
+CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y
CONFIG_PLATFORM_EC_LID_ANGLE=y
CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y
CONFIG_PLATFORM_EC_LID_SWITCH=y
CONFIG_PLATFORM_EC_MOTIONSENSE=y
CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
+CONFIG_PLATFORM_EC_TABLET_MODE=y
+CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y
# USBA
CONFIG_PLATFORM_EC_USBA=y
@@ -122,6 +122,7 @@ CONFIG_PLATFORM_EC_USB_PD_DEBUG_FIXED_LEVEL=y
CONFIG_PLATFORM_EC_USB_PD_DEBUG_LEVEL=2
CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447=y
CONFIG_PLATFORM_EC_USB_PD_TCPM_RT1718S=y
+CONFIG_PLATFORM_EC_USB_PD_TCPM_SBU=y
CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y
CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_BY_BOARD=y
diff --git a/zephyr/projects/corsola/prj_steelix.conf b/zephyr/projects/corsola/prj_steelix.conf
index 5354381f9b..48971c9ed4 100644
--- a/zephyr/projects/corsola/prj_steelix.conf
+++ b/zephyr/projects/corsola/prj_steelix.conf
@@ -4,4 +4,10 @@
# Variant config
CONFIG_BOARD_KINGLER=n
-CONFIG_BOARD_STEELIX=y \ No newline at end of file
+CONFIG_BOARD_STEELIX=y
+
+# steelix only use D2, drop the workaround config for H1
+CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=n
+
+# LED
+CONFIG_PLATFORM_EC_LED_PWM=n
diff --git a/zephyr/projects/corsola/src/kingler/led_steelix.c b/zephyr/projects/corsola/src/kingler/led_steelix.c
index a44f961441..2d2e1431a1 100644
--- a/zephyr/projects/corsola/src/kingler/led_steelix.c
+++ b/zephyr/projects/corsola/src/kingler/led_steelix.c
@@ -4,11 +4,26 @@
*
* Battery LED control for Steelix
*/
+
+#include <zephyr/drivers/pwm.h>
+#include <zephyr/logging/log.h>
+
+#include "board_led.h"
#include "common.h"
-#include "ec_commands.h"
#include "led_common.h"
#include "led_onoff_states.h"
-#include "led_pwm.h"
+#include "util.h"
+
+LOG_MODULE_REGISTER(board_led, LOG_LEVEL_ERR);
+
+#define BOARD_LED_PWM_PERIOD_NS BOARD_LED_HZ_TO_PERIOD_NS(100)
+
+static const struct board_led_pwm_dt_channel board_led_battery_red =
+ BOARD_LED_PWM_DT_CHANNEL_INITIALIZER(DT_NODELABEL(led_battery_red));
+static const struct board_led_pwm_dt_channel board_led_battery_green =
+ BOARD_LED_PWM_DT_CHANNEL_INITIALIZER(DT_NODELABEL(led_battery_green));
+static const struct board_led_pwm_dt_channel board_led_power_white =
+ BOARD_LED_PWM_DT_CHANNEL_INITIALIZER(DT_NODELABEL(led_power_white));
__override const int led_charge_lvl_1 = 5;
__override const int led_charge_lvl_2 = 97;
@@ -18,6 +33,7 @@ __override struct led_descriptor
[STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
[STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_GREEN, LED_INDEFINITE} },
[STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} },
+ [STATE_DISCHARGE_S0_BAT_LOW] = {{LED_OFF, LED_INDEFINITE} },
[STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} },
[STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} },
[STATE_BATTERY_ERROR] = {{EC_LED_COLOR_RED, 1 * LED_ONE_SEC},
@@ -26,20 +42,110 @@ __override struct led_descriptor
{EC_LED_COLOR_GREEN, 2 * LED_ONE_SEC} },
};
+__override const struct led_descriptor
+ led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = {
+ [PWR_LED_STATE_ON] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} },
+ [PWR_LED_STATE_SUSPEND_AC] = {{EC_LED_COLOR_WHITE, 3 * LED_ONE_SEC},
+ {LED_OFF, 0.5 * LED_ONE_SEC} },
+ [PWR_LED_STATE_SUSPEND_NO_AC] = {{EC_LED_COLOR_WHITE, 3 * LED_ONE_SEC},
+ {LED_OFF, 0.5 * LED_ONE_SEC} },
+ [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} },
+};
+
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_BATTERY_LED,
+ EC_LED_ID_POWER_LED,
+};
+
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+
+static void board_led_pwm_set_duty(const struct board_led_pwm_dt_channel *ch,
+ int percent)
+{
+ uint32_t pulse_ns;
+ int rv;
+
+ if (!device_is_ready(ch->dev)) {
+ LOG_ERR("PWM device %s not ready", ch->dev->name);
+ return;
+ }
+
+ pulse_ns = DIV_ROUND_NEAREST(BOARD_LED_PWM_PERIOD_NS * percent, 100);
+
+ LOG_DBG("Board LED PWM %s set percent (%d), pulse %d",
+ ch->dev->name, percent, pulse_ns);
+
+ rv = pwm_set(ch->dev, ch->channel, BOARD_LED_PWM_PERIOD_NS, pulse_ns,
+ ch->flags);
+ if (rv) {
+ LOG_ERR("pwm_set() failed %s (%d)", ch->dev->name, rv);
+ }
+}
+
__override void led_set_color_battery(enum ec_led_colors color)
{
switch (color) {
case EC_LED_COLOR_RED:
- set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_RED);
+ board_led_pwm_set_duty(&board_led_battery_red, 100);
+ board_led_pwm_set_duty(&board_led_battery_green, 0);
break;
case EC_LED_COLOR_GREEN:
- set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_GREEN);
+ board_led_pwm_set_duty(&board_led_battery_red, 0);
+ board_led_pwm_set_duty(&board_led_battery_green, 100);
break;
case EC_LED_COLOR_AMBER:
- set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_AMBER);
+ board_led_pwm_set_duty(&board_led_battery_red, 100);
+ board_led_pwm_set_duty(&board_led_battery_green, 20);
break;
default: /* LED_OFF and other unsupported colors */
- set_pwm_led_color(EC_LED_ID_BATTERY_LED, -1);
+ board_led_pwm_set_duty(&board_led_battery_red, 0);
+ board_led_pwm_set_duty(&board_led_battery_green, 0);
break;
}
}
+
+__override void led_set_color_power(enum ec_led_colors color)
+{
+ switch (color) {
+ case EC_LED_COLOR_WHITE:
+ board_led_pwm_set_duty(&board_led_power_white, 100);
+ break;
+ default:
+ board_led_pwm_set_duty(&board_led_power_white, 0);
+ break;
+ }
+}
+
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ if (led_id == EC_LED_ID_BATTERY_LED) {
+ brightness_range[EC_LED_COLOR_RED] = 1;
+ brightness_range[EC_LED_COLOR_GREEN] = 1;
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
+ } else if (led_id == EC_LED_ID_POWER_LED) {
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
+ }
+}
+
+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_RED] != 0) {
+ led_set_color_battery(EC_LED_COLOR_RED);
+ } else if (brightness[EC_LED_COLOR_GREEN] != 0) {
+ led_set_color_battery(EC_LED_COLOR_GREEN);
+ } else if (brightness[EC_LED_COLOR_AMBER] != 0) {
+ led_set_color_battery(EC_LED_COLOR_AMBER);
+ } else {
+ led_set_color_battery(LED_OFF);
+ }
+ } else if (led_id == EC_LED_ID_POWER_LED) {
+ if (brightness[EC_LED_COLOR_WHITE] != 0) {
+ led_set_color_power(EC_LED_COLOR_WHITE);
+ } else {
+ led_set_color_power(LED_OFF);
+ }
+ }
+
+ return EC_SUCCESS;
+}
diff --git a/zephyr/projects/corsola/src/kingler/usbc_config.c b/zephyr/projects/corsola/src/kingler/usbc_config.c
index d710e36187..42aa0a31d6 100644
--- a/zephyr/projects/corsola/src/kingler/usbc_config.c
+++ b/zephyr/projects/corsola/src/kingler/usbc_config.c
@@ -192,12 +192,6 @@ __override int board_rt1718s_init(int port)
RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_GPIO2_VBUS_CTRL,
RT1718S_GPIO2_VBUS_CTRL_FRS_RX_VBUS, 0xFF));
- /* Turn on SBU switch */
- RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_RT2_SBU_CTRL_01,
- RT1718S_RT2_SBU_CTRL_01_SBU_VIEN |
- RT1718S_RT2_SBU_CTRL_01_SBU2_SWEN |
- RT1718S_RT2_SBU_CTRL_01_SBU1_SWEN,
- 0xFF));
/* Trigger GPIO 1/2 change when FRS signal received */
RETURN_ERROR(rt1718s_update_bits8(port, RT1718S_FRS_CTRL3,
RT1718S_FRS_CTRL3_FRS_RX_WAIT_GPIO2 |
diff --git a/zephyr/projects/corsola/src/usb_pd_policy.c b/zephyr/projects/corsola/src/usb_pd_policy.c
index cdcb49ff2e..c9015de776 100644
--- a/zephyr/projects/corsola/src/usb_pd_policy.c
+++ b/zephyr/projects/corsola/src/usb_pd_policy.c
@@ -8,6 +8,7 @@
#include "chipset.h"
#include "hooks.h"
#include "timer.h"
+#include "typec_control.h"
#include "usb_dp_alt_mode.h"
#include "usb_mux.h"
#include "usb_pd.h"
@@ -112,6 +113,8 @@ __override void svdm_dp_post_config(int port)
{
mux_state_t mux_mode = svdm_dp_get_mux_mode(port);
+ typec_set_sbu(port, true);
+
/*
* Prior to post-config, the mux will be reset to safe mode, and this
* will break mux config and aux path config we did in the first DP
diff --git a/zephyr/projects/herobrine/BUILD.py b/zephyr/projects/herobrine/BUILD.py
index dd3eed1562..2a15441c55 100644
--- a/zephyr/projects/herobrine/BUILD.py
+++ b/zephyr/projects/herobrine/BUILD.py
@@ -51,6 +51,8 @@ register_variant(
extra_dts_overlays=[
here / "battery_hoglin.dts",
here / "gpio_hoglin.dts",
+ here / "led_pins_hoglin.dts",
+ here / "led_policy_hoglin.dts",
here / "motionsense_hoglin.dts",
here / "switchcap_hoglin.dts",
here / "usbc_hoglin.dts",
@@ -64,8 +66,8 @@ register_variant(
extra_dts_overlays=[
here / "battery_villager.dts",
here / "gpio_villager.dts",
- here / "gpio_led_villager.dts",
- here / "led_villager.dts",
+ here / "led_pins_villager.dts",
+ here / "led_policy_villager.dts",
here / "motionsense_villager.dts",
here / "switchcap.dts",
here / "usbc_villager.dts",
diff --git a/zephyr/projects/herobrine/CMakeLists.txt b/zephyr/projects/herobrine/CMakeLists.txt
index 64102e951c..537fa5ef68 100644
--- a/zephyr/projects/herobrine/CMakeLists.txt
+++ b/zephyr/projects/herobrine/CMakeLists.txt
@@ -12,8 +12,6 @@ cros_ec_library_include_directories(include)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC
"src/usbc_config.c"
"src/usb_pd_policy.c")
-zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON
- "src/led.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C
"src/i2c.c")
diff --git a/zephyr/projects/herobrine/gpio_hoglin.dts b/zephyr/projects/herobrine/gpio_hoglin.dts
index 6f2f05eacf..f0b8a43586 100644
--- a/zephyr/projects/herobrine/gpio_hoglin.dts
+++ b/zephyr/projects/herobrine/gpio_hoglin.dts
@@ -174,16 +174,18 @@
gpios = <&gpioc 1 GPIO_OUTPUT_LOW>;
enum-name = "GPIO_USB_C1_FRS_EN";
};
- gpio_ec_chg_led_y_c0: ec_chg_led_y_c0 {
+ gpio_ec_chg_led_b_c0: ec_chg_led_b_c0 {
+ #led-pin-cells = <1>;
gpios = <&gpio6 0 GPIO_OUTPUT_LOW>;
};
- gpio_ec_chg_led_w_c0: ec_chg_led_w_c0 {
+ gpio_ec_chg_led_r_c0: ec_chg_led_r_c0 {
+ #led-pin-cells = <1>;
gpios = <&gpioc 0 GPIO_OUTPUT_LOW>;
};
- gpio_ec_chg_led_y_c1: ec_chg_led_y_c1 {
+ gpio_ec_chg_led_y_c1: ec_chg_led_b_c1 {
gpios = <&gpioc 3 GPIO_OUTPUT_LOW>;
};
- gpio_ec_chg_led_w_c1: ec_chg_led_w_c1 {
+ gpio_ec_chg_led_w_c1: ec_chg_led_r_c1 {
gpios = <&gpioc 4 GPIO_OUTPUT_LOW>;
};
ap_ec_spi_mosi {
diff --git a/zephyr/projects/herobrine/keyboard.dts b/zephyr/projects/herobrine/keyboard.dts
index 8c5f306192..202b61bb4f 100644
--- a/zephyr/projects/herobrine/keyboard.dts
+++ b/zephyr/projects/herobrine/keyboard.dts
@@ -17,3 +17,31 @@
pinctrl-0 = <&pwm3_gp80>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/herobrine/led_pins_hoglin.dts b/zephyr/projects/herobrine/led_pins_hoglin.dts
new file mode 100644
index 0000000000..8603b4e61d
--- /dev/null
+++ b/zephyr/projects/herobrine/led_pins_hoglin.dts
@@ -0,0 +1,33 @@
+/* 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.
+ */
+
+/ {
+ gpio-led-pins {
+ compatible = "cros-ec,gpio-led-pins";
+
+ color_off: color-off {
+ led-color = "LED_OFF";
+ led-id = "EC_LED_ID_BATTERY_LED";
+ led-pins = <&gpio_ec_chg_led_b_c0 0>,
+ <&gpio_ec_chg_led_r_c0 0>;
+ };
+
+ color_blue: color-blue {
+ led-color = "LED_BLUE";
+ led-id = "EC_LED_ID_BATTERY_LED";
+ br-color = "EC_LED_COLOR_BLUE";
+ led-pins = <&gpio_ec_chg_led_b_c0 1>,
+ <&gpio_ec_chg_led_r_c0 0>;
+ };
+
+ color_red: color-red {
+ led-color = "LED_RED";
+ led-id = "EC_LED_ID_BATTERY_LED";
+ br-color = "EC_LED_COLOR_RED";
+ led-pins = <&gpio_ec_chg_led_b_c0 0>,
+ <&gpio_ec_chg_led_r_c0 1>;
+ };
+ };
+};
diff --git a/zephyr/projects/herobrine/gpio_led_villager.dts b/zephyr/projects/herobrine/led_pins_villager.dts
index 67a1d1926c..67a1d1926c 100644
--- a/zephyr/projects/herobrine/gpio_led_villager.dts
+++ b/zephyr/projects/herobrine/led_pins_villager.dts
diff --git a/zephyr/projects/herobrine/led_policy_hoglin.dts b/zephyr/projects/herobrine/led_policy_hoglin.dts
new file mode 100644
index 0000000000..80ee9f7829
--- /dev/null
+++ b/zephyr/projects/herobrine/led_policy_hoglin.dts
@@ -0,0 +1,97 @@
+/* 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.
+ */
+
+/ {
+ led-colors {
+ compatible = "cros-ec,led-colors";
+
+ power-state-charge {
+ charge-state = "PWR_STATE_CHARGE";
+
+ color-0 {
+ led-color = <&color_blue>;
+ };
+ };
+
+ power-state-discharge-s0 {
+ charge-state = "PWR_STATE_DISCHARGE";
+ chipset-state = "POWER_S0";
+
+ color-0 {
+ led-color = <&color_off>;
+ };
+ };
+
+ power-state-discharge-s3 {
+ charge-state = "PWR_STATE_DISCHARGE";
+ chipset-state = "POWER_S3";
+
+ /* Blue 1 sec, off 3 sec */
+ color-0 {
+ led-color = <&color_blue>;
+ period-ms = <1000>;
+ };
+ color-1 {
+ led-color = <&color_off>;
+ period-ms = <3000>;
+ };
+ };
+
+ power-state-discharge-s5 {
+ charge-state = "PWR_STATE_DISCHARGE";
+ chipset-state = "POWER_S5";
+
+ color-0 {
+ led-color = <&color_off>;
+ };
+ };
+
+ power-state-error {
+ charge-state = "PWR_STATE_ERROR";
+
+ /* Red 1 sec, off 1 sec */
+ color-0 {
+ led-color = <&color_red>;
+ period-ms = <1000>;
+ };
+ color-1 {
+ led-color = <&color_off>;
+ period-ms = <1000>;
+ };
+ };
+
+ power-state-near-full {
+ charge-state = "PWR_STATE_CHARGE_NEAR_FULL";
+
+ color-0 {
+ led-color = <&color_red>;
+ };
+ };
+
+ power-state-idle-forced {
+ charge-state = "PWR_STATE_IDLE";
+ extra-flag = "LED_CHFLAG_FORCE_IDLE";
+
+ /* Red 2 sec, Blue 2 sec */
+ color-0 {
+ led-color = <&color_red>;
+ period-ms = <2000>;
+ };
+ color-1 {
+ led-color = <&color_blue>;
+ period-ms = <2000>;
+ };
+ };
+
+ power-state-idle-default {
+ charge-state = "PWR_STATE_IDLE";
+ extra-flag = "LED_CHFLAG_DEFAULT";
+
+ color-0 {
+ led-color = <&color_red>;
+ };
+ };
+ };
+};
diff --git a/zephyr/projects/herobrine/led_villager.dts b/zephyr/projects/herobrine/led_policy_villager.dts
index 3bdf0147d7..46b0193e61 100644
--- a/zephyr/projects/herobrine/led_villager.dts
+++ b/zephyr/projects/herobrine/led_policy_villager.dts
@@ -1,3 +1,8 @@
+/* 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.
+ */
+
/ {
led-colors {
compatible = "cros-ec,led-colors";
diff --git a/zephyr/projects/herobrine/prj.conf b/zephyr/projects/herobrine/prj.conf
index 679c5c2424..e16d5c7899 100644
--- a/zephyr/projects/herobrine/prj.conf
+++ b/zephyr/projects/herobrine/prj.conf
@@ -30,7 +30,8 @@ CONFIG_SHELL_TAB_AUTOCOMPLETION=y
CONFIG_PLATFORM_EC_HIBERNATE_PSL=y
# LED
-CONFIG_PLATFORM_EC_LED_COMMON=y
+CONFIG_PLATFORM_EC_LED_COMMON=n
+CONFIG_PLATFORM_EC_LED_DT=y
# PWM
CONFIG_PWM=y
@@ -88,7 +89,7 @@ CONFIG_PLATFORM_EC_BATTERY_REVIVE_DISCONNECT=y
CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC=y
CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC_CHARGER=y
CONFIG_PLATFORM_EC_CHARGER_MIN_BAT_PCT_FOR_POWER_ON=2
-CONFIG_PLATFORM_EC_CHARGER_MIN_POWER_MW_FOR_POWER_ON=10000
+CONFIG_PLATFORM_EC_CHARGER_MIN_POWER_MW_FOR_POWER_ON=12500
CONFIG_PLATFORM_EC_CHARGER_PROFILE_OVERRIDE=y
CONFIG_PLATFORM_EC_CHARGER_PSYS=y
CONFIG_PLATFORM_EC_CHARGER_PSYS_READ=y
@@ -148,6 +149,7 @@ CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y
CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
CONFIG_PLATFORM_EC_TABLET_MODE=y
CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y
+CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000
# Sensor Drivers
CONFIG_PLATFORM_EC_ACCEL_BMA255=y
diff --git a/zephyr/projects/herobrine/prj_herobrine.conf b/zephyr/projects/herobrine/prj_herobrine.conf
index c91071d844..3c7eddbae6 100644
--- a/zephyr/projects/herobrine/prj_herobrine.conf
+++ b/zephyr/projects/herobrine/prj_herobrine.conf
@@ -5,10 +5,6 @@
# Herobrine-NPCX9 reference-board-specific Kconfig settings.
CONFIG_BOARD_HEROBRINE=y
-# LED
-CONFIG_PLATFORM_EC_LED_COMMON=n
-CONFIG_PLATFORM_EC_LED_DT=y
-
# Sensors
CONFIG_PLATFORM_EC_ALS=y
diff --git a/zephyr/projects/herobrine/prj_hoglin.conf b/zephyr/projects/herobrine/prj_hoglin.conf
index f68d139b78..370e942f45 100644
--- a/zephyr/projects/herobrine/prj_hoglin.conf
+++ b/zephyr/projects/herobrine/prj_hoglin.conf
@@ -13,4 +13,3 @@ CONFIG_PLATFORM_EC_ALS=y
# Sensor Drivers
CONFIG_PLATFORM_EC_ALS_TCS3400=y
CONFIG_PLATFORM_EC_ALS_TCS3400_EMULATED_IRQ_EVENT=y
-
diff --git a/zephyr/projects/herobrine/prj_villager.conf b/zephyr/projects/herobrine/prj_villager.conf
index a63e003788..34c366a36f 100644
--- a/zephyr/projects/herobrine/prj_villager.conf
+++ b/zephyr/projects/herobrine/prj_villager.conf
@@ -5,7 +5,4 @@
# Villager board-specific Kconfig settings.
CONFIG_BOARD_VILLAGER=y
-# LED
-CONFIG_PLATFORM_EC_LED_DT=y
-CONFIG_PLATFORM_EC_LED_COMMON=n
CONFIG_PLATFORM_EC_ACCEL_KX022=y
diff --git a/zephyr/projects/herobrine/src/led.c b/zephyr/projects/herobrine/src/led.c
deleted file mode 100644
index ac6092884d..0000000000
--- a/zephyr/projects/herobrine/src/led.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Power and battery LED control.
- */
-
-#include <zephyr/drivers/gpio.h>
-
-#include "battery.h"
-#include "charge_manager.h"
-#include "charge_state.h"
-#include "chipset.h"
-#include "ec_commands.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "led_common.h"
-#include "system.h"
-#include "util.h"
-
-#define BAT_LED_ON 1
-#define BAT_LED_OFF 0
-
-const enum ec_led_id supported_led_ids[] = {
- EC_LED_ID_RIGHT_LED,
-#ifndef CONFIG_BOARD_HOGLIN
- EC_LED_ID_LEFT_LED,
-#endif
-};
-
-const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
-
-enum led_color {
- LED_OFF = 0,
- LED_AMBER,
- LED_WHITE,
- LED_COLOR_COUNT /* Number of colors, not a color itself */
-};
-
-static void side_led_set_color(int port, enum led_color color)
-{
- gpio_pin_set_dt(port ?
- GPIO_DT_FROM_NODELABEL(gpio_ec_chg_led_y_c1) :
- GPIO_DT_FROM_NODELABEL(gpio_ec_chg_led_y_c0),
- (color == LED_AMBER) ? BAT_LED_ON : BAT_LED_OFF);
- gpio_pin_set_dt(port ?
- GPIO_DT_FROM_NODELABEL(gpio_ec_chg_led_w_c1) :
- GPIO_DT_FROM_NODELABEL(gpio_ec_chg_led_w_c0),
- (color == LED_WHITE) ? BAT_LED_ON : BAT_LED_OFF);
-}
-
-void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
-{
-#ifndef CONFIG_BOARD_HOGLIN
- brightness_range[EC_LED_COLOR_AMBER] = 1;
- brightness_range[EC_LED_COLOR_WHITE] = 1;
-#else
- brightness_range[EC_LED_COLOR_RED] = 1;
- brightness_range[EC_LED_COLOR_BLUE] = 1;
-#endif
-}
-
-int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
-{
- int port;
-
- switch (led_id) {
- case EC_LED_ID_RIGHT_LED:
- port = 0;
- break;
- case EC_LED_ID_LEFT_LED:
- port = 1;
- break;
- default:
- return EC_ERROR_PARAM1;
- }
-
- if (brightness[EC_LED_COLOR_WHITE] != 0)
- side_led_set_color(port, LED_WHITE);
- else if (brightness[EC_LED_COLOR_AMBER] != 0)
- side_led_set_color(port, LED_AMBER);
- else
- side_led_set_color(port, LED_OFF);
-
- return EC_SUCCESS;
-}
-
-/*
- * Set active charge port color to the parameter, turn off all others.
- * If no port is active (-1), turn off all LEDs.
- */
-static void set_active_port_color(enum led_color color)
-{
- int port = charge_manager_get_active_charge_port();
-
- if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED))
- side_led_set_color(0, (port == 0) ? color : LED_OFF);
- if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED))
- side_led_set_color(1, (port == 1) ? color : LED_OFF);
-}
-
-static void board_led_set_battery(void)
-{
- static int battery_ticks;
- uint32_t chflags = charge_get_flags();
-
- battery_ticks++;
-
- switch (charge_get_state()) {
- case PWR_STATE_CHARGE:
- /* Always indicate when charging, even in suspend. */
- set_active_port_color(LED_AMBER);
- break;
- case PWR_STATE_DISCHARGE:
- if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) {
- if (charge_get_percent() <= 10)
- side_led_set_color(0,
- (battery_ticks & 0x4) ? LED_WHITE : LED_OFF);
- else
- side_led_set_color(0, LED_OFF);
- }
-
- if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED))
- side_led_set_color(1, LED_OFF);
- break;
- case PWR_STATE_ERROR:
- set_active_port_color((battery_ticks & 0x2) ?
- LED_WHITE : LED_OFF);
- break;
- case PWR_STATE_CHARGE_NEAR_FULL:
- set_active_port_color(LED_WHITE);
- break;
- case PWR_STATE_IDLE: /* External power connected in IDLE */
- if (chflags & CHARGE_FLAG_FORCE_IDLE)
- set_active_port_color((battery_ticks & 0x4) ?
- LED_AMBER : LED_OFF);
- else
- set_active_port_color(LED_WHITE);
- break;
- default:
- /* Other states don't alter LED behavior */
- break;
- }
-}
-
-/* Called by hook task every TICK */
-static void led_tick(void)
-{
- board_led_set_battery();
-}
-DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
-
-void led_control(enum ec_led_id led_id, enum ec_led_state state)
-{
- enum led_color color;
-
- if ((led_id != EC_LED_ID_RECOVERY_HW_REINIT_LED) &&
- (led_id != EC_LED_ID_SYSRQ_DEBUG_LED))
- return;
-
- if (state == LED_STATE_RESET) {
- led_auto_control(EC_LED_ID_LEFT_LED, 1);
- led_auto_control(EC_LED_ID_RIGHT_LED, 1);
- board_led_set_battery();
- return;
- }
-
- color = state ? LED_WHITE : LED_OFF;
-
- led_auto_control(EC_LED_ID_LEFT_LED, 0);
- led_auto_control(EC_LED_ID_RIGHT_LED, 0);
-
- side_led_set_color(0, color);
- side_led_set_color(1, color);
-}
diff --git a/zephyr/projects/intelrvp/BUILD.py b/zephyr/projects/intelrvp/BUILD.py
index 7b8bf9cb42..755b6479a6 100644
--- a/zephyr/projects/intelrvp/BUILD.py
+++ b/zephyr/projects/intelrvp/BUILD.py
@@ -26,7 +26,7 @@ def register_intelrvp_project(
dts_overlays.append(here / "adlrvp/ioex.dts")
if project_name.startswith("mtlrvp"):
kconfig_files.append(here / "mtlrvp/prj.conf")
- dts_overlays.append(here / "mtlrvp/battery.dts")
+ dts_overlays.append(here / "adlrvp/battery.dts")
kconfig_files.extend(extra_kconfig_files)
dts_overlays.extend(extra_dts_overlays)
@@ -65,6 +65,7 @@ register_intelrvp_project(
here / "adlrvp/adlrvp_npcx/cbi_eeprom.dts",
here / "mtlrvp/mtlrvpp_npcx/fan.dts",
here / "mtlrvp/mtlrvpp_npcx/gpio.dts",
+ here / "mtlrvp/mtlrvpp_npcx/keyboard.dts",
here / "mtlrvp/mtlrvpp_npcx/interrupts.dts",
here / "mtlrvp/ioex.dts",
here / "mtlrvp/mtlrvpp_npcx/mtlrvp_npcx.dts",
diff --git a/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/keyboard.dts b/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/keyboard.dts
index e001827d69..e735234128 100644
--- a/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/keyboard.dts
+++ b/zephyr/projects/intelrvp/adlrvp/adlrvp_npcx/keyboard.dts
@@ -29,3 +29,31 @@
>;
};
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/intelrvp/mtlrvp/battery.dts b/zephyr/projects/intelrvp/mtlrvp/battery.dts
deleted file mode 100644
index 505e5878d2..0000000000
--- a/zephyr/projects/intelrvp/mtlrvp/battery.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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: getac_smp_hhp_408_3s {
- compatible = "getac,bq40z50-R3-S3", "battery-smart";
- };
- getac_smp_hhp_408_2s {
- compatible = "getac,bq40z50-R3-S2", "battery-smart";
- };
- };
-};
diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/keyboard.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/keyboard.dts
new file mode 100644
index 0000000000..e735234128
--- /dev/null
+++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/keyboard.dts
@@ -0,0 +1,59 @@
+/* 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.
+ */
+
+/ {
+ cros-keyscan {
+ compatible = "cros-keyscan";
+
+ output-settle = <35>;
+ debounce-down = <5000>;
+ debounce-up = <40000>;
+ poll-timeout = <100000>;
+
+ actual-key-mask = <
+ 0x14 /* C0 */
+ 0xff /* C1 */
+ 0xff /* C2 */
+ 0xff /* C3 */
+ 0xff /* C4 */
+ 0xf5 /* C5 */
+ 0xff /* C6 */
+ 0xa4 /* C7 */
+ 0xff /* C8 */
+ 0xfe /* C9 */
+ 0x55 /* C10 */
+ 0xfa /* C11 */
+ 0xca /* C12 */
+ >;
+ };
+};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx_power_signals.dts b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx_power_signals.dts
index 81219636f0..57b41bd9d2 100644
--- a/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx_power_signals.dts
+++ b/zephyr/projects/intelrvp/mtlrvp/mtlrvpp_npcx/mtlrvp_npcx_power_signals.dts
@@ -43,11 +43,18 @@
gpios = <&gpioa 1 GPIO_ACTIVE_LOW>;
interrupt-flags = <GPIO_INT_EDGE_BOTH>;
};
+ pwr-pch-pwrok {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "PCH_PWROK output to PCH";
+ enum-name = "PWR_PCH_PWROK";
+ gpios = <&gpiod 3 GPIO_OPEN_DRAIN>;
+ output;
+ };
pwr-ec-pch-sys-pwrok {
compatible = "intel,ap-pwrseq-gpio";
dbg-label = "SYS_PWROK output to PCH";
enum-name = "PWR_EC_PCH_SYS_PWROK";
- gpios = <&gpiof 5 0>;
+ gpios = <&gpiof 5 GPIO_OPEN_DRAIN>;
output;
};
pwr-sys-rst-l {
diff --git a/zephyr/projects/nissa/BUILD.py b/zephyr/projects/nissa/BUILD.py
index c490471bcb..a620e7b9ae 100644
--- a/zephyr/projects/nissa/BUILD.py
+++ b/zephyr/projects/nissa/BUILD.py
@@ -4,7 +4,7 @@
"""Define zmake projects for nissa."""
-# Nivviks and Craask has NPCX993F, Nereid has ITE81302
+# Nivviks and Craask, Pujjo has NPCX993F, Nereid has ITE81302
def register_nissa_project(
@@ -18,7 +18,7 @@ def register_nissa_project(
if chip.startswith("npcx"):
register_func = register_npcx_project
- register_func(
+ return register_func(
project_name=project_name,
zephyr_board=chip,
dts_overlays=["cbi.dts", *extra_dts_overlays],
@@ -26,7 +26,7 @@ def register_nissa_project(
)
-register_nissa_project(
+nivviks = register_nissa_project(
project_name="nivviks",
chip="npcx9m3f",
extra_dts_overlays=[
@@ -41,7 +41,7 @@ register_nissa_project(
extra_kconfig_files=[here / "prj_nivviks.conf"],
)
-register_nissa_project(
+nereid = register_nissa_project(
project_name="nereid",
chip="it8xxx2",
extra_dts_overlays=[
@@ -55,15 +55,30 @@ register_nissa_project(
extra_kconfig_files=[here / "prj_nereid.conf"],
)
-register_nissa_project(
+craask = register_nissa_project(
project_name="craask",
chip="npcx9m3f",
extra_dts_overlays=[
here / "craask_generated.dts",
here / "craask_overlay.dts",
here / "craask_motionsense.dts",
+ here / "craask_keyboard.dts",
here / "craask_power_signals.dts",
here / "craask_pwm_leds.dts",
],
extra_kconfig_files=[here / "prj_craask.conf"],
)
+
+pujjo = register_nissa_project(
+ project_name="pujjo",
+ chip="npcx9m3f",
+ extra_dts_overlays=[
+ here / "pujjo_generated.dts",
+ here / "pujjo_overlay.dts",
+ here / "pujjo_motionsense.dts",
+ here / "pujjo_keyboard.dts",
+ here / "pujjo_power_signals.dts",
+ here / "pujjo_pwm_leds.dts",
+ ],
+ extra_kconfig_files=[here / "prj_pujjo.conf"],
+)
diff --git a/zephyr/projects/nissa/CMakeLists.txt b/zephyr/projects/nissa/CMakeLists.txt
index 18a82b9def..afc96e924f 100644
--- a/zephyr/projects/nissa/CMakeLists.txt
+++ b/zephyr/projects/nissa/CMakeLists.txt
@@ -35,7 +35,17 @@ if(DEFINED CONFIG_BOARD_CRAASK)
zephyr_library_sources(
"src/craask/led.c"
)
- project(nivviks)
+ project(craask)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/craask/usbc.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "src/craask/charger.c")
endif()
+if(DEFINED CONFIG_BOARD_PUJJO)
+ project(pujjo)
+ zephyr_library_sources(
+ "src/led.c"
+ "src/pujjo/keyboard.c"
+ )
+ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "src/pujjo/fan.c")
+ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/pujjo/usbc.c")
+ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "src/pujjo/charger.c")
+endif()
diff --git a/zephyr/projects/nissa/Kconfig b/zephyr/projects/nissa/Kconfig
index 3f0ef5954a..87d7bca977 100644
--- a/zephyr/projects/nissa/Kconfig
+++ b/zephyr/projects/nissa/Kconfig
@@ -20,6 +20,12 @@ config BOARD_CRAASK
Build Google Craask board. Craask has Intel ADL-N SoC
with NPCX993FA0BX EC.
+config BOARD_PUJJO
+ bool "Google Pujjo Board"
+ help
+ Build Google Pujjo board. Pujjo has Intel ADL-N SoC
+ with NPCX993FA0BX EC.
+
module = NISSA
module-str = Nissa board-specific code
source "subsys/logging/Kconfig.template.log_config"
diff --git a/zephyr/projects/nissa/craask_keyboard.dts b/zephyr/projects/nissa/craask_keyboard.dts
new file mode 100644
index 0000000000..d3fd354b8f
--- /dev/null
+++ b/zephyr/projects/nissa/craask_keyboard.dts
@@ -0,0 +1,32 @@
+/* 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.
+ */
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/nissa/nivviks_keyboard.dts b/zephyr/projects/nissa/nivviks_keyboard.dts
index 72c573b796..71cb49ce65 100644
--- a/zephyr/projects/nissa/nivviks_keyboard.dts
+++ b/zephyr/projects/nissa/nivviks_keyboard.dts
@@ -16,3 +16,33 @@
pinctrl-0 = <&pwm6_gpc0>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ &kso13_gp04
+ &kso14_gp82
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/nissa/nivviks_overlay.dts b/zephyr/projects/nissa/nivviks_overlay.dts
index 926dc46129..bc10f510a5 100644
--- a/zephyr/projects/nissa/nivviks_overlay.dts
+++ b/zephyr/projects/nissa/nivviks_overlay.dts
@@ -261,7 +261,14 @@
*/
def-lvol-io-list {
compatible = "nuvoton,npcx-lvolctrl-def";
- lvol-io-pads = <&lvol_iof5 &lvol_iof4>;
+ lvol-io-pads = <
+ &lvol_iof5
+ &lvol_iof4
+ &lvol_io90 /* EC_I2C_SENSOR_SCL */
+ &lvol_io87 /* EC_I2C_SENSOR_SDA */
+ &lvol_ioe3 /* VCCIN_AUX_VID1 */
+ &lvol_io92 /* VCCIN_AUX_VID0 */
+ >;
};
/*
* Declare unused GPIOs so that they are shut down
diff --git a/zephyr/projects/nissa/prj.conf b/zephyr/projects/nissa/prj.conf
index 621355bf6a..df988de149 100644
--- a/zephyr/projects/nissa/prj.conf
+++ b/zephyr/projects/nissa/prj.conf
@@ -8,7 +8,6 @@ CONFIG_CROS_EC=y
CONFIG_PLATFORM_EC=y
CONFIG_SHIMMED_TASKS=y
CONFIG_LTO=y
-CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y
# Debug options and features; can be disabled to save memory or once bringup
# is complete.
diff --git a/zephyr/projects/nissa/prj_nereid.conf b/zephyr/projects/nissa/prj_nereid.conf
index 2508f5b13b..4b0db30556 100644
--- a/zephyr/projects/nissa/prj_nereid.conf
+++ b/zephyr/projects/nissa/prj_nereid.conf
@@ -8,10 +8,6 @@ CONFIG_CROS_FLASH_IT8XXX2=y
CONFIG_CROS_SYSTEM_IT8XXX2=y
CONFIG_ESPI_IT8XXX2=y
-# Permit more detailed debugging of chargers
-# TODO(b:230712704) disable when behavior is better understood
-CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_DUMP=y
-
# Allow more time for the charger to stabilise
CONFIG_PLATFORM_EC_POWER_BUTTON_INIT_TIMEOUT=5
diff --git a/zephyr/projects/nissa/prj_pujjo.conf b/zephyr/projects/nissa/prj_pujjo.conf
new file mode 100644
index 0000000000..e7e9cbd357
--- /dev/null
+++ b/zephyr/projects/nissa/prj_pujjo.conf
@@ -0,0 +1,40 @@
+# Copyright 2022 The ChromiumOS Authors.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# EC chip configuration: NPCX993
+CONFIG_BOARD_PUJJO=y
+CONFIG_CROS_FLASH_NPCX=y
+CONFIG_CROS_SYSTEM_NPCX=y
+CONFIG_SOC_SERIES_NPCX9=y
+CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y
+CONFIG_SYSCON=y
+CONFIG_TACH_NPCX=y
+CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=256
+
+# Sensor drivers
+CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y
+CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y
+
+# Keyboard
+CONFIG_CROS_KB_RAW_NPCX=y
+CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=y
+
+# TCPC+PPC: both C0 and C1 (if present) are RAA489000
+CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y
+CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=y
+CONFIG_PLATFORM_EC_USB_PD_VBUS_DETECT_TCPC=y
+CONFIG_PLATFORM_EC_USB_PD_TCPC_LPM_EXIT_DEBOUNCE_US=100000
+# RAA489000 uses TCPCI but not a separate PPC, so custom function is required
+CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y
+# type C port 1 redriver
+CONFIG_PLATFORM_EC_USBC_RETIMER_ANX7483=y
+
+# Charger driver and configuration
+CONFIG_PLATFORM_EC_CHARGER_RAA489000=y
+CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22
+
+# VSENSE: PP3300_S5 & PP1050_PROC
+CONFIG_ADC_CMP_NPCX=y
+CONFIG_SENSOR=y
+CONFIG_SENSOR_SHELL=n
diff --git a/zephyr/projects/nissa/pujjo_generated.dts b/zephyr/projects/nissa/pujjo_generated.dts
new file mode 100644
index 0000000000..1c429ae32c
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_generated.dts
@@ -0,0 +1,290 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * This file is auto-generated - do not edit!
+ */
+
+/ {
+
+ named-adc-channels {
+ compatible = "named-adc-channels";
+
+ adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc {
+ label = "EC_VSENSE_PP1050_PROC";
+ enum-name = "ADC_PP1050_PROC";
+ io-channels = <&adc0 4>;
+ };
+ adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 {
+ label = "EC_VSENSE_PP3300_S5";
+ enum-name = "ADC_PP3300_S5";
+ io-channels = <&adc0 6>;
+ };
+ adc_temp_sensor_1: temp_sensor_1 {
+ label = "TEMP_SENSOR_1";
+ enum-name = "ADC_TEMP_SENSOR_1";
+ io-channels = <&adc0 0>;
+ };
+ adc_temp_sensor_2: temp_sensor_2 {
+ label = "TEMP_SENSOR_2";
+ enum-name = "ADC_TEMP_SENSOR_2";
+ io-channels = <&adc0 1>;
+ };
+ };
+
+ named-gpios {
+ compatible = "named-gpios";
+
+ gpio_acc_int_l: acc_int_l {
+ gpios = <&gpio5 0 GPIO_INPUT>;
+ };
+ gpio_all_sys_pwrgd: all_sys_pwrgd {
+ gpios = <&gpioa 7 GPIO_INPUT>;
+ };
+ gpio_ccd_mode_odl: ccd_mode_odl {
+ gpios = <&gpioe 5 GPIO_INPUT>;
+ enum-name = "GPIO_CCD_MODE_ODL";
+ };
+ gpio_cpu_c10_gate_l: cpu_c10_gate_l {
+ gpios = <&gpio6 7 GPIO_INPUT>;
+ };
+ gpio_ec_battery_pres_odl: ec_battery_pres_odl {
+ gpios = <&gpioa 3 GPIO_INPUT>;
+ enum-name = "GPIO_BATT_PRES_ODL";
+ };
+ gpio_ec_cbi_wp: ec_cbi_wp {
+ gpios = <&gpio7 4 GPIO_OUTPUT>;
+ };
+ gpio_ec_edp_bl_en_od: ec_edp_bl_en_od {
+ gpios = <&gpiod 3 GPIO_ODR_HIGH>;
+ enum-name = "GPIO_ENABLE_BACKLIGHT";
+ };
+ gpio_ec_entering_rw: ec_entering_rw {
+ gpios = <&gpio0 3 GPIO_OUTPUT>;
+ enum-name = "GPIO_ENTERING_RW";
+ };
+ gpio_ec_gsc_packet_mode: ec_gsc_packet_mode {
+ gpios = <&gpio7 5 GPIO_OUTPUT>;
+ enum-name = "GPIO_PACKET_MODE_EN";
+ };
+ gpio_ec_kso_02_inv: ec_kso_02_inv {
+ gpios = <&gpio1 7 (GPIO_OUTPUT_LOW | GPIO_ACTIVE_LOW)>;
+ };
+ gpio_ec_pch_wake_odl: ec_pch_wake_odl {
+ gpios = <&gpiob 0 GPIO_ODR_LOW>;
+ };
+ gpio_ec_prochot_odl: ec_prochot_odl {
+ gpios = <&gpiof 1 GPIO_ODR_HIGH>;
+ };
+ gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok {
+ gpios = <&gpio6 1 GPIO_OUTPUT>;
+ };
+ gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd {
+ gpios = <&gpioe 4 GPIO_OUTPUT>;
+ };
+ gpio_ec_soc_int_odl: ec_soc_int_odl {
+ gpios = <&gpio8 0 GPIO_ODR_HIGH>;
+ enum-name = "GPIO_EC_INT_L";
+ };
+ gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od {
+ gpios = <&gpio7 2 GPIO_ODR_HIGH>;
+ };
+ gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl {
+ gpios = <&gpioc 1 GPIO_ODR_HIGH>;
+ enum-name = "GPIO_PCH_PWRBTN_L";
+ };
+ gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l {
+ gpios = <&gpioa 6 GPIO_OUTPUT>;
+ };
+ gpio_ec_soc_rtcrst: ec_soc_rtcrst {
+ gpios = <&gpio7 6 GPIO_OUTPUT>;
+ };
+ gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok {
+ gpios = <&gpio3 7 GPIO_OUTPUT>;
+ };
+ gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od {
+ gpios = <&gpioa 4 GPIO_ODR_HIGH>;
+ };
+ gpio_ec_wp_odl: ec_wp_odl {
+ gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>;
+ };
+ gpio_en_kb_bl: en_kb_bl {
+ gpios = <&gpioa 0 GPIO_OUTPUT>;
+ enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT";
+ };
+ gpio_en_pp3300_s5: en_pp3300_s5 {
+ gpios = <&gpiob 6 GPIO_OUTPUT>;
+ enum-name = "GPIO_TEMP_SENSOR_POWER";
+ };
+ gpio_en_pp5000_pen_x: en_pp5000_pen_x {
+ gpios = <&gpioe 2 GPIO_OUTPUT>;
+ };
+ gpio_en_pp5000_s5: en_pp5000_s5 {
+ gpios = <&gpio4 0 GPIO_OUTPUT>;
+ };
+ gpio_en_slp_z: en_slp_z {
+ gpios = <&gpioe 1 GPIO_OUTPUT>;
+ };
+ gpio_en_usb_a0_vbus: en_usb_a0_vbus {
+ gpios = <&gpio9 1 GPIO_OUTPUT>;
+ };
+ gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl {
+ gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>;
+ enum-name = "GPIO_POWER_BUTTON_L";
+ };
+ gpio_hdmi_sel: hdmi_sel {
+ gpios = <&gpioc 6 GPIO_OUTPUT>;
+ };
+ gpio_imu_int_l: imu_int_l {
+ gpios = <&gpio5 6 GPIO_INPUT>;
+ };
+ gpio_imvp91_vrrdy_od: imvp91_vrrdy_od {
+ gpios = <&gpio4 3 GPIO_INPUT>;
+ };
+ gpio_lid_open: lid_open {
+ gpios = <&gpiod 2 GPIO_INPUT>;
+ enum-name = "GPIO_LID_OPEN";
+ };
+ gpio_pen_detect_odl: pen_detect_odl {
+ gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>;
+ };
+ gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od {
+ gpios = <&gpiof 0 GPIO_INPUT>;
+ };
+ gpio_pg_pp5000_s5_od: pg_pp5000_s5_od {
+ gpios = <&gpio4 2 GPIO_INPUT>;
+ };
+ gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l {
+ gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>;
+ };
+ gpio_slp_s0_l: slp_s0_l {
+ gpios = <&gpio9 7 GPIO_INPUT>;
+ };
+ gpio_slp_s3_l: slp_s3_l {
+ gpios = <&gpioa 5 GPIO_INPUT>;
+ };
+ gpio_slp_s4_l: slp_s4_l {
+ gpios = <&gpio7 0 GPIO_INPUT>;
+ };
+ gpio_slp_sus_l: slp_sus_l {
+ gpios = <&gpio6 2 GPIO_INPUT>;
+ };
+ gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp {
+ gpios = <&gpiod 5 GPIO_OUTPUT>;
+ enum-name = "GPIO_USB2_ILIM_SEL";
+ };
+ gpio_sys_rst_odl: sys_rst_odl {
+ gpios = <&gpioc 5 GPIO_ODR_HIGH>;
+ };
+ gpio_tablet_mode_l: tablet_mode_l {
+ gpios = <&gpio9 5 GPIO_INPUT>;
+ enum-name = "GPIO_TABLET_MODE_L";
+ };
+ gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp {
+ gpios = <&gpio8 5 GPIO_OUTPUT>;
+ enum-name = "GPIO_USB1_ILIM_SEL";
+ };
+ gpio_usb_c0_int_odl: usb_c0_int_odl {
+ gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>;
+ };
+ gpio_vccin_aux_vid0: vccin_aux_vid0 {
+ gpios = <&gpio9 2 GPIO_INPUT>;
+ };
+ gpio_vccin_aux_vid1: vccin_aux_vid1 {
+ gpios = <&gpioe 3 GPIO_INPUT>;
+ };
+ gpio_voldn_btn_odl: voldn_btn_odl {
+ gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>;
+ enum-name = "GPIO_VOLUME_DOWN_L";
+ };
+ gpio_volup_btn_odl: volup_btn_odl {
+ gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>;
+ enum-name = "GPIO_VOLUME_UP_L";
+ };
+ };
+
+ named-i2c-ports {
+ compatible = "named-i2c-ports";
+
+ i2c_ec_i2c_eeprom: ec_i2c_eeprom {
+ i2c-port = <&i2c0_0>;
+ enum-name = "I2C_PORT_EEPROM";
+ };
+ i2c_ec_i2c_sensor: ec_i2c_sensor {
+ i2c-port = <&i2c1_0>;
+ enum-name = "I2C_PORT_SENSOR";
+ };
+ i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 {
+ i2c-port = <&i2c3_0>;
+ enum-name = "I2C_PORT_USB_C0_TCPC";
+ };
+ i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 {
+ i2c-port = <&i2c5_1>;
+ enum-name = "I2C_PORT_USB_C1_TCPC";
+ };
+ i2c_ec_i2c_batt: ec_i2c_batt {
+ i2c-port = <&i2c7_0>;
+ enum-name = "I2C_PORT_BATTERY";
+ };
+ };
+};
+
+&adc0 {
+ status = "okay";
+ pinctrl-0 = <&adc0_chan0_gp45
+ &adc0_chan1_gp44
+ &adc0_chan4_gp41
+ &adc0_chan6_gp34>;
+ pinctrl-names = "default";
+};
+
+
+&i2c0_0 {
+ status = "okay";
+ pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>;
+ pinctrl-names = "default";
+};
+
+&i2c1_0 {
+ status = "okay";
+ pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>;
+ pinctrl-names = "default";
+};
+
+&i2c3_0 {
+ status = "okay";
+ pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>;
+ pinctrl-names = "default";
+};
+
+&i2c5_1 {
+ status = "okay";
+ pinctrl-0 = <&i2c5_1_sda_scl_gpf4_f5>;
+ pinctrl-names = "default";
+};
+
+&i2c7_0 {
+ status = "okay";
+ pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>;
+ pinctrl-names = "default";
+};
+
+&i2c_ctrl0 {
+ status = "okay";
+};
+
+&i2c_ctrl1 {
+ status = "okay";
+};
+
+&i2c_ctrl3 {
+ status = "okay";
+};
+
+&i2c_ctrl5 {
+ status = "okay";
+};
+
+&i2c_ctrl7 {
+ status = "okay";
+};
diff --git a/zephyr/projects/nissa/pujjo_keyboard.dts b/zephyr/projects/nissa/pujjo_keyboard.dts
new file mode 100644
index 0000000000..71cb49ce65
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_keyboard.dts
@@ -0,0 +1,48 @@
+/* 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.
+ */
+
+/ {
+ kblight {
+ compatible = "cros-ec,kblight-pwm";
+ pwms = <&pwm6 6 PWM_KHZ(10) PWM_POLARITY_NORMAL>;
+ frequency = <10000>;
+ };
+};
+
+&pwm6 {
+ status = "okay";
+ pinctrl-0 = <&pwm6_gpc0>;
+ pinctrl-names = "default";
+};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ &kso13_gp04
+ &kso14_gp82
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/nissa/pujjo_motionsense.dts b/zephyr/projects/nissa/pujjo_motionsense.dts
new file mode 100644
index 0000000000..69ebf04c59
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_motionsense.dts
@@ -0,0 +1,163 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <dt-bindings/motionsense/utils.h>
+
+
+/ {
+ aliases {
+ /*
+ * Interrupt bindings for sensor devices.
+ */
+ lsm6dso-int = &base_accel;
+ lis2dw12-int = &lid_accel;
+ };
+
+ /*
+ * Declare mutexes used by sensor drivers.
+ * A mutex node is used to create an instance of mutex_t.
+ * A mutex node is referenced by a sensor node if the
+ * corresponding sensor driver needs to use the
+ * instance of the mutex.
+ */
+ motionsense-mutex {
+ compatible = "cros-ec,motionsense-mutex";
+ lid_mutex: lid-mutex {
+ label = "LID_MUTEX";
+ };
+
+ base_mutex: base-mutex {
+ label = "BASE_MUTEX";
+ };
+ };
+
+ /* Rotation matrix used by drivers. */
+ motionsense-rotation-ref {
+ compatible = "cros-ec,motionsense-rotation-ref";
+ lid_rot_ref: lid-rotation-ref {
+ mat33 = <(-1) 0 0
+ 0 1 0
+ 0 0 (-1)>;
+ };
+
+ base_rot_ref: base-rot-ref {
+ mat33 = <(-1) 0 0
+ 0 (-1) 0
+ 0 0 1>;
+ };
+ };
+
+ /*
+ * Driver specific data. A driver-specific data can be shared with
+ * different motion sensors while they are using the same driver.
+ *
+ * If a node's compatible starts with "cros-ec,accelgyro-", it is for
+ * a common structure defined in accelgyro.h.
+ * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for
+ * "struct als_drv_data_t" in accelgyro.h
+ */
+ motionsense-sensor-data {
+ lsm6dso_data: lsm6dso-drv-data {
+ compatible = "cros-ec,drvdata-lsm6dso";
+ status = "okay";
+ };
+
+ lis2dw12_data: lis2dw12-drv-data {
+ compatible = "cros-ec,drvdata-lis2dw12";
+ status = "okay";
+ };
+ };
+
+ /*
+ * List of motion sensors that creates motion_sensors array.
+ * The label "lid_accel" and "base_accel" are used to indicate
+ * motion sensor IDs for lid angle calculation.
+ * TODO:(b/229577857) The first entries of the array must be
+ * accelerometers,then gyroscope. Fix this dependency in the DTS
+ * processing which makes the devicetree entries independent.
+ */
+ motionsense-sensor {
+ lid_accel: lid-accel {
+ compatible = "cros-ec,lis2dw12";
+ status = "okay";
+
+ label = "Lid Accel";
+ active-mask = "SENSOR_ACTIVE_S0_S3";
+ location = "MOTIONSENSE_LOC_LID";
+ mutex = <&lid_mutex>;
+ port = <&i2c_ec_i2c_sensor>;
+ rot-standard-ref = <&lid_rot_ref>;
+ default-range = <2>;
+ drv-data = <&lis2dw12_data>;
+ i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS";
+ configs {
+ compatible =
+ "cros-ec,motionsense-sensor-config";
+ ec-s0 {
+ label = "SENSOR_CONFIG_EC_S0";
+ odr = <(10000 | ROUND_UP_FLAG)>;
+ };
+ ec-s3 {
+ label = "SENSOR_CONFIG_EC_S3";
+ odr = <(10000 | ROUND_UP_FLAG)>;
+ };
+ };
+ };
+
+ base_accel: base-accel {
+ compatible = "cros-ec,lsm6dso-accel";
+ status = "okay";
+
+ label = "Base Accel";
+ active-mask = "SENSOR_ACTIVE_S0_S3";
+ location = "MOTIONSENSE_LOC_BASE";
+ mutex = <&base_mutex>;
+ port = <&i2c_ec_i2c_sensor>;
+ /*
+ * May be replaced by alternate depending
+ * on board config.
+ */
+ rot-standard-ref = <&base_rot_ref>;
+ drv-data = <&lsm6dso_data>;
+ configs {
+ compatible =
+ "cros-ec,motionsense-sensor-config";
+ ec-s0 {
+ label = "SENSOR_CONFIG_EC_S0";
+ odr = <(10000 | ROUND_UP_FLAG)>;
+ };
+ ec-s3 {
+ label = "SENSOR_CONFIG_EC_S3";
+ odr = <(10000 | ROUND_UP_FLAG)>;
+ };
+ };
+ };
+
+ base_gyro: base-gyro {
+ compatible = "cros-ec,lsm6dso-gyro";
+ status = "okay";
+
+ label = "Base Gyro";
+ active-mask = "SENSOR_ACTIVE_S0_S3";
+ location = "MOTIONSENSE_LOC_BASE";
+ mutex = <&base_mutex>;
+ port = <&i2c_ec_i2c_sensor>;
+ rot-standard-ref = <&base_rot_ref>;
+ drv-data = <&lsm6dso_data>;
+ };
+ };
+
+ motionsense-sensor-info {
+ compatible = "cros-ec,motionsense-sensor-info";
+
+ /*
+ * list of GPIO interrupts that have to
+ * be enabled at initial stage
+ */
+ sensor-irqs = <&int_imu>;
+ /* list of sensors in force mode */
+ accel-force-mode-sensors = <&lid_accel>;
+ };
+};
diff --git a/zephyr/projects/nissa/pujjo_overlay.dts b/zephyr/projects/nissa/pujjo_overlay.dts
new file mode 100644
index 0000000000..c185d46e11
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_overlay.dts
@@ -0,0 +1,347 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <cros/thermistor/thermistor.dtsi>
+
+/ {
+ aliases {
+ gpio-cbi-wp = &gpio_ec_cbi_wp;
+ gpio-wp = &gpio_ec_wp_odl;
+ int-wp = &int_wp_l;
+ gpio-kbd-kso2 = &gpio_ec_kso_02_inv;
+ };
+
+ ec-console {
+ compatible = "ec-console";
+ disabled = "events", "lpc", "hostcmd";
+ };
+
+ batteries {
+ default_battery: lgc {
+ compatible = "lgc,ap18c8k", "battery-smart";
+ };
+ };
+
+ hibernate-wake-pins {
+ compatible = "cros-ec,hibernate-wake-pins";
+ wakeup-irqs = <
+ &int_power_button
+ &int_lid_open
+ >;
+ };
+
+ gpio-interrupts {
+ compatible = "cros-ec,gpio-interrupts";
+
+ int_power_button: power_button {
+ irq-pin = <&gpio_gsc_ec_pwr_btn_odl>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "power_button_interrupt";
+ };
+ int_wp_l: wp_l {
+ irq-pin = <&gpio_ec_wp_odl>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "switch_interrupt";
+ };
+ int_lid_open: lid_open {
+ irq-pin = <&gpio_lid_open>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "lid_interrupt";
+ };
+ int_tablet_mode: tablet_mode {
+ irq-pin = <&gpio_tablet_mode_l>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "gmr_tablet_switch_isr";
+ };
+ int_imu: ec_imu {
+ irq-pin = <&gpio_imu_int_l>;
+ flags = <GPIO_INT_EDGE_FALLING>;
+ handler = "lsm6dso_interrupt";
+ };
+ int_vol_down: vol_down {
+ irq-pin = <&gpio_voldn_btn_odl>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "button_interrupt";
+ };
+ int_vol_up: vol_up {
+ irq-pin = <&gpio_volup_btn_odl>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "button_interrupt";
+ };
+ int_usb_c0: usb_c0 {
+ irq-pin = <&gpio_usb_c0_int_odl>;
+ flags = <GPIO_INT_EDGE_FALLING>;
+ handler = "usb_interrupt";
+ };
+ int_usb_c1: usb_c1 {
+ irq-pin = <&gpio_sb_1>;
+ flags = <GPIO_INT_EDGE_FALLING>;
+ handler = "usb_interrupt";
+ };
+ };
+
+ named-gpios {
+ gpio_sb_1: sb_1 {
+ gpios = <&gpio0 2 GPIO_PULL_UP>;
+ no-auto-init;
+ };
+
+ gpio_sb_2: sb_2 {
+ gpios = <&gpiod 4 GPIO_OUTPUT>;
+ no-auto-init;
+ };
+
+ gpio_sb_3: sb_3 {
+ gpios = <&gpiof 4 GPIO_OPEN_DRAIN>;
+ no-auto-init;
+ };
+ gpio_sb_4: sb_4 {
+ gpios = <&gpiof 5 GPIO_INPUT>;
+ no-auto-init;
+ };
+ gpio_fan_enable: fan-enable {
+ gpios = <&gpio6 3 GPIO_OUTPUT>;
+ no-auto-init;
+ };
+ };
+
+ /*
+ * Aliases used for sub-board GPIOs.
+ */
+ aliases {
+ /*
+ * Input GPIO when used with type-C port 1
+ * Output when used with HDMI sub-board
+ */
+ gpio-usb-c1-int-odl = &gpio_sb_1;
+ gpio-en-rails-odl = &gpio_sb_1;
+ /*
+ * Sub-board with type A USB, enable.
+ */
+ gpio-en-usb-a1-vbus = &gpio_sb_2;
+ /*
+ * HPD pins for HDMI sub-board.
+ */
+ gpio-hdmi-en-odl = &gpio_sb_3;
+ gpio-hpd-odl = &gpio_sb_4;
+ /*
+ * Enable S5 rails for LTE sub-board
+ */
+ gpio-en-sub-s5-rails = &gpio_sb_2;
+ };
+
+ named-temp-sensors {
+ memory {
+ compatible = "cros-ec,temp-sensor-thermistor",
+ "cros-ec,temp-sensor";
+ thermistor = <&thermistor_3V3_51K1_47K_4050B>;
+ label = "DDR and SOC";
+ enum-name = "TEMP_SENSOR_1";
+ temp_fan_off = <35>;
+ temp_fan_max = <60>;
+ temp_host_high = <85>;
+ temp_host_halt = <90>;
+ temp_host_release_high = <80>;
+ adc = <&adc_temp_sensor_1>;
+ };
+ charger {
+ compatible = "cros-ec,temp-sensor-thermistor",
+ "cros-ec,temp-sensor";
+ thermistor = <&thermistor_3V3_51K1_47K_4050B>;
+ label = "Charger";
+ enum-name = "TEMP_SENSOR_2";
+ temp_fan_off = <35>;
+ temp_fan_max = <60>;
+ temp_host_high = <85>;
+ temp_host_halt = <90>;
+ temp_host_release_high = <80>;
+ adc = <&adc_temp_sensor_2>;
+ };
+ };
+
+ usba {
+ compatible = "cros-ec,usba-port-enable-pins";
+ /*
+ * sb_2 is only configured as GPIO when USB-A1 is present,
+ * but it's still safe to control when disabled.
+ *
+ * ILIM_SEL pins are referred to by legacy enum name,
+ * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on
+ * sub-boards that don't have USB-A so is safe to control
+ * regardless of system configuration.
+ */
+ enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>;
+ status = "okay";
+ };
+
+ usbc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port0@0 {
+ compatible = "named-usbc-port";
+ reg = <0>;
+ bc12 {
+ compatible = "pericom,pi3usb9201";
+ port = <&i2c_ec_i2c_usb_c0>;
+ /*
+ * BC1.2 interrupt is shared with TCPC, so
+ * IRQ is not specified here and handled by
+ * usb_c0_interrupt.
+ */
+ };
+ chg {
+ compatible = "intersil,isl923x";
+ status = "okay";
+ port = <&i2c_ec_i2c_usb_c0>;
+ };
+ usb-muxes = <&virtual_mux_0>;
+ };
+ port0-muxes {
+ virtual_mux_0: virtual-mux-0 {
+ compatible = "cros-ec,usbc-mux-virtual";
+ };
+ };
+ /*
+ * TODO(b:211693800): port1 may not be present on some
+ * sub-boards.
+ */
+ port1@1 {
+ compatible = "named-usbc-port";
+ reg = <1>;
+ bc12 {
+ compatible = "pericom,pi3usb9201";
+ port = <&i2c_ec_i2c_sub_usb_c1>;
+ };
+ chg {
+ compatible = "intersil,isl923x";
+ status = "okay";
+ port = <&i2c_ec_i2c_sub_usb_c1>;
+ };
+ /*
+ * Some sub-boards may disable all usb muxes in chain
+ * except virtual_mux_1
+ */
+ usb-muxes = <&virtual_mux_1 &anx7483_mux_1>;
+ };
+ port1-muxes {
+ virtual_mux_1: virtual-mux-1 {
+ compatible = "cros-ec,usbc-mux-virtual";
+ };
+ anx7483_mux_1: anx7483-mux-1 {
+ compatible = "analogix,anx7483";
+ port = <&i2c_ec_i2c_sub_usb_c1>;
+ i2c-addr-flags = "ANX7483_I2C_ADDR0_FLAGS";
+ };
+ };
+ };
+
+ fans {
+ compatible = "cros-ec,fans";
+
+ fan_0 {
+ pwms = <&pwm5 5 PWM_KHZ(1) PWM_POLARITY_NORMAL>;
+ pwm-frequency = <1000>;
+ rpm_min = <2200>;
+ rpm_start = <2200>;
+ rpm_max = <4200>;
+ tach = <&tach2>;
+ enable_gpio = <&gpio_fan_enable>;
+ };
+ };
+
+ /*
+ * Declare unused GPIOs so that they are shut down
+ * and use minimal power
+ */
+ unused-pins {
+ compatible = "unused-gpios";
+ unused-gpios =
+ <&gpio3 3 0>,
+ <&gpio3 6 0>,
+ <&gpiod 7 0>,
+ <&gpiof 2 0>,
+ <&gpiof 3 0>;
+ };
+};
+
+&thermistor_3V3_51K1_47K_4050B {
+ status = "okay";
+};
+
+&adc_ec_vsense_pp3300_s5 {
+ /*
+ * Voltage divider on input has 47k upper and 220k lower legs with
+ * 2714 mV full-scale reading on the ADC. Apply the largest possible
+ * multiplier (without overflowing int32) to get the best possible
+ * approximation of the actual ratio, but derate by a factor of two to
+ * ensure unexpectedly high values won't overflow.
+ */
+ mul = <(791261 / 2)>;
+ div = <(651975 / 2)>;
+};
+
+/* Set bus speeds for I2C */
+&i2c0_0 {
+ label = "I2C_EEPROM";
+ clock-frequency = <I2C_BITRATE_FAST>;
+
+ cbi_eeprom: eeprom@50 {
+ compatible = "atmel,at24";
+ reg = <0x50>;
+ label = "EEPROM_CBI";
+ size = <2048>;
+ pagesize = <16>;
+ address-width = <8>;
+ timeout = <5>;
+ };
+};
+
+&i2c1_0 {
+ label = "I2C_SENSOR";
+ clock-frequency = <I2C_BITRATE_FAST>;
+};
+
+&i2c3_0 {
+ label = "I2C_USB_C0_TCPC";
+ clock-frequency = <I2C_BITRATE_FAST_PLUS>;
+};
+
+&i2c5_1 {
+ label = "I2C_SUB_C1_TCPC";
+ clock-frequency = <I2C_BITRATE_FAST_PLUS>;
+};
+
+&i2c7_0 {
+ label = "I2C_BATTERY";
+ clock-frequency = <I2C_BITRATE_STANDARD>;
+};
+
+&pwm5_gpb7 {
+ drive-open-drain;
+};
+
+&pwm5 {
+ status = "okay";
+ pinctrl-0 = <&pwm5_gpb7>;
+ pinctrl-names = "default";
+};
+
+/* Tachometer for fan speed measurement */
+&tach2 {
+ status = "okay";
+ pinctrl-0 = <&ta2_1_in_gp73>;
+ pinctrl-names = "default";
+ port = <NPCX_TACH_PORT_A>; /* port-A is selected */
+ sample-clk = <NPCX_TACH_FREQ_LFCLK>; /* Use LFCLK as sampling clock */
+ pulses-per-round = <2>; /* number of pulses per round of encoder */
+};
+
+/* host interface */
+&espi0 {
+ status = "okay";
+ pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/nissa/pujjo_power_signals.dts b/zephyr/projects/nissa/pujjo_power_signals.dts
new file mode 100644
index 0000000000..91876f0402
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_power_signals.dts
@@ -0,0 +1,220 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/ {
+ chosen {
+ intel-ap-pwrseq,espi = &espi0;
+ };
+
+ common-pwrseq {
+ compatible = "intel,ap-pwrseq";
+
+ sys-pwrok-delay = <10>;
+ all-sys-pwrgd-timeout = <20>;
+ };
+
+ pwr-en-pp5000-s5 {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "PP5000_S5 enable output to regulator";
+ enum-name = "PWR_EN_PP5000_A";
+ gpios = <&gpio4 0 0>;
+ output;
+ };
+ pwr-en-pp3300-s5 {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "PP3300_S5 enable output to LS";
+ enum-name = "PWR_EN_PP3300_A";
+ gpios = <&gpiob 6 0>;
+ output;
+ };
+ pwr-pg-ec-rsmrst-od {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "RSMRST power good from regulator";
+ enum-name = "PWR_RSMRST";
+ gpios = <&gpio9 4 0>;
+ interrupt-flags = <GPIO_INT_EDGE_BOTH>;
+ };
+ pwr-ec-pch-rsmrst-odl {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "RSMRST output to PCH";
+ enum-name = "PWR_EC_PCH_RSMRST";
+ gpios = <&gpioa 6 0>;
+ output;
+ };
+ pwr-slp-s0-l {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "SLP_S0_L input from PCH";
+ enum-name = "PWR_SLP_S0";
+ gpios = <&gpio9 7 GPIO_ACTIVE_LOW>;
+ interrupt-flags = <GPIO_INT_EDGE_BOTH>;
+ };
+ pwr-slp-s3-l {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "SLP_S3_L input from PCH";
+ enum-name = "PWR_SLP_S3";
+ gpios = <&gpioa 5 GPIO_ACTIVE_LOW>;
+ interrupt-flags = <GPIO_INT_EDGE_BOTH>;
+ };
+ pwr-slp-sus-l {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "SLP_SUS_L input from PCH";
+ enum-name = "PWR_SLP_SUS";
+ gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
+ interrupt-flags = <GPIO_INT_EDGE_BOTH>;
+ };
+ pwr-ec-soc-dsw-pwrok {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "DSW_PWROK output to PCH";
+ enum-name = "PWR_EC_SOC_DSW_PWROK";
+ gpios = <&gpio6 1 0>;
+ output;
+ };
+ pwr-vccst-pwrgd-od {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "VCCST_PWRGD output to PCH";
+ enum-name = "PWR_VCCST_PWRGD";
+ gpios = <&gpioa 4 GPIO_OPEN_DRAIN>;
+ output;
+ };
+ pwr-imvp9-vrrdy-od {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "VRRDY input from IMVP9";
+ enum-name = "PWR_IMVP9_VRRDY";
+ gpios = <&gpio4 3 0>;
+ };
+ pwr-pch-pwrok {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "PCH_PWROK output to PCH";
+ enum-name = "PWR_PCH_PWROK";
+ gpios = <&gpio7 2 GPIO_OPEN_DRAIN>;
+ output;
+ };
+ pwr-ec-pch-sys-pwrok {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "SYS_PWROK output to PCH";
+ enum-name = "PWR_EC_PCH_SYS_PWROK";
+ gpios = <&gpio3 7 0>;
+ output;
+ };
+ pwr-sys-rst-l {
+ compatible = "intel,ap-pwrseq-gpio";
+ dbg-label = "SYS_RESET# output to PCH";
+ enum-name = "PWR_SYS_RST";
+ gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>;
+ output;
+ };
+ pwr-slp-s4 {
+ compatible = "intel,ap-pwrseq-vw";
+ dbg-label = "SLP_S4 virtual wire input from PCH";
+ enum-name = "PWR_SLP_S4";
+ virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4";
+ vw-invert;
+ };
+ pwr-slp-s5 {
+ compatible = "intel,ap-pwrseq-vw";
+ dbg-label = "SLP_S5 virtual wire input from PCH";
+ enum-name = "PWR_SLP_S5";
+ virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5";
+ vw-invert;
+ };
+ pwr-all-sys-pwrgd {
+ compatible = "intel,ap-pwrseq-external";
+ dbg-label = "Combined all power good";
+ enum-name = "PWR_ALL_SYS_PWRGD";
+ };
+ pwr-adc-pp3300 {
+ compatible = "intel,ap-pwrseq-adc";
+ dbg-label = "PP3300 PWROK (from ADC)";
+ enum-name = "PWR_DSW_PWROK";
+ trigger-high = <&cmp_pp3300_s5_high>;
+ trigger-low = <&cmp_pp3300_s5_low>;
+ };
+ pwr-adc-pp1p05 {
+ compatible = "intel,ap-pwrseq-adc";
+ dbg-label = "PP1P05 PWROK (from ADC)";
+ enum-name = "PWR_PG_PP1P05";
+ trigger-high = <&cmp_pp1p05_high>;
+ trigger-low = <&cmp_pp1p05_low>;
+ };
+
+ adc-cmp {
+ cmp_pp3300_s5_high: pp3300_high {
+ compatible = "nuvoton,adc-cmp";
+ io-channels = <&adc0 6>;
+ comparison = "ADC_CMP_NPCX_GREATER";
+ /*
+ * This is 90% of nominal voltage considering voltage
+ * divider on ADC input.
+ */
+ threshold-mv = <2448>;
+ };
+ cmp_pp3300_s5_low: pp3300_low {
+ compatible = "nuvoton,adc-cmp";
+ io-channels = <&adc0 6>;
+ comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL";
+ threshold-mv = <2448>;
+ };
+ cmp_pp1p05_high: pp1p05_high {
+ compatible = "nuvoton,adc-cmp";
+ io-channels = <&adc0 4>;
+ comparison = "ADC_CMP_NPCX_GREATER";
+ /* Setting at 90% of nominal voltage */
+ threshold-mv = <945>;
+ };
+ cmp_pp1p05_low: pp1p05_low {
+ compatible = "nuvoton,adc-cmp";
+ io-channels = <&adc0 4>;
+ comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL";
+ threshold-mv = <945>;
+ };
+ };
+};
+
+/*
+ * Because the power signals directly reference the GPIOs,
+ * the correspinding named-gpios need to have no-auto-init set.
+ */
+&gpio_ec_soc_dsw_pwrok {
+ no-auto-init;
+};
+&gpio_ec_soc_pch_pwrok_od {
+ no-auto-init;
+};
+&gpio_ec_soc_rsmrst_l {
+ no-auto-init;
+};
+&gpio_ec_soc_sys_pwrok {
+ no-auto-init;
+};
+&gpio_ec_soc_vccst_pwrgd_od {
+ no-auto-init;
+};
+&gpio_en_pp3300_s5 {
+ no-auto-init;
+};
+&gpio_en_pp5000_s5 {
+ no-auto-init;
+};
+&gpio_imvp91_vrrdy_od {
+ no-auto-init;
+};
+&gpio_rsmrst_pwrgd_l {
+ no-auto-init;
+};
+&gpio_slp_s0_l {
+ no-auto-init;
+};
+&gpio_slp_s3_l {
+ no-auto-init;
+};
+&gpio_slp_s4_l {
+ no-auto-init;
+};
+&gpio_slp_sus_l {
+ no-auto-init;
+};
+&gpio_sys_rst_odl {
+ no-auto-init;
+};
diff --git a/zephyr/projects/nissa/pujjo_pwm_leds.dts b/zephyr/projects/nissa/pujjo_pwm_leds.dts
new file mode 100644
index 0000000000..b6f657fb03
--- /dev/null
+++ b/zephyr/projects/nissa/pujjo_pwm_leds.dts
@@ -0,0 +1,63 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/ {
+ pwmleds {
+ compatible = "pwm-leds";
+ pwm_led0: pwm_led_0 {
+ pwms = <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>,
+ <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>,
+ <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>;
+ };
+ };
+
+ cros-pwmleds {
+ compatible = "cros-ec,pwm-leds";
+
+ leds = <&pwm_led0>;
+ frequency = <324>;
+
+ /*<red green blue>*/
+ color-map-red = <100 0 0>;
+ color-map-green = < 0 100 0>;
+ color-map-blue = < 0 0 100>;
+ color-map-yellow = < 0 50 50>;
+ color-map-white = <100 100 100>;
+ color-map-amber = <100 20 100>;
+
+ brightness-range = <100 100 100 0 0 0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pwm_led_0@0 {
+ reg = <0>;
+ ec-led-name = "EC_LED_ID_BATTERY_LED";
+ };
+ };
+};
+
+/* Enable LEDs to work while CPU suspended */
+
+&pwm0 {
+ status = "okay";
+ clock-bus = "NPCX_CLOCK_BUS_LFCLK";
+ pinctrl-0 = <&pwm0_gpc3>;
+ pinctrl-names = "default";
+};
+
+&pwm1 {
+ status = "okay";
+ clock-bus = "NPCX_CLOCK_BUS_LFCLK";
+ pinctrl-0 = <&pwm1_gpc2>;
+ pinctrl-names = "default";
+};
+
+&pwm2 {
+ status = "okay";
+ clock-bus = "NPCX_CLOCK_BUS_LFCLK";
+ pinctrl-0 = <&pwm2_gpc4>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/nissa/src/craask/led.c b/zephyr/projects/nissa/src/craask/led.c
index 53274f6c44..a0c0447419 100644
--- a/zephyr/projects/nissa/src/craask/led.c
+++ b/zephyr/projects/nissa/src/craask/led.c
@@ -18,6 +18,7 @@ __override struct led_descriptor
[STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
[STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} },
[STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} },
+ [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
[STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC},
{LED_OFF, 3 * LED_ONE_SEC} },
[STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} },
diff --git a/zephyr/projects/nissa/src/craask/usbc.c b/zephyr/projects/nissa/src/craask/usbc.c
index 0604411be0..32a390e502 100644
--- a/zephyr/projects/nissa/src/craask/usbc.c
+++ b/zephyr/projects/nissa/src/craask/usbc.c
@@ -10,6 +10,7 @@
#include "hooks.h"
#include "usb_mux.h"
#include "system.h"
+#include "driver/charger/isl923x_public.h"
#include "driver/retimer/anx7483_public.h"
#include "driver/tcpm/tcpci.h"
#include "driver/tcpm/raa489000.h"
@@ -67,9 +68,11 @@ int board_set_active_charge_port(int port)
/* Disable all ports. */
if (port == CHARGE_PORT_NONE) {
- for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++)
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
tcpc_write(i, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_LOW);
+ raa489000_enable_asgate(i, false);
+ }
return EC_SUCCESS;
}
@@ -91,6 +94,7 @@ int board_set_active_charge_port(int port)
if (tcpc_write(i, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_LOW))
LOG_WRN("p%d: sink path disable failed.", i);
+ raa489000_enable_asgate(i, false);
}
/*
@@ -101,7 +105,8 @@ int board_set_active_charge_port(int port)
charger_discharge_on_ac(1);
/* Enable requested charge port. */
- if (tcpc_write(port, TCPC_REG_COMMAND,
+ if (raa489000_enable_asgate(port, true) ||
+ tcpc_write(port, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_HIGH)) {
LOG_WRN("p%d: sink path enable failed.", port);
charger_discharge_on_ac(0);
@@ -188,6 +193,10 @@ int pd_set_power_supply_ready(int port)
if (rv)
return rv;
+ rv = raa489000_enable_asgate(port, true);
+ if (rv)
+ return rv;
+
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
diff --git a/zephyr/projects/nissa/src/led.c b/zephyr/projects/nissa/src/led.c
index fa28ccc179..27c78f8051 100644
--- a/zephyr/projects/nissa/src/led.c
+++ b/zephyr/projects/nissa/src/led.c
@@ -18,6 +18,8 @@ __override struct led_descriptor
[STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} },
[STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_GREEN, LED_INDEFINITE} },
[STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} },
+ [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC},
+ {LED_OFF, 3 * LED_ONE_SEC} },
[STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} },
[STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} },
[STATE_BATTERY_ERROR] = {{EC_LED_COLOR_RED, 1 * LED_ONE_SEC},
diff --git a/zephyr/projects/nissa/src/nereid/usbc.c b/zephyr/projects/nissa/src/nereid/usbc.c
index e731b73a76..eeab449c32 100644
--- a/zephyr/projects/nissa/src/nereid/usbc.c
+++ b/zephyr/projects/nissa/src/nereid/usbc.c
@@ -63,22 +63,19 @@ void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled)
__override bool pd_check_vbus_level(int port, enum vbus_level level)
{
- /*
- * While the charger can differentiate SAFE0V from REMOVED, doing so
- * requires doing a I2C read of the VBUS analog level. Because this
- * function can be polled by the USB state machines and doing the I2C
- * read is relatively costly, we only check the cached VBUS presence
- * (for which interrupts record transitions).
- */
- switch (level) {
- case VBUS_PRESENT:
- return sm5803_is_vbus_present(port);
- case VBUS_SAFE0V: /* Less than vSafe0V */
- case VBUS_REMOVED: /* Less than vSinkDisconnect */
- return !sm5803_is_vbus_present(port);
+ int vbus_voltage;
+
+ /* If we're unable to speak to the charger, best to guess false */
+ if (charger_get_vbus_voltage(port, &vbus_voltage)) {
+ return false;
}
- LOG_WRN("Unrecognized vbus_level value: %d", level);
- return false;
+
+ if (level == VBUS_SAFE0V)
+ return vbus_voltage < PD_V_SAFE0V_MAX;
+ else if (level == VBUS_PRESENT)
+ return vbus_voltage > PD_V_SAFE5V_MIN;
+ else
+ return vbus_voltage < PD_V_SINK_DISCONNECT_MAX;
}
/*
diff --git a/zephyr/projects/nissa/src/nivviks/usbc.c b/zephyr/projects/nissa/src/nivviks/usbc.c
index 0b061d2bd5..c068eba6f4 100644
--- a/zephyr/projects/nissa/src/nivviks/usbc.c
+++ b/zephyr/projects/nissa/src/nivviks/usbc.c
@@ -10,6 +10,7 @@
#include "hooks.h"
#include "usb_mux.h"
#include "system.h"
+#include "driver/charger/isl923x_public.h"
#include "driver/retimer/anx7483_public.h"
#include "driver/tcpm/tcpci.h"
#include "driver/tcpm/raa489000.h"
@@ -67,9 +68,11 @@ int board_set_active_charge_port(int port)
/* Disable all ports. */
if (port == CHARGE_PORT_NONE) {
- for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++)
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
tcpc_write(i, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_LOW);
+ raa489000_enable_asgate(i, false);
+ }
return EC_SUCCESS;
}
@@ -91,6 +94,7 @@ int board_set_active_charge_port(int port)
if (tcpc_write(i, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_LOW))
LOG_WRN("p%d: sink path disable failed.", i);
+ raa489000_enable_asgate(i, false);
}
/*
@@ -101,7 +105,8 @@ int board_set_active_charge_port(int port)
charger_discharge_on_ac(1);
/* Enable requested charge port. */
- if (tcpc_write(port, TCPC_REG_COMMAND,
+ if (raa489000_enable_asgate(port, true) ||
+ tcpc_write(port, TCPC_REG_COMMAND,
TCPC_REG_COMMAND_SNK_CTRL_HIGH)) {
LOG_WRN("p%d: sink path enable failed.", port);
charger_discharge_on_ac(0);
@@ -188,6 +193,10 @@ int pd_set_power_supply_ready(int port)
if (rv)
return rv;
+ rv = raa489000_enable_asgate(port, true);
+ if (rv)
+ return rv;
+
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
diff --git a/zephyr/projects/nissa/src/pujjo/charger.c b/zephyr/projects/nissa/src/pujjo/charger.c
new file mode 100644
index 0000000000..c6209bdf75
--- /dev/null
+++ b/zephyr/projects/nissa/src/pujjo/charger.c
@@ -0,0 +1,56 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr/logging/log.h>
+
+#include "battery.h"
+#include "charger.h"
+#include "charger/isl923x_public.h"
+#include "console.h"
+#include "extpower.h"
+#include "usb_pd.h"
+#include "nissa_common.h"
+
+LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL);
+
+int extpower_is_present(void)
+{
+ int port;
+ int rv;
+ bool acok;
+
+ for (port = 0; port < board_get_usb_pd_port_count(); port++) {
+ rv = raa489000_is_acok(port, &acok);
+ if ((rv == EC_SUCCESS) && acok)
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Pujjo does not have a GPIO indicating whether extpower is present,
+ * so detect using the charger(s).
+ */
+__override void board_check_extpower(void)
+{
+ static int last_extpower_present;
+ int extpower_present = extpower_is_present();
+
+ if (last_extpower_present ^ extpower_present)
+ extpower_handle_update(extpower_present);
+
+ last_extpower_present = extpower_present;
+}
+
+__override void board_hibernate(void)
+{
+ /* Shut down the chargers */
+ if (board_get_usb_pd_port_count() == 2)
+ raa489000_hibernate(CHARGER_SECONDARY, true);
+ raa489000_hibernate(CHARGER_PRIMARY, true);
+ LOG_INF("Charger(s) hibernated");
+ cflush();
+}
diff --git a/zephyr/projects/nissa/src/pujjo/fan.c b/zephyr/projects/nissa/src/pujjo/fan.c
new file mode 100644
index 0000000000..8914774452
--- /dev/null
+++ b/zephyr/projects/nissa/src/pujjo/fan.c
@@ -0,0 +1,45 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr/devicetree.h>
+#include <zephyr/drivers/gpio.h>
+#include <zephyr/logging/log.h>
+
+#include "cros_cbi.h"
+#include "fan.h"
+#include "gpio/gpio.h"
+#include "hooks.h"
+
+#include "nissa_common.h"
+
+LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL);
+
+/*
+ * Pujjo fan support
+ */
+static void fan_init(void)
+{
+ int ret;
+ uint32_t val;
+ /*
+ * Retrieve the fan config.
+ */
+ ret = cros_cbi_get_fw_config(FW_FAN, &val);
+ if (ret != 0) {
+ LOG_ERR("Error retrieving CBI FW_CONFIG field %d",
+ FW_FAN);
+ return;
+ }
+ if (val != FW_FAN_PRESENT) {
+ /* Disable the fan */
+ fan_set_count(0);
+ } else {
+ /* Configure the fan enable GPIO */
+ gpio_pin_configure_dt(
+ GPIO_DT_FROM_NODELABEL(gpio_fan_enable),
+ GPIO_OUTPUT);
+ }
+}
+DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_POST_FIRST);
diff --git a/zephyr/projects/nissa/src/pujjo/keyboard.c b/zephyr/projects/nissa/src/pujjo/keyboard.c
new file mode 100644
index 0000000000..e6d819e348
--- /dev/null
+++ b/zephyr/projects/nissa/src/pujjo/keyboard.c
@@ -0,0 +1,29 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ec_commands.h"
+
+static const struct ec_response_keybd_config pujjo_kb = {
+ .num_top_row_keys = 10,
+ .action_keys = {
+ TK_BACK, /* T1 */
+ TK_REFRESH, /* T2 */
+ TK_FULLSCREEN, /* T3 */
+ TK_OVERVIEW, /* T4 */
+ TK_SNAPSHOT, /* T5 */
+ TK_BRIGHTNESS_DOWN, /* T6 */
+ TK_BRIGHTNESS_UP, /* T7 */
+ TK_VOL_MUTE, /* T8 */
+ TK_VOL_DOWN, /* T9 */
+ TK_VOL_UP, /* T10 */
+ },
+ .capabilities = KEYBD_CAP_SCRNLOCK_KEY,
+};
+
+__override const struct ec_response_keybd_config
+*board_vivaldi_keybd_config(void)
+{
+ return &pujjo_kb;
+}
diff --git a/zephyr/projects/nissa/src/pujjo/usbc.c b/zephyr/projects/nissa/src/pujjo/usbc.c
new file mode 100644
index 0000000000..020f78dbdd
--- /dev/null
+++ b/zephyr/projects/nissa/src/pujjo/usbc.c
@@ -0,0 +1,281 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr/logging/log.h>
+
+#include "charge_state_v2.h"
+#include "chipset.h"
+#include "hooks.h"
+#include "usb_mux.h"
+#include "system.h"
+#include "driver/charger/isl923x_public.h"
+#include "driver/retimer/anx7483_public.h"
+#include "driver/tcpm/tcpci.h"
+#include "driver/tcpm/raa489000.h"
+
+#include "nissa_common.h"
+
+LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL);
+
+struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0_TCPC,
+ .addr_flags = RAA489000_TCPC0_I2C_FLAGS,
+ },
+ .drv = &raa489000_tcpm_drv,
+ /* RAA489000 implements TCPCI 2.0 */
+ .flags = TCPC_FLAGS_TCPCI_REV2_0 |
+ TCPC_FLAGS_VBUS_MONITOR,
+ },
+ { /* sub-board */
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C1_TCPC,
+ .addr_flags = RAA489000_TCPC0_I2C_FLAGS,
+ },
+ .drv = &raa489000_tcpm_drv,
+ /* RAA489000 implements TCPCI 2.0 */
+ .flags = TCPC_FLAGS_TCPCI_REV2_0 |
+ TCPC_FLAGS_VBUS_MONITOR,
+ },
+};
+
+int board_is_sourcing_vbus(int port)
+{
+ int regval;
+
+ tcpc_read(port, TCPC_REG_POWER_STATUS, &regval);
+ return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS);
+}
+
+int board_set_active_charge_port(int port)
+{
+ int is_real_port = (port >= 0 &&
+ port < CONFIG_USB_PD_PORT_MAX_COUNT);
+ int i;
+ int old_port;
+
+ if (!is_real_port && port != CHARGE_PORT_NONE)
+ return EC_ERROR_INVAL;
+
+ old_port = charge_manager_get_active_charge_port();
+
+ LOG_INF("New chg p%d", port);
+
+ /* Disable all ports. */
+ if (port == CHARGE_PORT_NONE) {
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ tcpc_write(i, TCPC_REG_COMMAND,
+ TCPC_REG_COMMAND_SNK_CTRL_LOW);
+ raa489000_enable_asgate(i, false);
+ }
+
+ return EC_SUCCESS;
+ }
+
+ /* Check if port is sourcing VBUS. */
+ if (board_is_sourcing_vbus(port)) {
+ LOG_WRN("Skip enable p%d", port);
+ return EC_ERROR_INVAL;
+ }
+
+ /*
+ * Turn off the other ports' sink path FETs, before enabling the
+ * requested charge port.
+ */
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ if (i == port)
+ continue;
+
+ if (tcpc_write(i, TCPC_REG_COMMAND,
+ TCPC_REG_COMMAND_SNK_CTRL_LOW))
+ LOG_WRN("p%d: sink path disable failed.", i);
+ raa489000_enable_asgate(i, false);
+ }
+
+ /*
+ * Stop the charger IC from switching while changing ports. Otherwise,
+ * we can overcurrent the adapter we're switching to. (crbug.com/926056)
+ */
+ if (old_port != CHARGE_PORT_NONE)
+ charger_discharge_on_ac(1);
+
+ /* Enable requested charge port. */
+ if (raa489000_enable_asgate(port, true) ||
+ tcpc_write(port, TCPC_REG_COMMAND,
+ TCPC_REG_COMMAND_SNK_CTRL_HIGH)) {
+ LOG_WRN("p%d: sink path enable failed.", port);
+ charger_discharge_on_ac(0);
+ return EC_ERROR_UNKNOWN;
+ }
+
+ /* Allow the charger IC to begin/continue switching. */
+ charger_discharge_on_ac(0);
+
+ return EC_SUCCESS;
+}
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+ int regval;
+
+ /*
+ * The interrupt line is shared between the TCPC and BC1.2 detector IC.
+ * Therefore, go out and actually read the alert registers to report the
+ * alert status.
+ */
+ if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) {
+ if (!tcpc_read16(0, TCPC_REG_ALERT, &regval)) {
+ /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */
+ if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0))
+ regval &= ~((1 << 14) | (1 << 13) | (1 << 12));
+
+ if (regval)
+ status |= PD_STATUS_TCPC_ALERT_0;
+ }
+ }
+
+ if (board_get_usb_pd_port_count() == 2 &&
+ !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) {
+ if (!tcpc_read16(1, TCPC_REG_ALERT, &regval)) {
+ /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */
+ if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0))
+ regval &= ~((1 << 14) | (1 << 13) | (1 << 12));
+
+ if (regval)
+ status |= PD_STATUS_TCPC_ALERT_1;
+ }
+ }
+
+ return status;
+}
+
+void pd_power_supply_reset(int port)
+{
+ /* Disable VBUS */
+ tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW);
+
+ /* Notify host of power info change. */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+}
+
+__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
+{
+ if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT)
+ return;
+
+ raa489000_set_output_current(port, rp);
+}
+
+int pd_set_power_supply_ready(int port)
+{
+ int rv;
+
+ if (port >= CONFIG_USB_PD_PORT_MAX_COUNT)
+ return EC_ERROR_INVAL;
+
+ /* Disable charging. */
+ rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW);
+ if (rv)
+ return rv;
+
+ /* Our policy is not to source VBUS when the AP is off. */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ return EC_ERROR_NOT_POWERED;
+
+ /* Provide Vbus. */
+ rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH);
+ if (rv)
+ return rv;
+
+ rv = raa489000_enable_asgate(port, true);
+ if (rv)
+ return rv;
+
+ /* Notify host of power info change. */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+
+ return EC_SUCCESS;
+}
+
+void board_reset_pd_mcu(void)
+{
+ /*
+ * TODO(b:147316511): could send a reset command to the TCPC here
+ * if needed.
+ */
+}
+
+/*
+ * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible
+ * for an interrupt to be lost if one asserts the IRQ, the other does the same
+ * then the first releases it: there will only be one falling edge to trigger
+ * the interrupt, and the line will be held low. We handle this by running a
+ * deferred check after a falling edge to see whether the IRQ is still being
+ * asserted. If it is, we assume an interrupt may have been lost and we need
+ * to poll each chip for events again.
+ */
+#define USBC_INT_POLL_DELAY_US 5000
+
+static void poll_c0_int(void);
+DECLARE_DEFERRED(poll_c0_int);
+static void poll_c1_int(void);
+DECLARE_DEFERRED(poll_c1_int);
+
+static void usbc_interrupt_trigger(int port)
+{
+ schedule_deferred_pd_interrupt(port);
+ usb_charger_task_set_event(port, USB_CHG_EVENT_BC12);
+}
+
+static inline void poll_usb_gpio(int port,
+ const struct gpio_dt_spec *gpio,
+ const struct deferred_data *ud)
+{
+ if (!gpio_pin_get_dt(gpio)) {
+ usbc_interrupt_trigger(port);
+ hook_call_deferred(ud, USBC_INT_POLL_DELAY_US);
+ }
+}
+
+static void poll_c0_int (void)
+{
+ poll_usb_gpio(0,
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl),
+ &poll_c0_int_data);
+}
+
+static void poll_c1_int (void)
+{
+ poll_usb_gpio(1,
+ GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl),
+ &poll_c1_int_data);
+}
+
+void usb_interrupt(enum gpio_signal signal)
+{
+ int port;
+ const struct deferred_data *ud;
+
+ if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) {
+ port = 0;
+ ud = &poll_c0_int_data;
+ } else {
+ port = 1;
+ ud = &poll_c1_int_data;
+ }
+ /*
+ * We've just been called from a falling edge, so there's definitely
+ * no lost IRQ right now. Cancel any pending check.
+ */
+ hook_call_deferred(ud, -1);
+ /* Trigger polling of TCPC and BC1.2 in respective tasks */
+ usbc_interrupt_trigger(port);
+ /* Check for lost interrupts in a bit */
+ hook_call_deferred(ud, USBC_INT_POLL_DELAY_US);
+}
diff --git a/zephyr/projects/npcx_evb/npcx9/keyboard.dts b/zephyr/projects/npcx_evb/npcx9/keyboard.dts
index e2a5010952..e3ce1b1e20 100644
--- a/zephyr/projects/npcx_evb/npcx9/keyboard.dts
+++ b/zephyr/projects/npcx_evb/npcx9/keyboard.dts
@@ -41,3 +41,31 @@
pinctrl-0 = <&pwm2_gpc4>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &alt7_no_ksi0_sl
+ &alt7_no_ksi1_sl
+ &alt7_no_ksi2_sl
+ &alt7_no_ksi3_sl
+ &alt7_no_ksi4_sl
+ &alt7_no_ksi5_sl
+ &alt7_no_ksi6_sl
+ &alt7_no_ksi7_sl
+ &alt8_no_kso00_sl
+ &alt8_no_kso01_sl
+ &alt8_no_kso03_sl
+ &alt8_no_kso04_sl
+ &alt8_no_kso05_sl
+ &alt8_no_kso06_sl
+ &alt8_no_kso07_sl
+ &alt9_no_kso08_sl
+ &alt9_no_kso09_sl
+ &alt9_no_kso10_sl
+ &alt9_no_kso11_sl
+ &alt9_no_kso12_sl
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/skyrim/include/gpio_map.h b/zephyr/projects/skyrim/include/gpio_map.h
index 969549bc5d..ca1272a9ed 100644
--- a/zephyr/projects/skyrim/include/gpio_map.h
+++ b/zephyr/projects/skyrim/include/gpio_map.h
@@ -23,5 +23,6 @@ enum power_signal {
#define GPIO_ENTERING_RW GPIO_UNIMPLEMENTED
#define GPIO_PCH_SYS_PWROK GPIO_UNIMPLEMENTED
+#define GPIO_PCH_SLP_S0_L GPIO_PCH_SLP_S3_L
#endif /* __ZEPHYR_GPIO_MAP_H */
diff --git a/zephyr/projects/skyrim/keyboard.dts b/zephyr/projects/skyrim/keyboard.dts
index 792e6074d1..216ea97045 100644
--- a/zephyr/projects/skyrim/keyboard.dts
+++ b/zephyr/projects/skyrim/keyboard.dts
@@ -17,3 +17,31 @@
pinctrl-0 = <&pwm1_gpc2>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <
+ &ksi0_gp31
+ &ksi1_gp30
+ &ksi2_gp27
+ &ksi3_gp26
+ &ksi4_gp25
+ &ksi5_gp24
+ &ksi6_gp23
+ &ksi7_gp22
+ &kso00_gp21
+ &kso01_gp20
+ &kso03_gp16
+ &kso04_gp15
+ &kso05_gp14
+ &kso06_gp13
+ &kso07_gp12
+ &kso08_gp11
+ &kso09_gp10
+ &kso10_gp07
+ &kso11_gp06
+ &kso12_gp05
+ >;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/projects/skyrim/prj.conf b/zephyr/projects/skyrim/prj.conf
index aea666c234..47e9c1d096 100644
--- a/zephyr/projects/skyrim/prj.conf
+++ b/zephyr/projects/skyrim/prj.conf
@@ -19,7 +19,9 @@ CONFIG_AP=y
CONFIG_AP_X86_AMD=y
CONFIG_PLATFORM_EC_POWERSEQ=y
CONFIG_PLATFORM_EC_POWER_BUTTON_TO_PCH_CUSTOM=y
+CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y
CONFIG_PLATFORM_EC_POWERSEQ_RSMRST_DELAY=y
+CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y
CONFIG_PLATFORM_EC_PORT80=y
# Power button
diff --git a/zephyr/projects/skyrim/usbc_config.c b/zephyr/projects/skyrim/usbc_config.c
index 7e3b6ba486..fe60db2a69 100644
--- a/zephyr/projects/skyrim/usbc_config.c
+++ b/zephyr/projects/skyrim/usbc_config.c
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* Guybrush family-specific USB-C configuration */
+/* Skyrim family-specific USB-C configuration */
#include <zephyr/drivers/gpio.h>
@@ -110,18 +110,69 @@ struct usb_mux usbc1_sbu_mux = {
.driver = &ioex_sbu_mux_driver,
};
-int baseboard_anx7483_mux_set(const struct usb_mux *me,
+int baseboard_anx7483_c0_mux_set(const struct usb_mux *me,
mux_state_t mux_state)
{
return anx7483_set_default_tuning(me, mux_state);
}
+int baseboard_anx7483_c1_mux_set(const struct usb_mux *me,
+ mux_state_t mux_state)
+{
+ bool flipped = mux_state & USB_PD_MUX_POLARITY_INVERTED;
+
+ /* Remove flipped from the state for easier compraisons */
+ mux_state = mux_state & ~USB_PD_MUX_POLARITY_INVERTED;
+
+ RETURN_ERROR(anx7483_set_default_tuning(me, mux_state));
+
+ if (mux_state == USB_PD_MUX_USB_ENABLED) {
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_DRX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_DRX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ } else if (mux_state == USB_PD_MUX_DP_ENABLED) {
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_UTX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_UTX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ } else if (mux_state == USB_PD_MUX_DOCK && !flipped) {
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_DRX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_UTX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ } else if (mux_state == USB_PD_MUX_DOCK && flipped) {
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_URX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_UTX1,
+ ANX7483_EQ_SETTING_12_5DB));
+ RETURN_ERROR(anx7483_set_eq(me, ANX7483_PIN_DRX2,
+ ANX7483_EQ_SETTING_12_5DB));
+ }
+
+ return EC_SUCCESS;
+}
+
struct usb_mux usbc0_anx7483 = {
.usb_port = USBC_PORT_C0,
.i2c_port = I2C_PORT_TCPC0,
.i2c_addr_flags = ANX7483_I2C_ADDR0_FLAGS,
.driver = &anx7483_usb_retimer_driver,
- .board_set = &baseboard_anx7483_mux_set,
+ .board_set = &baseboard_anx7483_c0_mux_set,
.next_mux = &usbc0_sbu_mux,
};
@@ -129,6 +180,13 @@ __overridable int board_c1_ps8818_mux_set(const struct usb_mux *me,
mux_state_t mux_state)
{
CPRINTSUSB("C1: PS8818 mux using default tuning");
+
+ /* Once a DP connection is established, we need to set IN_HPD */
+ if (mux_state & USB_PD_MUX_DP_ENABLED)
+ ioex_set_level(IOEX_USB_C1_HPD_IN_DB, 1);
+ else
+ ioex_set_level(IOEX_USB_C1_HPD_IN_DB, 0);
+
return 0;
}
@@ -146,7 +204,7 @@ struct usb_mux usbc1_anx7483 = {
.i2c_port = I2C_PORT_TCPC1,
.i2c_addr_flags = ANX7483_I2C_ADDR0_FLAGS,
.driver = &anx7483_usb_retimer_driver,
- .board_set = &baseboard_anx7483_mux_set,
+ .board_set = &baseboard_anx7483_c1_mux_set,
.next_mux = &usbc1_sbu_mux,
};
@@ -168,8 +226,6 @@ struct usb_mux usb_muxes[] = {
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == CONFIG_USB_PD_PORT_MAX_COUNT);
-/* TODO: HPD signal on PS8818 DB */
-
/*
* USB C0 (general) and C1 (just ANX DB) use IOEX pins to
* indicate flipped polarity to a protection switch.
@@ -350,10 +406,10 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
/* TODO: sbu_fault_interrupt from io expander */
/* Round up 3250 max current to multiple of 128mA for ISL9241 AC prochot. */
-#define GUYBRUSH_AC_PROCHOT_CURRENT_MA 3328
+#define SKYRIM_AC_PROCHOT_CURRENT_MA 3328
static void set_ac_prochot(void)
{
- isl9241_set_ac_prochot(CHARGER_SOLO, GUYBRUSH_AC_PROCHOT_CURRENT_MA);
+ isl9241_set_ac_prochot(CHARGER_SOLO, SKYRIM_AC_PROCHOT_CURRENT_MA);
}
DECLARE_HOOK(HOOK_INIT, set_ac_prochot, HOOK_PRIO_DEFAULT);
diff --git a/zephyr/shim/chip/mchp/include/flash_chip.h b/zephyr/shim/chip/mchp/include/flash_chip.h
index 9af8bd330d..b3677fb45c 100644
--- a/zephyr/shim/chip/mchp/include/flash_chip.h
+++ b/zephyr/shim/chip/mchp/include/flash_chip.h
@@ -11,15 +11,19 @@
* Similar to W25X40, both only have one status reg
*/
#define CONFIG_SPI_FLASH_W25X40 /* Internal SPI flash type. */
-
#define CONFIG_FLASH_WRITE_SIZE 0x1 /* minimum write size */
#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 /* one page size for write */
-#define CONFIG_FLASH_ERASE_SIZE 0x10000
+#define CONFIG_FLASH_ERASE_SIZE 0x1000
#define CONFIG_FLASH_BANK_SIZE CONFIG_FLASH_ERASE_SIZE
-/* RO image resides at start of protected region, right after header */
-#define CONFIG_RO_STORAGE_OFF CONFIG_RO_HDR_SIZE
-
-#define CONFIG_RW_STORAGE_OFF 0
+/* RO image resides at 4KB offset in protected region
+ * The first 4KB in the protected region starting at offset 0 contains
+ * the Boot-ROM TAGs and Boot-ROM Header for EC_RO. These objects are
+ * not loaded into RAM.
+ * RW image is never loaded by the Boot-ROM therefore no TAG or Header
+ * is needed. RW starts at offset 0 in RW storage region.
+ */
+#define CONFIG_RO_STORAGE_OFF 0x1000
+#define CONFIG_RW_STORAGE_OFF 0
#endif /* __CROS_EC_FLASH_CHIP_H */
diff --git a/zephyr/shim/chip/mchp/system.c b/zephyr/shim/chip/mchp/system.c
index f4e0d09d4d..25fdfc9897 100644
--- a/zephyr/shim/chip/mchp/system.c
+++ b/zephyr/shim/chip/mchp/system.c
@@ -11,6 +11,29 @@
LOG_MODULE_REGISTER(shim_xec_system, LOG_LEVEL_ERR);
+#define GET_BBRAM_OFS(node) \
+ DT_PROP(DT_PATH(named_bbram_regions, node), offset)
+#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size)
+
+/*
+ * Reset image type back to RO in BBRAM as watchdog resets.
+ * Watchdog reset will reset EC chip, ROM loader loads RO
+ * image stored in SPI flash chip in default.
+ */
+void cros_chip_wdt_handler(const struct device *wdt_dev, int channel_id)
+{
+ const struct device *bbram_dev = DEVICE_DT_GET(DT_NODELABEL(bbram));
+ uint32_t value = EC_IMAGE_RO;
+
+ if (!device_is_ready(bbram_dev)) {
+ LOG_ERR("WDT ISR: device %s is not ready", bbram_dev->name);
+ return;
+ }
+
+ bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value);
+}
+
static void chip_bbram_status_check(void)
{
const struct device *bbram_dev;
diff --git a/zephyr/shim/chip/mchp/system_download_from_flash.c b/zephyr/shim/chip/mchp/system_download_from_flash.c
index 665db2cccd..99026fe822 100644
--- a/zephyr/shim/chip/mchp/system_download_from_flash.c
+++ b/zephyr/shim/chip/mchp/system_download_from_flash.c
@@ -10,6 +10,10 @@
#include "system_chip.h"
/* Modules Map */
+#define WDT_NODE DT_INST(0, microchip_xec_watchdog)
+#define STRUCT_WDT_REG_BASE_ADDR \
+ ((struct wdt_regs *)(DT_REG_ADDR(WDT_NODE)))
+
#define PCR_NODE DT_INST(0, microchip_xec_pcr)
#define STRUCT_PCR_REG_BASE_ADDR \
((struct pcr_regs *)DT_REG_ADDR_BY_IDX(PCR_NODE, 0))
@@ -26,15 +30,15 @@
(MCHP_QMSPI_STS_DONE | MCHP_QMSPI_STS_DMA_DONE)
#define QSPI_STATUS_ERR \
- (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \
+ (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \
MCHP_QMSPI_STS_PROG_ERR | MCHP_QMSPI_STS_LDMA_RX_ERR)
-
noreturn void __keep __attribute__ ((section(".code_in_sram2")))
__start_qspi(uint32_t resetVectAddr)
{
struct pcr_regs *pcr = STRUCT_PCR_REG_BASE_ADDR;
struct qmspi_regs *qspi = STRUCT_QSPI_REG_BASE_ADDR;
+ struct wdt_regs *wdt = STRUCT_WDT_REG_BASE_ADDR;
uint32_t qsts = 0;
uint32_t exeAddr = 0;
@@ -47,6 +51,9 @@ __start_qspi(uint32_t resetVectAddr)
break;
}
+ /* Stop the watchdog */
+ wdt->CTRL &= ~MCHP_WDT_CTRL_EN;
+
qspi->MODE &= ~(MCHP_QMSPI_M_ACTIVATE);
if (qsts & QSPI_STATUS_ERR) {
pcr->SYS_RST |= MCHP_PCR_SYS_RESET_NOW;
@@ -67,8 +74,7 @@ __start_qspi(uint32_t resetVectAddr)
;
}
-/* PK SCM */
-uintptr_t __lfw_sram_start = 0x127800;
+uintptr_t __lfw_sram_start = CONFIG_CROS_EC_RAM_BASE + CONFIG_CROS_EC_RAM_SIZE;
typedef void (*START_QSPI_IN_SRAM_FP)(uint32_t);
@@ -85,9 +91,9 @@ void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr,
/* Check valid address for jumpiing */
__ASSERT_NO_MSG(exeAddr != 0x0);
-
+ /* Configure QMSPI controller */
qspi->MODE = MCHP_QMSPI_M_SRST;
- fdiv = 4;
+ fdiv = 2;
if (pcr->TURBO_CLK & MCHP_PCR_TURBO_CLK_96M)
fdiv *= 2;
diff --git a/zephyr/shim/chip/mchp/system_external_storage.c b/zephyr/shim/chip/mchp/system_external_storage.c
index 2c7312db3a..c326a07328 100644
--- a/zephyr/shim/chip/mchp/system_external_storage.c
+++ b/zephyr/shim/chip/mchp/system_external_storage.c
@@ -4,13 +4,35 @@
*/
#include <zephyr/devicetree.h>
-#include <zephyr/drivers/syscon.h>
+#include <zephyr/drivers/bbram.h>
+#include <soc.h>
#include "clock_chip.h"
#include "common.h"
#include "system.h"
#include "system_chip.h"
+#include "config_chip.h"
+#define MCHP_ECRO_WORD 0x4F524345u /* ASCII ECRO */
+#define MCHP_ECRW_WORD 0x57524345u /* ASCII ECRW */
+#define MCHP_PCR_NODE DT_INST(0, microchip_xec_pcr)
+
+#define GET_BBRAM_OFS(node) \
+ DT_PROP(DT_PATH(named_bbram_regions, node), offset)
+#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size)
+
+static const struct device *const bbram_dev =
+ COND_CODE_1(DT_HAS_CHOSEN(cros_ec_bbram),
+ DEVICE_DT_GET(DT_CHOSEN(cros_ec_bbram)), NULL);
+
+/* Build image type string in RO/RW image */
+#ifdef CONFIG_CROS_EC_RO
+const uint32_t mchp_image_type = MCHP_ECRO_WORD;
+#elif CONFIG_CROS_EC_RW
+const uint32_t mchp_image_type = MCHP_ECRW_WORD;
+#else
+#error "Unsupported image type!"
+#endif
/*
* Make sure CONFIG_XXX flash offsets are correct for MEC172x 512KB SPI flash.
@@ -29,19 +51,12 @@ void system_jump_to_booter(void)
case EC_IMAGE_RW:
flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF;
- flash_used = CONFIG_RW_SIZE;
- break;
-#ifdef CONFIG_RW_B
- case EC_IMAGE_RW_B:
- flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
- CONFIG_RW_B_STORAGE_OFF;
- flash_used = CONFIG_RW_SIZE;
+ flash_used = CONFIG_CROS_EC_RW_SIZE;
break;
-#endif
case EC_IMAGE_RO:
default: /* Jump to RO by default */
- flash_offset = 0x100; /* 256 bytes */
- flash_used = (352 * 1024);
+ flash_offset = CONFIG_PLATFORM_EC_RO_HEADER_OFFSET;
+ flash_used = CONFIG_CROS_EC_RO_SIZE;
break;
}
@@ -53,9 +68,11 @@ void system_jump_to_booter(void)
/* MCHP Read selected image from SPI flash into SRAM
* Need a jump to little-fw (LFW).
- * MEC172x Boot-ROM load API is probably not usuable for this.
*/
- system_download_from_flash(flash_offset, 0xC0000u, flash_used, 0xC0004);
+ system_download_from_flash(flash_offset,
+ CONFIG_CROS_EC_PROGRAM_MEMORY_BASE,
+ flash_used,
+ (CONFIG_CROS_EC_PROGRAM_MEMORY_BASE + 4u));
}
uint32_t system_get_lfw_address(void)
@@ -66,13 +83,51 @@ uint32_t system_get_lfw_address(void)
enum ec_image system_get_shrspi_image_copy(void)
{
- return EC_IMAGE_RO;
+ enum ec_image img = EC_IMAGE_UNKNOWN;
+ uint32_t value = 0u;
+
+ if (bbram_dev) {
+ if (!bbram_read(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value)) {
+ img = (enum ec_image)(value & 0x7fu);
+ }
+ }
+
+ if (img == EC_IMAGE_UNKNOWN) {
+ img = EC_IMAGE_RO;
+ if (mchp_image_type == MCHP_ECRW_WORD) {
+ img = EC_IMAGE_RW;
+ }
+ system_set_image_copy(img);
+ }
+
+ return img;
}
-/*
- * This configures HW to point to EC_RW or EC_RO.
+/* Flash is not memory mapped. Store a flag indicating the image.
+ * ECS WDT_CNT is register available to applications. It implements bits[3:0]
+ * which are not reset by a watch dog event only by VTR/chip reset.
+ * VBAT memory is safer only if the board has a stable VBAT power rail.
*/
void system_set_image_copy(enum ec_image copy)
{
- /* TODO(b/226599277): check if further development is requested */
+ uint32_t value = (uint32_t)copy;
+
+ if (!bbram_dev) {
+ return;
+ }
+
+ switch (copy) {
+ case EC_IMAGE_RW:
+ case EC_IMAGE_RW_B:
+ value = EC_IMAGE_RW;
+ break;
+ case EC_IMAGE_RO:
+ default:
+ value = EC_IMAGE_RO;
+ break;
+ }
+
+ bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load),
+ GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value);
}
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 9d86e8551b..73f38a72f4 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -1869,6 +1869,11 @@ extern struct jump_data mock_jump_data;
#define CONFIG_ACCEL_SPOOF_MODE
#endif
+#undef CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ
+#ifdef CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ
+#define CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ
+#endif
+
#undef CONFIG_CMD_ACCEL_SPOOF
#ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_SPOOF
#define CONFIG_CMD_ACCEL_SPOOF
diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt
index 9273a41fde..dee8d0af71 100644
--- a/zephyr/shim/src/CMakeLists.txt
+++ b/zephyr/shim/src/CMakeLists.txt
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-zephyr_library_sources(chipset_api.c)
zephyr_library_sources(console.c)
zephyr_library_sources(crc.c)
zephyr_library_sources(gpio.c)
@@ -27,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_BATTERY
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_RT9490
bc12_rt9490.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER charger.c)
+zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ chipset_api.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI
espi.c)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN fan.c)
diff --git a/zephyr/shim/src/chipset_api.c b/zephyr/shim/src/chipset_api.c
index 2804de8e78..3bfa420980 100644
--- a/zephyr/shim/src/chipset_api.c
+++ b/zephyr/shim/src/chipset_api.c
@@ -7,7 +7,6 @@
#include "common.h"
-#if defined(CONFIG_AP_PWRSEQ)
#include "ap_power/ap_power_interface.h"
#include "chipset_state_check.h"
@@ -45,34 +44,3 @@ void init_reset_log(void)
{
ap_power_init_reset_log();
}
-
-#else
-
-#if !defined(HAS_TASK_CHIPSET)
-#include "chipset.h"
-
-/* When no chipset is present, assume it is always off. */
-int chipset_in_state(int state_mask)
-{
- return state_mask & CHIPSET_STATE_ANY_OFF;
-}
-int chipset_in_or_transitioning_to_state(int state_mask)
-{
- return state_mask & CHIPSET_STATE_ANY_OFF;
-}
-void chipset_exit_hard_off(void) { }
-void chipset_throttle_cpu(int throttle) { }
-void chipset_force_shutdown(enum chipset_shutdown_reason reason) { }
-void chipset_reset(enum chipset_shutdown_reason reason) { }
-void power_interrupt(enum gpio_signal signal) { }
-void chipset_handle_espi_reset_assert(void) { }
-void chipset_handle_reboot(void) { }
-void chipset_reset_request_interrupt(enum gpio_signal signal) { }
-void chipset_warm_reset_interrupt(enum gpio_signal signal) { }
-void chipset_ap_rst_interrupt(enum gpio_signal signal) { }
-void chipset_power_good_interrupt(enum gpio_signal signal) { }
-void chipset_watchdog_interrupt(enum gpio_signal signal) { }
-void init_reset_log(void) { }
-
-#endif /* !defined(HAS_TASK_CHIPSET) */
-#endif /*defined(CONFIG_AP_PWRSEQ) */
diff --git a/zephyr/shim/src/console.c b/zephyr/shim/src/console.c
index 1093a26dff..f8051d8638 100644
--- a/zephyr/shim/src/console.c
+++ b/zephyr/shim/src/console.c
@@ -344,7 +344,8 @@ static void zephyr_print(const char *buff, size_t size)
* Also, console_buf_notify_chars uses a mutex, which may not be
* locked in ISRs.
*/
- if (k_is_in_isr() || shell_stopped) {
+ if (k_is_in_isr() || shell_stopped ||
+ shell_zephyr->ctx->state != SHELL_STATE_ACTIVE) {
printk("%s", buff);
} else {
shell_fprintf(shell_zephyr, SHELL_NORMAL, "%s", buff);
diff --git a/zephyr/shim/src/led_driver/led.h b/zephyr/shim/src/led_driver/led.h
index af2b11fa92..8c4e7654d5 100644
--- a/zephyr/shim/src/led_driver/led.h
+++ b/zephyr/shim/src/led_driver/led.h
@@ -119,4 +119,9 @@ void led_set_color(enum led_color color, enum ec_led_id led_id);
*/
void led_set_color_with_node(const struct led_pins_node_t *pins_node);
+#ifdef TEST_BUILD
+const struct led_pins_node_t *led_get_node(enum led_color color,
+ enum ec_led_id led_id);
+#endif /* TEST_BUILD */
+
#endif /* __CROS_EC_LED_H__ */
diff --git a/zephyr/shim/src/led_driver/led_gpio.c b/zephyr/shim/src/led_driver/led_gpio.c
index 598839a30f..5a4735a162 100644
--- a/zephyr/shim/src/led_driver/led_gpio.c
+++ b/zephyr/shim/src/led_driver/led_gpio.c
@@ -128,4 +128,23 @@ __override int led_is_supported(enum ec_led_id led_id)
return ((1 << (int)led_id) & supported_leds);
}
+
+#ifdef TEST_BUILD
+const struct led_pins_node_t *led_get_node(enum led_color color,
+ enum ec_led_id led_id)
+{
+ const struct led_pins_node_t *pin_node = NULL;
+
+ for (int i = 0; i < ARRAY_SIZE(pins_node); i++) {
+ if (pins_node[i]->led_id == led_id &&
+ pins_node[i]->led_color == color) {
+ pin_node = pins_node[i];
+ break;
+ }
+ }
+
+ return pin_node;
+}
+#endif /* TEST_BUILD */
+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(COMPAT_GPIO_LED) */
diff --git a/zephyr/shim/src/watchdog.c b/zephyr/shim/src/watchdog.c
index afb385054b..00cd5c4c30 100644
--- a/zephyr/shim/src/watchdog.c
+++ b/zephyr/shim/src/watchdog.c
@@ -27,6 +27,11 @@ static void wdt_warning_handler(const struct device *wdt_dev, int channel_id)
#ifdef TEST_BUILD
wdt_warning_triggered = true;
#endif
+#ifdef CONFIG_SOC_SERIES_MEC172X
+ extern void cros_chip_wdt_handler(const struct device *wdt_dev,
+ int channel_id);
+ cros_chip_wdt_handler(wdt_dev, channel_id);
+#endif
}
int watchdog_init(void)
diff --git a/zephyr/subsys/ap_pwrseq/power_signals.c b/zephyr/subsys/ap_pwrseq/power_signals.c
index f3405b4119..135a0d9ac1 100644
--- a/zephyr/subsys/ap_pwrseq/power_signals.c
+++ b/zephyr/subsys/ap_pwrseq/power_signals.c
@@ -310,7 +310,7 @@ void power_signal_init(void)
* don't get OR'ed in later on.
*/
for (int i = 0; i < ARRAY_SIZE(polled_signals); i++) {
- atomic_clear_bit(&power_signals, i);
+ atomic_clear_bit(&power_signals, polled_signals[i]);
}
/*
* Save the current state so that new changes can be
diff --git a/zephyr/subsys/ap_pwrseq/x86_non_dsx_mtl_pwrseq_sm.c b/zephyr/subsys/ap_pwrseq/x86_non_dsx_mtl_pwrseq_sm.c
index d6430e906c..5183824117 100644
--- a/zephyr/subsys/ap_pwrseq/x86_non_dsx_mtl_pwrseq_sm.c
+++ b/zephyr/subsys/ap_pwrseq/x86_non_dsx_mtl_pwrseq_sm.c
@@ -9,27 +9,32 @@ LOG_MODULE_DECLARE(ap_pwrseq, CONFIG_AP_PWRSEQ_LOG_LEVEL);
static void ap_off(void)
{
+ power_signal_set(PWR_PCH_PWROK, 0);
power_signal_set(PWR_EC_PCH_SYS_PWROK, 0);
}
/* Generate SYS_PWROK->SOC if needed by system */
-static void generate_sys_pwrok_handler(void)
+static void generate_pwrok_handler(void)
{
+ int all_sys_pwrgd_in;
+
if (power_signal_get(PWR_EC_PCH_SYS_PWROK) == 0) {
k_msleep(AP_PWRSEQ_DT_VALUE(sys_pwrok_delay));
- /*
- * Loop through all PWROK signals defined by the board and set
- * to match the current ALL_SYS_PWRGD input.
- */
- if (power_signal_get(PWR_ALL_SYS_PWRGD) == 0) {
- LOG_DBG("PG_EC_ALL_SYS_PWRGD deasserted, "
- "shutting AP off!");
- ap_off();
- return;
- }
- LOG_INF("Turning on PWR_EC_PCH_SYS_PWROK");
- power_signal_set(PWR_EC_PCH_SYS_PWROK, 1);
}
+
+ all_sys_pwrgd_in = power_signal_get(PWR_ALL_SYS_PWRGD);
+ /* Loop through all PWROK signals defined by the board */
+ if (all_sys_pwrgd_in == 0) {
+ LOG_DBG("PG_EC_ALL_SYS_PWRGD deasserted, "
+ "shutting AP off!");
+ ap_off();
+ return;
+ }
+
+ power_signal_set(PWR_EC_PCH_SYS_PWROK, all_sys_pwrgd_in);
+ /* PCH_PWROK is set to combined result of ALL_SYS_PWRGD and SLP_S3 */
+ power_signal_set(PWR_PCH_PWROK, all_sys_pwrgd_in &&
+ !power_signal_get(PWR_SLP_S3));
}
/* Chipset specific power state machine handler */
@@ -45,7 +50,7 @@ enum power_states_ndsx chipset_pwr_sm_run(enum power_states_ndsx curr_state)
break;
case SYS_POWER_STATE_S0:
/* Send SYS_PWROK->SoC if conditions met */
- generate_sys_pwrok_handler();
+ generate_pwrok_handler();
break;
default:
break;
diff --git a/zephyr/test/drivers/BUILD.py b/zephyr/test/drivers/BUILD.py
index 9e3465c18e..c43579da2e 100644
--- a/zephyr/test/drivers/BUILD.py
+++ b/zephyr/test/drivers/BUILD.py
@@ -6,6 +6,13 @@
register_host_test(
"drivers",
- dts_overlays=["overlay.dts"],
+ dts_overlays=[
+ "overlay.dts",
+ here / "led_driver/led_pins.dts",
+ here / "led_driver/led_policy.dts",
+ ],
+ kconfig_files=[
+ here / "led_driver/prj.conf",
+ ],
test_args=["-flash={test_temp_dir}/flash.bin"],
)
diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt
index b4c85defa2..33163427b5 100644
--- a/zephyr/test/drivers/CMakeLists.txt
+++ b/zephyr/test/drivers/CMakeLists.txt
@@ -53,7 +53,7 @@ target_sources(app PRIVATE
src/panic.c
src/power_common.c
src/ppc_sn5s330.c
- src/ppc_syv682c.c
+ src/ppc_syv682x.c
src/ps8xxx.c
src/smart.c
src/stm_mems_common.c
@@ -74,5 +74,6 @@ target_sources(app PRIVATE
)
add_subdirectory(isl923x)
+add_subdirectory(led_driver)
set_compiler_property(APPEND PROPERTY coverage -O0)
diff --git a/zephyr/test/drivers/led_driver/CMakeLists.txt b/zephyr/test/drivers/led_driver/CMakeLists.txt
new file mode 100644
index 0000000000..2f96eba2d3
--- /dev/null
+++ b/zephyr/test/drivers/led_driver/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright 2022 The ChromiumOS Authors.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Create library name based on current directory
+zephyr_library_get_current_dir_lib_name(${ZEPHYR_BASE} lib_name)
+
+# Create interface library
+zephyr_interface_library_named(${lib_name})
+
+# Add include paths
+zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
+zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+zephyr_include_directories("${PLATFORM_EC}/zephyr/shim/src/led_driver")
+
+# Add source files
+zephyr_library_sources("${CMAKE_CURRENT_SOURCE_DIR}/src/led.c")
+
+# Link in the library
+zephyr_library_link_libraries(${lib_name})
diff --git a/zephyr/test/drivers/led_driver/led_pins.dts b/zephyr/test/drivers/led_driver/led_pins.dts
new file mode 100644
index 0000000000..0127d762b2
--- /dev/null
+++ b/zephyr/test/drivers/led_driver/led_pins.dts
@@ -0,0 +1,54 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+ /* Based off of `ec/zephyr/projects/herobrine/led_pins_herobrine.dts`
+ * Modified led-colors to obtain better test coverage.
+ */
+/ {
+ gpio-led-pins {
+ compatible = "cros-ec,gpio-led-pins";
+
+ color_off_left: color-off-left {
+ led-color = "LED_OFF";
+ led-id = "EC_LED_ID_SYSRQ_DEBUG_LED";
+ led-pins = <&gpio_ec_chg_led_y_c1 0>,
+ <&gpio_ec_chg_led_w_c1 0>;
+ };
+ color_off_right: color-off-right {
+ led-color = "LED_OFF";
+ led-id = "EC_LED_ID_RIGHT_LED";
+ led-pins = <&gpio_ec_chg_led_y_c0 0>,
+ <&gpio_ec_chg_led_w_c0 0>;
+ };
+ color_blue_left: color-blue-left {
+ led-color = "LED_BLUE";
+ led-id = "EC_LED_ID_SYSRQ_DEBUG_LED";
+ br-color = "EC_LED_COLOR_BLUE";
+ led-pins = <&gpio_ec_chg_led_y_c1 1>,
+ <&gpio_ec_chg_led_w_c1 0>;
+ };
+ color_blue_right: color-blue-right {
+ led-color = "LED_BLUE";
+ led-id = "EC_LED_ID_RIGHT_LED";
+ br-color = "EC_LED_COLOR_BLUE";
+ led-pins = <&gpio_ec_chg_led_y_c0 1>,
+ <&gpio_ec_chg_led_w_c0 0>;
+ };
+ color_white_left: color-white-left {
+ led-color = "LED_WHITE";
+ led-id = "EC_LED_ID_SYSRQ_DEBUG_LED";
+ br-color = "EC_LED_COLOR_WHITE";
+ led-pins = <&gpio_ec_chg_led_y_c1 0>,
+ <&gpio_ec_chg_led_w_c1 1>;
+ };
+ color_white_right: color-white-right {
+ led-color = "LED_WHITE";
+ led-id = "EC_LED_ID_RIGHT_LED";
+ br-color = "EC_LED_COLOR_WHITE";
+ led-pins = <&gpio_ec_chg_led_y_c0 0>,
+ <&gpio_ec_chg_led_w_c0 1>;
+ };
+ };
+};
diff --git a/zephyr/test/drivers/led_driver/led_policy.dts b/zephyr/test/drivers/led_driver/led_policy.dts
new file mode 100644
index 0000000000..dbbc23062f
--- /dev/null
+++ b/zephyr/test/drivers/led_driver/led_policy.dts
@@ -0,0 +1,215 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Based off of `ec/zephyr/projects/herobrine/led_policy_herobrine.dts`
+ * Modified led-colors to obtain better test coverage.
+ */
+
+#include <dt-bindings/battery.h>
+
+/ {
+ led-colors {
+ compatible = "cros-ec,led-colors";
+
+ power-state-charge-left {
+ charge-state = "PWR_STATE_CHARGE";
+ charge-port = <1>; /* Left port */
+
+ /* Turn off the right LED */
+ color-0 {
+ led-color = <&color_off_right>;
+ };
+ /* Left LED to Blue */
+ color-1 {
+ led-color = <&color_blue_left>;
+ };
+ };
+
+ power-state-charge-right {
+ charge-state = "PWR_STATE_CHARGE";
+ charge-port = <0>; /* Right port */
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED to Blue */
+ color-1 {
+ led-color = <&color_blue_right>;
+ };
+ };
+
+ power-state-discharge-right-low {
+ charge-state = "PWR_STATE_DISCHARGE";
+ /* Battery percent range (>= Empty, <= Low) */
+ batt-lvl = <BATTERY_LEVEL_EMPTY BATTERY_LEVEL_LOW>;
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED - White 1 sec, off 3 sec */
+ color-1 {
+ led-color = <&color_white_right>;
+ period-ms = <1000>;
+ };
+ color-2 {
+ led-color = <&color_off_right>;
+ period-ms = <3000>;
+ };
+ };
+
+ power-state-discharge-right {
+ charge-state = "PWR_STATE_DISCHARGE";
+ /* Battery percent range (> Low, <= Full) */
+ batt-lvl = <(BATTERY_LEVEL_LOW + 1) BATTERY_LEVEL_FULL>;
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Turn off the right LED */
+ color-1 {
+ led-color = <&color_off_right>;
+ };
+ };
+
+ power-state-error-left {
+ charge-state = "PWR_STATE_ERROR";
+ charge-port = <1>; /* Left port */
+
+ /* Turn off the right LED */
+ color-0 {
+ led-color = <&color_off_right>;
+ };
+ /* Left LED - White 2 sec, off 2 sec */
+ color-1 {
+ led-color = <&color_white_left>;
+ period-ms = <2000>;
+ };
+ color-2 {
+ led-color = <&color_off_right>;
+ period-ms = <2000>;
+ };
+ };
+
+ power-state-error-right {
+ charge-state = "PWR_STATE_ERROR";
+ charge-port = <0>; /* Right port */
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED - White 2 sec, off 2 sec */
+ color-1 {
+ led-color = <&color_white_right>;
+ period-ms = <2000>;
+ };
+ color-2 {
+ led-color = <&color_off_right>;
+ period-ms = <2000>;
+ };
+ };
+
+ power-state-near-full-left {
+ charge-state = "PWR_STATE_CHARGE_NEAR_FULL";
+ charge-port = <1>; /* Left port */
+
+ /* Turn off the right LED */
+ color-0 {
+ led-color = <&color_off_right>;
+ };
+ /* Left LED to White */
+ color-1 {
+ led-color = <&color_white_left>;
+ };
+ };
+
+ power-state-near-full-right {
+ charge-state = "PWR_STATE_CHARGE_NEAR_FULL";
+ charge-port = <0>; /* Right port */
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED to White */
+ color-1 {
+ led-color = <&color_white_right>;
+ };
+ };
+
+ power-state-idle-forced-left {
+ charge-state = "PWR_STATE_IDLE";
+ charge-port = <1>; /* Left port */
+ extra-flag = "LED_CHFLAG_FORCE_IDLE";
+
+ /* Turn off the right LED */
+ color-0 {
+ led-color = <&color_off_right>;
+ };
+ /* Left LED - Blue 3 sec, Off 1 sec */
+ color-1 {
+ led-color = <&color_blue_left>;
+ period-ms = <3000>;
+ };
+ color-2 {
+ led-color = <&color_off_left>;
+ period-ms = <1000>;
+ };
+ };
+
+ power-state-idle-forced-right {
+ charge-state = "PWR_STATE_IDLE";
+ charge-port = <0>; /* Right port */
+ extra-flag = "LED_CHFLAG_FORCE_IDLE";
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED - Blue 3 sec, Off 1 sec */
+ color-1 {
+ led-color = <&color_blue_right>;
+ period-ms = <3000>;
+ };
+ color-2 {
+ led-color = <&color_off_right>;
+ period-ms = <1000>;
+ };
+ };
+
+ power-state-idle-default-left {
+ charge-state = "PWR_STATE_IDLE";
+ charge-port = <1>; /* Left port */
+ extra-flag = "LED_CHFLAG_DEFAULT";
+
+ /* Turn off the right LED */
+ color-0 {
+ led-color = <&color_off_right>;
+ };
+ /* Left LED to White */
+ color-1 {
+ led-color = <&color_white_left>;
+ };
+ };
+
+ power-state-idle-default-right {
+ charge-state = "PWR_STATE_IDLE";
+ charge-port = <0>; /* Right port */
+ extra-flag = "LED_CHFLAG_DEFAULT";
+
+ /* Turn off the left LED */
+ color-0 {
+ led-color = <&color_off_left>;
+ };
+ /* Right LED to White */
+ color-1 {
+ led-color = <&color_white_right>;
+ };
+ };
+ };
+};
diff --git a/zephyr/test/drivers/led_driver/prj.conf b/zephyr/test/drivers/led_driver/prj.conf
new file mode 100644
index 0000000000..abdb8cc6a1
--- /dev/null
+++ b/zephyr/test/drivers/led_driver/prj.conf
@@ -0,0 +1,6 @@
+# Copyright 2022 The ChromiumOS Authors.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+CONFIG_PLATFORM_EC_LED_COMMON=n
+CONFIG_PLATFORM_EC_LED_DT=y
diff --git a/zephyr/test/drivers/led_driver/src/led.c b/zephyr/test/drivers/led_driver/src/led.c
new file mode 100644
index 0000000000..5c0c9d0c01
--- /dev/null
+++ b/zephyr/test/drivers/led_driver/src/led.c
@@ -0,0 +1,69 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <ztest.h>
+#include "ec_commands.h"
+#include "gpio.h"
+#include "led.h"
+#include "led_common.h"
+#include "test/drivers/test_state.h"
+
+#define VERIFY_LED_COLOR(color, led_id) \
+ { \
+ const struct led_pins_node_t *pin_node = \
+ led_get_node(color, led_id); \
+ for (int j = 0; j < pin_node->pins_count; j++) { \
+ int val = gpio_pin_get_dt(gpio_get_dt_spec( \
+ pin_node->gpio_pins[j].signal)); \
+ int expecting = pin_node->gpio_pins[j].val; \
+ zassert_equal(expecting, val, "[%d]: %d != %d", j, \
+ expecting, val); \
+ } \
+ }
+
+ZTEST_SUITE(led_driver, drivers_predicate_post_main, NULL, NULL, NULL, NULL);
+
+ZTEST(led_driver, test_led_control)
+{
+ /* Exercise valid led_id, set to RESET state */
+ led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_RESET);
+ VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED);
+
+ /* Exercise valid led_id, set to OFF state.
+ * Verify matches OFF color defined in device tree
+ */
+ led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_OFF);
+ VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED);
+
+ /* Exercise valid led_id, set to ON state.
+ * Verify matches ON color defined in device tree
+ */
+ led_control(EC_LED_ID_SYSRQ_DEBUG_LED, LED_STATE_ON);
+ VERIFY_LED_COLOR(LED_BLUE, EC_LED_ID_SYSRQ_DEBUG_LED);
+
+ /* Exercise invalid led_id -- no change to led color */
+ led_control(EC_LED_ID_LEFT_LED, LED_STATE_RESET);
+ VERIFY_LED_COLOR(LED_BLUE, EC_LED_ID_SYSRQ_DEBUG_LED);
+}
+
+ZTEST(led_driver, test_led_brightness)
+{
+ uint8_t brightness[EC_LED_COLOR_COUNT] = { -1 };
+
+ /* Verify LED set to OFF */
+ led_set_brightness(EC_LED_ID_SYSRQ_DEBUG_LED, brightness);
+ VERIFY_LED_COLOR(LED_OFF, EC_LED_ID_SYSRQ_DEBUG_LED);
+
+ /* Verify LED colors defined in device tree are reflected in the
+ * brightness array.
+ */
+ led_get_brightness_range(EC_LED_ID_SYSRQ_DEBUG_LED, brightness);
+ zassert_equal(brightness[EC_LED_COLOR_BLUE], 1, NULL);
+ zassert_equal(brightness[EC_LED_COLOR_WHITE], 1, NULL);
+
+ /* Verify LED set to WHITE */
+ led_set_brightness(EC_LED_ID_SYSRQ_DEBUG_LED, brightness);
+ VERIFY_LED_COLOR(LED_WHITE, EC_LED_ID_SYSRQ_DEBUG_LED);
+}
diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts
index df0888175f..d8c92a53ef 100644
--- a/zephyr/test/drivers/overlay.dts
+++ b/zephyr/test/drivers/overlay.dts
@@ -166,6 +166,22 @@
gpios = <&gpio0 29 (GPIO_ACTIVE_LOW | GPIO_INPUT)>;
no-auto-init;
};
+ gpio_ec_chg_led_y_c0: ec_chg_led_y_c0 {
+ #led-pin-cells = <1>;
+ gpios = <&gpio0 30 (GPIO_INPUT | GPIO_OUTPUT_LOW)>;
+ };
+ gpio_ec_chg_led_w_c0: ec_chg_led_w_c0 {
+ #led-pin-cells = <1>;
+ gpios = <&gpio0 31 (GPIO_INPUT | GPIO_OUTPUT_LOW)>;
+ };
+ gpio_ec_chg_led_y_c1: ec_chg_led_y_c1 {
+ #led-pin-cells = <1>;
+ gpios = <&gpio0 32 (GPIO_INPUT | GPIO_OUTPUT_LOW)>;
+ };
+ gpio_ec_chg_led_w_c1: ec_chg_led_w_c1 {
+ #led-pin-cells = <1>;
+ gpios = <&gpio0 33 (GPIO_INPUT | GPIO_OUTPUT_LOW)>;
+ };
};
gpio-interrupts {
@@ -776,7 +792,7 @@
};
&gpio0 {
- ngpios = <30>;
+ ngpios = <34>;
};
&i2c0 {
diff --git a/zephyr/test/drivers/src/espi.c b/zephyr/test/drivers/src/espi.c
index 91746e7c45..67fc3c6f90 100644
--- a/zephyr/test/drivers/src/espi.c
+++ b/zephyr/test/drivers/src/espi.c
@@ -58,4 +58,25 @@ ZTEST_USER(espi, test_host_command_typec_status)
zassert_equal(args.response_size, sizeof(response), NULL);
}
+ZTEST_USER(espi, test_host_command_usb_pd_get_amode)
+{
+ /* Only test we've enabled the command */
+ struct ec_params_usb_pd_get_mode_request params = {
+ .port = PORT,
+ .svid_idx = 0,
+ };
+ struct ec_params_usb_pd_get_mode_response response;
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_USB_PD_GET_AMODE, 0, response, params);
+
+ zassert_ok(host_command_process(&args), NULL);
+ zassert_ok(args.result, NULL);
+ /* Note: with no SVIDs the response size is the size of the svid field.
+ * See the usb alt mode test for verifying larger struct sizes
+ *
+ * TODO(b/219562077): Add the above described test.
+ */
+ zassert_equal(args.response_size, sizeof(response.svid), NULL);
+}
+
ZTEST_SUITE(espi, drivers_predicate_post_main, NULL, NULL, NULL, NULL);
diff --git a/zephyr/test/drivers/src/integration/usbc/usb_alt_mode.c b/zephyr/test/drivers/src/integration/usbc/usb_alt_mode.c
index 472c57d978..fadb595e4b 100644
--- a/zephyr/test/drivers/src/integration/usbc/usb_alt_mode.c
+++ b/zephyr/test/drivers/src/integration/usbc/usb_alt_mode.c
@@ -20,6 +20,8 @@
#include "test/drivers/utils.h"
#include "test/drivers/test_state.h"
+#define TEST_PORT USBC_PORT_C0
+
struct usbc_alt_mode_fixture {
const struct emul *tcpci_emul;
const struct emul *charger_emul;
@@ -66,7 +68,7 @@ static void *usbc_alt_mode_setup(void)
fixture.tcpci_emul =
emul_get_binding(DT_LABEL(DT_NODELABEL(tcpci_emul)));
/* The configured TCPCI rev must match the emulator's supported rev. */
- tcpc_config[0].flags |= TCPC_FLAGS_TCPCI_REV2_0;
+ tcpc_config[TEST_PORT].flags |= TCPC_FLAGS_TCPCI_REV2_0;
tcpci_emul_set_rev(fixture.tcpci_emul, TCPCI_EMUL_REV2_0_VER1_1);
fixture.charger_emul =
emul_get_binding(DT_LABEL(DT_NODELABEL(isl923x_emul)));
@@ -127,7 +129,7 @@ ZTEST_F(usbc_alt_mode, verify_discovery)
uint8_t response_buffer[EC_LPC_HOST_PACKET_SIZE];
struct ec_response_typec_discovery *discovery =
(struct ec_response_typec_discovery *)response_buffer;
- host_cmd_typec_discovery(USBC_PORT_C0, TYPEC_PARTNER_SOP,
+ host_cmd_typec_discovery(TEST_PORT, TYPEC_PARTNER_SOP,
response_buffer, sizeof(response_buffer));
/* The host command does not count the VDM header in identity_count. */
diff --git a/zephyr/test/drivers/src/ppc_syv682c.c b/zephyr/test/drivers/src/ppc_syv682c.c
deleted file mode 100644
index 9707f374ac..0000000000
--- a/zephyr/test/drivers/src/ppc_syv682c.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <zephyr/device.h>
-#include <zephyr/devicetree/gpio.h>
-#include <zephyr/drivers/gpio/gpio_emul.h>
-#include <fff.h>
-#include <zephyr/zephyr.h>
-#include <ztest.h>
-#include <ztest_assert.h>
-
-#include "emul/emul_common_i2c.h"
-#include "emul/emul_syv682x.h"
-#include "test/drivers/stubs.h"
-#include "syv682x.h"
-#include "timer.h"
-#include "test/drivers/test_state.h"
-#include "usbc_ppc.h"
-
-#define SYV682X_ORD DT_DEP_ORD(DT_NODELABEL(syv682x_emul))
-#define GPIO_USB_C1_FRS_EN_PATH DT_PATH(named_gpios, usb_c1_frs_en)
-
-#define GPIO_USB_C1_FRS_EN_PORT DT_GPIO_PIN(GPIO_USB_C1_FRS_EN_PATH, gpios)
-
-/* Configuration for a mock I2C access function that sometimes fails. */
-struct reg_to_fail_data {
- int reg_access_to_fail;
- int reg_access_fail_countdown;
-};
-
-static const int syv682x_port = 1;
-
-static void syv682x_test_after(void *data)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- ARG_UNUSED(data);
-
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- /* Clear the mock read/write functions */
- i2c_common_emul_set_read_func(emul, NULL, NULL);
- i2c_common_emul_set_write_func(emul, NULL, NULL);
-
- /* Don't fail on any register access */
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
- i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_board_is_syv682c)
-{
- zassert_true(syv682x_board_is_syv682c(syv682x_port), NULL);
-}
-
-static void check_control_1_default_init(uint8_t control_1)
-{
- /*
- * During init, when not in dead battery mode, the driver should
- * configure the high-voltage channel as sink but leave the power path
- * disabled. The driver should set the current limits according to
- * configuration.
- */
- int ilim;
-
- zassert_true(control_1 & SYV682X_CONTROL_1_PWR_ENB,
- "Default init, but power path enabled");
- ilim = (control_1 & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT;
- zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM,
- "Default init, but HV current limit set to %d", ilim);
- zassert_false(control_1 & SYV682X_CONTROL_1_HV_DR,
- "Default init, but source mode selected");
- zassert_true(control_1 & SYV682X_CONTROL_1_CH_SEL,
- "Default init, but 5V power path selected");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_init)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- const struct device *gpio_dev =
- DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios));
- uint8_t reg;
- int ilim;
-
- /*
- * With a dead battery, the device powers up sinking VBUS, and the
- * driver should keep that going..
- */
- zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG,
- SYV682X_CONTROL_1_CH_SEL), NULL);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_5V,
- SYV682X_CONTROL_4_NONE);
- zassert_ok(ppc_init(syv682x_port), "PPC init failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- NULL);
- zassert_true(reg & SYV682X_CONTROL_1_CH_SEL,
- "Dead battery init, but CH_SEL set to 5V power path");
- zassert_false(reg &
- (SYV682X_CONTROL_1_PWR_ENB | SYV682X_CONTROL_1_HV_DR),
- "Dead battery init, but CONTROL_1 is 0x%x", reg);
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "Dead battery init, but VBUS source enabled");
-
- /* With VBUS at vSafe0V, init should set the default configuration. */
- zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG,
- SYV682X_CONTROL_1_PWR_ENB), NULL);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_0V,
- SYV682X_CONTROL_4_NONE);
- zassert_ok(ppc_init(syv682x_port), "PPC init failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- NULL);
- check_control_1_default_init(reg);
-
- /* With sink disabled, init should do the same thing. */
- zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG,
- SYV682X_CONTROL_1_CH_SEL), NULL);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_0V,
- SYV682X_CONTROL_4_NONE);
- zassert_ok(ppc_init(syv682x_port), "PPC init failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- NULL);
- check_control_1_default_init(reg);
-
- /*
- * Any init sequence should also disable the FRS GPIO, set the 5V
- * current limit according to configuration, set over-current, over-
- * voltage, and discharge parameters appropriately, and enable CC lines.
- */
- zassert_equal(gpio_emul_output_get(gpio_dev, GPIO_USB_C1_FRS_EN_PORT),
- 0, "FRS enabled, but FRS GPIO not asserted");
- ilim = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
- zassert_equal(ilim, CONFIG_PLATFORM_EC_USB_PD_PULLUP,
- "Default init, but 5V current limit set to %d", ilim);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, &reg),
- NULL);
- zassert_equal(reg, (SYV682X_OC_DELAY_10MS << SYV682X_OC_DELAY_SHIFT) |
- (SYV682X_DSG_RON_200_OHM << SYV682X_DSG_RON_SHIFT) |
- (SYV682X_DSG_TIME_50MS << SYV682X_DSG_TIME_SHIFT),
- "Default init, but CONTROL_2 is 0x%x", reg);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_3_REG, &reg),
- NULL);
- zassert_equal(reg, (SYV682X_OVP_23_7 << SYV682X_OVP_BIT_SHIFT) |
- SYV682X_RVS_MASK,
- "Default init, but CONTROL_3 is 0x%x", reg);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- NULL);
- zassert_equal(reg & ~SYV682X_CONTROL_4_INT_MASK,
- SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS,
- "Default init, but CONTROL_4 is 0x%x", reg);
-
- /* Disable the power path again. */
- zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG,
- SYV682X_CONTROL_1_PWR_ENB), NULL);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
-}
-
-ZTEST(ppc_syv682c, test_syv682x_vbus_enable)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- uint8_t reg;
-
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- zassert_not_equal(reg & SYV682X_CONTROL_1_PWR_ENB,
- SYV682X_CONTROL_1_PWR_ENB, "VBUS sourcing disabled");
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "PPC sourcing VBUS at beginning of test");
-
- zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
- "VBUS enable failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
- "VBUS sourcing disabled");
- zassert_true(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is not sourcing VBUS after VBUS enabled");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_interrupt)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- uint8_t reg;
-
- zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
- "VBUS enable failed");
- /* An OC event less than 100 ms should not cause VBUS to turn off. */
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_5V,
- SYV682X_CONTROL_4_NONE);
- msleep(50);
- zassert_true(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is not sourcing VBUS after 50 ms OC");
- /* But one greater than 100 ms should. */
- msleep(60);
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is sourcing VBUS after 100 ms OC");
-
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
- /*
- * TODO(b/190519131): Organize the tests to be more hermetic and avoid
- * the following issue: The driver triggers overcurrent protection. If
- * overcurrent protection is triggered 3 times, the TC won't turn the
- * port back on without a detach. This could frustrate efforts to test
- * the TC.
- */
-
- /*
- * A TSD event should cause the driver to disable source and sink paths.
- * (The device will have already physically disabled them.) The state of
- * the sink path is not part of the driver's API.
- */
- zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
- "Source enable failed");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_TSD,
- SYV682X_CONTROL_4_NONE);
- msleep(1);
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is sourcing power after TSD");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- /* An OVP event should cause the driver to disable the source path. */
- zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
- "Source enable failed");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OVP,
- SYV682X_CONTROL_4_NONE);
- msleep(1);
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is sourcing power after OVP");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- /*
- * A high-voltage OC while sinking should cause the driver to try to
- * re-enable the sink path until the OC count limit is reached, at which
- * point the driver should leave it disabled.
- */
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
- "Sink enable failed");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV,
- SYV682X_CONTROL_4_NONE);
- msleep(1);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
- "Power path disabled after HV_OC handled");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV,
- SYV682X_CONTROL_4_NONE);
- /* Alert GPIO doesn't change so wait for delayed syv682x interrupt */
- msleep(15);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
- "Power path disabled after HV_OC handled");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV,
- SYV682X_CONTROL_4_NONE);
- /* Alert GPIO doesn't change so wait for delayed syv682x interrupt */
- msleep(15);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB,
- SYV682X_CONTROL_1_PWR_ENB,
- "Power path enabled after HV_OC handled 3 times");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- /*
- * A VCONN OC event less than 100 ms should not cause the driver to turn
- * VCONN off.
- */
- ppc_set_vconn(syv682x_port, true);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_VCONN_OCP);
- msleep(1);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_true(reg &
- (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2),
- "VCONN disabled after initial VCONN OC");
- msleep(50);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_true(reg &
- (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2),
- "VCONN disabled after short VCONN OC");
- /*
- * But if the event keeps going for over 100 ms continuously, the driver
- * should turn VCONN off.
- */
- msleep(60);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_false(reg &
- (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2),
- "VCONN enabled after long VCONN OC");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- /*
- * A VCONN over-voltage (VBAT_OVP) event will cause the device to
- * disconnect CC and VCONN. The driver should then reinitialize the
- * device, which will enable both CC lines but leave VCONN disabled. The
- * driver should then run generic CC over-voltage handling.
- */
- ppc_set_vconn(syv682x_port, true);
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_VBAT_OVP);
- msleep(1);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_true(reg & SYV682X_CONTROL_4_CC1_BPS,
- "CC1 disabled after handling VBAT_OVP");
- zassert_true(reg & SYV682X_CONTROL_4_CC2_BPS,
- "CC2 disabled after handling VBAT_OVP");
- zassert_false(reg &
- (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2),
- "VCONN enabled after handling VBAT_OVP");
- /*
- * TODO(b/190519131): The PD stack should generate a Reset in response
- * to a CC over-voltage event. There is currently no easy way to test
- * that a Hard Reset occurred.
- */
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_frs)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- const struct device *gpio_dev =
- DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios));
- uint8_t reg;
-
- /*
- * Enabling FRS should enable only the appropriate CC line based on
- * polarity. Disabling FRS should enable both CC lines.
- */
- ppc_vbus_sink_enable(syv682x_port, true);
- zassert_false(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is sourcing VBUS after sink enabled");
- ppc_set_polarity(syv682x_port, 0 /* CC1 */);
- ppc_set_frs_enable(syv682x_port, true);
- zassert_equal(gpio_emul_output_get(gpio_dev, GPIO_USB_C1_FRS_EN_PORT),
- 1, "FRS enabled, but FRS GPIO not asserted");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_equal(reg &
- (SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS),
- SYV682X_CONTROL_4_CC1_BPS,
- "FRS enabled with CC1 polarity, but CONTROL_4 is 0x%x",
- reg);
- ppc_set_frs_enable(syv682x_port, false);
- zassert_equal(gpio_emul_output_get(gpio_dev, GPIO_USB_C1_FRS_EN_PORT),
- 0, "FRS disabled, but FRS GPIO not deasserted");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_equal(reg &
- (SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS),
- SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS,
- "FRS enabled with CC1 polarity, but CONTROL_4 is 0x%x",
- reg);
-
- ppc_set_polarity(syv682x_port, 1 /* CC2 */);
- ppc_set_frs_enable(syv682x_port, true);
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, &reg),
- "Reading CONTROL_4 failed");
- zassert_equal(reg &
- (SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS),
- SYV682X_CONTROL_4_CC2_BPS,
- "FRS enabled with CC2 polarity, but CONTROL_4 is 0x%x",
- reg);
-
- /*
- * An FRS event when the PPC is Sink should cause the PPC to switch from
- * Sink to Source.
- */
- syv682x_emul_set_condition(emul, SYV682X_STATUS_FRS,
- SYV682X_CONTROL_4_NONE);
- msleep(1);
- zassert_true(ppc_is_sourcing_vbus(syv682x_port),
- "PPC is not sourcing VBUS after FRS signal handled");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_source_current_limit)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- uint8_t reg;
- int ilim_val;
-
- zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_USB),
- "Could not set source current limit");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
- zassert_equal(reg & SYV682X_5V_ILIM_MASK, SYV682X_5V_ILIM_1_25,
- "Set USB Rp value, but 5V_ILIM is %d", ilim_val);
-
- zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_1A5),
- "Could not set source current limit");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
- zassert_equal(ilim_val, SYV682X_5V_ILIM_1_75,
- "Set 1.5A Rp value, but 5V_ILIM is %d", ilim_val);
-
- zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_3A0),
- "Could not set source current limit");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- "Reading CONTROL_1 failed");
- ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
- zassert_equal(ilim_val, SYV682X_5V_ILIM_3_30,
- "Set 3.0A Rp value, but 5V_ILIM is %d", ilim_val);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_write_busy)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- /*
- * Writes should fail while the BUSY bit is set, except that writes to
- * CONTROL_4 should succeed on the SYV682C. 1000 reads is intentionally
- * many more than the driver is expected to make before reaching its
- * timeout. It is not a goal of this test to verify the frequency of
- * polling or the exact value of the timeout.
- */
- syv682x_emul_set_busy_reads(emul, 1000);
- zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_USB),
- EC_ERROR_TIMEOUT, "SYV682 busy, but write completed");
- zassert_ok(ppc_set_frs_enable(syv682x_port, false),
- "Could not set CONTROL_4 while busy on SYV682C");
-
- /*
- * If the busy bit clears before the driver reaches its timeout, the
- * write should succeed.
- */
- syv682x_emul_set_busy_reads(emul, 1);
- zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_USB), 0,
- "SYV682 not busy, but write failed");
-
- syv682x_emul_set_busy_reads(emul, 0);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_dev_is_connected)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- uint8_t reg;
-
- zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SRC),
- "Could not connect device as source");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, &reg),
- "Reading CONTROL_2 failed");
- zassert_false(reg & SYV682X_CONTROL_2_FDSG,
- "Connected as source, but force discharge enabled");
-
- zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_DISCONNECTED),
- "Could not disconnect device");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, &reg),
- "Reading CONTROL_2 failed");
- zassert_true(reg & SYV682X_CONTROL_2_FDSG,
- "Disconnected, but force discharge disabled");
-
- zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SNK),
- "Could not connect device as source");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_vbus_sink_enable)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- uint8_t reg;
- int ilim;
-
- /*
- * If VBUS source is already enabled, disabling VBUS sink should
- * trivially succeed.
- */
- zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
- "VBUS enable failed");
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
- "Sink disable failed");
-
- /*
- * After enabling VBUS sink, the HV power path should be enabled in sink
- * mode with the configured current limit.
- */
- zassert_ok(ppc_vbus_source_enable(syv682x_port, false),
- "VBUS enable failed");
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
- "Sink disable failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- NULL);
- zassert_true(reg & SYV682X_CONTROL_1_CH_SEL,
- "Sink enabled, but CH_SEL set to 5V power path");
- zassert_false(reg & SYV682X_CONTROL_1_PWR_ENB,
- "Sink enabled, but power path disabled");
- zassert_false(reg & SYV682X_CONTROL_1_HV_DR,
- "Sink enabled, but high-voltage path in source mode");
- ilim = (reg & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT;
- zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM,
- "Sink enabled, but HV current limit set to %d", ilim);
-
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
- "Sink disable failed");
- zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, &reg),
- NULL);
- zassert_true(reg & SYV682X_CONTROL_1_PWR_ENB,
- "Sink disabled, but power path enabled");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_vbus_sink_oc_limit)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
- "Sink enable failed");
-
- /* Generate 4 consecutive sink over-current interrupts. After reaching
- * this count, the driver should prevent sink enable until the count is
- * cleared by sink disable.
- */
- for (int i = 0; i < 4; ++i) {
- syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV,
- SYV682X_CONTROL_4_NONE);
- msleep(15);
- }
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
-
- zassert_not_equal(ppc_vbus_sink_enable(syv682x_port, true), EC_SUCCESS,
- "VBUS sink enable succeeded after 4 OC events");
-
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
- "Sink disable failed");
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
- "Sink enable failed");
- zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
- "Sink disable failed");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_set_vconn)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_VBAT_OVP);
- zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
- "VBAT OVP, but ppc_set_vconn succeeded");
-}
-
-ZTEST(ppc_syv682c, test_syv682x_ppc_dump)
-{
- /*
- * The ppc_dump command should succeed for this port. Don't check the
- * output, since there are no standard requirements for that.
- */
- const struct ppc_drv *drv = ppc_chips[syv682x_port].drv;
-
- zassert_ok(drv->reg_dump(syv682x_port), "ppc_dump command failed");
-}
-
-/* Intercepts I2C reads as a mock. Fails to read for the register at offset
- * reg_access_to_fail on read number N, where N is the initial value of
- * reg_access_fail_countdown.
- */
-static int mock_read_intercept_reg_fail(struct i2c_emul *emul, int reg,
- uint8_t *val, int bytes, void *data)
-{
- struct reg_to_fail_data *test_data = data;
-
- if (reg == test_data->reg_access_to_fail) {
- test_data->reg_access_fail_countdown--;
- if (test_data->reg_access_fail_countdown <= 0)
- return -1;
- }
- return 1;
-}
-
-ZTEST(ppc_syv682c, test_syv682x_i2c_error_status)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- /* Failed STATUS read should cause init to fail. */
- i2c_common_emul_set_read_fail_reg(emul, SYV682X_STATUS_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "STATUS read error, but init succeeded");
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_i2c_error_control_1)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
- const struct ppc_drv *drv = ppc_chips[syv682x_port].drv;
- struct reg_to_fail_data reg_fail = {
- .reg_access_to_fail = 0,
- .reg_access_fail_countdown = 0,
- };
-
- /* Failed CONTROL_1 read */
- i2c_common_emul_set_read_fail_reg(emul, SYV682X_CONTROL_1_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_1 read error, but init succeeded");
- zassert_not_equal(ppc_vbus_source_enable(syv682x_port, true),
- EC_SUCCESS,
- "CONTROL_1 read error, but VBUS source enable "
- "succeeded");
- zassert_not_equal(ppc_vbus_sink_enable(syv682x_port, true), EC_SUCCESS,
- "CONTROL_1 read error, but VBUS sink enable "
- "succeeded");
- zassert_not_equal(ppc_set_vbus_source_current_limit(syv682x_port,
- TYPEC_RP_USB),
- EC_SUCCESS,
- "CONTROL_1 read error, but set current limit "
- "succeeded");
- zassert_ok(drv->reg_dump(syv682x_port),
- "CONTROL_1 read error, and ppc_dump failed");
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-
- /* Init reads CONTROL_1 several times. The 3rd read happens while
- * setting the source current limit. Check that init fails when that
- * read fails.
- */
- i2c_common_emul_set_read_func(emul, &mock_read_intercept_reg_fail,
- &reg_fail);
- reg_fail.reg_access_to_fail = SYV682X_CONTROL_1_REG;
- reg_fail.reg_access_fail_countdown = 3;
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_1 read error, but init succeeded");
- i2c_common_emul_set_read_func(emul, NULL, NULL);
-
- /* Failed CONTROL_1 write */
- i2c_common_emul_set_write_fail_reg(emul, SYV682X_CONTROL_1_REG);
-
- /* During init, the driver will write CONTROL_1 either to disable all
- * power paths (normal case) or to enable the sink path (dead battery
- * case). vSafe0V in STATUS is one indication of the normal case.
- */
- syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_0V,
- SYV682X_CONTROL_4_NONE);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_1 write error, but init succeeded");
- syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
- SYV682X_CONTROL_4_NONE);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_1 write error, but init succeeded");
-
- zassert_not_equal(ppc_vbus_source_enable(syv682x_port, true),
- EC_SUCCESS,
- "CONTROL_1 write error, but VBUS source "
- "enable succeeded");
- i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_i2c_error_control_2)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- /* Failed CONTROL_2 read */
- i2c_common_emul_set_read_fail_reg(emul, SYV682X_CONTROL_2_REG);
- zassert_not_equal(ppc_discharge_vbus(syv682x_port, true), EC_SUCCESS,
- "CONTROL_2 read error, but VBUS discharge succeeded");
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-
- /* Failed CONTROL_2 write */
- i2c_common_emul_set_write_fail_reg(emul, SYV682X_CONTROL_2_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_2 write error, but init succeeded");
- i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_i2c_error_control_3)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- /* Failed CONTROL_3 read */
- i2c_common_emul_set_read_fail_reg(emul, SYV682X_CONTROL_3_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_3 read error, but VBUS discharge succeeded");
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-
- /* Failed CONTROL_3 write */
- i2c_common_emul_set_write_fail_reg(emul, SYV682X_CONTROL_3_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_3 write error, but init succeeded");
- i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST(ppc_syv682c, test_syv682x_i2c_error_control_4)
-{
- struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD);
-
- /* Failed CONTROL_4 read */
- i2c_common_emul_set_read_fail_reg(emul, SYV682X_CONTROL_4_REG);
- zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
- "CONTROL_2 read error, but VCONN set succeeded");
- i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-
- /* Failed CONTROL_4 write */
- i2c_common_emul_set_write_fail_reg(emul, SYV682X_CONTROL_4_REG);
- zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
- "CONTROL_4 write error, but init succeeded");
- zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
- "CONTROL_4 write error, but VCONN set succeeded");
- i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
-}
-
-ZTEST_SUITE(ppc_syv682c, drivers_predicate_post_main, NULL, NULL,
- syv682x_test_after, NULL);
diff --git a/zephyr/test/drivers/src/ppc_syv682x.c b/zephyr/test/drivers/src/ppc_syv682x.c
new file mode 100644
index 0000000000..aa08c26745
--- /dev/null
+++ b/zephyr/test/drivers/src/ppc_syv682x.c
@@ -0,0 +1,804 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr/device.h>
+#include <zephyr/devicetree/gpio.h>
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/drivers/gpio.h>
+#include <fff.h>
+#include <zephyr/zephyr.h>
+#include <ztest.h>
+#include <ztest_assert.h>
+
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_syv682x.h"
+#include "test/drivers/stubs.h"
+#include "syv682x.h"
+#include "timer.h"
+#include "test/drivers/test_state.h"
+#include "test/drivers/utils.h"
+#include "usbc_ppc.h"
+
+#define SYV682X_ORD DT_DEP_ORD(DT_NODELABEL(syv682x_emul))
+#define GPIO_USB_C1_FRS_EN_PATH DT_PATH(named_gpios, usb_c1_frs_en)
+
+struct ppc_syv682x_fixture {
+ struct i2c_emul *ppc_emul;
+ const struct device *frs_en_gpio_port;
+ int frs_en_gpio_pin;
+};
+
+/* Configuration for a mock I2C access function that sometimes fails. */
+struct reg_to_fail_data {
+ int reg_access_to_fail;
+ int reg_access_fail_countdown;
+};
+
+static const int syv682x_port = 1;
+
+static void *syv682x_test_setup(void)
+{
+ static struct ppc_syv682x_fixture fixture;
+
+ fixture.ppc_emul = syv682x_emul_get(SYV682X_ORD);
+ zassume_not_null(fixture.ppc_emul, NULL);
+ fixture.frs_en_gpio_port =
+ DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios));
+ zassume_not_null(fixture.frs_en_gpio_port, NULL);
+ fixture.frs_en_gpio_pin = DT_GPIO_PIN(GPIO_USB_C1_FRS_EN_PATH, gpios);
+
+ return &fixture;
+}
+
+static void syv682x_test_after(void *data)
+{
+ struct ppc_syv682x_fixture *fixture = data;
+ struct i2c_emul *emul = fixture->ppc_emul;
+
+ /* Disable the power path and clear interrupt conditions. */
+ zassume_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG,
+ SYV682X_CONTROL_1_PWR_ENB),
+ NULL);
+ syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_NONE);
+
+ /* Clear the mock read/write functions */
+ i2c_common_emul_set_read_func(emul, NULL, NULL);
+ i2c_common_emul_set_write_func(emul, NULL, NULL);
+
+ /* Don't fail on any register access */
+ i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
+ i2c_common_emul_set_write_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_SUITE(ppc_syv682x, drivers_predicate_post_main, syv682x_test_setup, NULL,
+ syv682x_test_after, NULL);
+
+ZTEST_F(ppc_syv682x, test_syv682x_board_is_syv682c)
+{
+ /*
+ * The SYV682x driver should assume a version-C part in the absence of a
+ * board override.
+ */
+ zassert_true(syv682x_board_is_syv682c(syv682x_port), NULL);
+}
+
+static void check_control_1_default_init(uint8_t control_1)
+{
+ /*
+ * During init, when not in dead battery mode, the driver should
+ * configure the high-voltage channel as sink but leave the power path
+ * disabled. The driver should set the current limits according to
+ * configuration.
+ */
+ int ilim;
+
+ zassert_true(control_1 & SYV682X_CONTROL_1_PWR_ENB,
+ "Default init, but power path enabled");
+ ilim = (control_1 & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT;
+ zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM,
+ "Default init, but HV current limit set to %d", ilim);
+ zassert_false(control_1 & SYV682X_CONTROL_1_HV_DR,
+ "Default init, but source mode selected");
+ zassert_true(control_1 & SYV682X_CONTROL_1_CH_SEL,
+ "Default init, but 5V power path selected");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_init_dead_battery)
+{
+ uint8_t reg;
+
+ /*
+ * With a dead battery, the device powers up sinking VBUS, and the
+ * driver should keep that going.
+ */
+ zassume_ok(syv682x_emul_set_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ SYV682X_CONTROL_1_CH_SEL),
+ NULL);
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_VSAFE_5V,
+ SYV682X_CONTROL_4_NONE);
+ zassert_ok(ppc_init(syv682x_port), "PPC init failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+ zassert_true(reg & SYV682X_CONTROL_1_CH_SEL,
+ "Dead battery init, but CH_SEL set to 5V power path");
+ zassert_false(reg & (SYV682X_CONTROL_1_PWR_ENB |
+ SYV682X_CONTROL_1_HV_DR),
+ "Dead battery init, but CONTROL_1 is 0x%x", reg);
+ zassert_false(ppc_is_sourcing_vbus(syv682x_port),
+ "Dead battery init, but VBUS source enabled");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_init_vsafe0v)
+{
+ uint8_t reg;
+
+ /* With VBUS at vSafe0V, init should set the default configuration. */
+ zassume_ok(syv682x_emul_set_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ SYV682X_CONTROL_1_PWR_ENB),
+ NULL);
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_VSAFE_0V,
+ SYV682X_CONTROL_4_NONE);
+ zassert_ok(ppc_init(syv682x_port), "PPC init failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+ check_control_1_default_init(reg);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_init_sink_disabled)
+{
+ uint8_t reg;
+
+ /* With sink disabled, init should do the same thing. */
+ zassume_ok(syv682x_emul_set_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ SYV682X_CONTROL_1_CH_SEL),
+ NULL);
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_VSAFE_0V,
+ SYV682X_CONTROL_4_NONE);
+ zassert_ok(ppc_init(syv682x_port), "PPC init failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+ check_control_1_default_init(reg);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_init_common)
+{
+ uint8_t reg;
+ int ilim;
+
+ zassert_ok(ppc_init(syv682x_port), "PPC init failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+
+ /*
+ * Any init sequence should also disable the FRS GPIO, set the 5V
+ * current limit according to configuration, set over-current, over-
+ * voltage, and discharge parameters appropriately, and enable CC lines.
+ */
+ zassert_equal(gpio_emul_output_get(this->frs_en_gpio_port,
+ this->frs_en_gpio_pin),
+ 0, "FRS enabled, but FRS GPIO not asserted");
+ ilim = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
+ zassert_equal(ilim, CONFIG_PLATFORM_EC_USB_PD_PULLUP,
+ "Default init, but 5V current limit set to %d", ilim);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_2_REG,
+ &reg),
+ NULL);
+ zassert_equal(reg,
+ (SYV682X_OC_DELAY_10MS << SYV682X_OC_DELAY_SHIFT) |
+ (SYV682X_DSG_RON_200_OHM
+ << SYV682X_DSG_RON_SHIFT) |
+ (SYV682X_DSG_TIME_50MS << SYV682X_DSG_TIME_SHIFT),
+ "Default init, but CONTROL_2 is 0x%x", reg);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_3_REG,
+ &reg),
+ NULL);
+ zassert_equal(reg,
+ (SYV682X_OVP_23_7 << SYV682X_OVP_BIT_SHIFT) |
+ SYV682X_RVS_MASK,
+ "Default init, but CONTROL_3 is 0x%x", reg);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ NULL);
+ zassert_equal(reg & ~SYV682X_CONTROL_4_INT_MASK,
+ SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS,
+ "Default init, but CONTROL_4 is 0x%x", reg);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_source_enable)
+{
+ uint8_t reg;
+
+ zassert_ok(ppc_vbus_source_enable(syv682x_port, true),
+ "VBUS enable failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
+ "VBUS sourcing enabled but power path disabled");
+ zassert_true(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is not sourcing VBUS after VBUS enabled");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_source_disable)
+{
+ zassert_ok(ppc_vbus_source_enable(syv682x_port, false),
+ "VBUS disable failed");
+ zassert_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC sourcing VBUS after disable");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_source_oc)
+{
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, true),
+ "VBUS enable failed");
+ /* An OC event less than 100 ms should not cause VBUS to turn off. */
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OC_5V,
+ SYV682X_CONTROL_4_NONE);
+ msleep(50);
+ zassert_true(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is not sourcing VBUS after 50 ms OC");
+ /* But one greater than 100 ms should. */
+ msleep(60);
+ zassert_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is sourcing VBUS after 100 ms OC");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_tsd)
+{
+ /*
+ * A TSD event should cause the driver to disable source and sink paths.
+ * (The device will have already physically disabled them.) The state of
+ * the sink path is not part of the driver's API.
+ */
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, true),
+ "Source enable failed");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_TSD,
+ SYV682X_CONTROL_4_NONE);
+ msleep(1);
+ zassert_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is sourcing power after TSD");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_vbus_ovp)
+{
+ /* An OVP event should cause the driver to disable the source path. */
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, true),
+ "Source enable failed");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OVP,
+ SYV682X_CONTROL_4_NONE);
+ msleep(1);
+ zassert_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is sourcing power after OVP");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_vbus_hv_oc)
+{
+ uint8_t reg;
+
+ /*
+ * A high-voltage OC while sinking should cause the driver to try to
+ * re-enable the sink path until the OC count limit is reached, at which
+ * point the driver should leave it disabled.
+ */
+ zassume_ok(ppc_vbus_sink_enable(syv682x_port, true),
+ "Sink enable failed");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OC_HV,
+ SYV682X_CONTROL_4_NONE);
+ msleep(1);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
+ "Power path disabled after HV_OC handled");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OC_HV,
+ SYV682X_CONTROL_4_NONE);
+ /* Alert GPIO doesn't change so wait for delayed syv682x interrupt */
+ msleep(15);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0,
+ "Power path disabled after HV_OC handled");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OC_HV,
+ SYV682X_CONTROL_4_NONE);
+ /* Alert GPIO doesn't change so wait for delayed syv682x interrupt */
+ msleep(15);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB,
+ SYV682X_CONTROL_1_PWR_ENB,
+ "Power path enabled after HV_OC handled 3 times");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_vconn_oc)
+{
+ uint8_t reg;
+
+ /*
+ * A VCONN OC event less than 100 ms should not cause the driver to turn
+ * VCONN off.
+ */
+ ppc_set_vconn(syv682x_port, true);
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_VCONN_OCP);
+ msleep(1);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_true(reg & (SYV682X_CONTROL_4_VCONN1 |
+ SYV682X_CONTROL_4_VCONN2),
+ "VCONN disabled after initial VCONN OC");
+ msleep(50);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_true(reg & (SYV682X_CONTROL_4_VCONN1 |
+ SYV682X_CONTROL_4_VCONN2),
+ "VCONN disabled after short VCONN OC");
+ /*
+ * But if the event keeps going for over 100 ms continuously, the driver
+ * should turn VCONN off.
+ */
+ msleep(60);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_false(reg & (SYV682X_CONTROL_4_VCONN1 |
+ SYV682X_CONTROL_4_VCONN2),
+ "VCONN enabled after long VCONN OC");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_interrupt_vconn_ov)
+{
+ uint8_t reg;
+
+ /*
+ * A VCONN over-voltage (VBAT_OVP) event will cause the device to
+ * disconnect CC and VCONN. The driver should then reinitialize the
+ * device, which will enable both CC lines but leave VCONN disabled. The
+ * driver should then run generic CC over-voltage handling.
+ */
+ ppc_set_vconn(syv682x_port, true);
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_VBAT_OVP);
+ msleep(1);
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_true(reg & SYV682X_CONTROL_4_CC1_BPS,
+ "CC1 disabled after handling VBAT_OVP");
+ zassert_true(reg & SYV682X_CONTROL_4_CC2_BPS,
+ "CC2 disabled after handling VBAT_OVP");
+ zassert_false(reg & (SYV682X_CONTROL_4_VCONN1 |
+ SYV682X_CONTROL_4_VCONN2),
+ "VCONN enabled after handling VBAT_OVP");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_frs_enable)
+{
+ const struct device *gpio_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios));
+ uint8_t reg;
+
+ /*
+ * Enabling FRS should enable only the appropriate CC line based on
+ * polarity. Disabling FRS should enable both CC lines.
+ */
+ ppc_vbus_sink_enable(syv682x_port, true);
+ zassume_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is sourcing VBUS after sink enabled");
+ ppc_set_polarity(syv682x_port, 0 /* CC1 */);
+ ppc_set_frs_enable(syv682x_port, true);
+ zassert_equal(gpio_emul_output_get(gpio_dev, this->frs_en_gpio_pin), 1,
+ "FRS enabled, but FRS GPIO not asserted");
+ zassert_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_equal(
+ reg & (SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS),
+ SYV682X_CONTROL_4_CC1_BPS,
+ "FRS enabled with CC1 polarity, but CONTROL_4 is 0x%x", reg);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_frs_disable)
+{
+ const struct device *gpio_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios));
+ uint8_t reg;
+
+ ppc_vbus_sink_enable(syv682x_port, true);
+ zassume_false(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is sourcing VBUS after sink enabled");
+ ppc_set_polarity(syv682x_port, 0 /* CC1 */);
+
+ ppc_set_frs_enable(syv682x_port, false);
+ zassert_equal(gpio_emul_output_get(gpio_dev, this->frs_en_gpio_pin), 0,
+ "FRS disabled, but FRS GPIO not deasserted");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_4_REG,
+ &reg),
+ "Reading CONTROL_4 failed");
+ zassert_equal(
+ reg & (SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS),
+ SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS,
+ "FRS disabled with CC1 polarity, but CONTROL_4 is 0x%x", reg);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_frs_trigger)
+{
+ /*
+ * An FRS event when the PPC is Sink should cause the PPC to switch from
+ * Sink to Source.
+ */
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_FRS,
+ SYV682X_CONTROL_4_NONE);
+ msleep(1);
+ zassert_true(ppc_is_sourcing_vbus(syv682x_port),
+ "PPC is not sourcing VBUS after FRS signal handled");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_NONE);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_source_current_limit_usb_default)
+{
+ uint8_t reg;
+ int ilim_val;
+
+ zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_USB),
+ "Could not set source current limit");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
+ zassert_equal(reg & SYV682X_5V_ILIM_MASK, SYV682X_5V_ILIM_1_25,
+ "Set USB Rp value, but 5V_ILIM is %d", ilim_val);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_source_current_limit_1500ma)
+{
+ uint8_t reg;
+ int ilim_val;
+
+ zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_1A5),
+ "Could not set source current limit");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
+ zassert_equal(ilim_val, SYV682X_5V_ILIM_1_75,
+ "Set 1.5A Rp value, but 5V_ILIM is %d", ilim_val);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_source_current_limit_3000ma)
+{
+ uint8_t reg;
+ int ilim_val;
+
+ zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_3A0),
+ "Could not set source current limit");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ "Reading CONTROL_1 failed");
+ ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT;
+ zassert_equal(ilim_val, SYV682X_5V_ILIM_3_30,
+ "Set 3.0A Rp value, but 5V_ILIM is %d", ilim_val);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_write_busy)
+{
+ /*
+ * Writes should fail while the BUSY bit is set, except that writes to
+ * CONTROL_4 should succeed on the SYV682C. 1000 reads is intentionally
+ * many more than the driver is expected to make before reaching its
+ * timeout. It is not a goal of this test to verify the frequency of
+ * polling or the exact value of the timeout.
+ */
+ syv682x_emul_set_busy_reads(this->ppc_emul, 1000);
+ zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_USB),
+ EC_ERROR_TIMEOUT, "SYV682 busy, but write completed");
+ zassert_ok(ppc_set_frs_enable(syv682x_port, false),
+ "Could not set CONTROL_4 while busy on SYV682C");
+
+ /*
+ * If the busy bit clears before the driver reaches its timeout, the
+ * write should succeed.
+ */
+ syv682x_emul_set_busy_reads(this->ppc_emul, 1);
+ zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_USB),
+ 0, "SYV682 not busy, but write failed");
+
+ syv682x_emul_set_busy_reads(this->ppc_emul, 0);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_dev_is_connected)
+{
+ uint8_t reg;
+
+ zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SRC),
+ "Could not connect device as source");
+ zassert_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_2_REG,
+ &reg),
+ "Reading CONTROL_2 failed");
+ zassert_false(reg & SYV682X_CONTROL_2_FDSG,
+ "Connected as source, but force discharge enabled");
+
+ zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_DISCONNECTED),
+ "Could not disconnect device");
+ zassert_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_2_REG,
+ &reg),
+ "Reading CONTROL_2 failed");
+ zassert_true(reg & SYV682X_CONTROL_2_FDSG,
+ "Disconnected, but force discharge disabled");
+
+ zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SNK),
+ "Could not connect device as source");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_sink_enable_trivial)
+{
+ /*
+ * If VBUS source is already enabled, disabling VBUS sink should
+ * trivially succeed.
+ */
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, true),
+ "VBUS enable failed");
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
+ "Sink disable failed");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_sink_enable_power_path)
+{
+ uint8_t reg;
+ int ilim;
+
+ /*
+ * After enabling VBUS sink, the HV power path should be enabled in sink
+ * mode with the configured current limit.
+ */
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, false),
+ "VBUS enable failed");
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
+ "Sink disable failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+ zassert_true(reg & SYV682X_CONTROL_1_CH_SEL,
+ "Sink enabled, but CH_SEL set to 5V power path");
+ zassert_false(reg & SYV682X_CONTROL_1_PWR_ENB,
+ "Sink enabled, but power path disabled");
+ zassert_false(reg & SYV682X_CONTROL_1_HV_DR,
+ "Sink enabled, but high-voltage path in source mode");
+ ilim = (reg & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT;
+ zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM,
+ "Sink enabled, but HV current limit set to %d", ilim);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_sink_disable)
+{
+ uint8_t reg;
+
+ zassume_ok(ppc_vbus_source_enable(syv682x_port, false),
+ "VBUS enable failed");
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
+ "Sink disable failed");
+
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
+ "Sink disable failed");
+ zassume_ok(syv682x_emul_get_reg(this->ppc_emul, SYV682X_CONTROL_1_REG,
+ &reg),
+ NULL);
+ zassert_true(reg & SYV682X_CONTROL_1_PWR_ENB,
+ "Sink disabled, but power path enabled");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_vbus_sink_oc_limit)
+{
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
+ "Sink enable failed");
+
+ /* Generate 4 consecutive sink over-current interrupts. After reaching
+ * this count, the driver should prevent sink enable until the count is
+ * cleared by sink disable.
+ */
+ for (int i = 0; i < 4; ++i) {
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_OC_HV,
+ SYV682X_CONTROL_4_NONE);
+ msleep(15);
+ }
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_NONE);
+
+ zassert_not_equal(ppc_vbus_sink_enable(syv682x_port, true), EC_SUCCESS,
+ "VBUS sink enable succeeded after 4 OC events");
+
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
+ "Sink disable failed");
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, true),
+ "Sink enable failed");
+ zassert_ok(ppc_vbus_sink_enable(syv682x_port, false),
+ "Sink disable failed");
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_set_vconn)
+{
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_VBAT_OVP);
+ zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
+ "VBAT OVP, but ppc_set_vconn succeeded");
+}
+
+ZTEST(ppc_syv682x, test_syv682x_ppc_dump)
+{
+ /*
+ * The ppc_dump command should succeed for this port. Don't check the
+ * output, since there are no standard requirements for that.
+ */
+ const struct ppc_drv *drv = ppc_chips[syv682x_port].drv;
+
+ zassert_ok(drv->reg_dump(syv682x_port), "ppc_dump command failed");
+}
+
+/* Intercepts I2C reads as a mock. Fails to read for the register at offset
+ * reg_access_to_fail on read number N, where N is the initial value of
+ * reg_access_fail_countdown.
+ */
+static int mock_read_intercept_reg_fail(struct i2c_emul *emul, int reg,
+ uint8_t *val, int bytes, void *data)
+{
+ struct reg_to_fail_data *test_data = data;
+
+ if (reg == test_data->reg_access_to_fail) {
+ test_data->reg_access_fail_countdown--;
+ if (test_data->reg_access_fail_countdown <= 0)
+ return -1;
+ }
+ return 1;
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_i2c_error_status)
+{
+ /* Failed STATUS read should cause init to fail. */
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul, SYV682X_STATUS_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "STATUS read error, but init succeeded");
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_i2c_error_control_1)
+{
+ const struct ppc_drv *drv = ppc_chips[syv682x_port].drv;
+ struct reg_to_fail_data reg_fail = {
+ .reg_access_to_fail = 0,
+ .reg_access_fail_countdown = 0,
+ };
+
+ /* Failed CONTROL_1 read */
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_1_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_1 read error, but init succeeded");
+ zassert_not_equal(ppc_vbus_source_enable(syv682x_port, true),
+ EC_SUCCESS,
+ "CONTROL_1 read error, but VBUS source enable "
+ "succeeded");
+ zassert_not_equal(ppc_vbus_sink_enable(syv682x_port, true), EC_SUCCESS,
+ "CONTROL_1 read error, but VBUS sink enable "
+ "succeeded");
+ zassert_not_equal(ppc_set_vbus_source_current_limit(syv682x_port,
+ TYPEC_RP_USB),
+ EC_SUCCESS,
+ "CONTROL_1 read error, but set current limit "
+ "succeeded");
+ zassert_ok(drv->reg_dump(syv682x_port),
+ "CONTROL_1 read error, and ppc_dump failed");
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Init reads CONTROL_1 several times. The 3rd read happens while
+ * setting the source current limit. Check that init fails when that
+ * read fails.
+ */
+ i2c_common_emul_set_read_func(this->ppc_emul,
+ &mock_read_intercept_reg_fail, &reg_fail);
+ reg_fail.reg_access_to_fail = SYV682X_CONTROL_1_REG;
+ reg_fail.reg_access_fail_countdown = 3;
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_1 read error, but init succeeded");
+ i2c_common_emul_set_read_func(this->ppc_emul, NULL, NULL);
+
+ /* Failed CONTROL_1 write */
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_1_REG);
+
+ /* During init, the driver will write CONTROL_1 either to disable all
+ * power paths (normal case) or to enable the sink path (dead battery
+ * case). vSafe0V in STATUS is one indication of the normal case.
+ */
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_VSAFE_0V,
+ SYV682X_CONTROL_4_NONE);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_1 write error, but init succeeded");
+ syv682x_emul_set_condition(this->ppc_emul, SYV682X_STATUS_NONE,
+ SYV682X_CONTROL_4_NONE);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_1 write error, but init succeeded");
+
+ zassert_not_equal(ppc_vbus_source_enable(syv682x_port, true),
+ EC_SUCCESS,
+ "CONTROL_1 write error, but VBUS source "
+ "enable succeeded");
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_i2c_error_control_2)
+{
+ /* Failed CONTROL_2 read */
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_2_REG);
+ zassert_not_equal(ppc_discharge_vbus(syv682x_port, true), EC_SUCCESS,
+ "CONTROL_2 read error, but VBUS discharge succeeded");
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Failed CONTROL_2 write */
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_2_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_2 write error, but init succeeded");
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_i2c_error_control_3)
+{
+ /* Failed CONTROL_3 read */
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_3_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_3 read error, but VBUS discharge succeeded");
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Failed CONTROL_3 write */
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_3_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_3 write error, but init succeeded");
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
+
+ZTEST_F(ppc_syv682x, test_syv682x_i2c_error_control_4)
+{
+ /* Failed CONTROL_4 read */
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_4_REG);
+ zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
+ "CONTROL_2 read error, but VCONN set succeeded");
+ i2c_common_emul_set_read_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+
+ /* Failed CONTROL_4 write */
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ SYV682X_CONTROL_4_REG);
+ zassert_not_equal(ppc_init(syv682x_port), EC_SUCCESS,
+ "CONTROL_4 write error, but init succeeded");
+ zassert_not_equal(ppc_set_vconn(syv682x_port, true), EC_SUCCESS,
+ "CONTROL_4 write error, but VCONN set succeeded");
+ i2c_common_emul_set_write_fail_reg(this->ppc_emul,
+ I2C_COMMON_EMUL_NO_FAIL_REG);
+}
diff --git a/zephyr/test/drivers/src/watchdog.c b/zephyr/test/drivers/src/watchdog.c
index d66ee77bd8..8b91247f12 100644
--- a/zephyr/test/drivers/src/watchdog.c
+++ b/zephyr/test/drivers/src/watchdog.c
@@ -23,6 +23,8 @@
#include "watchdog.h"
#include "test/drivers/test_state.h"
+#define wdt DEVICE_DT_GET(DT_CHOSEN(cros_ec_watchdog))
+
/**
* @brief Default watchdog timeout plus some time for it to expire.
*/
@@ -47,6 +49,12 @@ static void watchdog_before(void *state)
ARG_UNUSED(state);
set_test_runner_tid();
wdt_warning_triggered = false;
+
+ /* When shuffling need watchdog initialized and running
+ * for other tests.
+ */
+ (void) watchdog_init();
+ (void) wdt_setup(wdt, 0);
}
/**
@@ -72,12 +80,7 @@ ZTEST(watchdog, test_watchdog_init)
{
int retval = EC_SUCCESS;
- /* Test successful initialization */
- retval = watchdog_init();
- zassert_equal(EC_SUCCESS, retval, "Expected EC_SUCCESS, returned %d.",
- retval);
-
- /* Test already initialized */
+ /* Test already initialized (initialized in watchdog_before) */
retval = watchdog_init();
zassert_equal(-ENOMEM, retval, "Expected -ENOMEM, returned %d.",
retval);
@@ -120,6 +123,9 @@ ZTEST(watchdog, test_watchdog_reload)
*/
ZTEST(watchdog, test_wdt_warning_handler)
{
+ /* Feed the dog so timer is reset */
+ watchdog_reload();
+
zassert_false(wdt_warning_triggered, "Watchdog timer expired early.");
k_timer_start(&ktimer, K_MSEC(DEFAULT_WDT_EXPIRY_MS), K_NO_WAIT);
diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py
index e56e13a519..9e00473752 100644
--- a/zephyr/zmake/tests/test_version.py
+++ b/zephyr/zmake/tests/test_version.py
@@ -133,7 +133,6 @@ EXPECTED_HEADER = (
'#define CROS_EC_VERSION32 "trogdor_v2.6.1004-cmsis:0dead0,"\n'
'#define BUILDER "toukmond@pokey"\n'
'#define DATE "2021-06-28 03:18:53"\n'
- '#define CROS_FWID_MISSING_STR "CROS_FWID_MISSING"\n'
"#define CROS_FWID32 CROS_FWID_MISSING_STR\n"
)
HEADER_VERSION_STR_STATIC = "trogdor_v2.6.0-STATIC"
@@ -143,7 +142,6 @@ EXPECTED_HEADER_STATIC = (
'#define CROS_EC_VERSION32 "trogdor_v2.6.0-STATIC"\n'
'#define BUILDER "reproducible@build"\n'
'#define DATE "STATIC_VERSION_DATE"\n'
- '#define CROS_FWID_MISSING_STR "CROS_FWID_MISSING"\n'
"#define CROS_FWID32 CROS_FWID_MISSING_STR\n"
)
diff --git a/zephyr/zmake/zmake/output_packers.py b/zephyr/zmake/zmake/output_packers.py
index c09c6cc84c..78ee7649e6 100644
--- a/zephyr/zmake/zmake/output_packers.py
+++ b/zephyr/zmake/zmake/output_packers.py
@@ -237,7 +237,7 @@ class MchpPacker(BinmanPacker):
"""Packer for RO/RW image to generate a .bin build using FMAP.
This expects that the build is setup to generate a
- zephyr.npcx.bin for the RO image, which should be packed using
+ zephyr.mchp.bin for the RO image, which should be packed using
Microchip's loader format.
"""
diff --git a/zephyr/zmake/zmake/version.py b/zephyr/zmake/zmake/version.py
index 2333ad46df..5ac060f23b 100644
--- a/zephyr/zmake/zmake/version.py
+++ b/zephyr/zmake/zmake/version.py
@@ -162,7 +162,6 @@ def write_version_header(version_str, output_path, static=False):
add_def("BUILDER", "{}@{}".format(getpass.getuser(), platform.node()))
add_def("DATE", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
- add_def("CROS_FWID_MISSING_STR", "CROS_FWID_MISSING")
# TODO(b/198475757): Add zmake support for getting CROS_FWID32
add_def_unquoted("CROS_FWID32", "CROS_FWID_MISSING_STR")