summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Marheine <pmarheine@chromium.org>2023-02-16 00:14:21 +0000
committerPeter Marheine <pmarheine@chromium.org>2023-02-16 00:14:21 +0000
commitf43d6df6f2860dbe8ec15aebdc28890771ad7897 (patch)
tree6877eff7016f9979e46017ea5221a16d36344304
parentdce247e97903a2464ff8884106bffa43587c1dcb (diff)
parent0849542c72359150a357945c010dca6b5a213633 (diff)
downloadchrome-ec-firmware-nissa-15217.126.B-main.tar.gz
Merge remote-tracking branch cros/main into firmware-nissa-15217.B-mainfirmware-nissa-15217.126.B-main
Generated by: ./util/update_release_branch.py --zephyr --board nissa firmware- nissa-15217.B-main Relevant changes: git log --oneline dce247e979..0849542c72 -- zephyr/program/nissa util/getversion.sh 0849542c72 zephyr: add sleep property for keyboard factory test 5825d894b9 nissa: disable PLATFORM_EC_TCPC_INTERRUPT 25a400690f yavikso: Update fan table version 3 9263f14536 zephyr: remove shi node and add references to shi0 b40c6970d3 Craask: Charger limit for 65w adapter 6fd2d3ea6c zephyr: add comments for tcpc driver 00986ffb1c zephyr: move usbc interrupt handler to shim 2508094b14 yaviks: reduce RW image size (64KB) 55b6aaf52f yaviks: enable keyboard factory test 4786d1eac6 nissa: Add ocpc init function to Nissa boards 2ae1083638 zephyr: cros_kb: set KSI/KSO kbs mode by pinctrl driver d415f4665a yaviks: Fix OCPC Vsys overshooting 93f9d42a7c zephyr: config: drop few more redundant options BRANCH=None BUG=b:254148652 b:260762509 b:265220075 b:268273712 b:265763662 BUG=b:253557900 b:254148652 b:269212593 b:267404783 b:262352202 TEST=`make -j buildall` Force-Relevant-Builds: all Change-Id: I195dd82af114180b611f9afd1465a69f7f43d417 Signed-off-by: Peter Marheine <pmarheine@chromium.org>
-rw-r--r--.gitlab-ci.yml14
-rw-r--r--.isort.cfg2
-rw-r--r--Makefile.toolchain2
-rw-r--r--PRESUBMIT.cfg1
-rw-r--r--baseboard/cherry/baseboard.c6
-rw-r--r--baseboard/dedede/variant_ec_it8320.c3
-rw-r--r--baseboard/trogdor/usb_pd_policy.c22
-rw-r--r--board/aurash/board.c566
-rw-r--r--board/aurash/board.h198
-rw-r--r--board/aurash/build.mk22
-rw-r--r--board/aurash/ec.tasklist28
-rw-r--r--board/aurash/fans.c50
-rw-r--r--board/aurash/fw_config.c65
-rw-r--r--board/aurash/fw_config.h41
-rw-r--r--board/aurash/gpio.inc182
-rw-r--r--board/aurash/i2c.c77
-rw-r--r--board/aurash/led.c260
-rw-r--r--board/aurash/pwm.c39
-rw-r--r--board/aurash/sensors.c114
-rw-r--r--board/aurash/usbc_config.c416
-rw-r--r--board/aurash/usbc_config.h20
-rw-r--r--board/aurash/vif_override.xml3
-rw-r--r--board/brask/board.c8
-rw-r--r--board/brya/usbc_config.c4
-rw-r--r--board/casta/battery.c7
-rw-r--r--board/coachz/board.c6
-rw-r--r--board/constitution/board.c600
-rw-r--r--board/constitution/board.h204
-rw-r--r--board/constitution/build.mk22
-rw-r--r--board/constitution/ec.tasklist29
-rw-r--r--board/constitution/fans.c50
-rw-r--r--board/constitution/fw_config.c65
-rw-r--r--board/constitution/fw_config.h41
-rw-r--r--board/constitution/gpio.inc187
-rw-r--r--board/constitution/i2c.c77
-rw-r--r--board/constitution/led.c260
-rw-r--r--board/constitution/pwm.c39
-rw-r--r--board/constitution/sensors.c114
-rw-r--r--board/constitution/usbc_config.c416
-rw-r--r--board/constitution/usbc_config.h20
-rw-r--r--board/constitution/vif_override.xml3
-rw-r--r--board/dibbi/board.c121
-rw-r--r--board/dibbi/board.h18
-rw-r--r--board/dibbi/build.mk1
-rw-r--r--board/dibbi/gpio.inc109
-rw-r--r--board/dibbi/usb_pd_policy.c26
-rw-r--r--board/hatch_fp/build.mk1
-rw-r--r--board/hyperdebug/board.h21
-rw-r--r--board/hyperdebug/gpio.c670
-rw-r--r--board/hyperdebug/gpio.inc175
-rw-r--r--board/jinlon/thermal.c28
-rw-r--r--board/kuldax/board.c12
-rw-r--r--board/kuldax/fw_config.c5
-rw-r--r--board/kuldax/fw_config.h16
-rw-r--r--board/nautilus/battery.c6
-rw-r--r--board/nocturne_fp/build.mk1
-rw-r--r--board/omnigul/board.c8
-rw-r--r--board/omnigul/board.h50
-rw-r--r--board/omnigul/build.mk1
-rw-r--r--board/omnigul/ec.tasklist5
-rw-r--r--board/omnigul/generated-gpio.inc32
-rw-r--r--board/omnigul/gpio.inc5
-rw-r--r--board/omnigul/i2c.c24
-rw-r--r--board/omnigul/keyboard.c55
-rw-r--r--board/omnigul/keyboard_customization.c102
-rw-r--r--board/omnigul/keyboard_customization.h80
-rw-r--r--board/omnigul/led.c11
-rw-r--r--board/omnigul/pwm.c14
-rw-r--r--board/omnigul/sensors.c136
-rw-r--r--board/omnigul/usbc_config.c326
-rw-r--r--board/omnigul/usbc_config.h11
-rw-r--r--board/redrix/board.c6
-rwxr-xr-xchip/ish/util/pack_ec.py1
-rwxr-xr-xchip/mchp/util/pack_ec.py1
-rwxr-xr-xchip/mchp/util/pack_ec_mec152x.py1
-rwxr-xr-xchip/mchp/util/pack_ec_mec172x.py1
-rw-r--r--chip/stm32/clock-stm32l4.c4
-rw-r--r--chip/stm32/dfu_bootmanager_main.c10
-rw-r--r--common/body_detection.c5
-rw-r--r--common/build.mk6
-rw-r--r--common/charge_state_v2.c7
-rw-r--r--common/flash.c4
-rw-r--r--common/i2c_controller.c3
-rw-r--r--common/mock/dp_alt_mode_mock.c5
-rw-r--r--common/ocpc.c4
-rw-r--r--common/peripheral_charger.c4
-rw-r--r--common/system_safe_mode.c15
-rw-r--r--common/usb_pd_alt_mode_dfp.c436
-rw-r--r--common/usb_pd_discovery.c471
-rw-r--r--common/usb_pd_host_cmd.c78
-rw-r--r--common/usb_pd_policy.c67
-rw-r--r--common/usbc/build.mk2
-rw-r--r--common/usbc/usb_pd_dpm.c17
-rw-r--r--common/usbc/usb_pe_drp_sm.c59
-rw-r--r--common/usbc/usb_pe_private.h2
-rw-r--r--core/cortex-m/ec.lds.S16
-rw-r--r--core/cortex-m/irq_handler.h31
-rw-r--r--core/cortex-m/panic.c3
-rw-r--r--cts/common/board.py3
-rwxr-xr-xcts/cts.py1
-rw-r--r--docs/fingerprint/fingerprint-dev-for-partners.md173
-rw-r--r--docs/fingerprint/fingerprint-firmware-testing-for-partners.md6
-rw-r--r--docs/zephyr/zephyr_ap_ec_comm.md7
-rw-r--r--docs/zephyr/ztest.md13
-rw-r--r--driver/charger/isl923x.c37
-rw-r--r--driver/charger/rt9490.c2
-rw-r--r--driver/nfc/ctn730.c2
-rw-r--r--driver/ppc/rt1739.c58
-rw-r--r--driver/ppc/rt1739.h1
-rw-r--r--driver/retimer/bb_retimer.c2
-rw-r--r--driver/sha256/sha256_it8xxx2.c32
-rw-r--r--driver/tcpm/it83xx_pd.h4
-rw-r--r--driver/tcpm/it8xxx2.c15
-rw-r--r--driver/wpc/cps8100.c2
-rw-r--r--driver/wpc/cps8100.h15
-rwxr-xr-xextra/cr50_rma_open/cr50_rma_open.py1
-rwxr-xr-xextra/stack_analyzer/stack_analyzer.py1
-rw-r--r--extra/tigertool/ecusb/pty_driver.py1
-rw-r--r--extra/tigertool/ecusb/tiny_servo_common.py3
-rw-r--r--extra/tigertool/ecusb/tiny_servod.py3
-rwxr-xr-xextra/tigertool/tigertest.py1
-rwxr-xr-xextra/tigertool/tigertool.py1
-rwxr-xr-xextra/usb_power/powerlog.py5
-rw-r--r--extra/usb_power/stats_manager.py1
-rwxr-xr-xextra/usb_serial/console.py1
-rwxr-xr-xextra/usb_updater/fw_update.py5
-rwxr-xr-xextra/usb_updater/servo_updater.py2
-rwxr-xr-xfirmware_builder.py32
-rw-r--r--fuzz/fuzz_config.h4
-rw-r--r--fuzz/pchg_fuzz.c6
-rw-r--r--include/config.h23
-rw-r--r--include/fpsensor.h66
-rw-r--r--include/fpsensor_alg.h78
-rw-r--r--include/i2c.h7
-rw-r--r--include/peripheral_charger.h6
-rw-r--r--include/usb_dp_alt_mode.h37
-rw-r--r--include/usb_pd.h14
-rw-r--r--include/usb_pd_tcpm.h4
-rw-r--r--power/mt8186.c36
-rw-r--r--setup.py1
-rw-r--r--test/build.mk1
-rw-r--r--test/fake_usbc.c8
-rwxr-xr-xtest/run_device_tests.py98
-rw-r--r--test/test_config.h6
-rw-r--r--test/timer_jump.py1
-rw-r--r--test/tpm_seed_clear.c104
-rw-r--r--test/tpm_seed_clear.tasklist10
-rw-r--r--test/usb_pe_drp_old.c39
-rwxr-xr-xutil/build_with_clang.py5
-rwxr-xr-xutil/check_zephyr_project_config.py4
l---------util/check_zephyr_project_config.py.vpython31
-rwxr-xr-xutil/check_zephyr_project_config_unittest.py1
-rwxr-xr-xutil/clangd_config.py2
-rw-r--r--util/config_allowed.txt1
-rwxr-xr-xutil/crash_analyzer.py1
-rwxr-xr-xutil/ec3po/console.py6
-rwxr-xr-xutil/ec3po/console_unittest.py5
-rw-r--r--util/ec3po/interpreter.py1
-rwxr-xr-xutil/ec3po/interpreter_unittest.py3
-rw-r--r--util/ec3po/threadproc_shim.py1
-rwxr-xr-xutil/ec_openocd.py1
-rw-r--r--util/ectool.cc3
-rwxr-xr-xutil/flash_jlink.py1
-rwxr-xr-xutil/inject-keys.py1
-rwxr-xr-xutil/kconfig_check.py1
-rwxr-xr-xutil/lcov_stencil.py3
-rwxr-xr-xutil/presubmit_check.sh23
-rw-r--r--util/run_ects.py1
-rwxr-xr-xutil/run_tests.sh4
-rw-r--r--util/test_kconfig_check.py1
-rwxr-xr-xutil/twister_launcher.py4
-rwxr-xr-xutil/twister_tags.py1
-rwxr-xr-xutil/uart_stress_tester.py5
-rwxr-xr-xutil/update_release_branch.py1
-rwxr-xr-xutil/zephyr_check_compliance.py136
-rwxr-xr-xutil/zephyr_check_compliance_unittest.py119
-rw-r--r--zephyr/CMakeLists.txt10
-rw-r--r--zephyr/Kconfig.flash1
-rw-r--r--zephyr/Kconfig.i2c7
-rw-r--r--zephyr/Kconfig.pd19
-rw-r--r--zephyr/Kconfig.powerseq8
-rw-r--r--zephyr/Kconfig.retimer2
-rw-r--r--zephyr/Kconfig.usbc9
-rw-r--r--zephyr/Kconfig.usbc_ss_mux1
-rw-r--r--zephyr/Makefile.cq4
-rw-r--r--zephyr/app/ec/Kconfig2
-rw-r--r--zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x7
-rw-r--r--zephyr/app/ec/chip/arm/st_stm32/Kconfig.stm3232
-rw-r--r--zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx211
-rw-r--r--zephyr/app/ec/ec_app_main.c8
-rw-r--r--zephyr/app/ec/soc/Kconfig6
-rw-r--r--zephyr/boards/arm/mec1727/mec1727.dts5
-rw-r--r--zephyr/boards/arm/npcx7/npcx7.dts13
-rw-r--r--zephyr/boards/arm/npcx9/npcx9.dtsi13
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx_evb.dtsi13
-rw-r--r--zephyr/boards/riscv/it8xxx2/it8xxx2.dts4
-rw-r--r--zephyr/drivers/cros_flash/cros_flash_it8xxx2.c2
-rw-r--r--zephyr/drivers/cros_flash/cros_flash_xec.c6
-rw-r--r--zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c53
-rw-r--r--zephyr/drivers/cros_shi/Kconfig4
-rw-r--r--zephyr/drivers/cros_shi/cros_shi_it8xxx2.c2
-rw-r--r--zephyr/drivers/cros_shi/cros_shi_npcx.c60
-rw-r--r--zephyr/drivers/cros_system/CMakeLists.txt1
-rw-r--r--zephyr/drivers/cros_system/Kconfig23
-rw-r--r--zephyr/drivers/cros_system/cros_system_stm32.c150
-rw-r--r--zephyr/dts/bindings/battery/battery-smart.yaml2
-rw-r--r--zephyr/dts/bindings/battery/bms-gf,cr50.yaml53
-rw-r--r--zephyr/dts/bindings/battery/smp,l21m4pg0.yaml53
-rw-r--r--zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml8
-rw-r--r--zephyr/dts/bindings/cros_pwr_signal/mediatek,mt8188-power-signal-list.yaml21
-rw-r--r--zephyr/dts/bindings/cros_shi/ite,it8xxx2-cros-shi.yaml19
-rw-r--r--zephyr/dts/bindings/cros_shi/nuvoton,npcx-cros-shi.yaml35
-rw-r--r--zephyr/dts/bindings/emul/tcpci.yaml14
-rw-r--r--zephyr/dts/bindings/gpio/gpio-enum-name.yaml1
-rw-r--r--zephyr/dts/bindings/power/ap-pwrseq-sub-states.yaml21
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml7
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml13
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml13
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml14
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml7
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml5
-rw-r--r--zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml7
-rw-r--r--zephyr/dts/bindings/vendor-prefixes.txt3
-rw-r--r--zephyr/emul/emul_isl923x.c11
-rw-r--r--zephyr/emul/tcpc/emul_tcpci.c5
-rwxr-xr-xzephyr/firmware_builder.py16
-rw-r--r--zephyr/include/ap_power/ap_pwrseq.h197
-rw-r--r--zephyr/include/ap_power/ap_pwrseq_sm.h390
-rw-r--r--zephyr/include/ap_power/ap_pwrseq_sm_defs.h78
-rw-r--r--zephyr/include/cros/ite/it8xxx2.dtsi12
-rw-r--r--zephyr/include/cros/nuvoton/npcx.dtsi4
-rw-r--r--zephyr/include/emul/emul_isl923x.h8
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci.h13
-rw-r--r--zephyr/include/soc/nuvoton_npcx/reg_def_cros.h83
-rw-r--r--zephyr/program/brya/i2c.dts18
-rw-r--r--zephyr/program/brya/interrupts.dts10
-rw-r--r--zephyr/program/corsola/ite_keyboard.dtsi26
-rw-r--r--zephyr/program/corsola/ite_program.conf2
-rw-r--r--zephyr/program/corsola/ite_shi.dtsi3
-rw-r--r--zephyr/program/corsola/npcx_host_interface.dtsi2
-rw-r--r--zephyr/program/corsola/npcx_i2c.dtsi12
-rw-r--r--zephyr/program/corsola/npcx_interrupts.dtsi10
-rw-r--r--zephyr/program/corsola/src/npcx_usbc.c8
-rw-r--r--zephyr/program/corsola/tentacruel/project.conf2
-rw-r--r--zephyr/program/geralt/geralt/battery.dtsi5
-rw-r--r--zephyr/program/geralt/geralt/project.overlay1
-rw-r--r--zephyr/program/geralt/gpio.dtsi8
-rw-r--r--zephyr/program/geralt/i2c.dtsi1
-rw-r--r--zephyr/program/geralt/interrupts.dtsi15
-rw-r--r--zephyr/program/geralt/keyboard.dtsi30
-rw-r--r--zephyr/program/geralt/power_signal.dtsi6
-rw-r--r--zephyr/program/geralt/program.conf7
-rw-r--r--zephyr/program/geralt/shi.dtsi3
-rw-r--r--zephyr/program/geralt/src/hibernate.c3
-rw-r--r--zephyr/program/geralt/src/hooks.c8
-rw-r--r--zephyr/program/geralt/src/usb_pd_policy.c2
-rw-r--r--zephyr/program/geralt/src/usbc_config.c46
-rw-r--r--zephyr/program/geralt/usbc.dtsi2
-rw-r--r--zephyr/program/herobrine/common.dtsi2
-rw-r--r--zephyr/program/herobrine/hoglin/project.overlay12
-rw-r--r--zephyr/program/herobrine/i2c.dtsi12
-rw-r--r--zephyr/program/herobrine/interrupts.dtsi10
-rw-r--r--zephyr/program/herobrine/program.conf1
-rw-r--r--zephyr/program/herobrine/src/usbc_config.c4
-rw-r--r--zephyr/program/intelrvp/adlrvp/adlrvp_mchp/prj.conf3
-rw-r--r--zephyr/program/intelrvp/adlrvp/adlrvp_npcx/prj.conf3
-rw-r--r--zephyr/program/intelrvp/mtlrvp/mtlrvpp_mchp/prj.conf3
-rw-r--r--zephyr/program/intelrvp/prj.conf1
-rw-r--r--zephyr/program/it8xxx2_evb/shi.dts3
-rw-r--r--zephyr/program/nissa/craask/project.conf5
-rw-r--r--zephyr/program/nissa/craask/src/usbc.c4
-rw-r--r--zephyr/program/nissa/joxer/keyboard.dtsi26
-rw-r--r--zephyr/program/nissa/nereid/keyboard.dtsi26
-rw-r--r--zephyr/program/nissa/program.conf3
-rw-r--r--zephyr/program/nissa/shi.dtsi3
-rw-r--r--zephyr/program/nissa/src/common.c11
-rw-r--r--zephyr/program/nissa/xivur/project.conf1
-rw-r--r--zephyr/program/nissa/yaviks/fan.dtsi22
-rw-r--r--zephyr/program/nissa/yaviks/gpio.dtsi4
-rw-r--r--zephyr/program/nissa/yaviks/keyboard.dtsi50
-rw-r--r--zephyr/program/nissa/yaviks/overlay.dtsi18
-rw-r--r--zephyr/program/nissa/yaviks/project.conf6
-rw-r--r--zephyr/program/nissa/yaviks/src/keyboard.c19
-rw-r--r--zephyr/program/rex/interrupts.dtsi11
-rw-r--r--zephyr/program/rex/rex.dtsi12
-rw-r--r--zephyr/program/rex/src/usbc_config.c4
-rw-r--r--zephyr/program/skyrim/crystaldrift/CMakeLists.txt1
-rw-r--r--zephyr/program/skyrim/crystaldrift/project.overlay17
-rw-r--r--zephyr/program/skyrim/crystaldrift/src/alt_charger.c8
-rw-r--r--zephyr/program/skyrim/crystaldrift/src/fan.c2
-rw-r--r--zephyr/program/skyrim/crystaldrift/src/keyboard.c29
-rw-r--r--zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c4
-rw-r--r--zephyr/program/skyrim/frostflow/project.conf2
-rw-r--r--zephyr/program/skyrim/frostflow/project.overlay71
-rw-r--r--zephyr/program/skyrim/frostflow/src/thermal.c12
-rw-r--r--zephyr/program/skyrim/frostflow/src/usb_mux_config.c119
-rw-r--r--zephyr/program/skyrim/i2c.dtsi12
-rw-r--r--zephyr/program/skyrim/interrupts.dtsi10
-rw-r--r--zephyr/program/skyrim/markarth/CMakeLists.txt4
-rw-r--r--zephyr/program/skyrim/markarth/include/keyboard_customization.h80
-rw-r--r--zephyr/program/skyrim/markarth/project.conf9
-rw-r--r--zephyr/program/skyrim/markarth/project.overlay28
-rw-r--r--zephyr/program/skyrim/markarth/src/fan.c2
-rw-r--r--zephyr/program/skyrim/markarth/src/keyboard.c45
-rw-r--r--zephyr/program/skyrim/markarth/src/keyboard_customization.c83
-rw-r--r--zephyr/program/skyrim/skyrim/src/alt_charger.c8
-rw-r--r--zephyr/program/skyrim/skyrim/src/fan.c2
-rw-r--r--zephyr/program/skyrim/src/usbc_config.c4
-rw-r--r--zephyr/program/skyrim/winterhold/project.conf4
-rw-r--r--zephyr/program/skyrim/winterhold/project.overlay6
-rw-r--r--zephyr/program/skyrim/winterhold/src/sensor.c4
-rw-r--r--zephyr/program/skyrim/winterhold/src/thermal.c16
-rw-r--r--zephyr/program/skyrim/winterhold/src/usb_mux_config.c2
-rw-r--r--zephyr/program/trogdor/lazor/host_interface_npcx.dts2
-rw-r--r--zephyr/program/trogdor/lazor/i2c.dts12
-rw-r--r--zephyr/program/trogdor/lazor/interrupts.dts10
-rw-r--r--zephyr/program/trogdor/lazor/prj.conf1
-rw-r--r--zephyr/program/trogdor/lazor/src/usbc_config.c4
-rw-r--r--zephyr/shim/chip/CMakeLists.txt2
-rw-r--r--zephyr/shim/chip/it8xxx2/gpio.c72
-rw-r--r--zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h28
-rw-r--r--zephyr/shim/chip/it8xxx2/keyboard_raw.c27
-rw-r--r--zephyr/shim/chip/npcx/shi.c2
-rw-r--r--zephyr/shim/chip/stm32/CMakeLists.txt5
-rw-r--r--zephyr/shim/chip/stm32/include/flash_chip.h22
-rw-r--r--zephyr/shim/include/builtin/assert.h5
-rw-r--r--zephyr/shim/include/config_chip.h25
-rw-r--r--zephyr/shim/include/ec_tasks.h18
-rw-r--r--zephyr/shim/include/shimmed_task_id.h12
-rw-r--r--zephyr/shim/include/shimmed_tasks.h8
-rw-r--r--zephyr/shim/include/usbc/tcpc_anx7447.h4
-rw-r--r--zephyr/shim/include/usbc/tcpc_anx7447_emul.h4
-rw-r--r--zephyr/shim/include/usbc/tcpc_ccgxxf.h9
-rw-r--r--zephyr/shim/include/usbc/tcpc_fusb302.h13
-rw-r--r--zephyr/shim/include/usbc/tcpc_generic_emul.h9
-rw-r--r--zephyr/shim/include/usbc/tcpc_nct38xx.h9
-rw-r--r--zephyr/shim/include/usbc/tcpc_ps8xxx.h13
-rw-r--r--zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h9
-rw-r--r--zephyr/shim/include/usbc/tcpc_rt1718s.h8
-rw-r--r--zephyr/shim/include/usbc/utils.h12
-rw-r--r--zephyr/shim/include/zephyr_hooks_shim.h2
-rw-r--r--zephyr/shim/include/zephyr_host_command.h25
-rw-r--r--zephyr/shim/include/zephyr_mkbp_event.h9
-rw-r--r--zephyr/shim/src/host_command.c12
-rw-r--r--zephyr/shim/src/panic.c9
-rw-r--r--zephyr/shim/src/rtc.c8
-rw-r--r--zephyr/shim/src/tasks.c108
-rw-r--r--zephyr/shim/src/tcpc.c83
-rw-r--r--zephyr/subsys/ap_pwrseq/CMakeLists.txt3
-rw-r--r--zephyr/subsys/ap_pwrseq/Kconfig10
-rw-r--r--zephyr/subsys/ap_pwrseq/ap_pwrseq.c314
-rw-r--r--zephyr/subsys/ap_pwrseq/ap_pwrseq_drv_sm.h71
-rw-r--r--zephyr/subsys/ap_pwrseq/ap_pwrseq_sm.c262
-rw-r--r--zephyr/test/drivers/CMakeLists.txt3
-rw-r--r--zephyr/test/drivers/Kconfig9
-rw-r--r--zephyr/test/drivers/ap_vdm_control/prj.conf3
-rw-r--r--zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c118
-rw-r--r--zephyr/test/drivers/boards/native_posix.overlay14
-rw-r--r--zephyr/test/drivers/common/include/test/drivers/utils.h11
-rw-r--r--zephyr/test/drivers/common/src/stubs.c8
-rw-r--r--zephyr/test/drivers/common/src/utils.c17
-rw-r--r--zephyr/test/drivers/console_cmd_crash/CMakeLists.txt8
-rw-r--r--zephyr/test/drivers/console_cmd_crash/src/crash.c (renamed from zephyr/test/drivers/default/src/console_cmd/crash.c)0
-rw-r--r--zephyr/test/drivers/default/src/console_cmd/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/default/src/espi.c19
-rw-r--r--zephyr/test/drivers/default/src/integration/usbc/usb_pd_ctrl_msg.c3
-rw-r--r--zephyr/test/drivers/default/src/isl923x.c12
-rw-r--r--zephyr/test/drivers/flash/src/flash.c218
-rw-r--r--zephyr/test/drivers/gpio_unhook/CMakeLists.txt7
-rw-r--r--zephyr/test/drivers/gpio_unhook/src/is_not_ready.c30
-rw-r--r--zephyr/test/drivers/gpio_unhook/src/un_init_hooks.c15
-rw-r--r--zephyr/test/drivers/host_command_thread/src/main.c25
-rw-r--r--zephyr/test/drivers/panic_event/CMakeLists.txt6
-rw-r--r--zephyr/test/drivers/panic_event/src/panic_event.c65
-rw-r--r--zephyr/test/drivers/prj.conf4
-rw-r--r--zephyr/test/drivers/shim_rtc/src/test_shim_rtc.c17
-rw-r--r--zephyr/test/drivers/testcase.yaml27
-rw-r--r--zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode.c20
-rw-r--r--zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode__require_ap_mode_entry.c89
-rw-r--r--zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode_ec_mode_entry.c21
-rw-r--r--zephyr/test/drivers/usbc_console_pd/usbc_legacy.dts25
-rw-r--r--zephyr/test/ec_app/boards/native_posix.overlay16
-rw-r--r--zephyr/test/ec_app/prj.conf3
-rw-r--r--zephyr/test/ec_app/src/main.c13
-rw-r--r--zephyr/test/skyrim/CMakeLists.txt8
-rw-r--r--zephyr/test/skyrim/Kconfig38
-rw-r--r--zephyr/test/skyrim/boards/native_posix.overlay73
-rw-r--r--zephyr/test/skyrim/prj.conf2
-rw-r--r--zephyr/test/skyrim/src/common.c7
-rw-r--r--zephyr/test/skyrim/src/common/alt_charger.c55
-rw-r--r--zephyr/test/skyrim/src/common/fan.c92
-rw-r--r--zephyr/test/skyrim/src/common/ppc_config.c58
-rw-r--r--zephyr/test/skyrim/src/crystaldrift/common.c3
-rw-r--r--zephyr/test/skyrim/src/frostflow/usb_mux_config.c60
-rw-r--r--zephyr/test/skyrim/src/markarth/common.c3
-rw-r--r--zephyr/test/skyrim/src/winterhold/ppc_config.c38
-rw-r--r--zephyr/test/skyrim/testcase.yaml57
-rw-r--r--zephyr/test/system_safe_mode/prj.conf1
-rw-r--r--zephyr/test/system_safe_mode/src/system_safe_mode.c18
-rw-r--r--zephyr/test/tasks/CMakeLists.txt5
-rw-r--r--zephyr/test/tasks/extra_tasks.c149
-rw-r--r--zephyr/test/tasks/main.c21
-rw-r--r--zephyr/test/tasks/prj.conf6
-rw-r--r--zephyr/test/tasks/testcase.yaml24
-rw-r--r--zephyr/test/vboot_efs2/boards/native_posix.overlay2
-rw-r--r--zephyr/zmake/bazel_main.py16
-rw-r--r--zephyr/zmake/setup.py1
-rw-r--r--zephyr/zmake/tests/conftest.py1
-rw-r--r--zephyr/zmake/tests/test_build_config.py3
-rw-r--r--zephyr/zmake/tests/test_jobserver.py2
-rw-r--r--zephyr/zmake/tests/test_modules.py1
-rw-r--r--zephyr/zmake/tests/test_packers.py1
-rw-r--r--zephyr/zmake/tests/test_project.py1
-rw-r--r--zephyr/zmake/tests/test_toolchains.py1
-rw-r--r--zephyr/zmake/tests/test_util.py1
-rw-r--r--zephyr/zmake/tests/test_version.py1
-rw-r--r--zephyr/zmake/tests/test_zmake.py3
-rw-r--r--zephyr/zmake/zmake/configlib.py2
-rw-r--r--zephyr/zmake/zmake/multiproc.py1
-rw-r--r--zephyr/zmake/zmake/output_packers.py2
-rw-r--r--zephyr/zmake/zmake/project.py5
-rw-r--r--zephyr/zmake/zmake/zmake.py1
422 files changed, 11911 insertions, 2549 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1dc1cf7ead..38573fd436 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -157,7 +157,7 @@ before_script:
"${MODULES_DIR}/**"
"${EC_DIR}/zephyr/drivers/**" "${EC_DIR}/zephyr/include/drivers/**"
"${EC_DIR}/zephyr/shim/chip/**" "${EC_DIR}/zephyr/shim/core/**"
- "${EC_DIR}/zephyr/program/**" "/usr/include/**"
+ "/usr/include/**"
"${EC_DIR}/build/**" "${EC_DIR}/twister-out*/**"
"${EC_DIR}/test/**"
"${EC_DIR}/zephyr/shim/chip/npcx/npcx_monitor/**"
@@ -172,7 +172,7 @@ before_script:
"${ZEPHYR_BASE}/**" "${MODULES_DIR}/**"
"${EC_DIR}/zephyr/drivers/**" "${EC_DIR}/zephyr/include/drivers/**"
"${EC_DIR}/zephyr/shim/chip/**" "${EC_DIR}/zephyr/shim/core/**"
- "${EC_DIR}/zephyr/program/**" "/usr/include/**"
+ "/usr/include/**"
"${EC_DIR}/build/**" "${EC_DIR}/twister-out*/**"
"${EC_DIR}/zephyr/shim/chip/npcx/npcx_monitor/**"
"${EC_DIR}/test/**"
@@ -283,6 +283,16 @@ rex_coverage:
PROJECT: "rex"
<<: *coverage_template
+geralt:
+ variables:
+ PROJECT: "geralt"
+ <<: *build_template
+
+geralt_coverage:
+ variables:
+ PROJECT: "geralt"
+ <<: *coverage_template
+
ec_coverage:
stage: test
needs: []
diff --git a/.isort.cfg b/.isort.cfg
deleted file mode 100644
index b9fb3f3e8c..0000000000
--- a/.isort.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[settings]
-profile=black
diff --git a/Makefile.toolchain b/Makefile.toolchain
index 12e8440763..a0f4533ffa 100644
--- a/Makefile.toolchain
+++ b/Makefile.toolchain
@@ -113,7 +113,7 @@ else
HOSTGCOV=$(CURDIR)/util/llvm-gcov.sh
endif
-C_WARN = -Wstrict-prototypes -Wdeclaration-after-statement -Wno-pointer-sign
+C_WARN = -Wstrict-prototypes -Wno-pointer-sign
C_WARN += -Werror-implicit-function-declaration
COMMON_WARN += -Wall -Wundef \
-Wno-trigraphs -Wno-format-security -Wno-address-of-packed-member \
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index 1167b45d9e..03a926a92e 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -35,3 +35,4 @@ ec_commands_h = util/linux_ec_commands_h_check.sh
migrated_files = util/migrated_files.sh ${PRESUBMIT_FILES}
twister_test_tags = util/twister_tags.py --validate-files ${PRESUBMIT_FILES}
check_zephyr_project_config = util/check_zephyr_project_config.py -d ${PRESUBMIT_FILES}
+zephyr_check_compliance = util/zephyr_check_compliance.py ${PRESUBMIT_COMMIT}
diff --git a/baseboard/cherry/baseboard.c b/baseboard/cherry/baseboard.c
index 1a4277a2b9..36df319f8c 100644
--- a/baseboard/cherry/baseboard.c
+++ b/baseboard/cherry/baseboard.c
@@ -91,13 +91,17 @@ __override void board_hibernate_late(void)
* Don't care for devices with Z-state.
*/
gpio_set_level(GPIO_EN_PP5000_A, 0);
- isl9238c_hibernate(CHARGER_SOLO);
gpio_set_level(GPIO_EN_SLP_Z, 1);
/* should not reach here */
__builtin_unreachable();
}
+void board_hibernate(void)
+{
+ isl9238c_hibernate(CHARGER_SOLO);
+}
+
static void board_tcpc_init(void)
{
gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
diff --git a/baseboard/dedede/variant_ec_it8320.c b/baseboard/dedede/variant_ec_it8320.c
index 37929ceb0b..5e5590d60c 100644
--- a/baseboard/dedede/variant_ec_it8320.c
+++ b/baseboard/dedede/variant_ec_it8320.c
@@ -73,6 +73,7 @@ const struct vcmp_t vcmp_list[] = {
BUILD_ASSERT(ARRAY_SIZE(vcmp_list) <= CHIP_VCMP_COUNT);
BUILD_ASSERT(ARRAY_SIZE(vcmp_list) == VCMP_COUNT);
+#ifndef BOARD_DIBBI
/* I2C Ports */
const struct i2c_port_t i2c_ports[] = {
{ .name = "eeprom",
@@ -86,6 +87,7 @@ const struct i2c_port_t i2c_ports[] = {
.kbps = 100,
.scl = GPIO_EC_I2C_BATTERY_SCL,
.sda = GPIO_EC_I2C_BATTERY_SDA },
+
#if defined(HAS_TASK_MOTIONSENSE) || defined(BOARD_SHOTZO)
{ .name = "sensor",
.port = I2C_PORT_SENSOR,
@@ -109,3 +111,4 @@ const struct i2c_port_t i2c_ports[] = {
.sda = GPIO_EC_I2C_USB_C0_SDA },
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+#endif
diff --git a/baseboard/trogdor/usb_pd_policy.c b/baseboard/trogdor/usb_pd_policy.c
index 2e064518e0..04a2e78519 100644
--- a/baseboard/trogdor/usb_pd_policy.c
+++ b/baseboard/trogdor/usb_pd_policy.c
@@ -201,32 +201,10 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
*/
gpio_set_level(GPIO_DP_MUX_SEL, port == 1);
gpio_set_level(GPIO_DP_MUX_OE_L, 0);
-
- /* Connect the SBU lines in PPC chip. */
- if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
- ppc_set_sbu(port, 1);
-
- /*
- * Connect the USB SS/DP lines in TCPC chip.
- *
- * When mf_pref not true, still use the dock muxing
- * because of the board USB-C topology (limited to 2
- * lanes DP).
- */
- usb_mux_set(port, USB_PD_MUX_DOCK, USB_SWITCH_CONNECT,
- polarity_rm_dts(pd_get_polarity(port)));
} else {
/* Disconnect the DP port selection mux. */
gpio_set_level(GPIO_DP_MUX_OE_L, 1);
gpio_set_level(GPIO_DP_MUX_SEL, 0);
-
- /* Disconnect the SBU lines in PPC chip. */
- if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
- ppc_set_sbu(port, 0);
-
- /* Disconnect the DP but keep the USB SS lines in TCPC chip. */
- usb_mux_set(port, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT,
- polarity_rm_dts(pd_get_polarity(port)));
}
if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && (irq || lvl))
diff --git a/board/aurash/board.c b/board/aurash/board.c
new file mode 100644
index 0000000000..742cb97ad9
--- /dev/null
+++ b/board/aurash/board.c
@@ -0,0 +1,566 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "adc.h"
+#include "builtin/assert.h"
+#include "button.h"
+#include "charge_manager.h"
+#include "charge_state_v2.h"
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "driver/tcpm/tcpci.h"
+#include "fw_config.h"
+#include "gpio.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "power.h"
+#include "power_button.h"
+#include "switch.h"
+#include "throttle_ap.h"
+#include "usbc_config.h"
+#include "usbc_ppc.h"
+
+/* Console output macros */
+#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ##args)
+#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args)
+
+static void power_monitor(void);
+DECLARE_DEFERRED(power_monitor);
+
+/******************************************************************************/
+/* USB-A charging control */
+
+const int usb_port_enable[USB_PORT_COUNT] = {
+ GPIO_EN_PP5000_USBA,
+};
+BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT);
+
+/******************************************************************************/
+
+int board_set_active_charge_port(int port)
+{
+ CPRINTS("Requested charge port change to %d", port);
+
+ /*
+ * The charge manager may ask us to switch to no charger if we're
+ * running off USB-C only but upstream doesn't support PD. It requires
+ * that we accept this switch otherwise it triggers an assert and EC
+ * reset; it's not possible to boot the AP anyway, but we want to avoid
+ * resetting the EC so we can continue to do the "low power" LED blink.
+ */
+ if (port == CHARGE_PORT_NONE)
+ return EC_SUCCESS;
+
+ if (port < 0 || CHARGE_PORT_COUNT <= port)
+ return EC_ERROR_INVAL;
+
+ if (port == charge_manager_get_active_charge_port())
+ return EC_SUCCESS;
+
+ /* Don't charge from a source port */
+ if (board_vbus_source_enabled(port))
+ return EC_ERROR_INVAL;
+
+ if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ int bj_active, bj_requested;
+
+ if (charge_manager_get_active_charge_port() != CHARGE_PORT_NONE)
+ /* Change is only permitted while the system is off */
+ return EC_ERROR_INVAL;
+
+ /*
+ * Current setting is no charge port but the AP is on, so the
+ * charge manager is out of sync (probably because we're
+ * reinitializing after sysjump). Reject requests that aren't
+ * in sync with our outputs.
+ */
+ bj_active = !gpio_get_level(GPIO_EN_PPVAR_BJ_ADP_L);
+ bj_requested = port == CHARGE_PORT_BARRELJACK;
+ if (bj_active != bj_requested)
+ return EC_ERROR_INVAL;
+ }
+
+ CPRINTS("New charger p%d", port);
+
+ switch (port) {
+ case CHARGE_PORT_TYPEC0:
+ case CHARGE_PORT_TYPEC1:
+ case CHARGE_PORT_TYPEC2:
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1);
+ break;
+ case CHARGE_PORT_BARRELJACK:
+ /* Make sure BJ adapter is sourcing power */
+ if (gpio_get_level(GPIO_BJ_ADP_PRESENT_ODL))
+ return EC_ERROR_INVAL;
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 0);
+ break;
+ default:
+ return EC_ERROR_INVAL;
+ }
+
+ return EC_SUCCESS;
+}
+
+static uint8_t usbc_overcurrent;
+static int32_t base_5v_power_s5;
+static int32_t base_5v_power_z1;
+
+/*
+ * Power usage for each port as measured or estimated.
+ * Units are milliwatts (5v x ma current)
+ */
+
+/* PP5000_S5 loads */
+#define PWR_S5_BASE_LOAD (5 * 1431)
+#define PWR_S5_FRONT_HIGH (5 * 1737)
+#define PWR_S5_FRONT_LOW (5 * 1055)
+#define PWR_S5_REAR_HIGH (5 * 1737)
+#define PWR_S5_REAR_LOW (5 * 1055)
+#define PWR_S5_HDMI (5 * 580)
+#define PWR_S5_MAX (5 * 10000)
+#define FRONT_DELTA (PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW)
+#define REAR_DELTA (PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW)
+
+/* PP5000_Z1 loads */
+#define PWR_Z1_BASE_LOAD (5 * 5)
+#define PWR_Z1_C_HIGH (5 * 3600)
+#define PWR_Z1_C_LOW (5 * 2000)
+#define PWR_Z1_MAX (5 * 9000)
+/*
+ * Update the 5V power usage, assuming no throttling,
+ * and invoke the power monitoring.
+ */
+static void update_5v_usage(void)
+{
+ int front_ports = 0;
+ int rear_ports = 0;
+
+ /*
+ * Recalculate the 5V load, assuming no throttling.
+ */
+ base_5v_power_s5 = PWR_S5_BASE_LOAD;
+ if (!gpio_get_level(GPIO_USB_A0_OC_ODL)) {
+ front_ports++;
+ base_5v_power_s5 += PWR_S5_FRONT_LOW;
+ }
+ if (!gpio_get_level(GPIO_USB_A1_OC_ODL)) {
+ front_ports++;
+ base_5v_power_s5 += PWR_S5_FRONT_LOW;
+ }
+ /*
+ * Only 1 front port can run higher power at a time.
+ */
+ if (front_ports > 0)
+ base_5v_power_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
+
+ if (!gpio_get_level(GPIO_USB_A2_OC_ODL)) {
+ rear_ports++;
+ base_5v_power_s5 += PWR_S5_REAR_LOW;
+ }
+ if (!gpio_get_level(GPIO_USB_A3_OC_ODL)) {
+ rear_ports++;
+ base_5v_power_s5 += PWR_S5_REAR_LOW;
+ }
+ /*
+ * Only 1 rear port can run higher power at a time.
+ */
+ if (rear_ports > 0)
+ base_5v_power_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
+ if (!gpio_get_level(GPIO_HDMI_CONN_OC_ODL))
+ base_5v_power_s5 += PWR_S5_HDMI;
+ base_5v_power_z1 = PWR_Z1_BASE_LOAD;
+ if (usbc_overcurrent)
+ base_5v_power_z1 += PWR_Z1_C_HIGH;
+ /*
+ * Invoke the power handler immediately.
+ */
+ hook_call_deferred(&power_monitor_data, 0);
+}
+DECLARE_DEFERRED(update_5v_usage);
+/*
+ * Start power monitoring after ADCs have been initialised.
+ */
+DECLARE_HOOK(HOOK_INIT, update_5v_usage, HOOK_PRIO_INIT_ADC + 1);
+
+static void port_ocp_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&update_5v_usage_data, 0);
+}
+/* Must come after other header files and interrupt handler declarations */
+#include "gpio_list.h"
+
+/******************************************************************************/
+/*
+ * Barrel jack power supply handling
+ *
+ * EN_PPVAR_BJ_ADP_L must default active to ensure we can power on when the
+ * barrel jack is connected, and the USB-C port can bring the EC up fine in
+ * dead-battery mode. Both the USB-C and barrel jack switches do reverse
+ * protection, so we're safe to turn one on then the other off- but we should
+ * only do that if the system is off since it might still brown out.
+ */
+
+#define ADP_DEBOUNCE_MS 1000 /* Debounce time for BJ plug/unplug */
+/* Debounced connection state of the barrel jack */
+static int8_t adp_connected = -1;
+static void adp_connect_deferred(void)
+{
+ struct charge_port_info pi = { 0 };
+ int connected = !gpio_get_level(GPIO_BJ_ADP_PRESENT_ODL);
+
+ /* Debounce */
+ if (connected == adp_connected)
+ return;
+ if (connected)
+ ec_bj_power(&pi.voltage, &pi.current);
+ charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
+ DEDICATED_CHARGE_PORT, &pi);
+ adp_connected = connected;
+}
+DECLARE_DEFERRED(adp_connect_deferred);
+
+/* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */
+void adp_connect_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC);
+}
+
+static void adp_state_init(void)
+{
+ ASSERT(CHARGE_PORT_ENUM_COUNT == CHARGE_PORT_COUNT);
+ /*
+ * Initialize all charge suppliers to 0. The charge manager waits until
+ * all ports have reported in before doing anything.
+ */
+ for (int i = 0; i < CHARGE_PORT_COUNT; i++) {
+ for (int j = 0; j < CHARGE_SUPPLIER_COUNT; j++)
+ charge_manager_update_charge(j, i, NULL);
+ }
+
+ /* Report charge state from the barrel jack. */
+ adp_connect_deferred();
+}
+DECLARE_HOOK(HOOK_INIT, adp_state_init, HOOK_PRIO_INIT_CHARGE_MANAGER + 1);
+
+static void board_init(void)
+{
+ gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_ODL);
+ gpio_enable_interrupt(GPIO_HDMI_CONN_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A0_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A1_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A2_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A3_OC_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+
+void board_overcurrent_event(int port, int is_overcurrented)
+{
+ /* Check that port number is valid. */
+ if ((port < 0) || (port >= CONFIG_USB_PD_PORT_MAX_COUNT))
+ return;
+ usbc_overcurrent = is_overcurrented;
+ update_5v_usage();
+}
+/*
+ * Power monitoring and management.
+ *
+ * the power budgets are met without letting the system fall into
+ * power deficit (perhaps causing a brownout).
+ *
+ * There are 2 power budgets that need to be managed:
+ * The overall goal is to gracefully manage the power demand so that
+ * - overall system power as measured on the main power supply rail.
+ * - 5V power delivered to the USB and HDMI ports.
+ *
+ * The actual system power demand is calculated from the VBUS voltage and
+ * the input current (read from a shunt), averaged over 5 readings.
+ * The power budget limit is from the charge manager.
+ *
+ * The 5V power cannot be read directly. Instead, we rely on overcurrent
+ * inputs from the USB and HDMI ports to indicate that the port is in use
+ * (and drawing maximum power).
+ *
+ * There are 3 throttles that can be applied (in priority order):
+ *
+ * - Type A BC1.2 front port restriction (3W)
+ * - Type A BC1.2 rear port restriction (3W)
+ * - Type C PD (throttle to 1.5A if sourcing)
+ * - Turn on PROCHOT, which immediately throttles the CPU.
+ *
+ * The first 3 throttles affect both the system power and the 5V rails.
+ * The third is a last resort to force an immediate CPU throttle to
+ * reduce the overall power use.
+ *
+ * The strategy is to determine what the state of the throttles should be,
+ * and to then turn throttles off or on as needed to match this.
+ *
+ * This function runs on demand, or every 2 ms when the CPU is up,
+ * and continually monitors the power usage, applying the
+ * throttles when necessary.
+ *
+ * All measurements are in milliwatts.
+ */
+#define THROT_TYPE_A_FRONT BIT(0)
+#define THROT_TYPE_A_REAR BIT(1)
+#define THROT_TYPE_C0 BIT(2)
+#define THROT_TYPE_C1 BIT(3)
+#define THROT_TYPE_C2 BIT(4)
+#define THROT_PROCHOT BIT(5)
+
+/*
+ * Power gain if front USB A ports are limited.
+ */
+#define POWER_GAIN_TYPE_A 3200
+/*
+ * Power gain if Type C port is limited.
+ */
+#define POWER_GAIN_TYPE_C 8800
+/*
+ * Power is averaged over 10 ms, with a reading every 2 ms.
+ */
+#define POWER_DELAY_MS 2
+#define POWER_READINGS (10 / POWER_DELAY_MS)
+
+static void power_monitor(void)
+{
+ static uint32_t current_state;
+ static uint32_t history[POWER_READINGS];
+ static uint8_t index;
+ int32_t delay;
+ uint32_t new_state = 0, diff;
+ int32_t headroom_5v_s5 = PWR_S5_MAX - base_5v_power_s5;
+ int32_t headroom_5v_z1 = PWR_Z1_MAX - base_5v_power_z1;
+
+ /*
+ * If CPU is off or suspended, no need to throttle
+ * or restrict power.
+ */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF | CHIPSET_STATE_SUSPEND)) {
+ /*
+ * Slow down monitoring, assume no throttling required.
+ */
+ delay = 20 * MSEC;
+ /*
+ * Clear the first entry of the power table so that
+ * it is re-initilalised when the CPU starts.
+ */
+ history[0] = 0;
+ } else {
+ int32_t charger_mw;
+
+ delay = POWER_DELAY_MS * MSEC;
+ /*
+ * Get current charger limit (in mw).
+ * If not configured yet, skip.
+ */
+ charger_mw = charge_manager_get_power_limit_uw() / 1000;
+ if (charger_mw != 0) {
+ int32_t gap, total, max, power;
+ int i;
+
+ /*
+ * Read power usage.
+ */
+ power = (adc_read_channel(ADC_VBUS) *
+ adc_read_channel(ADC_PPVAR_IMON)) /
+ 1000;
+ /* Init power table */
+ if (history[0] == 0) {
+ for (i = 0; i < POWER_READINGS; i++)
+ history[i] = power;
+ }
+ /*
+ * Update the power readings and
+ * calculate the average and max.
+ */
+ history[index] = power;
+ index = (index + 1) % POWER_READINGS;
+ total = 0;
+ max = history[0];
+ for (i = 0; i < POWER_READINGS; i++) {
+ total += history[i];
+ if (history[i] > max)
+ max = history[i];
+ }
+ /*
+ * For Type-C power supplies, there is
+ * less tolerance for exceeding the rating,
+ * so use the max power that has been measured
+ * over the measuring period.
+ * For barrel-jack supplies, the rating can be
+ * exceeded briefly, so use the average.
+ */
+ if (charge_manager_get_supplier() == CHARGE_SUPPLIER_PD)
+ power = max;
+ else
+ power = total / POWER_READINGS;
+ /*
+ * Calculate gap, and if negative, power
+ * demand is exceeding configured power budget, so
+ * throttling is required to reduce the demand.
+ */
+ gap = charger_mw - power;
+ /*
+ * Limiting type-A power rear ports.
+ */
+ if (gap <= 0) {
+ new_state |= THROT_TYPE_A_REAR;
+ headroom_5v_s5 += REAR_DELTA;
+ if (!(current_state & THROT_TYPE_A_REAR))
+ gap += POWER_GAIN_TYPE_A;
+ }
+ /*
+ * Limiting type-A power front ports.
+ */
+ if (gap <= 0) {
+ new_state |= THROT_TYPE_A_FRONT;
+ headroom_5v_s5 += FRONT_DELTA;
+ if (!(current_state & THROT_TYPE_A_REAR))
+ gap += POWER_GAIN_TYPE_A;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(0) && gap <= 0) {
+ new_state |= THROT_TYPE_C0;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C0))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(1) && gap <= 0) {
+ new_state |= THROT_TYPE_C1;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C1))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(2) && gap <= 0) {
+ new_state |= THROT_TYPE_C2;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C2))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * As a last resort, turn on PROCHOT to
+ * throttle the CPU.
+ */
+ if (gap <= 0)
+ new_state |= THROT_PROCHOT;
+ }
+ }
+ /*
+ * Check the 5v power usage and if necessary,
+ * adjust the throttles in priority order.
+ *
+ * Either throttle may have already been activated by
+ * the overall power control.
+ *
+ * We rely on the overcurrent detection to inform us
+ * if the port is in use.
+ *
+ * - If type C not already throttled:
+ * * If not overcurrent, prefer to limit type C [1].
+ * * If in overcurrentuse:
+ * - limit type A first [2]
+ * - If necessary, limit type C [3].
+ * - If type A not throttled, if necessary limit it [2].
+ */
+ if (headroom_5v_z1 < 0) {
+ /*
+ * Check whether type C is not throttled,
+ * and is not overcurrent.
+ */
+ if (!((new_state & THROT_TYPE_C0) || usbc_overcurrent)) {
+ /*
+ * [1] Type C not in overcurrent, throttle it.
+ */
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ new_state |= THROT_TYPE_C0;
+ }
+ /*
+ * [2] If still under-budget, limit type C.
+ * No need to check if it is already throttled or not.
+ */
+ if (headroom_5v_z1 < 0)
+ new_state |= THROT_TYPE_C0;
+ }
+ if (headroom_5v_s5 < 0) {
+ /*
+ * [1] If type A rear not already throttled, and power still
+ * needed, limit type A rear.
+ */
+ if (!(new_state & THROT_TYPE_A_REAR) && headroom_5v_s5 < 0) {
+ headroom_5v_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
+ new_state |= THROT_TYPE_A_REAR;
+ }
+ /*
+ * [2] If type A front not already throttled, and power still
+ * needed, limit type A front.
+ */
+ if (!(new_state & THROT_TYPE_A_FRONT) && headroom_5v_s5 < 0) {
+ headroom_5v_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
+ new_state |= THROT_TYPE_A_FRONT;
+ }
+ }
+ /*
+ * Turn the throttles on or off if they have changed.
+ */
+ diff = new_state ^ current_state;
+ current_state = new_state;
+ if (diff & THROT_PROCHOT) {
+ int prochot = (new_state & THROT_PROCHOT) ? 0 : 1;
+
+ gpio_set_level(GPIO_EC_PROCHOT_ODL, prochot);
+ }
+ if (diff & THROT_TYPE_C0) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C0) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(0, rp);
+ tcpm_select_rp_value(0, rp);
+ pd_update_contract(0);
+ }
+ if (diff & THROT_TYPE_C1) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C1) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(1, rp);
+ tcpm_select_rp_value(1, rp);
+ pd_update_contract(1);
+ }
+ if (diff & THROT_TYPE_C2) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C2) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(2, rp);
+ tcpm_select_rp_value(2, rp);
+ pd_update_contract(2);
+ }
+ if (diff & THROT_TYPE_A_REAR) {
+ int typea_bc = (new_state & THROT_TYPE_A_REAR) ? 1 : 0;
+
+ gpio_set_level(GPIO_USB_A_LOW_PWR0_OD, typea_bc);
+ gpio_set_level(GPIO_USB_A_LOW_PWR1_OD, typea_bc);
+ }
+ if (diff & THROT_TYPE_A_FRONT) {
+ int typea_bc = (new_state & THROT_TYPE_A_FRONT) ? 1 : 0;
+
+ gpio_set_level(GPIO_USB_A_LOW_PWR2_OD, typea_bc);
+ gpio_set_level(GPIO_USB_A_LOW_PWR3_OD, typea_bc);
+ }
+ hook_call_deferred(&power_monitor_data, delay);
+}
diff --git a/board/aurash/board.h b/board/aurash/board.h
new file mode 100644
index 0000000000..3aa49a6189
--- /dev/null
+++ b/board/aurash/board.h
@@ -0,0 +1,198 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Brask board configuration */
+
+#ifndef __CROS_EC_BOARD_H
+#define __CROS_EC_BOARD_H
+
+#include "compile_time_macros.h"
+
+/* Baseboard features */
+#include "baseboard.h"
+
+#define CONFIG_MP2964
+
+/* Barrel Jack */
+#define DEDICATED_CHARGE_PORT 3
+
+/* HDMI CEC */
+#define CONFIG_CEC
+#define CEC_GPIO_OUT GPIO_HDMI_CEC_OUT
+#define CEC_GPIO_IN GPIO_HDMI_CEC_IN
+#define CEC_GPIO_PULL_UP GPIO_HDMI_CEC_PULL_UP
+
+/* USB Type A Features */
+#define USB_PORT_COUNT 4
+#define CONFIG_USB_PORT_POWER_DUMB
+
+/* USB Type C and USB PD defines */
+#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY
+
+#define CONFIG_IO_EXPANDER
+#define CONFIG_IO_EXPANDER_NCT38XX
+#define CONFIG_IO_EXPANDER_PORT_COUNT 2
+
+#define CONFIG_USB_PD_PPC
+#define CONFIG_USB_PD_TCPM_RT1715
+#define CONFIG_USBC_RETIMER_INTEL_BB
+
+#define CONFIG_USBC_RETIMER_KB800X
+#define CONFIG_KB800X_CUSTOM_XBAR
+#define CONFIG_USBC_PPC_SYV682X
+#undef CONFIG_SYV682X_HV_ILIM
+#define CONFIG_SYV682X_HV_ILIM SYV682X_HV_ILIM_5_50
+
+/* TODO: b/177608416 - measure and check these values on brya */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 30000 /* us */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
+/* The design should support up to 100W. */
+/* TODO(b/197702356): Set the max PD to 60W now and change it
+ * to 100W after we verify it.
+ */
+#define PD_OPERATING_POWER_MW CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON
+#define PD_MAX_POWER_MW 100000
+#define PD_MAX_CURRENT_MA 5000
+#define PD_MAX_VOLTAGE_MV 20000
+
+/*
+ * Macros for GPIO signals used in common code that don't match the
+ * schematic names. Signal names in gpio.inc match the schematic and are
+ * then redefined here to so it's more clear which signal is being used for
+ * which purpose.
+ */
+#define GPIO_AC_PRESENT GPIO_ACOK_OD
+#define GPIO_CPU_PROCHOT GPIO_EC_PROCHOT_ODL
+#define GPIO_EC_INT_L GPIO_EC_PCH_INT_ODL
+#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW
+#define GPIO_PACKET_MODE_EN GPIO_EC_GSC_PACKET_MODE
+#define GPIO_PCH_PWRBTN_L GPIO_EC_PCH_PWR_BTN_ODL
+#define GPIO_PCH_RSMRST_L GPIO_EC_PCH_RSMRST_L
+#define GPIO_PCH_RTCRST GPIO_EC_PCH_RTCRST
+#define GPIO_PCH_SLP_S0_L GPIO_SYS_SLP_S0IX_L
+#define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L
+#define GPIO_TEMP_SENSOR_POWER GPIO_SEQ_EC_DSW_PWROK
+
+/*
+ * GPIO_EC_PCH_INT_ODL is used for MKBP events as well as a PCH wakeup
+ * signal.
+ */
+#define GPIO_PCH_WAKE_L GPIO_EC_PCH_INT_ODL
+#define GPIO_PG_EC_ALL_SYS_PWRGD GPIO_SEQ_EC_ALL_SYS_PG
+#define GPIO_PG_EC_DSW_PWROK GPIO_SEQ_EC_DSW_PWROK
+#define GPIO_PG_EC_RSMRST_ODL GPIO_SEQ_EC_RSMRST_ODL
+#define GPIO_POWER_BUTTON_L GPIO_GSC_EC_PWR_BTN_ODL
+#define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL
+#define GPIO_WP_L GPIO_EC_WP_ODL
+#define GPIO_RECOVERY_L GPIO_EC_RECOVERY_BTN_OD
+#define GPIO_RECOVERY_L_2 GPIO_GSC_EC_RECOVERY_BTN_OD
+
+/* I2C Bus Configuration */
+
+#define I2C_PORT_DP_REDRIVER NPCX_I2C_PORT0_0
+
+#define I2C_PORT_USB_C0_C2_TCPC NPCX_I2C_PORT1_0
+#define I2C_PORT_USB_C1_TCPC NPCX_I2C_PORT4_1
+
+#define I2C_PORT_USB_C0_C2_PPC NPCX_I2C_PORT2_0
+#define I2C_PORT_USB_C1_PPC NPCX_I2C_PORT6_1
+
+#define I2C_PORT_USB_C0_C2_BC12 NPCX_I2C_PORT2_0
+#define I2C_PORT_USB_C1_BC12 NPCX_I2C_PORT6_1
+
+#define I2C_PORT_USB_C0_C2_MUX NPCX_I2C_PORT3_0
+#define I2C_PORT_USB_C1_MUX NPCX_I2C_PORT6_1
+
+#define I2C_PORT_QI NPCX_I2C_PORT5_0
+#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0
+#define I2C_PORT_MP2964 NPCX_I2C_PORT7_0
+
+#define I2C_ADDR_EEPROM_FLAGS 0x50
+
+#define I2C_ADDR_MP2964_FLAGS 0x20
+
+#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x58
+#define USBC_PORT_C2_BB_RETIMER_I2C_ADDR 0x59
+
+/* Enabling Thunderbolt-compatible mode */
+#define CONFIG_USB_PD_TBT_COMPAT_MODE
+
+/* Enabling USB4 mode */
+#define CONFIG_USB_PD_USB4
+#define CONFIG_USB_PD_DATA_RESET_MSG
+
+/* Retimer */
+#define CONFIG_USBC_RETIMER_FW_UPDATE
+
+/* Thermal features */
+#define CONFIG_THERMISTOR
+#define CONFIG_TEMP_SENSOR
+#define CONFIG_TEMP_SENSOR_POWER
+#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B
+
+/* ADC */
+#define CONFIG_ADC
+
+/*
+ * TODO(b/197478860): Enable the fan control. We need
+ * to check the sensor value and adjust the fan speed.
+ */
+#define CONFIG_FANS FAN_CH_COUNT
+
+/* Include math_util for bitmask_uint64 used in pd_timers */
+#define CONFIG_MATH_UTIL
+
+#ifndef __ASSEMBLER__
+
+#include "gpio_signal.h" /* needed by registers.h */
+#include "registers.h"
+#include "usbc_config.h"
+
+enum charge_port {
+ CHARGE_PORT_TYPEC0,
+ CHARGE_PORT_TYPEC1,
+ CHARGE_PORT_TYPEC2,
+ CHARGE_PORT_BARRELJACK,
+ CHARGE_PORT_ENUM_COUNT
+};
+
+enum adc_channel {
+ ADC_TEMP_SENSOR_1_CPU,
+ ADC_TEMP_SENSOR_2_CPU_VR,
+ ADC_TEMP_SENSOR_3_WIFI,
+ ADC_TEMP_SENSOR_4_DIMM,
+ ADC_VBUS,
+ ADC_PPVAR_IMON, /* ADC3 */
+ ADC_CH_COUNT
+};
+
+enum temp_sensor_id {
+ TEMP_SENSOR_1_CPU,
+ TEMP_SENSOR_2_CPU_VR,
+ TEMP_SENSOR_3_WIFI,
+ TEMP_SENSOR_4_DIMM,
+ TEMP_SENSOR_COUNT
+};
+
+enum ioex_port { IOEX_C0_NCT38XX = 0, IOEX_C2_NCT38XX, IOEX_PORT_COUNT };
+
+enum pwm_channel {
+ PWM_CH_LED_GREEN, /* PWM0 */
+ PWM_CH_FAN, /* PWM5 */
+ PWM_CH_LED_RED, /* PWM2 */
+ PWM_CH_COUNT
+};
+
+enum fan_channel { FAN_CH_0 = 0, FAN_CH_COUNT };
+
+enum mft_channel { MFT_CH_0 = 0, MFT_CH_COUNT };
+
+extern void adp_connect_interrupt(enum gpio_signal signal);
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* __CROS_EC_BOARD_H */
diff --git a/board/aurash/build.mk b/board/aurash/build.mk
new file mode 100644
index 0000000000..2301983a1f
--- /dev/null
+++ b/board/aurash/build.mk
@@ -0,0 +1,22 @@
+# -*- makefile -*-
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Brask board specific files build
+#
+
+CHIP:=npcx
+CHIP_FAMILY:=npcx9
+CHIP_VARIANT:=npcx9m3f
+BASEBOARD:=brask
+
+board-y=
+board-y+=board.o
+board-y+=fans.o
+board-y+=fw_config.o
+board-y+=i2c.o
+board-y+=led.o
+board-y+=pwm.o
+board-y+=sensors.o
+board-y+=usbc_config.o
diff --git a/board/aurash/ec.tasklist b/board/aurash/ec.tasklist
new file mode 100644
index 0000000000..2d063fe252
--- /dev/null
+++ b/board/aurash/ec.tasklist
@@ -0,0 +1,28 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * See CONFIG_TASK_LIST in config.h for details.
+ *
+ * USB_CHG_Px tasks must be contiguous (see USB_CHG_PORT_TO_TASK_ID(x)).
+ * PD_Cx tasks must be contiguous (see PD_PORT_TO_TASK_ID(x))
+ */
+
+#define CONFIG_TASK_LIST \
+ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P2, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_MUX, usb_mux_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(POWERBTN, power_button_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C2, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_INT_C0, pd_shared_alert_task, (BIT(2) | BIT(0)), LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CEC, cec_task, NULL, LARGER_TASK_STACK_SIZE)
diff --git a/board/aurash/fans.c b/board/aurash/fans.c
new file mode 100644
index 0000000000..ecc93bd330
--- /dev/null
+++ b/board/aurash/fans.c
@@ -0,0 +1,50 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Physical fans. These are logically separate from pwm_channels. */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "fan.h"
+#include "fan_chip.h"
+#include "hooks.h"
+#include "pwm.h"
+
+/* MFT channels. These are logically separate from pwm_channels. */
+const struct mft_t mft_channels[] = {
+ [MFT_CH_0] = {
+ .module = NPCX_MFT_MODULE_2,
+ .clk_src = TCKC_LFCLK,
+ .pwm_id = PWM_CH_FAN,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT);
+
+static const struct fan_conf fan_conf_0 = {
+ .flags = FAN_USE_RPM_MODE,
+ .ch = MFT_CH_0, /* Use MFT id to control fan */
+ .pgood_gpio = -1,
+ .enable_gpio = GPIO_EN_PP5000_FAN,
+};
+
+/*
+ * TOOD(b/197478860): need to update for real fan
+ *
+ * Prototype fan spins at about 7200 RPM at 100% PWM.
+ * Set minimum at around 30% PWM.
+ */
+static const struct fan_rpm fan_rpm_0 = {
+ .rpm_min = 2200,
+ .rpm_start = 2200,
+ .rpm_max = 7200,
+};
+
+const struct fan_t fans[FAN_CH_COUNT] = {
+ [FAN_CH_0] = {
+ .conf = &fan_conf_0,
+ .rpm = &fan_rpm_0,
+ },
+};
diff --git a/board/aurash/fw_config.c b/board/aurash/fw_config.c
new file mode 100644
index 0000000000..957a5c8c50
--- /dev/null
+++ b/board/aurash/fw_config.c
@@ -0,0 +1,65 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "cbi.h"
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "fw_config.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args)
+
+static union brask_cbi_fw_config fw_config;
+BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t));
+
+/*
+ * FW_CONFIG defaults for brask if the CBI.FW_CONFIG data is not
+ * initialized.
+ */
+static const union brask_cbi_fw_config fw_config_defaults = {
+ .audio = DB_NAU88L25B_I2S,
+ .bj_power = BJ_135W,
+};
+
+/*
+ * Barrel-jack power adapter ratings.
+ */
+static const struct {
+ int voltage;
+ int current;
+} bj_power[] = {
+ [BJ_135W] = { /* 0 - 135W (also default) */
+ .voltage = 19500,
+ .current = 6920
+ },
+ [BJ_230W] = { /* 1 - 230W */
+ .voltage = 19500,
+ .current = 11800
+ }
+};
+
+/****************************************************************************
+ * Brask FW_CONFIG access
+ */
+void board_init_fw_config(void)
+{
+ if (cbi_get_fw_config(&fw_config.raw_value)) {
+ CPRINTS("CBI: Read FW_CONFIG failed, using board defaults");
+ fw_config = fw_config_defaults;
+ }
+}
+
+void ec_bj_power(uint32_t *voltage, uint32_t *current)
+{
+ unsigned int bj;
+
+ bj = fw_config.bj_power;
+ /* Out of range value defaults to 0 */
+ if (bj >= ARRAY_SIZE(bj_power))
+ bj = 0;
+ *voltage = bj_power[bj].voltage;
+ *current = bj_power[bj].current;
+}
diff --git a/board/aurash/fw_config.h b/board/aurash/fw_config.h
new file mode 100644
index 0000000000..c2afd4c603
--- /dev/null
+++ b/board/aurash/fw_config.h
@@ -0,0 +1,41 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __BOARD_BRASK_FW_CONFIG_H_
+#define __BOARD_BRASK_FW_CONFIG_H_
+
+#include <stdint.h>
+
+/****************************************************************************
+ * CBI FW_CONFIG layout for Brask board.
+ *
+ * Source of truth is the project/brask/brask/config.star configuration file.
+ */
+enum ec_cfg_audio_type { DB_AUDIO_UNKNOWN = 0, DB_NAU88L25B_I2S = 1 };
+
+enum ec_cfg_bj_power { BJ_135W = 0, BJ_230W = 1 };
+
+union brask_cbi_fw_config {
+ struct {
+ uint32_t audio : 3;
+ uint32_t bj_power : 2;
+ uint32_t reserved_1 : 27;
+ };
+ uint32_t raw_value;
+};
+
+/**
+ * Read the cached FW_CONFIG. Guaranteed to have valid values.
+ *
+ * @return the FW_CONFIG for the board.
+ */
+union brask_cbi_fw_config get_fw_config(void);
+
+/**
+ * Get the barrel-jack power from FW_CONFIG.
+ */
+void ec_bj_power(uint32_t *voltage, uint32_t *current);
+
+#endif /* __BOARD_BRASK_FW_CONFIG_H_ */
diff --git a/board/aurash/gpio.inc b/board/aurash/gpio.inc
new file mode 100644
index 0000000000..9a5b431848
--- /dev/null
+++ b/board/aurash/gpio.inc
@@ -0,0 +1,182 @@
+/* -*- mode:c -*-
+ *
+ * Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* INTERRUPT GPIOs: */
+
+GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH, extpower_interrupt)
+GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt)
+GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt)
+GPIO_INT(GSC_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH, power_button_interrupt)
+GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SEQ_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SLP_SUS_L, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SYS_SLP_S0IX_L, PIN(D, 5), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(USB_C0_BC12_INT_ODL, PIN(C, 6), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C0_C2_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, tcpc_alert_event)
+GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C0_RT_INT_ODL, PIN(B, 1), GPIO_INT_FALLING, retimer_interrupt)
+GPIO_INT(USB_C1_BC12_INT_ODL, PIN(5, 0), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C1_PPC_INT_ODL, PIN(F, 5), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert_event)
+GPIO_INT(USB_C2_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C2_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C2_RT_INT_ODL, PIN(4, 1), GPIO_INT_FALLING, retimer_interrupt)
+GPIO_INT(BJ_ADP_PRESENT_ODL, PIN(8, 2), GPIO_INT_BOTH | GPIO_PULL_UP, adp_connect_interrupt)
+GPIO_INT(EC_RECOVERY_BTN_OD, PIN(2, 3), GPIO_INT_BOTH, button_interrupt)
+GPIO_INT(HDMI_CONN_OC_ODL, PIN(2, 4), GPIO_INPUT | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A0_OC_ODL, PIN(3, 1), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A1_OC_ODL, PIN(3, 0), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A2_OC_ODL, PIN(2, 7), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A3_OC_ODL, PIN(2, 6), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+
+/* CCD */
+GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT)
+
+/* Security */
+GPIO(EC_ENTERING_RW, PIN(0, 3), GPIO_OUT_LOW)
+GPIO(EC_GSC_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW)
+
+/* Fan */
+GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH)
+
+/* ADC, need to check the usage */
+GPIO(ANALOG_PPVAR_PWR_IN_IMON_EC, PIN(4, 2), GPIO_INPUT)
+
+/* Display */
+GPIO(DP_CONN_OC_ODL, PIN(2, 5), GPIO_INPUT)
+
+
+/* BarrelJack */
+GPIO(EN_PPVAR_BJ_ADP_L, PIN(0, 7), GPIO_OUT_LOW)
+
+/* Chipset PCH */
+GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT)
+GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH)
+GPIO(EC_PCH_RSMRST_L, PIN(A, 6), GPIO_OUT_LOW)
+GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW)
+GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW)
+GPIO(EC_PCH_WAKE_ODL, PIN(C, 0), GPIO_ODR_HIGH)
+GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH)
+GPIO(EN_S5_RAILS, PIN(B, 6), GPIO_OUT_LOW)
+GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW)
+GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
+GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW)
+GPIO(IMVP9_VRRDY_OD, PIN(6, 0), GPIO_INPUT)
+GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT)
+
+/* Button */
+GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH)
+GPIO(GSC_EC_RECOVERY_BTN_OD, PIN(2, 2), GPIO_INPUT)
+
+/* NFC */
+/* TODO(b/194068530): Enable NFC */
+GPIO(NFC_COIL_ACT_L, PIN(D, 4), GPIO_INPUT)
+GPIO(NFC_LOW_POWER_MODE, PIN(9, 5), GPIO_OUT_HIGH)
+GPIO(NFC_CARD_DET_L, PIN(A, 3), GPIO_INPUT)
+GPIO(EN_NFC_BUZZER, PIN(0, 5), GPIO_OUT_LOW)
+
+/* Wireless Charger */
+GPIO(EC_QI_PWR, PIN(D, 2), GPIO_OUT_LOW)
+GPIO(QI_RESET_L, PIN(9, 3), GPIO_OUT_HIGH)
+
+/* HDMI CEC */
+/* TODO(b/197474873): Enable HDMI CEC */
+GPIO(HDMI_CEC_IN, PIN(4, 0), GPIO_INPUT)
+GPIO(HDMI_CEC_OUT, PIN(D, 3), GPIO_OUT_HIGH | GPIO_OPEN_DRAIN)
+GPIO(HDMI_CEC_PULL_UP, PIN(C, 2), GPIO_OUT_HIGH)
+
+/* I2C SCL/SDA */
+GPIO(EC_I2C_QI_SCL, PIN(3, 3), GPIO_INPUT)
+GPIO(EC_I2C_QI_SDA, PIN(3, 6), GPIO_INPUT)
+GPIO(EC_I2C_MISC_SCL_R, PIN(B, 3), GPIO_INPUT)
+GPIO(EC_I2C_MISC_SDA_R, PIN(B, 2), GPIO_INPUT)
+GPIO(EC_I2C_DP_SCL, PIN(B, 5), GPIO_INPUT)
+GPIO(EC_I2C_DP_SDA, PIN(B, 4), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_PPC_SCL, PIN(9, 2), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_PPC_SDA, PIN(9, 1), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_RT_SCL, PIN(D, 1), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_RT_SDA, PIN(D, 0), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_TCPC_SCL, PIN(9, 0), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_TCPC_SDA, PIN(8, 7), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_MIX_SCL, PIN(E, 4), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_MIX_SDA, PIN(E, 3), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_TCPC_SCL, PIN(F, 3), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_TCPC_SDA, PIN(F, 2), GPIO_INPUT)
+
+/* USBA */
+GPIO(EN_PP5000_USBA, PIN(D, 7), GPIO_OUT_LOW)
+GPIO(USB_A0_STATUS_L, PIN(2, 1), GPIO_INPUT)
+GPIO(USB_A1_STATUS_L, PIN(2, 0), GPIO_INPUT)
+GPIO(USB_A2_STATUS_L, PIN(1, 7), GPIO_INPUT)
+GPIO(USB_A3_STATUS_L, PIN(1, 6), GPIO_INPUT)
+GPIO(USB_A_LOW_PWR0_OD, PIN(1, 5), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR1_OD, PIN(1, 4), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR2_OD, PIN(1, 1), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR3_OD, PIN(1, 0), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_OC_SOC_L, PIN(8, 0), GPIO_OUT_HIGH)
+
+/* LED */
+/* TODO(b/197471359): LED implementation */
+GPIO(LED_GREEN_L, PIN(C, 3), GPIO_OUT_LOW)
+GPIO(LED_RED_L, PIN(C, 4), GPIO_OUT_LOW)
+
+/* USBC */
+GPIO(USB_C0_C2_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
+GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW)
+GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT)
+GPIO(USB_C1_RT_RST_R_L, PIN(0, 2), GPIO_OUT_LOW)
+
+/* GPIO02_P2 to PU */
+/* GPIO03_P2 to PU */
+IOEX(USB_C0_OC_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 4), GPIO_ODR_HIGH)
+IOEX(USB_C0_FRS_EN, EXPIN(IOEX_C0_NCT38XX, 0, 6), GPIO_LOW)
+IOEX(USB_C0_RT_RST_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 7), GPIO_ODR_LOW)
+
+IOEX(USB_C2_RT_RST_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 2), GPIO_ODR_LOW)
+IOEX(USB_C1_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 3), GPIO_ODR_HIGH)
+IOEX(USB_C2_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 4), GPIO_ODR_HIGH)
+IOEX(USB_C2_FRS_EN, EXPIN(IOEX_C2_NCT38XX, 0, 6), GPIO_LOW)
+/* GPIO07_P2 to PU */
+
+/* UART alternate functions */
+ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* GPIO64/CR_SIN1, GPO65/CR_SOUT1/FLPRG1_L */
+
+/* I2C alternate functions */
+ALTERNATE(PIN_MASK(3, 0x48), 0, MODULE_I2C, 0) /* GPIO33/I2C5_SCL0/CTS_L, GPIO36/RTS_L/I2C5_SDA0 */
+ALTERNATE(PIN_MASK(8, 0x80), 0, MODULE_I2C, 0) /* GPIO87/I2C1_SDA0 */
+ALTERNATE(PIN_MASK(9, 0x07), 0, MODULE_I2C, 0) /* GPIO92/I2C2_SCL0, GPIO91/I2C2_SDA0, GPIO90/I2C1_SCL0 */
+ALTERNATE(PIN_MASK(B, 0x0c), 0, MODULE_I2C, 0) /* GPIOB3/I2C7_SCL0/DCD_L, GPIOB2/I2C7_SDA0/DSR_L */
+ALTERNATE(PIN_MASK(B, 0x30), 0, MODULE_I2C, 0) /* GPIOB5/I2C0_SCL0, GPIOB4/I2C0_SDA0 */
+ALTERNATE(PIN_MASK(D, 0x03), 0, MODULE_I2C, 0) /* GPIOD1/I2C3_SCL0, GPIOD0/I2C3_SDA0 */
+ALTERNATE(PIN_MASK(E, 0x18), 0, MODULE_I2C, 0) /* GPIOE4/I2C6_SCL1/I3C_SCL, GPIOE3/I2C6_SDA1/I3C_SDA */
+ALTERNATE(PIN_MASK(F, 0x0c), 0, MODULE_I2C, 0) /* GPIOF3/I2C4_SCL1, GPIOF2/I2C4_SDA1 */
+
+/* PWM alternate functions */
+ALTERNATE(PIN_MASK(7, 0x08), 0, MODULE_PWM, 0) /* GPIO73/TA2 */
+ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */
+ALTERNATE(PIN_MASK(C, 0x18), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0 */
+
+/* ADC alternate functions */
+ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */
+ALTERNATE(PIN_MASK(4, 0x38), 0, MODULE_ADC, 0) /* GPIO45/ADC0, GPIO44/ADC1, GPIO43/ADC2 */
+ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */
+
+/* Unused Pins */
+UNUSED(PIN(D, 6)) /* GPOD6/CR_SOUT3/SHDF_ESPI_L */
+UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */
+UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */
+UNUSED(PIN(6, 6)) /* GPIO66 */
+UNUSED(PIN(8, 1)) /* GPIO81/PECI_DATA */
+UNUSED(PIN(5, 6)) /* GPIO56/CLKRUN# */
+UNUSED(PIN(9, 7)) /* GPIO97 */
+UNUSED(PIN(8, 6)) /* GPIO86/TXD/CR_SOUT2 */
+UNUSED(PIN(1, 3)) /* KSO06/GPO13/GP_SEL# */
+UNUSED(PIN(1, 2)) /* KSO07/GPO12/JEN# */
+UNUSED(PIN(0, 6)) /* KSO11/GPIO06/P80_CLK */
+UNUSED(PIN(0, 4)) /* KSO13/GPIO04 */
diff --git a/board/aurash/i2c.c b/board/aurash/i2c.c
new file mode 100644
index 0000000000..a637f03717
--- /dev/null
+++ b/board/aurash/i2c.c
@@ -0,0 +1,77 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "i2c.h"
+
+/* I2C port map configuration */
+const struct i2c_port_t i2c_ports[] = {
+ {
+ /* I2C0 */
+ .name = "dp_redriver",
+ .port = I2C_PORT_DP_REDRIVER,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_DP_SCL,
+ .sda = GPIO_EC_I2C_DP_SDA,
+ },
+ {
+ /* I2C1 */
+ .name = "tcpc0,2",
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_TCPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_TCPC_SDA,
+ },
+ {
+ /* I2C2 */
+ .name = "ppc0,2",
+ .port = I2C_PORT_USB_C0_C2_PPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_PPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_PPC_SDA,
+ },
+ {
+ /* I2C3 */
+ .name = "retimer0,2",
+ .port = I2C_PORT_USB_C0_C2_MUX,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_RT_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_RT_SDA,
+ },
+ {
+ /* I2C4 C1 TCPC */
+ .name = "tcpc1",
+ .port = I2C_PORT_USB_C1_TCPC,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA,
+ },
+ {
+ /* I2C5 */
+ .name = "wireless_charger",
+ .port = I2C_PORT_QI,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_QI_SCL,
+ .sda = GPIO_EC_I2C_QI_SDA,
+ },
+ {
+ /* I2C6 */
+ .name = "ppc1",
+ .port = I2C_PORT_USB_C1_PPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C1_MIX_SCL,
+ .sda = GPIO_EC_I2C_USB_C1_MIX_SDA,
+ },
+ {
+ /* I2C7 */
+ .name = "eeprom",
+ .port = I2C_PORT_EEPROM,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_MISC_SCL_R,
+ .sda = GPIO_EC_I2C_MISC_SDA_R,
+ },
+};
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
diff --git a/board/aurash/led.c b/board/aurash/led.c
new file mode 100644
index 0000000000..a8c725258b
--- /dev/null
+++ b/board/aurash/led.c
@@ -0,0 +1,260 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Power LED control for Brask.
+ * Solid green - active power
+ * Green flashing - suspended
+ * Red flashing - alert
+ * Solid red - critical
+ */
+
+#include "chipset.h"
+#include "console.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "led_common.h"
+#include "pwm.h"
+#include "timer.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_GPIO, format, ##args)
+
+/*
+ * Due to the CSME-Lite processing, upon startup the CPU transitions through
+ * S0->S3->S5->S3->S0, causing the LED to turn on/off/on, so
+ * delay turning off the LED during suspend/shutdown.
+ */
+#define LED_CPU_DELAY_MS (2000 * MSEC)
+
+const enum ec_led_id supported_led_ids[] = { EC_LED_ID_POWER_LED };
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+
+enum led_color {
+ LED_OFF = 0,
+ LED_RED,
+ LED_GREEN,
+
+ /* Number of colors, not a color itself */
+ LED_COLOR_COUNT
+};
+
+static int set_color_power(enum led_color color, int duty)
+{
+ int green = 0;
+ int red = 0;
+
+ if (duty < 0 || 100 < duty)
+ return EC_ERROR_UNKNOWN;
+
+ switch (color) {
+ case LED_OFF:
+ break;
+ case LED_GREEN:
+ green = 1;
+ break;
+ case LED_RED:
+ red = 1;
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+
+ if (red)
+ pwm_set_duty(PWM_CH_LED_RED, duty);
+ else
+ pwm_set_duty(PWM_CH_LED_RED, 0);
+
+ if (green)
+ pwm_set_duty(PWM_CH_LED_GREEN, duty);
+ else
+ pwm_set_duty(PWM_CH_LED_GREEN, 0);
+
+ return EC_SUCCESS;
+}
+
+static int set_color(enum ec_led_id id, enum led_color color, int duty)
+{
+ switch (id) {
+ case EC_LED_ID_POWER_LED:
+ return set_color_power(color, duty);
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+}
+
+#define LED_PULSE_US (2 * SECOND)
+/* 40 msec for nice and smooth transition. */
+#define LED_PULSE_TICK_US (40 * MSEC)
+
+/*
+ * When pulsing is enabled, brightness is incremented by <duty_inc> every
+ * <interval> usec from 0 to 100% in LED_PULSE_US usec. Then it's decremented
+ * likewise in LED_PULSE_US usec.
+ */
+static struct {
+ uint32_t interval;
+ int duty_inc;
+ enum led_color color;
+ int duty;
+} led_pulse;
+
+#define CONFIG_TICK(interval, color) \
+ config_tick((interval), 100 / (LED_PULSE_US / (interval)), (color))
+
+static void config_tick(uint32_t interval, int duty_inc, enum led_color color)
+{
+ led_pulse.interval = interval;
+ led_pulse.duty_inc = duty_inc;
+ led_pulse.color = color;
+ led_pulse.duty = 0;
+}
+
+static void pulse_power_led(enum led_color color)
+{
+ set_color(EC_LED_ID_POWER_LED, color, led_pulse.duty);
+ if (led_pulse.duty + led_pulse.duty_inc > 100)
+ led_pulse.duty_inc = led_pulse.duty_inc * -1;
+ else if (led_pulse.duty + led_pulse.duty_inc < 0)
+ led_pulse.duty_inc = led_pulse.duty_inc * -1;
+ led_pulse.duty += led_pulse.duty_inc;
+}
+
+static void led_tick(void);
+DECLARE_DEFERRED(led_tick);
+static void led_tick(void)
+{
+ uint32_t elapsed;
+ uint32_t next = 0;
+ uint32_t start = get_time().le.lo;
+
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ pulse_power_led(led_pulse.color);
+ elapsed = get_time().le.lo - start;
+ next = led_pulse.interval > elapsed ? led_pulse.interval - elapsed : 0;
+ hook_call_deferred(&led_tick_data, next);
+}
+
+static void led_suspend(void)
+{
+ CONFIG_TICK(LED_PULSE_TICK_US, LED_GREEN);
+ led_tick();
+}
+DECLARE_DEFERRED(led_suspend);
+
+static void led_shutdown(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_OFF, 0);
+}
+DECLARE_DEFERRED(led_shutdown);
+
+static void led_shutdown_hook(void)
+{
+ hook_call_deferred(&led_tick_data, -1);
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, led_shutdown_hook, HOOK_PRIO_DEFAULT);
+
+static void led_suspend_hook(void)
+{
+ hook_call_deferred(&led_shutdown_data, -1);
+ hook_call_deferred(&led_suspend_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, led_suspend_hook, HOOK_PRIO_DEFAULT);
+
+static void led_resume(void)
+{
+ /*
+ * Assume there is no race condition with led_tick, which also
+ * runs in hook_task.
+ */
+ hook_call_deferred(&led_tick_data, -1);
+ /*
+ * Avoid invoking the suspend/shutdown delayed hooks.
+ */
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, -1);
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_GREEN, 100);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, led_resume, HOOK_PRIO_DEFAULT);
+
+void led_alert(int enable)
+{
+ if (enable) {
+ /* Overwrite the current signal */
+ config_tick(1 * SECOND, 100, LED_RED);
+ led_tick();
+ } else {
+ /* Restore the previous signal */
+ if (chipset_in_state(CHIPSET_STATE_ON))
+ led_resume();
+ else if (chipset_in_state(CHIPSET_STATE_SUSPEND))
+ led_suspend_hook();
+ else if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ led_shutdown_hook();
+ }
+}
+
+void show_critical_error(void)
+{
+ hook_call_deferred(&led_tick_data, -1);
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_RED, 100);
+}
+
+static int command_led(int argc, const char **argv)
+{
+ enum ec_led_id id = EC_LED_ID_POWER_LED;
+
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+
+ if (!strcasecmp(argv[1], "debug")) {
+ led_auto_control(id, !led_auto_control_is_enabled(id));
+ ccprintf("o%s\n", led_auto_control_is_enabled(id) ? "ff" : "n");
+ } else if (!strcasecmp(argv[1], "off")) {
+ set_color(id, LED_OFF, 0);
+ } else if (!strcasecmp(argv[1], "red")) {
+ set_color(id, LED_RED, 100);
+ } else if (!strcasecmp(argv[1], "green")) {
+ set_color(id, LED_GREEN, 100);
+ } else if (!strcasecmp(argv[1], "alert")) {
+ led_alert(1);
+ } else if (!strcasecmp(argv[1], "crit")) {
+ show_critical_error();
+ } else {
+ return EC_ERROR_PARAM1;
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(led, command_led, "[debug|red|green|off|alert|crit]",
+ "Turn on/off LED.");
+
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ brightness_range[EC_LED_COLOR_RED] = 100;
+ brightness_range[EC_LED_COLOR_GREEN] = 100;
+}
+
+int led_set_brightness(enum ec_led_id id, const uint8_t *brightness)
+{
+ if (brightness[EC_LED_COLOR_RED])
+ return set_color(id, LED_RED, brightness[EC_LED_COLOR_RED]);
+ else if (brightness[EC_LED_COLOR_GREEN])
+ return set_color(id, LED_GREEN, brightness[EC_LED_COLOR_GREEN]);
+ else
+ return set_color(id, LED_OFF, 0);
+}
+__override void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ /* Blink alert if insufficient power per system_can_boot_ap(). */
+ int insufficient_power =
+ (charge_ma * charge_mv) <
+ (CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON * 1000);
+ led_alert(insufficient_power);
+}
diff --git a/board/aurash/pwm.c b/board/aurash/pwm.c
new file mode 100644
index 0000000000..a53243ca5a
--- /dev/null
+++ b/board/aurash/pwm.c
@@ -0,0 +1,39 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "hooks.h"
+#include "pwm.h"
+#include "pwm_chip.h"
+
+const struct pwm_t pwm_channels[] = {
+ [PWM_CH_LED_GREEN] = { .channel = 0,
+ .flags = PWM_CONFIG_ACTIVE_LOW |
+ PWM_CONFIG_DSLEEP,
+ .freq = 2000 },
+ [PWM_CH_FAN] = { .channel = 5,
+ .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP,
+ .freq = 1000 },
+ [PWM_CH_LED_RED] = { .channel = 2,
+ .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
+ .freq = 2000 },
+};
+BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+
+static void board_pwm_init(void)
+{
+ /*
+ * TODO(b/197478860): Turn on the fan at 100% by default
+ * We need to find tune the fan speed according to the
+ * thermal sensor value.
+ */
+ pwm_enable(PWM_CH_FAN, 1);
+ pwm_set_duty(PWM_CH_FAN, 100);
+
+ pwm_enable(PWM_CH_LED_RED, 1);
+ pwm_enable(PWM_CH_LED_GREEN, 1);
+}
+DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT);
diff --git a/board/aurash/sensors.c b/board/aurash/sensors.c
new file mode 100644
index 0000000000..211faace1c
--- /dev/null
+++ b/board/aurash/sensors.c
@@ -0,0 +1,114 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "adc_chip.h"
+#include "common.h"
+#include "hooks.h"
+#include "temp_sensor.h"
+#include "temp_sensor/thermistor.h"
+#include "thermal.h"
+
+/* ADC configuration */
+const struct adc_t adc_channels[] = {
+ [ADC_TEMP_SENSOR_1_CPU] = {
+ .name = "TEMP_CPU",
+ .input_ch = NPCX_ADC_CH0,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_2_CPU_VR] = {
+ .name = "TEMP_CPU_VR",
+ .input_ch = NPCX_ADC_CH1,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_3_WIFI] = {
+ .name = "TEMP_WIFI",
+ .input_ch = NPCX_ADC_CH6,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_4_DIMM] = {
+ .name = "TEMP_DIMM",
+ .input_ch = NPCX_ADC_CH7,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_VBUS] = { /* 5/39 voltage divider */
+ .name = "VBUS",
+ .input_ch = NPCX_ADC_CH2,
+ .factor_mul = ADC_MAX_VOLT * 39,
+ .factor_div = (ADC_READ_MAX + 1) * 5,
+ },
+ [ADC_PPVAR_IMON] = { /* 872.3 mV/A */
+ .name = "PPVAR_IMON",
+ .input_ch = NPCX_ADC_CH3,
+ .factor_mul = ADC_MAX_VOLT * 1433,
+ .factor_div = (ADC_READ_MAX + 1) * 1250,
+ },
+
+};
+BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
+
+/* Temperature sensor configuration */
+const struct temp_sensor_t temp_sensors[] = {
+ [TEMP_SENSOR_1_CPU] = { .name = "CPU",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_1_CPU },
+ [TEMP_SENSOR_2_CPU_VR] = { .name = "CPU VR",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_2_CPU_VR },
+ [TEMP_SENSOR_3_WIFI] = { .name = "WIFI",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_3_WIFI },
+ [TEMP_SENSOR_4_DIMM] = { .name = "DIMM",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_4_DIMM },
+};
+BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
+
+/*
+ * TODO(b/180681346): update for Alder Lake/brya
+ *
+ * Tiger Lake specifies 100 C as maximum TDP temperature. THRMTRIP# occurs at
+ * 130 C. However, sensor is located next to DDR, so we need to use the lower
+ * DDR temperature limit (85 C)
+ */
+/*
+ * TODO(b/202062363): Remove when clang is fixed.
+ */
+#define THERMAL_CPU \
+ { \
+ .temp_host = { \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \
+ [EC_TEMP_THRESH_HALT] = C_TO_K(80), \
+ }, \
+ .temp_host_release = { \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(65), \
+ }, \
+ .temp_fan_off = C_TO_K(35), \
+ .temp_fan_max = C_TO_K(50), \
+ }
+__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU;
+
+/*
+ * TODO(b/197478860): add the thermal sensor setting
+ */
+/* this should really be "const" */
+struct ec_thermal_config thermal_params[] = {
+ [TEMP_SENSOR_1_CPU] = THERMAL_CPU,
+ [TEMP_SENSOR_2_CPU_VR] = THERMAL_CPU,
+ [TEMP_SENSOR_3_WIFI] = THERMAL_CPU,
+ [TEMP_SENSOR_4_DIMM] = THERMAL_CPU,
+};
+BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);
diff --git a/board/aurash/usbc_config.c b/board/aurash/usbc_config.c
new file mode 100644
index 0000000000..a7a7cf682f
--- /dev/null
+++ b/board/aurash/usbc_config.c
@@ -0,0 +1,416 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "driver/bc12/pi3usb9201_public.h"
+#include "driver/ppc/syv682x_public.h"
+#include "driver/retimer/bb_retimer_public.h"
+#include "driver/retimer/kb800x.h"
+#include "driver/tcpm/nct38xx.h"
+#include "driver/tcpm/rt1715.h"
+#include "driver/tcpm/tcpci.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "ioexpander.h"
+#include "system.h"
+#include "task.h"
+#include "task_id.h"
+#include "timer.h"
+#include "usb_charge.h"
+#include "usb_mux.h"
+#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
+#include "usbc_config.h"
+#include "usbc_ppc.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args)
+
+/* USBC TCPC configuration */
+const struct tcpc_config_t tcpc_config[] = {
+ [USBC_PORT_C0] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
+ },
+ .drv = &nct38xx_tcpm_drv,
+ .flags = TCPC_FLAGS_TCPCI_REV2_0 |
+ TCPC_FLAGS_NO_DEBUG_ACC_CONTROL,
+ },
+ [USBC_PORT_C1] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C1_TCPC,
+ .addr_flags = RT1715_I2C_ADDR_FLAGS,
+ },
+ .drv = &rt1715_tcpm_drv,
+ },
+ [USBC_PORT_C2] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
+ },
+ .drv = &nct38xx_tcpm_drv,
+ .flags = TCPC_FLAGS_TCPCI_REV2_0,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
+BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT);
+
+/* USBC PPC configuration */
+struct ppc_config_t ppc_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_PPC,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
+ .drv = &syv682x_drv,
+ },
+ [USBC_PORT_C1] = {
+ .i2c_port = I2C_PORT_USB_C1_PPC,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
+ .drv = &syv682x_drv,
+ },
+ [USBC_PORT_C2] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_PPC,
+ .i2c_addr_flags = SYV682X_ADDR2_FLAGS,
+ .drv = &syv682x_drv,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
+
+unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+
+/* USBC mux configuration - Alder Lake includes internal mux */
+static const struct usb_mux_chain usbc0_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C0,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+static const struct usb_mux_chain usbc1_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C1,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+static const struct usb_mux_chain usbc2_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C2,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+
+struct kb800x_control_t kb800x_control[] = {
+ [USBC_PORT_C0] = {
+ },
+ [USBC_PORT_C1] = {
+ .retimer_rst_gpio = GPIO_USB_C1_RT_RST_R_L,
+ .ss_lanes = {
+ [KB800X_A0] = KB800X_TX0, [KB800X_A1] = KB800X_RX0,
+ [KB800X_B0] = KB800X_RX1, [KB800X_B1] = KB800X_TX1,
+ [KB800X_C0] = KB800X_RX0, [KB800X_C1] = KB800X_TX0,
+ [KB800X_D0] = KB800X_TX1, [KB800X_D1] = KB800X_RX1,
+ }
+ },
+ [USBC_PORT_C2] = {
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(kb800x_control) == USBC_PORT_COUNT);
+
+const struct usb_mux_chain usb_muxes[] = {
+ [USBC_PORT_C0] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C0,
+ .driver = &bb_usb_retimer,
+ .hpd_update = bb_retimer_hpd_update,
+ .i2c_port = I2C_PORT_USB_C0_C2_MUX,
+ .i2c_addr_flags = USBC_PORT_C0_BB_RETIMER_I2C_ADDR,
+ },
+ .next = &usbc0_tcss_usb_mux,
+ },
+ [USBC_PORT_C1] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C1,
+ .driver = &kb800x_usb_mux_driver,
+ .i2c_port = I2C_PORT_USB_C1_MUX,
+ .i2c_addr_flags = KB800X_I2C_ADDR0_FLAGS,
+ },
+ .next = &usbc1_tcss_usb_mux,
+ },
+ [USBC_PORT_C2] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C2,
+ .driver = &bb_usb_retimer,
+ .hpd_update = bb_retimer_hpd_update,
+ .i2c_port = I2C_PORT_USB_C0_C2_MUX,
+ .i2c_addr_flags = USBC_PORT_C2_BB_RETIMER_I2C_ADDR,
+ },
+ .next = &usbc2_tcss_usb_mux,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
+
+/* BC1.2 charger detect configuration */
+const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+ [USBC_PORT_C1] = {
+ .i2c_port = I2C_PORT_USB_C1_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+ [USBC_PORT_C2] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_1_FLAGS,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT);
+
+/*
+ * USB C0 and C2 uses burnside bridge chips and have their reset
+ * controlled by their respective TCPC chips acting as GPIO expanders.
+ *
+ * ioex_init() is normally called before we take the TCPCs out of
+ * reset, so we need to start in disabled mode, then explicitly
+ * call ioex_init().
+ */
+
+struct ioexpander_config_t ioex_config[] = {
+ [IOEX_C0_NCT38XX] = {
+ .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
+ .i2c_addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
+ .drv = &nct38xx_ioexpander_drv,
+ .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
+ },
+ [IOEX_C2_NCT38XX] = {
+ .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
+ .i2c_addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
+ .drv = &nct38xx_ioexpander_drv,
+ .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ioex_config) == CONFIG_IO_EXPANDER_PORT_COUNT);
+
+__override int bb_retimer_power_enable(const struct usb_mux *me, bool enable)
+{
+ enum ioex_signal rst_signal;
+
+ if (me->usb_port == USBC_PORT_C0) {
+ rst_signal = IOEX_USB_C0_RT_RST_ODL;
+ } else if (me->usb_port == USBC_PORT_C2) {
+ rst_signal = IOEX_USB_C2_RT_RST_ODL;
+ } else {
+ return EC_ERROR_INVAL;
+ }
+
+ /*
+ * We do not have a load switch for the burnside bridge chips,
+ * so we only need to sequence reset.
+ */
+
+ if (enable) {
+ /*
+ * Tpw, minimum time from VCC to RESET_N de-assertion is 100us.
+ * For boards that don't provide a load switch control, the
+ * retimer_init() function ensures power is up before calling
+ * this function.
+ */
+ ioex_set_level(rst_signal, 1);
+ /*
+ * Allow 1ms time for the retimer to power up lc_domain
+ * which powers I2C controller within retimer
+ */
+ msleep(1);
+ } else {
+ ioex_set_level(rst_signal, 0);
+ msleep(1);
+ }
+ return EC_SUCCESS;
+}
+
+__override int bb_retimer_reset(const struct usb_mux *me)
+{
+ /*
+ * TODO(b/193402306, b/195375738): Remove this once transition to
+ * QS Silicon is complete
+ */
+ bb_retimer_power_enable(me, false);
+ msleep(5);
+ bb_retimer_power_enable(me, true);
+ msleep(25);
+
+ return EC_SUCCESS;
+}
+
+void board_reset_pd_mcu(void)
+{
+ enum gpio_signal tcpc_rst;
+
+ tcpc_rst = GPIO_USB_C0_C2_TCPC_RST_ODL;
+
+ /*
+ * TODO(b/179648104): figure out correct timing
+ */
+
+ gpio_set_level(tcpc_rst, 0);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 0);
+
+ /*
+ * delay for power-on to reset-off and min. assertion time
+ */
+
+ msleep(20);
+
+ gpio_set_level(tcpc_rst, 1);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 1);
+
+ /* wait for chips to come up */
+
+ msleep(50);
+}
+
+static void enable_ioex(int ioex)
+{
+ ioex_init(ioex);
+}
+
+static void board_tcpc_init(void)
+{
+ /* Don't reset TCPCs after initial reset */
+ if (!system_jumped_late()) {
+ board_reset_pd_mcu();
+
+ /*
+ * These IO expander pins are implemented using the
+ * C0/C2 TCPC, so they must be set up after the TCPC has
+ * been taken out of reset.
+ */
+ enable_ioex(IOEX_C0_NCT38XX);
+ enable_ioex(IOEX_C2_NCT38XX);
+ }
+
+ /* Enable PPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL);
+
+ /* Enable TCPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_C2_TCPC_INT_ODL);
+
+ gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET);
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (gpio_get_level(GPIO_USB_C0_C2_TCPC_INT_ODL) == 0)
+ status |= PD_STATUS_TCPC_ALERT_0 | PD_STATUS_TCPC_ALERT_2;
+
+ if (gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0)
+ status |= PD_STATUS_TCPC_ALERT_1;
+
+ return status;
+}
+
+int ppc_get_alert_status(int port)
+{
+ if (port == USBC_PORT_C0)
+ return gpio_get_level(GPIO_USB_C0_PPC_INT_ODL) == 0;
+ else if (port == USBC_PORT_C1)
+ return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0;
+ else if (port == USBC_PORT_C2)
+ return gpio_get_level(GPIO_USB_C2_PPC_INT_ODL) == 0;
+ return 0;
+}
+
+void tcpc_alert_event(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_C2_TCPC_INT_ODL:
+ schedule_deferred_pd_interrupt(USBC_PORT_C0);
+ break;
+ case GPIO_USB_C1_TCPC_INT_ODL:
+ schedule_deferred_pd_interrupt(USBC_PORT_C1);
+ break;
+ default:
+ break;
+ }
+}
+
+void bc12_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_BC12_INT_ODL:
+ usb_charger_task_set_event(0, USB_CHG_EVENT_BC12);
+ break;
+ case GPIO_USB_C1_BC12_INT_ODL:
+ usb_charger_task_set_event(1, USB_CHG_EVENT_BC12);
+ break;
+ case GPIO_USB_C2_BC12_INT_ODL:
+ usb_charger_task_set_event(2, USB_CHG_EVENT_BC12);
+ break;
+ default:
+ break;
+ }
+}
+
+void ppc_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C0);
+ break;
+ case GPIO_USB_C1_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C1);
+ break;
+ case GPIO_USB_C2_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C2);
+ break;
+ default:
+ break;
+ }
+}
+
+void retimer_interrupt(enum gpio_signal signal)
+{
+ /*
+ * TODO(b/179513527): add USB-C support
+ */
+}
+
+__override bool board_is_dts_port(int port)
+{
+ return port == USBC_PORT_C0;
+}
+
+__override bool board_is_tbt_usb4_port(int port)
+{
+ return true;
+}
+
+__override enum tbt_compat_cable_speed board_get_max_tbt_speed(int port)
+{
+ if (!board_is_tbt_usb4_port(port))
+ return TBT_SS_RES_0;
+
+ return TBT_SS_TBT_GEN3;
+}
diff --git a/board/aurash/usbc_config.h b/board/aurash/usbc_config.h
new file mode 100644
index 0000000000..778ca51a0d
--- /dev/null
+++ b/board/aurash/usbc_config.h
@@ -0,0 +1,20 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Brya board-specific USB-C configuration */
+
+#ifndef __CROS_EC_USBC_CONFIG_H
+#define __CROS_EC_USBC_CONFIG_H
+
+#define CONFIG_USB_PD_PORT_MAX_COUNT 3
+
+enum usbc_port {
+ USBC_PORT_C0 = 0,
+ USBC_PORT_C1,
+ USBC_PORT_C2,
+ USBC_PORT_COUNT
+};
+
+#endif /* __CROS_EC_USBC_CONFIG_H */
diff --git a/board/aurash/vif_override.xml b/board/aurash/vif_override.xml
new file mode 100644
index 0000000000..32736caf64
--- /dev/null
+++ b/board/aurash/vif_override.xml
@@ -0,0 +1,3 @@
+<!-- Add VIF field overrides here. See genvif.c and the Vendor Info File
+ Definition from the USB-IF.
+-->
diff --git a/board/brask/board.c b/board/brask/board.c
index 19753765c2..be41092f0e 100644
--- a/board/brask/board.c
+++ b/board/brask/board.c
@@ -12,6 +12,7 @@
#include "console.h"
#include "cros_board_info.h"
#include "driver/tcpm/tcpci.h"
+#include "driver/wpc/cps8100.h"
#include "fw_config.h"
#include "gpio.h"
#include "gpio_signal.h"
@@ -41,7 +42,6 @@ const int usb_port_enable[USB_PORT_COUNT] = {
};
BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT);
-extern struct pchg_drv cps8100_drv;
struct pchg pchgs[] = {
[0] = {
.cfg = &(const struct pchg_config) {
@@ -58,7 +58,11 @@ struct pchg pchgs[] = {
.events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
},
};
-const int pchg_count = ARRAY_SIZE(pchgs);
+
+int board_get_pchg_count(void)
+{
+ return ARRAY_SIZE(pchgs);
+}
__override void board_pchg_power_on(int port, bool on)
{
diff --git a/board/brya/usbc_config.c b/board/brya/usbc_config.c
index eb6f898a26..03cf197569 100644
--- a/board/brya/usbc_config.c
+++ b/board/brya/usbc_config.c
@@ -384,10 +384,10 @@ static void board_tcpc_init(void)
gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL);
+#ifndef CONFIG_ZEPHYR
/* Enable TCPC interrupts. */
gpio_enable_interrupt(GPIO_USB_C0_C2_TCPC_INT_ODL);
-#ifndef CONFIG_ZEPHYR
/* Enable BC1.2 interrupts. */
gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL);
gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL);
@@ -395,8 +395,8 @@ static void board_tcpc_init(void)
if (ec_cfg_usb_db_type() != DB_USB_ABSENT) {
gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
- gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
#ifndef CONFIG_ZEPHYR
+ gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL);
#endif /* !CONFIG_ZEPHYR */
}
diff --git a/board/casta/battery.c b/board/casta/battery.c
index 81e2d98e40..846165ff13 100644
--- a/board/casta/battery.c
+++ b/board/casta/battery.c
@@ -14,7 +14,8 @@
#define CHARGING_VOLTAGE_MV_SAFE 8400
#define CHARGING_CURRENT_MA_SAFE 1500
-
+#define CHARGING_VOLTAGE_MV_ADJUST 8600
+#define CHARGING_CURRENT_MA_ADJUST 3200
/*
* Battery info for all casta battery types. Note that the fields
* start_charging_min/max and charging_min/max are not used for the charger.
@@ -103,7 +104,11 @@ int charger_profile_override(struct charge_state_data *curr)
return 0;
current = curr->requested_current;
+ if (current > CHARGING_CURRENT_MA_ADJUST)
+ current = CHARGING_CURRENT_MA_ADJUST;
voltage = curr->requested_voltage;
+ if (voltage > CHARGING_VOLTAGE_MV_ADJUST)
+ voltage = CHARGING_VOLTAGE_MV_ADJUST;
bat_temp_c = curr->batt.temperature - 2731;
batt_info = battery_get_info();
diff --git a/board/coachz/board.c b/board/coachz/board.c
index 85fe06c38d..931695dc38 100644
--- a/board/coachz/board.c
+++ b/board/coachz/board.c
@@ -80,7 +80,11 @@ struct pchg pchgs[] = {
.events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
},
};
-const int pchg_count = ARRAY_SIZE(pchgs);
+
+int board_get_pchg_count(void)
+{
+ return ARRAY_SIZE(pchgs);
+}
/* GPIO Interrupt Handlers */
static void tcpc_alert_event(enum gpio_signal signal)
diff --git a/board/constitution/board.c b/board/constitution/board.c
new file mode 100644
index 0000000000..5cd4d9deae
--- /dev/null
+++ b/board/constitution/board.c
@@ -0,0 +1,600 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "adc.h"
+#include "builtin/assert.h"
+#include "button.h"
+#include "charge_manager.h"
+#include "charge_state_v2.h"
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "driver/tcpm/tcpci.h"
+#include "driver/wpc/cps8100.h"
+#include "fw_config.h"
+#include "gpio.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "peripheral_charger.h"
+#include "power.h"
+#include "power_button.h"
+#include "switch.h"
+#include "throttle_ap.h"
+#include "usbc_config.h"
+#include "usbc_ppc.h"
+
+#include <stdbool.h>
+
+/* Console output macros */
+#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ##args)
+#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args)
+
+static void power_monitor(void);
+DECLARE_DEFERRED(power_monitor);
+
+/******************************************************************************/
+/* USB-A charging control */
+
+const int usb_port_enable[USB_PORT_COUNT] = {
+ GPIO_EN_PP5000_USBA,
+};
+BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT);
+
+struct pchg pchgs[] = {
+ [0] = {
+ .cfg = &(const struct pchg_config) {
+ .drv = &cps8100_drv,
+ .i2c_port = I2C_PORT_QI,
+ .irq_pin = GPIO_QI_INT_ODL,
+ .full_percent = 96,
+ .block_size = 128,
+ },
+ .policy = {
+ [PCHG_CHIPSET_STATE_ON] = &pchg_policy_on,
+ [PCHG_CHIPSET_STATE_SUSPEND] = &pchg_policy_suspend,
+ },
+ .events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
+ },
+};
+
+int board_get_pchg_count(void)
+{
+ return ARRAY_SIZE(pchgs);
+}
+
+__override void board_pchg_power_on(int port, bool on)
+{
+ if (port == 0)
+ gpio_set_level(GPIO_EC_QI_PWR, on);
+ else
+ CPRINTS("%s: Invalid port=%d", __func__, port);
+}
+
+/******************************************************************************/
+
+int board_set_active_charge_port(int port)
+{
+ CPRINTS("Requested charge port change to %d", port);
+
+ /*
+ * The charge manager may ask us to switch to no charger if we're
+ * running off USB-C only but upstream doesn't support PD. It requires
+ * that we accept this switch otherwise it triggers an assert and EC
+ * reset; it's not possible to boot the AP anyway, but we want to avoid
+ * resetting the EC so we can continue to do the "low power" LED blink.
+ */
+ if (port == CHARGE_PORT_NONE)
+ return EC_SUCCESS;
+
+ if (port < 0 || CHARGE_PORT_COUNT <= port)
+ return EC_ERROR_INVAL;
+
+ if (port == charge_manager_get_active_charge_port())
+ return EC_SUCCESS;
+
+ /* Don't charge from a source port */
+ if (board_vbus_source_enabled(port))
+ return EC_ERROR_INVAL;
+
+ if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ int bj_active, bj_requested;
+
+ if (charge_manager_get_active_charge_port() != CHARGE_PORT_NONE)
+ /* Change is only permitted while the system is off */
+ return EC_ERROR_INVAL;
+
+ /*
+ * Current setting is no charge port but the AP is on, so the
+ * charge manager is out of sync (probably because we're
+ * reinitializing after sysjump). Reject requests that aren't
+ * in sync with our outputs.
+ */
+ bj_active = !gpio_get_level(GPIO_EN_PPVAR_BJ_ADP_L);
+ bj_requested = port == CHARGE_PORT_BARRELJACK;
+ if (bj_active != bj_requested)
+ return EC_ERROR_INVAL;
+ }
+
+ CPRINTS("New charger p%d", port);
+
+ switch (port) {
+ case CHARGE_PORT_TYPEC0:
+ case CHARGE_PORT_TYPEC1:
+ case CHARGE_PORT_TYPEC2:
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1);
+ break;
+ case CHARGE_PORT_BARRELJACK:
+ /* Make sure BJ adapter is sourcing power */
+ if (gpio_get_level(GPIO_BJ_ADP_PRESENT_ODL))
+ return EC_ERROR_INVAL;
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 0);
+ break;
+ default:
+ return EC_ERROR_INVAL;
+ }
+
+ return EC_SUCCESS;
+}
+
+static uint8_t usbc_overcurrent;
+static int32_t base_5v_power_s5;
+static int32_t base_5v_power_z1;
+
+/*
+ * Power usage for each port as measured or estimated.
+ * Units are milliwatts (5v x ma current)
+ */
+
+/* PP5000_S5 loads */
+#define PWR_S5_BASE_LOAD (5 * 1431)
+#define PWR_S5_FRONT_HIGH (5 * 1737)
+#define PWR_S5_FRONT_LOW (5 * 1055)
+#define PWR_S5_REAR_HIGH (5 * 1737)
+#define PWR_S5_REAR_LOW (5 * 1055)
+#define PWR_S5_HDMI (5 * 580)
+#define PWR_S5_MAX (5 * 10000)
+#define FRONT_DELTA (PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW)
+#define REAR_DELTA (PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW)
+
+/* PP5000_Z1 loads */
+#define PWR_Z1_BASE_LOAD (5 * 5)
+#define PWR_Z1_C_HIGH (5 * 3600)
+#define PWR_Z1_C_LOW (5 * 2000)
+#define PWR_Z1_MAX (5 * 9000)
+/*
+ * Update the 5V power usage, assuming no throttling,
+ * and invoke the power monitoring.
+ */
+static void update_5v_usage(void)
+{
+ int front_ports = 0;
+ int rear_ports = 0;
+
+ /*
+ * Recalculate the 5V load, assuming no throttling.
+ */
+ base_5v_power_s5 = PWR_S5_BASE_LOAD;
+ if (!gpio_get_level(GPIO_USB_A0_OC_ODL)) {
+ front_ports++;
+ base_5v_power_s5 += PWR_S5_FRONT_LOW;
+ }
+ if (!gpio_get_level(GPIO_USB_A1_OC_ODL)) {
+ front_ports++;
+ base_5v_power_s5 += PWR_S5_FRONT_LOW;
+ }
+ /*
+ * Only 1 front port can run higher power at a time.
+ */
+ if (front_ports > 0)
+ base_5v_power_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
+
+ if (!gpio_get_level(GPIO_USB_A2_OC_ODL)) {
+ rear_ports++;
+ base_5v_power_s5 += PWR_S5_REAR_LOW;
+ }
+ if (!gpio_get_level(GPIO_USB_A3_OC_ODL)) {
+ rear_ports++;
+ base_5v_power_s5 += PWR_S5_REAR_LOW;
+ }
+ /*
+ * Only 1 rear port can run higher power at a time.
+ */
+ if (rear_ports > 0)
+ base_5v_power_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
+ if (!gpio_get_level(GPIO_HDMI_CONN_OC_ODL))
+ base_5v_power_s5 += PWR_S5_HDMI;
+ base_5v_power_z1 = PWR_Z1_BASE_LOAD;
+ if (usbc_overcurrent)
+ base_5v_power_z1 += PWR_Z1_C_HIGH;
+ /*
+ * Invoke the power handler immediately.
+ */
+ hook_call_deferred(&power_monitor_data, 0);
+}
+DECLARE_DEFERRED(update_5v_usage);
+/*
+ * Start power monitoring after ADCs have been initialised.
+ */
+DECLARE_HOOK(HOOK_INIT, update_5v_usage, HOOK_PRIO_INIT_ADC + 1);
+
+static void port_ocp_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&update_5v_usage_data, 0);
+}
+/* Must come after other header files and interrupt handler declarations */
+#include "gpio_list.h"
+
+/******************************************************************************/
+/*
+ * Barrel jack power supply handling
+ *
+ * EN_PPVAR_BJ_ADP_L must default active to ensure we can power on when the
+ * barrel jack is connected, and the USB-C port can bring the EC up fine in
+ * dead-battery mode. Both the USB-C and barrel jack switches do reverse
+ * protection, so we're safe to turn one on then the other off- but we should
+ * only do that if the system is off since it might still brown out.
+ */
+
+#define ADP_DEBOUNCE_MS 1000 /* Debounce time for BJ plug/unplug */
+/* Debounced connection state of the barrel jack */
+static int8_t adp_connected = -1;
+static void adp_connect_deferred(void)
+{
+ struct charge_port_info pi = { 0 };
+ int connected = !gpio_get_level(GPIO_BJ_ADP_PRESENT_ODL);
+
+ /* Debounce */
+ if (connected == adp_connected)
+ return;
+ if (connected)
+ ec_bj_power(&pi.voltage, &pi.current);
+ charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
+ DEDICATED_CHARGE_PORT, &pi);
+ adp_connected = connected;
+}
+DECLARE_DEFERRED(adp_connect_deferred);
+
+/* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */
+void adp_connect_interrupt(enum gpio_signal signal)
+{
+ hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC);
+}
+
+static void adp_state_init(void)
+{
+ ASSERT(CHARGE_PORT_ENUM_COUNT == CHARGE_PORT_COUNT);
+ /*
+ * Initialize all charge suppliers to 0. The charge manager waits until
+ * all ports have reported in before doing anything.
+ */
+ for (int i = 0; i < CHARGE_PORT_COUNT; i++) {
+ for (int j = 0; j < CHARGE_SUPPLIER_COUNT; j++)
+ charge_manager_update_charge(j, i, NULL);
+ }
+
+ /* Report charge state from the barrel jack. */
+ adp_connect_deferred();
+}
+DECLARE_HOOK(HOOK_INIT, adp_state_init, HOOK_PRIO_INIT_CHARGE_MANAGER + 1);
+
+static void board_init(void)
+{
+ gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_ODL);
+ gpio_enable_interrupt(GPIO_HDMI_CONN_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A0_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A1_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A2_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A3_OC_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+
+void board_overcurrent_event(int port, int is_overcurrented)
+{
+ /* Check that port number is valid. */
+ if ((port < 0) || (port >= CONFIG_USB_PD_PORT_MAX_COUNT))
+ return;
+ usbc_overcurrent = is_overcurrented;
+ update_5v_usage();
+}
+/*
+ * Power monitoring and management.
+ *
+ * the power budgets are met without letting the system fall into
+ * power deficit (perhaps causing a brownout).
+ *
+ * There are 2 power budgets that need to be managed:
+ * The overall goal is to gracefully manage the power demand so that
+ * - overall system power as measured on the main power supply rail.
+ * - 5V power delivered to the USB and HDMI ports.
+ *
+ * The actual system power demand is calculated from the VBUS voltage and
+ * the input current (read from a shunt), averaged over 5 readings.
+ * The power budget limit is from the charge manager.
+ *
+ * The 5V power cannot be read directly. Instead, we rely on overcurrent
+ * inputs from the USB and HDMI ports to indicate that the port is in use
+ * (and drawing maximum power).
+ *
+ * There are 3 throttles that can be applied (in priority order):
+ *
+ * - Type A BC1.2 front port restriction (3W)
+ * - Type A BC1.2 rear port restriction (3W)
+ * - Type C PD (throttle to 1.5A if sourcing)
+ * - Turn on PROCHOT, which immediately throttles the CPU.
+ *
+ * The first 3 throttles affect both the system power and the 5V rails.
+ * The third is a last resort to force an immediate CPU throttle to
+ * reduce the overall power use.
+ *
+ * The strategy is to determine what the state of the throttles should be,
+ * and to then turn throttles off or on as needed to match this.
+ *
+ * This function runs on demand, or every 2 ms when the CPU is up,
+ * and continually monitors the power usage, applying the
+ * throttles when necessary.
+ *
+ * All measurements are in milliwatts.
+ */
+#define THROT_TYPE_A_FRONT BIT(0)
+#define THROT_TYPE_A_REAR BIT(1)
+#define THROT_TYPE_C0 BIT(2)
+#define THROT_TYPE_C1 BIT(3)
+#define THROT_TYPE_C2 BIT(4)
+#define THROT_PROCHOT BIT(5)
+
+/*
+ * Power gain if front USB A ports are limited.
+ */
+#define POWER_GAIN_TYPE_A 3200
+/*
+ * Power gain if Type C port is limited.
+ */
+#define POWER_GAIN_TYPE_C 8800
+/*
+ * Power is averaged over 10 ms, with a reading every 2 ms.
+ */
+#define POWER_DELAY_MS 2
+#define POWER_READINGS (10 / POWER_DELAY_MS)
+
+static void power_monitor(void)
+{
+ static uint32_t current_state;
+ static uint32_t history[POWER_READINGS];
+ static uint8_t index;
+ int32_t delay;
+ uint32_t new_state = 0, diff;
+ int32_t headroom_5v_s5 = PWR_S5_MAX - base_5v_power_s5;
+ int32_t headroom_5v_z1 = PWR_Z1_MAX - base_5v_power_z1;
+
+ /*
+ * If CPU is off or suspended, no need to throttle
+ * or restrict power.
+ */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF | CHIPSET_STATE_SUSPEND)) {
+ /*
+ * Slow down monitoring, assume no throttling required.
+ */
+ delay = 20 * MSEC;
+ /*
+ * Clear the first entry of the power table so that
+ * it is re-initilalised when the CPU starts.
+ */
+ history[0] = 0;
+ } else {
+ int32_t charger_mw;
+
+ delay = POWER_DELAY_MS * MSEC;
+ /*
+ * Get current charger limit (in mw).
+ * If not configured yet, skip.
+ */
+ charger_mw = charge_manager_get_power_limit_uw() / 1000;
+ if (charger_mw != 0) {
+ int32_t gap, total, max, power;
+ int i;
+
+ /*
+ * Read power usage.
+ */
+ power = (adc_read_channel(ADC_VBUS) *
+ adc_read_channel(ADC_PPVAR_IMON)) /
+ 1000;
+ /* Init power table */
+ if (history[0] == 0) {
+ for (i = 0; i < POWER_READINGS; i++)
+ history[i] = power;
+ }
+ /*
+ * Update the power readings and
+ * calculate the average and max.
+ */
+ history[index] = power;
+ index = (index + 1) % POWER_READINGS;
+ total = 0;
+ max = history[0];
+ for (i = 0; i < POWER_READINGS; i++) {
+ total += history[i];
+ if (history[i] > max)
+ max = history[i];
+ }
+ /*
+ * For Type-C power supplies, there is
+ * less tolerance for exceeding the rating,
+ * so use the max power that has been measured
+ * over the measuring period.
+ * For barrel-jack supplies, the rating can be
+ * exceeded briefly, so use the average.
+ */
+ if (charge_manager_get_supplier() == CHARGE_SUPPLIER_PD)
+ power = max;
+ else
+ power = total / POWER_READINGS;
+ /*
+ * Calculate gap, and if negative, power
+ * demand is exceeding configured power budget, so
+ * throttling is required to reduce the demand.
+ */
+ gap = charger_mw - power;
+ /*
+ * Limiting type-A power rear ports.
+ */
+ if (gap <= 0) {
+ new_state |= THROT_TYPE_A_REAR;
+ headroom_5v_s5 += REAR_DELTA;
+ if (!(current_state & THROT_TYPE_A_REAR))
+ gap += POWER_GAIN_TYPE_A;
+ }
+ /*
+ * Limiting type-A power front ports.
+ */
+ if (gap <= 0) {
+ new_state |= THROT_TYPE_A_FRONT;
+ headroom_5v_s5 += FRONT_DELTA;
+ if (!(current_state & THROT_TYPE_A_REAR))
+ gap += POWER_GAIN_TYPE_A;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(0) && gap <= 0) {
+ new_state |= THROT_TYPE_C0;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C0))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(1) && gap <= 0) {
+ new_state |= THROT_TYPE_C1;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C1))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * If the type-C port is sourcing power,
+ * check whether it should be throttled.
+ */
+ if (ppc_is_sourcing_vbus(2) && gap <= 0) {
+ new_state |= THROT_TYPE_C2;
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ if (!(current_state & THROT_TYPE_C2))
+ gap += POWER_GAIN_TYPE_C;
+ }
+ /*
+ * As a last resort, turn on PROCHOT to
+ * throttle the CPU.
+ */
+ if (gap <= 0)
+ new_state |= THROT_PROCHOT;
+ }
+ }
+ /*
+ * Check the 5v power usage and if necessary,
+ * adjust the throttles in priority order.
+ *
+ * Either throttle may have already been activated by
+ * the overall power control.
+ *
+ * We rely on the overcurrent detection to inform us
+ * if the port is in use.
+ *
+ * - If type C not already throttled:
+ * * If not overcurrent, prefer to limit type C [1].
+ * * If in overcurrentuse:
+ * - limit type A first [2]
+ * - If necessary, limit type C [3].
+ * - If type A not throttled, if necessary limit it [2].
+ */
+ if (headroom_5v_z1 < 0) {
+ /*
+ * Check whether type C is not throttled,
+ * and is not overcurrent.
+ */
+ if (!((new_state & THROT_TYPE_C0) || usbc_overcurrent)) {
+ /*
+ * [1] Type C not in overcurrent, throttle it.
+ */
+ headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
+ new_state |= THROT_TYPE_C0;
+ }
+ /*
+ * [2] If still under-budget, limit type C.
+ * No need to check if it is already throttled or not.
+ */
+ if (headroom_5v_z1 < 0)
+ new_state |= THROT_TYPE_C0;
+ }
+ if (headroom_5v_s5 < 0) {
+ /*
+ * [1] If type A rear not already throttled, and power still
+ * needed, limit type A rear.
+ */
+ if (!(new_state & THROT_TYPE_A_REAR) && headroom_5v_s5 < 0) {
+ headroom_5v_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
+ new_state |= THROT_TYPE_A_REAR;
+ }
+ /*
+ * [2] If type A front not already throttled, and power still
+ * needed, limit type A front.
+ */
+ if (!(new_state & THROT_TYPE_A_FRONT) && headroom_5v_s5 < 0) {
+ headroom_5v_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
+ new_state |= THROT_TYPE_A_FRONT;
+ }
+ }
+ /*
+ * Turn the throttles on or off if they have changed.
+ */
+ diff = new_state ^ current_state;
+ current_state = new_state;
+ if (diff & THROT_PROCHOT) {
+ int prochot = (new_state & THROT_PROCHOT) ? 0 : 1;
+
+ gpio_set_level(GPIO_EC_PROCHOT_ODL, prochot);
+ }
+ if (diff & THROT_TYPE_C0) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C0) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(0, rp);
+ tcpm_select_rp_value(0, rp);
+ pd_update_contract(0);
+ }
+ if (diff & THROT_TYPE_C1) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C1) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(1, rp);
+ tcpm_select_rp_value(1, rp);
+ pd_update_contract(1);
+ }
+ if (diff & THROT_TYPE_C2) {
+ enum tcpc_rp_value rp = (new_state & THROT_TYPE_C2) ?
+ TYPEC_RP_1A5 :
+ TYPEC_RP_3A0;
+
+ ppc_set_vbus_source_current_limit(2, rp);
+ tcpm_select_rp_value(2, rp);
+ pd_update_contract(2);
+ }
+ if (diff & THROT_TYPE_A_REAR) {
+ int typea_bc = (new_state & THROT_TYPE_A_REAR) ? 1 : 0;
+
+ gpio_set_level(GPIO_USB_A_LOW_PWR0_OD, typea_bc);
+ gpio_set_level(GPIO_USB_A_LOW_PWR1_OD, typea_bc);
+ }
+ if (diff & THROT_TYPE_A_FRONT) {
+ int typea_bc = (new_state & THROT_TYPE_A_FRONT) ? 1 : 0;
+
+ gpio_set_level(GPIO_USB_A_LOW_PWR2_OD, typea_bc);
+ gpio_set_level(GPIO_USB_A_LOW_PWR3_OD, typea_bc);
+ }
+ hook_call_deferred(&power_monitor_data, delay);
+}
diff --git a/board/constitution/board.h b/board/constitution/board.h
new file mode 100644
index 0000000000..88e74a8e64
--- /dev/null
+++ b/board/constitution/board.h
@@ -0,0 +1,204 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Brask board configuration */
+
+#ifndef __CROS_EC_BOARD_H
+#define __CROS_EC_BOARD_H
+
+#include "compile_time_macros.h"
+
+/* Baseboard features */
+#include "baseboard.h"
+
+#define CONFIG_MP2964
+
+/* Barrel Jack */
+#define DEDICATED_CHARGE_PORT 3
+
+/* HDMI CEC */
+#define CONFIG_CEC
+#define CEC_GPIO_OUT GPIO_HDMI_CEC_OUT
+#define CEC_GPIO_IN GPIO_HDMI_CEC_IN
+#define CEC_GPIO_PULL_UP GPIO_HDMI_CEC_PULL_UP
+
+/* USB Type A Features */
+#define USB_PORT_COUNT 4
+#define CONFIG_USB_PORT_POWER_DUMB
+
+/* USB Type C and USB PD defines */
+#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY
+
+#define CONFIG_IO_EXPANDER
+#define CONFIG_IO_EXPANDER_NCT38XX
+#define CONFIG_IO_EXPANDER_PORT_COUNT 2
+
+#define CONFIG_USB_PD_PPC
+#define CONFIG_USB_PD_TCPM_RT1715
+#define CONFIG_USBC_RETIMER_INTEL_BB
+
+#define CONFIG_USBC_RETIMER_KB800X
+#define CONFIG_KB800X_CUSTOM_XBAR
+#define CONFIG_USBC_PPC_SYV682X
+#undef CONFIG_SYV682X_HV_ILIM
+#define CONFIG_SYV682X_HV_ILIM SYV682X_HV_ILIM_5_50
+
+/* TODO: b/177608416 - measure and check these values on brya */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 30000 /* us */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
+/* The design should support up to 100W. */
+/* TODO(b/197702356): Set the max PD to 60W now and change it
+ * to 100W after we verify it.
+ */
+#define PD_OPERATING_POWER_MW CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON
+#define PD_MAX_POWER_MW 100000
+#define PD_MAX_CURRENT_MA 5000
+#define PD_MAX_VOLTAGE_MV 20000
+
+/*
+ * Macros for GPIO signals used in common code that don't match the
+ * schematic names. Signal names in gpio.inc match the schematic and are
+ * then redefined here to so it's more clear which signal is being used for
+ * which purpose.
+ */
+#define GPIO_AC_PRESENT GPIO_ACOK_OD
+#define GPIO_CPU_PROCHOT GPIO_EC_PROCHOT_ODL
+#define GPIO_EC_INT_L GPIO_EC_PCH_INT_ODL
+#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW
+#define GPIO_PACKET_MODE_EN GPIO_EC_GSC_PACKET_MODE
+#define GPIO_PCH_PWRBTN_L GPIO_EC_PCH_PWR_BTN_ODL
+#define GPIO_PCH_RSMRST_L GPIO_EC_PCH_RSMRST_L
+#define GPIO_PCH_RTCRST GPIO_EC_PCH_RTCRST
+#define GPIO_PCH_SLP_S0_L GPIO_SYS_SLP_S0IX_L
+#define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L
+#define GPIO_TEMP_SENSOR_POWER GPIO_SEQ_EC_DSW_PWROK
+
+/*
+ * GPIO_EC_PCH_INT_ODL is used for MKBP events as well as a PCH wakeup
+ * signal.
+ */
+#define GPIO_PCH_WAKE_L GPIO_EC_PCH_INT_ODL
+#define GPIO_PG_EC_ALL_SYS_PWRGD GPIO_SEQ_EC_ALL_SYS_PG
+#define GPIO_PG_EC_DSW_PWROK GPIO_SEQ_EC_DSW_PWROK
+#define GPIO_PG_EC_RSMRST_ODL GPIO_SEQ_EC_RSMRST_ODL
+#define GPIO_POWER_BUTTON_L GPIO_GSC_EC_PWR_BTN_ODL
+#define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL
+#define GPIO_WP_L GPIO_EC_WP_ODL
+#define GPIO_RECOVERY_L GPIO_EC_RECOVERY_BTN_OD
+#define GPIO_RECOVERY_L_2 GPIO_GSC_EC_RECOVERY_BTN_OD
+
+/* I2C Bus Configuration */
+
+#define I2C_PORT_DP_REDRIVER NPCX_I2C_PORT0_0
+
+#define I2C_PORT_USB_C0_C2_TCPC NPCX_I2C_PORT1_0
+#define I2C_PORT_USB_C1_TCPC NPCX_I2C_PORT4_1
+
+#define I2C_PORT_USB_C0_C2_PPC NPCX_I2C_PORT2_0
+#define I2C_PORT_USB_C1_PPC NPCX_I2C_PORT6_1
+
+#define I2C_PORT_USB_C0_C2_BC12 NPCX_I2C_PORT2_0
+#define I2C_PORT_USB_C1_BC12 NPCX_I2C_PORT6_1
+
+#define I2C_PORT_USB_C0_C2_MUX NPCX_I2C_PORT3_0
+#define I2C_PORT_USB_C1_MUX NPCX_I2C_PORT6_1
+
+#define I2C_PORT_QI NPCX_I2C_PORT5_0
+#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0
+#define I2C_PORT_MP2964 NPCX_I2C_PORT7_0
+
+#define I2C_ADDR_EEPROM_FLAGS 0x50
+
+#define I2C_ADDR_MP2964_FLAGS 0x20
+
+#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x58
+#define USBC_PORT_C2_BB_RETIMER_I2C_ADDR 0x59
+
+/* Enabling Thunderbolt-compatible mode */
+#define CONFIG_USB_PD_TBT_COMPAT_MODE
+
+/* Enabling USB4 mode */
+#define CONFIG_USB_PD_USB4
+#define CONFIG_USB_PD_DATA_RESET_MSG
+
+/* Retimer */
+#define CONFIG_USBC_RETIMER_FW_UPDATE
+
+/* Thermal features */
+#define CONFIG_THERMISTOR
+#define CONFIG_TEMP_SENSOR
+#define CONFIG_TEMP_SENSOR_POWER
+#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B
+
+/* ADC */
+#define CONFIG_ADC
+
+/*
+ * TODO(b/197478860): Enable the fan control. We need
+ * to check the sensor value and adjust the fan speed.
+ */
+#define CONFIG_FANS FAN_CH_COUNT
+
+/* Include math_util for bitmask_uint64 used in pd_timers */
+#define CONFIG_MATH_UTIL
+
+/* WPC/Qi charger */
+#ifdef SECTION_IS_RW
+#define CONFIG_PERIPHERAL_CHARGER
+#define CONFIG_CPS8100
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include "gpio_signal.h" /* needed by registers.h */
+#include "registers.h"
+#include "usbc_config.h"
+
+enum charge_port {
+ CHARGE_PORT_TYPEC0,
+ CHARGE_PORT_TYPEC1,
+ CHARGE_PORT_TYPEC2,
+ CHARGE_PORT_BARRELJACK,
+ CHARGE_PORT_ENUM_COUNT
+};
+
+enum adc_channel {
+ ADC_TEMP_SENSOR_1_CPU,
+ ADC_TEMP_SENSOR_2_CPU_VR,
+ ADC_TEMP_SENSOR_3_WIFI,
+ ADC_TEMP_SENSOR_4_DIMM,
+ ADC_VBUS,
+ ADC_PPVAR_IMON, /* ADC3 */
+ ADC_CH_COUNT
+};
+
+enum temp_sensor_id {
+ TEMP_SENSOR_1_CPU,
+ TEMP_SENSOR_2_CPU_VR,
+ TEMP_SENSOR_3_WIFI,
+ TEMP_SENSOR_4_DIMM,
+ TEMP_SENSOR_COUNT
+};
+
+enum ioex_port { IOEX_C0_NCT38XX = 0, IOEX_C2_NCT38XX, IOEX_PORT_COUNT };
+
+enum pwm_channel {
+ PWM_CH_LED_GREEN, /* PWM0 */
+ PWM_CH_FAN, /* PWM5 */
+ PWM_CH_LED_RED, /* PWM2 */
+ PWM_CH_COUNT
+};
+
+enum fan_channel { FAN_CH_0 = 0, FAN_CH_COUNT };
+
+enum mft_channel { MFT_CH_0 = 0, MFT_CH_COUNT };
+
+extern void adp_connect_interrupt(enum gpio_signal signal);
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* __CROS_EC_BOARD_H */
diff --git a/board/constitution/build.mk b/board/constitution/build.mk
new file mode 100644
index 0000000000..2301983a1f
--- /dev/null
+++ b/board/constitution/build.mk
@@ -0,0 +1,22 @@
+# -*- makefile -*-
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Brask board specific files build
+#
+
+CHIP:=npcx
+CHIP_FAMILY:=npcx9
+CHIP_VARIANT:=npcx9m3f
+BASEBOARD:=brask
+
+board-y=
+board-y+=board.o
+board-y+=fans.o
+board-y+=fw_config.o
+board-y+=i2c.o
+board-y+=led.o
+board-y+=pwm.o
+board-y+=sensors.o
+board-y+=usbc_config.o
diff --git a/board/constitution/ec.tasklist b/board/constitution/ec.tasklist
new file mode 100644
index 0000000000..8db6ebf7a3
--- /dev/null
+++ b/board/constitution/ec.tasklist
@@ -0,0 +1,29 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * See CONFIG_TASK_LIST in config.h for details.
+ *
+ * USB_CHG_Px tasks must be contiguous (see USB_CHG_PORT_TO_TASK_ID(x)).
+ * PD_Cx tasks must be contiguous (see PD_PORT_TO_TASK_ID(x))
+ */
+
+#define CONFIG_TASK_LIST \
+ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS_RW(PCHG, pchg_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_CHG_P2, usb_charger_task, 0, TASK_STACK_SIZE) \
+ TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(USB_MUX, usb_mux_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(POWERBTN, power_button_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_C2, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_INT_C0, pd_shared_alert_task, (BIT(2) | BIT(0)), LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CEC, cec_task, NULL, LARGER_TASK_STACK_SIZE)
diff --git a/board/constitution/fans.c b/board/constitution/fans.c
new file mode 100644
index 0000000000..ecc93bd330
--- /dev/null
+++ b/board/constitution/fans.c
@@ -0,0 +1,50 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Physical fans. These are logically separate from pwm_channels. */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "fan.h"
+#include "fan_chip.h"
+#include "hooks.h"
+#include "pwm.h"
+
+/* MFT channels. These are logically separate from pwm_channels. */
+const struct mft_t mft_channels[] = {
+ [MFT_CH_0] = {
+ .module = NPCX_MFT_MODULE_2,
+ .clk_src = TCKC_LFCLK,
+ .pwm_id = PWM_CH_FAN,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT);
+
+static const struct fan_conf fan_conf_0 = {
+ .flags = FAN_USE_RPM_MODE,
+ .ch = MFT_CH_0, /* Use MFT id to control fan */
+ .pgood_gpio = -1,
+ .enable_gpio = GPIO_EN_PP5000_FAN,
+};
+
+/*
+ * TOOD(b/197478860): need to update for real fan
+ *
+ * Prototype fan spins at about 7200 RPM at 100% PWM.
+ * Set minimum at around 30% PWM.
+ */
+static const struct fan_rpm fan_rpm_0 = {
+ .rpm_min = 2200,
+ .rpm_start = 2200,
+ .rpm_max = 7200,
+};
+
+const struct fan_t fans[FAN_CH_COUNT] = {
+ [FAN_CH_0] = {
+ .conf = &fan_conf_0,
+ .rpm = &fan_rpm_0,
+ },
+};
diff --git a/board/constitution/fw_config.c b/board/constitution/fw_config.c
new file mode 100644
index 0000000000..957a5c8c50
--- /dev/null
+++ b/board/constitution/fw_config.c
@@ -0,0 +1,65 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "cbi.h"
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "cros_board_info.h"
+#include "fw_config.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args)
+
+static union brask_cbi_fw_config fw_config;
+BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t));
+
+/*
+ * FW_CONFIG defaults for brask if the CBI.FW_CONFIG data is not
+ * initialized.
+ */
+static const union brask_cbi_fw_config fw_config_defaults = {
+ .audio = DB_NAU88L25B_I2S,
+ .bj_power = BJ_135W,
+};
+
+/*
+ * Barrel-jack power adapter ratings.
+ */
+static const struct {
+ int voltage;
+ int current;
+} bj_power[] = {
+ [BJ_135W] = { /* 0 - 135W (also default) */
+ .voltage = 19500,
+ .current = 6920
+ },
+ [BJ_230W] = { /* 1 - 230W */
+ .voltage = 19500,
+ .current = 11800
+ }
+};
+
+/****************************************************************************
+ * Brask FW_CONFIG access
+ */
+void board_init_fw_config(void)
+{
+ if (cbi_get_fw_config(&fw_config.raw_value)) {
+ CPRINTS("CBI: Read FW_CONFIG failed, using board defaults");
+ fw_config = fw_config_defaults;
+ }
+}
+
+void ec_bj_power(uint32_t *voltage, uint32_t *current)
+{
+ unsigned int bj;
+
+ bj = fw_config.bj_power;
+ /* Out of range value defaults to 0 */
+ if (bj >= ARRAY_SIZE(bj_power))
+ bj = 0;
+ *voltage = bj_power[bj].voltage;
+ *current = bj_power[bj].current;
+}
diff --git a/board/constitution/fw_config.h b/board/constitution/fw_config.h
new file mode 100644
index 0000000000..c2afd4c603
--- /dev/null
+++ b/board/constitution/fw_config.h
@@ -0,0 +1,41 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __BOARD_BRASK_FW_CONFIG_H_
+#define __BOARD_BRASK_FW_CONFIG_H_
+
+#include <stdint.h>
+
+/****************************************************************************
+ * CBI FW_CONFIG layout for Brask board.
+ *
+ * Source of truth is the project/brask/brask/config.star configuration file.
+ */
+enum ec_cfg_audio_type { DB_AUDIO_UNKNOWN = 0, DB_NAU88L25B_I2S = 1 };
+
+enum ec_cfg_bj_power { BJ_135W = 0, BJ_230W = 1 };
+
+union brask_cbi_fw_config {
+ struct {
+ uint32_t audio : 3;
+ uint32_t bj_power : 2;
+ uint32_t reserved_1 : 27;
+ };
+ uint32_t raw_value;
+};
+
+/**
+ * Read the cached FW_CONFIG. Guaranteed to have valid values.
+ *
+ * @return the FW_CONFIG for the board.
+ */
+union brask_cbi_fw_config get_fw_config(void);
+
+/**
+ * Get the barrel-jack power from FW_CONFIG.
+ */
+void ec_bj_power(uint32_t *voltage, uint32_t *current);
+
+#endif /* __BOARD_BRASK_FW_CONFIG_H_ */
diff --git a/board/constitution/gpio.inc b/board/constitution/gpio.inc
new file mode 100644
index 0000000000..59282f81aa
--- /dev/null
+++ b/board/constitution/gpio.inc
@@ -0,0 +1,187 @@
+/* -*- mode:c -*-
+ *
+ * Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* INTERRUPT GPIOs: */
+
+GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH, extpower_interrupt)
+GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt)
+GPIO_INT(EC_WP_ODL, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt)
+GPIO_INT(GSC_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH, power_button_interrupt)
+GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SEQ_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SEQ_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SLP_SUS_L, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(SYS_SLP_S0IX_L, PIN(D, 5), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(USB_C0_BC12_INT_ODL, PIN(C, 6), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C0_C2_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, tcpc_alert_event)
+GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C0_RT_INT_ODL, PIN(B, 1), GPIO_INT_FALLING, retimer_interrupt)
+GPIO_INT(USB_C1_BC12_INT_ODL, PIN(5, 0), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C1_PPC_INT_ODL, PIN(F, 5), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert_event)
+GPIO_INT(USB_C2_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt)
+GPIO_INT(USB_C2_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt)
+GPIO_INT(USB_C2_RT_INT_ODL, PIN(4, 1), GPIO_INT_FALLING, retimer_interrupt)
+GPIO_INT(BJ_ADP_PRESENT_ODL, PIN(8, 2), GPIO_INT_BOTH | GPIO_PULL_UP, adp_connect_interrupt)
+GPIO_INT(EC_RECOVERY_BTN_OD, PIN(2, 3), GPIO_INT_BOTH, button_interrupt)
+GPIO_INT(HDMI_CONN_OC_ODL, PIN(2, 4), GPIO_INPUT | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A0_OC_ODL, PIN(3, 1), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A1_OC_ODL, PIN(3, 0), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A2_OC_ODL, PIN(2, 7), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+GPIO_INT(USB_A3_OC_ODL, PIN(2, 6), GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH, port_ocp_interrupt)
+#ifdef SECTION_IS_RW
+GPIO_INT(QI_INT_ODL, PIN(9, 6), GPIO_INT_FALLING, pchg_irq)
+#else
+UNIMPLEMENTED(QI_INT_ODL)
+#endif
+
+/* CCD */
+GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT)
+
+/* Security */
+GPIO(EC_ENTERING_RW, PIN(0, 3), GPIO_OUT_LOW)
+GPIO(EC_GSC_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW)
+
+/* Fan */
+GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH)
+
+/* ADC, need to check the usage */
+GPIO(ANALOG_PPVAR_PWR_IN_IMON_EC, PIN(4, 2), GPIO_INPUT)
+
+/* Display */
+GPIO(DP_CONN_OC_ODL, PIN(2, 5), GPIO_INPUT)
+
+
+/* BarrelJack */
+GPIO(EN_PPVAR_BJ_ADP_L, PIN(0, 7), GPIO_OUT_LOW)
+
+/* Chipset PCH */
+GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT)
+GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH)
+GPIO(EC_PCH_RSMRST_L, PIN(A, 6), GPIO_OUT_LOW)
+GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW)
+GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW)
+GPIO(EC_PCH_WAKE_ODL, PIN(C, 0), GPIO_ODR_HIGH)
+GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH)
+GPIO(EN_S5_RAILS, PIN(B, 6), GPIO_OUT_LOW)
+GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW)
+GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
+GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW)
+GPIO(IMVP9_VRRDY_OD, PIN(6, 0), GPIO_INPUT)
+GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT)
+
+/* Button */
+GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH)
+GPIO(GSC_EC_RECOVERY_BTN_OD, PIN(2, 2), GPIO_INPUT)
+
+/* NFC */
+/* TODO(b/194068530): Enable NFC */
+GPIO(NFC_COIL_ACT_L, PIN(D, 4), GPIO_INPUT)
+GPIO(NFC_LOW_POWER_MODE, PIN(9, 5), GPIO_OUT_HIGH)
+GPIO(NFC_CARD_DET_L, PIN(A, 3), GPIO_INPUT)
+GPIO(EN_NFC_BUZZER, PIN(0, 5), GPIO_OUT_LOW)
+
+/* Wireless Charger */
+GPIO(EC_QI_PWR, PIN(D, 2), GPIO_OUT_LOW)
+GPIO(QI_RESET_L, PIN(9, 3), GPIO_OUT_HIGH)
+
+/* HDMI CEC */
+/* TODO(b/197474873): Enable HDMI CEC */
+GPIO(HDMI_CEC_IN, PIN(4, 0), GPIO_INPUT)
+GPIO(HDMI_CEC_OUT, PIN(D, 3), GPIO_OUT_HIGH | GPIO_OPEN_DRAIN)
+GPIO(HDMI_CEC_PULL_UP, PIN(C, 2), GPIO_OUT_HIGH)
+
+/* I2C SCL/SDA */
+GPIO(EC_I2C_QI_SCL, PIN(3, 3), GPIO_INPUT)
+GPIO(EC_I2C_QI_SDA, PIN(3, 6), GPIO_INPUT)
+GPIO(EC_I2C_MISC_SCL_R, PIN(B, 3), GPIO_INPUT)
+GPIO(EC_I2C_MISC_SDA_R, PIN(B, 2), GPIO_INPUT)
+GPIO(EC_I2C_DP_SCL, PIN(B, 5), GPIO_INPUT)
+GPIO(EC_I2C_DP_SDA, PIN(B, 4), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_PPC_SCL, PIN(9, 2), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_PPC_SDA, PIN(9, 1), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_RT_SCL, PIN(D, 1), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_RT_SDA, PIN(D, 0), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_TCPC_SCL, PIN(9, 0), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_C2_TCPC_SDA, PIN(8, 7), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_MIX_SCL, PIN(E, 4), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_MIX_SDA, PIN(E, 3), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_TCPC_SCL, PIN(F, 3), GPIO_INPUT)
+GPIO(EC_I2C_USB_C1_TCPC_SDA, PIN(F, 2), GPIO_INPUT)
+
+/* USBA */
+GPIO(EN_PP5000_USBA, PIN(D, 7), GPIO_OUT_LOW)
+GPIO(USB_A0_STATUS_L, PIN(2, 1), GPIO_INPUT)
+GPIO(USB_A1_STATUS_L, PIN(2, 0), GPIO_INPUT)
+GPIO(USB_A2_STATUS_L, PIN(1, 7), GPIO_INPUT)
+GPIO(USB_A3_STATUS_L, PIN(1, 6), GPIO_INPUT)
+GPIO(USB_A_LOW_PWR0_OD, PIN(1, 5), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR1_OD, PIN(1, 4), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR2_OD, PIN(1, 1), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_LOW_PWR3_OD, PIN(1, 0), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(USB_A_OC_SOC_L, PIN(8, 0), GPIO_OUT_HIGH)
+
+/* LED */
+/* TODO(b/197471359): LED implementation */
+GPIO(LED_GREEN_L, PIN(C, 3), GPIO_OUT_LOW)
+GPIO(LED_RED_L, PIN(C, 4), GPIO_OUT_LOW)
+
+/* USBC */
+GPIO(USB_C0_C2_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
+GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW)
+GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT)
+GPIO(USB_C1_RT_RST_R_L, PIN(0, 2), GPIO_OUT_LOW)
+
+/* GPIO02_P2 to PU */
+/* GPIO03_P2 to PU */
+IOEX(USB_C0_OC_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 4), GPIO_ODR_HIGH)
+IOEX(USB_C0_FRS_EN, EXPIN(IOEX_C0_NCT38XX, 0, 6), GPIO_LOW)
+IOEX(USB_C0_RT_RST_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 7), GPIO_ODR_LOW)
+
+IOEX(USB_C2_RT_RST_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 2), GPIO_ODR_LOW)
+IOEX(USB_C1_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 3), GPIO_ODR_HIGH)
+IOEX(USB_C2_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 4), GPIO_ODR_HIGH)
+IOEX(USB_C2_FRS_EN, EXPIN(IOEX_C2_NCT38XX, 0, 6), GPIO_LOW)
+/* GPIO07_P2 to PU */
+
+/* UART alternate functions */
+ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* GPIO64/CR_SIN1, GPO65/CR_SOUT1/FLPRG1_L */
+
+/* I2C alternate functions */
+ALTERNATE(PIN_MASK(3, 0x48), 0, MODULE_I2C, 0) /* GPIO33/I2C5_SCL0/CTS_L, GPIO36/RTS_L/I2C5_SDA0 */
+ALTERNATE(PIN_MASK(8, 0x80), 0, MODULE_I2C, 0) /* GPIO87/I2C1_SDA0 */
+ALTERNATE(PIN_MASK(9, 0x07), 0, MODULE_I2C, 0) /* GPIO92/I2C2_SCL0, GPIO91/I2C2_SDA0, GPIO90/I2C1_SCL0 */
+ALTERNATE(PIN_MASK(B, 0x0c), 0, MODULE_I2C, 0) /* GPIOB3/I2C7_SCL0/DCD_L, GPIOB2/I2C7_SDA0/DSR_L */
+ALTERNATE(PIN_MASK(B, 0x30), 0, MODULE_I2C, 0) /* GPIOB5/I2C0_SCL0, GPIOB4/I2C0_SDA0 */
+ALTERNATE(PIN_MASK(D, 0x03), 0, MODULE_I2C, 0) /* GPIOD1/I2C3_SCL0, GPIOD0/I2C3_SDA0 */
+ALTERNATE(PIN_MASK(E, 0x18), 0, MODULE_I2C, 0) /* GPIOE4/I2C6_SCL1/I3C_SCL, GPIOE3/I2C6_SDA1/I3C_SDA */
+ALTERNATE(PIN_MASK(F, 0x0c), 0, MODULE_I2C, 0) /* GPIOF3/I2C4_SCL1, GPIOF2/I2C4_SDA1 */
+
+/* PWM alternate functions */
+ALTERNATE(PIN_MASK(7, 0x08), 0, MODULE_PWM, 0) /* GPIO73/TA2 */
+ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */
+ALTERNATE(PIN_MASK(C, 0x18), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0 */
+
+/* ADC alternate functions */
+ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */
+ALTERNATE(PIN_MASK(4, 0x38), 0, MODULE_ADC, 0) /* GPIO45/ADC0, GPIO44/ADC1, GPIO43/ADC2 */
+ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */
+
+/* Unused Pins */
+UNUSED(PIN(D, 6)) /* GPOD6/CR_SOUT3/SHDF_ESPI_L */
+UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */
+UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */
+UNUSED(PIN(6, 6)) /* GPIO66 */
+UNUSED(PIN(8, 1)) /* GPIO81/PECI_DATA */
+UNUSED(PIN(5, 6)) /* GPIO56/CLKRUN# */
+UNUSED(PIN(9, 7)) /* GPIO97 */
+UNUSED(PIN(8, 6)) /* GPIO86/TXD/CR_SOUT2 */
+UNUSED(PIN(1, 3)) /* KSO06/GPO13/GP_SEL# */
+UNUSED(PIN(1, 2)) /* KSO07/GPO12/JEN# */
+UNUSED(PIN(0, 6)) /* KSO11/GPIO06/P80_CLK */
+UNUSED(PIN(0, 4)) /* KSO13/GPIO04 */
diff --git a/board/constitution/i2c.c b/board/constitution/i2c.c
new file mode 100644
index 0000000000..a637f03717
--- /dev/null
+++ b/board/constitution/i2c.c
@@ -0,0 +1,77 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "i2c.h"
+
+/* I2C port map configuration */
+const struct i2c_port_t i2c_ports[] = {
+ {
+ /* I2C0 */
+ .name = "dp_redriver",
+ .port = I2C_PORT_DP_REDRIVER,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_DP_SCL,
+ .sda = GPIO_EC_I2C_DP_SDA,
+ },
+ {
+ /* I2C1 */
+ .name = "tcpc0,2",
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_TCPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_TCPC_SDA,
+ },
+ {
+ /* I2C2 */
+ .name = "ppc0,2",
+ .port = I2C_PORT_USB_C0_C2_PPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_PPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_PPC_SDA,
+ },
+ {
+ /* I2C3 */
+ .name = "retimer0,2",
+ .port = I2C_PORT_USB_C0_C2_MUX,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_C2_RT_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_C2_RT_SDA,
+ },
+ {
+ /* I2C4 C1 TCPC */
+ .name = "tcpc1",
+ .port = I2C_PORT_USB_C1_TCPC,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA,
+ },
+ {
+ /* I2C5 */
+ .name = "wireless_charger",
+ .port = I2C_PORT_QI,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_QI_SCL,
+ .sda = GPIO_EC_I2C_QI_SDA,
+ },
+ {
+ /* I2C6 */
+ .name = "ppc1",
+ .port = I2C_PORT_USB_C1_PPC,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C1_MIX_SCL,
+ .sda = GPIO_EC_I2C_USB_C1_MIX_SDA,
+ },
+ {
+ /* I2C7 */
+ .name = "eeprom",
+ .port = I2C_PORT_EEPROM,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_MISC_SCL_R,
+ .sda = GPIO_EC_I2C_MISC_SDA_R,
+ },
+};
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
diff --git a/board/constitution/led.c b/board/constitution/led.c
new file mode 100644
index 0000000000..a8c725258b
--- /dev/null
+++ b/board/constitution/led.c
@@ -0,0 +1,260 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Power LED control for Brask.
+ * Solid green - active power
+ * Green flashing - suspended
+ * Red flashing - alert
+ * Solid red - critical
+ */
+
+#include "chipset.h"
+#include "console.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "led_common.h"
+#include "pwm.h"
+#include "timer.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_GPIO, format, ##args)
+
+/*
+ * Due to the CSME-Lite processing, upon startup the CPU transitions through
+ * S0->S3->S5->S3->S0, causing the LED to turn on/off/on, so
+ * delay turning off the LED during suspend/shutdown.
+ */
+#define LED_CPU_DELAY_MS (2000 * MSEC)
+
+const enum ec_led_id supported_led_ids[] = { EC_LED_ID_POWER_LED };
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+
+enum led_color {
+ LED_OFF = 0,
+ LED_RED,
+ LED_GREEN,
+
+ /* Number of colors, not a color itself */
+ LED_COLOR_COUNT
+};
+
+static int set_color_power(enum led_color color, int duty)
+{
+ int green = 0;
+ int red = 0;
+
+ if (duty < 0 || 100 < duty)
+ return EC_ERROR_UNKNOWN;
+
+ switch (color) {
+ case LED_OFF:
+ break;
+ case LED_GREEN:
+ green = 1;
+ break;
+ case LED_RED:
+ red = 1;
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+
+ if (red)
+ pwm_set_duty(PWM_CH_LED_RED, duty);
+ else
+ pwm_set_duty(PWM_CH_LED_RED, 0);
+
+ if (green)
+ pwm_set_duty(PWM_CH_LED_GREEN, duty);
+ else
+ pwm_set_duty(PWM_CH_LED_GREEN, 0);
+
+ return EC_SUCCESS;
+}
+
+static int set_color(enum ec_led_id id, enum led_color color, int duty)
+{
+ switch (id) {
+ case EC_LED_ID_POWER_LED:
+ return set_color_power(color, duty);
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+}
+
+#define LED_PULSE_US (2 * SECOND)
+/* 40 msec for nice and smooth transition. */
+#define LED_PULSE_TICK_US (40 * MSEC)
+
+/*
+ * When pulsing is enabled, brightness is incremented by <duty_inc> every
+ * <interval> usec from 0 to 100% in LED_PULSE_US usec. Then it's decremented
+ * likewise in LED_PULSE_US usec.
+ */
+static struct {
+ uint32_t interval;
+ int duty_inc;
+ enum led_color color;
+ int duty;
+} led_pulse;
+
+#define CONFIG_TICK(interval, color) \
+ config_tick((interval), 100 / (LED_PULSE_US / (interval)), (color))
+
+static void config_tick(uint32_t interval, int duty_inc, enum led_color color)
+{
+ led_pulse.interval = interval;
+ led_pulse.duty_inc = duty_inc;
+ led_pulse.color = color;
+ led_pulse.duty = 0;
+}
+
+static void pulse_power_led(enum led_color color)
+{
+ set_color(EC_LED_ID_POWER_LED, color, led_pulse.duty);
+ if (led_pulse.duty + led_pulse.duty_inc > 100)
+ led_pulse.duty_inc = led_pulse.duty_inc * -1;
+ else if (led_pulse.duty + led_pulse.duty_inc < 0)
+ led_pulse.duty_inc = led_pulse.duty_inc * -1;
+ led_pulse.duty += led_pulse.duty_inc;
+}
+
+static void led_tick(void);
+DECLARE_DEFERRED(led_tick);
+static void led_tick(void)
+{
+ uint32_t elapsed;
+ uint32_t next = 0;
+ uint32_t start = get_time().le.lo;
+
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ pulse_power_led(led_pulse.color);
+ elapsed = get_time().le.lo - start;
+ next = led_pulse.interval > elapsed ? led_pulse.interval - elapsed : 0;
+ hook_call_deferred(&led_tick_data, next);
+}
+
+static void led_suspend(void)
+{
+ CONFIG_TICK(LED_PULSE_TICK_US, LED_GREEN);
+ led_tick();
+}
+DECLARE_DEFERRED(led_suspend);
+
+static void led_shutdown(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_OFF, 0);
+}
+DECLARE_DEFERRED(led_shutdown);
+
+static void led_shutdown_hook(void)
+{
+ hook_call_deferred(&led_tick_data, -1);
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, led_shutdown_hook, HOOK_PRIO_DEFAULT);
+
+static void led_suspend_hook(void)
+{
+ hook_call_deferred(&led_shutdown_data, -1);
+ hook_call_deferred(&led_suspend_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, led_suspend_hook, HOOK_PRIO_DEFAULT);
+
+static void led_resume(void)
+{
+ /*
+ * Assume there is no race condition with led_tick, which also
+ * runs in hook_task.
+ */
+ hook_call_deferred(&led_tick_data, -1);
+ /*
+ * Avoid invoking the suspend/shutdown delayed hooks.
+ */
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, -1);
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_GREEN, 100);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, led_resume, HOOK_PRIO_DEFAULT);
+
+void led_alert(int enable)
+{
+ if (enable) {
+ /* Overwrite the current signal */
+ config_tick(1 * SECOND, 100, LED_RED);
+ led_tick();
+ } else {
+ /* Restore the previous signal */
+ if (chipset_in_state(CHIPSET_STATE_ON))
+ led_resume();
+ else if (chipset_in_state(CHIPSET_STATE_SUSPEND))
+ led_suspend_hook();
+ else if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ led_shutdown_hook();
+ }
+}
+
+void show_critical_error(void)
+{
+ hook_call_deferred(&led_tick_data, -1);
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ set_color(EC_LED_ID_POWER_LED, LED_RED, 100);
+}
+
+static int command_led(int argc, const char **argv)
+{
+ enum ec_led_id id = EC_LED_ID_POWER_LED;
+
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+
+ if (!strcasecmp(argv[1], "debug")) {
+ led_auto_control(id, !led_auto_control_is_enabled(id));
+ ccprintf("o%s\n", led_auto_control_is_enabled(id) ? "ff" : "n");
+ } else if (!strcasecmp(argv[1], "off")) {
+ set_color(id, LED_OFF, 0);
+ } else if (!strcasecmp(argv[1], "red")) {
+ set_color(id, LED_RED, 100);
+ } else if (!strcasecmp(argv[1], "green")) {
+ set_color(id, LED_GREEN, 100);
+ } else if (!strcasecmp(argv[1], "alert")) {
+ led_alert(1);
+ } else if (!strcasecmp(argv[1], "crit")) {
+ show_critical_error();
+ } else {
+ return EC_ERROR_PARAM1;
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(led, command_led, "[debug|red|green|off|alert|crit]",
+ "Turn on/off LED.");
+
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ brightness_range[EC_LED_COLOR_RED] = 100;
+ brightness_range[EC_LED_COLOR_GREEN] = 100;
+}
+
+int led_set_brightness(enum ec_led_id id, const uint8_t *brightness)
+{
+ if (brightness[EC_LED_COLOR_RED])
+ return set_color(id, LED_RED, brightness[EC_LED_COLOR_RED]);
+ else if (brightness[EC_LED_COLOR_GREEN])
+ return set_color(id, LED_GREEN, brightness[EC_LED_COLOR_GREEN]);
+ else
+ return set_color(id, LED_OFF, 0);
+}
+__override void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ /* Blink alert if insufficient power per system_can_boot_ap(). */
+ int insufficient_power =
+ (charge_ma * charge_mv) <
+ (CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON * 1000);
+ led_alert(insufficient_power);
+}
diff --git a/board/constitution/pwm.c b/board/constitution/pwm.c
new file mode 100644
index 0000000000..a53243ca5a
--- /dev/null
+++ b/board/constitution/pwm.c
@@ -0,0 +1,39 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "hooks.h"
+#include "pwm.h"
+#include "pwm_chip.h"
+
+const struct pwm_t pwm_channels[] = {
+ [PWM_CH_LED_GREEN] = { .channel = 0,
+ .flags = PWM_CONFIG_ACTIVE_LOW |
+ PWM_CONFIG_DSLEEP,
+ .freq = 2000 },
+ [PWM_CH_FAN] = { .channel = 5,
+ .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP,
+ .freq = 1000 },
+ [PWM_CH_LED_RED] = { .channel = 2,
+ .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
+ .freq = 2000 },
+};
+BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+
+static void board_pwm_init(void)
+{
+ /*
+ * TODO(b/197478860): Turn on the fan at 100% by default
+ * We need to find tune the fan speed according to the
+ * thermal sensor value.
+ */
+ pwm_enable(PWM_CH_FAN, 1);
+ pwm_set_duty(PWM_CH_FAN, 100);
+
+ pwm_enable(PWM_CH_LED_RED, 1);
+ pwm_enable(PWM_CH_LED_GREEN, 1);
+}
+DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT);
diff --git a/board/constitution/sensors.c b/board/constitution/sensors.c
new file mode 100644
index 0000000000..211faace1c
--- /dev/null
+++ b/board/constitution/sensors.c
@@ -0,0 +1,114 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "adc_chip.h"
+#include "common.h"
+#include "hooks.h"
+#include "temp_sensor.h"
+#include "temp_sensor/thermistor.h"
+#include "thermal.h"
+
+/* ADC configuration */
+const struct adc_t adc_channels[] = {
+ [ADC_TEMP_SENSOR_1_CPU] = {
+ .name = "TEMP_CPU",
+ .input_ch = NPCX_ADC_CH0,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_2_CPU_VR] = {
+ .name = "TEMP_CPU_VR",
+ .input_ch = NPCX_ADC_CH1,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_3_WIFI] = {
+ .name = "TEMP_WIFI",
+ .input_ch = NPCX_ADC_CH6,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_TEMP_SENSOR_4_DIMM] = {
+ .name = "TEMP_DIMM",
+ .input_ch = NPCX_ADC_CH7,
+ .factor_mul = ADC_MAX_VOLT,
+ .factor_div = ADC_READ_MAX + 1,
+ .shift = 0,
+ },
+ [ADC_VBUS] = { /* 5/39 voltage divider */
+ .name = "VBUS",
+ .input_ch = NPCX_ADC_CH2,
+ .factor_mul = ADC_MAX_VOLT * 39,
+ .factor_div = (ADC_READ_MAX + 1) * 5,
+ },
+ [ADC_PPVAR_IMON] = { /* 872.3 mV/A */
+ .name = "PPVAR_IMON",
+ .input_ch = NPCX_ADC_CH3,
+ .factor_mul = ADC_MAX_VOLT * 1433,
+ .factor_div = (ADC_READ_MAX + 1) * 1250,
+ },
+
+};
+BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
+
+/* Temperature sensor configuration */
+const struct temp_sensor_t temp_sensors[] = {
+ [TEMP_SENSOR_1_CPU] = { .name = "CPU",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_1_CPU },
+ [TEMP_SENSOR_2_CPU_VR] = { .name = "CPU VR",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_2_CPU_VR },
+ [TEMP_SENSOR_3_WIFI] = { .name = "WIFI",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_3_WIFI },
+ [TEMP_SENSOR_4_DIMM] = { .name = "DIMM",
+ .type = TEMP_SENSOR_TYPE_BOARD,
+ .read = get_temp_3v3_30k9_47k_4050b,
+ .idx = ADC_TEMP_SENSOR_4_DIMM },
+};
+BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
+
+/*
+ * TODO(b/180681346): update for Alder Lake/brya
+ *
+ * Tiger Lake specifies 100 C as maximum TDP temperature. THRMTRIP# occurs at
+ * 130 C. However, sensor is located next to DDR, so we need to use the lower
+ * DDR temperature limit (85 C)
+ */
+/*
+ * TODO(b/202062363): Remove when clang is fixed.
+ */
+#define THERMAL_CPU \
+ { \
+ .temp_host = { \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \
+ [EC_TEMP_THRESH_HALT] = C_TO_K(80), \
+ }, \
+ .temp_host_release = { \
+ [EC_TEMP_THRESH_HIGH] = C_TO_K(65), \
+ }, \
+ .temp_fan_off = C_TO_K(35), \
+ .temp_fan_max = C_TO_K(50), \
+ }
+__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU;
+
+/*
+ * TODO(b/197478860): add the thermal sensor setting
+ */
+/* this should really be "const" */
+struct ec_thermal_config thermal_params[] = {
+ [TEMP_SENSOR_1_CPU] = THERMAL_CPU,
+ [TEMP_SENSOR_2_CPU_VR] = THERMAL_CPU,
+ [TEMP_SENSOR_3_WIFI] = THERMAL_CPU,
+ [TEMP_SENSOR_4_DIMM] = THERMAL_CPU,
+};
+BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);
diff --git a/board/constitution/usbc_config.c b/board/constitution/usbc_config.c
new file mode 100644
index 0000000000..a7a7cf682f
--- /dev/null
+++ b/board/constitution/usbc_config.c
@@ -0,0 +1,416 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "driver/bc12/pi3usb9201_public.h"
+#include "driver/ppc/syv682x_public.h"
+#include "driver/retimer/bb_retimer_public.h"
+#include "driver/retimer/kb800x.h"
+#include "driver/tcpm/nct38xx.h"
+#include "driver/tcpm/rt1715.h"
+#include "driver/tcpm/tcpci.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "gpio_signal.h"
+#include "hooks.h"
+#include "ioexpander.h"
+#include "system.h"
+#include "task.h"
+#include "task_id.h"
+#include "timer.h"
+#include "usb_charge.h"
+#include "usb_mux.h"
+#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
+#include "usbc_config.h"
+#include "usbc_ppc.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args)
+
+/* USBC TCPC configuration */
+const struct tcpc_config_t tcpc_config[] = {
+ [USBC_PORT_C0] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
+ },
+ .drv = &nct38xx_tcpm_drv,
+ .flags = TCPC_FLAGS_TCPCI_REV2_0 |
+ TCPC_FLAGS_NO_DEBUG_ACC_CONTROL,
+ },
+ [USBC_PORT_C1] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C1_TCPC,
+ .addr_flags = RT1715_I2C_ADDR_FLAGS,
+ },
+ .drv = &rt1715_tcpm_drv,
+ },
+ [USBC_PORT_C2] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0_C2_TCPC,
+ .addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
+ },
+ .drv = &nct38xx_tcpm_drv,
+ .flags = TCPC_FLAGS_TCPCI_REV2_0,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
+BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT);
+
+/* USBC PPC configuration */
+struct ppc_config_t ppc_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_PPC,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
+ .drv = &syv682x_drv,
+ },
+ [USBC_PORT_C1] = {
+ .i2c_port = I2C_PORT_USB_C1_PPC,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
+ .drv = &syv682x_drv,
+ },
+ [USBC_PORT_C2] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_PPC,
+ .i2c_addr_flags = SYV682X_ADDR2_FLAGS,
+ .drv = &syv682x_drv,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
+
+unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+
+/* USBC mux configuration - Alder Lake includes internal mux */
+static const struct usb_mux_chain usbc0_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C0,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+static const struct usb_mux_chain usbc1_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C1,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+static const struct usb_mux_chain usbc2_tcss_usb_mux = {
+ .mux =
+ &(const struct usb_mux){
+ .usb_port = USBC_PORT_C2,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
+ },
+};
+
+struct kb800x_control_t kb800x_control[] = {
+ [USBC_PORT_C0] = {
+ },
+ [USBC_PORT_C1] = {
+ .retimer_rst_gpio = GPIO_USB_C1_RT_RST_R_L,
+ .ss_lanes = {
+ [KB800X_A0] = KB800X_TX0, [KB800X_A1] = KB800X_RX0,
+ [KB800X_B0] = KB800X_RX1, [KB800X_B1] = KB800X_TX1,
+ [KB800X_C0] = KB800X_RX0, [KB800X_C1] = KB800X_TX0,
+ [KB800X_D0] = KB800X_TX1, [KB800X_D1] = KB800X_RX1,
+ }
+ },
+ [USBC_PORT_C2] = {
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(kb800x_control) == USBC_PORT_COUNT);
+
+const struct usb_mux_chain usb_muxes[] = {
+ [USBC_PORT_C0] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C0,
+ .driver = &bb_usb_retimer,
+ .hpd_update = bb_retimer_hpd_update,
+ .i2c_port = I2C_PORT_USB_C0_C2_MUX,
+ .i2c_addr_flags = USBC_PORT_C0_BB_RETIMER_I2C_ADDR,
+ },
+ .next = &usbc0_tcss_usb_mux,
+ },
+ [USBC_PORT_C1] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C1,
+ .driver = &kb800x_usb_mux_driver,
+ .i2c_port = I2C_PORT_USB_C1_MUX,
+ .i2c_addr_flags = KB800X_I2C_ADDR0_FLAGS,
+ },
+ .next = &usbc1_tcss_usb_mux,
+ },
+ [USBC_PORT_C2] = {
+ .mux = &(const struct usb_mux) {
+ .usb_port = USBC_PORT_C2,
+ .driver = &bb_usb_retimer,
+ .hpd_update = bb_retimer_hpd_update,
+ .i2c_port = I2C_PORT_USB_C0_C2_MUX,
+ .i2c_addr_flags = USBC_PORT_C2_BB_RETIMER_I2C_ADDR,
+ },
+ .next = &usbc2_tcss_usb_mux,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
+
+/* BC1.2 charger detect configuration */
+const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+ [USBC_PORT_C1] = {
+ .i2c_port = I2C_PORT_USB_C1_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
+ },
+ [USBC_PORT_C2] = {
+ .i2c_port = I2C_PORT_USB_C0_C2_BC12,
+ .i2c_addr_flags = PI3USB9201_I2C_ADDR_1_FLAGS,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT);
+
+/*
+ * USB C0 and C2 uses burnside bridge chips and have their reset
+ * controlled by their respective TCPC chips acting as GPIO expanders.
+ *
+ * ioex_init() is normally called before we take the TCPCs out of
+ * reset, so we need to start in disabled mode, then explicitly
+ * call ioex_init().
+ */
+
+struct ioexpander_config_t ioex_config[] = {
+ [IOEX_C0_NCT38XX] = {
+ .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
+ .i2c_addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
+ .drv = &nct38xx_ioexpander_drv,
+ .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
+ },
+ [IOEX_C2_NCT38XX] = {
+ .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
+ .i2c_addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
+ .drv = &nct38xx_ioexpander_drv,
+ .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ioex_config) == CONFIG_IO_EXPANDER_PORT_COUNT);
+
+__override int bb_retimer_power_enable(const struct usb_mux *me, bool enable)
+{
+ enum ioex_signal rst_signal;
+
+ if (me->usb_port == USBC_PORT_C0) {
+ rst_signal = IOEX_USB_C0_RT_RST_ODL;
+ } else if (me->usb_port == USBC_PORT_C2) {
+ rst_signal = IOEX_USB_C2_RT_RST_ODL;
+ } else {
+ return EC_ERROR_INVAL;
+ }
+
+ /*
+ * We do not have a load switch for the burnside bridge chips,
+ * so we only need to sequence reset.
+ */
+
+ if (enable) {
+ /*
+ * Tpw, minimum time from VCC to RESET_N de-assertion is 100us.
+ * For boards that don't provide a load switch control, the
+ * retimer_init() function ensures power is up before calling
+ * this function.
+ */
+ ioex_set_level(rst_signal, 1);
+ /*
+ * Allow 1ms time for the retimer to power up lc_domain
+ * which powers I2C controller within retimer
+ */
+ msleep(1);
+ } else {
+ ioex_set_level(rst_signal, 0);
+ msleep(1);
+ }
+ return EC_SUCCESS;
+}
+
+__override int bb_retimer_reset(const struct usb_mux *me)
+{
+ /*
+ * TODO(b/193402306, b/195375738): Remove this once transition to
+ * QS Silicon is complete
+ */
+ bb_retimer_power_enable(me, false);
+ msleep(5);
+ bb_retimer_power_enable(me, true);
+ msleep(25);
+
+ return EC_SUCCESS;
+}
+
+void board_reset_pd_mcu(void)
+{
+ enum gpio_signal tcpc_rst;
+
+ tcpc_rst = GPIO_USB_C0_C2_TCPC_RST_ODL;
+
+ /*
+ * TODO(b/179648104): figure out correct timing
+ */
+
+ gpio_set_level(tcpc_rst, 0);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 0);
+
+ /*
+ * delay for power-on to reset-off and min. assertion time
+ */
+
+ msleep(20);
+
+ gpio_set_level(tcpc_rst, 1);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 1);
+
+ /* wait for chips to come up */
+
+ msleep(50);
+}
+
+static void enable_ioex(int ioex)
+{
+ ioex_init(ioex);
+}
+
+static void board_tcpc_init(void)
+{
+ /* Don't reset TCPCs after initial reset */
+ if (!system_jumped_late()) {
+ board_reset_pd_mcu();
+
+ /*
+ * These IO expander pins are implemented using the
+ * C0/C2 TCPC, so they must be set up after the TCPC has
+ * been taken out of reset.
+ */
+ enable_ioex(IOEX_C0_NCT38XX);
+ enable_ioex(IOEX_C2_NCT38XX);
+ }
+
+ /* Enable PPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL);
+
+ /* Enable TCPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_C2_TCPC_INT_ODL);
+
+ gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET);
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ if (gpio_get_level(GPIO_USB_C0_C2_TCPC_INT_ODL) == 0)
+ status |= PD_STATUS_TCPC_ALERT_0 | PD_STATUS_TCPC_ALERT_2;
+
+ if (gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0)
+ status |= PD_STATUS_TCPC_ALERT_1;
+
+ return status;
+}
+
+int ppc_get_alert_status(int port)
+{
+ if (port == USBC_PORT_C0)
+ return gpio_get_level(GPIO_USB_C0_PPC_INT_ODL) == 0;
+ else if (port == USBC_PORT_C1)
+ return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0;
+ else if (port == USBC_PORT_C2)
+ return gpio_get_level(GPIO_USB_C2_PPC_INT_ODL) == 0;
+ return 0;
+}
+
+void tcpc_alert_event(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_C2_TCPC_INT_ODL:
+ schedule_deferred_pd_interrupt(USBC_PORT_C0);
+ break;
+ case GPIO_USB_C1_TCPC_INT_ODL:
+ schedule_deferred_pd_interrupt(USBC_PORT_C1);
+ break;
+ default:
+ break;
+ }
+}
+
+void bc12_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_BC12_INT_ODL:
+ usb_charger_task_set_event(0, USB_CHG_EVENT_BC12);
+ break;
+ case GPIO_USB_C1_BC12_INT_ODL:
+ usb_charger_task_set_event(1, USB_CHG_EVENT_BC12);
+ break;
+ case GPIO_USB_C2_BC12_INT_ODL:
+ usb_charger_task_set_event(2, USB_CHG_EVENT_BC12);
+ break;
+ default:
+ break;
+ }
+}
+
+void ppc_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C0);
+ break;
+ case GPIO_USB_C1_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C1);
+ break;
+ case GPIO_USB_C2_PPC_INT_ODL:
+ syv682x_interrupt(USBC_PORT_C2);
+ break;
+ default:
+ break;
+ }
+}
+
+void retimer_interrupt(enum gpio_signal signal)
+{
+ /*
+ * TODO(b/179513527): add USB-C support
+ */
+}
+
+__override bool board_is_dts_port(int port)
+{
+ return port == USBC_PORT_C0;
+}
+
+__override bool board_is_tbt_usb4_port(int port)
+{
+ return true;
+}
+
+__override enum tbt_compat_cable_speed board_get_max_tbt_speed(int port)
+{
+ if (!board_is_tbt_usb4_port(port))
+ return TBT_SS_RES_0;
+
+ return TBT_SS_TBT_GEN3;
+}
diff --git a/board/constitution/usbc_config.h b/board/constitution/usbc_config.h
new file mode 100644
index 0000000000..778ca51a0d
--- /dev/null
+++ b/board/constitution/usbc_config.h
@@ -0,0 +1,20 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Brya board-specific USB-C configuration */
+
+#ifndef __CROS_EC_USBC_CONFIG_H
+#define __CROS_EC_USBC_CONFIG_H
+
+#define CONFIG_USB_PD_PORT_MAX_COUNT 3
+
+enum usbc_port {
+ USBC_PORT_C0 = 0,
+ USBC_PORT_C1,
+ USBC_PORT_C2,
+ USBC_PORT_COUNT
+};
+
+#endif /* __CROS_EC_USBC_CONFIG_H */
diff --git a/board/constitution/vif_override.xml b/board/constitution/vif_override.xml
new file mode 100644
index 0000000000..32736caf64
--- /dev/null
+++ b/board/constitution/vif_override.xml
@@ -0,0 +1,3 @@
+<!-- Add VIF field overrides here. See genvif.c and the Vendor Info File
+ Definition from the USB-IF.
+-->
diff --git a/board/dibbi/board.c b/board/dibbi/board.c
index eee386a043..d3358eb2ff 100644
--- a/board/dibbi/board.c
+++ b/board/dibbi/board.c
@@ -6,10 +6,12 @@
/* Dibbi board-specific configuration */
#include "adc_chip.h"
+#include "board.h"
#include "button.h"
#include "charge_manager.h"
#include "charge_state_v2.h"
#include "charger.h"
+#include "driver/ppc/syv682x_public.h"
#include "driver/tcpm/it83xx_pd.h"
#include "driver/temp_sensor/thermistor.h"
#include "driver/usb_mux/it5205.h"
@@ -31,6 +33,7 @@
#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_tcpm.h"
+#include "usbc_ppc.h"
#define CPRINTUSB(format, args...) cprints(CC_USBCHARGE, format, ##args)
@@ -72,6 +75,19 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
+/* PPCs */
+struct ppc_config_t ppc_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0,
+ .i2c_addr_flags = SYV682X_ADDR0_FLAGS,
+ .frs_en = GPIO_EC_USB_C0_FRS_EN,
+ .drv = &syv682x_drv,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
+
+unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+
/* USB Muxes */
const struct usb_mux_chain usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
@@ -90,6 +106,7 @@ const int usb_port_enable[USB_PORT_COUNT] = {
GPIO_EN_USB_A0_VBUS,
GPIO_EN_USB_A1_VBUS,
GPIO_EN_USB_A2_VBUS,
+ GPIO_EN_USB_A3_VBUS,
};
/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */
@@ -128,19 +145,14 @@ const struct temp_sensor_t temp_sensors[] = {
};
BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
-static void c0_ccsbu_ovp_interrupt(enum gpio_signal s)
-{
- cprints(CC_USBPD, "C0: CC OVP, SBU OVP, or thermal event");
- pd_handle_cc_overvoltage(0);
-}
-
void board_init(void)
{
int on;
- gpio_enable_interrupt(GPIO_USB_C0_CCSBU_OVP_ODL);
- gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_L);
- gpio_enable_interrupt(GPIO_USBC_ADP_PRESENT_L);
+ gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT);
+
+ /* Enable PPC interrupt */
+ gpio_enable_interrupt(GPIO_USB_C0_FAULT_L);
/* Turn on 5V if the system is on, otherwise turn it off */
on = chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_ANY_SUSPEND |
@@ -179,20 +191,18 @@ int board_vbus_source_enabled(int port)
{
if (port != CHARGE_PORT_TYPEC0)
return 0;
- return gpio_get_level(GPIO_EN_USB_C0_VBUS);
+
+ return ppc_is_sourcing_vbus(port);
}
/* Vconn control for integrated ITE TCPC */
void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled)
{
- /* Vconn control is only for port 0 */
- if (port)
- return;
-
- if (cc_pin == USBPD_CC_PIN_1)
- gpio_set_level(GPIO_EN_USB_C0_CC1_VCONN, !!enabled);
- else
- gpio_set_level(GPIO_EN_USB_C0_CC2_VCONN, !!enabled);
+ /*
+ * We ignore the cc_pin and PPC vconn because polarity and PPC vconn
+ * should already be set correctly in the PPC driver via the pd
+ * state machine.
+ */
}
__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
@@ -204,7 +214,8 @@ __override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
/* Switch between 1.5A and 3A ILIM values */
ilim3A = (rp == TYPEC_RP_3A0);
- gpio_set_level(GPIO_USB_C0_VBUS_ILIM, ilim3A);
+
+ tcpm_select_rp_value(0, ilim3A);
}
/******************************************************************************/
@@ -238,7 +249,7 @@ static int8_t bj_adp_connected = -1;
static void adp_connect_deferred(void)
{
const struct charge_port_info *pi;
- int connected = !gpio_get_level(GPIO_BJ_ADP_PRESENT_L);
+ int connected = gpio_get_level(GPIO_BJ_ADP_PRESENT);
/* Debounce */
if (connected == bj_adp_connected)
@@ -263,12 +274,6 @@ void adp_connect_interrupt(enum gpio_signal signal)
hook_call_deferred(&adp_connect_deferred_data, ADP_DEBOUNCE_MS * MSEC);
}
-/* IRQ for USB-C plug/unplug. */
-void usbc_connect_interrupt(enum gpio_signal signal)
-{
- task_wake(TASK_ID_PD_C0);
-}
-
int board_set_active_charge_port(int port)
{
const int active_port = charge_manager_get_active_charge_port();
@@ -307,17 +312,17 @@ int board_set_active_charge_port(int port)
switch (port) {
case CHARGE_PORT_TYPEC0:
- gpio_set_level(GPIO_EN_PPVAR_USBC_ADP_L, 0);
- gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1);
- gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_L);
+ ppc_vbus_sink_enable(USBC_PORT_C0, 1);
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_OD, 1);
+ gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT);
break;
case CHARGE_PORT_BARRELJACK:
/* Make sure BJ adapter is sourcing power */
- if (gpio_get_level(GPIO_BJ_ADP_PRESENT_L))
+ if (!gpio_get_level(GPIO_BJ_ADP_PRESENT))
return EC_ERROR_INVAL;
- gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 0);
- gpio_set_level(GPIO_EN_PPVAR_USBC_ADP_L, 1);
- gpio_disable_interrupt(GPIO_BJ_ADP_PRESENT_L);
+ gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_OD, 0);
+ ppc_vbus_sink_enable(USBC_PORT_C0, 1);
+ gpio_disable_interrupt(GPIO_BJ_ADP_PRESENT);
break;
default:
return EC_ERROR_INVAL;
@@ -339,8 +344,8 @@ static void board_charge_manager_init(void)
charge_manager_update_charge(j, i, NULL);
}
- port = gpio_get_level(GPIO_BJ_ADP_PRESENT_L) ? CHARGE_PORT_TYPEC0 :
- CHARGE_PORT_BARRELJACK;
+ port = gpio_get_level(GPIO_BJ_ADP_PRESENT) ? CHARGE_PORT_BARRELJACK :
+ CHARGE_PORT_TYPEC0;
CPRINTUSB("Power source is p%d (%s)", port,
port == CHARGE_PORT_TYPEC0 ? "USB-C" : "BJ");
@@ -370,5 +375,51 @@ __override int extpower_is_present(void)
return 1;
}
+void ppc_interrupt(enum gpio_signal signal)
+{
+ if (signal == GPIO_USB_C0_FAULT_L)
+ syv682x_interrupt(USBC_PORT_C0);
+}
+
+/* I2C Ports */
+const struct i2c_port_t i2c_ports[] = {
+ { .name = "eeprom",
+ .port = I2C_PORT_EEPROM,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C_EEPROM_SCL,
+ .sda = GPIO_EC_I2C_EEPROM_SDA },
+
+ { .name = "hdmi2_edid",
+ .port = I2C_PORT_HDMI2_EDID,
+ .kbps = 100,
+ .scl = GPIO_EC_I2C_HDMI2_EDID_SCL,
+ .sda = GPIO_EC_I2C_HDMI2_EDID_SDA },
+
+ { .name = "usbc0",
+ .port = I2C_PORT_USB_C0,
+ .kbps = 1000,
+ .scl = GPIO_EC_I2C_USB_C0_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_SDA },
+
+ { .name = "hdmi2_src_ddc",
+ .port = I2C_PORT_HDMI2_SRC_DDC,
+ .kbps = 100,
+ .scl = GPIO_EC_I2C_HDMI2_SRC_DDC_SCL,
+ .sda = GPIO_EC_I2C_HDMI2_SRC_DDC_SDA },
+
+ { .name = "hdmi1_edid",
+ .port = I2C_PORT_HDMI1_EDID,
+ .kbps = 100,
+ .scl = GPIO_EC_I2C_HDMI1_EDID_SCL,
+ .sda = GPIO_EC_I2C_HDMI1_EDID_SDA },
+
+ { .name = "hdmi1_src_ddc",
+ .port = I2C_PORT_HDMI1_SRC_DDC,
+ .kbps = 100,
+ .scl = GPIO_EC_I2C_HDMI1_SRC_DDC_SCL,
+ .sda = GPIO_EC_I2C_HDMI1_SRC_DDC_SDA },
+};
+
+const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
/* Must come after other header files and interrupt handler declarations */
#include "gpio_list.h"
diff --git a/board/dibbi/board.h b/board/dibbi/board.h
index c59a540b5d..e3d0b0925b 100644
--- a/board/dibbi/board.h
+++ b/board/dibbi/board.h
@@ -17,6 +17,14 @@
#define CONFIG_CMD_CHARGER_DUMP
+/* I2C Bus Configuration */
+#define I2C_PORT_HDMI2_EDID IT83XX_I2C_CH_B
+#undef I2C_PORT_USB_C0
+#define I2C_PORT_USB_C0 IT83XX_I2C_CH_C
+#define I2C_PORT_HDMI2_SRC_DDC IT83XX_I2C_CH_D
+#define I2C_PORT_HDMI1_EDID IT83XX_I2C_CH_E
+#define I2C_PORT_HDMI1_SRC_DDC IT83XX_I2C_CH_F
+
/* Power */
#undef CONFIG_CHARGER
#undef CONFIG_CHARGER_DISCHARGE_ON_AC
@@ -44,13 +52,19 @@
#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP /* C0: ITE EC TCPC */
#define CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT 1
+/* PPC */
+#define CONFIG_USB_PD_DISCHARGE_PPC
+#define CONFIG_USB_PD_VBUS_DETECT_PPC
+#define CONFIG_USBC_PPC
+#define CONFIG_USBC_PPC_SYV682X
+
/* USB Mux and Retimer */
#define CONFIG_USB_MUX_IT5205 /* C0: ITE Mux */
#define I2C_PORT_USB_MUX I2C_PORT_USB_C0 /* Required for ITE Mux */
/* USB Type A Features */
#define CONFIG_USB_PORT_POWER_DUMB
-#define USB_PORT_COUNT 3 /* Type A ports */
+#define USB_PORT_COUNT 4 /* Type A ports */
/* No battery */
#undef CONFIG_BATTERY_CUT_OFF
@@ -121,6 +135,8 @@ enum charge_port {
CHARGE_PORT_BARRELJACK,
};
+enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_COUNT };
+
enum pwm_channel {
PWM_CH_LED_RED,
PWM_CH_LED_GREEN,
diff --git a/board/dibbi/build.mk b/board/dibbi/build.mk
index 07ea50c392..8336360a6a 100644
--- a/board/dibbi/build.mk
+++ b/board/dibbi/build.mk
@@ -10,5 +10,6 @@ CHIP:=it83xx
CHIP_FAMILY:=it8320
CHIP_VARIANT:=it8320dx
BASEBOARD:=dedede
+BOARD:=dibbi
board-y=board.o led.o usb_pd_policy.o
diff --git a/board/dibbi/gpio.inc b/board/dibbi/gpio.inc
index a5c0c02a72..a79d08d5ee 100644
--- a/board/dibbi/gpio.inc
+++ b/board/dibbi/gpio.inc
@@ -13,34 +13,33 @@ GPIO_INT(SLP_S4_L, PIN(I, 5), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(SLP_S3_L, PIN(H, 3), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt)
GPIO_INT(SLP_S0_L, PIN(E, 4), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(SLP_SUS_L, PIN(G, 2), GPIO_INT_BOTH, power_signal_interrupt)
-GPIO_INT(VCCIN_AUX_VID0, PIN(D, 0), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(VCCIN_AUX_VID0, PIN(D, 0), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt)
+GPIO_INT(VCCIN_AUX_VID1, PIN(K, 1), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt)
GPIO_INT(RSMRST_PWRGD_L, PIN(E, 1), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(CPU_C10_GATE_L, PIN(G, 1), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PG_DRAM_OD, PIN(D, 3), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt)
GPIO_INT(PG_PP1050_ST_OD, PIN(L, 1), GPIO_INT_BOTH, power_signal_interrupt)
-GPIO_INT(VCCIN_AUX_VID1, PIN(K, 1), GPIO_INT_BOTH, power_signal_interrupt)
+GPIO_INT(EC_VSNS_PP3300_S5, PIN(I, 0), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PG_VCCIO_EXT_OD, PIN(D, 7), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt)
-GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt)
+GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt)
GPIO_INT(H1_EC_PWR_BTN_ODL, PIN(E, 2), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt)
#ifdef CONFIG_LOW_POWER_IDLE
/* Used to wake up the EC from Deep Doze mode when writing to console */
-GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_BOTH, uart_deepsleep_interrupt) /* UART_DBG_TX_EC_RX */
+GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_BOTH, uart_deepsleep_interrupt) /* UART_DBG_TX_EC_RX */
#endif
-/* USB-C interrupts */
-GPIO_INT(USB_C0_CCSBU_OVP_ODL, PIN(K, 6), GPIO_INT_FALLING | GPIO_PULL_UP, c0_ccsbu_ovp_interrupt) /* Fault protection */
-
/* Other interrupts */
GPIO_INT(EC_WP_OD, PIN(A, 6), GPIO_INT_BOTH, switch_interrupt)
/* Directly connected recovery button */
-GPIO_INT(EC_RECOVERY_BTN_ODL, PIN(K, 7), GPIO_INT_BOTH, button_interrupt)
+GPIO_INT(EC_RECOVERY_BTN_ODL, PIN(K, 7), GPIO_INT_BOTH, button_interrupt)
/* Recovery button input from H1 */
-GPIO_INT(H1_EC_RECOVERY_BTN_ODL, PIN(K, 4), GPIO_INT_BOTH, button_interrupt)
-GPIO_INT(BJ_ADP_PRESENT_L, PIN(A, 7), GPIO_INT_BOTH | GPIO_PULL_UP, adp_connect_interrupt)
-GPIO_INT(USBC_ADP_PRESENT_L, PIN(K, 3), GPIO_INT_BOTH | GPIO_PULL_UP, usbc_connect_interrupt)
+GPIO_INT(H1_EC_RECOVERY_BTN_ODL,PIN(K, 4), GPIO_INT_BOTH, button_interrupt)
+GPIO_INT(BJ_ADP_PRESENT, PIN(A, 7), GPIO_INT_BOTH, adp_connect_interrupt)
+GPIO_INT(USB_C0_FAULT_L, PIN(K, 0), GPIO_INT_FALLING, ppc_interrupt)
/* Power sequence GPIOs */
+GPIO(EC_AP_PSYS, PIN(J, 2), GPIO_OUT_LOW)
GPIO(EC_AP_RTCRST, PIN(K, 2), GPIO_OUT_LOW)
GPIO(EC_AP_PWR_BTN_ODL, PIN(B, 6), GPIO_ODR_HIGH)
GPIO(EC_AP_DPWROK, PIN(L, 7), GPIO_OUT_LOW)
@@ -48,20 +47,19 @@ GPIO(EC_AP_RSMRST_L, PIN(H, 0), GPIO_OUT_LOW)
GPIO(EC_AP_WAKE_ODL, PIN(D, 5), GPIO_ODR_HIGH)
GPIO(SYS_RST_ODL, PIN(D, 1), GPIO_ODR_HIGH)
GPIO(EC_AP_SYS_PWROK, PIN(F, 2), GPIO_OUT_LOW)
-GPIO(PG_PP5000_U_OD, PIN(E, 3), GPIO_INPUT)
+GPIO(PG_PP5000_U_OD, PIN(J, 0), GPIO_INPUT)
+GPIO(EN_PP5000_U, PIN(K, 5), GPIO_OUT_LOW)
+GPIO(PG_PP3300_A, PIN(B, 5), GPIO_INPUT)
GPIO(EN_PP3300_A, PIN(C, 5), GPIO_OUT_LOW)
GPIO(EC_AP_PCH_PWROK_OD, PIN(D, 6), GPIO_ODR_LOW)
-GPIO(EN_PP5000_U, PIN(K, 5), GPIO_OUT_LOW)
/* TODO(b:149775160) - Modify if needed if we ever use this signal. */
GPIO(EN_VCCST, PIN(D, 4), GPIO_INPUT)
GPIO(EN_VCCIO_EXT, PIN(B, 2), GPIO_OUT_LOW)
GPIO(EC_PROCHOT_ODL, PIN(I, 1), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
GPIO(EC_AP_VCCST_PWRGD_OD, PIN(E, 5), GPIO_ODR_LOW)
GPIO(ALL_SYS_PWRGD, PIN(B, 7), GPIO_OUT_LOW)
-GPIO(EN_PPVAR_BJ_ADP_L, PIN(J, 0), GPIO_OUT_LOW)
-GPIO(EN_PPVAR_USBC_ADP_L, PIN(J, 1), GPIO_OUT_LOW)
-GPIO(EN_USB_C0_VBUS, PIN(I, 7), GPIO_OUT_LOW)
-GPIO(USB_C0_VBUS_ILIM, PIN(I, 6), GPIO_OUT_LOW)
+GPIO(EN_PPVAR_BJ_ADP_OD, PIN(E, 3), GPIO_OUT_LOW)
+GPIO(ACK_PPVAR_BJ_ADP_ODL, PIN(A, 0), GPIO_INPUT)
/* Required for icelake chipset code, but implemented through other means for dedede */
UNIMPLEMENTED(AC_PRESENT)
@@ -71,72 +69,87 @@ UNIMPLEMENTED(PG_EC_ALL_SYS_PWRGD)
/* Required for dedede baseboard but not used in dibbi */
UNIMPLEMENTED(USB_C0_INT_ODL)
UNIMPLEMENTED(EN_SLP_Z)
+UNIMPLEMENTED(EC_BATTERY_PRES_ODL)
/* I2C pins - Alternate function below configures I2C module on these pins */
GPIO(EC_I2C_EEPROM_SCL, PIN(B, 3), GPIO_INPUT)
GPIO(EC_I2C_EEPROM_SDA, PIN(B, 4), GPIO_INPUT)
-GPIO(EC_I2C_BATTERY_SCL, PIN(C, 1), GPIO_INPUT)
-GPIO(EC_I2C_BATTERY_SDA, PIN(C, 2), GPIO_INPUT)
-GPIO(EC_I2C_SENSOR_SCL, PIN(F, 6), GPIO_INPUT | GPIO_SEL_1P8V)
-GPIO(EC_I2C_SENSOR_SDA, PIN(F, 7), GPIO_INPUT | GPIO_SEL_1P8V)
-GPIO(EC_I2C_USB_C0_SCL, PIN(A, 4), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_SDA, PIN(A, 5), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_SCL, PIN(F, 6), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_SDA, PIN(F, 7), GPIO_INPUT)
+GPIO(EC_I2C_HDMI1_EDID_SCL, PIN(E, 0), GPIO_INPUT)
+GPIO(EC_I2C_HDMI1_EDID_SDA, PIN(E, 7), GPIO_INPUT)
+GPIO(EC_I2C_HDMI2_EDID_SCL, PIN(C, 1), GPIO_INPUT)
+GPIO(EC_I2C_HDMI2_EDID_SDA, PIN(C, 2), GPIO_INPUT)
+GPIO(EC_I2C_HDMI1_SRC_DDC_SCL, PIN(A, 4), GPIO_INPUT)
+GPIO(EC_I2C_HDMI1_SRC_DDC_SDA, PIN(A, 5), GPIO_INPUT)
+GPIO(EC_I2C_HDMI2_SRC_DDC_SCL, PIN(H, 1), GPIO_INPUT)
+GPIO(EC_I2C_HDMI2_SRC_DDC_SDA, PIN(H, 2), GPIO_INPUT)
/* USB pins */
-GPIO(EN_USB_C0_CC1_VCONN, PIN(H, 4), GPIO_OUT_LOW)
-GPIO(EN_USB_C0_CC2_VCONN, PIN(H, 6), GPIO_OUT_LOW)
GPIO(EC_AP_USB_C0_HPD, PIN(L, 4), GPIO_OUT_LOW)
GPIO(EN_USB_A0_VBUS, PIN(L, 6), GPIO_OUT_LOW)
GPIO(EN_USB_A1_VBUS, PIN(C, 6), GPIO_OUT_LOW)
GPIO(EN_USB_A2_VBUS, PIN(C, 4), GPIO_OUT_LOW)
+GPIO(EN_USB_A3_VBUS, PIN(J, 5), GPIO_OUT_LOW)
+GPIO(EC_USB_C0_FRS_EN, PIN(K, 6), GPIO_OUT_LOW)
+GPIO(USB_C0_SBU_MUX_FAULT, PIN(I, 7), GPIO_INPUT)
/* MKBP event synchronization */
/* TODO(b/257833880) Check whether this pin is needed */
-GPIO(EC_AP_MKBP_INT_L, PIN(L, 5), GPIO_ODR_HIGH)
-
-/* Misc pins which will run to the I/O board */
-GPIO(EC_SUB_IO_1_1, PIN(L, 3), GPIO_INPUT)
-GPIO(EC_SUB_IO_1_2, PIN(F, 0), GPIO_INPUT)
-GPIO(EC_SUB_IO_2_1, PIN(F, 1), GPIO_INPUT)
-GPIO(EC_SUB_IO_2_2, PIN(L, 2), GPIO_INPUT)
+GPIO(EC_AP_MKBP_INT_L, PIN(L, 5), GPIO_ODR_HIGH)
+
+/* HDMI */
+GPIO(HDMI1_CEC, PIN(F, 0), GPIO_OUT_LOW)
+GPIO(HDMI2_CEC_IN, PIN(J, 3), GPIO_INPUT)
+GPIO(HDMI2_CEC, PIN(F, 1), GPIO_OUT_LOW)
+GPIO(HDMI1_SRC_HPD, PIN(F, 3), GPIO_INPUT)
+GPIO(HDMI2_SRC_HPD, PIN(KSO_L, 3), GPIO_INPUT)
+GPIO(EC_HDMI1_SRC_HPD_OUT, PIN(I, 6), GPIO_OUT_LOW)
+GPIO(EC_HDMI2_SRC_HPD_OUT, PIN(KSO_L, 4), GPIO_OUT_LOW)
+GPIO(HDMI1_EDID_SEL, PIN(J, 1), GPIO_OUT_LOW)
+GPIO(HDMI2_EDID_SEL, PIN(KSO_L, 5), GPIO_OUT_LOW)
+GPIO(EDID_BTN_ODL, PIN(C, 3), GPIO_INPUT)
+GPIO(EC_EN_PP5000_HDMI1, PIN(KSO_L, 6), GPIO_OUT_LOW)
+GPIO(EC_EN_PP5000_HDMI2, PIN(KSO_L, 7), GPIO_OUT_LOW)
/* Misc */
-GPIO(EC_ENTERING_RW, PIN(G, 0), GPIO_OUT_LOW)
+GPIO(EC_ENTERING_RW, PIN(C, 7), GPIO_OUT_LOW)
GPIO(CCD_MODE_ODL, PIN(H, 5), GPIO_ODR_HIGH)
-GPIO(EC_BATTERY_PRES_ODL, PIN(I, 4), GPIO_INPUT)
-GPIO(ECH1_PACKET_MODE, PIN(H, 1), GPIO_OUT_LOW)
+GPIO(ECH1_PACKET_MODE, PIN(C, 0), GPIO_OUT_LOW)
+GPIO(EN_RS232_X, PIN(E, 6), GPIO_OUT_LOW)
+GPIO(UART0_RX, PIN(B, 1), GPIO_OUT_LOW) /* UART_EC_TX_DBG_RX */
/* NC pins, enable internal pull-down to avoid floating state. */
-GPIO(GPIOC0_NC, PIN(C, 0), GPIO_INPUT | GPIO_PULL_DOWN)
-GPIO(GPIOC3_NC, PIN(C, 3), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(GPIOG0_NC, PIN(G, 0), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOG3_NC, PIN(G, 3), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOG4_NC, PIN(G, 4), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOG5_NC, PIN(G, 5), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOG6_NC, PIN(G, 6), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOG7_NC, PIN(G, 7), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(GPIOH4_NC, PIN(H, 4), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(GPIOH6_NC, PIN(H, 6), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(GPIOI4_NC, PIN(I, 4), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOJ4_NC, PIN(J, 4), GPIO_INPUT | GPIO_PULL_DOWN)
-GPIO(GPIOJ5_NC, PIN(J, 5), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOJ6_NC, PIN(J, 6), GPIO_INPUT | GPIO_PULL_DOWN)
-GPIO(GPIOK0_NC, PIN(K, 0), GPIO_INPUT | GPIO_PULL_DOWN)
-GPIO(GPIOL0_NC, PIN(L, 0), GPIO_INPUT | GPIO_PULL_DOWN)
+GPIO(GPIOK3_NC, PIN(K, 3), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOM6_NC, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN)
-/* TODO(b/257833880) add any new unused pins */
/* Alternate functions GPIO definitions */
/* UART */
ALTERNATE(PIN_MASK(B, BIT(0) | BIT(1)), 0, MODULE_UART, 0) /* UART for debug */
/* I2C */
-ALTERNATE(PIN_MASK(B, BIT(3) | BIT(4)), 0, MODULE_I2C, 0) /* I2C0 */
-ALTERNATE(PIN_MASK(C, BIT(1) | BIT(2)), 0, MODULE_I2C, 0) /* I2C1 */
-ALTERNATE(PIN_MASK(F, BIT(6) | BIT(7)), 0, MODULE_I2C, GPIO_SEL_1P8V) /* I2C2 - 1.8V */
-ALTERNATE(PIN_MASK(E, BIT(0) | BIT(7)), 0, MODULE_I2C, 0) /* I2C4 */
-ALTERNATE(PIN_MASK(A, BIT(4) | BIT(5)), 0, MODULE_I2C, 0) /* I2C5 */
+ALTERNATE(PIN_MASK(B, BIT(3) | BIT(4)), 0, MODULE_I2C, 0) /* I2C0 - EEPROM */
+ALTERNATE(PIN_MASK(C, BIT(1) | BIT(2)), 0, MODULE_I2C, 0) /* I2C1 - HDMI2_EDID */
+ALTERNATE(PIN_MASK(F, BIT(6) | BIT(7)), 0, MODULE_I2C, 0) /* I2C2 - USB_C0 */
+ALTERNATE(PIN_MASK(E, BIT(0) | BIT(7)), 0, MODULE_I2C, 0) /* I2C4 - HDMI1_EDID */
+ALTERNATE(PIN_MASK(A, BIT(4) | BIT(5)), 0, MODULE_I2C, 0) /* I2C5 - HDMI1_SRC_DDC */
+ALTERNATE(PIN_MASK(H, BIT(1) | BIT(2)), 0, MODULE_I2C, 0) /* I2C3 - HDMI2_SRC_DDC */
/* ADC */
-ALTERNATE(PIN_MASK(I, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC0: EC_VSNS_PP3300_A, ADC2: TEMP_SENSOR_1, ADC3: TEMP_SENSOR_2 */
-ALTERNATE(PIN_MASK(L, BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC15: PPVAR_PWR_IN_IMON, ADC16: SNS_PPVAR_PWR_IN */
+ALTERNATE(PIN_MASK(I, BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC2: TEMP_SENSOR_1, ADC3: TEMP_SENSOR_2 */
+ALTERNATE(PIN_MASK(L, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC13: TEMP_SENSOR_3, ADC15: ANALOG_PPVAR_PWR_IN_IMON, ADC16: SNS_PPVAR_PWR_IN */
/* PWM */
ALTERNATE(PIN_MASK(A, BIT(1) | BIT(2) | BIT(3)), 0, MODULE_PWM, 0) /* LED_[R,G,B]_ODL */
diff --git a/board/dibbi/usb_pd_policy.c b/board/dibbi/usb_pd_policy.c
index 9d573b9c61..21cdf82a57 100644
--- a/board/dibbi/usb_pd_policy.c
+++ b/board/dibbi/usb_pd_policy.c
@@ -8,9 +8,9 @@
#include "chipset.h"
#include "common.h"
#include "console.h"
-#include "driver/tcpm/tcpci.h"
#include "gpio.h"
#include "usb_pd.h"
+#include "usbc_ppc.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args)
@@ -36,11 +36,19 @@ int pd_check_vconn_swap(int port)
void pd_power_supply_reset(int port)
{
+ int prev_en;
+
if (port < 0 || port >= board_get_usb_pd_port_count())
return;
+ prev_en = ppc_is_sourcing_vbus(port);
+
/* Disable VBUS source */
- gpio_set_level(GPIO_EN_USB_C0_VBUS, 0);
+ ppc_vbus_source_enable(port, 0);
+
+ /* Enable discharge if we were previously sourcing 5V */
+ if (prev_en)
+ pd_set_vbus_discharge(port, 1);
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -48,11 +56,19 @@ void pd_power_supply_reset(int port)
int pd_set_power_supply_ready(int port)
{
+ int rv;
+
/* Disable charging */
- gpio_set_level(GPIO_EN_PPVAR_USBC_ADP_L, 1);
+ rv = ppc_vbus_sink_enable(port, 0);
+ if (rv)
+ return rv;
+
+ pd_set_vbus_discharge(port, 0);
/* Enable VBUS source */
- gpio_set_level(GPIO_EN_USB_C0_VBUS, 1);
+ rv = ppc_vbus_source_enable(port, 1);
+ if (rv)
+ return rv;
/* Notify host of power info change. */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
@@ -65,5 +81,5 @@ __override int pd_snk_is_vbus_provided(int port)
if (port != CHARGE_PORT_TYPEC0)
return 0;
- return gpio_get_level(GPIO_USBC_ADP_PRESENT_L);
+ return ppc_is_vbus_present(port);
}
diff --git a/board/hatch_fp/build.mk b/board/hatch_fp/build.mk
index 5dd5f637bd..2647b4af9c 100644
--- a/board/hatch_fp/build.mk
+++ b/board/hatch_fp/build.mk
@@ -66,6 +66,7 @@ test-list-y=\
system_is_locked \
timer \
timer_dos \
+ tpm_seed_clear \
utils \
utils_str \
diff --git a/board/hyperdebug/board.h b/board/hyperdebug/board.h
index 4e0dfa6afd..c5afe4d014 100644
--- a/board/hyperdebug/board.h
+++ b/board/hyperdebug/board.h
@@ -10,9 +10,6 @@
#define CONFIG_LTO
-/* 48 MHz SYSCLK clock frequency */
-#define CPU_CLOCK 48000000
-
/* Configure the flash */
#undef CONFIG_RO_SIZE
#undef CONFIG_FW_PSTATE_OFF
@@ -39,6 +36,21 @@
#else /* !SECTION_IS_RO */
+/*
+ * PLL configuration. Freq = STM32_HSE_CLOCK or HSI (16MHz) * N / M / R.
+ *
+ * In our case, 16MHz * 13 / 1 / 2 = 104MHz.
+ */
+
+#undef STM32_PLLM
+#undef STM32_PLLN
+#undef STM32_PLLR
+#define STM32_PLLM 1
+#define STM32_PLLN 13
+#define STM32_PLLR 2
+
+#define STM32_USE_PLL
+
#define CONFIG_BOARD_PRE_INIT
#define CONFIG_ROM_BASE 0x0
@@ -195,5 +207,8 @@ enum usb_strings {
*/
#define OCTOSPI_TRANSACTION_TIMEOUT_US (500 * MSEC)
+/* Interrupt handler, called by common/gpio.c. */
+void gpio_edge(enum gpio_signal signal);
+
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/hyperdebug/gpio.c b/board/hyperdebug/gpio.c
index 59f224571a..7dbc063237 100644
--- a/board/hyperdebug/gpio.c
+++ b/board/hyperdebug/gpio.c
@@ -4,11 +4,246 @@
*/
/* HyperDebug GPIO logic and console commands */
+#include "atomic.h"
+#include "builtin/assert.h"
#include "common.h"
#include "console.h"
+#include "cpu.h"
#include "gpio.h"
+#include "hooks.h"
+#include "registers.h"
+#include "shared_mem.h"
+#include "task.h"
+#include "timer.h"
#include "util.h"
+/*
+ * A cyclic buffer is used to record events (edges) of one or more GPIO
+ * signals. Each event records the time since the previous event, and the
+ * signal that changed (the direction of change is not explicitly recorded).
+ *
+ * So conceptually the buffer entries are pairs of (diff: u64, signal_no: u8).
+ * These entries are encoded as bytes in the following way: First the timestamp
+ * diff is shifted left by signal_bits, and the signal_no value put into the
+ * lower bits freed up this way. Now we have a single u64, which often will be
+ * a small value (or at least, when the edges happen rapidly, and the need to
+ * store many of them the highest, then the u64 will be a small value). This
+ * u64 is then stored 7 bits at a time in successive bytes, with the most
+ * significant bit indicating whether more bytes belong to the same entry.
+ *
+ * The chain of relative timestamps are resolved by keeping two absolute
+ * timestamps: head_time is the time of the most recently inserted event, and is
+ * accessed and updated only by the interrupt handler. tail_time is the past
+ * timestamp on which the diff of the oldest record in the buffer is based (the
+ * timestamp of the last record to be removed from the buffer), it is accessed
+ * and updated only from the non-interrupt code that removes records from the
+ * buffer.
+ *
+ * In a similar fashion, the signal level is recorded "at both ends" in for each
+ * monitored signal by head_level and tail_level, the former only accessed from
+ * the interrupt handler, and the latter only accessed from non-interrupt code.
+ */
+struct cyclic_buffer_header_t {
+ /* Number of signals being monitored in this buffer. */
+ uint8_t num_signals;
+ /* The number of bits required to represent 0..num_signals-1. */
+ uint8_t signal_bits;
+ /* Sticky bit recording if overflow occurred. */
+ volatile uint8_t overflow;
+ /* Time of the most recent event, updated from interrupt context. */
+ volatile timestamp_t head_time;
+ /* Time base that the oldest event is relative to. */
+ timestamp_t tail_time;
+ /* Index at which new records are placed, updated from interrupt. */
+ volatile uint32_t head;
+ /* Index af oldest record. */
+ uint32_t tail;
+ /*
+ * Size of cyclic byte buffer, determined at runtime, not necessarily
+ * power of two. Head and tail wrap to zero here.
+ */
+ uint32_t size;
+ /* Data contents */
+ uint8_t data[];
+};
+
+/*
+ * The STM32L5 has 16 edge detection circuits. Each pin can only be used with
+ * one of them. That is, detector 0 can take its input from one of pins A0,
+ * B0, C0, ..., while detector 1 can choose between A1, B1, etc.
+ *
+ * Information about the current use of each detection circuit is stored in 16
+ * "slots" below.
+ */
+struct monitoring_slot_t {
+ /* Link to buffer recording edges of this signal. */
+ struct cyclic_buffer_header_t *buffer;
+ /* EC enum id of the signal used by this detection slot. */
+ int gpio_signal;
+ /* The index of the signal as used in the recording buffer. */
+ uint8_t signal_no;
+ /* Most recently recorded level of the signal. */
+ volatile uint8_t head_level;
+ /* Level as of the current oldest end (tail) of the recording. */
+ uint8_t tail_level;
+};
+struct monitoring_slot_t monitoring_slots[16];
+
+/*
+ * Counts unacknowledged buffer overflows. Whenever non-zero, the red LED
+ * will flash.
+ */
+atomic_t num_cur_error_conditions;
+
+/*
+ * Counts the number of cyclic buffers currently in existence, the green LED
+ * will flash whenever this is non-zero, indicating the monitoring activity.
+ */
+int num_cur_monitoring = 0;
+
+static __attribute__((noinline)) void overflow(struct monitoring_slot_t *slot)
+{
+ struct cyclic_buffer_header_t *buffer_header = slot->buffer;
+ gpio_disable_interrupt(slot->gpio_signal);
+ buffer_header->overflow = 1;
+ atomic_add(&num_cur_error_conditions, 1);
+}
+
+void gpio_edge(enum gpio_signal signal)
+{
+ /*
+ * Hardware has detected one or more edges since last time. We
+ * process by looking at the current level of the signal. If opposite
+ * the most recent level, we record one edge, if the same as most
+ * recent level, we record two edges, that is, a zero-width pulse.
+ * This is useful for tests trying to verify e.g. that there are no
+ * glitches on a particular signal, and want to know about any pulses,
+ * however narrow.
+ */
+ timestamp_t now = get_time();
+ int gpio_num = GPIO_MASK_TO_NUM(gpio_list[signal].mask);
+ struct monitoring_slot_t *slot = monitoring_slots + gpio_num;
+ int current_level = gpio_get_level(signal);
+ struct cyclic_buffer_header_t *buffer_header = slot->buffer;
+ uint8_t *buffer_data = buffer_header->data;
+ uint32_t tail = buffer_header->tail, head = buffer_header->head,
+ size = buffer_header->size;
+ uint64_t diff = now.val - buffer_header->head_time.val;
+
+ uint8_t signal_bits = buffer_header->signal_bits;
+
+ /*
+ * Race condition here! If three or more edges happen in
+ * rapid succession, we may fail to record some of them, but
+ * we should never over-report edges.
+ *
+ * Since the edge interrupts pending bit has been cleared before the
+ * "current_level" was polled, if an edge happened between the two, then
+ * an interrupt is currently pending, and when handled after this method
+ * returns, the logic below would wrongly conclude that the signal must
+ * have seen two transitions, in order to end up at the same level as
+ * before. In order to avoid such over-reporting, we clear "pending"
+ * interrupt bit below, but only for the direction that goes "towards"
+ * the level measured above.
+ */
+ if (current_level)
+ STM32_EXTI_RPR = BIT(gpio_num);
+ else
+ STM32_EXTI_FPR = BIT(gpio_num);
+
+ /*
+ * Insert an entry recording the time since last event, and which
+ * signal changed (the direction of the edge is not explicitly
+ * recorded, as it can be inferred from the initial level).
+ *
+ * The time difference and pin index are encoded in `diff`, which will
+ * be a small integer if the event arrive rapidly. 7 bits of this
+ * integer is then put into one byte at a time, using the high bit of
+ * each byte to indicate if more are to come. This encoding will use
+ * only one byte per event, in the best case, allowing tens of
+ * thousands of events to be buffered.
+ */
+ diff <<= signal_bits;
+ diff |= slot->signal_no;
+ do {
+ buffer_data[head++] = ((diff >= 0x80) ? 0x80 : 0x00) |
+ (diff & 0x7F);
+ diff >>= 7;
+ if (head == size)
+ head = 0;
+ if (head == tail) {
+ /*
+ * The new head will not be persisted, maintaining the
+ * invatiant that head and tail are equal only when the
+ * buffer is empty.
+ */
+ return overflow(slot);
+ }
+ } while (diff);
+
+ /*
+ * If current level equals the previous level, then record an
+ * additional edge 0ms after the previous.
+ */
+ if (!!current_level == !!slot->head_level) {
+ /*
+ * Add a record with zero diff, and the same signal no. (Will
+ * always fit in one byte, as signal_no never uses more than 7
+ * bits.)
+ */
+ buffer_data[head++] = slot->signal_no;
+ if (head == size)
+ head = 0;
+ if (head == tail) {
+ /*
+ * The new head will not be persisted, maintaining the
+ * invatiant that head and tail are equal only when the
+ * buffer is empty.
+ */
+ return overflow(slot);
+ }
+ } else {
+ slot->head_level = current_level;
+ }
+ buffer_header->head = head;
+ buffer_header->head_time = now;
+}
+
+static void board_gpio_init(void)
+{
+ /* Mark every slot as unused. */
+ for (int i = 0; i < ARRAY_SIZE(monitoring_slots); i++)
+ monitoring_slots[i].gpio_signal = GPIO_COUNT;
+}
+DECLARE_HOOK(HOOK_INIT, board_gpio_init, HOOK_PRIO_DEFAULT);
+
+static void stop_all_gpio_monitoring(void)
+{
+ struct monitoring_slot_t *slot;
+ struct cyclic_buffer_header_t *buffer_header;
+ for (int i = 0; i < ARRAY_SIZE(monitoring_slots); i++) {
+ slot = monitoring_slots + i;
+ if (!slot->buffer)
+ continue;
+
+ /* Disable interrupts for all signals feeding into the same
+ * cyclic buffer. */
+ buffer_header = slot->buffer;
+ for (int j = i; j < ARRAY_SIZE(monitoring_slots); j++) {
+ slot = monitoring_slots + i;
+ if (slot->buffer != buffer_header)
+ continue;
+ gpio_disable_interrupt(slot->gpio_signal);
+ slot->gpio_signal = GPIO_COUNT;
+ }
+ /* Deallocate this one cyclic buffer. */
+ num_cur_monitoring--;
+ if (buffer_header->overflow)
+ atomic_sub(&num_cur_error_conditions, 1);
+ shared_mem_release((char *)buffer_header);
+ }
+}
+
/**
* Find a GPIO signal by name.
*
@@ -102,3 +337,438 @@ static int command_gpio_pull_mode(int argc, const char **argv)
DECLARE_CONSOLE_COMMAND_FLAGS(gpiopullmode, command_gpio_pull_mode,
"name <none | up | down>",
"Set a GPIO weak pull mode", CMD_FLAG_RESTRICTED);
+
+/*
+ * Set multiple aspects of a GPIO pin simultaneously, that is, can switch output
+ * level, opendrain/pushpull, and pullup simultaneously, eliminating the risk of
+ * glitches.
+ */
+static int command_gpio_multiset(int argc, const char **argv)
+{
+ int gpio;
+ int flags;
+
+ if (argc < 4)
+ return EC_ERROR_PARAM_COUNT;
+
+ gpio = find_signal_by_name(argv[2]);
+ if (gpio == GPIO_COUNT)
+ return EC_ERROR_PARAM2;
+ flags = gpio_get_flags(gpio);
+
+ if (argc > 3 && strcasecmp(argv[3], "-") != 0) {
+ flags = flags & ~(GPIO_LOW | GPIO_HIGH);
+ if (strcasecmp(argv[3], "0") == 0)
+ flags |= GPIO_LOW;
+ else if (strcasecmp(argv[3], "1") == 0)
+ flags |= GPIO_HIGH;
+ else
+ return EC_ERROR_PARAM3;
+ }
+
+ if (argc > 4 && strcasecmp(argv[4], "-") != 0) {
+ flags = flags & ~(GPIO_INPUT | GPIO_OUTPUT | GPIO_OPEN_DRAIN);
+ if (strcasecmp(argv[4], "input") == 0)
+ flags |= GPIO_INPUT;
+ else if (strcasecmp(argv[4], "opendrain") == 0)
+ flags |= GPIO_OUTPUT | GPIO_OPEN_DRAIN;
+ else if (strcasecmp(argv[4], "pushpull") == 0)
+ flags |= GPIO_OUTPUT;
+ else if (strcasecmp(argv[4], "alternate") == 0)
+ flags |= GPIO_ALTERNATE;
+ else
+ return EC_ERROR_PARAM4;
+ }
+
+ if (argc > 5 && strcasecmp(argv[5], "-") != 0) {
+ flags = flags & ~(GPIO_PULL_UP | GPIO_PULL_DOWN);
+ if (strcasecmp(argv[5], "none") == 0)
+ ;
+ else if (strcasecmp(argv[5], "up") == 0)
+ flags |= GPIO_PULL_UP;
+ else if (strcasecmp(argv[5], "down") == 0)
+ flags |= GPIO_PULL_DOWN;
+ else
+ return EC_ERROR_PARAM5;
+ }
+
+ /* Update GPIO flags. */
+ gpio_set_flags(gpio, flags);
+ return EC_SUCCESS;
+}
+
+static int command_gpio_monitoring_start(int argc, const char **argv)
+{
+ BUILD_ASSERT(STM32_IRQ_EXTI15 < 32);
+ int gpios[16];
+ int gpio_num = argc - 3;
+ int i;
+ timestamp_t now;
+ int rv;
+ uint32_t nvic_mask;
+ size_t cyclic_buffer_size = 8192; /* Maybe configurable by parameter */
+ struct cyclic_buffer_header_t *buf;
+ struct monitoring_slot_t *slot;
+
+ if (gpio_num <= 0 || gpio_num > 16)
+ return EC_ERROR_PARAM_COUNT;
+
+ for (i = 0; i < gpio_num; i++) {
+ gpios[i] = find_signal_by_name(argv[3 + i]);
+ if (gpios[i] == GPIO_COUNT) {
+ rv = EC_ERROR_PARAM3 + i;
+ goto out_partial_cleanup;
+ }
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ if (slot->gpio_signal != GPIO_COUNT) {
+ ccprintf("Error: Monitoring of %s conflicts with %s\n",
+ argv[3 + i],
+ gpio_list[slot->gpio_signal].name);
+ rv = EC_ERROR_PARAM3 + i;
+ goto out_partial_cleanup;
+ }
+ slot->gpio_signal = gpios[i];
+ }
+
+ /*
+ * All the requested signals were available for monitoring, and their
+ * slots have been marked as reserved for the respective signal.
+ */
+ rv = shared_mem_acquire(sizeof(struct cyclic_buffer_header_t) +
+ cyclic_buffer_size,
+ (char **)&buf);
+ if (rv != EC_SUCCESS)
+ goto out_cleanup;
+
+ buf->head = buf->tail = 0;
+ buf->size = cyclic_buffer_size;
+ buf->overflow = 0;
+ buf->num_signals = gpio_num;
+ buf->signal_bits = 0;
+ /* Compute how many bits are required to represent 0..gpio_num-1. */
+ while ((gpio_num - 1) >> buf->signal_bits)
+ buf->signal_bits++;
+
+ for (i = 0; i < gpio_num; i++) {
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ slot->buffer = buf;
+ slot->signal_no = i;
+ }
+
+ /*
+ * The code relies on all EXTIn interrupts belonging to the same 32-bit
+ * NVIC register, so that multiple interrupts can be "unleashed"
+ * simultaneously.
+ */
+ nvic_mask = 0;
+
+ /*
+ * Disable interrupts in GPIO/EXTI detection circuits (should be
+ * disabled already, but disabled and clear pending bit to be on the
+ * safe side).
+ */
+ for (i = 0; i < gpio_num; i++) {
+ int gpio_num = GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ gpio_disable_interrupt(gpios[i]);
+ gpio_clear_pending_interrupt(gpios[i]);
+ nvic_mask |= BIT(STM32_IRQ_EXTI0 + gpio_num);
+ }
+ /* Also disable interrupts at NVIC (interrupt controller) level. */
+ CPU_NVIC_UNPEND(0) = nvic_mask;
+ CPU_NVIC_DIS(0) = nvic_mask;
+
+ for (i = 0; i < gpio_num; i++) {
+ int gpio_num = GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ slot = monitoring_slots + gpio_num;
+ /*
+ * Tell the GPIO block to start detecting rising and falling
+ * edges, and latch them in STM32_EXTI_RPR and STM32_EXTI_FPR
+ * respectively. Interrupts are still disabled in the NVIC,
+ * meaning that the execution will not be interrupted, yet, even
+ * if the GPIO block requests interrupt.
+ */
+ gpio_enable_interrupt(gpios[i]);
+ slot->tail_level = slot->head_level = gpio_get_level(gpios[i]);
+ /*
+ * Race condition here! If three or more edges happen in
+ * rapid succession, we may fail to record some of them, but
+ * we should never over-report edges.
+ *
+ * Since edge detection was enabled before the "head_level"
+ * was polled, if an edge happened between the two, then an
+ * interrupt is currently pending, and when handled after this
+ * loop, the logic in the gpio_edge interrupt handler would
+ * wrongly conclude that the signal must have seen two
+ * transitions, in order to end up at the same level as before.
+ * In order to avoid such over-reporting, we clear "pending"
+ * interrupt bit below, but only for the direction that goes
+ * "towards" the level measured above.
+ */
+ if (slot->head_level)
+ STM32_EXTI_RPR = BIT(gpio_num);
+ else
+ STM32_EXTI_FPR = BIT(gpio_num);
+ }
+ /*
+ * Now enable the handling of the set of interrupts.
+ */
+ now = get_time();
+ buf->head_time = now;
+ CPU_NVIC_EN(0) = nvic_mask;
+
+ buf->tail_time = now;
+ num_cur_monitoring++;
+ ccprintf(" @%lld\n", buf->tail_time.val);
+
+ /*
+ * Dump the initial level of each input, for the convenience of the
+ * caller. (Allow makes monitoring useful, even if a signal has no
+ * transitions during the monitoring period.
+ */
+ for (i = 0; i < gpio_num; i++) {
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ ccprintf(" %d %s %d\n", i, gpio_list[gpios[i]].name,
+ slot->tail_level);
+ }
+
+ return EC_SUCCESS;
+
+out_cleanup:
+ i = gpio_num;
+out_partial_cleanup:
+ while (i-- > 0) {
+ monitoring_slots[GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask)]
+ .gpio_signal = GPIO_COUNT;
+ }
+ return rv;
+}
+
+static int command_gpio_monitoring_read(int argc, const char **argv)
+{
+ int gpios[16];
+ int gpio_num = argc - 3;
+ int i;
+ struct cyclic_buffer_header_t *buf = NULL;
+ struct monitoring_slot_t *slot;
+ int gpio_signals_by_no[16];
+ uint8_t signal_bits;
+ uint32_t tail, head;
+ timestamp_t tail_time, now;
+
+ if (gpio_num <= 0 || gpio_num > 16)
+ return EC_ERROR_PARAM_COUNT;
+
+ for (i = 0; i < gpio_num; i++) {
+ gpios[i] = find_signal_by_name(argv[3 + i]);
+ if (gpios[i] == GPIO_COUNT)
+ return EC_ERROR_PARAM3 + i; /* May overflow */
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ if (slot->gpio_signal != gpios[i]) {
+ ccprintf("Error: Not monitoring %s\n",
+ gpio_list[gpios[i]].name);
+ return EC_ERROR_PARAM3 + i;
+ }
+ if (buf == NULL) {
+ buf = slot->buffer;
+ } else if (buf != slot->buffer) {
+ ccprintf(
+ "Error: Not monitoring %s as part of same groups as %s\n",
+ gpio_list[gpios[i]].name,
+ gpio_list[gpios[0]].name);
+ return EC_ERROR_PARAM3 + i;
+ }
+ gpio_signals_by_no[slot->signal_no] = gpios[i];
+ }
+ if (gpio_num != buf->num_signals) {
+ ccprintf("Error: Not full set of signals monitored\n");
+ return EC_ERROR_INVAL;
+ }
+
+ /*
+ * We read current time, before taking a snapshot of the head pointer as
+ * set by the interrupt handler. This way, we can guarantee that the
+ * transcript will include any edge happening at or before the `now`
+ * timestamp. If an interrupt happens between the two lines below,
+ * causing our head pointer to include an event that happened after
+ * "now", then it will be skipped in the loop below, and kept for the
+ * next invocation of `gpio monitoring read`.
+ */
+ now = get_time();
+ head = buf->head;
+
+ ccprintf(" @%lld\n", now.val);
+ signal_bits = buf->signal_bits;
+ tail = buf->tail;
+ tail_time = buf->tail_time;
+ while (tail != head) {
+ uint8_t *buffer = buf->data;
+ timestamp_t diff;
+ uint8_t byte;
+ uint8_t signal_no;
+ int shift = 0;
+ uint32_t tentative_tail = tail;
+ struct monitoring_slot_t *slot;
+ diff.val = 0;
+ do {
+ byte = buffer[tentative_tail++];
+ if (tentative_tail == buf->size)
+ tentative_tail = 0;
+ diff.val |= (byte & 0x7F) << shift;
+ shift += 7;
+ } while (byte & 0x80);
+ signal_no = diff.val & (0xFF >> (8 - signal_bits));
+ diff.val >>= signal_bits;
+ if (tail_time.val + diff.val > now.val) {
+ /*
+ * Do not consume this or subsequent records, which
+ * apparently happened after our "now" timestamp from
+ * earlier in the execution of this method.
+ */
+ break;
+ }
+ tail = tentative_tail;
+ tail_time.val += diff.val;
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(
+ gpio_list[gpio_signals_by_no[signal_no]].mask);
+ /* To conserve bandwidth, timestamps are relative to `now`. */
+ ccprintf(" %d %lld %s\n", signal_no, tail_time.val - now.val,
+ slot->tail_level ? "F" : "R");
+ slot->tail_level = !slot->tail_level;
+ }
+ buf->tail = tail;
+ buf->tail_time = tail_time;
+ if (buf->overflow) {
+ ccprintf("Error: Buffer overflow\n");
+ }
+
+ return EC_SUCCESS;
+}
+
+static int command_gpio_monitoring_stop(int argc, const char **argv)
+{
+ int gpios[16];
+ int gpio_num = argc - 3;
+ int i;
+ struct cyclic_buffer_header_t *buf = NULL;
+ struct monitoring_slot_t *slot;
+
+ if (gpio_num <= 0 || gpio_num > 16)
+ return EC_ERROR_PARAM_COUNT;
+
+ for (i = 0; i < gpio_num; i++) {
+ gpios[i] = find_signal_by_name(argv[3 + i]);
+ if (gpios[i] == GPIO_COUNT)
+ return EC_ERROR_PARAM3 + i; /* May overflow */
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ if (slot->gpio_signal != gpios[i]) {
+ ccprintf("Error: Not monitoring %s\n",
+ gpio_list[gpios[i]].name);
+ return EC_ERROR_PARAM3 + i;
+ }
+ if (buf == NULL) {
+ buf = slot->buffer;
+ } else if (buf != slot->buffer) {
+ ccprintf(
+ "Error: Not monitoring %s as part of same groups as %s\n",
+ gpio_list[gpios[i]].name,
+ gpio_list[gpios[0]].name);
+ return EC_ERROR_PARAM3 + i;
+ }
+ }
+ if (gpio_num != buf->num_signals) {
+ ccprintf("Error: Not full set of signals monitored\n");
+ return EC_ERROR_INVAL;
+ }
+
+ for (i = 0; i < gpio_num; i++) {
+ gpio_disable_interrupt(gpios[i]);
+ }
+
+ /*
+ * With no more interrupts modifying the buffer, it can be deallocated.
+ */
+ num_cur_monitoring--;
+ for (i = 0; i < gpio_num; i++) {
+ slot = monitoring_slots +
+ GPIO_MASK_TO_NUM(gpio_list[gpios[i]].mask);
+ slot->gpio_signal = GPIO_COUNT;
+ slot->buffer = NULL;
+ }
+
+ if (buf->overflow)
+ atomic_sub(&num_cur_error_conditions, 1);
+
+ shared_mem_release((char *)buf);
+ return EC_SUCCESS;
+}
+
+static int command_gpio_monitoring(int argc, const char **argv)
+{
+ if (argc < 3)
+ return EC_ERROR_PARAM_COUNT;
+ if (!strcasecmp(argv[2], "start"))
+ return command_gpio_monitoring_start(argc, argv);
+ if (!strcasecmp(argv[2], "read"))
+ return command_gpio_monitoring_read(argc, argv);
+ if (!strcasecmp(argv[2], "stop"))
+ return command_gpio_monitoring_stop(argc, argv);
+ return EC_ERROR_PARAM2;
+}
+
+static int command_gpio(int argc, const char **argv)
+{
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+ if (!strcasecmp(argv[1], "monitoring"))
+ return command_gpio_monitoring(argc, argv);
+ if (!strcasecmp(argv[1], "multiset"))
+ return command_gpio_multiset(argc, argv);
+ return EC_ERROR_PARAM1;
+}
+DECLARE_CONSOLE_COMMAND_FLAGS(gpio, command_gpio,
+ "multiset PIN [level] [mode] [pullmode]"
+ "\nmonitoring start PIN"
+ "\nmonitoring read PIN"
+ "\nmonitoring stop PIN",
+ "GPIO manipulation", CMD_FLAG_RESTRICTED);
+
+static int command_reinit(int argc, const char **argv)
+{
+ stop_all_gpio_monitoring();
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND_FLAGS(reinit, command_reinit, "",
+ "Stop any ongoing operation",
+ CMD_FLAG_RESTRICTED);
+
+static void led_tick(void)
+{
+ /* Indicate ongoing GPIO monitoring by flashing the green LED. */
+ if (num_cur_monitoring)
+ gpio_set_level(GPIO_NUCLEO_LED1,
+ !gpio_get_level(GPIO_NUCLEO_LED1));
+ else {
+ /*
+ * If not flashing, leave the green LED on, to indicate that
+ * HyperDebug firmware is running and ready.
+ */
+ gpio_set_level(GPIO_NUCLEO_LED1, 1);
+ }
+ /* Indicate error conditions by flashing red LED. */
+ if (atomic_add(&num_cur_error_conditions, 0))
+ gpio_set_level(GPIO_NUCLEO_LED3,
+ !gpio_get_level(GPIO_NUCLEO_LED3));
+ else {
+ /*
+ * If not flashing, leave the red LED off.
+ */
+ gpio_set_level(GPIO_NUCLEO_LED3, 0);
+ }
+}
+DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
diff --git a/board/hyperdebug/gpio.inc b/board/hyperdebug/gpio.inc
index 3641dabea2..f13a2406ca 100644
--- a/board/hyperdebug/gpio.inc
+++ b/board/hyperdebug/gpio.inc
@@ -13,122 +13,123 @@
* symbolic name further below.
*/
-GPIO(CN7_1, PIN(C, 6), GPIO_INPUT)
-GPIO(CN7_2, PIN(B, 8), GPIO_ALTERNATE) /* I2C1 SCL */
-GPIO(CN7_3, PIN(D, 11), GPIO_INPUT)
-GPIO(CN7_4, PIN(B, 9), GPIO_ALTERNATE) /* I2C1 SDA */
-GPIO(CN7_5, PIN(B, 13), GPIO_INPUT)
+GPIO_INT(CN7_1, PIN(C, 6), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN7_2, PIN(B, 8), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C1 SCL */
+GPIO_INT(CN7_3, PIN(D, 11), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN7_4, PIN(B, 9), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C1 SDA */
+GPIO_INT(CN7_5, PIN(B, 13), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN7_6 is VREFP */
-GPIO(CN7_7, PIN(D, 12), GPIO_INPUT)
+GPIO_INT(CN7_7, PIN(D, 12), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN7_8 is GND */
-GPIO(CN7_9, PIN(A, 4), GPIO_INPUT) /* DAC0 */
-GPIO(CN7_10, PIN(A, 5), GPIO_INPUT) /* DAC1 */
-GPIO(CN7_11, PIN(B, 4), GPIO_INPUT)
-GPIO(CN7_12, PIN(A, 6), GPIO_INPUT)
-/*GPIO(CN7_13, PIN(B, 5), GPIO_INPUT) Nucleo USB-C */
-GPIO(CN7_14, PIN(A, 7), GPIO_INPUT)
-GPIO(CN7_15, PIN(B, 3), GPIO_INPUT)
-GPIO(CN7_16, PIN(D, 14), GPIO_INPUT)
-/*GPIO(CN7_17, PIN(A, 4), GPIO_INPUT)*/
-GPIO(CN7_18, PIN(D, 15), GPIO_INPUT)
-/*GPIO(CN7_19, PIN(B, 4), GPIO_INPUT)*/
-GPIO(CN7_20, PIN(F, 12), GPIO_INPUT)
+GPIO_INT(CN7_9, PIN(A, 4), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) /* DAC0 */
+GPIO_INT(CN7_10, PIN(A, 5), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) /* DAC1 */
+GPIO_INT(CN7_11, PIN(B, 4), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN7_12, PIN(A, 6), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN7_13, PIN(B, 5), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) Nucleo USB-C */
+GPIO_INT(CN7_14, PIN(A, 7), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN7_15, PIN(B, 3), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN7_16, PIN(D, 14), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN7_17, PIN(A, 4), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)*/
+GPIO_INT(CN7_18, PIN(D, 15), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN7_19, PIN(B, 4), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)*/
+GPIO_INT(CN7_20, PIN(F, 12), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN8_1 is NC */
-GPIO(CN8_2, PIN(C, 8), GPIO_INPUT)
+GPIO_INT(CN8_2, PIN(C, 8), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN8_3 is IOREF */
-GPIO(CN8_4, PIN(C, 9), GPIO_INPUT)
+GPIO_INT(CN8_4, PIN(C, 9), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN8_5 is NRST */
-GPIO(CN8_6, PIN(C, 10), GPIO_ALTERNATE) /* UART4 TX */
+GPIO_INT(CN8_6, PIN(C, 10), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART4 TX */
/* CN8_7 is 3V3 */
-GPIO(CN8_8, PIN(C, 11), GPIO_ALTERNATE) /* UART4 RX */
+GPIO_INT(CN8_8, PIN(C, 11), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART4 RX */
/* CN8_9 is 5V */
-GPIO(CN8_10, PIN(C, 12), GPIO_ALTERNATE) /* UART5 TX */
+GPIO_INT(CN8_10, PIN(C, 12), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART5 TX */
/* CN8_11 is GND */
-GPIO(CN8_12, PIN(D, 2), GPIO_ALTERNATE) /* UART5 RX */
+GPIO_INT(CN8_12, PIN(D, 2), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART5 RX */
/* CN8_13 is GND */
-GPIO(CN8_14, PIN(F, 3), GPIO_INPUT)
+GPIO_INT(CN8_14, PIN(F, 3), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN8_15 is VIN */
-GPIO(CN8_16, PIN(F, 5), GPIO_INPUT)
+GPIO_INT(CN8_16, PIN(F, 5), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
-GPIO(CN9_1, PIN(A, 3), GPIO_INPUT)
-GPIO(CN9_2, PIN(D, 7), GPIO_INPUT)
-GPIO(CN9_3, PIN(A, 2), GPIO_INPUT)
-GPIO(CN9_4, PIN(D, 6), GPIO_ALTERNATE) /* UART2 RX */
-GPIO(CN9_5, PIN(C, 3), GPIO_INPUT)
-GPIO(CN9_6, PIN(D, 5), GPIO_ALTERNATE) /* UART2 TX */
-GPIO(CN9_7, PIN(B, 0), GPIO_INPUT)
-GPIO(CN9_8, PIN(D, 4), GPIO_ALTERNATE) /* SPI2 CODI */
-GPIO(CN9_9, PIN(C, 1), GPIO_ALTERNATE) /* I2C3 SDA */
-GPIO(CN9_10, PIN(D, 3), GPIO_ALTERNATE) /* SPI2 CIDO */
-GPIO(CN9_11, PIN(C, 0), GPIO_ALTERNATE) /* I2C3 SCL */
+GPIO_INT(CN9_1, PIN(A, 3), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_2, PIN(D, 7), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_3, PIN(A, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_4, PIN(D, 6), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART2 RX */
+GPIO_INT(CN9_5, PIN(C, 3), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_6, PIN(D, 5), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART2 TX */
+GPIO_INT(CN9_7, PIN(B, 0), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_8, PIN(D, 4), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* SPI2 CODI */
+GPIO_INT(CN9_9, PIN(C, 1), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C3 SDA */
+GPIO_INT(CN9_10, PIN(D, 3), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* SPI2 CIDO */
+GPIO_INT(CN9_11, PIN(C, 0), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C3 SCL */
/* CN9_12 is GND */
-GPIO(CN9_13, PIN(B, 2), GPIO_INPUT)
-GPIO(CN9_14, PIN(E, 2), GPIO_INPUT)
-GPIO(CN9_15, PIN(B, 6), GPIO_INPUT)
-GPIO(CN9_16, PIN(E, 4), GPIO_INPUT)
-GPIO(CN9_17, PIN(F, 2), GPIO_INPUT)
-GPIO(CN9_18, PIN(E, 5), GPIO_INPUT)
-GPIO(CN9_19, PIN(F, 1), GPIO_ALTERNATE) /* I2C2 SCL */
-GPIO(CN9_20, PIN(E, 6), GPIO_INPUT)
-GPIO(CN9_21, PIN(F, 0), GPIO_ALTERNATE) /* I2C2 SDA */
-GPIO(CN9_22, PIN(E, 3), GPIO_INPUT)
+GPIO_INT(CN9_13, PIN(B, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_14, PIN(E, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_15, PIN(B, 6), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_16, PIN(E, 4), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_17, PIN(F, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_18, PIN(E, 5), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_19, PIN(F, 1), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C2 SCL */
+GPIO_INT(CN9_20, PIN(E, 6), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_21, PIN(F, 0), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* I2C2 SDA */
+GPIO_INT(CN9_22, PIN(E, 3), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN9_23 is GND */
-GPIO(CN9_24, PIN(F, 8), GPIO_INPUT)
-GPIO(CN9_25, PIN(D, 0), GPIO_OUT_HIGH) /* SPI2 CS */
-GPIO(CN9_26, PIN(F, 7), GPIO_INPUT)
-GPIO(CN9_27, PIN(D, 1), GPIO_ALTERNATE) /* SPI2 CLK */
-GPIO(CN9_28, PIN(F, 9), GPIO_INPUT)
-GPIO(CN9_29, PIN(G, 0), GPIO_INPUT)
-GPIO(CN9_30, PIN(G, 1), GPIO_INPUT)
+GPIO_INT(CN9_24, PIN(F, 8), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_25, PIN(D, 0), GPIO_OUT_HIGH | GPIO_INT_BOTH, gpio_edge) /* SPI2 CS */
+GPIO_INT(CN9_26, PIN(F, 7), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_27, PIN(D, 1), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* SPI2 CLK */
+GPIO_INT(CN9_28, PIN(F, 9), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_29, PIN(G, 0), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN9_30, PIN(G, 1), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN10_1 is AVDD */
-GPIO(CN10_2, PIN(F, 13), GPIO_INPUT)
+GPIO_INT(CN10_2, PIN(F, 13), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN10_3 is AGND */
-GPIO(CN10_4, PIN(E, 9), GPIO_INPUT)
+GPIO_INT(CN10_4, PIN(E, 9), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* CN10_5 is GND */
-GPIO(CN10_6, PIN(E, 11), GPIO_OUT_HIGH) /* QSPI CS */
-GPIO(CN10_7, PIN(B, 1), GPIO_INPUT)
-GPIO(CN10_8, PIN(F, 14), GPIO_INPUT)
-/*GPIO(CN10_9, PIN(C, 2), GPIO_INPUT) Nucleo USB VBUS sense */
-GPIO(CN10_10, PIN(E, 13), GPIO_ALTERNATE) /* QSPI D1 */
-GPIO(CN10_11, PIN(A, 1), GPIO_INPUT)
-GPIO(CN10_12, PIN(F, 15), GPIO_INPUT)
-/*GPIO(CN10_13, PIN(A, 2), GPIO_INPUT)*/
-GPIO(CN10_14, PIN(D, 8), GPIO_ALTERNATE) /* UART3 TX */
-GPIO(CN10_15, PIN(B, 10), GPIO_INPUT)
-GPIO(CN10_16, PIN(D, 9), GPIO_ALTERNATE) /* UART3 RX */
+GPIO_INT(CN10_6, PIN(E, 11), GPIO_OUT_HIGH | GPIO_INT_BOTH, gpio_edge) /* QSPI CS */
+GPIO_INT(CN10_7, PIN(B, 1), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN10_8, PIN(F, 14), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN10_9, PIN(C, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) Nucleo USB VBUS sense */
+GPIO_INT(CN10_10, PIN(E, 13), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* QSPI D1 */
+GPIO_INT(CN10_11, PIN(A, 1), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN10_12, PIN(F, 15), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN10_13, PIN(A, 2), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)*/
+GPIO_INT(CN10_14, PIN(D, 8), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART3 TX */
+GPIO_INT(CN10_15, PIN(B, 10), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN10_16, PIN(D, 9), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* UART3 RX */
/* CN10_17 is GND */
-GPIO(CN10_18, PIN(E, 8), GPIO_INPUT)
-GPIO(CN10_19, PIN(E, 15), GPIO_ALTERNATE) /* QSPI D3 */
-GPIO(CN10_20, PIN(E, 7), GPIO_INPUT)
-/*GPIO(CN10_21, PIN(B, 0), GPIO_INPUT)*/
+GPIO_INT(CN10_18, PIN(E, 8), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN10_19, PIN(E, 15), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* QSPI D3 */
+GPIO_INT(CN10_20, PIN(E, 7), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN10_21, PIN(B, 0), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)*/
/* CN10_22 is GND */
-GPIO(CN10_23, PIN(E, 12), GPIO_ALTERNATE) /* QSPI D0 */
-GPIO(CN10_24, PIN(E, 10), GPIO_ALTERNATE) /* QSPI CLK */
-GPIO(CN10_25, PIN(E, 14), GPIO_ALTERNATE) /* QSPI D2 */
-/*GPIO(CN10_26, PIN(E, 12), GPIO_INPUT) QSPI */
+GPIO_INT(CN10_23, PIN(E, 12), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* QSPI D0 */
+GPIO_INT(CN10_24, PIN(E, 10), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* QSPI CLK */
+GPIO_INT(CN10_25, PIN(E, 14), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge) /* QSPI D2 */
+/*GPIO_INT(CN10_26, PIN(E, 12), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) QSPI */
/* CN10_27 is GND */
-/*GPIO(CN10_28, PIN(E, 14), GPIO_INPUT) QSPI */
-GPIO(CN10_29, PIN(A, 0), GPIO_INPUT)
-/*GPIO(CN10_30, PIN(E, 15), GPIO_INPUT) QSPI */
-GPIO(CN10_31, PIN(A, 8), GPIO_INPUT)
-/*GPIO(CN10_32, PIN(B, 10), GPIO_INPUT)*/
-GPIO(CN10_33, PIN(E, 0), GPIO_INPUT)
-GPIO(CN10_34, PIN(B, 11), GPIO_INPUT)
+/*GPIO_INT(CN10_28, PIN(E, 14), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) QSPI */
+GPIO_INT(CN10_29, PIN(A, 0), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN10_30, PIN(E, 15), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) QSPI */
+GPIO_INT(CN10_31, PIN(A, 8), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+/*GPIO_INT(CN10_32, PIN(B, 10), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)*/
+GPIO_INT(CN10_33, PIN(E, 0), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(CN10_34, PIN(B, 11), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge)
/* These pins are used for USART and are set to alternate mode below */
-GPIO(LPUART1_HYPER_RX, PIN(G, 7), GPIO_ALTERNATE)
-GPIO(LPUART1_HYPER_TX, PIN(G, 8), GPIO_ALTERNATE)
+GPIO_INT(HYPER_CONSOLE_TX, PIN(G, 7), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge)
+GPIO_INT(HYPER_CONSOLE_RX, PIN(G, 8), GPIO_ALTERNATE | GPIO_INT_BOTH, gpio_edge)
/* USB pins */
GPIO(USB_FS_DM, PIN(A, 11), GPIO_ALTERNATE)
GPIO(USB_FS_DP, PIN(A, 12), GPIO_ALTERNATE)
/* Signals for hardware on the Nucleo board itself */
-GPIO(NUCLEO_LED1, PIN(C, 7), GPIO_OUT_HIGH) /* Green */
-GPIO(NUCLEO_LED2, PIN(B, 7), GPIO_OUT_LOW) /* Blue */
-GPIO(NUCLEO_LED3, PIN(A, 9), GPIO_OUT_LOW) /* Red */
+GPIO_INT(NUCLEO_LED1, PIN(C, 7), GPIO_OUT_HIGH | GPIO_INT_BOTH, gpio_edge) /* Green */
+GPIO_INT(NUCLEO_LED2, PIN(B, 7), GPIO_OUT_LOW | GPIO_INT_BOTH, gpio_edge) /* Blue */
+GPIO_INT(NUCLEO_LED3, PIN(A, 9), GPIO_OUT_LOW | GPIO_INT_BOTH, gpio_edge) /* Red */
+GPIO_INT(NUCLEO_USER_BTN, PIN(C, 13), GPIO_INPUT | GPIO_INT_BOTH, gpio_edge) /* User button */
/* Unimplemented signals since we are not an EC */
UNIMPLEMENTED(ENTERING_RW)
diff --git a/board/jinlon/thermal.c b/board/jinlon/thermal.c
index 70e6016109..6a18861af3 100644
--- a/board/jinlon/thermal.c
+++ b/board/jinlon/thermal.c
@@ -41,50 +41,50 @@ static const struct fan_step *fan_step_table;
static const struct fan_step fan_table_clamshell[] = {
{
/* level 0 */
- .on = { 0, -1, 54, 37 },
+ .on = { 0, -1, 54, 41 },
.off = { 99, -1, 99, 99 },
.rpm = { 0, 0 },
},
{
/* level 1 */
- .on = { 0, -1, 57, 39 },
- .off = { 99, -1, 54, 37 },
+ .on = { 0, -1, 57, 42 },
+ .off = { 99, -1, 54, 41 },
.rpm = { 3950, 3850 },
},
{
/* level 2 */
- .on = { 0, -1, 58, 40 },
- .off = { 99, -1, 57, 39 },
+ .on = { 0, -1, 58, 43 },
+ .off = { 99, -1, 57, 42 },
.rpm = { 4200, 4100 },
},
{
/* level 3 */
- .on = { 0, -1, 59, 41 },
- .off = { 99, -1, 58, 40 },
+ .on = { 0, -1, 59, 44 },
+ .off = { 99, -1, 58, 43 },
.rpm = { 4550, 4450 },
},
{
/* level 4 */
- .on = { 62, -1, 60, 42 },
- .off = { 58, -1, 59, 41 },
+ .on = { 62, -1, 60, 45 },
+ .off = { 58, -1, 59, 44 },
.rpm = { 4900, 4800 },
},
{
/* level 5 */
- .on = { 64, -1, 61, 43 },
- .off = { 62, -1, 60, 42 },
+ .on = { 64, -1, 61, 46 },
+ .off = { 62, -1, 60, 45 },
.rpm = { 5250, 5150 },
},
{
/* level 6 */
- .on = { 65, -1, 64, 45 },
- .off = { 63, -1, 61, 43 },
+ .on = { 65, -1, 64, 47 },
+ .off = { 63, -1, 61, 46 },
.rpm = { 5400, 5300 },
},
{
/* level 7 */
.on = { 100, -1, 100, 100 },
- .off = { 65, -1, 62, 44 },
+ .off = { 65, -1, 62, 47 },
.rpm = { 6000, 5900 },
},
};
diff --git a/board/kuldax/board.c b/board/kuldax/board.c
index 922a7a3a75..c462672ba8 100644
--- a/board/kuldax/board.c
+++ b/board/kuldax/board.c
@@ -12,6 +12,7 @@
#include "console.h"
#include "cros_board_info.h"
#include "driver/tcpm/tcpci.h"
+#include "driver/wpc/cps8100.h"
#include "fw_config.h"
#include "gpio.h"
#include "gpio_signal.h"
@@ -41,7 +42,6 @@ const int usb_port_enable[USB_PORT_COUNT] = {
};
BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT);
-extern struct pchg_drv cps8100_drv;
struct pchg pchgs[] = {
[0] = {
.cfg = &(const struct pchg_config) {
@@ -58,7 +58,6 @@ struct pchg pchgs[] = {
.events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
},
};
-const int pchg_count = ARRAY_SIZE(pchgs);
__override void board_pchg_power_on(int port, bool on)
{
@@ -68,6 +67,15 @@ __override void board_pchg_power_on(int port, bool on)
CPRINTS("%s: Invalid port=%d", __func__, port);
}
+int board_get_pchg_count(void)
+{
+ if (ec_cfg_has_peripheral_charger()) {
+ return ARRAY_SIZE(pchgs);
+ } else {
+ return 0;
+ }
+}
+
/******************************************************************************/
int board_set_active_charge_port(int port)
diff --git a/board/kuldax/fw_config.c b/board/kuldax/fw_config.c
index 4229f3bed1..7f0204f667 100644
--- a/board/kuldax/fw_config.c
+++ b/board/kuldax/fw_config.c
@@ -71,3 +71,8 @@ void ec_bj_power(uint32_t *voltage, uint32_t *current)
*voltage = bj_power[bj].voltage;
*current = bj_power[bj].current;
}
+
+bool ec_cfg_has_peripheral_charger(void)
+{
+ return (fw_config.peripheral_charger == PERIPHERAL_CHARGER_ENABLE);
+}
diff --git a/board/kuldax/fw_config.h b/board/kuldax/fw_config.h
index d7fa0a11a9..cdba1b16d7 100644
--- a/board/kuldax/fw_config.h
+++ b/board/kuldax/fw_config.h
@@ -17,11 +17,20 @@ enum ec_cfg_audio_type { DB_AUDIO_UNKNOWN = 0, DB_NAU88L25B_I2S = 1 };
enum ec_cfg_bj_power { BJ_150W = 0, BJ_230W = 1, BJ_65W = 2, BJ_135W = 3 };
+/*
+ * Peripheral charger (Bits 5)
+ */
+enum ec_cfg_peripheral_charger {
+ PERIPHERAL_CHARGER_ENABLE = 0,
+ PERIPHERAL_CHARGER_DISABLE = 1
+};
+
union brask_cbi_fw_config {
struct {
uint32_t audio : 3;
uint32_t bj_power : 2;
- uint32_t reserved_1 : 27;
+ uint32_t peripheral_charger : 1;
+ uint32_t reserved_1 : 26;
};
uint32_t raw_value;
};
@@ -38,4 +47,9 @@ union brask_cbi_fw_config get_fw_config(void);
*/
void ec_bj_power(uint32_t *voltage, uint32_t *current);
+/**
+ * SWITCH the peripheral charger function enable/disable from FW_CONFIG.
+ */
+bool ec_cfg_has_peripheral_charger(void);
+
#endif /* __BOARD_BRASK_FW_CONFIG_H_ */
diff --git a/board/nautilus/battery.c b/board/nautilus/battery.c
index c36d48a69a..8f0c4baa4e 100644
--- a/board/nautilus/battery.c
+++ b/board/nautilus/battery.c
@@ -30,6 +30,8 @@ static enum battery_present batt_pres_prev = BP_NOT_SURE;
#define CHARGING_VOLTAGE_MV_SAFE 8400
#define CHARGING_CURRENT_MA_SAFE 1500
+#define CHARGING_VOLTAGE_MV_ADJUST 8600
+#define CHARGING_CURRENT_MA_ADJUST 3200
static const struct battery_info info = {
.voltage_max = 8600,
@@ -88,7 +90,11 @@ int charger_profile_override(struct charge_state_data *curr)
} temp_zone;
current = curr->requested_current;
+ if (current > CHARGING_CURRENT_MA_ADJUST)
+ current = CHARGING_CURRENT_MA_ADJUST;
voltage = curr->requested_voltage;
+ if (voltage > CHARGING_VOLTAGE_MV_ADJUST)
+ voltage = CHARGING_VOLTAGE_MV_ADJUST;
bat_temp_c = curr->batt.temperature - 2731;
/*
diff --git a/board/nocturne_fp/build.mk b/board/nocturne_fp/build.mk
index 08d803be20..49d5db1582 100644
--- a/board/nocturne_fp/build.mk
+++ b/board/nocturne_fp/build.mk
@@ -65,6 +65,7 @@ test-list-y=\
system_is_locked \
timer \
timer_dos \
+ tpm_seed_clear \
utils \
utils_str \
diff --git a/board/omnigul/board.c b/board/omnigul/board.c
index 93d32aa0e4..0c963416f2 100644
--- a/board/omnigul/board.c
+++ b/board/omnigul/board.c
@@ -4,14 +4,11 @@
*/
#include "button.h"
-#include "cbi.h"
-#include "charge_ramp.h"
#include "charger.h"
#include "common.h"
#include "console.h"
#include "driver/accel_lis2dw12.h"
#include "driver/accelgyro_lsm6dso.h"
-#include "driver/als_tcs3400.h"
#include "fw_config.h"
#include "gpio.h"
#include "gpio_signal.h"
@@ -32,11 +29,6 @@
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ##args)
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ##args)
-__override void board_cbi_init(void)
-{
- config_usb_db_type();
-}
-
/* Called on AP S3 -> S0 transition */
static void board_chipset_resume(void)
{
diff --git a/board/omnigul/board.h b/board/omnigul/board.h
index 2f260f88f8..73140b6fb3 100644
--- a/board/omnigul/board.h
+++ b/board/omnigul/board.h
@@ -28,7 +28,7 @@
/* LED */
#define CONFIG_LED_PWM
-#define CONFIG_LED_PWM_COUNT 2
+#define CONFIG_LED_PWM_COUNT 1
#undef CONFIG_LED_PWM_NEAR_FULL_COLOR
#undef CONFIG_LED_PWM_SOC_ON_COLOR
#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR
@@ -43,13 +43,6 @@
#define CONFIG_ACCEL_LSM6DSO_INT_EVENT \
TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL)
-/* TCS3400 ALS */
-#define CONFIG_ALS
-#define ALS_COUNT 1
-#define CONFIG_ALS_TCS3400
-#define CONFIG_ALS_TCS3400_INT_EVENT \
- TASK_EVENT_MOTION_SENSOR_INTERRUPT(CLEAR_ALS)
-
/* Enable sensor fifo, must also define the _SIZE and _THRES */
#define CONFIG_ACCEL_FIFO
/* FIFO size is in power of 2. */
@@ -57,9 +50,6 @@
/* Depends on how fast the AP boots and typical ODRs */
#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3)
-/* Sensors without hardware interrupt are in forced mode */
-#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(CLEAR_ALS)
-
/* Lid accel */
#define CONFIG_LID_ANGLE
#define CONFIG_LID_ANGLE_UPDATE
@@ -82,13 +72,14 @@
#define CONFIG_IO_EXPANDER
#define CONFIG_IO_EXPANDER_NCT38XX
-#define CONFIG_IO_EXPANDER_PORT_COUNT 2
+#define CONFIG_IO_EXPANDER_PORT_COUNT 1
#define CONFIG_USB_PD_FRS_PPC
#define CONFIG_USB_PD_TCPM_PS8815
#define CONFIG_USB_PD_TCPM_PS8815_FORCE_DID
-#define CONFIG_USBC_RETIMER_INTEL_BB
+#undef CONFIG_USB_CHARGER
+#undef CONFIG_BC12_DETECT_PI3USB9201
/* I2C speed console command */
#define CONFIG_CMD_I2C_SPEED
@@ -105,11 +96,11 @@
#define PD_VCONN_SWAP_DELAY 5000 /* us */
/*
- * Passive USB-C cables only support up to 60W.
+ * Passive USB-C cables only support up to 65W.
*/
#define PD_OPERATING_POWER_MW 15000
-#define PD_MAX_POWER_MW 60000
-#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_POWER_MW 65000
+#define PD_MAX_CURRENT_MA 3250
#define PD_MAX_VOLTAGE_MV 20000
/*
@@ -153,16 +144,12 @@
#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0
-#define I2C_PORT_USB_C0_C2_TCPC NPCX_I2C_PORT1_0
+#define I2C_PORT_USB_C0_TCPC NPCX_I2C_PORT1_0
#define I2C_PORT_USB_C1_TCPC NPCX_I2C_PORT4_1
-#define I2C_PORT_USB_C0_C2_PPC NPCX_I2C_PORT2_0
+#define I2C_PORT_USB_C0_PPC NPCX_I2C_PORT2_0
#define I2C_PORT_USB_C1_PPC NPCX_I2C_PORT6_1
-#define I2C_PORT_USB_C0_C2_BC12 NPCX_I2C_PORT2_0
-#define I2C_PORT_USB_C1_BC12 NPCX_I2C_PORT6_1
-
-#define I2C_PORT_USB_C0_C2_MUX NPCX_I2C_PORT3_0
#define I2C_PORT_USB_C1_MUX NPCX_I2C_PORT6_1
#define I2C_PORT_BATTERY NPCX_I2C_PORT5_0
@@ -200,12 +187,16 @@
/* Charger defines */
#define CONFIG_CHARGER_ISL9241
-#define CONFIG_CHARGE_RAMP_SW
#define CONFIG_CHARGER_SENSE_RESISTOR 10
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10
#undef CONFIG_CHARGER_INPUT_CURRENT_DERATE_PCT
#define CONFIG_CHARGER_INPUT_CURRENT_DERATE_PCT 10
+/* KEYBOARD */
+#define CONFIG_KEYBOARD_CUSTOMIZATION
+#define CONFIG_KEYBOARD_VIVALDI
+#define CONFIG_KEYBOARD_REFRESH_ROW3
+
/*
* Older boards have a different ADC assignment.
*/
@@ -222,7 +213,6 @@ enum adc_channel {
ADC_TEMP_SENSOR_1_DDR_SOC,
ADC_TEMP_SENSOR_2_AMBIENT,
ADC_TEMP_SENSOR_3_CHARGER,
- ADC_TEMP_SENSOR_4_WWAN,
ADC_CH_COUNT
};
@@ -230,18 +220,10 @@ enum temp_sensor_id {
TEMP_SENSOR_1_DDR_SOC,
TEMP_SENSOR_2_AMBIENT,
TEMP_SENSOR_3_CHARGER,
- TEMP_SENSOR_4_WWAN,
TEMP_SENSOR_COUNT
};
-enum sensor_id {
- LID_ACCEL = 0,
- BASE_ACCEL,
- BASE_GYRO,
- CLEAR_ALS,
- RGB_ALS,
- SENSOR_COUNT
-};
+enum sensor_id { LID_ACCEL = 0, BASE_ACCEL, BASE_GYRO, SENSOR_COUNT };
enum ioex_port { IOEX_C0_NCT38XX = 0, IOEX_C2_NCT38XX, IOEX_PORT_COUNT };
@@ -249,11 +231,9 @@ enum battery_type { BATTERY_AP19B8M, BATTERY_AP20CBL, BATTERY_TYPE_COUNT };
enum pwm_channel {
PWM_CH_LED2 = 0, /* PWM0 (white charger) */
- PWM_CH_LED3, /* PWM1 (orange on DB) */
PWM_CH_LED1, /* PWM2 (orange charger) */
PWM_CH_KBLIGHT, /* PWM3 */
PWM_CH_FAN, /* PWM5 */
- PWM_CH_LED4, /* PWM7 (white on DB) */
PWM_CH_COUNT
};
diff --git a/board/omnigul/build.mk b/board/omnigul/build.mk
index 87e1ebf7e6..d8488c6b9d 100644
--- a/board/omnigul/build.mk
+++ b/board/omnigul/build.mk
@@ -23,3 +23,4 @@ board-y+=led.o
board-y+=pwm.o
board-y+=sensors.o
board-y+=usbc_config.o
+board-y+=keyboard_customization.o
diff --git a/board/omnigul/ec.tasklist b/board/omnigul/ec.tasklist
index 65410deb84..c2ef5f48cc 100644
--- a/board/omnigul/ec.tasklist
+++ b/board/omnigul/ec.tasklist
@@ -12,10 +12,6 @@
#define CONFIG_TASK_LIST \
TASK_ALWAYS(HOOKS, hook_task, NULL, HOOKS_TASK_STACK_SIZE) \
- TASK_ALWAYS(CHG_RAMP, chg_ramp_task, NULL, BASEBOARD_CHG_RAMP_TASK_STACK_SIZE) \
- TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \
- TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 0, TASK_STACK_SIZE) \
- TASK_ALWAYS(USB_CHG_P2, usb_charger_task, 0, TASK_STACK_SIZE) \
TASK_ALWAYS(CHARGER, charger_task, NULL, BASEBOARD_CHARGER_TASK_STACK_SIZE) \
TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \
@@ -27,6 +23,5 @@
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_C0, pd_task, NULL, BASEBOARD_PD_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_C1, pd_task, NULL, BASEBOARD_PD_TASK_STACK_SIZE) \
- TASK_ALWAYS(PD_C2, pd_task, NULL, BASEBOARD_PD_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_INT_C0, pd_shared_alert_task, (BIT(2) | BIT(0)), BASEBOARD_PD_INT_TASK_STACK_SIZE) \
TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, BASEBOARD_PD_INT_TASK_STACK_SIZE)
diff --git a/board/omnigul/generated-gpio.inc b/board/omnigul/generated-gpio.inc
index f4772188a5..d7f950ca48 100644
--- a/board/omnigul/generated-gpio.inc
+++ b/board/omnigul/generated-gpio.inc
@@ -5,7 +5,6 @@
/* INTERRUPT GPIOs: */
GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt)
GPIO_INT(EC_ACCEL_INT_R_L, PIN(8, 1), GPIO_SEL_1P8V | GPIO_INT_FALLING, lis2dw12_interrupt)
-GPIO_INT(EC_ALS_RGB_INT_R_L, PIN(D, 4), GPIO_INT_FALLING, tcs3400_interrupt)
GPIO_INT(EC_IMU_INT_R_L, PIN(5, 6), GPIO_SEL_1P8V | GPIO_INT_FALLING, lsm6dso_interrupt)
GPIO_INT(EC_PROCHOT_IN_L, PIN(F, 0), GPIO_INT_BOTH, throttle_ap_prochot_input_interrupt)
GPIO_INT(EC_VOLDN_BTN_ODL, PIN(9, 3), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt)
@@ -20,16 +19,10 @@ GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, power_signal_
GPIO_INT(SLP_SUS_L, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(SYS_SLP_S0IX_L, PIN(D, 5), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(TABLET_MODE_L, PIN(9, 5), GPIO_INT_BOTH, gmr_tablet_switch_isr)
-GPIO_INT(USB_C0_BC12_INT_ODL, PIN(C, 6), GPIO_INT_FALLING, bc12_interrupt)
-GPIO_INT(USB_C0_C2_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, tcpc_alert_event)
+GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, tcpc_alert_event)
GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, ppc_interrupt)
-GPIO_INT(USB_C0_RT_INT_ODL, PIN(B, 1), GPIO_INT_FALLING, retimer_interrupt)
-GPIO_INT(USB_C1_BC12_INT_ODL, PIN(5, 0), GPIO_INT_FALLING, bc12_interrupt)
GPIO_INT(USB_C1_PPC_INT_ODL, PIN(F, 5), GPIO_INT_FALLING, ppc_interrupt)
GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert_event)
-GPIO_INT(USB_C2_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt)
-GPIO_INT(USB_C2_PPC_INT_ODL, PIN(7, 0), GPIO_INT_FALLING, ppc_interrupt)
-GPIO_INT(USB_C2_RT_INT_ODL, PIN(4, 1), GPIO_INT_FALLING, retimer_interrupt)
/* USED GPIOs: */
GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT)
@@ -45,12 +38,10 @@ GPIO(EC_I2C_MISC_SCL_R, PIN(B, 3), GPIO_INPUT)
GPIO(EC_I2C_MISC_SDA_R, PIN(B, 2), GPIO_INPUT)
GPIO(EC_I2C_SENSOR_SCL, PIN(B, 5), GPIO_INPUT | GPIO_SEL_1P8V)
GPIO(EC_I2C_SENSOR_SDA, PIN(B, 4), GPIO_INPUT | GPIO_SEL_1P8V)
-GPIO(EC_I2C_USB_C0_C2_PPC_BC_SCL, PIN(9, 2), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_C2_PPC_BC_SDA, PIN(9, 1), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_C2_RT_SCL, PIN(D, 1), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_C2_RT_SDA, PIN(D, 0), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_C2_TCPC_SCL, PIN(9, 0), GPIO_INPUT)
-GPIO(EC_I2C_USB_C0_C2_TCPC_SDA, PIN(8, 7), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_PPC_BC_SCL, PIN(9, 2), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_PPC_BC_SDA, PIN(9, 1), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_TCPC_SCL, PIN(9, 0), GPIO_INPUT)
+GPIO(EC_I2C_USB_C0_TCPC_SDA, PIN(8, 7), GPIO_INPUT)
GPIO(EC_I2C_USB_C1_MIX_SCL, PIN(E, 4), GPIO_INPUT)
GPIO(EC_I2C_USB_C1_MIX_SDA, PIN(E, 3), GPIO_INPUT)
GPIO(EC_I2C_USB_C1_TCPC_SCL, PIN(F, 3), GPIO_INPUT)
@@ -70,9 +61,8 @@ GPIO(EN_S5_RAILS, PIN(B, 6), GPIO_OUT_LOW)
GPIO(IMVP9_VRRDY_OD, PIN(4, 3), GPIO_INPUT)
GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW)
GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
-GPIO(USB_C0_C2_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
+GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW)
GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW)
-GPIO(USB_C1_RST_ODL, PIN(9, 6), GPIO_ODR_LOW)
GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT)
GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_LOW)
GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW)
@@ -121,5 +111,15 @@ UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */
UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */
UNUSED(PIN(6, 6)) /* GPIO66 */
UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */
+UNUSED(PIN(4, 1)) /*GPIO41/ADC4*/
+UNUSED(PIN(7, 0)) /*GPIO70/PS2_DAT0*/
+UNUSED(PIN(8, 3)) /*GPIO83/KSO15*/
+UNUSED(PIN(9, 6)) /*GPIO96/F_DIO1*/
+UNUSED(PIN(B, 1)) /*GPIOB1/KSO17/CR_SIN4*/
+UNUSED(PIN(D, 0)) /*GPIOD0/I2C3_SDA0*/
+UNUSED(PIN(D, 1)) /*GPIOD1/I2C3_SCL0*/
+UNUSED(PIN(D, 4)) /*GPIOD4/CR_SIN3*/
+UNUSED(PIN(C, 6)) /*GPIOC6/SMI*/
+UNUSED(PIN(5, 0)) /*GPIO50*/
/* Pre-configured PSL balls: J8 K6 */
diff --git a/board/omnigul/gpio.inc b/board/omnigul/gpio.inc
index 2c841123c0..0bb243eefe 100644
--- a/board/omnigul/gpio.inc
+++ b/board/omnigul/gpio.inc
@@ -35,9 +35,4 @@ GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW)
IOEX(USB_C0_OC_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 4), GPIO_ODR_HIGH)
IOEX(USB_C0_FRS_EN, EXPIN(IOEX_C0_NCT38XX, 0, 6), GPIO_OUT_LOW)
IOEX(USB_C0_RT_RST_ODL, EXPIN(IOEX_C0_NCT38XX, 0, 7), GPIO_ODR_LOW)
-
-IOEX(USB_C2_RT_RST_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 2), GPIO_ODR_LOW)
-IOEX(USB_C1_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 3), GPIO_ODR_HIGH)
-IOEX(USB_C2_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 4), GPIO_ODR_HIGH)
-IOEX(USB_C2_FRS_EN, EXPIN(IOEX_C2_NCT38XX, 0, 6), GPIO_OUT_LOW)
/* GPIO07_P2 to PU */
diff --git a/board/omnigul/i2c.c b/board/omnigul/i2c.c
index 839813723f..1dfad89ee4 100644
--- a/board/omnigul/i2c.c
+++ b/board/omnigul/i2c.c
@@ -21,27 +21,19 @@ const struct i2c_port_t i2c_ports[] = {
},
{
/* I2C1 */
- .name = "tcpc0,2",
- .port = I2C_PORT_USB_C0_C2_TCPC,
+ .name = "tcpc0",
+ .port = I2C_PORT_USB_C0_TCPC,
.kbps = 1000,
- .scl = GPIO_EC_I2C_USB_C0_C2_TCPC_SCL,
- .sda = GPIO_EC_I2C_USB_C0_C2_TCPC_SDA,
+ .scl = GPIO_EC_I2C_USB_C0_TCPC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_TCPC_SDA,
},
{
/* I2C2 */
- .name = "ppc0,2",
- .port = I2C_PORT_USB_C0_C2_PPC,
+ .name = "ppc0",
+ .port = I2C_PORT_USB_C0_PPC,
.kbps = 1000,
- .scl = GPIO_EC_I2C_USB_C0_C2_PPC_BC_SCL,
- .sda = GPIO_EC_I2C_USB_C0_C2_PPC_BC_SDA,
- },
- {
- /* I2C3 */
- .name = "retimer0,2",
- .port = I2C_PORT_USB_C0_C2_MUX,
- .kbps = 1000,
- .scl = GPIO_EC_I2C_USB_C0_C2_RT_SCL,
- .sda = GPIO_EC_I2C_USB_C0_C2_RT_SDA,
+ .scl = GPIO_EC_I2C_USB_C0_PPC_BC_SCL,
+ .sda = GPIO_EC_I2C_USB_C0_PPC_BC_SDA,
},
{
/* I2C4 C1 TCPC */
diff --git a/board/omnigul/keyboard.c b/board/omnigul/keyboard.c
index b3d7bcd7c2..8e26876a73 100644
--- a/board/omnigul/keyboard.c
+++ b/board/omnigul/keyboard.c
@@ -4,6 +4,7 @@
*/
#include "common.h"
+#include "ec_commands.h"
#include "keyboard_scan.h"
#include "timer.h"
@@ -18,7 +19,57 @@ __override struct keyboard_scan_config keyscan_config = {
.min_post_scan_delay_us = 1000,
.poll_timeout_us = 100 * MSEC,
.actual_key_mask = {
- 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,
- 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
+ 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xa4, 0xff, 0xf7, 0x55, 0xfb, 0xca /* full set */
},
};
+
+static const struct ec_response_keybd_config omnigul_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 &omnigul_kb;
+}
+
+/*
+ * Row Column info for Top row keys T1 - T15.
+ * on mithrax_kb keyboard Row Column is customization
+ * need define row col to mapping matrix layout.
+ */
+__override const struct key {
+ uint8_t row;
+ uint8_t col;
+} vivaldi_keys[] = {
+ { .row = 0, .col = 2 }, /* T1 */
+ { .row = 3, .col = 2 }, /* T2 */
+ { .row = 2, .col = 2 }, /* T3 */
+ { .row = 1, .col = 2 }, /* T4 */
+ { .row = 3, .col = 4 }, /* T5 */
+ { .row = 2, .col = 4 }, /* T6 */
+ { .row = 1, .col = 4 }, /* T7 */
+ { .row = 2, .col = 9 }, /* T8 */
+ { .row = 1, .col = 9 }, /* T9 */
+ { .row = 0, .col = 4 }, /* T10 */
+ { .row = 3, .col = 0 }, /* T11 */
+ { .row = 1, .col = 5 }, /* T12 */
+ { .row = 3, .col = 5 }, /* T13 */
+ { .row = 0, .col = 9 }, /* T14 */
+ { .row = 0, .col = 11 }, /* T15 */
+};
+BUILD_ASSERT(ARRAY_SIZE(vivaldi_keys) == MAX_TOP_ROW_KEYS);
diff --git a/board/omnigul/keyboard_customization.c b/board/omnigul/keyboard_customization.c
new file mode 100644
index 0000000000..54565c5b96
--- /dev/null
+++ b/board/omnigul/keyboard_customization.c
@@ -0,0 +1,102 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "keyboard_8042_sharedlib.h"
+#include "keyboard_config.h"
+#include "keyboard_customization.h"
+#include "keyboard_protocol.h"
+#include "keyboard_raw.h"
+
+static uint16_t scancode_set2[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = {
+ { 0x0000, 0x0000, 0x0014, 0x0000, 0xe014, 0x0000, 0x0000, 0x0000 },
+ { 0x0058, 0x0076, 0x000d, 0x000e, 0x001c, 0x001a, 0x0016, 0x0015 },
+ { 0x0005, 0x000c, 0x0004, 0x0006, 0x0023, 0x0021, 0x0026, 0x0024 },
+ { 0x0032, 0x0034, 0x002c, 0x002e, 0x002b, 0x002a, 0x0025, 0x002d },
+ { 0x000a, 0x0083, 0x000b, 0x0003, 0x001b, 0x0022, 0x001e, 0x001d },
+ { 0x0051, 0x0000, 0x005b, 0x0000, 0x0042, 0x0041, 0x003e, 0x0043 },
+ { 0x0031, 0x0033, 0x0035, 0x0036, 0x003b, 0x003a, 0x003d, 0x003c },
+ { 0x0000, 0x0000, 0x0061, 0x0000, 0x0000, 0x0012, 0x0000, 0x0059 },
+ { 0x0055, 0x0052, 0x0054, 0x004e, 0x004c, 0x004a, 0x0045, 0x004d },
+ { 0x0000, 0x0078, 0x0009, 0x0000, 0x004b, 0x0049, 0x0046, 0x0044 },
+ { 0xe011, 0x0000, 0x006a, 0x0000, 0x005d, 0x0000, 0x0011, 0x0000 },
+ { 0x0000, 0x0066, 0x0000, 0x005d, 0x005a, 0x0029, 0xe072, 0xe075 },
+ { 0x0000, 0xe064, 0x0000, 0x0067, 0x0000, 0x0000, 0xe074, 0xe06b },
+};
+
+uint16_t get_scancode_set2(uint8_t row, uint8_t col)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ return scancode_set2[col][row];
+ return 0;
+}
+
+void set_scancode_set2(uint8_t row, uint8_t col, uint16_t val)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ scancode_set2[col][row] = val;
+}
+
+void board_keyboard_drive_col(int col)
+{
+ /* Drive all lines to high */
+ if (col == KEYBOARD_COLUMN_NONE)
+ gpio_set_level(GPIO_KBD_KSO2, 0);
+
+ /* Set KBSOUT to zero to detect key-press */
+ else if (col == KEYBOARD_COLUMN_ALL)
+ gpio_set_level(GPIO_KBD_KSO2, 1);
+
+ /* Drive one line for detection */
+ else {
+ if (col == 2)
+ gpio_set_level(GPIO_KBD_KSO2, 1);
+ else
+ gpio_set_level(GPIO_KBD_KSO2, 0);
+ }
+}
+
+#ifdef CONFIG_KEYBOARD_DEBUG
+static uint8_t keycap_label[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = {
+ { 'c', KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO },
+ { KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { 'q', KLLI_UNKNO, KLLI_UNKNO, KLLI_TAB, '`', '1', KLLI_UNKNO, 'a' },
+ { KLLI_R_ALT, KLLI_L_ALT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { KLLI_UNKNO, KLLI_SPACE, 'e', KLLI_F4, KLLI_SEARC, '3', KLLI_F3,
+ KLLI_UNKNO },
+ { 'x', 'z', KLLI_F2, KLLI_F1, 's', '2', 'w', KLLI_ESC },
+ { 'v', 'b', 'g', 't', '5', '4', 'r', 'f' },
+ { 'm', 'n', 'h', 'y', '6', '7', 'u', 'j' },
+ { '.', KLLI_DOWN, '\\', 'o', KLLI_F10, '9', KLLI_UNKNO, 'l' },
+ { KLLI_R_SHT, KLLI_L_SHT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { ',', KLLI_UNKNO, KLLI_F7, KLLI_F6, KLLI_F5, '8', 'i', 'k' },
+ { KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_F9, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_LEFT, KLLI_UNKNO },
+ { KLLI_R_CTR, KLLI_L_CTR, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { '/', KLLI_UP, '-', KLLI_UNKNO, '0', 'p', '[', ';' },
+ { '\'', KLLI_ENTER, KLLI_UNKNO, KLLI_UNKNO, '=', KLLI_B_SPC, ']', 'd' },
+ { KLLI_UNKNO, KLLI_F8, KLLI_RIGHT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO },
+};
+
+uint8_t get_keycap_label(uint8_t row, uint8_t col)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ return keycap_label[col][row];
+ return KLLI_UNKNO;
+}
+
+void set_keycap_label(uint8_t row, uint8_t col, uint8_t val)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ keycap_label[col][row] = val;
+}
+#endif
diff --git a/board/omnigul/keyboard_customization.h b/board/omnigul/keyboard_customization.h
new file mode 100644
index 0000000000..8e7e3ee2c1
--- /dev/null
+++ b/board/omnigul/keyboard_customization.h
@@ -0,0 +1,80 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Keyboard configuration */
+
+#ifndef __KEYBOARD_CUSTOMIZATION_H
+#define __KEYBOARD_CUSTOMIZATION_H
+
+#define KEYBOARD_MASK_PWRBTN KEYBOARD_ROW_TO_MASK(3)
+
+/*
+ * KEYBOARD_COLS_MAX has the build time column size. It's used to allocate
+ * exact spaces for arrays. Actual keyboard scanning is done using
+ * keyboard_cols, which holds a runtime column size.
+ */
+#ifdef CONFIG_KEYBOARD_CUSTOMIZATION
+#undef KEYBOARD_COLS_MAX
+#undef KEYBOARD_ROWS
+
+#define KEYBOARD_COLS_MAX 13
+#define KEYBOARD_ROWS 8
+#endif
+
+/*
+ * WARNING: Do not directly modify it. You should call keyboard_raw_set_cols,
+ * instead. It checks whether you're eligible or not.
+ */
+extern uint8_t keyboard_cols;
+
+#define KEYBOARD_ROW_TO_MASK(r) (1 << (r))
+
+/* Columns and masks for keys we particularly care about */
+#define KEYBOARD_COL_DOWN 11
+#define KEYBOARD_ROW_DOWN 6
+#define KEYBOARD_MASK_DOWN KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_DOWN)
+#define KEYBOARD_COL_ESC 1
+#define KEYBOARD_ROW_ESC 1
+#define KEYBOARD_MASK_ESC KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_ESC)
+#define KEYBOARD_COL_KEY_H 6
+#define KEYBOARD_ROW_KEY_H 1
+#define KEYBOARD_MASK_KEY_H KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_H)
+#define KEYBOARD_COL_KEY_R 3
+#define KEYBOARD_ROW_KEY_R 7
+#define KEYBOARD_MASK_KEY_R KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_R)
+#define KEYBOARD_COL_LEFT_ALT 10
+#define KEYBOARD_ROW_LEFT_ALT 6
+#define KEYBOARD_MASK_LEFT_ALT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_ALT)
+#define KEYBOARD_COL_REFRESH 2
+#define KEYBOARD_ROW_REFRESH 3
+#define KEYBOARD_MASK_REFRESH KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_REFRESH)
+#define KEYBOARD_COL_RIGHT_ALT 10
+#define KEYBOARD_ROW_RIGHT_ALT 0
+#define KEYBOARD_MASK_RIGHT_ALT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_RIGHT_ALT)
+#define KEYBOARD_DEFAULT_COL_VOL_UP 4
+#define KEYBOARD_DEFAULT_ROW_VOL_UP 0
+#define KEYBOARD_COL_LEFT_CTRL 0
+#define KEYBOARD_ROW_LEFT_CTRL 2
+#define KEYBOARD_MASK_LEFT_CTRL KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_CTRL)
+#define KEYBOARD_COL_RIGHT_CTRL 0
+#define KEYBOARD_ROW_RIGHT_CTRL 4
+#define KEYBOARD_MASK_RIGHT_CTRL KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_RIGHT_CTRL)
+#define KEYBOARD_COL_SEARCH 1
+#define KEYBOARD_ROW_SEARCH 0
+#define KEYBOARD_MASK_SEARCH KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_SEARCH)
+#define KEYBOARD_COL_KEY_0 8
+#define KEYBOARD_ROW_KEY_0 6
+#define KEYBOARD_MASK_KEY_0 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_0)
+#define KEYBOARD_COL_KEY_1 1
+#define KEYBOARD_ROW_KEY_1 6
+#define KEYBOARD_MASK_KEY_1 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_1)
+#define KEYBOARD_COL_KEY_2 4
+#define KEYBOARD_ROW_KEY_2 6
+#define KEYBOARD_MASK_KEY_2 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_2)
+#define KEYBOARD_COL_LEFT_SHIFT 7
+#define KEYBOARD_ROW_LEFT_SHIFT 5
+#define KEYBOARD_MASK_LEFT_SHIFT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_SHIFT)
+
+#endif /* __KEYBOARD_CUSTOMIZATION_H */
diff --git a/board/omnigul/led.c b/board/omnigul/led.c
index 2d9e9220a0..00368f553b 100644
--- a/board/omnigul/led.c
+++ b/board/omnigul/led.c
@@ -20,7 +20,6 @@
const enum ec_led_id supported_led_ids[] = {
EC_LED_ID_LEFT_LED,
- EC_LED_ID_RIGHT_LED,
};
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
@@ -45,13 +44,6 @@ struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = {
.enable = &pwm_enable,
.set_duty = &pwm_set_duty,
},
- {
- .ch0 = PWM_CH_LED3,
- .ch1 = PWM_CH_LED4,
- .ch2 = PWM_LED_NO_CHANNEL,
- .enable = &pwm_enable,
- .set_duty = &pwm_set_duty,
- },
};
void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
@@ -71,9 +63,6 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
case EC_LED_ID_LEFT_LED:
pwm_id = PWM_LED0;
break;
- case EC_LED_ID_RIGHT_LED:
- pwm_id = PWM_LED1;
- break;
default:
return EC_ERROR_UNKNOWN;
}
diff --git a/board/omnigul/pwm.c b/board/omnigul/pwm.c
index 63cb02ec75..23046bac73 100644
--- a/board/omnigul/pwm.c
+++ b/board/omnigul/pwm.c
@@ -15,11 +15,6 @@ const struct pwm_t pwm_channels[] = {
.flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
.freq = 4800,
},
- [PWM_CH_LED3] = {
- .channel = 1,
- .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
- .freq = 4800,
- },
[PWM_CH_LED1] = {
.channel = 2,
.flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
@@ -41,11 +36,6 @@ const struct pwm_t pwm_channels[] = {
.flags = PWM_CONFIG_OPEN_DRAIN,
.freq = 25000,
},
- [PWM_CH_LED4] = {
- .channel = 7,
- .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP,
- .freq = 4800,
- },
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
@@ -59,10 +49,6 @@ static void board_pwm_init(void)
pwm_set_duty(PWM_CH_LED1, 0);
pwm_enable(PWM_CH_LED2, 1);
pwm_set_duty(PWM_CH_LED2, 0);
- pwm_enable(PWM_CH_LED3, 1);
- pwm_set_duty(PWM_CH_LED3, 0);
- pwm_enable(PWM_CH_LED4, 1);
- pwm_set_duty(PWM_CH_LED4, 0);
pwm_enable(PWM_CH_KBLIGHT, 1);
pwm_set_duty(PWM_CH_KBLIGHT, 50);
diff --git a/board/omnigul/sensors.c b/board/omnigul/sensors.c
index 8faf3729e8..8dff333241 100644
--- a/board/omnigul/sensors.c
+++ b/board/omnigul/sensors.c
@@ -8,7 +8,6 @@
#include "common.h"
#include "driver/accel_lis2dw12.h"
#include "driver/accelgyro_lsm6dso.h"
-#include "driver/als_tcs3400_public.h"
#include "gpio.h"
#include "hooks.h"
#include "motion_sense.h"
@@ -39,13 +38,6 @@ struct adc_t adc_channels[] = {
.factor_div = ADC_READ_MAX + 1,
.shift = 0,
},
- [ADC_TEMP_SENSOR_4_WWAN] = {
- .name = "TEMP_WWAN",
- .input_ch = NPCX_ADC_CH7,
- .factor_mul = ADC_MAX_VOLT,
- .factor_div = ADC_READ_MAX + 1,
- .shift = 0,
- },
};
BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
@@ -64,60 +56,6 @@ static const mat33_fp_t base_standard_ref = { { FLOAT_TO_FP(1), 0, 0 },
{ 0, FLOAT_TO_FP(-1), 0 },
{ 0, 0, FLOAT_TO_FP(-1) } };
-/* TCS3400 private data */
-static struct als_drv_data_t g_tcs3400_data = {
- .als_cal.scale = 1,
- .als_cal.uscale = 0,
- .als_cal.offset = 0,
- .als_cal.channel_scale = {
- .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kc from VPD */
- .cover_scale = ALS_CHANNEL_SCALE(1.0), /* CT */
- },
-};
-
-/*
- * TODO: b/184702900 need to calibrate ALS/RGB sensor. At default settings,
- * shining phone flashlight on sensor pegs all readings at 0xFFFF.
- */
-static struct tcs3400_rgb_drv_data_t g_tcs3400_rgb_data = {
- .calibration.rgb_cal[X] = {
- .offset = 0,
- .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(1.0),
- .scale = {
- .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kr */
- .cover_scale = ALS_CHANNEL_SCALE(1.0)
- }
- },
- .calibration.rgb_cal[Y] = {
- .offset = 0,
- .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(1.0),
- .scale = {
- .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kg */
- .cover_scale = ALS_CHANNEL_SCALE(1.0)
- },
- },
- .calibration.rgb_cal[Z] = {
- .offset = 0,
- .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(0),
- .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(1.0),
- .scale = {
- .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kb */
- .cover_scale = ALS_CHANNEL_SCALE(1.0)
- }
- },
- .calibration.irt = INT_TO_FP(1),
- .saturation.again = TCS_DEFAULT_AGAIN,
- .saturation.atime = TCS_DEFAULT_ATIME,
-};
-
struct motion_sensor_t motion_sensors[] = {
[LID_ACCEL] = {
.name = "Lid Accel",
@@ -191,59 +129,13 @@ struct motion_sensor_t motion_sensors[] = {
.min_frequency = LSM6DSO_ODR_MIN_VAL,
.max_frequency = LSM6DSO_ODR_MAX_VAL,
},
-
- [CLEAR_ALS] = {
- .name = "Clear Light",
- .active_mask = SENSOR_ACTIVE_S0_S3,
- .chip = MOTIONSENSE_CHIP_TCS3400,
- .type = MOTIONSENSE_TYPE_LIGHT,
- .location = MOTIONSENSE_LOC_CAMERA,
- .drv = &tcs3400_drv,
- .drv_data = &g_tcs3400_data,
- .port = I2C_PORT_SENSOR,
- .i2c_spi_addr_flags = TCS3400_I2C_ADDR_FLAGS,
- .rot_standard_ref = NULL,
- .default_range = 0x10000, /* scale = 1x, uscale = 0 */
- .min_frequency = TCS3400_LIGHT_MIN_FREQ,
- .max_frequency = TCS3400_LIGHT_MAX_FREQ,
- .config = {
- /* Run ALS sensor in S0 */
- [SENSOR_CONFIG_EC_S0] = {
- .odr = 1000,
- },
- },
- },
-
- [RGB_ALS] = {
- /*
- * RGB channels read by CLEAR_ALS and so the i2c port and
- * address do not need to be defined for RGB_ALS.
- */
- .name = "RGB Light",
- .active_mask = SENSOR_ACTIVE_S0_S3,
- .chip = MOTIONSENSE_CHIP_TCS3400,
- .type = MOTIONSENSE_TYPE_LIGHT_RGB,
- .location = MOTIONSENSE_LOC_CAMERA,
- .drv = &tcs3400_rgb_drv,
- .drv_data = &g_tcs3400_rgb_data,
- .rot_standard_ref = NULL,
- .default_range = 0x10000, /* scale = 1x, uscale = 0 */
- },
};
const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
-/* ALS instances when LPC mapping is needed. Each entry directs to a sensor. */
-const struct motion_sensor_t *motion_als_sensors[] = {
- &motion_sensors[CLEAR_ALS],
-};
-BUILD_ASSERT(ARRAY_SIZE(motion_als_sensors) == ALS_COUNT);
-
static void baseboard_sensors_init(void)
{
/* Enable gpio interrupt for lid accel sensor */
gpio_enable_interrupt(GPIO_EC_ACCEL_INT_R_L);
- /* Enable interrupt for the TCS3400 color light sensor */
- gpio_enable_interrupt(GPIO_EC_ALS_RGB_INT_R_L);
/* Enable gpio interrupt for base accelgyro sensor */
gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L);
}
@@ -269,12 +161,6 @@ const struct temp_sensor_t temp_sensors[] = {
.read = get_temp_3v3_30k9_47k_4050b,
.idx = ADC_TEMP_SENSOR_3_CHARGER,
},
- [TEMP_SENSOR_4_WWAN] = {
- .name = "WWAN",
- .type = TEMP_SENSOR_TYPE_BOARD,
- .read = get_temp_3v3_30k9_47k_4050b,
- .idx = ADC_TEMP_SENSOR_4_WWAN,
- },
};
BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
@@ -362,31 +248,9 @@ __maybe_unused static const struct ec_thermal_config thermal_ambient =
__maybe_unused static const struct ec_thermal_config thermal_charger =
THERMAL_CHARGER;
-/*
- * TODO(b/180681346): update for brya WWAN module
- */
-/*
- * TODO(b/202062363): Remove when clang is fixed.
- */
-#define THERMAL_WWAN \
- { \
- .temp_host = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(130), \
- [EC_TEMP_THRESH_HALT] = C_TO_K(130), \
- }, \
- .temp_host_release = { \
- [EC_TEMP_THRESH_HIGH] = C_TO_K(100), \
- }, \
- .temp_fan_off = C_TO_K(35), \
- .temp_fan_max = C_TO_K(60), \
- }
-__maybe_unused static const struct ec_thermal_config thermal_wwan =
- THERMAL_WWAN;
-
struct ec_thermal_config thermal_params[] = {
[TEMP_SENSOR_1_DDR_SOC] = THERMAL_CPU,
[TEMP_SENSOR_2_AMBIENT] = THERMAL_AMBIENT,
[TEMP_SENSOR_3_CHARGER] = THERMAL_CHARGER,
- [TEMP_SENSOR_4_WWAN] = THERMAL_WWAN,
};
BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);
diff --git a/board/omnigul/usbc_config.c b/board/omnigul/usbc_config.c
index 087208b413..bba78767b1 100644
--- a/board/omnigul/usbc_config.c
+++ b/board/omnigul/usbc_config.c
@@ -2,22 +2,15 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
-#include "cbi.h"
-#include "charge_ramp.h"
-#include "charger.h"
#include "common.h"
#include "compile_time_macros.h"
#include "console.h"
-#include "driver/bc12/pi3usb9201_public.h"
#include "driver/ppc/nx20p348x.h"
#include "driver/ppc/syv682x_public.h"
-#include "driver/retimer/bb_retimer_public.h"
#include "driver/tcpm/nct38xx.h"
#include "driver/tcpm/ps8xxx_public.h"
#include "driver/tcpm/tcpci.h"
#include "ec_commands.h"
-#include "fw_config.h"
#include "gpio.h"
#include "gpio_signal.h"
#include "hooks.h"
@@ -26,7 +19,6 @@
#include "task.h"
#include "task_id.h"
#include "timer.h"
-#include "usb_charge.h"
#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_tcpm.h"
@@ -39,17 +31,12 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args)
-#ifdef CONFIG_ZEPHYR
-enum ioex_port { IOEX_C0_NCT38XX = 0, IOEX_C2_NCT38XX, IOEX_PORT_COUNT };
-#endif /* CONFIG_ZEPHYR */
-
-#ifndef CONFIG_ZEPHYR
/* USBC TCPC configuration */
const struct tcpc_config_t tcpc_config[] = {
[USBC_PORT_C0] = {
.bus_type = EC_BUS_TYPE_I2C,
.i2c_info = {
- .port = I2C_PORT_USB_C0_C2_TCPC,
+ .port = I2C_PORT_USB_C0_TCPC,
.addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
},
.drv = &nct38xx_tcpm_drv,
@@ -68,37 +55,24 @@ const struct tcpc_config_t tcpc_config[] = {
TCPC_FLAGS_CONTROL_VCONN |
TCPC_FLAGS_CONTROL_FRS,
},
- [USBC_PORT_C2] = {
- .bus_type = EC_BUS_TYPE_I2C,
- .i2c_info = {
- .port = I2C_PORT_USB_C0_C2_TCPC,
- .addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
- },
- .drv = &nct38xx_tcpm_drv,
- .flags = TCPC_FLAGS_TCPCI_REV2_0,
- },
};
BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT);
-#endif /* !CONFIG_ZEPHYR */
/******************************************************************************/
/* USB-A charging control */
-#ifndef CONFIG_ZEPHYR
const int usb_port_enable[USB_PORT_COUNT] = {
GPIO_EN_PP5000_USBA_R,
};
-#endif
BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT);
/******************************************************************************/
-#ifndef CONFIG_ZEPHYR
/* USBC PPC configuration */
struct ppc_config_t ppc_chips[] = {
[USBC_PORT_C0] = {
- .i2c_port = I2C_PORT_USB_C0_C2_PPC,
+ .i2c_port = I2C_PORT_USB_C0_PPC,
.i2c_addr_flags = SYV682X_ADDR0_FLAGS,
.frs_en = IOEX_USB_C0_FRS_EN,
.drv = &syv682x_drv,
@@ -109,35 +83,11 @@ struct ppc_config_t ppc_chips[] = {
.i2c_addr_flags = NX20P3483_ADDR2_FLAGS,
.drv = &nx20p348x_drv,
},
- [USBC_PORT_C2] = {
- .i2c_port = I2C_PORT_USB_C0_C2_PPC,
- .i2c_addr_flags = SYV682X_ADDR2_FLAGS,
- .frs_en = IOEX_USB_C2_FRS_EN,
- .drv = &syv682x_drv,
- },
};
BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
-/* USBC mux configuration - Alder Lake includes internal mux */
-static const struct usb_mux_chain usbc0_tcss_usb_mux = {
- .mux =
- &(const struct usb_mux){
- .usb_port = USBC_PORT_C0,
- .driver = &virtual_usb_mux_driver,
- .hpd_update = &virtual_hpd_update,
- },
-};
-static const struct usb_mux_chain usbc2_tcss_usb_mux = {
- .mux =
- &(const struct usb_mux){
- .usb_port = USBC_PORT_C2,
- .driver = &virtual_usb_mux_driver,
- .hpd_update = &virtual_hpd_update,
- },
-};
-
/*
* USB3 DB mux configuration - the top level mux still needs to be set
* to the virtual_usb_mux_driver so the AP gets notified of mux changes
@@ -155,14 +105,10 @@ static const struct usb_mux_chain usbc1_usb3_db_retimer = {
const struct usb_mux_chain usb_muxes[] = {
[USBC_PORT_C0] = {
.mux = &(const struct usb_mux) {
- .usb_port = USBC_PORT_C0,
- .flags = USB_MUX_FLAG_CAN_IDLE,
- .driver = &bb_usb_retimer,
- .hpd_update = bb_retimer_hpd_update,
- .i2c_port = I2C_PORT_USB_C0_C2_MUX,
- .i2c_addr_flags = USBC_PORT_C0_BB_RETIMER_I2C_ADDR,
+ .usb_port = USBC_PORT_C1,
+ .driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
},
- .next = &usbc0_tcss_usb_mux,
},
[USBC_PORT_C1] = {
.mux = &(const struct usb_mux) {
@@ -173,41 +119,10 @@ const struct usb_mux_chain usb_muxes[] = {
},
.next = &usbc1_usb3_db_retimer,
},
- [USBC_PORT_C2] = {
- .mux = &(const struct usb_mux) {
- .usb_port = USBC_PORT_C2,
- .flags = USB_MUX_FLAG_CAN_IDLE,
- .driver = &bb_usb_retimer,
- .hpd_update = bb_retimer_hpd_update,
- .i2c_port = I2C_PORT_USB_C0_C2_MUX,
- .i2c_addr_flags = USBC_PORT_C2_BB_RETIMER_I2C_ADDR,
- },
- .next = &usbc2_tcss_usb_mux,
- },
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
-/* BC1.2 charger detect configuration */
-const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
- [USBC_PORT_C0] = {
- .i2c_port = I2C_PORT_USB_C0_C2_BC12,
- .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
- },
- [USBC_PORT_C1] = {
- .i2c_port = I2C_PORT_USB_C1_BC12,
- .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS,
- },
- [USBC_PORT_C2] = {
- .i2c_port = I2C_PORT_USB_C0_C2_BC12,
- .i2c_addr_flags = PI3USB9201_I2C_ADDR_1_FLAGS,
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT);
-
/*
- * USB C0 and C2 uses burnside bridge chips and have their reset
- * controlled by their respective TCPC chips acting as GPIO expanders.
- *
* ioex_init() is normally called before we take the TCPCs out of
* reset, so we need to start in disabled mode, then explicitly
* call ioex_init().
@@ -215,134 +130,22 @@ BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT);
struct ioexpander_config_t ioex_config[] = {
[IOEX_C0_NCT38XX] = {
- .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
+ .i2c_host_port = I2C_PORT_USB_C0_TCPC,
.i2c_addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS,
.drv = &nct38xx_ioexpander_drv,
.flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
},
- [IOEX_C2_NCT38XX] = {
- .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC,
- .i2c_addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS,
- .drv = &nct38xx_ioexpander_drv,
- .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED,
- },
};
BUILD_ASSERT(ARRAY_SIZE(ioex_config) == CONFIG_IO_EXPANDER_PORT_COUNT);
-#endif /* !CONFIG_ZEPHYR */
-
-#ifdef CONFIG_CHARGE_RAMP_SW
-
-/*
- * TODO(b/181508008): tune this threshold
- */
-
-#define BC12_MIN_VOLTAGE 4400
-
-/**
- * Return true if VBUS is too low
- */
-int board_is_vbus_too_low(int port, enum chg_ramp_vbus_state ramp_state)
-{
- int voltage;
-
- if (charger_get_vbus_voltage(port, &voltage))
- voltage = 0;
-
- if (voltage == 0) {
- CPRINTS("%s: must be disconnected", __func__);
- return 1;
- }
-
- if (voltage < BC12_MIN_VOLTAGE) {
- CPRINTS("%s: port %d: vbus %d lower than %d", __func__, port,
- voltage, BC12_MIN_VOLTAGE);
- return 1;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_CHARGE_RAMP_SW */
-
-void config_usb_db_type(void)
-{
- enum ec_cfg_usb_db_type db_type = ec_cfg_usb_db_type();
-
- /*
- * TODO(b/180434685): implement multiple DB types
- */
-
- CPRINTS("Configured USB DB type number is %d", db_type);
-}
-
-__override int bb_retimer_power_enable(const struct usb_mux *me, bool enable)
-{
- enum ioex_signal rst_signal;
-
- if (me->usb_port == USBC_PORT_C0) {
-/* TODO: explore how to handle board id in zephyr*/
-#ifndef CONFIG_ZEPHYR
- rst_signal = IOEX_USB_C0_RT_RST_ODL;
-#else
- /* On Zephyr use bb_controls generated from DTS */
- rst_signal = bb_controls[me->usb_port].retimer_rst_gpio;
-#endif /* !CONFIG_ZEPHYR */
- } else if (me->usb_port == USBC_PORT_C2) {
-/* TODO: explore how to handle board id in zephyr*/
-#ifndef CONFIG_ZEPHYR
- rst_signal = IOEX_USB_C2_RT_RST_ODL;
-#else
- /* On Zephyr use bb_controls generated from DTS */
- rst_signal = bb_controls[me->usb_port].retimer_rst_gpio;
-#endif /* !CONFIG_ZEPHYR */
- } else {
- return EC_ERROR_INVAL;
- }
-
- /*
- * We do not have a load switch for the burnside bridge chips,
- * so we only need to sequence reset.
- */
-
- if (enable) {
- /*
- * Tpw, minimum time from VCC to RESET_N de-assertion is 100us.
- * For boards that don't provide a load switch control, the
- * retimer_init() function ensures power is up before calling
- * this function.
- */
- ioex_set_level(rst_signal, 1);
- /*
- * Allow 1ms time for the retimer to power up lc_domain
- * which powers I2C controller within retimer
- */
- msleep(1);
- } else {
- ioex_set_level(rst_signal, 0);
- msleep(1);
- }
- return EC_SUCCESS;
-}
void board_reset_pd_mcu(void)
{
- enum gpio_signal tcpc_rst;
-
-#ifndef CONFIG_ZEPHYR
- tcpc_rst = GPIO_USB_C0_C2_TCPC_RST_ODL;
-#else
- tcpc_rst = GPIO_UNIMPLEMENTED;
-#endif /* !CONFIG_ZEPHYR */
-
/*
* TODO(b/179648104): figure out correct timing
*/
- gpio_set_level(tcpc_rst, 0);
- if (ec_cfg_usb_db_type() != DB_USB_ABSENT) {
- gpio_set_level(GPIO_USB_C1_RST_ODL, 0);
- gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0);
- }
+ gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 0);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0);
/*
* delay for power-on to reset-off and min. assertion time
@@ -350,11 +153,8 @@ void board_reset_pd_mcu(void)
msleep(20);
- gpio_set_level(tcpc_rst, 1);
- if (ec_cfg_usb_db_type() != DB_USB_ABSENT) {
- gpio_set_level(GPIO_USB_C1_RST_ODL, 1);
- gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1);
- }
+ gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 1);
+ gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1);
/* wait for chips to come up */
@@ -367,39 +167,21 @@ static void board_tcpc_init(void)
if (!system_jumped_late())
board_reset_pd_mcu();
- /*
- * These IO expander pins are implemented using the
- * C0/C2 TCPC, so they must be set up after the TCPC has
- * been taken out of reset.
- */
-#ifndef CONFIG_ZEPHYR
+ /*
+ * These IO expander pins are implemented using the
+ * C0/C2 TCPC, so they must be set up after the TCPC has
+ * been taken out of reset.
+ */
+
ioex_init(IOEX_C0_NCT38XX);
- ioex_init(IOEX_C2_NCT38XX);
-#else
- gpio_reset_port(DEVICE_DT_GET(DT_NODELABEL(ioex_port1)));
- gpio_reset_port(DEVICE_DT_GET(DT_NODELABEL(ioex_port2)));
-#endif
/* Enable PPC interrupts. */
gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
- gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
/* Enable TCPC interrupts. */
- gpio_enable_interrupt(GPIO_USB_C0_C2_TCPC_INT_ODL);
-
-#ifndef CONFIG_ZEPHYR
- /* Enable BC1.2 interrupts. */
- gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL);
- gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL);
-#endif /* !CONFIG_ZEPHYR */
-
- if (ec_cfg_usb_db_type() != DB_USB_ABSENT) {
- gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL);
- gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
-#ifndef CONFIG_ZEPHYR
- gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL);
-#endif /* !CONFIG_ZEPHYR */
- }
+ gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET);
@@ -407,11 +189,10 @@ uint16_t tcpc_get_alert_status(void)
{
uint16_t status = 0;
- if (gpio_get_level(GPIO_USB_C0_C2_TCPC_INT_ODL) == 0)
+ if (gpio_get_level(GPIO_USB_C0_TCPC_INT_ODL) == 0)
status |= PD_STATUS_TCPC_ALERT_0 | PD_STATUS_TCPC_ALERT_2;
- if ((ec_cfg_usb_db_type() != DB_USB_ABSENT) &&
- gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0)
+ if (gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0)
status |= PD_STATUS_TCPC_ALERT_1;
return status;
@@ -421,50 +202,24 @@ int ppc_get_alert_status(int port)
{
if (port == USBC_PORT_C0)
return gpio_get_level(GPIO_USB_C0_PPC_INT_ODL) == 0;
- else if ((port == USBC_PORT_C1) &&
- (ec_cfg_usb_db_type() != DB_USB_ABSENT))
+ else if (port == USBC_PORT_C1)
return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0;
- else if (port == USBC_PORT_C2)
- return gpio_get_level(GPIO_USB_C2_PPC_INT_ODL) == 0;
return 0;
}
-#ifndef CONFIG_ZEPHYR
void tcpc_alert_event(enum gpio_signal signal)
{
switch (signal) {
- case GPIO_USB_C0_C2_TCPC_INT_ODL:
+ case GPIO_USB_C0_TCPC_INT_ODL:
schedule_deferred_pd_interrupt(USBC_PORT_C0);
break;
case GPIO_USB_C1_TCPC_INT_ODL:
- if (ec_cfg_usb_db_type() == DB_USB_ABSENT)
- break;
schedule_deferred_pd_interrupt(USBC_PORT_C1);
break;
default:
break;
}
}
-#endif
-
-void bc12_interrupt(enum gpio_signal signal)
-{
- switch (signal) {
- case GPIO_USB_C0_BC12_INT_ODL:
- usb_charger_task_set_event(0, USB_CHG_EVENT_BC12);
- break;
- case GPIO_USB_C1_BC12_INT_ODL:
- if (ec_cfg_usb_db_type() == DB_USB_ABSENT)
- break;
- usb_charger_task_set_event(1, USB_CHG_EVENT_BC12);
- break;
- case GPIO_USB_C2_BC12_INT_ODL:
- usb_charger_task_set_event(2, USB_CHG_EVENT_BC12);
- break;
- default:
- break;
- }
-}
void ppc_interrupt(enum gpio_signal signal)
{
@@ -473,47 +228,14 @@ void ppc_interrupt(enum gpio_signal signal)
syv682x_interrupt(USBC_PORT_C0);
break;
case GPIO_USB_C1_PPC_INT_ODL:
- switch (ec_cfg_usb_db_type()) {
- case DB_USB_ABSENT:
- case DB_USB_ABSENT2:
- break;
- case DB_USB3_PS8815:
- nx20p348x_interrupt(USBC_PORT_C1);
- break;
- }
- break;
- case GPIO_USB_C2_PPC_INT_ODL:
- syv682x_interrupt(USBC_PORT_C2);
+ nx20p348x_interrupt(USBC_PORT_C1);
break;
default:
break;
}
}
-void retimer_interrupt(enum gpio_signal signal)
-{
- /*
- * TODO(b/179513527): add USB-C support
- */
-}
-
__override bool board_is_dts_port(int port)
{
return port == USBC_PORT_C0;
}
-
-__override bool board_is_tbt_usb4_port(int port)
-{
- if (port == USBC_PORT_C0 || port == USBC_PORT_C2)
- return true;
-
- return false;
-}
-
-__override enum tbt_compat_cable_speed board_get_max_tbt_speed(int port)
-{
- if (!board_is_tbt_usb4_port(port))
- return TBT_SS_RES_0;
-
- return TBT_SS_TBT_GEN3;
-}
diff --git a/board/omnigul/usbc_config.h b/board/omnigul/usbc_config.h
index e1f598ad21..cd4e387406 100644
--- a/board/omnigul/usbc_config.h
+++ b/board/omnigul/usbc_config.h
@@ -9,16 +9,9 @@
#define __CROS_EC_USBC_CONFIG_H
#ifndef CONFIG_ZEPHYR
-#define CONFIG_USB_PD_PORT_MAX_COUNT 3
+#define CONFIG_USB_PD_PORT_MAX_COUNT 2
#endif
-enum usbc_port {
- USBC_PORT_C0 = 0,
- USBC_PORT_C1,
- USBC_PORT_C2,
- USBC_PORT_COUNT
-};
-
-void config_usb_db_type(void);
+enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT };
#endif /* __CROS_EC_USBC_CONFIG_H */
diff --git a/board/redrix/board.c b/board/redrix/board.c
index 5b0b1b40a7..84d4520e70 100644
--- a/board/redrix/board.c
+++ b/board/redrix/board.c
@@ -59,7 +59,11 @@ struct pchg pchgs[] = {
.events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
},
};
-const int pchg_count = ARRAY_SIZE(pchgs);
+
+int board_get_pchg_count(void)
+{
+ return ARRAY_SIZE(pchgs);
+}
#endif
/******************************************************************************/
diff --git a/chip/ish/util/pack_ec.py b/chip/ish/util/pack_ec.py
index 7f381005f0..13a2afafd9 100755
--- a/chip/ish/util/pack_ec.py
+++ b/chip/ish/util/pack_ec.py
@@ -20,6 +20,7 @@ each binaries into right memory location.
import argparse
import struct
+
MANIFEST_ENTRY_SIZE = 0x80
HEADER_SIZE = 0x1000
PAGE_SIZE = 0x1000
diff --git a/chip/mchp/util/pack_ec.py b/chip/mchp/util/pack_ec.py
index 1b0a2e9959..8991718cf9 100755
--- a/chip/mchp/util/pack_ec.py
+++ b/chip/mchp/util/pack_ec.py
@@ -14,6 +14,7 @@ import subprocess
import tempfile
import zlib # CRC32
+
# MEC1701 has 256KB SRAM from 0xE0000 - 0x120000
# SRAM is divided into contiguous CODE & DATA
# CODE at [0xE0000, 0x117FFF] DATA at [0x118000, 0x11FFFF]
diff --git a/chip/mchp/util/pack_ec_mec152x.py b/chip/mchp/util/pack_ec_mec152x.py
index a463a43b6c..43721b3336 100755
--- a/chip/mchp/util/pack_ec_mec152x.py
+++ b/chip/mchp/util/pack_ec_mec152x.py
@@ -14,6 +14,7 @@ import subprocess
import tempfile
import zlib # CRC32
+
# MEC152xH has 256KB SRAM from 0xE0000 - 0x120000
# SRAM is divided into contiguous CODE & DATA
# CODE at [0xE0000, 0x117FFF] DATA at [0x118000, 0x11FFFF]
diff --git a/chip/mchp/util/pack_ec_mec172x.py b/chip/mchp/util/pack_ec_mec172x.py
index 6bd2db984b..a8e867888c 100755
--- a/chip/mchp/util/pack_ec_mec172x.py
+++ b/chip/mchp/util/pack_ec_mec172x.py
@@ -14,6 +14,7 @@ import subprocess
import tempfile
import zlib # CRC32
+
# MEC172x has 416KB SRAM from 0xC0000 - 0x127FFF
# SRAM is divided into contiguous CODE & DATA
# CODE at [0xC0000, 0x117FFF] DATA at [0x118000, 0x127FFF]
diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c
index 6d10fbf79e..9ade941812 100644
--- a/chip/stm32/clock-stm32l4.c
+++ b/chip/stm32/clock-stm32l4.c
@@ -647,9 +647,9 @@ static int command_clock(int argc, const char **argv)
DECLARE_CONSOLE_COMMAND(clock, command_clock,
"hsi | msi"
#ifdef STM32_HSE_CLOCK
- " | hse | pll"
+ " | hse"
#endif
- ,
+ " | pll",
"Set clock frequency");
uint32_t rtcss_to_us(uint32_t rtcss)
diff --git a/chip/stm32/dfu_bootmanager_main.c b/chip/stm32/dfu_bootmanager_main.c
index bad07c23b7..cec747e762 100644
--- a/chip/stm32/dfu_bootmanager_main.c
+++ b/chip/stm32/dfu_bootmanager_main.c
@@ -51,7 +51,10 @@
*/
static int rw_is_empty(void)
{
- return crec_flash_is_erased(CONFIG_RW_MEM_OFF, 8);
+ if (IS_ENABLED(CONFIG_FLASH_CROS))
+ return crec_flash_is_erased(CONFIG_RW_MEM_OFF, 8);
+ /* No flash support, we cannot tell. Assume not empty. */
+ return 0;
}
/*
@@ -131,6 +134,11 @@ static void jump_to_arm_reset_vector(uint32_t addr)
/* Load stack pointer */
"ldr r0, [r1, 0]\n"
"msr msp, r0\n"
+ /*
+ * Memory barrier to ensure subsequent instructions uses modified
+ * stack pointer.
+ */
+ "isb\n"
/* Load reset vector */
"ldr r0, [r1, 4]\n"
/* Jump without saving return address (would modify msp) */
diff --git a/common/body_detection.c b/common/body_detection.c
index 50b9b93d1c..8623948897 100644
--- a/common/body_detection.c
+++ b/common/body_detection.c
@@ -182,7 +182,10 @@ void body_detect_reset(void)
int odr = body_sensor->drv->get_data_rate(body_sensor);
int rms_noise = body_sensor->drv->get_rms_noise(body_sensor);
- body_detect_change_state(BODY_DETECTION_ON_BODY, false);
+ if (motion_state == BODY_DETECTION_ON_BODY)
+ stationary_timeframe = 0;
+ else
+ body_detect_change_state(BODY_DETECTION_ON_BODY, false);
/*
* The sensor is suspended since its ODR is 0,
* there is no need to reset until sensor is up again
diff --git a/common/build.mk b/common/build.mk
index 6b3e7db25c..591ea9fd6b 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -188,6 +188,7 @@ common-$(CONFIG_USB_PD_HOST_CMD)+=usb_pd_host_cmd.o
common-$(CONFIG_USB_PD_CONSOLE_CMD)+=usb_pd_console_cmd.o
endif
common-$(CONFIG_USB_PD_ALT_MODE_DFP)+=usb_pd_alt_mode_dfp.o
+common-$(CONFIG_USB_PD_DISCOVERY)+=usb_pd_discovery.o
common-$(CONFIG_USB_PD_ALT_MODE_UFP)+=usb_pd_alt_mode_ufp.o
common-$(CONFIG_USB_PD_DPS)+=dps.o
common-$(CONFIG_USB_PD_LOGGING)+=event_log.o pd_log.o
@@ -252,11 +253,6 @@ $(out)/RW/common/rsa.o: CFLAGS+=-O3
$(out)/RO/common/rsa.o: CFLAGS+=-O3
endif
-# AES-GCM code needs C99, else we'd have to move many variables declarations
-# around.
-$(out)/RW/common/aes-gcm.o: CFLAGS+=-std=c99 -Wno-declaration-after-statement
-$(out)/RO/common/aes-gcm.o: CFLAGS+=-std=c99 -Wno-declaration-after-statement
-
ifneq ($(CONFIG_BOOTBLOCK),)
ifdef BOOTBLOCK
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 25876ac28a..dad7d42cff 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -2548,13 +2548,6 @@ charge_command_charge_control(struct host_cmd_handler_args *args)
DECLARE_HOST_COMMAND(EC_CMD_CHARGE_CONTROL, charge_command_charge_control,
EC_VER_MASK(1) | EC_VER_MASK(2));
-static void reset_current_limit(void)
-{
- user_current_limit = -1U;
-}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, reset_current_limit, HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, reset_current_limit, HOOK_PRIO_DEFAULT);
-
static enum ec_status
charge_command_current_limit(struct host_cmd_handler_args *args)
{
diff --git a/common/flash.c b/common/flash.c
index c68f47a368..de2596ab27 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -1183,7 +1183,7 @@ static int command_flash_read(int argc, const char **argv)
int offset = -1;
int size = 256;
int rv;
- char *data;
+ uint8_t *data;
int i;
rv = parse_offset_size(argc, argv, 1, &offset, &size);
@@ -1194,7 +1194,7 @@ static int command_flash_read(int argc, const char **argv)
size = shared_mem_size();
/* Acquire the shared memory buffer */
- rv = shared_mem_acquire(size, &data);
+ rv = shared_mem_acquire(size, (char **)&data);
if (rv) {
ccputs("Can't get shared mem\n");
return rv;
diff --git a/common/i2c_controller.c b/common/i2c_controller.c
index 96809ee84c..3332f771f6 100644
--- a/common/i2c_controller.c
+++ b/common/i2c_controller.c
@@ -269,7 +269,8 @@ int i2c_xfer_unlocked(const int port, const uint16_t addr_flags,
case 0:
return EC_SUCCESS;
case -EIO:
- return EC_ERROR_INVAL;
+ ret = EC_ERROR_INVAL;
+ continue;
default:
return EC_ERROR_UNKNOWN;
}
diff --git a/common/mock/dp_alt_mode_mock.c b/common/mock/dp_alt_mode_mock.c
index ed769ed4b5..98f14949ed 100644
--- a/common/mock/dp_alt_mode_mock.c
+++ b/common/mock/dp_alt_mode_mock.c
@@ -29,8 +29,3 @@ void mock_dp_alt_mode_reset(void)
{
/* Nothing to do right now, but in the future ... */
}
-
-void dp_init(int port)
-{
- CPRINTS("C%d: DP init", port);
-}
diff --git a/common/ocpc.c b/common/ocpc.c
index 88308e5bc7..a176eea075 100644
--- a/common/ocpc.c
+++ b/common/ocpc.c
@@ -685,6 +685,10 @@ void ocpc_reset(struct ocpc_data *ocpc)
!(batt.flags & BATT_FLAG_BAD_VOLTAGE)) ?
batt.voltage :
battery_get_info()->voltage_normal;
+#ifdef CONFIG_CHARGER_NARROW_VDC
+ if (voltage < battery_get_info()->voltage_min)
+ voltage = battery_get_info()->voltage_min;
+#endif
CPRINTS("OCPC: C%d Init VSYS to %dmV", ocpc->active_chg_chip,
voltage);
charger_set_voltage(ocpc->active_chg_chip, voltage);
diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c
index bf139c1688..9e73100db1 100644
--- a/common/peripheral_charger.c
+++ b/common/peripheral_charger.c
@@ -26,6 +26,8 @@ static struct queue const host_events =
QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, uint32_t);
struct mutex host_event_mtx;
+static int pchg_count;
+
/*
* Events and errors to be reported to the host in each chipset state.
*
@@ -778,6 +780,8 @@ static void pchg_startup(void)
CPRINTS("%s", __func__);
queue_init(&host_events);
+ pchg_count = board_get_pchg_count();
+
for (p = 0; p < pchg_count; p++) {
rv = EC_SUCCESS;
ctx = &pchgs[p];
diff --git a/common/system_safe_mode.c b/common/system_safe_mode.c
index 539bbb626d..e86aa5216f 100644
--- a/common/system_safe_mode.c
+++ b/common/system_safe_mode.c
@@ -8,6 +8,7 @@
#include "cpu.h"
#include "ec_commands.h"
#include "hooks.h"
+#include "host_command.h"
#include "panic.h"
#include "stddef.h"
#include "system.h"
@@ -88,6 +89,13 @@ bool command_is_allowed_in_safe_mode(int command)
return false;
}
+static void system_safe_mode_start(void)
+{
+ if (IS_ENABLED(CONFIG_HOSTCMD_EVENTS))
+ host_set_single_event(EC_HOST_EVENT_PANIC);
+}
+DECLARE_DEFERRED(system_safe_mode_start);
+
int start_system_safe_mode(void)
{
if (!system_is_in_rw()) {
@@ -111,6 +119,13 @@ int start_system_safe_mode(void)
schedule_system_safe_mode_timeout();
+ /*
+ * Schedule a deferred function to run immediately
+ * after returning from fault handler. Defer operations that
+ * must not run in an ISR to this function.
+ */
+ hook_call_deferred(&system_safe_mode_start_data, 0);
+
in_safe_mode = true;
panic_printf("\nStarting system safe mode\n");
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c
index 6df0215274..caba71bb31 100644
--- a/common/usb_pd_alt_mode_dfp.c
+++ b/common/usb_pd_alt_mode_dfp.c
@@ -163,6 +163,7 @@ void pd_prepare_sysjump(void)
#endif /* CONFIG_ZEPHYR */
}
+#ifdef CONFIG_USB_PD_DP_MODE
/*
* This algorithm defaults to choosing higher pin config over lower ones in
* order to prefer multi-function if desired.
@@ -226,6 +227,7 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status)
return 1 << get_next_bit(&pin_caps);
}
+#endif /* CONFIG_USB_PD_DP_MODE */
struct svdm_amode_data *pd_get_amode_data(int port, enum tcpci_msg_type type,
uint16_t svid)
@@ -324,23 +326,6 @@ int pd_dfp_exit_mode(int port, enum tcpci_msg_type type, uint16_t svid,
return 1;
}
-/*
- * Check if the SVID has been recorded previously. Some peripherals provide
- * duplicated SVID.
- */
-static bool is_svid_duplicated(const struct pd_discovery *disc, uint16_t svid)
-{
- int i;
-
- for (i = 0; i < disc->svid_cnt; ++i)
- if (disc->svids[i].svid == svid) {
- CPRINTF("ERR:SVIDDUP\n");
- return true;
- }
-
- return false;
-}
-
void dfp_consume_attention(int port, uint32_t *payload)
{
uint16_t svid = PD_VDO_VID(payload[0]);
@@ -355,143 +340,6 @@ void dfp_consume_attention(int port, uint32_t *payload)
modep->fx->attention(port, payload);
}
-void dfp_consume_identity(int port, enum tcpci_msg_type type, int cnt,
- uint32_t *payload)
-{
- int ptype;
- struct pd_discovery *disc;
- size_t identity_size;
-
- if (type == TCPCI_MSG_SOP_PRIME &&
- !IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) {
- CPRINTF("ERR:Unexpected cable response\n");
- return;
- }
-
- ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]);
- disc = pd_get_am_discovery_and_notify_access(port, type);
- identity_size =
- MIN(sizeof(union disc_ident_ack), (cnt - 1) * sizeof(uint32_t));
-
- /* Note: only store VDOs, not the VDM header */
- memcpy(disc->identity.raw_value, payload + 1, identity_size);
- disc->identity_cnt = identity_size / sizeof(uint32_t);
-
- switch (ptype) {
- case IDH_PTYPE_AMA:
- /* Leave vbus ON if the following macro is false */
- if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) &&
- IS_ENABLED(CONFIG_USBC_VCONN_SWAP)) {
- /* Adapter is requesting vconn, try to supply it */
- if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)]))
- pd_try_vconn_src(port);
-
- /* Only disable vbus if vconn was requested */
- if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)]) &&
- !PD_VDO_AMA_VBUS_REQ(payload[VDO_I(AMA)]))
- pd_power_supply_reset(port);
- }
- break;
- default:
- break;
- }
- pd_set_identity_discovery(port, type, PD_DISC_COMPLETE);
-}
-
-void dfp_consume_svids(int port, enum tcpci_msg_type type, int cnt,
- uint32_t *payload)
-{
- int i;
- uint32_t *ptr = payload + 1;
- int vdo = 1;
- uint16_t svid0, svid1;
- struct pd_discovery *disc =
- pd_get_am_discovery_and_notify_access(port, type);
-
- for (i = disc->svid_cnt; i < disc->svid_cnt + 12; i += 2) {
- if (i >= SVID_DISCOVERY_MAX) {
- CPRINTF("ERR:SVIDCNT\n");
- break;
- }
- /*
- * Verify we're still within the valid packet (count will be one
- * for the VDM header + xVDOs)
- */
- if (vdo >= cnt)
- break;
-
- svid0 = PD_VDO_SVID_SVID0(*ptr);
- if (!svid0)
- break;
-
- if (!is_svid_duplicated(disc, svid0))
- disc->svids[disc->svid_cnt++].svid = svid0;
-
- svid1 = PD_VDO_SVID_SVID1(*ptr);
- if (!svid1)
- break;
-
- if (!is_svid_duplicated(disc, svid1))
- disc->svids[disc->svid_cnt++].svid = svid1;
-
- ptr++;
- vdo++;
- }
- /* TODO(tbroch) need to re-issue discover svids if > 12 */
- if (i && ((i % 12) == 0))
- CPRINTF("ERR:SVID+12\n");
-
- pd_set_svids_discovery(port, type, PD_DISC_COMPLETE);
-}
-
-void dfp_consume_modes(int port, enum tcpci_msg_type type, int cnt,
- uint32_t *payload)
-{
- int svid_idx;
- struct svid_mode_data *mode_discovery = NULL;
- struct pd_discovery *disc =
- pd_get_am_discovery_and_notify_access(port, type);
- uint16_t response_svid = (uint16_t)PD_VDO_VID(payload[0]);
-
- for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) {
- uint16_t svid = disc->svids[svid_idx].svid;
-
- if (svid == response_svid) {
- mode_discovery = &disc->svids[svid_idx];
- break;
- }
- }
- if (!mode_discovery) {
- const struct svid_mode_data *requested_mode_data =
- pd_get_next_mode(port, type);
- CPRINTF("C%d: Mode response for undiscovered SVID %x, but TCPM "
- "requested SVID %x\n",
- port, response_svid, requested_mode_data->svid);
- /*
- * Although SVIDs discovery seemed like it succeeded before, the
- * partner is now responding with undiscovered SVIDs. Discovery
- * cannot reasonably continue under these circumstances.
- */
- pd_set_modes_discovery(port, type, requested_mode_data->svid,
- PD_DISC_FAIL);
- return;
- }
-
- mode_discovery->mode_cnt = cnt - 1;
- if (mode_discovery->mode_cnt < 1) {
- CPRINTF("ERR:NOMODE\n");
- pd_set_modes_discovery(port, type, mode_discovery->svid,
- PD_DISC_FAIL);
- return;
- }
-
- memcpy(mode_discovery->mode_vdo, &payload[1],
- sizeof(uint32_t) * mode_discovery->mode_cnt);
- disc->svid_idx++;
- pd_set_modes_discovery(port, type, mode_discovery->svid,
- PD_DISC_COMPLETE);
-}
-
int pd_alt_mode(int port, enum tcpci_msg_type type, uint16_t svid)
{
struct svdm_amode_data *modep = pd_get_amode_data(port, type, svid);
@@ -499,200 +347,6 @@ int pd_alt_mode(int port, enum tcpci_msg_type type, uint16_t svid)
return (modep) ? modep->opos : -1;
}
-void pd_set_identity_discovery(int port, enum tcpci_msg_type type,
- enum pd_discovery_state disc)
-{
- struct pd_discovery *pd =
- pd_get_am_discovery_and_notify_access(port, type);
-
- pd->identity_discovery = disc;
-}
-
-enum pd_discovery_state pd_get_identity_discovery(int port,
- enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
-
- return disc->identity_discovery;
-}
-
-const union disc_ident_ack *pd_get_identity_response(int port,
- enum tcpci_msg_type type)
-{
- if (type >= DISCOVERY_TYPE_COUNT)
- return NULL;
-
- return &pd_get_am_discovery(port, type)->identity;
-}
-
-uint16_t pd_get_identity_vid(int port)
-{
- const union disc_ident_ack *resp =
- pd_get_identity_response(port, TCPCI_MSG_SOP);
-
- return resp->idh.usb_vendor_id;
-}
-
-uint16_t pd_get_identity_pid(int port)
-{
- const union disc_ident_ack *resp =
- pd_get_identity_response(port, TCPCI_MSG_SOP);
-
- return resp->product.product_id;
-}
-
-uint8_t pd_get_product_type(int port)
-{
- const union disc_ident_ack *resp =
- pd_get_identity_response(port, TCPCI_MSG_SOP);
-
- return resp->idh.product_type;
-}
-
-void pd_set_svids_discovery(int port, enum tcpci_msg_type type,
- enum pd_discovery_state disc)
-{
- struct pd_discovery *pd =
- pd_get_am_discovery_and_notify_access(port, type);
-
- pd->svids_discovery = disc;
-}
-
-enum pd_discovery_state pd_get_svids_discovery(int port,
- enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
-
- return disc->svids_discovery;
-}
-
-int pd_get_svid_count(int port, enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
-
- return disc->svid_cnt;
-}
-
-uint16_t pd_get_svid(int port, uint16_t svid_idx, enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
-
- return disc->svids[svid_idx].svid;
-}
-
-void pd_set_modes_discovery(int port, enum tcpci_msg_type type, uint16_t svid,
- enum pd_discovery_state disc)
-{
- struct pd_discovery *pd =
- pd_get_am_discovery_and_notify_access(port, type);
- int svid_idx;
-
- for (svid_idx = 0; svid_idx < pd->svid_cnt; ++svid_idx) {
- struct svid_mode_data *mode_data = &pd->svids[svid_idx];
-
- if (mode_data->svid != svid)
- continue;
-
- mode_data->discovery = disc;
- return;
- }
-}
-
-enum pd_discovery_state pd_get_modes_discovery(int port,
- enum tcpci_msg_type type)
-{
- const struct svid_mode_data *mode_data = pd_get_next_mode(port, type);
-
- /*
- * If there are no SVIDs for which to discover modes, mode discovery is
- * trivially complete.
- */
- if (!mode_data)
- return PD_DISC_COMPLETE;
-
- return mode_data->discovery;
-}
-
-int pd_get_mode_vdo_for_svid(int port, enum tcpci_msg_type type, uint16_t svid,
- uint32_t *vdo_out)
-{
- int idx;
- const struct pd_discovery *disc;
-
- if (type >= DISCOVERY_TYPE_COUNT)
- return 0;
-
- disc = pd_get_am_discovery(port, type);
-
- for (idx = 0; idx < disc->svid_cnt; ++idx) {
- if (pd_get_svid(port, idx, type) == svid) {
- memcpy(vdo_out, disc->svids[idx].mode_vdo,
- sizeof(uint32_t) * disc->svids[idx].mode_cnt);
- return disc->svids[idx].mode_cnt;
- }
- }
- return 0;
-}
-
-const struct svid_mode_data *pd_get_next_mode(int port,
- enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
- const struct svid_mode_data *failed_mode_data = NULL;
- bool svid_good_discovery = false;
- int svid_idx;
-
- /* Walk through all of the discovery mode entries */
- for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) {
- const struct svid_mode_data *mode_data = &disc->svids[svid_idx];
-
- /* Discovery is needed, so send this one back now */
- if (mode_data->discovery == PD_DISC_NEEDED)
- return mode_data;
-
- /* Discovery already succeeded, save that it was seen */
- if (mode_data->discovery == PD_DISC_COMPLETE)
- svid_good_discovery = true;
- /* Discovery already failed, save first failure */
- else if (!failed_mode_data)
- failed_mode_data = mode_data;
- }
-
- /* If no good entries were located, then return last failed */
- if (!svid_good_discovery)
- return failed_mode_data;
-
- /*
- * Mode discovery has been attempted for every discovered SVID (if
- * any exist)
- */
- return NULL;
-}
-
-const uint32_t *pd_get_mode_vdo(int port, uint16_t svid_idx,
- enum tcpci_msg_type type)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
-
- return disc->svids[svid_idx].mode_vdo;
-}
-
-bool pd_is_mode_discovered_for_svid(int port, enum tcpci_msg_type type,
- uint16_t svid)
-{
- const struct pd_discovery *disc = pd_get_am_discovery(port, type);
- const struct svid_mode_data *mode_data;
-
- for (mode_data = disc->svids; mode_data < disc->svids + disc->svid_cnt;
- ++mode_data) {
- if (mode_data->svid == svid &&
- mode_data->discovery == PD_DISC_COMPLETE)
- return true;
- }
-
- return false;
-}
-
void notify_sysjump_ready(void)
{
/*
@@ -703,86 +357,7 @@ void notify_sysjump_ready(void)
task_set_event(sysjump_task_waiting, TASK_EVENT_SYSJUMP_READY);
}
-static inline bool is_pd_rev3(int port, enum tcpci_msg_type type)
-{
- return pd_get_rev(port, type) == PD_REV30;
-}
-
-/*
- * ############################################################################
- *
- * (Charge Through) Vconn Powered Device functions
- *
- * ############################################################################
- */
-bool is_vpd_ct_supported(int port)
-{
- const struct pd_discovery *disc =
- pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
- union vpd_vdo vpd = disc->identity.product_t1.vpd;
-
- return vpd.ct_support;
-}
-
-/*
- * ############################################################################
- *
- * Cable communication functions
- *
- * ############################################################################
- */
-enum idh_ptype get_usb_pd_cable_type(int port)
-{
- const struct pd_discovery *disc =
- pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
-
- return disc->identity.idh.product_type;
-}
-
-bool is_usb2_cable_support(int port)
-{
- const struct pd_discovery *disc =
- pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
-
- return disc->identity.idh.product_type == IDH_PTYPE_PCABLE ||
- pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) < VDM_VER20 ||
- disc->identity.product_t2.a2_rev30.usb_20_support ==
- USB2_SUPPORTED;
-}
-
-bool is_cable_speed_gen2_capable(int port)
-{
- const struct pd_discovery *disc =
- pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
-
- switch (pd_get_rev(port, TCPCI_MSG_SOP_PRIME)) {
- case PD_REV20:
- return disc->identity.product_t1.p_rev20.ss ==
- USB_R20_SS_U31_GEN1_GEN2;
-
- case PD_REV30:
- return disc->identity.product_t1.p_rev30.ss ==
- USB_R30_SS_U32_U40_GEN2 ||
- disc->identity.product_t1.p_rev30.ss ==
- USB_R30_SS_U40_GEN3;
- default:
- return false;
- }
-}
-
-bool is_active_cable_element_retimer(int port)
-{
- const struct pd_discovery *disc =
- pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
-
- /* Ref: USB PD Spec 2.0 Table 6-29 Active Cable VDO
- * Revision 2 Active cables do not have Active element support.
- */
- return is_pd_rev3(port, TCPCI_MSG_SOP_PRIME) &&
- disc->identity.idh.product_type == IDH_PTYPE_ACABLE &&
- disc->identity.product_t2.a2_rev30.active_elem == ACTIVE_RETIMER;
-}
-
+#ifdef CONFIG_USB_PD_DP_MODE
__overridable void svdm_safe_dp_mode(int port)
{
/* make DP interface safe until configure */
@@ -1040,6 +615,7 @@ __overridable void svdm_exit_dp_mode(int port)
baseboard_mst_enable_control(port, 0);
#endif
}
+#endif /* CONFIG_USB_PD_DP_MODE */
#ifdef CONFIG_USB_PD_TCPMV1
__overridable int svdm_enter_gfu_mode(int port, uint32_t mode_caps)
@@ -1104,6 +680,7 @@ __overridable int svdm_tbt_compat_attention(int port, uint32_t *payload)
* configuration to Device Policy Manager.
*/
const struct svdm_amode_fx supported_modes[] = {
+#ifdef CONFIG_USB_PD_DP_MODE
{
.svid = USB_SID_DISPLAYPORT,
.enter = &svdm_enter_dp_mode,
@@ -1113,6 +690,7 @@ const struct svdm_amode_fx supported_modes[] = {
.attention = &svdm_dp_attention,
.exit = &svdm_exit_dp_mode,
},
+#endif /* CONFIG_USB_PD_DP_MODE */
#ifdef CONFIG_USB_PD_TCPMV1
{
.svid = USB_VID_GOOGLE,
@@ -1136,7 +714,7 @@ const struct svdm_amode_fx supported_modes[] = {
};
const int supported_modes_cnt = ARRAY_SIZE(supported_modes);
-#ifdef CONFIG_CMD_MFALLOW
+#if defined(CONFIG_CMD_MFALLOW)
static int command_mfallow(int argc, const char **argv)
{
char *e;
diff --git a/common/usb_pd_discovery.c b/common/usb_pd_discovery.c
new file mode 100644
index 0000000000..3fad82d10d
--- /dev/null
+++ b/common/usb_pd_discovery.c
@@ -0,0 +1,471 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternate Mode Discovery storage, access, and helpers
+ */
+
+#include "builtin/assert.h"
+#include "chipset.h"
+#include "console.h"
+#include "gpio.h"
+#include "task.h"
+#include "task_id.h"
+#include "timer.h"
+#include "typec_control.h"
+#include "usb_charge.h"
+#include "usb_common.h"
+#include "usb_dp_alt_mode.h"
+#include "usb_mux.h"
+#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
+#include "usb_tbt_alt_mode.h"
+#include "usbc_ppc.h"
+#include "util.h"
+
+#ifdef CONFIG_COMMON_RUNTIME
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args)
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args)
+#else
+#define CPRINTS(format, args...)
+#define CPRINTF(format, args...)
+#endif
+
+/*
+ * Check if the SVID has been recorded previously. Some peripherals provide
+ * duplicated SVID.
+ */
+static bool is_svid_duplicated(const struct pd_discovery *disc, uint16_t svid)
+{
+ int i;
+
+ for (i = 0; i < disc->svid_cnt; ++i)
+ if (disc->svids[i].svid == svid) {
+ CPRINTF("ERR:SVIDDUP\n");
+ return true;
+ }
+
+ return false;
+}
+
+void dfp_consume_identity(int port, enum tcpci_msg_type type, int cnt,
+ uint32_t *payload)
+{
+ int ptype;
+ struct pd_discovery *disc;
+ size_t identity_size;
+
+ if (type == TCPCI_MSG_SOP_PRIME &&
+ !IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) {
+ CPRINTF("ERR:Unexpected cable response\n");
+ return;
+ }
+
+ ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]);
+ disc = pd_get_am_discovery_and_notify_access(port, type);
+ identity_size =
+ MIN(sizeof(union disc_ident_ack), (cnt - 1) * sizeof(uint32_t));
+
+ /* Note: only store VDOs, not the VDM header */
+ memcpy(disc->identity.raw_value, payload + 1, identity_size);
+ disc->identity_cnt = identity_size / sizeof(uint32_t);
+
+ switch (ptype) {
+ case IDH_PTYPE_AMA:
+ /* Leave vbus ON if the following macro is false */
+ if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) &&
+ IS_ENABLED(CONFIG_USBC_VCONN_SWAP)) {
+ /* Adapter is requesting vconn, try to supply it */
+ if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)]))
+ pd_try_vconn_src(port);
+
+ /* Only disable vbus if vconn was requested */
+ if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)]) &&
+ !PD_VDO_AMA_VBUS_REQ(payload[VDO_I(AMA)]))
+ pd_power_supply_reset(port);
+ }
+ break;
+ default:
+ break;
+ }
+ pd_set_identity_discovery(port, type, PD_DISC_COMPLETE);
+}
+
+void dfp_consume_svids(int port, enum tcpci_msg_type type, int cnt,
+ uint32_t *payload)
+{
+ int i;
+ uint32_t *ptr = payload + 1;
+ int vdo = 1;
+ uint16_t svid0, svid1;
+ struct pd_discovery *disc =
+ pd_get_am_discovery_and_notify_access(port, type);
+
+ for (i = disc->svid_cnt; i < disc->svid_cnt + 12; i += 2) {
+ if (i >= SVID_DISCOVERY_MAX) {
+ CPRINTF("ERR:SVIDCNT\n");
+ break;
+ }
+ /*
+ * Verify we're still within the valid packet (count will be one
+ * for the VDM header + xVDOs)
+ */
+ if (vdo >= cnt)
+ break;
+
+ svid0 = PD_VDO_SVID_SVID0(*ptr);
+ if (!svid0)
+ break;
+
+ if (!is_svid_duplicated(disc, svid0))
+ disc->svids[disc->svid_cnt++].svid = svid0;
+
+ svid1 = PD_VDO_SVID_SVID1(*ptr);
+ if (!svid1)
+ break;
+
+ if (!is_svid_duplicated(disc, svid1))
+ disc->svids[disc->svid_cnt++].svid = svid1;
+
+ ptr++;
+ vdo++;
+ }
+ /* TODO(tbroch) need to re-issue discover svids if > 12 */
+ if (i && ((i % 12) == 0))
+ CPRINTF("ERR:SVID+12\n");
+
+ pd_set_svids_discovery(port, type, PD_DISC_COMPLETE);
+}
+
+void dfp_consume_modes(int port, enum tcpci_msg_type type, int cnt,
+ uint32_t *payload)
+{
+ int svid_idx;
+ struct svid_mode_data *mode_discovery = NULL;
+ struct pd_discovery *disc =
+ pd_get_am_discovery_and_notify_access(port, type);
+ uint16_t response_svid = (uint16_t)PD_VDO_VID(payload[0]);
+
+ for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) {
+ uint16_t svid = disc->svids[svid_idx].svid;
+
+ if (svid == response_svid) {
+ mode_discovery = &disc->svids[svid_idx];
+ break;
+ }
+ }
+ if (!mode_discovery) {
+ const struct svid_mode_data *requested_mode_data =
+ pd_get_next_mode(port, type);
+ CPRINTF("C%d: Mode response for undiscovered SVID %x, but TCPM "
+ "requested SVID %x\n",
+ port, response_svid, requested_mode_data->svid);
+ /*
+ * Although SVIDs discovery seemed like it succeeded before, the
+ * partner is now responding with undiscovered SVIDs. Discovery
+ * cannot reasonably continue under these circumstances.
+ */
+ pd_set_modes_discovery(port, type, requested_mode_data->svid,
+ PD_DISC_FAIL);
+ return;
+ }
+
+ mode_discovery->mode_cnt = cnt - 1;
+ if (mode_discovery->mode_cnt < 1) {
+ CPRINTF("ERR:NOMODE\n");
+ pd_set_modes_discovery(port, type, mode_discovery->svid,
+ PD_DISC_FAIL);
+ return;
+ }
+
+ memcpy(mode_discovery->mode_vdo, &payload[1],
+ sizeof(uint32_t) * mode_discovery->mode_cnt);
+ disc->svid_idx++;
+ pd_set_modes_discovery(port, type, mode_discovery->svid,
+ PD_DISC_COMPLETE);
+}
+
+void pd_disable_discovery(int port)
+{
+ /* Mark identity and SVIDs for the port partner and cable as failed.
+ * With no discovered SVIDs, there are no modes to mark as failed.
+ */
+ pd_set_identity_discovery(port, TCPCI_MSG_SOP, PD_DISC_FAIL);
+ pd_set_svids_discovery(port, TCPCI_MSG_SOP, PD_DISC_FAIL);
+ pd_set_identity_discovery(port, TCPCI_MSG_SOP_PRIME, PD_DISC_FAIL);
+ pd_set_svids_discovery(port, TCPCI_MSG_SOP_PRIME, PD_DISC_FAIL);
+}
+
+void pd_set_identity_discovery(int port, enum tcpci_msg_type type,
+ enum pd_discovery_state disc)
+{
+ struct pd_discovery *pd =
+ pd_get_am_discovery_and_notify_access(port, type);
+
+ pd->identity_discovery = disc;
+}
+
+enum pd_discovery_state pd_get_identity_discovery(int port,
+ enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+
+ return disc->identity_discovery;
+}
+
+const union disc_ident_ack *pd_get_identity_response(int port,
+ enum tcpci_msg_type type)
+{
+ if (type >= DISCOVERY_TYPE_COUNT)
+ return NULL;
+
+ return &pd_get_am_discovery(port, type)->identity;
+}
+
+uint16_t pd_get_identity_vid(int port)
+{
+ const union disc_ident_ack *resp =
+ pd_get_identity_response(port, TCPCI_MSG_SOP);
+
+ return resp->idh.usb_vendor_id;
+}
+
+uint16_t pd_get_identity_pid(int port)
+{
+ const union disc_ident_ack *resp =
+ pd_get_identity_response(port, TCPCI_MSG_SOP);
+
+ return resp->product.product_id;
+}
+
+uint8_t pd_get_product_type(int port)
+{
+ const union disc_ident_ack *resp =
+ pd_get_identity_response(port, TCPCI_MSG_SOP);
+
+ return resp->idh.product_type;
+}
+
+void pd_set_svids_discovery(int port, enum tcpci_msg_type type,
+ enum pd_discovery_state disc)
+{
+ struct pd_discovery *pd =
+ pd_get_am_discovery_and_notify_access(port, type);
+
+ pd->svids_discovery = disc;
+}
+
+enum pd_discovery_state pd_get_svids_discovery(int port,
+ enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+
+ return disc->svids_discovery;
+}
+
+int pd_get_svid_count(int port, enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+
+ return disc->svid_cnt;
+}
+
+uint16_t pd_get_svid(int port, uint16_t svid_idx, enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+
+ return disc->svids[svid_idx].svid;
+}
+
+void pd_set_modes_discovery(int port, enum tcpci_msg_type type, uint16_t svid,
+ enum pd_discovery_state disc)
+{
+ struct pd_discovery *pd =
+ pd_get_am_discovery_and_notify_access(port, type);
+ int svid_idx;
+
+ for (svid_idx = 0; svid_idx < pd->svid_cnt; ++svid_idx) {
+ struct svid_mode_data *mode_data = &pd->svids[svid_idx];
+
+ if (mode_data->svid != svid)
+ continue;
+
+ mode_data->discovery = disc;
+ return;
+ }
+}
+
+enum pd_discovery_state pd_get_modes_discovery(int port,
+ enum tcpci_msg_type type)
+{
+ const struct svid_mode_data *mode_data = pd_get_next_mode(port, type);
+
+ /*
+ * If there are no SVIDs for which to discover modes, mode discovery is
+ * trivially complete.
+ */
+ if (!mode_data)
+ return PD_DISC_COMPLETE;
+
+ return mode_data->discovery;
+}
+
+int pd_get_mode_vdo_for_svid(int port, enum tcpci_msg_type type, uint16_t svid,
+ uint32_t *vdo_out)
+{
+ int idx;
+ const struct pd_discovery *disc;
+
+ if (type >= DISCOVERY_TYPE_COUNT)
+ return 0;
+
+ disc = pd_get_am_discovery(port, type);
+
+ for (idx = 0; idx < disc->svid_cnt; ++idx) {
+ if (pd_get_svid(port, idx, type) == svid) {
+ memcpy(vdo_out, disc->svids[idx].mode_vdo,
+ sizeof(uint32_t) * disc->svids[idx].mode_cnt);
+ return disc->svids[idx].mode_cnt;
+ }
+ }
+ return 0;
+}
+
+const struct svid_mode_data *pd_get_next_mode(int port,
+ enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+ const struct svid_mode_data *failed_mode_data = NULL;
+ bool svid_good_discovery = false;
+ int svid_idx;
+
+ /* Walk through all of the discovery mode entries */
+ for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) {
+ const struct svid_mode_data *mode_data = &disc->svids[svid_idx];
+
+ /* Discovery is needed, so send this one back now */
+ if (mode_data->discovery == PD_DISC_NEEDED)
+ return mode_data;
+
+ /* Discovery already succeeded, save that it was seen */
+ if (mode_data->discovery == PD_DISC_COMPLETE)
+ svid_good_discovery = true;
+ /* Discovery already failed, save first failure */
+ else if (!failed_mode_data)
+ failed_mode_data = mode_data;
+ }
+
+ /* If no good entries were located, then return last failed */
+ if (!svid_good_discovery)
+ return failed_mode_data;
+
+ /*
+ * Mode discovery has been attempted for every discovered SVID (if
+ * any exist)
+ */
+ return NULL;
+}
+
+const uint32_t *pd_get_mode_vdo(int port, uint16_t svid_idx,
+ enum tcpci_msg_type type)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+
+ return disc->svids[svid_idx].mode_vdo;
+}
+
+bool pd_is_mode_discovered_for_svid(int port, enum tcpci_msg_type type,
+ uint16_t svid)
+{
+ const struct pd_discovery *disc = pd_get_am_discovery(port, type);
+ const struct svid_mode_data *mode_data;
+
+ for (mode_data = disc->svids; mode_data < disc->svids + disc->svid_cnt;
+ ++mode_data) {
+ if (mode_data->svid == svid &&
+ mode_data->discovery == PD_DISC_COMPLETE)
+ return true;
+ }
+
+ return false;
+}
+
+static inline bool is_pd_rev3(int port, enum tcpci_msg_type type)
+{
+ return pd_get_rev(port, type) == PD_REV30;
+}
+
+/*
+ * ############################################################################
+ *
+ * (Charge Through) Vconn Powered Device functions
+ *
+ * ############################################################################
+ */
+bool is_vpd_ct_supported(int port)
+{
+ const struct pd_discovery *disc =
+ pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
+ union vpd_vdo vpd = disc->identity.product_t1.vpd;
+
+ return vpd.ct_support;
+}
+
+/*
+ * ############################################################################
+ *
+ * Cable communication functions
+ *
+ * ############################################################################
+ */
+enum idh_ptype get_usb_pd_cable_type(int port)
+{
+ const struct pd_discovery *disc =
+ pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
+
+ return disc->identity.idh.product_type;
+}
+
+bool is_usb2_cable_support(int port)
+{
+ const struct pd_discovery *disc =
+ pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
+
+ return disc->identity.idh.product_type == IDH_PTYPE_PCABLE ||
+ pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) < VDM_VER20 ||
+ disc->identity.product_t2.a2_rev30.usb_20_support ==
+ USB2_SUPPORTED;
+}
+
+bool is_cable_speed_gen2_capable(int port)
+{
+ const struct pd_discovery *disc =
+ pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
+
+ switch (pd_get_rev(port, TCPCI_MSG_SOP_PRIME)) {
+ case PD_REV20:
+ return disc->identity.product_t1.p_rev20.ss ==
+ USB_R20_SS_U31_GEN1_GEN2;
+
+ case PD_REV30:
+ return disc->identity.product_t1.p_rev30.ss ==
+ USB_R30_SS_U32_U40_GEN2 ||
+ disc->identity.product_t1.p_rev30.ss ==
+ USB_R30_SS_U40_GEN3;
+ default:
+ return false;
+ }
+}
+
+bool is_active_cable_element_retimer(int port)
+{
+ const struct pd_discovery *disc =
+ pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME);
+
+ /* Ref: USB PD Spec 2.0 Table 6-29 Active Cable VDO
+ * Revision 2 Active cables do not have Active element support.
+ */
+ return is_pd_rev3(port, TCPCI_MSG_SOP_PRIME) &&
+ disc->identity.idh.product_type == IDH_PTYPE_ACABLE &&
+ disc->identity.product_t2.a2_rev30.active_elem == ACTIVE_RETIMER;
+}
diff --git a/common/usb_pd_host_cmd.c b/common/usb_pd_host_cmd.c
index 459c700ded..89f7a80848 100644
--- a/common/usb_pd_host_cmd.c
+++ b/common/usb_pd_host_cmd.c
@@ -102,38 +102,6 @@ DECLARE_HOST_COMMAND(EC_CMD_PD_CHIP_INFO, hc_remote_pd_chip_info,
#endif /* CONFIG_EC_CMD_PD_CHIP_INFO && !CONFIG_USB_PD_TCPC */
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
-static enum ec_status hc_remote_pd_set_amode(struct host_cmd_handler_args *args)
-{
- const struct ec_params_usb_pd_set_mode_request *p = args->params;
-
- if ((p->port >= board_get_usb_pd_port_count()) || (!p->svid) ||
- (!p->opos))
- return EC_RES_INVALID_PARAM;
-
- switch (p->cmd) {
- case PD_EXIT_MODE:
- if (pd_dfp_exit_mode(p->port, TCPCI_MSG_SOP, p->svid, p->opos))
- pd_send_vdm(p->port, p->svid,
- CMD_EXIT_MODE | VDO_OPOS(p->opos), NULL, 0);
- else {
- CPRINTF("Failed exit mode\n");
- return EC_RES_ERROR;
- }
- break;
- case PD_ENTER_MODE:
- if (pd_dfp_enter_mode(p->port, TCPCI_MSG_SOP, p->svid, p->opos))
- pd_send_vdm(p->port, p->svid,
- CMD_ENTER_MODE | VDO_OPOS(p->opos), NULL,
- 0);
- break;
- default:
- return EC_RES_INVALID_PARAM;
- }
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_USB_PD_SET_AMODE, hc_remote_pd_set_amode,
- EC_VER_MASK(0));
-
static enum ec_status hc_remote_pd_discovery(struct host_cmd_handler_args *args)
{
const struct ec_params_usb_pd_info_request *p = args->params;
@@ -155,38 +123,6 @@ static enum ec_status hc_remote_pd_discovery(struct host_cmd_handler_args *args)
DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DISCOVERY, hc_remote_pd_discovery,
EC_VER_MASK(0));
-static enum ec_status hc_remote_pd_get_amode(struct host_cmd_handler_args *args)
-{
- struct svdm_amode_data *modep;
- const struct ec_params_usb_pd_get_mode_request *p = args->params;
- struct ec_params_usb_pd_get_mode_response *r = args->response;
-
- if (p->port >= board_get_usb_pd_port_count())
- return EC_RES_INVALID_PARAM;
-
- /* no more to send */
- /* TODO(b/148528713): Use TCPMv2's separate storage for SOP'. */
- if (p->svid_idx >= pd_get_svid_count(p->port, TCPCI_MSG_SOP)) {
- r->svid = 0;
- args->response_size = sizeof(r->svid);
- return EC_RES_SUCCESS;
- }
-
- r->svid = pd_get_svid(p->port, p->svid_idx, TCPCI_MSG_SOP);
- r->opos = 0;
- memcpy(r->vdo, pd_get_mode_vdo(p->port, p->svid_idx, TCPCI_MSG_SOP),
- sizeof(uint32_t) * PDO_MODES);
- modep = pd_get_amode_data(p->port, TCPCI_MSG_SOP, r->svid);
-
- if (modep)
- r->opos = pd_alt_mode(p->port, TCPCI_MSG_SOP, r->svid);
-
- args->response_size = sizeof(*r);
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_USB_PD_GET_AMODE, hc_remote_pd_get_amode,
- EC_VER_MASK(0));
-
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
#ifdef CONFIG_COMMON_RUNTIME
@@ -363,14 +299,12 @@ static enum ec_status hc_usb_pd_control(struct host_cmd_handler_args *args)
r_v2->state[0] = '\0';
r_v2->control_flags = get_pd_control_flags(p->port);
- if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) {
- r_v2->dp_mode = get_dp_pin_mode(p->port);
- if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)) {
- r_v2->cable_speed =
- get_tbt_cable_speed(p->port);
- r_v2->cable_gen =
- get_tbt_rounded_support(p->port);
- }
+
+ r_v2->dp_mode = get_dp_pin_mode(p->port);
+
+ if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)) {
+ r_v2->cable_speed = get_tbt_cable_speed(p->port);
+ r_v2->cable_gen = get_tbt_rounded_support(p->port);
}
if (args->version == 1)
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 036e253766..1678536d50 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -507,3 +507,70 @@ int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload)
}
return rsize;
}
+
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+static enum ec_status hc_remote_pd_set_amode(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_usb_pd_set_mode_request *p = args->params;
+
+ if ((p->port >= board_get_usb_pd_port_count()) || (!p->svid) ||
+ (!p->opos))
+ return EC_RES_INVALID_PARAM;
+
+ switch (p->cmd) {
+ case PD_EXIT_MODE:
+ if (pd_dfp_exit_mode(p->port, TCPCI_MSG_SOP, p->svid, p->opos))
+ pd_send_vdm(p->port, p->svid,
+ CMD_EXIT_MODE | VDO_OPOS(p->opos), NULL, 0);
+ else {
+ CPRINTF("Failed exit mode\n");
+ return EC_RES_ERROR;
+ }
+ break;
+ case PD_ENTER_MODE:
+ if (pd_dfp_enter_mode(p->port, TCPCI_MSG_SOP, p->svid, p->opos))
+ pd_send_vdm(p->port, p->svid,
+ CMD_ENTER_MODE | VDO_OPOS(p->opos), NULL,
+ 0);
+ break;
+ default:
+ return EC_RES_INVALID_PARAM;
+ }
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_USB_PD_SET_AMODE, hc_remote_pd_set_amode,
+ EC_VER_MASK(0));
+
+static enum ec_status hc_remote_pd_get_amode(struct host_cmd_handler_args *args)
+{
+ struct svdm_amode_data *modep;
+ const struct ec_params_usb_pd_get_mode_request *p = args->params;
+ struct ec_params_usb_pd_get_mode_response *r = args->response;
+
+ if (p->port >= board_get_usb_pd_port_count())
+ return EC_RES_INVALID_PARAM;
+
+ /* no more to send */
+ /* TODO(b/148528713): Use TCPMv2's separate storage for SOP'. */
+ if (p->svid_idx >= pd_get_svid_count(p->port, TCPCI_MSG_SOP)) {
+ r->svid = 0;
+ args->response_size = sizeof(r->svid);
+ return EC_RES_SUCCESS;
+ }
+
+ r->svid = pd_get_svid(p->port, p->svid_idx, TCPCI_MSG_SOP);
+ r->opos = 0;
+ memcpy(r->vdo, pd_get_mode_vdo(p->port, p->svid_idx, TCPCI_MSG_SOP),
+ sizeof(uint32_t) * PDO_MODES);
+ modep = pd_get_amode_data(p->port, TCPCI_MSG_SOP, r->svid);
+
+ if (modep)
+ r->opos = pd_alt_mode(p->port, TCPCI_MSG_SOP, r->svid);
+
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_USB_PD_GET_AMODE, hc_remote_pd_get_amode,
+ EC_VER_MASK(0));
+
+#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/common/usbc/build.mk b/common/usbc/build.mk
index 15c9f06001..99043ffab8 100644
--- a/common/usbc/build.mk
+++ b/common/usbc/build.mk
@@ -31,7 +31,7 @@ all-obj-$(CONFIG_USB_CTVPD)+=$(_usbc_dir)usb_pe_ctvpd_sm.o
all-obj-$(CONFIG_USB_DRP_ACC_TRYSRC)+=$(_usbc_dir)usbc_pd_policy.o
all-obj-$(CONFIG_USB_DRP_ACC_TRYSRC)+=$(_usbc_dir)usb_pe_drp_sm.o
all-obj-$(CONFIG_USB_DRP_ACC_TRYSRC)+=$(_usbc_dir)usb_pd_dpm.o
-all-obj-$(CONFIG_USB_DRP_ACC_TRYSRC)+=$(_usbc_dir)dp_alt_mode.o
+all-obj-$(CONFIG_USB_PD_DP_MODE)+=$(_usbc_dir)dp_alt_mode.o
all-obj-$(CONFIG_USB_PD_TBT_COMPAT_MODE)+=$(_usbc_dir)tbt_alt_mode.o
all-obj-$(CONFIG_USB_PD_USB4)+=$(_usbc_dir)usb_mode.o
all-obj-$(CONFIG_CMD_PD)+=$(_usbc_dir)usb_pd_console.o
diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c
index 2fc75bc746..397e5071e5 100644
--- a/common/usbc/usb_pd_dpm.c
+++ b/common/usbc/usb_pd_dpm.c
@@ -283,27 +283,20 @@ enum ec_status pd_request_enter_mode(int port, enum typec_mode mode)
DPM_FLAG_ENTER_USB4))
return EC_RES_BUSY;
- switch (mode) {
- case TYPEC_MODE_DP:
+ if (IS_ENABLED(CONFIG_USB_PD_DP_MODE) && mode == TYPEC_MODE_DP) {
if (dp_is_idle(port))
dp_init(port);
DPM_SET_FLAG(port, DPM_FLAG_ENTER_DP);
- break;
-#ifdef CONFIG_USB_PD_TBT_COMPAT_MODE
- case TYPEC_MODE_TBT:
+ } else if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) &&
+ mode == TYPEC_MODE_TBT) {
/* TODO(b/235984702#comment21): Refactor alt mode modules
* to better support mode reentry. */
if (dp_is_idle(port))
dp_init(port);
DPM_SET_FLAG(port, DPM_FLAG_ENTER_TBT);
- break;
-#endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */
-#ifdef CONFIG_USB_PD_USB4
- case TYPEC_MODE_USB4:
+ } else if (IS_ENABLED(CONFIG_USB_PD_USB4) && mode == TYPEC_MODE_USB4) {
DPM_SET_FLAG(port, DPM_FLAG_ENTER_USB4);
- break;
-#endif
- default:
+ } else {
return EC_RES_INVALID_PARAM;
}
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 4e06a35ddf..3037ed1fca 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -911,6 +911,15 @@ void pe_got_hard_reset(int port)
assert(port == TASK_ID_TO_PD_PORT(task_get_current()));
/*
+ * If we're in the middle of an FRS, any error should cause us to follow
+ * the ErrorRecovery path
+ */
+ if (pe_in_frs_mode(port)) {
+ set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY);
+ return;
+ }
+
+ /*
* Transition from any state to the PE_SRC_Hard_Reset_Received or
* PE_SNK_Transition_to_default state when:
* 1) Hard Reset Signaling is detected.
@@ -1263,8 +1272,12 @@ void pe_got_soft_reset(int port)
/*
* The PE_SRC_Soft_Reset state Shall be entered from any state when a
* Soft_Reset Message is received from the Protocol Layer.
+ *
+ * However, if we're in the middle of an FRS sequence, we need to go to
+ * ErrorRecovery instead.
*/
- set_state_pe(port, PE_SOFT_RESET);
+ set_state_pe(port, pe_in_frs_mode(port) ? PE_WAIT_FOR_ERROR_RECOVERY :
+ PE_SOFT_RESET);
}
__overridable bool pd_can_charge_from_device(int port, const int pdo_cnt,
@@ -1927,13 +1940,6 @@ __maybe_unused static bool pe_attempt_port_discovery(int port)
if (!IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP))
assert(0);
- /*
- * DONE set once modal entry is successful, discovery completes, or
- * discovery results in a NAK
- */
- if (PE_CHK_FLAG(port, PE_FLAGS_VDM_SETUP_DONE))
- return false;
-
/* Apply Port Discovery DR Swap Policy */
if (port_discovery_dr_swap_policy(
port, pe[port].data_role,
@@ -1951,12 +1957,9 @@ __maybe_unused static bool pe_attempt_port_discovery(int port)
*/
if (pe[port].data_role == PD_ROLE_UFP &&
prl_get_rev(port, TCPCI_MSG_SOP) == PD_REV20) {
- pd_set_identity_discovery(port, TCPCI_MSG_SOP, PD_DISC_FAIL);
- pd_set_identity_discovery(port, TCPCI_MSG_SOP_PRIME,
- PD_DISC_FAIL);
+ pd_disable_discovery(port);
pd_notify_event(port, PD_STATUS_EVENT_SOP_DISC_DONE);
pd_notify_event(port, PD_STATUS_EVENT_SOP_PRIME_DISC_DONE);
- PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE);
return false;
}
@@ -1970,12 +1973,6 @@ __maybe_unused static bool pe_attempt_port_discovery(int port)
return true;
}
- /* If mode entry was successful, disable the timer */
- if (PE_CHK_FLAG(port, PE_FLAGS_VDM_SETUP_DONE)) {
- pd_timer_disable(port, PE_TIMER_DISCOVER_IDENTITY);
- return false;
- }
-
/*
* Run discovery functions when the timer indicating either cable
* discovery spacing or BUSY spacing runs out.
@@ -2014,6 +2011,9 @@ __maybe_unused static bool pe_attempt_port_discovery(int port)
pe[port].tx_type = TCPCI_MSG_SOP_PRIME;
set_state_pe(port, PE_INIT_VDM_MODES_REQUEST);
return true;
+ } else {
+ pd_timer_disable(port, PE_TIMER_DISCOVER_IDENTITY);
+ return false;
}
}
@@ -5164,10 +5164,9 @@ static void pe_prs_snk_src_send_swap_run(int port)
* Handle discarded message
*/
if (msg_check & PE_MSG_DISCARDED) {
- if (pe_in_frs_mode(port))
- pe_set_hard_reset(port);
- else
- set_state_pe(port, PE_SNK_READY);
+ set_state_pe(port, pe_in_frs_mode(port) ?
+ PE_WAIT_FOR_ERROR_RECOVERY :
+ PE_SNK_READY);
return;
}
@@ -6144,19 +6143,12 @@ static void pe_vdm_request_dpm_run(int port)
uint32_t *payload = (uint32_t *)rx_emsg[port].buf;
int sop = PD_HEADER_GET_SOP(rx_emsg[port].header);
uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header);
- uint16_t svid = PD_VDO_VID(payload[0]);
- uint8_t vdm_cmd = PD_VDO_CMD(payload[0]);
/*
* PE initiator VDM-ACKed state for requested VDM, like
* PE_INIT_VDM_FOO_ACKed, embedded here.
*/
dpm_vdm_acked(port, sop, cnt, payload);
-
- if (sop == TCPCI_MSG_SOP && svid == USB_SID_DISPLAYPORT &&
- vdm_cmd == CMD_DP_CONFIG) {
- PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE);
- }
break;
}
case VDM_RESULT_NAK: {
@@ -6166,7 +6158,6 @@ static void pe_vdm_request_dpm_run(int port)
* PE initiator VDM-NAKed state for requested VDM, like
* PE_INIT_VDM_FOO_NAKed, embedded here.
*/
- PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE);
/*
* Because Not Supported messages or response timeouts are
@@ -6194,7 +6185,6 @@ static void pe_vdm_request_dpm_exit(int port)
{
if (PE_CHK_FLAG(port, PE_FLAGS_VDM_REQUEST_TIMEOUT)) {
PE_CLR_FLAG(port, PE_FLAGS_VDM_REQUEST_TIMEOUT);
- PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE);
/*
* Mark failure to respond as discovery failure.
@@ -7797,12 +7787,7 @@ void pd_dfp_discovery_init(int port)
void pd_dfp_mode_init(int port)
{
- /*
- * Clear the VDM Setup Done and Modal Operation flags so we will
- * have a fresh discovery
- */
- PE_CLR_MASK(port, BIT(PE_FLAGS_VDM_SETUP_DONE_FN) |
- BIT(PE_FLAGS_MODAL_OPERATION_FN));
+ PE_CLR_FLAG(port, PE_FLAGS_MODAL_OPERATION);
memset(pe[port].partner_amodes, 0, sizeof(pe[port].partner_amodes));
diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h
index c6703f6fd3..6bbf947bea 100644
--- a/common/usbc/usb_pe_private.h
+++ b/common/usbc/usb_pe_private.h
@@ -48,8 +48,6 @@ enum {
PE_FLAGS_PS_RESET_COMPLETE_FN,
/* VCONN swap operation has completed */
PE_FLAGS_VCONN_SWAP_COMPLETE_FN,
- /* Flag to note no more setup VDMs (discovery, etc.) should be sent */
- PE_FLAGS_VDM_SETUP_DONE_FN,
/* Flag to note PR Swap just completed for Startup entry */
PE_FLAGS_PR_SWAP_COMPLETE_FN,
/* Flag to note FRS/PRS context in shared state machine path */
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index b6dc1dd7df..b370d1acf0 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -389,6 +389,22 @@ SECTIONS
#define INIT_ROM_LMA ORIGIN(ROM_RESIDENT_VMA)
#endif
+ /*
+ * This SRAM section is not used by common/ or chip/stm32/, but
+ * available if particular boards want to move the vector table
+ * into SRAM for performance or mutability.
+ */
+ .vtable : {
+ /*
+ * Vector table must be at the base of SRAM. The vector
+ * table section contains a RAM copy of the vector table used on
+ * STM chips for relocating the vector table.
+ */
+ . = ALIGN(8);
+ *(.bss.vector_table)
+ . = ALIGN(8);
+ } > IRAM
+
#ifdef CONFIG_PRESERVE_LOGS
.preserve_logs(NOLOAD) : {
. = ALIGN(8);
diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h
index eb23de7049..b510064652 100644
--- a/core/cortex-m/irq_handler.h
+++ b/core/cortex-m/irq_handler.h
@@ -23,20 +23,19 @@
* ensure it is enabled in the interrupt controller with the right priority.
*/
#define DECLARE_IRQ(irq, routine, priority) DECLARE_IRQ_(irq, routine, priority)
-#define DECLARE_IRQ_(irq, routine, priority) \
- void IRQ_HANDLER(irq)(void); \
- typedef struct { \
- int fake[irq >= CONFIG_IRQ_COUNT ? -1 : 1]; \
- } irq_num_check_##irq; \
- static void __keep routine(void); \
- void IRQ_HANDLER(irq)(void) \
- { \
- void *ret = __builtin_return_address(0); \
- TASK_START_IRQ_HANDLER(ret); \
- routine(); \
- task_resched_if_needed(ret); \
- } \
- const struct irq_priority __keep IRQ_PRIORITY(irq) \
- __attribute__((section(".rodata.irqprio"))) = { irq, \
- priority }
+#define DECLARE_IRQ_(irq, routine, priority) \
+ void IRQ_HANDLER(irq)(void); \
+ typedef struct { \
+ int fake[irq >= CONFIG_IRQ_COUNT ? -1 : 1]; \
+ } irq_num_check_##irq; \
+ static void __keep routine(void); \
+ void IRQ_HANDLER(irq)(void) \
+ { \
+ void *ret = __builtin_return_address(0); \
+ TASK_START_IRQ_HANDLER(ret); \
+ routine(); \
+ task_resched_if_needed(ret); \
+ } \
+ const struct irq_priority __keep IRQ_PRIORITY(irq) __attribute__(( \
+ weak, section(".rodata.irqprio"))) = { irq, priority }
#endif /* __CROS_EC_IRQ_HANDLER_H */
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index 7d364ec2a0..eefe068931 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -364,9 +364,6 @@ void __keep report_panic(void)
if (IS_ENABLED(CONFIG_ARMV7M_CACHE))
cpu_clean_invalidate_dcache();
- if (IS_ENABLED(CONFIG_HOSTCMD_EVENTS))
- host_set_single_event(EC_HOST_EVENT_PANIC);
-
/* Start safe mode if possible */
if (IS_ENABLED(CONFIG_SYSTEM_SAFE_MODE)) {
/* TODO: check for nested exceptions */
diff --git a/cts/common/board.py b/cts/common/board.py
index 3f92ff50ad..d04f73fe5f 100644
--- a/cts/common/board.py
+++ b/cts/common/board.py
@@ -6,14 +6,15 @@
from __future__ import print_function
+from abc import ABCMeta, abstractmethod
import os
import shutil
import subprocess as sp
-from abc import ABCMeta, abstractmethod
import serial # pylint:disable=import-error
import six
+
OCD_SCRIPT_DIR = "/usr/share/openocd/scripts"
OPENOCD_CONFIGS = {
"stm32l476g-eval": "board/stm32l4discovery.cfg",
diff --git a/cts/cts.py b/cts/cts.py
index f61de47398..619c8858c2 100755
--- a/cts/cts.py
+++ b/cts/cts.py
@@ -27,6 +27,7 @@ import time
import common.board as board
+
CTS_RC_PREFIX = "CTS_RC_"
DEFAULT_TH = "stm32l476g-eval"
DEFAULT_DUT = "nucleo-f072rb"
diff --git a/docs/fingerprint/fingerprint-dev-for-partners.md b/docs/fingerprint/fingerprint-dev-for-partners.md
index f6378f5d46..aafa5e0731 100644
--- a/docs/fingerprint/fingerprint-dev-for-partners.md
+++ b/docs/fingerprint/fingerprint-dev-for-partners.md
@@ -118,8 +118,8 @@ Open **two** terminals and enter the chroot in each:
# from a terminal on your machine
(outside chroot) $ cd ~/chromiumos/src
-# enter the chroot (the flag is important)
-(outside chroot) $ cros_sdk --no-ns-pid
+# enter the chroot
+(outside chroot) $ cros_sdk
```
<!-- mdformat off(b/139308852) -->
@@ -152,75 +152,114 @@ Run `servod`:
You should see something like this. Leave it running:
```bash
-2019-04-11 15:21:53,715 - servod - INFO - Start
-2019-04-11 15:21:53,765 - servod - INFO - Found servo, vid: 0x18d1 pid: 0x5002 sid: 911416-00789
-2019-04-11 15:21:53,766 - servod - INFO - Found XML overlay for board zerblebarn
-2019-04-11 15:21:53,766 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_v2_r1.xml, None, 0)
-2019-04-11 15:21:53,767 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_v2_r0.xml, None, 0)
-2019-04-11 15:21:53,771 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/common.xml, None, 0)
-2019-04-11 15:21:53,772 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/power_tools.xml, None, 0)
-2019-04-11 15:21:53,774 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/keyboard.xml, None, 0)
-2019-04-11 15:21:53,775 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/uart_common.xml, None, 0)
-2019-04-11 15:21:53,777 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/ftdii2c_cmd.xml, None, 0)
-2019-04-11 15:21:53,777 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/usb_image_management.xml, None, 0)
-2019-04-11 15:21:53,784 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_zerblebarn_overlay.xml, None, 0)
-2019-04-11 15:21:53,785 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servoflex_v2_r0_p50.xml, None, 0)
-2019-04-11 15:21:53,792 - Servod - INFO - Initializing interface 1 to ftdi_empty
-2019-04-11 15:21:53,792 - Servod - INFO - Initializing interface 2 to ftdi_i2c
-2019-04-11 15:21:53,795 - Servod - INFO - Initializing interface 3 to ftdi_uart
-2019-04-11 15:21:53,799 - Servod - INFO - /dev/pts/8
-2019-04-11 15:21:53,799 - Servod - INFO - Initializing interface 4 to ftdi_uart
-2019-04-11 15:21:53,802 - Servod - INFO - /dev/pts/9
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 5 to ftdi_empty
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 6 to ftdi_empty
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 7 to ftdi_uart
-2019-04-11 15:21:53,805 - Servod - INFO - /dev/pts/10
-2019-04-11 15:21:53,805 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,805 - Servod - INFO - Initializing interface 8 to ftdi_uart
-2019-04-11 15:21:53,808 - Servod - INFO - /dev/pts/11
-2019-04-11 15:21:53,808 - Servod - INFO - Initializing interface 9 to ec3po_uart
-2019-04-11 15:21:53,811 - PD/Cr50 - EC3PO Interface - INFO - -------------------- PD/Cr50 console on: /dev/pts/12
-2019-04-11 15:21:53,811 - Servod - INFO - Initializing interface 10 to ec3po_uart
-2019-04-11 15:21:53,812 - EC - EC3PO Interface - INFO - -------------------- EC console on: /dev/pts/14
-2019-04-11 15:21:54,316 - Servod - INFO - Initialized i2c_mux to rem
-2019-04-11 15:21:54,317 - Servod - INFO - Initialized i2c_mux_en to on
-2019-04-11 15:21:54,319 - Servod - INFO - Initialized pch_disable to off
-2019-04-11 15:21:54,320 - Servod - INFO - Initialized jtag_buf_on_flex_en to off
-2019-04-11 15:21:54,321 - Servod - INFO - Initialized cold_reset to off
-2019-04-11 15:21:54,322 - Servod - INFO - Initialized warm_reset to off
-2019-04-11 15:21:54,323 - Servod - INFO - Initialized spi1_buf_on_flex_en to off
-2019-04-11 15:21:54,324 - Servod - INFO - Initialized spi_hold to off
-2019-04-11 15:21:54,326 - Servod - INFO - Initialized pwr_button to release
-2019-04-11 15:21:54,327 - Servod - INFO - Initialized lid_open to yes
-2019-04-11 15:21:54,328 - Servod - INFO - Initialized spi2_buf_on_flex_en to off
-2019-04-11 15:21:54,330 - Servod - INFO - Initialized rec_mode to off
-2019-04-11 15:21:54,331 - Servod - INFO - Initialized fw_up to off
-2019-04-11 15:21:54,332 - Servod - INFO - Initialized usb_mux_sel1 to dut_sees_usbkey
-2019-04-11 15:21:54,333 - Servod - INFO - Initialized prtctl4_pwren to on
-2019-04-11 15:21:54,334 - Servod - INFO - Initialized uart3_en to on
-2019-04-11 15:21:54,334 - Servod - INFO - Initialized dut_hub_pwren to on
-2019-04-11 15:21:54,335 - Servod - INFO - Initialized kbd_en to off
-2019-04-11 15:21:54,337 - Servod - INFO - Initialized spi1_vref to pp3300
-2019-04-11 15:21:54,338 - Servod - INFO - Initialized spi2_vref to pp1800
-2019-04-11 15:21:54,339 - Servod - INFO - Initialized uart2_en to on
-2019-04-11 15:21:54,340 - Servod - INFO - Initialized uart1_en to on
-2019-04-11 15:21:54,341 - Servod - INFO - Initialized jtag_buf_en to off
-2019-04-11 15:21:54,342 - Servod - INFO - Initialized fw_wp_en to off
-2019-04-11 15:21:54,343 - Servod - INFO - Initialized sd_vref_sel to off
-2019-04-11 15:21:54,343 - Servod - INFO - Initialized ec_ec3po_interp_connect to on
-2019-04-11 15:21:54,344 - Servod - INFO - Initialized uart3_vref to off
-2019-04-11 15:21:54,345 - Servod - INFO - Initialized jtag_vref_sel0 to pp3300
-2019-04-11 15:21:54,346 - Servod - INFO - Initialized jtag_vref_sel1 to pp3300
-2019-04-11 15:21:54,346 - Servod - INFO - Initialized fpmcu_ec3po_interp_connect to on
-2019-04-11 15:21:54,349 - ServoDeviceWatchdog - INFO - Watchdog setup for devices: set([(6353, 20482, '911416-00789')])
-2019-04-11 15:21:54,351 - servod - INFO - Listening on localhost port 9999
+2023-02-03 15:05:30,632 - servod - INFO - Start
+2023-02-03 15:05:30,639 - servod - INFO - Found XML overlay for board icetower
+2023-02-03 15:05:30,639 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servo_micro.xml, None, 0)
+2023-02-03 15:05:30,640 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/common.xml, None, 0)
+2023-02-03 15:05:30,640 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/power_tools.xml, None, 0)
+2023-02-03 15:05:30,642 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/keyboard.xml, None, 0)
+2023-02-03 15:05:30,644 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/uart_common.xml, None, 0)
+2023-02-03 15:05:30,644 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/ec_info.xml, None, 0)
+2023-02-03 15:05:30,645 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/cpu_fw_spi.xml, None, 0)
+2023-02-03 15:05:30,645 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servo_adc_enabled_noop.xml, None, 0)
+2023-02-03 15:05:30,648 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servo_icetower_overlay.xml, None, 0)
+2023-02-03 15:05:30,648 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servo_fpmcu_dev_board_common_overlay.xml, None, 0)
+2023-02-03 15:05:30,649 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servoflex_v2_r0_p50.xml, None, 0)
+2023-02-03 15:05:30,649 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/fpmcu_dev_board_common_inas.xml, None, 0)
+2023-02-03 15:05:30,649 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/ina2xx.xml, None, 0)
+2023-02-03 15:05:30,650 - SystemConfig - INFO - Loading XML config (/usr/lib64/python3.6/site-packages/servo/data/servo_fpmcu_dev_board_uart_common_overlay.xml, None, 0)
+2023-02-03 15:05:30,655 - Servod - INFO - Initializing interface 1 to stm32_uart
+2023-02-03 15:05:30,655 - Interface.Build - INFO - Suart: interface: {'name': 'stm32_uart', 'interface': 0, 'index': 1}
+2023-02-03 15:05:30,661 - Interface.Build - INFO - /dev/pts/2
+2023-02-03 15:05:30,661 - Servod - INFO - Initializing interface 2 to stm32_i2c
+2023-02-03 15:05:30,661 - Interface.Build - INFO - Si2cBus: interface: {'name': 'stm32_i2c', 'interface': 4, 'index': 2}
+2023-02-03 15:05:30,661 - root - INFO - Skipping modprobe of i2c-dev: it is already loaded per existence of: /sys/module/i2c_dev/
+2023-02-03 15:05:30,661 - root - INFO - Executing command: ['modprobe', '--quiet', '--', 'i2c-pseudo']
+2023-02-03 15:05:30,664 - i2c_base - INFO - path b'/dev/i2c-pseudo-controller' not found, cannot start I2C pseudo adapter
+2023-02-03 15:05:30,665 - Servod - INFO - Initializing interface 3 to stm32_uart
+2023-02-03 15:05:30,666 - Interface.Build - INFO - Suart: interface: {'name': 'stm32_uart', 'interface': 3, 'index': 3}
+2023-02-03 15:05:30,670 - Interface.Build - INFO - /dev/pts/3
+2023-02-03 15:05:30,670 - Servod - INFO - Initializing interface 6 to ec3po_uart
+2023-02-03 15:05:30,673 - servo_micro - EC3PO Interface - INFO - -------------------- servo_micro console on: /dev/pts/4
+2023-02-03 15:05:30,673 - Servod - INFO - Initializing interface 7 to stm32_uart
+2023-02-03 15:05:30,673 - Interface.Build - INFO - Suart: interface: {'name': 'stm32_uart', 'interface': 6, 'index': 7}
+2023-02-03 15:05:30,678 - Interface.Build - INFO - /dev/pts/6
+2023-02-03 15:05:30,678 - Servod - INFO - Initializing interface 8 to stm32_uart
+2023-02-03 15:05:30,679 - Interface.Build - INFO - Suart: interface: {'name': 'stm32_uart', 'interface': 5, 'index': 8}
+2023-02-03 15:05:30,684 - Interface.Build - INFO - /dev/pts/7
+2023-02-03 15:05:30,684 - Servod - INFO - Initializing interface 9 to ec3po_uart
+2023-02-03 15:05:30,685 - PD/Cr50 - EC3PO Interface - INFO - -------------------- PD/Cr50 console on: /dev/pts/8
+2023-02-03 15:05:30,685 - Servod - INFO - Initializing interface 10 to ec3po_uart
+2023-02-03 15:05:30,687 - EC - EC3PO Interface - INFO - -------------------- EC console on: /dev/pts/10
+2023-02-03 15:05:30,687 - Servod - INFO - Initializing interface 11 to ec3po_uart
+2023-02-03 15:05:30,688 - CPU - EC3PO Interface - INFO - -------------------- CPU console on: /dev/pts/12
+2023-02-03 15:05:31,193 - Servod - INFO - Initialized init_keyboard to on
+2023-02-03 15:05:31,194 - root - WARNING - cpu_ec3po_interp_connect: '1' not found in the param values
+2023-02-03 15:05:31,195 - root - WARNING - cpu_ec3po_interp_connect: update drv to get and set values from the param map {'off': '0'}
+2023-02-03 15:05:31,195 - Servod - INFO - Initialized cpu_ec3po_interp_connect to off
+2023-02-03 15:05:31,200 - Servod - INFO - Initialized cpu_uart_raw_debug to off
+2023-02-03 15:05:31,202 - Servod - INFO - Initialized cpu_uart_timestamp to off
+2023-02-03 15:05:31,204 - Servod - INFO - Initialized ec_ec3po_interp_connect to on
+2023-02-03 15:05:31,205 - Servod - INFO - Initialized ec_uart_raw_debug to off
+2023-02-03 15:05:31,206 - Servod - INFO - Initialized ec_uart_timestamp to on
+2023-02-03 15:05:31,207 - Servod - INFO - Initialized ec_uart_flush to on
+2023-02-03 15:05:31,290 - CPU - EC3PO.Console - INFO - /dev/pts/12 - Disabling uart timestamps.
+2023-02-03 15:05:31,308 - Servod - INFO - Initialized uart1_en to on
+2023-02-03 15:05:31,335 - Servod - INFO - Initialized servo_micro_ec_boot_mode_uut to off
+2023-02-03 15:05:31,462 - Servod - INFO - Initialized servo_jtag_trst to off
+2023-02-03 15:05:31,564 - Servod - INFO - Initialized spi1_buf_en to off
+2023-02-03 15:05:31,664 - Servod - INFO - Initialized spi2_buf_en to off
+2023-02-03 15:05:31,767 - Servod - INFO - Initialized uart2_en to on
+2023-02-03 15:05:32,020 - Servod - INFO - Initialized spi1_vref to pp3300
+2023-02-03 15:05:32,268 - Servod - INFO - Initialized spi2_vref to pp1800
+2023-02-03 15:05:32,396 - Servod - INFO - Initialized servo_jtag_trst_dir to off
+2023-02-03 15:05:32,521 - Servod - INFO - Initialized servo_jtag_tdi_dir to off
+2023-02-03 15:05:32,620 - Servod - INFO - Initialized gpio_expander_reset to off
+2023-02-03 15:05:32,721 - Servod - INFO - Initialized uart3_on_spi1 to off
+2023-02-03 15:05:32,824 - Servod - INFO - Initialized SERVO_JTAG_TMS_DIR to off
+2023-02-03 15:05:32,952 - Servod - INFO - Initialized SERVO_JTAG_TDO_SEL to off
+2023-02-03 15:05:33,078 - Servod - INFO - Initialized SERVO_JTAG_TMS to off
+2023-02-03 15:05:33,206 - Servod - INFO - Initialized UART3_TX_SERVO_JTAG_TCK to off
+2023-02-03 15:05:33,334 - Servod - INFO - Initialized UART3_RX_JTAG_BUFFER_TO_SERVO_TDO to off
+2023-02-03 15:05:33,459 - Servod - INFO - Initialized SERVO_JTAG_TDO_BUFFER_EN to off
+2023-02-03 15:05:33,585 - Servod - INFO - Initialized SERVO_JTAG_TDI to off
+2023-02-03 15:05:33,711 - Servod - INFO - Initialized SERVO_JTAG_RTCK to off
+2023-02-03 15:05:33,808 - Servod - INFO - Initialized JTAG_BUFOUT_EN_L to off
+2023-02-03 15:05:33,936 - Servod - INFO - Initialized JTAG_BUFIN_EN_L to off
+2023-02-03 15:05:33,936 - Servod - INFO - Initialized usbpd_uart_routing to off
+2023-02-03 15:05:33,940 - Servod - INFO - Initialized fw_wp_en to off
+2023-02-03 15:05:33,943 - Servod - INFO - Initialized tp1 to off
+2023-02-03 15:05:33,948 - Servod - INFO - Initialized cold_reset to off
+2023-02-03 15:05:33,952 - Servod - INFO - Initialized pwr_button to release
+2023-02-03 15:05:33,958 - Servod - INFO - Initialized warm_reset to on
+2023-02-03 15:05:33,962 - Servod - INFO - Initialized rec_mode to on
+2023-02-03 15:05:33,968 - Servod - INFO - Initialized fw_up to off
+2023-02-03 15:05:33,972 - Servod - INFO - Initialized lid_open to yes
+2023-02-03 15:05:33,976 - Servod - INFO - Initialized pch_disable to off
+2023-02-03 15:05:33,978 - Servod - INFO - Initialized tp2 to off
+2023-02-03 15:05:34,380 - servoFirmwareChecker - INFO - servo_micro firmware up to date.
+2023-02-03 15:05:34,381 - Servod - INFO - Initialized servo_micro_firmware_uptodate to check
+2023-02-03 15:05:34,382 - Servod - INFO - Initialized servo_ec3po_interp_connect to on
+2023-02-03 15:05:34,384 - Servod - INFO - Initialized servo_micro_uart_raw_debug to off
+2023-02-03 15:05:34,385 - Servod - INFO - Initialized servo_micro_uart_timestamp to on
+2023-02-03 15:05:34,387 - Servod - INFO - Initialized usbpd_ec3po_interp_connect to on
+2023-02-03 15:05:34,389 - Servod - INFO - Initialized jtag_vref_sel0 to pp3300
+2023-02-03 15:05:34,391 - Servod - INFO - Initialized jtag_vref_sel1 to pp3300
+2023-02-03 15:05:34,398 - Servod - INFO - Initialized hpd to off
+2023-02-03 15:05:34,399 - Servod - INFO - Initialized fpmcu_ec3po_interp_connect to off
+2023-02-03 15:05:34,401 - Servod - INFO - Initialized fpmcu_ec3po_interp_connect_1 to off
+2023-02-03 15:05:34,401 - DeviceWatchdog - INFO - Watchdog setup for devices: [18d1:501a MICRO-S-2201160335]
+2023-02-03 15:05:34,402 - servod - INFO - Listening on localhost port 9999
```
In the other terminal, build and flash the firmware:
+Make sure the toolchain is installed:
+
+```bash
+(chroot) $ sudo cros_setup_toolchains
+```
+
Navigate to the EC source:
```bash
diff --git a/docs/fingerprint/fingerprint-firmware-testing-for-partners.md b/docs/fingerprint/fingerprint-firmware-testing-for-partners.md
index c1a8456a3e..b9de1e92f4 100644
--- a/docs/fingerprint/fingerprint-firmware-testing-for-partners.md
+++ b/docs/fingerprint/fingerprint-firmware-testing-for-partners.md
@@ -57,8 +57,8 @@ This document will assume you are using Servo V4.
# from a terminal on your machine
(outside chroot) $ cd ~/chromiumos/src
-# enter the chroot (the flag is important)
-(outside chroot) $ cros_sdk --no-ns-pid
+# enter the chroot
+(outside chroot) $ cros_sdk
# build autotest for the board to be tested
(chroot) $ emerge-<BOARD> autotest
@@ -79,7 +79,7 @@ Use another terminal and enter the chroot like before:
```bash
(outside chroot) $ cd ~/chromiumos/src
-(outside chroot) $ cros_sdk --no-ns-pid
+(outside chroot) $ cros_sdk
```
To run a single test, use this command in your chroot:
diff --git a/docs/zephyr/zephyr_ap_ec_comm.md b/docs/zephyr/zephyr_ap_ec_comm.md
index dca948fbe9..711b2449ec 100644
--- a/docs/zephyr/zephyr_ap_ec_comm.md
+++ b/docs/zephyr/zephyr_ap_ec_comm.md
@@ -110,20 +110,19 @@ selected host interface and SoC family. Each SoC driver has specific
compatibility string which is used to get node with configuration from the
device tree.
For example, the nuvoton npcx chip uses compatibility string
-`nuvoton,npcx-cros-shi`.
+`nuvoton,npcx-shi`.
The node's required properties are defined in yaml files: [SHI bindings]
```
/ {
- shi: shi@4000f000 {
- compatible = "nuvoton,npcx-cros-shi";
+ shi0: shi@4000f000 {
+ compatible = "nuvoton,npcx-shi";
reg = <0x4000f000 0x120>;
interrupts = <18 1>;
clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 1>;
pinctrl-0 = <&altc_shi_sl>;
shi-cs-wui =<&wui_io53>;
- label = "SHI";
};
}
```
diff --git a/docs/zephyr/ztest.md b/docs/zephyr/ztest.md
index d6b598b0e3..5adcae7c5b 100644
--- a/docs/zephyr/ztest.md
+++ b/docs/zephyr/ztest.md
@@ -128,20 +128,17 @@ platform/ec$ ./twister -T path/to/my/tests
### Run a specific test
```shell
-platform/ec$ ./twister -s external/platform/ec/zephyr/test/<test dir>/<my.test.case>
+platform/ec$ ./twister -s <test dir>/<my.test.scenario>
```
For example:
```shell
-platform/ec$ ./twister -s external/platform/ec/zephyr/test/drivers/drivers.default
+platform/ec$ ./twister -s drivers/drivers.default
```
-Explanation of this string: `external/` is not a path component, but rather a
-label that indicates we are running tests from outside of the Zephyr tree;
-`platform/ec/zephyr/test/` is the location of our tests relative to the first
-common parent of `ZEPHYR_BASE` and `platform/ec`; `drivers` is the directory for
-our driver tests, and `drivers.default` is a specific test scenario defined in
-that directory's `testcase.yaml` file.
+Explanation of this string: `drivers/` is the directory under `zephyr/test/`
+that contains the requested test, and `drivers.default` is the specific test
+scenario specified in that directory's `testcase.yaml` file.
### Run all tests with coverage
diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c
index 24e9e488a5..a5fae9329d 100644
--- a/driver/charger/isl923x.c
+++ b/driver/charger/isl923x.c
@@ -887,7 +887,28 @@ enum ec_error_list raa489000_is_acok(int chgnum, bool *acok)
rv = raw_read16(chgnum, ISL9238_REG_INFO2, &regval);
if (rv != EC_SUCCESS)
return rv;
- *acok = (regval & RAA489000_INFO2_ACOK);
+
+ /*
+ * ACOK can sometimes be asserted when RAA489000 is sourcing VBUS in OTG
+ * mode, because that bit is derived from the VBUS comparator. If the
+ * charger reports it's in OTG mode, always say ACOK is false because we
+ * can't be running from a charger if we're also sourcing VBUS and the
+ * ACOK bit may be untrustworthy.
+ *
+ * This may sometimes report incorrectly because the state bits of
+ * the Information2 register take a small amount of time to update on
+ * a state change. In most cases the event hooks used to trigger
+ * raa489000_check_ac_present are good indications of a state change,
+ * but during power role swaps there may be no hooks executed so it's
+ * most consistent to use the charger's reported state only (otherwise
+ * some situations could use the EC's view of the current state and
+ * others would require asking the charger).
+ */
+ if (((regval >> RAA489000_INFO2_STATE_SHIFT) &
+ RAA489000_INFO2_STATE_MASK) == RAA489000_INFO2_STATE_OTG)
+ *acok = false;
+ else
+ *acok = (regval & RAA489000_INFO2_ACOK) != 0;
return EC_SUCCESS;
}
@@ -1460,6 +1481,7 @@ static enum ec_error_list raa489000_set_vsys_compensation(int chgnum,
*/
return EC_ERROR_UNIMPLEMENTED;
}
+#endif /* CONFIG_CHARGER_RAA489000 && CONFIG_OCPC */
#ifdef CONFIG_PLATFORM_EC_RAA489000_AC_PRESENT_CONTROL
/*
@@ -1477,8 +1499,14 @@ void raa489000_check_ac_delayed(void)
static bool current_val;
bool new_val;
int rv, regval;
+ int chgnum =
+#ifdef CONFIG_OCPC
+ CHARGER_PRIMARY;
+#else
+ 0;
+#endif
- rv = raw_read16(CHARGER_PRIMARY, ISL9238_REG_INFO2, &regval);
+ rv = raw_read16(chgnum, ISL9238_REG_INFO2, &regval);
if (rv == EC_SUCCESS) {
new_val = (((regval >> RAA489000_INFO2_STATE_SHIFT) &
RAA489000_INFO2_STATE_MASK) ==
@@ -1492,8 +1520,7 @@ void raa489000_check_ac_delayed(void)
* be low.
*/
current_val = new_val;
- isl923x_set_comparator_inversion(CHARGER_PRIMARY,
- new_val);
+ isl923x_set_comparator_inversion(chgnum, new_val);
}
}
}
@@ -1521,8 +1548,6 @@ DECLARE_HOOK(HOOK_POWER_SUPPLY_CHANGE, raa489000_check_ac_present,
HOOK_PRIO_DEFAULT);
#endif /* CONFIG_PLATFORM_EC_RAA489000_AC_PRESENT_CONTROL */
-#endif /* CONFIG_CHARGER_RAA489000 && CONFIG_OCPC */
-
const struct charger_drv isl923x_drv = {
.init = &isl923x_init,
.post_init = &isl923x_post_init,
diff --git a/driver/charger/rt9490.c b/driver/charger/rt9490.c
index 016ef12d44..e37c65dc1c 100644
--- a/driver/charger/rt9490.c
+++ b/driver/charger/rt9490.c
@@ -635,6 +635,7 @@ const struct charger_drv rt9490_drv = {
#endif
};
+#ifdef CONFIG_USB_CHARGER
/* BC1.2 */
static int rt9490_get_bc12_ilim(enum charge_supplier supplier)
{
@@ -790,6 +791,7 @@ struct bc12_config bc12_ports[CHARGE_PORT_COUNT] = {
},
};
#endif /* CONFIG_BC12_SINGLE_DRIVER */
+#endif /* CONFIG_USB_CHARGER */
int rt9490_get_thermistor_val(const struct temp_sensor_t *sensor, int *temp_ptr)
{
diff --git a/driver/nfc/ctn730.c b/driver/nfc/ctn730.c
index c8fa1fbdc2..61f5281994 100644
--- a/driver/nfc/ctn730.c
+++ b/driver/nfc/ctn730.c
@@ -739,7 +739,7 @@ static int cc_ctn730(int argc, const char **argv)
return EC_ERROR_PARAM_COUNT;
port = strtoi(argv[1], &end, 0);
- if (*end || port < 0 || pchg_count <= port)
+ if (*end || port < 0 || board_get_pchg_count() <= port)
return EC_ERROR_PARAM2;
cmd->message_type = CTN730_MESSAGE_TYPE_COMMAND;
diff --git a/driver/ppc/rt1739.c b/driver/ppc/rt1739.c
index 6a6e718c0c..e85f4f6202 100644
--- a/driver/ppc/rt1739.c
+++ b/driver/ppc/rt1739.c
@@ -5,6 +5,7 @@
/* Richtek RT1739 USB-C Power Path Controller */
#include "atomic.h"
+#include "battery.h"
#include "common.h"
#include "config.h"
#include "console.h"
@@ -89,19 +90,26 @@ static int rt1739_vbus_sink_enable(int port, int enable)
#ifdef CONFIG_CMD_PPC_DUMP
static int rt1739_dump(int port)
{
+ ccprintf(" ");
+ for (int i = 0; i < 16; i++) {
+ ccprintf("%2X ", i);
+ }
+ ccprintf("\n");
+
for (int i = 0; i <= 0x61; i++) {
int val = 0;
int rt = read_reg(port, i, &val);
if (i % 16 == 0)
- CPRINTF("%02X: ", i);
+ ccprintf("%02X: ", i);
if (rt)
- CPRINTF("-- ");
+ ccprintf("-- ");
else
- CPRINTF("%02X ", val);
+ ccprintf("%02X ", val);
if (i % 16 == 15)
- CPRINTF("\n");
+ ccprintf("\n");
}
+ ccprintf("\n");
return EC_SUCCESS;
}
@@ -240,12 +248,42 @@ static int rt1739_set_frs_enable(int port, int enable)
static int rt1739_init(int port)
{
- int device_id, oc_setting;
+ int device_id, oc_setting, sys_ctrl, vbus_switch_ctrl;
+ bool batt_connected = false;
atomic_clear(&flags[port]);
- RETURN_ERROR(write_reg(port, RT1739_REG_SW_RESET, RT1739_SW_RESET));
- usleep(1 * MSEC);
+ RETURN_ERROR(read_reg(port, RT1739_REG_SYS_CTRL, &sys_ctrl));
+ RETURN_ERROR(
+ read_reg(port, RT1739_REG_VBUS_SWITCH_CTRL, &vbus_switch_ctrl));
+
+ if (IS_ENABLED(CONFIG_BATTERY_FUEL_GAUGE)) {
+ batt_connected = (battery_get_disconnect_state() ==
+ BATTERY_NOT_DISCONNECTED);
+ }
+
+ if (sys_ctrl & RT1739_DEAD_BATTERY) {
+ /*
+ * Dead battery boot, see b/267412033#comment6 for the init
+ * sequence.
+ */
+ RETURN_ERROR(
+ write_reg(port, RT1739_REG_SYS_CTRL,
+ RT1739_DEAD_BATTERY | RT1739_SHUTDOWN_OFF));
+ rt1739_vbus_sink_enable(port, true);
+ RETURN_ERROR(write_reg(port, RT1739_REG_SYS_CTRL,
+ RT1739_OT_EN | RT1739_SHUTDOWN_OFF));
+ } else if (batt_connected || !(vbus_switch_ctrl & RT1739_HV_SNK_EN)) {
+ /*
+ * If rt1739 is not sinking, or there's a working battery,
+ * we can reset its registers safely.
+ *
+ * Otherwise, don't touch the VBUS_SWITCH_CTRL reg.
+ */
+ RETURN_ERROR(
+ write_reg(port, RT1739_REG_SW_RESET, RT1739_SW_RESET));
+ usleep(1 * MSEC);
+ }
RETURN_ERROR(write_reg(port, RT1739_REG_SYS_CTRL,
RT1739_OT_EN | RT1739_SHUTDOWN_OFF));
@@ -278,6 +316,7 @@ static int rt1739_init(int port)
return EC_SUCCESS;
}
+#ifdef CONFIG_USB_CHARGER
static int rt1739_get_bc12_ilim(int charge_supplier)
{
switch (charge_supplier) {
@@ -375,6 +414,7 @@ static void rt1739_usb_charger_task_event(const int port, uint32_t evt)
rt1739_enable_bc12_detection(port, false);
}
}
+#endif /* CONFIG_USB_CHARGER */
static atomic_t pending_events;
@@ -396,8 +436,10 @@ void rt1739_deferred_interrupt(void)
if (read_reg(port, RT1739_REG_INT_EVENT5, &event5))
continue;
+#ifdef CONFIG_USB_CHARGER
if (event5 & RT1739_BC12_SNK_DONE_INT)
usb_charger_task_set_event(port, USB_CHG_EVENT_BC12);
+#endif /* CONFIG_USB_CHARGER */
/* write to clear EVENT4 since FRS interrupt has been handled */
write_reg(port, RT1739_REG_INT_EVENT4, event4);
@@ -438,6 +480,7 @@ const struct ppc_drv rt1739_ppc_drv = {
.interrupt = &rt1739_interrupt,
};
+#ifdef CONFIG_USB_CHARGER
const struct bc12_drv rt1739_bc12_drv = {
.usb_charger_task_init = rt1739_usb_charger_task_init,
.usb_charger_task_event = rt1739_usb_charger_task_event,
@@ -451,3 +494,4 @@ struct bc12_config bc12_ports[CHARGE_PORT_COUNT] = {
},
};
#endif /* CONFIG_BC12_SINGLE_DRIVER */
+#endif /* CONFIG_USB_CHARGER */
diff --git a/driver/ppc/rt1739.h b/driver/ppc/rt1739.h
index d93369094f..620045ef40 100644
--- a/driver/ppc/rt1739.h
+++ b/driver/ppc/rt1739.h
@@ -40,6 +40,7 @@
#define RT1739_REG_SYS_CTRL 0x20
#define RT1739_OT_EN BIT(4)
+#define RT1739_DEAD_BATTERY BIT(1)
#define RT1739_SHUTDOWN_OFF BIT(0)
#define RT1739_REG_VBUS_SWITCH_CTRL 0x21
diff --git a/driver/retimer/bb_retimer.c b/driver/retimer/bb_retimer.c
index 5c07e43e71..88eb4835fc 100644
--- a/driver/retimer/bb_retimer.c
+++ b/driver/retimer/bb_retimer.c
@@ -432,6 +432,8 @@ static int retimer_set_state(const struct usb_mux *me, mux_state_t mux_state,
* Bit 8: DP_CONNECTION
* 0 – No DP connection
* 1 – DP connected
+ *
+ * TODO: Refactor if CONFIG_USB_PD_VDM_AP_CONTROL is supported
*/
if (mux_state & USB_PD_MUX_DP_ENABLED) {
set_retimer_con |= BB_RETIMER_DP_CONNECTION;
diff --git a/driver/sha256/sha256_it8xxx2.c b/driver/sha256/sha256_it8xxx2.c
index 32fda2c714..eb9d83e948 100644
--- a/driver/sha256/sha256_it8xxx2.c
+++ b/driver/sha256/sha256_it8xxx2.c
@@ -66,7 +66,7 @@ void SHA256_init(struct sha256_ctx *ctx)
static void SHA256_chip_calculation(struct sha256_ctx *ctx)
{
- volatile uint8_t hash_ctrl __unused;
+ uint8_t hash_ctrl __unused;
uint32_t key;
key = irq_lock();
@@ -85,7 +85,35 @@ void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len)
ASSERT(len % 4 == 0);
while (rem_len) {
- ctx->w[ctx->w_index++] = htobe32(p[data_index++]);
+ uint32_t tmp, x = p[data_index++];
+
+ /*
+ * htobe32(x); manually inlining this saves several instructions
+ * when compared to a call to __bswapsi2, saving function call
+ * overhead and reloading of the mask constants (because there
+ * are registers to spare in this function). It's written as
+ * inline assembly to ensure that it won't get lowered to a
+ * __builtin_bswap32 that might not be inlined.
+ *
+ * x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
+ * x = (x << 16) | (x >> 16)
+ */
+ if (IS_ENABLED(CONFIG_RISCV) &&
+ IS_ENABLED(CONFIG_LITTLE_ENDIAN)) {
+ __asm__(" slli %[scratch], %[x], 8\n"
+ " srli %[x], %[x], 8\n"
+ " and %[scratch], %[scratch], %[hi]\n"
+ " and %[x], %[x], %[lo]\n"
+ " or %[x], %[scratch], %[x]\n"
+ " slli %[scratch], %[x], 16\n"
+ " srli %[x], %[x], 16\n"
+ " or %[x], %[x], %[scratch]\n"
+ : [x] "+r"(x), [scratch] "=&r"(tmp)
+ : [hi] "r"(0xFF00FF00), [lo] "r"(0x00FF00FF));
+ } else {
+ x = htobe32(x);
+ }
+ ctx->w[ctx->w_index++] = x;
if (ctx->w_index >= 16) {
SHA256_chip_calculation(ctx);
}
diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h
index 2cb63aa22f..db9dda6285 100644
--- a/driver/tcpm/it83xx_pd.h
+++ b/driver/tcpm/it83xx_pd.h
@@ -134,7 +134,11 @@
#define USBPD_REG_MASK_CC_SELECT_RP_RESERVED (BIT(3) | BIT(2) | BIT(1))
#define USBPD_REG_MASK_CC_SELECT_RP_DEF (BIT(3) | BIT(2))
#define USBPD_REG_MASK_CC_SELECT_RP_1A5 BIT(3)
+#ifdef IT8XXX2_USBPD_RP_3A0_VALUE_IS_ZERO
+#define USBPD_REG_MASK_CC_SELECT_RP_3A0 0
+#else
#define USBPD_REG_MASK_CC_SELECT_RP_3A0 BIT(2)
+#endif
#define USBPD_REG_MASK_CC1_CC2_SELECTION BIT(0)
#define IT83XX_USBPD_CCCSR(p) REG8(IT83XX_USBPD_BASE(p) + 0x05)
#define USBPD_REG_MASK_CC2_DISCONNECT BIT(7)
diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c
index 9bf50e1335..2029659de0 100644
--- a/driver/tcpm/it8xxx2.c
+++ b/driver/tcpm/it8xxx2.c
@@ -349,10 +349,21 @@ static void it8xxx2_enable_vconn(enum usbpd_port port, int enabled)
static void it8xxx2_enable_cc(enum usbpd_port port, int enable)
{
- if (enable)
+ if (enable) {
+#ifdef IT8XXX2_USBPD_CCGCR_BIT7_RESERVED
+ IT83XX_USBPD_CCCSR(port) &= ~(USBPD_REG_MASK_CC1_DISCONNECT |
+ USBPD_REG_MASK_CC2_DISCONNECT);
+#else
IT83XX_USBPD_CCGCR(port) &= ~USBPD_REG_MASK_DISABLE_CC;
- else
+#endif
+ } else {
+#ifdef IT8XXX2_USBPD_CCGCR_BIT7_RESERVED
+ IT83XX_USBPD_CCCSR(port) |= (USBPD_REG_MASK_CC1_DISCONNECT |
+ USBPD_REG_MASK_CC2_DISCONNECT);
+#else
IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC;
+#endif
+ }
}
static void it8xxx2_set_power_role(enum usbpd_port port, int power_role)
diff --git a/driver/wpc/cps8100.c b/driver/wpc/cps8100.c
index acfdc06a32..bac911d167 100644
--- a/driver/wpc/cps8100.c
+++ b/driver/wpc/cps8100.c
@@ -544,7 +544,7 @@ static int cc_cps8100(int argc, const char **argv)
return EC_ERROR_PARAM_COUNT;
port = strtoi(argv[1], &end, 0);
- if (*end || port < 0 || pchg_count <= port)
+ if (*end || port < 0 || board_get_pchg_count() <= port)
return EC_ERROR_PARAM2;
ctx = &pchgs[port];
diff --git a/driver/wpc/cps8100.h b/driver/wpc/cps8100.h
new file mode 100644
index 0000000000..0fb6fe0c4e
--- /dev/null
+++ b/driver/wpc/cps8100.h
@@ -0,0 +1,15 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* cps8100 Qi wireless power transmitter module for Chrome EC */
+
+#ifndef __CROS_EC_WPC_CPS8100_H
+#define __CROS_EC_WPC_CPS8100_H
+
+#include "peripheral_charger.h"
+
+extern struct pchg_drv cps8100_drv;
+
+#endif /* __CROS_EC_WPC_CPS8100_H */
diff --git a/extra/cr50_rma_open/cr50_rma_open.py b/extra/cr50_rma_open/cr50_rma_open.py
index dc9c144158..14cd26134f 100755
--- a/extra/cr50_rma_open/cr50_rma_open.py
+++ b/extra/cr50_rma_open/cr50_rma_open.py
@@ -52,6 +52,7 @@ import time
import serial # pylint:disable=import-error
+
SCRIPT_VERSION = 5
CCD_IS_UNRESTRICTED = 1 << 0
WP_IS_DISABLED = 1 << 1
diff --git a/extra/stack_analyzer/stack_analyzer.py b/extra/stack_analyzer/stack_analyzer.py
index 2431545c6a..72db999cd4 100755
--- a/extra/stack_analyzer/stack_analyzer.py
+++ b/extra/stack_analyzer/stack_analyzer.py
@@ -24,6 +24,7 @@ import subprocess
import yaml # pylint:disable=import-error
+
SECTION_RO = "RO"
SECTION_RW = "RW"
# Default size of extra stack frame needed by exception context switch.
diff --git a/extra/tigertool/ecusb/pty_driver.py b/extra/tigertool/ecusb/pty_driver.py
index 723bf41b57..da9ed4ab25 100644
--- a/extra/tigertool/ecusb/pty_driver.py
+++ b/extra/tigertool/ecusb/pty_driver.py
@@ -18,6 +18,7 @@ import time
import pexpect # pylint:disable=import-error
from pexpect import fdpexpect # pylint:disable=import-error
+
# Expecting a result in 3 seconds is plenty even for slow platforms.
DEFAULT_UART_TIMEOUT = 3
FLUSH_UART_TIMEOUT = 1
diff --git a/extra/tigertool/ecusb/tiny_servo_common.py b/extra/tigertool/ecusb/tiny_servo_common.py
index fc028104ed..2d87cf043c 100644
--- a/extra/tigertool/ecusb/tiny_servo_common.py
+++ b/extra/tigertool/ecusb/tiny_servo_common.py
@@ -13,7 +13,8 @@ import time
import six
import usb # pylint:disable=import-error
-from . import pty_driver, stm32uart
+from . import pty_driver
+from . import stm32uart
def get_subprocess_args():
diff --git a/extra/tigertool/ecusb/tiny_servod.py b/extra/tigertool/ecusb/tiny_servod.py
index f8d61b5305..ca84b4474a 100644
--- a/extra/tigertool/ecusb/tiny_servod.py
+++ b/extra/tigertool/ecusb/tiny_servod.py
@@ -4,7 +4,8 @@
"""Helper class to facilitate communication to servo ec console."""
-from ecusb import pty_driver, stm32uart
+from ecusb import pty_driver
+from ecusb import stm32uart
class TinyServod(object):
diff --git a/extra/tigertool/tigertest.py b/extra/tigertool/tigertest.py
index b1186cca77..637652de5c 100755
--- a/extra/tigertool/tigertest.py
+++ b/extra/tigertool/tigertest.py
@@ -9,6 +9,7 @@ import argparse
import subprocess
import sys
+
# Script to control tigertail USB-C Mux board.
#
# optional arguments:
diff --git a/extra/tigertool/tigertool.py b/extra/tigertool/tigertool.py
index 69303aa02a..f036000afe 100755
--- a/extra/tigertool/tigertool.py
+++ b/extra/tigertool/tigertool.py
@@ -13,6 +13,7 @@ import time
import ecusb.tiny_servo_common as c
+
STM_VIDPID = "18d1:5027"
serialno = "Uninitialized"
diff --git a/extra/usb_power/powerlog.py b/extra/usb_power/powerlog.py
index 13e41bd23a..ded8d83215 100755
--- a/extra/usb_power/powerlog.py
+++ b/extra/usb_power/powerlog.py
@@ -13,6 +13,7 @@ from __future__ import print_function
import argparse
import array
+from distutils import sysconfig
import json
import logging
import os
@@ -21,10 +22,10 @@ import struct
import sys
import time
import traceback
-from distutils import sysconfig
-import usb # pylint:disable=import-error
from stats_manager import StatsManager # pylint:disable=import-error
+import usb # pylint:disable=import-error
+
# Directory where hdctools installs configuration files into.
LIB_DIR = os.path.join(
diff --git a/extra/usb_power/stats_manager.py b/extra/usb_power/stats_manager.py
index 2035138731..fc24ef6cae 100644
--- a/extra/usb_power/stats_manager.py
+++ b/extra/usb_power/stats_manager.py
@@ -16,6 +16,7 @@ import os
import numpy # pylint:disable=import-error
+
STATS_PREFIX = "@@"
NAN_TAG = "*"
NAN_DESCRIPTION = "%s domains contain NaN samples" % NAN_TAG
diff --git a/extra/usb_serial/console.py b/extra/usb_serial/console.py
index 2b0ecd5f13..07444c39f3 100755
--- a/extra/usb_serial/console.py
+++ b/extra/usb_serial/console.py
@@ -18,6 +18,7 @@ import threading
import time
import tty
+
try:
import usb # pylint:disable=import-error
except ModuleNotFoundError:
diff --git a/extra/usb_updater/fw_update.py b/extra/usb_updater/fw_update.py
index a77de94a7c..08d579e311 100755
--- a/extra/usb_updater/fw_update.py
+++ b/extra/usb_updater/fw_update.py
@@ -12,13 +12,14 @@ import argparse
import array
import json
import os
+from pprint import pprint
import struct
import sys
import time
-from pprint import pprint
-import usb # pylint:disable=import-error
from ecusb.stm32usb import SusbError
+import usb # pylint:disable=import-error
+
debug = False
diff --git a/extra/usb_updater/servo_updater.py b/extra/usb_updater/servo_updater.py
index c0be11fdde..e53eaac85e 100755
--- a/extra/usb_updater/servo_updater.py
+++ b/extra/usb_updater/servo_updater.py
@@ -16,9 +16,9 @@ import re
import subprocess
import time
+from ecusb import tiny_servod
import ecusb.tiny_servo_common as c
import fw_update
-from ecusb import tiny_servod
class ServoUpdaterException(Exception):
diff --git a/firmware_builder.py b/firmware_builder.py
index dfe1161c59..d633f56388 100755
--- a/firmware_builder.py
+++ b/firmware_builder.py
@@ -17,11 +17,12 @@ import shutil
import subprocess
import sys
-from chromite.api.gen_sdk.chromite.api import firmware_pb2
-
# pylint: disable=import-error
from google.protobuf import json_format
+from chromite.api.gen_sdk.chromite.api import firmware_pb2
+
+
DEFAULT_BUNDLE_DIRECTORY = "/tmp/artifact_bundles"
DEFAULT_BUNDLE_METADATA_FILE = "/tmp/artifact_bundle_metadata"
@@ -61,20 +62,24 @@ def build(opts):
message.
"""
metric_list = firmware_pb2.FwBuildMetricList()
+ ec_dir = pathlib.Path(__file__).parent
# Run formatting checks on all python files.
+ cmd = ["black", "--check", "."]
+ print(f"# Running {' '.join(cmd)}.")
+ subprocess.run(cmd, cwd=os.path.dirname(__file__), check=True)
+ chromite_dir = ec_dir.resolve().parent.parent.parent / "chromite"
+ cmd = [
+ "isort",
+ f"--settings-file={chromite_dir / '.isort.cfg'}",
+ "--check",
+ "--gitignore",
+ "--dont-follow-links",
+ ".",
+ ]
+ print(f"# Running {' '.join(cmd)}.")
subprocess.run(
- ["black", "--check", "."], cwd=os.path.dirname(__file__), check=True
- )
- subprocess.run(
- [
- "isort",
- "--settings-file=.isort.cfg",
- "--check",
- "--gitignore",
- "--dont-follow-links",
- ".",
- ],
+ cmd,
cwd=os.path.dirname(__file__),
check=True,
)
@@ -88,7 +93,6 @@ def build(opts):
file.write(json_format.MessageToJson(metric_list))
return
- ec_dir = pathlib.Path(__file__).parent
subprocess.run([ec_dir / "util" / "check_clang_format.py"], check=True)
cmd = ["make", "clobber"]
diff --git a/fuzz/fuzz_config.h b/fuzz/fuzz_config.h
index 006919d314..d642513b24 100644
--- a/fuzz/fuzz_config.h
+++ b/fuzz/fuzz_config.h
@@ -54,6 +54,8 @@
#define CONFIG_USB_PD_DECODE_SOP
#define CONFIG_USB_DRP_ACC_TRYSRC
#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
#define CONFIG_USBC_VCONN_SWAP
@@ -75,6 +77,8 @@
#define CONFIG_USB_PD_DECODE_SOP
#define CONFIG_USB_DRP_ACC_TRYSRC
#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
#define CONFIG_USBC_VCONN_SWAP
diff --git a/fuzz/pchg_fuzz.c b/fuzz/pchg_fuzz.c
index 06c94a2d83..9b265066d2 100644
--- a/fuzz/pchg_fuzz.c
+++ b/fuzz/pchg_fuzz.c
@@ -34,7 +34,6 @@ struct pchg pchgs[] = {
.events = QUEUE_NULL(PCHG_EVENT_QUEUE_SIZE, enum pchg_event),
},
};
-const int pchg_count = ARRAY_SIZE(pchgs);
static pthread_cond_t done_cond;
static pthread_mutex_t lock;
@@ -47,6 +46,11 @@ static uint8_t input[MAX_MESSAGE_SIZE * MAX_MESSAGES];
static uint8_t *head, *tail;
static bool data_available;
+int board_get_pchg_count(void)
+{
+ return ARRAY_SIZE(pchgs);
+}
+
int pchg_i2c_xfer(int port, uint16_t addr_flags, const uint8_t *out,
int out_size, uint8_t *in, int in_size, int flags)
{
diff --git a/include/config.h b/include/config.h
index e563fad17c..4084c357f2 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4566,15 +4566,18 @@
#define CONFIG_USB_PD_HOST_CMD
#endif
-/* Support for USB PD alternate mode */
+/* Support for USB PD alternate mode entry */
#undef CONFIG_USB_PD_ALT_MODE
-/* Support for USB PD alternate mode of Downward Facing Port */
+/* Support for USB PD alternate mode entry by a Downward Facing Port */
#undef CONFIG_USB_PD_ALT_MODE_DFP
-/* Support for USB PD alternate mode of Upward Facing Port */
+/* Support for USB PD alternate mode entry from an Upward Facing Port */
#undef CONFIG_USB_PD_ALT_MODE_UFP
+/* Support for automatic USB PD Discovery VDM probing and storage */
+#undef CONFIG_USB_PD_DISCOVERY
+
/*
* Do not enter USB PD alternate modes or USB4 automatically. Wait for the AP to
* direct the EC to enter a mode. This requires AP software support.
@@ -4805,6 +4808,9 @@
/* Enable the encoding of msg SOP* in bits 31-28 of 32-bit msg header type */
#undef CONFIG_USB_PD_DECODE_SOP
+/* Enable to support DisplayPort mode from the EC */
+#undef CONFIG_USB_PD_DP_MODE
+
/*
* The USB4 specification defines compatibility support for USB4 products to
* interact with existing Thunderbolt 3 products. Enable this config to enter
@@ -5925,6 +5931,17 @@
/******************************************************************************/
/*
+ * If CONFIG_USB_PD_ALT_MODE_DFP is set and this isn't a zephyr build (which
+ * already did its preprocessing earlier), then enable DP Mode by default and
+ * also enable discovery by default.
+ */
+#if defined(CONFIG_USB_PD_ALT_MODE_DFP) && !defined(CONFIG_ZEPHYR)
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
+#endif
+
+/******************************************************************************/
+/*
* If CONFIG_USBC_SS_MUX_DFP_ONLY is enabled, make sure
* CONFIG_USB_PD_ALT_MODE_UFP is not enabled
*/
diff --git a/include/fpsensor.h b/include/fpsensor.h
index a59eea1b89..3078e2a304 100644
--- a/include/fpsensor.h
+++ b/include/fpsensor.h
@@ -10,6 +10,7 @@
#include "common.h"
#include "ec_commands.h"
+#include "fpsensor_alg.h"
#include <stdint.h>
@@ -135,71 +136,6 @@ int fp_sensor_acquire_image(uint8_t *image_data);
int fp_sensor_acquire_image_with_mode(uint8_t *image_data, int mode);
/**
- * Compares given finger image against enrolled templates.
- *
- * The matching algorithm can update the template with additional biometric data
- * from the image, if it chooses to do so.
- *
- * @param[in,out] templ a pointer to the array of template buffers.
- * @param templ_count the number of buffers in the array of templates.
- * @param[in] image the buffer containing the finger image
- * @param match_index index of the matched finger in the template array if any.
- * @param[out] update_bitmap contains one bit per template, the bit is set if
- * the match has updated the given template.
- *
- * @return EC_MKBP_FP_ERR_MATCH_NO on non-match
- * @return EC_MKBP_FP_ERR_MATCH_YES for match when template was not updated with
- * new data
- * @return EC_MKBP_FP_ERR_MATCH_YES_UPDATED for match when template was updated
- * @return EC_MKBP_FP_ERR_MATCH_YES_UPDATE_FAILED match, but update failed (not
- * saved)
- * @return EC_MKBP_FP_ERR_MATCH_LOW_QUALITY when matching could not be performed
- * due to low image quality
- * @return EC_MKBP_FP_ERR_MATCH_LOW_COVERAGE when matching could not be
- * performed due to finger covering too little area of the sensor
- * @return negative value on error
- */
-int fp_finger_match(void *templ, uint32_t templ_count, uint8_t *image,
- int32_t *match_index, uint32_t *update_bitmap);
-
-/**
- * Start a finger enrollment session.
- *
- * @return 0 on success
- * @return negative value on error
- */
-int fp_enrollment_begin(void);
-
-/**
- * Generate a template from the finger whose enrollment has just being
- * completed.
- *
- * @param[out] templ template buffer, which can be set to NULL to abort current
- * enrollment process.
- *
- * @return 0 on success, negative value on error
- */
-int fp_enrollment_finish(void *templ);
-
-/**
- * Adds fingerprint image to the current enrollment session.
- *
- * @param[in] image Image to add to enrollment
- * @param[out] completion The percentage of the enrollment process that is
- * complete: [0-100].
- *
- * @return 0 on success
- * @return EC_MKBP_FP_ERR_ENROLL_OK when image was successfully enrolled
- * @return EC_MKBP_FP_ERR_ENROLL_IMMOBILE when image added, but user should be
- * advised to move finger
- * @return EC_MKBP_FP_ERR_ENROLL_LOW_QUALITY when image could not be used due to
- * low image quality
- * @return EC_MKBP_FP_ERR_ENROLL_LOW_COVERAGE when image could not be used
- * due to finger covering too little area of the sensor
- */
-int fp_finger_enroll(uint8_t *image, int *completion);
-
-/**
* Runs a test for defective pixels.
*
* Should be triggered periodically by the client. The maintenance command can
diff --git a/include/fpsensor_alg.h b/include/fpsensor_alg.h
new file mode 100644
index 0000000000..ba86359ba0
--- /dev/null
+++ b/include/fpsensor_alg.h
@@ -0,0 +1,78 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Fingerprint sensor interface */
+
+#ifndef __CROS_EC_FPSENSOR_ALG_H
+#define __CROS_EC_FPSENSOR_ALG_H
+
+#include <stdint.h>
+
+/**
+ * Compares given finger image against enrolled templates.
+ *
+ * The matching algorithm can update the template with additional biometric data
+ * from the image, if it chooses to do so.
+ *
+ * @param[in,out] templ a pointer to the array of template buffers.
+ * @param templ_count the number of buffers in the array of templates.
+ * @param[in] image the buffer containing the finger image
+ * @param match_index index of the matched finger in the template array if any.
+ * @param[out] update_bitmap contains one bit per template, the bit is set if
+ * the match has updated the given template.
+ *
+ * @return EC_MKBP_FP_ERR_MATCH_NO on non-match
+ * @return EC_MKBP_FP_ERR_MATCH_YES for match when template was not updated with
+ * new data
+ * @return EC_MKBP_FP_ERR_MATCH_YES_UPDATED for match when template was updated
+ * @return EC_MKBP_FP_ERR_MATCH_YES_UPDATE_FAILED match, but update failed (not
+ * saved)
+ * @return EC_MKBP_FP_ERR_MATCH_LOW_QUALITY when matching could not be performed
+ * due to low image quality
+ * @return EC_MKBP_FP_ERR_MATCH_LOW_COVERAGE when matching could not be
+ * performed due to finger covering too little area of the sensor
+ * @return negative value on error
+ */
+int fp_finger_match(void *templ, uint32_t templ_count, uint8_t *image,
+ int32_t *match_index, uint32_t *update_bitmap);
+
+/**
+ * Start a finger enrollment session.
+ *
+ * @return 0 on success
+ * @return negative value on error
+ */
+int fp_enrollment_begin(void);
+
+/**
+ * Generate a template from the finger whose enrollment has just being
+ * completed.
+ *
+ * @param[out] templ template buffer, which can be set to NULL to abort current
+ * enrollment process.
+ *
+ * @return 0 on success, negative value on error
+ */
+int fp_enrollment_finish(void *templ);
+
+/**
+ * Adds fingerprint image to the current enrollment session.
+ *
+ * @param[in] image Image to add to enrollment
+ * @param[out] completion The percentage of the enrollment process that is
+ * complete: [0-100].
+ *
+ * @return 0 on success
+ * @return EC_MKBP_FP_ERR_ENROLL_OK when image was successfully enrolled
+ * @return EC_MKBP_FP_ERR_ENROLL_IMMOBILE when image added, but user should be
+ * advised to move finger
+ * @return EC_MKBP_FP_ERR_ENROLL_LOW_QUALITY when image could not be used due to
+ * low image quality
+ * @return EC_MKBP_FP_ERR_ENROLL_LOW_COVERAGE when image could not be used
+ * due to finger covering too little area of the sensor
+ */
+int fp_finger_enroll(uint8_t *image, int *completion);
+
+#endif /* __CROS_EC_FPSENSOR_ALG_H */
diff --git a/include/i2c.h b/include/i2c.h
index 4da9306abb..741b578ec8 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -8,6 +8,13 @@
#ifndef __CROS_EC_I2C_H
#define __CROS_EC_I2C_H
+/*
+ * I don't know why but gcc's preprocessor doesn't like the autoconf.h file,
+ * sometimes. Adding a #line directive anywhere in this file seems to fix the
+ * problem. #line marks the *next* line, so it is off by one.
+ */
+#line 17
+
#include "common.h"
#include "gpio_signal.h"
#include "host_command.h"
diff --git a/include/peripheral_charger.h b/include/peripheral_charger.h
index e4b4993d47..bb27a1207d 100644
--- a/include/peripheral_charger.h
+++ b/include/peripheral_charger.h
@@ -343,7 +343,6 @@ struct pchg_drv {
* Should be defined in board.c.
*/
extern struct pchg pchgs[];
-extern const int pchg_count;
/* Utility macro converting port config to port number. */
#define PCHG_CTX_TO_PORT(ctx) ((ctx) - &pchgs[0])
@@ -368,4 +367,9 @@ void pchg_task(void *u);
*/
__override_proto void board_pchg_power_on(int port, bool on);
+/**
+ * Return counts for PCHG charger.
+ */
+int board_get_pchg_count(void);
+
#endif /* __CROS_EC_PERIPHERAL_CHARGER_H */
diff --git a/include/usb_dp_alt_mode.h b/include/usb_dp_alt_mode.h
index 275580b407..eb2d1a25e1 100644
--- a/include/usb_dp_alt_mode.h
+++ b/include/usb_dp_alt_mode.h
@@ -17,6 +17,7 @@
#include <stdint.h>
+#ifdef CONFIG_USB_PD_DP_MODE
/*
* Initialize DP state for the specified port.
*
@@ -88,4 +89,40 @@ void dp_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd);
enum dpm_msg_setup_status dp_setup_next_vdm(int port, int *vdo_count,
uint32_t *vdm);
+#else /* CONFIG_USB_PD_DP_MODE */
+static inline void dp_init(int port)
+{
+}
+
+static inline bool dp_is_active(int port)
+{
+ return false;
+}
+
+static inline bool dp_is_idle(int port)
+{
+ return true;
+}
+
+static inline bool dp_entry_is_done(int port)
+{
+ return false;
+}
+
+static inline void dp_vdm_acked(int port, enum tcpci_msg_type type,
+ int vdo_count, uint32_t *vdm)
+{
+}
+
+static inline void dp_vdm_naked(int port, enum tcpci_msg_type type,
+ uint8_t vdm_cmd)
+{
+}
+
+static inline enum dpm_msg_setup_status
+dp_setup_next_vdm(int port, int *vdo_count, uint32_t *vdm)
+{
+ return MSG_SETUP_ERROR;
+}
+#endif /* CONFIG_USB_PD_DP_MODE */
#endif /* __CROS_EC_USB_DP_ALT_MODE_H */
diff --git a/include/usb_pd.h b/include/usb_pd.h
index cb31f986c7..ddc632e91c 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1960,6 +1960,13 @@ void pd_dfp_discovery_init(int port);
void pd_dfp_mode_init(int port);
/**
+ * Mark all discovery types as failed to prevent any further discovery attempts
+ * until a connection change or DPM request triggers discovery again.
+ * @param port USB-C port number
+ */
+void pd_disable_discovery(int port);
+
+/**
* Set identity discovery state for this type and port
*
* @param port USB-C port number
@@ -3150,6 +3157,7 @@ __override_proto int board_pd_set_frs_enable(int port, int enable);
*/
__overridable void board_frs_handler(int port);
+#ifdef CONFIG_USB_PD_DP_MODE
/**
* Get current DisplayPort pin mode on the specified port.
*
@@ -3157,6 +3165,12 @@ __overridable void board_frs_handler(int port);
* @return MODE_DP_PIN_[A-E] if used else 0
*/
__override_proto uint8_t get_dp_pin_mode(int port);
+#else
+static inline uint8_t get_dp_pin_mode(int port)
+{
+ return 0;
+}
+#endif /* CONFIG_USB_PD_DP_MODE */
/**
* Get board specific usb pd port count
diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h
index 56d0c0abfc..1888002a85 100644
--- a/include/usb_pd_tcpm.h
+++ b/include/usb_pd_tcpm.h
@@ -585,7 +585,11 @@ struct tcpc_config_t {
const struct tcpm_drv *drv;
/* See TCPC_FLAGS_* above */
uint32_t flags;
+#ifdef CONFIG_PLATFORM_EC_TCPC_INTERRUPT
+ struct gpio_dt_spec irq_gpio;
+#else
enum gpio_signal alert_signal;
+#endif
};
#ifndef CONFIG_USB_PD_TCPC_RUNTIME_CONFIG
diff --git a/power/mt8186.c b/power/mt8186.c
index 00972e53a0..f4f91faa51 100644
--- a/power/mt8186.c
+++ b/power/mt8186.c
@@ -4,7 +4,7 @@
*/
/*
- * MT8186 SoC power sequencing module for Chrome EC
+ * MT8186/MT8188 SoC power sequencing module for Chrome EC
*
* This implements the following features:
*
@@ -22,7 +22,6 @@
*/
#include "battery.h"
-#include "builtin/assert.h"
#include "chipset.h"
#include "common.h"
#include "gpio.h"
@@ -55,6 +54,9 @@
#define POWERBTN_BOOT_DELAY (10 * MSEC)
#define PMIC_EN_PULSE_MS 50
+/* PG4200 S5 ready delay */
+#define PG_PP4200_S5_DELAY (100 * MSEC)
+
/* Maximum time it should for PMIC to turn on after toggling PMIC_EN_ODL. */
#define PMIC_EN_TIMEOUT (300 * MSEC)
@@ -68,17 +70,10 @@
#define NORMAL_SHUTDOWN_DELAY (150 * MSEC)
#define RESET_FLAG_TIMEOUT (2 * SECOND)
-#ifndef CONFIG_ZEPHYR
-/* power signal list. Must match order of enum power_signal. */
-const struct power_signal_info power_signal_list[] = {
- { GPIO_AP_EC_SYSRST_ODL, POWER_SIGNAL_ACTIVE_LOW, "AP_IN_RST" },
- { GPIO_AP_IN_SLEEP_L, POWER_SIGNAL_ACTIVE_LOW, "AP_IN_S3" },
- { GPIO_AP_EC_WDTRST_L, POWER_SIGNAL_ACTIVE_LOW, "AP_WDT_ASSERTED" },
- { GPIO_AP_EC_WARM_RST_REQ, POWER_SIGNAL_ACTIVE_HIGH,
- "AP_WARM_RST_REQ" },
-};
-BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
-#endif /* CONFIG_ZEPHYR */
+#if defined(CONFIG_PLATFORM_EC_POWERSEQ_MT8188) && \
+ !DT_NODE_EXISTS(DT_NODELABEL(en_pp4200_s5))
+#error Must have dt node en_pp4200_s5 for MT8188 power sequence
+#endif
/* indicate MT8186 is processing a chipset reset. */
static bool is_resetting;
@@ -360,6 +355,14 @@ enum power_state power_handle_state(enum power_state state)
gpio_enable_interrupt(GPIO_AP_EC_WARM_RST_REQ);
gpio_enable_interrupt(GPIO_AP_EC_WDTRST_L);
+#if DT_NODE_EXISTS(DT_NODELABEL(en_pp4200_s5))
+ gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_pp4200_s5), 1);
+
+ if (power_wait_mask_signals_timeout(PG_PP4200_S5, PG_PP4200_S5,
+ PG_PP4200_S5_DELAY))
+ return POWER_S5G3;
+#endif
+
GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1);
msleep(PMIC_EN_PULSE_MS);
GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 0);
@@ -447,9 +450,15 @@ enum power_state power_handle_state(enum power_state state)
/* Call hooks before we remove power rails */
hook_notify(HOOK_CHIPSET_SHUTDOWN);
+#if DT_NODE_EXISTS(DT_NODELABEL(en_pp4200_s5))
+ gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_pp4200_s5), 0);
+
+ hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
+#endif
return POWER_S5;
case POWER_S5G3:
+#if !DT_NODE_EXISTS(DT_NODELABEL(en_pp4200_s5))
/*
* Normally, this is called in S3S5, but if it's a shutdown
* triggered by EC side, then EC is unable to set up PMIC
@@ -459,6 +468,7 @@ enum power_state power_handle_state(enum power_state state)
* will enter G3 after EC_PMIC_EN_ODL is released.
*/
hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE);
+#endif
return POWER_G3;
default:
CPRINTS("Unexpected power state %d", state);
diff --git a/setup.py b/setup.py
index 51ab1cff64..031894cfe0 100644
--- a/setup.py
+++ b/setup.py
@@ -4,6 +4,7 @@
from setuptools import setup
+
setup(
name="ec3po",
version="1.0.0rc1",
diff --git a/test/build.mk b/test/build.mk
index 963882cea2..e22563d064 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -266,6 +266,7 @@ thermal-y=thermal.o
timer_calib-y=timer_calib.o
timer_dos-y=timer_dos.o
timer-y=timer.o
+tpm_seed_clear-y=tpm_seed_clear.o
uptime-y=uptime.o
usb_common-y=usb_common_test.o fake_battery.o
usb_pd_int-y=usb_pd_int.o
diff --git a/test/fake_usbc.c b/test/fake_usbc.c
index 19e14ba5c8..798cd1fc57 100644
--- a/test/fake_usbc.c
+++ b/test/fake_usbc.c
@@ -270,14 +270,6 @@ const char *pd_get_task_state_name(int port)
}
#endif /* CONFIG_USB_DRP_ACC_TRYSRC */
-void dp_init(int port)
-{
-}
-
-void dp_vdm_acked(int port, int cmd)
-{
-}
-
void dpm_init(int port)
{
}
diff --git a/test/run_device_tests.py b/test/run_device_tests.py
index a2277afd4f..4661d57b74 100755
--- a/test/run_device_tests.py
+++ b/test/run_device_tests.py
@@ -18,7 +18,7 @@ machine against a board connected to a local machine. For example:
Start servod and JLink locally:
(local chroot) $ sudo servod --board dragonclaw
-(local chroot) $ JLinkRemoteServerCLExe -select USB
+(local chroot) $ sudo JLinkRemoteServerCLExe -select USB
Forward the FPMCU console on a TCP port:
@@ -37,27 +37,31 @@ Run the script on the remote machine:
--jlink_port 19020 --console_port 10000
"""
# pylint: enable=line-too-long
+# TODO(b/267800058): refactor into multiple modules
+# pylint: disable=too-many-lines
import argparse
import concurrent
+from concurrent.futures.thread import ThreadPoolExecutor
+from dataclasses import dataclass
+from dataclasses import field
+from enum import Enum
import io
import logging
import os
+from pathlib import Path
import re
import socket
import subprocess
import sys
import time
-from concurrent.futures.thread import ThreadPoolExecutor
-from dataclasses import dataclass, field
-from enum import Enum
-from pathlib import Path
from typing import BinaryIO, Dict, List, Optional, Tuple
# pylint: disable=import-error
import colorama # type: ignore[import]
-import fmap
from contextlib2 import ExitStack
+import fmap
+
# pylint: enable=import-error
@@ -71,6 +75,8 @@ ALL_TESTS_FAILED_REGEX = re.compile(r"Fail! \(\d+ tests\)\r\n")
SINGLE_CHECK_PASSED_REGEX = re.compile(r"Pass: .*")
SINGLE_CHECK_FAILED_REGEX = re.compile(r".*failed:.*")
+RW_IMAGE_BOOTED_REGEX = re.compile(r"^\[Image: RW.*")
+
ASSERTION_FAILURE_REGEX = re.compile(r"ASSERTION FAILURE.*")
DATA_ACCESS_VIOLATION_8020000_REGEX = re.compile(
@@ -131,6 +137,15 @@ class ImageType(Enum):
RW = 2
+class ApplicationType(Enum):
+ """
+ Select the application type to use (test or production)
+ """
+
+ TEST = 1
+ PRODUCTION = 2
+
+
@dataclass
class BoardConfig:
"""Board-specific configuration."""
@@ -150,7 +165,8 @@ class TestConfig:
# pylint: disable=too-many-instance-attributes
test_name: str
- image_to_use: ImageType = ImageType.RW
+ imagetype_to_use: ImageType = ImageType.RW
+ apptype_to_use: ApplicationType = ApplicationType.TEST
finish_regexes: List = None
fail_regexes: List = None
toggle_power: bool = False
@@ -204,6 +220,12 @@ class AllTests:
def get_public_tests(board_config: BoardConfig) -> List[TestConfig]:
"""Return public test configs for the specified board."""
tests = [
+ TestConfig(
+ test_name="production_app_test",
+ finish_regexes=[RW_IMAGE_BOOTED_REGEX],
+ imagetype_to_use=ImageType.RW,
+ apptype_to_use=ApplicationType.PRODUCTION,
+ ),
TestConfig(test_name="abort"),
TestConfig(test_name="aes"),
TestConfig(test_name="always_memset"),
@@ -214,12 +236,12 @@ class AllTests:
TestConfig(test_name="exception"),
TestConfig(
test_name="flash_physical",
- image_to_use=ImageType.RO,
+ imagetype_to_use=ImageType.RO,
toggle_power=True,
),
TestConfig(
test_name="flash_write_protect",
- image_to_use=ImageType.RO,
+ imagetype_to_use=ImageType.RO,
toggle_power=True,
enable_hw_write_protect=True,
),
@@ -227,7 +249,7 @@ class AllTests:
TestConfig(
config_name="fpsensor_spi_ro",
test_name="fpsensor",
- image_to_use=ImageType.RO,
+ imagetype_to_use=ImageType.RO,
test_args=["spi"],
),
TestConfig(
@@ -238,7 +260,7 @@ class AllTests:
TestConfig(
config_name="fpsensor_uart_ro",
test_name="fpsensor",
- image_to_use=ImageType.RO,
+ imagetype_to_use=ImageType.RO,
test_args=["uart"],
),
TestConfig(
@@ -256,7 +278,7 @@ class AllTests:
TestConfig(
config_name="mpu_ro",
test_name="mpu",
- image_to_use=ImageType.RO,
+ imagetype_to_use=ImageType.RO,
finish_regexes=[board_config.mpu_regex],
),
TestConfig(
@@ -282,7 +304,9 @@ class AllTests:
finish_regexes=[board_config.rollback_region1_regex],
test_args=["region1"],
),
- TestConfig(test_name="rollback_entropy", image_to_use=ImageType.RO),
+ TestConfig(
+ test_name="rollback_entropy", imagetype_to_use=ImageType.RO
+ ),
TestConfig(test_name="rtc"),
TestConfig(test_name="sha256"),
TestConfig(test_name="sha256_unrolled"),
@@ -305,6 +329,7 @@ class AllTests:
),
TestConfig(test_name="timer"),
TestConfig(test_name="timer_dos"),
+ TestConfig(test_name="tpm_seed_clear"),
TestConfig(test_name="utils", timeout_secs=20),
TestConfig(test_name="utils_str"),
]
@@ -501,6 +526,14 @@ def power(board_config: BoardConfig, power_on: bool) -> None:
subprocess.run(cmd, check=False).check_returncode()
+def power_cycle(board_config: BoardConfig) -> None:
+ """power_cycle the boards."""
+ logging.debug("power_cycling board")
+ power(board_config, power_on=False)
+ time.sleep(1)
+ power(board_config, power_on=True)
+
+
def hw_write_protect(enable: bool) -> None:
"""Enable/disable hardware write protect."""
if enable:
@@ -516,7 +549,9 @@ def hw_write_protect(enable: bool) -> None:
subprocess.run(cmd, check=False).check_returncode()
-def build(test_name: str, board_name: str, compiler: str) -> None:
+def build(
+ test_name: str, board_name: str, compiler: str, app_type: ApplicationType
+) -> None:
"""Build specified test for specified board."""
cmd = ["make"]
@@ -525,10 +560,15 @@ def build(test_name: str, board_name: str, compiler: str) -> None:
cmd = cmd + [
"BOARD=" + board_name,
- "test-" + test_name,
"-j",
]
+ # If the image type is a test image, then apply test- prefix to the target name
+ if app_type == ApplicationType.TEST:
+ cmd = cmd + [
+ "test-" + test_name,
+ ]
+
logging.debug('Running command: "%s"', " ".join(cmd))
subprocess.run(cmd, check=False).check_returncode()
@@ -626,12 +666,14 @@ def run_test(
# Wait for boot to finish
time.sleep(1)
console.write("\n".encode())
- if test.image_to_use == ImageType.RO:
+ if test.imagetype_to_use == ImageType.RO:
console.write("reboot ro\n".encode())
time.sleep(1)
- test_cmd = "runtest " + " ".join(test.test_args) + "\n"
- console.write(test_cmd.encode())
+ # Skip runtest if using standard app type
+ if test.apptype_to_use != ApplicationType.PRODUCTION:
+ test_cmd = "runtest " + " ".join(test.test_args) + "\n"
+ console.write(test_cmd.encode())
while True:
console.flush()
@@ -706,11 +748,19 @@ def flash_and_run_test(
build_board = test.build_board
# build test binary
- build(test.test_name, build_board, args.compiler)
+ build(test.test_name, build_board, args.compiler, test.apptype_to_use)
- image_path = os.path.join(
- EC_DIR, "build", build_board, test.test_name, test.test_name + ".bin"
- )
+ if test.apptype_to_use == ApplicationType.PRODUCTION:
+ image_path = os.path.join(EC_DIR, "build", build_board, "ec.bin")
+ else:
+ image_path = os.path.join(
+ EC_DIR,
+ "build",
+ build_board,
+ test.test_name,
+ test.test_name + ".bin",
+ )
+ logging.debug("image_path: %s", image_path)
if test.ro_image is not None:
try:
@@ -741,9 +791,7 @@ def flash_and_run_test(
return False
if test.toggle_power:
- power(board_config, power_on=False)
- time.sleep(1)
- power(board_config, power_on=True)
+ power_cycle(board_config)
hw_write_protect(test.enable_hw_write_protect)
diff --git a/test/test_config.h b/test/test_config.h
index 704c3b42c1..926ebba090 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -451,6 +451,8 @@ int ncp15wb_calculate_temp(uint16_t adc);
#define CONFIG_USB_PD_DISCHARGE_GPIO
#undef CONFIG_USB_PD_HOST_CMD
#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
#define CONFIG_USBC_SS_MUX
#define CONFIG_USB_PD_3A_PORTS 0 /* Host does not define a 3.0 A PDO */
#endif
@@ -475,6 +477,8 @@ int ncp15wb_calculate_temp(uint16_t adc);
#define CONFIG_USB_PD_DISCHARGE_GPIO
#undef CONFIG_USB_PD_HOST_CMD
#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
#define CONFIG_USBC_SS_MUX
#define I2C_PORT_HOST_TCPC 0
#define CONFIG_CHARGE_MANAGER
@@ -551,6 +555,8 @@ int ncp15wb_calculate_temp(uint16_t adc);
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_TEST_USB_PE_SM
#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DISCOVERY
#define CONFIG_USBC_VCONN
#define CONFIG_USBC_VCONN_SWAP
#define CONFIG_USB_PID 0x5036
diff --git a/test/timer_jump.py b/test/timer_jump.py
index a4350cecdf..bd2310f3d7 100644
--- a/test/timer_jump.py
+++ b/test/timer_jump.py
@@ -7,6 +7,7 @@
import time
+
DELAY = 5
ERROR_MARGIN = 0.5
diff --git a/test/tpm_seed_clear.c b/test/tpm_seed_clear.c
new file mode 100644
index 0000000000..2077c82e01
--- /dev/null
+++ b/test/tpm_seed_clear.c
@@ -0,0 +1,104 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "ec_commands.h"
+#include "system.h"
+#include "task.h"
+#include "test_util.h"
+
+#ifdef SECTION_IS_RW
+#include "fpsensor_state.h"
+#endif
+
+#include <stdint.h>
+#include <string.h>
+
+test_static const uint8_t default_fake_tpm_seed[] = {
+ 0xd9, 0x71, 0xaf, 0xc4, 0xcd, 0x36, 0xe3, 0x60, 0xf8, 0x5a, 0xa0,
+ 0xa6, 0x2c, 0xb3, 0xf5, 0xe2, 0xeb, 0xb9, 0xd8, 0x2f, 0xb5, 0x78,
+ 0x5c, 0x79, 0x82, 0xce, 0x06, 0x3f, 0xcc, 0x23, 0xb9, 0xe7,
+};
+
+test_static const uint8_t zero_fake_tpm_seed[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+#ifdef SECTION_IS_RO
+test_static uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES];
+#endif
+
+test_static int test_tpm_seed_before_reboot(void)
+{
+ if (IS_ENABLED(SECTION_IS_RW)) {
+ TEST_ASSERT_ARRAY_EQ(tpm_seed, zero_fake_tpm_seed,
+ FP_CONTEXT_TPM_BYTES);
+ memcpy(tpm_seed, default_fake_tpm_seed, FP_CONTEXT_TPM_BYTES);
+ TEST_ASSERT_ARRAY_EQ(tpm_seed, default_fake_tpm_seed,
+ FP_CONTEXT_TPM_BYTES);
+ }
+ return EC_SUCCESS;
+}
+
+test_static int test_tpm_seed_after_reboot(void)
+{
+ if (IS_ENABLED(SECTION_IS_RW)) {
+ TEST_ASSERT_ARRAY_EQ(tpm_seed, zero_fake_tpm_seed,
+ FP_CONTEXT_TPM_BYTES);
+ }
+ return EC_SUCCESS;
+}
+
+test_static void run_test_step1(void)
+{
+ ccprints("Step 1: tpm_seed_clear\n");
+ cflush();
+
+ RUN_TEST(test_tpm_seed_before_reboot);
+
+ if (test_get_error_count()) {
+ test_reboot_to_next_step(TEST_STATE_FAILED);
+ } else {
+ test_reboot_to_next_step(TEST_STATE_STEP_2);
+ }
+}
+
+test_static void run_test_step2(void)
+{
+ ccprints("Step 2: tpm_seed_clear\n");
+ cflush();
+
+ RUN_TEST(test_tpm_seed_after_reboot);
+
+ if (test_get_error_count()) {
+ test_reboot_to_next_step(TEST_STATE_FAILED);
+ } else {
+ test_reboot_to_next_step(TEST_STATE_PASSED);
+ }
+}
+
+void test_run_step(uint32_t state)
+{
+ if (state & TEST_STATE_MASK(TEST_STATE_STEP_1)) {
+ run_test_step1();
+ } else if (state & TEST_STATE_MASK(TEST_STATE_STEP_2)) {
+ run_test_step2();
+ }
+}
+int task_test(void *unused)
+{
+ if (IS_ENABLED(SECTION_IS_RW))
+ test_run_multistep();
+ return EC_SUCCESS;
+}
+
+void run_test(int argc, const char **argv)
+{
+ test_reset();
+ msleep(100); /* Wait for TASK_ID_TEST to initialize */
+ task_wake(TASK_ID_TEST);
+}
diff --git a/test/tpm_seed_clear.tasklist b/test/tpm_seed_clear.tasklist
new file mode 100644
index 0000000000..59918a1ab0
--- /dev/null
+++ b/test/tpm_seed_clear.tasklist
@@ -0,0 +1,10 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * See CONFIG_TASK_LIST in config.h for details.
+ */
+#define CONFIG_TEST_TASK_LIST \
+ TASK_TEST(TEST, task_test, NULL, TASK_STACK_SIZE)
diff --git a/test/usb_pe_drp_old.c b/test/usb_pe_drp_old.c
index 4ea07c1ec9..c352760d1d 100644
--- a/test/usb_pe_drp_old.c
+++ b/test/usb_pe_drp_old.c
@@ -83,11 +83,40 @@ void pd_set_error_recovery(int port)
{
}
+/* Skip discovery (and the corresponding DRS and VCS sequences) by default. A
+ * test may enable this to allow those sequences to run.
+ */
+static bool discovery_enabled;
+
+__override bool port_discovery_dr_swap_policy(int port, enum pd_data_role dr,
+ bool dr_swap_flag)
+{
+ if (!discovery_enabled)
+ return false;
+
+ if (dr_swap_flag && dr == PD_ROLE_UFP)
+ return true;
+
+ return false;
+}
+
+__override bool port_discovery_vconn_swap_policy(int port, bool vconn_swap_flag)
+{
+ if (!discovery_enabled)
+ return false;
+
+ if (IS_ENABLED(CONFIG_USBC_VCONN) && vconn_swap_flag &&
+ !tc_is_vconn_src(port) && tc_check_vconn_swap(port))
+ return true;
+
+ return false;
+}
+
test_static void setup_source(void)
{
/* Start PE. */
task_wait_event(10 * MSEC);
- pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
+ pd_disable_discovery(PORT0);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
/* As long as we're hacking our way to ready, clear any DPM requests */
pe_clr_dpm_requests(PORT0);
@@ -103,7 +132,7 @@ test_static void setup_sink(void)
task_wait_event(10 * MSEC);
pd_comm_enable(PORT0, 1);
task_wait_event(10 * MSEC);
- pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
+ pd_disable_discovery(PORT0);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
/* As long as we're hacking our way to ready, clear any DPM requests */
pe_clr_dpm_requests(PORT0);
@@ -131,7 +160,7 @@ static int test_pe_frs(void)
* background tasks (ex. discovery) aren't running.
*/
tc_prs_src_snk_assert_rd(PORT0);
- pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
+ pd_disable_discovery(PORT0);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
pe_clr_dpm_requests(PORT0);
set_state_pe(PORT0, PE_SNK_READY);
@@ -332,6 +361,8 @@ test_static int test_prl_is_busy(enum pd_power_role pr)
{
int ready_state;
+ discovery_enabled = true;
+
if (pr == PD_ROLE_SOURCE)
ready_state = PE_SRC_READY;
else
@@ -363,6 +394,8 @@ test_static int test_prl_is_busy(enum pd_power_role pr)
*/
TEST_ASSERT(get_state_pe(PORT0) != ready_state);
+ discovery_enabled = false;
+
return EC_SUCCESS;
}
diff --git a/util/build_with_clang.py b/util/build_with_clang.py
index cc4397cab1..ea3a244797 100755
--- a/util/build_with_clang.py
+++ b/util/build_with_clang.py
@@ -7,6 +7,7 @@
"""Build firmware with clang instead of gcc."""
import argparse
import concurrent
+from concurrent.futures import ThreadPoolExecutor
import logging
import multiprocessing
import os
@@ -14,7 +15,7 @@ import shutil
import subprocess
import sys
import typing
-from concurrent.futures import ThreadPoolExecutor
+
# Add to this list as compilation errors are fixed for boards.
BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [
@@ -105,6 +106,7 @@ BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [
"ambassador",
"anahera",
"atlas",
+ "aurash",
"banshee",
"berknip",
"bloog",
@@ -117,6 +119,7 @@ BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [
"casta",
"chronicler",
"collis",
+ "constitution",
"copano",
"coral",
"corori",
diff --git a/util/check_zephyr_project_config.py b/util/check_zephyr_project_config.py
index a49e9855b9..d879a9f04e 100755
--- a/util/check_zephyr_project_config.py
+++ b/util/check_zephyr_project_config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env vpython3
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
@@ -14,6 +14,7 @@ import site
import sys
import tempfile
+
EC_BASE = pathlib.Path(__file__).parent.parent
if "ZEPHYR_BASE" in os.environ:
@@ -35,6 +36,7 @@ site.addsitedir(ZEPHYR_BASE / "scripts" / "kconfig")
import kconfiglib
import zephyr_module
+
# pylint:enable=import-error,wrong-import-position
# Known configuration file extensions.
diff --git a/util/check_zephyr_project_config.py.vpython3 b/util/check_zephyr_project_config.py.vpython3
new file mode 120000
index 0000000000..d586316989
--- /dev/null
+++ b/util/check_zephyr_project_config.py.vpython3
@@ -0,0 +1 @@
+../../../third_party/zephyr/main/.vpython3 \ No newline at end of file
diff --git a/util/check_zephyr_project_config_unittest.py b/util/check_zephyr_project_config_unittest.py
index ad28d8e128..d881cc5a91 100755
--- a/util/check_zephyr_project_config_unittest.py
+++ b/util/check_zephyr_project_config_unittest.py
@@ -13,6 +13,7 @@ import unittest
import check_zephyr_project_config
import mock # pylint:disable=import-error
+
# pylint:disable=protected-access
diff --git a/util/clangd_config.py b/util/clangd_config.py
index 1e013b4159..e9b23e3a04 100755
--- a/util/clangd_config.py
+++ b/util/clangd_config.py
@@ -10,10 +10,10 @@ import argparse
import glob
import multiprocessing
import os
+from pathlib import Path
import shutil
import subprocess
import sys
-from pathlib import Path
from typing import List, Optional
diff --git a/util/config_allowed.txt b/util/config_allowed.txt
index 3c792ae0fb..1b4bc1c107 100644
--- a/util/config_allowed.txt
+++ b/util/config_allowed.txt
@@ -491,7 +491,6 @@ CONFIG_I2C_CONTROLLER
CONFIG_I2C_EXTRA_PACKET_SIZE
CONFIG_I2C_HID_TOUCHPAD
CONFIG_I2C_MULTI_PORT_CONTROLLER
-CONFIG_I2C_NACK_RETRY_COUNT
CONFIG_I2C_PERIPHERAL
CONFIG_I2C_SCL_GATE_ADDR
CONFIG_I2C_SCL_GATE_ADDR_FLAGS
diff --git a/util/crash_analyzer.py b/util/crash_analyzer.py
index 88592f800a..d564984500 100755
--- a/util/crash_analyzer.py
+++ b/util/crash_analyzer.py
@@ -10,6 +10,7 @@ import pathlib
import re
import sys
+
# TODO(b/253492108): Add regexp for missing architectures.
# Regex tested here: https://regex101.com/r/K5S8cB/1
_REGEX_CORTEX_M0 = (
diff --git a/util/ec3po/console.py b/util/ec3po/console.py
index 12b31baa60..cc822a7073 100755
--- a/util/ec3po/console.py
+++ b/util/ec3po/console.py
@@ -17,6 +17,7 @@ from __future__ import print_function
import argparse
import binascii
import ctypes
+from datetime import datetime
import logging
import os
import pty
@@ -25,10 +26,11 @@ import select
import stat
import sys
import traceback
-from datetime import datetime
+from ec3po import interpreter
+from ec3po import threadproc_shim
import six
-from ec3po import interpreter, threadproc_shim
+
PROMPT = b"> "
CONSOLE_INPUT_LINE_SIZE = 80 # Taken from the CONFIG_* with the same name.
diff --git a/util/ec3po/console_unittest.py b/util/ec3po/console_unittest.py
index e2a3d588fd..dfa411f3c8 100755
--- a/util/ec3po/console_unittest.py
+++ b/util/ec3po/console_unittest.py
@@ -14,9 +14,12 @@ import logging
import tempfile
import unittest
+from ec3po import console
+from ec3po import interpreter
+from ec3po import threadproc_shim
import mock # pylint:disable=import-error
import six
-from ec3po import console, interpreter, threadproc_shim
+
ESC_STRING = six.int2byte(console.ControlKey.ESC)
diff --git a/util/ec3po/interpreter.py b/util/ec3po/interpreter.py
index 8d21af247a..16c047039b 100644
--- a/util/ec3po/interpreter.py
+++ b/util/ec3po/interpreter.py
@@ -25,6 +25,7 @@ import traceback
import six
+
COMMAND_RETRIES = 3 # Number of attempts to retry a command.
EC_MAX_READ = 1024 # Max bytes to read at a time from the EC.
EC_SYN = b"\xec" # Byte indicating EC interrogation.
diff --git a/util/ec3po/interpreter_unittest.py b/util/ec3po/interpreter_unittest.py
index e8f19e2e46..a6bfd3baec 100755
--- a/util/ec3po/interpreter_unittest.py
+++ b/util/ec3po/interpreter_unittest.py
@@ -13,9 +13,10 @@ import logging
import tempfile
import unittest
+from ec3po import interpreter
+from ec3po import threadproc_shim
import mock # pylint:disable=import-error
import six
-from ec3po import interpreter, threadproc_shim
def GetBuiltins(func):
diff --git a/util/ec3po/threadproc_shim.py b/util/ec3po/threadproc_shim.py
index f76841dbf7..b468de1535 100644
--- a/util/ec3po/threadproc_shim.py
+++ b/util/ec3po/threadproc_shim.py
@@ -38,6 +38,7 @@ from threading import Thread as ThreadOrProcess
from six.moves.queue import Queue
+
# True if this module has ec3po using subprocesses, False if using threads.
USING_SUBPROCS = False
diff --git a/util/ec_openocd.py b/util/ec_openocd.py
index e0a15bd08b..4d114d4343 100755
--- a/util/ec_openocd.py
+++ b/util/ec_openocd.py
@@ -12,6 +12,7 @@ import subprocess
import sys
import time
+
"""
Flashes and debugs the EC through openocd
"""
diff --git a/util/ectool.cc b/util/ectool.cc
index c997e8e7c3..6a7768b130 100644
--- a/util/ectool.cc
+++ b/util/ectool.cc
@@ -3647,9 +3647,6 @@ static int print_fan(int idx)
switch (rv) {
case EC_FAN_SPEED_NOT_PRESENT:
return -1;
- case EC_FAN_SPEED_STALLED:
- printf("Fan %d stalled!\n", idx);
- break;
default:
printf("Fan %d RPM: %d\n", idx, rv);
break;
diff --git a/util/flash_jlink.py b/util/flash_jlink.py
index dc462e354b..9f4a55e544 100755
--- a/util/flash_jlink.py
+++ b/util/flash_jlink.py
@@ -25,6 +25,7 @@ import sys
import tempfile
import time
+
DEFAULT_SEGGER_REMOTE_PORT = 19020
# Commands are documented here: https://wiki.segger.com/J-Link_Commander
diff --git a/util/inject-keys.py b/util/inject-keys.py
index 7ff72ea134..71eb7a3281 100755
--- a/util/inject-keys.py
+++ b/util/inject-keys.py
@@ -13,6 +13,7 @@ import string
import subprocess
import sys
+
KEYMATRIX = {
"`": (3, 1),
"1": (6, 1),
diff --git a/util/kconfig_check.py b/util/kconfig_check.py
index f3d127175c..1b67f0c846 100755
--- a/util/kconfig_check.py
+++ b/util/kconfig_check.py
@@ -27,6 +27,7 @@ import re
import sys
import traceback
+
# Try to use kconfiglib if available, but fall back to a simple recursive grep.
# This is used by U-Boot in some situations so we keep it to avoid forking this
# script.
diff --git a/util/lcov_stencil.py b/util/lcov_stencil.py
index 12d613c6a4..ba08f0ccaa 100755
--- a/util/lcov_stencil.py
+++ b/util/lcov_stencil.py
@@ -13,12 +13,13 @@ https://github.com/linux-test-project/lcov/blob/master/bin/geninfo
"""
import argparse
+from collections import defaultdict
import logging
import re
import sys
-from collections import defaultdict
from typing import Dict, Set
+
EXTRACT_LINE = re.compile(r"^(FN|DA|BRDA):(\d+),")
EXTRACT_FN = re.compile(r"^(FN):(\d+),(\S+)")
EXTRACT_FNDA = re.compile(r"^(FNDA):(\d+),(\S+)")
diff --git a/util/presubmit_check.sh b/util/presubmit_check.sh
index 5cec68ddd4..0fcd4a3319 100755
--- a/util/presubmit_check.sh
+++ b/util/presubmit_check.sh
@@ -19,26 +19,3 @@ if git diff --no-ext-diff "${upstream_branch}" HEAD |
echo "error: CPRINTS strings should not include newline characters" >&2
exit 1
fi
-
-# Directories that need to be tested by separate unit tests.
-unittest_dirs="util/ec3po/ extra/stack_analyzer/"
-
-for dir in $unittest_dirs; do
- dir_files=$(echo "${PRESUBMIT_FILES}" | grep "${dir}")
- if [[ -z "${dir_files}" ]]; then
- continue
- fi
-
- if [[ ! -e "${dir}/.tests-passed" ]]; then
- echo "Unit tests have not passed. Please run \"${dir}run_tests.sh\"."
- exit 1
- fi
-
- changed_files=$(find ${dir_files} -newer "${dir}/.tests-passed")
- if [[ -n "${changed_files}" ]] && [[ -n "${dir_files}" ]]; then
- echo "Files have changed since last time unit tests passed:"
- echo "${changed_files}" | sed -e 's/^/ /'
- echo "Please run \"${dir}run_tests.sh\"."
- exit 1
- fi
-done
diff --git a/util/run_ects.py b/util/run_ects.py
index a3bf4d295c..e9ab944938 100644
--- a/util/run_ects.py
+++ b/util/run_ects.py
@@ -11,6 +11,7 @@ import os
import subprocess
import sys
+
# List of tests to run.
TESTS = ["meta", "gpio", "hook", "i2c", "interrupt", "mutex", "task", "timer"]
diff --git a/util/run_tests.sh b/util/run_tests.sh
index 56732ee13e..729faf517d 100755
--- a/util/run_tests.sh
+++ b/util/run_tests.sh
@@ -26,3 +26,7 @@ cd util
# NOTE: this uses the Zephyr version of kconfiglib, runs separately from
# test_kconfig_check.py
pytest check_zephyr_project_config_unittest.py
+
+# Run the Zephyr check_compliance wrapper test.
+# NOTE: this uses vpython so it does not run correctly through pytest.
+./zephyr_check_compliance_unittest.py
diff --git a/util/test_kconfig_check.py b/util/test_kconfig_check.py
index 3e459006b1..e30df416fb 100644
--- a/util/test_kconfig_check.py
+++ b/util/test_kconfig_check.py
@@ -14,6 +14,7 @@ import unittest
import kconfig_check
+
# Prefix that we strip from each Kconfig option, when considering whether it is
# equivalent to a CONFIG option with the same name
PREFIX = "PLATFORM_EC_"
diff --git a/util/twister_launcher.py b/util/twister_launcher.py
index 2d6fe9616a..9178b142d9 100755
--- a/util/twister_launcher.py
+++ b/util/twister_launcher.py
@@ -82,16 +82,16 @@ import argparse
import json
import os
import pathlib
+from pathlib import Path
import re
import shlex
import shutil
+from shutil import which
import socket
import subprocess
import sys
import tempfile
import time
-from pathlib import Path
-from shutil import which
def find_checkout() -> Path:
diff --git a/util/twister_tags.py b/util/twister_tags.py
index 68ac5846bd..851c526bac 100755
--- a/util/twister_tags.py
+++ b/util/twister_tags.py
@@ -24,6 +24,7 @@ import sys
import yaml # pylint: disable=import-error
+
TAG_TO_DESCRIPTION = {
"common": "Directly test shared code in the ec/common dir",
"mkbp": "Testing the MKBP (Matrix Keyboard Protocol) stack",
diff --git a/util/uart_stress_tester.py b/util/uart_stress_tester.py
index 8abb71d144..2e96174930 100755
--- a/util/uart_stress_tester.py
+++ b/util/uart_stress_tester.py
@@ -17,7 +17,9 @@ Prerequisite:
e.g. dut-control cr50_uart_timestamp:off
"""
-from __future__ import absolute_import, division, print_function
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
import argparse
import atexit
@@ -30,6 +32,7 @@ import time
import serial # pylint:disable=import-error
+
BAUDRATE = 115200 # Default baudrate setting for UART port
CROS_USERNAME = "root" # Account name to login to ChromeOS
CROS_PASSWORD = "test0000" # Password to login to ChromeOS
diff --git a/util/update_release_branch.py b/util/update_release_branch.py
index 939d572dc4..93527c312c 100755
--- a/util/update_release_branch.py
+++ b/util/update_release_branch.py
@@ -19,6 +19,7 @@ import subprocess
import sys
import textwrap
+
BUG_NONE_PATTERN = re.compile("none", flags=re.IGNORECASE)
diff --git a/util/zephyr_check_compliance.py b/util/zephyr_check_compliance.py
new file mode 100755
index 0000000000..24fea8594e
--- /dev/null
+++ b/util/zephyr_check_compliance.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env vpython3
+
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Check a single commit using the Zephyr check_compliance.py script."""
+
+# [VPYTHON:BEGIN]
+# python_version: "3.8"
+# wheel: <
+# name: "infra/python/wheels/junitparser-py2_py3"
+# version: "version:2.8.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/future-py2_py3"
+# version: "version:0.18.2"
+# >
+# wheel: <
+# name: "infra/python/wheels/python-magic-py2_py3"
+# version: "version:0.4.24"
+# >
+# wheel: <
+# name: "infra/python/wheels/pyyaml-py3"
+# version: "version:5.3.1"
+# >
+# wheel: <
+# name: "infra/python/wheels/yamllint-py3"
+# version: "version:1.29.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/pathspec-py3"
+# version: "version:0.9.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/lxml/${vpython_platform}"
+# version: "version:4.6.3"
+# >
+# [VPYTHON:END]
+
+import argparse
+import os
+import pathlib
+import site
+import sys
+
+
+EC_BASE = pathlib.Path(__file__).parent.parent
+
+if "ZEPHYR_BASE" in os.environ:
+ ZEPHYR_BASE = pathlib.Path(os.environ.get("ZEPHYR_BASE"))
+else:
+ ZEPHYR_BASE = pathlib.Path(
+ EC_BASE.resolve().parent.parent / "third_party" / "zephyr" / "main"
+ )
+
+site.addsitedir(ZEPHYR_BASE / "scripts" / "ci")
+# pylint:disable=import-error,wrong-import-position
+import check_compliance
+
+
+# pylint:enable=import-error,wrong-import-position
+
+
+# Fake ref used by "pre-upload.py --pre-submit"
+PRE_SUBMIT_REF = "pre-submit"
+
+
+def _parse_args(argv):
+ parser = argparse.ArgumentParser(description=__doc__)
+
+ parser.add_argument(
+ "commit",
+ help="Git commit to be checked, hash or reference.",
+ )
+
+ return parser.parse_args(argv)
+
+
+def _patch_get_files():
+ """Patch compliance get_files() to exclude non zephyr files."""
+ original_get_files = check_compliance.get_files
+
+ def patched_get_files(**kwargs):
+ out = []
+ for file in original_get_files(**kwargs):
+ if file.startswith("zephyr/"):
+ out.append(file)
+ return out
+
+ check_compliance.get_files = patched_get_files
+
+
+def _changed_files(commit_range):
+ check_compliance.COMMIT_RANGE = commit_range
+ check_compliance.GIT_TOP = EC_BASE
+
+ files = check_compliance.get_files(filter="d")
+ if len(files) > 0:
+ return True
+
+ return False
+
+
+def main(argv):
+ """Main function"""
+ args = _parse_args(argv)
+
+ if args.commit == PRE_SUBMIT_REF:
+ # Skip if there's no actual commit
+ return
+
+ commit_range = f"{args.commit}~1..{args.commit}"
+
+ _patch_get_files()
+
+ if not _changed_files(commit_range):
+ # Exit early if nothing changed
+ return
+
+ # TODO: also enable DevicetreeBindings
+ check_compliance.main(
+ [
+ "--output=",
+ "--no-case-output",
+ "-m",
+ "YAMLLint",
+ "-c",
+ commit_range,
+ ]
+ )
+ # Never returns, check_compliance.main() calls sys.exit()
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/util/zephyr_check_compliance_unittest.py b/util/zephyr_check_compliance_unittest.py
new file mode 100755
index 0000000000..1d4be968d0
--- /dev/null
+++ b/util/zephyr_check_compliance_unittest.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env vpython3
+
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit tests for check_zephyr_project_config.py"""
+
+# [VPYTHON:BEGIN]
+# python_version: "3.8"
+# wheel: <
+# name: "infra/python/wheels/mock-py3"
+# version: "version:4.0.3"
+# >
+# wheel: <
+# name: "infra/python/wheels/junitparser-py2_py3"
+# version: "version:2.8.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/future-py2_py3"
+# version: "version:0.18.2"
+# >
+# wheel: <
+# name: "infra/python/wheels/python-magic-py2_py3"
+# version: "version:0.4.24"
+# >
+# wheel: <
+# name: "infra/python/wheels/pyyaml-py3"
+# version: "version:5.3.1"
+# >
+# wheel: <
+# name: "infra/python/wheels/yamllint-py3"
+# version: "version:1.29.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/pathspec-py3"
+# version: "version:0.9.0"
+# >
+# wheel: <
+# name: "infra/python/wheels/lxml/${vpython_platform}"
+# version: "version:4.6.3"
+# >
+# [VPYTHON:END]
+
+import unittest
+
+import mock # pylint:disable=import-error
+import zephyr_check_compliance
+
+
+# pylint:disable=protected-access,no-self-use
+
+
+class TestZephyrCheckCompliance(unittest.TestCase):
+ """Tests for zephyr_check_compliance."""
+
+ @mock.patch("check_compliance.get_files")
+ def test_changed_files(self, get_files_mock):
+ """Test _changed_files."""
+ get_files_mock.return_value = [
+ "file1",
+ "file2",
+ ]
+
+ zephyr_check_compliance._patch_get_files()
+ out = zephyr_check_compliance._changed_files("ref")
+ self.assertFalse(out)
+
+ get_files_mock.return_value.append("zephyr/file3")
+
+ zephyr_check_compliance._patch_get_files()
+ out = zephyr_check_compliance._changed_files("ref")
+ self.assertTrue(out)
+
+ @mock.patch("zephyr_check_compliance._changed_files")
+ @mock.patch("check_compliance.main")
+ def test_main(self, main_mock, changed_files_mock):
+ """Tests the main function."""
+ changed_files_mock.return_value = True
+
+ zephyr_check_compliance.main(["ref"])
+
+ changed_files_mock.assert_called_with("ref~1..ref")
+ main_mock.assert_called_with(
+ [
+ "--output=",
+ "--no-case-output",
+ "-m",
+ "YAMLLint",
+ "-c",
+ "ref~1..ref",
+ ]
+ )
+
+ @mock.patch("zephyr_check_compliance._changed_files")
+ @mock.patch("check_compliance.main")
+ def test_main_skip_presubmit(self, main_mock, changed_files_mock):
+ """Tests the main function."""
+ changed_files_mock.return_value = False
+
+ zephyr_check_compliance.main([zephyr_check_compliance.PRE_SUBMIT_REF])
+
+ self.assertEqual(changed_files_mock.call_count, 0)
+ self.assertEqual(main_mock.call_count, 0)
+
+ @mock.patch("zephyr_check_compliance._changed_files")
+ @mock.patch("check_compliance.main")
+ def test_main_skip(self, main_mock, changed_files_mock):
+ """Tests the main function."""
+ changed_files_mock.return_value = False
+
+ zephyr_check_compliance.main(["ref"])
+
+ changed_files_mock.assert_called_with("ref~1..ref")
+ self.assertEqual(main_mock.call_count, 0)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index 5fd91e2335..e3c5780a4c 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -358,6 +358,9 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP
"${PLATFORM_EC}/power/host_sleep.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_MT8186
"${PLATFORM_EC}/power/mt8186.c")
+# Re-use mt8186.c code
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_MT8188
+ "${PLATFORM_EC}/power/mt8186.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_MT8192
"${PLATFORM_EC}/power/mt8192.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_SC7180
@@ -433,6 +436,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_RETIMER_INTEL_HB
"${PLATFORM_EC}/driver/retimer/bb_retimer.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_RETIMER_PS8818
"${PLATFORM_EC}/driver/retimer/ps8818.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_RETIMER_PS8811
+ "${PLATFORM_EC}/driver/retimer/ps8811.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_RETIMER_ANX7451
"${PLATFORM_EC}/driver/usb_mux/anx7451.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_SS_MUX
@@ -468,6 +473,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_OCP
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_ALT_MODE_DFP
"${PLATFORM_EC}/common/usb_pd_alt_mode_dfp.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_DISCOVERY
+ "${PLATFORM_EC}/common/usb_pd_discovery.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_ALT_MODE_UFP
"${PLATFORM_EC}/common/usb_pd_alt_mode_ufp.c")
@@ -487,7 +494,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC
"${PLATFORM_EC}/common/usbc/usb_tc_drp_acc_trysrc_sm.c"
"${PLATFORM_EC}/common/usbc/usb_pe_drp_sm.c"
"${PLATFORM_EC}/common/usbc/usb_pd_dpm.c"
- "${PLATFORM_EC}/common/usbc/usbc_pd_policy.c"
+ "${PLATFORM_EC}/common/usbc/usbc_pd_policy.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_DP_MODE
"${PLATFORM_EC}/common/usbc/dp_alt_mode.c")
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PRL_SM
diff --git a/zephyr/Kconfig.flash b/zephyr/Kconfig.flash
index c8fa606bde..8f3c77499a 100644
--- a/zephyr/Kconfig.flash
+++ b/zephyr/Kconfig.flash
@@ -56,6 +56,7 @@ choice PLATFORM_EC_STORAGE_TYPE
default PLATFORM_EC_EXTERNAL_STORAGE if SOC_FAMILY_NPCX
default PLATFORM_EC_EXTERNAL_STORAGE if SOC_FAMILY_MEC
default PLATFORM_EC_INTERNAL_STORAGE if SOC_FAMILY_RISCV_ITE
+ default PLATFORM_EC_INTERNAL_STORAGE if SOC_FAMILY_STM32
help
Sets the EC code storage type.
diff --git a/zephyr/Kconfig.i2c b/zephyr/Kconfig.i2c
index 9fa1d274aa..fa65ec8f9d 100644
--- a/zephyr/Kconfig.i2c
+++ b/zephyr/Kconfig.i2c
@@ -77,4 +77,11 @@ config PLATFORM_EC_SMBUS_PEC
This option also enables error checking function on smart batteries.
+config PLATFORM_EC_I2C_NACK_RETRY_COUNT
+ int "I2C operation retry count when transaction error"
+ default 0
+ help
+ Defines I2C operation retry count when transaction general input/output
+ error (-EIO) and also when the I2C is busy.
+
endif # PLATFORM_EC_I2C
diff --git a/zephyr/Kconfig.pd b/zephyr/Kconfig.pd
index bd50d64c43..68ecfe78e6 100644
--- a/zephyr/Kconfig.pd
+++ b/zephyr/Kconfig.pd
@@ -32,6 +32,7 @@ config PLATFORM_EC_USB_PD_HOST_CMD
config PLATFORM_EC_CONSOLE_CMD_MFALLOW
bool "Console command: mfallow"
default y
+ depends on CONFIG_USB_PD_DP_MODE
help
Controls whether multi-function support is allowed for DP (Display
Port) connections. Default setting allows multi-function support when
@@ -224,6 +225,7 @@ config PLATFORM_EC_USB_PD_VDM_AP_CONTROL
config PLATFORM_EC_USB_PD_ALT_MODE_DFP
bool "Downward Facing Port support"
default y
+ depends on PLATFORM_EC_USB_PD_DISCOVERY
help
Enable support for USB Power Delivery alternate mode of Downward
Facing Port.
@@ -242,6 +244,14 @@ config PLATFORM_EC_USB_PD_ALT_MODE_UFP
USB4 and ThunderBolt operation when the Chromium OS data role
resolves to the UFP role.
+config PLATFORM_EC_USB_PD_DISCOVERY
+ bool "Enable EC to direct Discover VDMs"
+ default y
+ help
+ This enables support for the EC probing and storing the various
+ partner discovery messages (DiscoverIdentity, DiscoverModes,
+ DiscoverSVIDs).
+
config PLATFORM_EC_USB_PD_USB32_DRD
bool "Port is capable of operating as a USB3.2 device"
default n
@@ -376,6 +386,15 @@ config PLATFORM_EC_USB_PD_TRY_SRC
for laptops, for example, since when attaching to a cellphone we want
the laptop to charge the phone, not vice versa.
+config PLATFORM_EC_USB_PD_DP_MODE
+ bool "EC-driven DP support"
+ depends on !PLATFORM_EC_USB_PD_VDM_AP_CONTROL
+ default y
+ help
+ This enables support for entering DisplayPort alternate mode as a
+ DFP from the Embedded Controller directly. This flag gates all the
+ on-EC logic for determining specifics such as VDM contents.
+
config PLATFORM_EC_USB_PD_USB4
bool "USB4 support"
depends on PLATFORM_EC_USB_PD_REV30
diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq
index 4b438f0bce..7865a6b8e2 100644
--- a/zephyr/Kconfig.powerseq
+++ b/zephyr/Kconfig.powerseq
@@ -217,6 +217,14 @@ config PLATFORM_EC_POWERSEQ_MT8186
help
Use the MT8186 code for power sequencing.
+config PLATFORM_EC_POWERSEQ_MT8188
+ bool "Use common MT8188 code for power sequencing"
+ default y
+ depends on AP_ARM_MTK_MT8188
+ help
+ Use the MT8188 code for power sequencing. Re-use MT8186 common
+ code.
+
config PLATFORM_EC_POWERSEQ_SC7180
bool "SC7180 power sequencing"
depends on AP_ARM_QUALCOMM_SC7180
diff --git a/zephyr/Kconfig.retimer b/zephyr/Kconfig.retimer
index a5c37d7ecb..8c5390eb31 100644
--- a/zephyr/Kconfig.retimer
+++ b/zephyr/Kconfig.retimer
@@ -11,6 +11,7 @@ config PLATFORM_EC_USBC_RETIMER_INTEL_BB
depends on DT_HAS_INTEL_JHL8040R_ENABLED
select PLATFORM_EC_USB_PD_USB4
select PLATFORM_EC_USB_PD_TBT_COMPAT_MODE
+ select PLATFORM_EC_USBC_RETIMER_FW_UPDATE
help
Enable this to support the Intel Burnside Bridge Thunderbolt / USB /
DisplayPort retimer.
@@ -37,6 +38,7 @@ config PLATFORM_EC_USBC_RETIMER_INTEL_HB
depends on DT_HAS_INTEL_JHL9040R_ENABLED
select PLATFORM_EC_USB_PD_USB4
select PLATFORM_EC_USB_PD_TBT_COMPAT_MODE
+ select PLATFORM_EC_USBC_RETIMER_FW_UPDATE
help
Enable this to support the Intel Hayden Bridge Thunderbolt / USB /
DisplayPort retimer.
diff --git a/zephyr/Kconfig.usbc b/zephyr/Kconfig.usbc
index 53c918816c..13fc8c653e 100644
--- a/zephyr/Kconfig.usbc
+++ b/zephyr/Kconfig.usbc
@@ -31,6 +31,15 @@ rsource "Kconfig.usb_charger"
if PLATFORM_EC_USBC
+config PLATFORM_EC_TCPC_INTERRUPT
+ bool "Enables tcpc driver"
+ default y
+ help
+ By default, the tcpc driver is automatically enabled and will
+ initialize using the devicetree configs. Disable to stop tcpc
+ interrupt callbacks from being generated and save space on flash if a
+ custom driver is used instead.
+
config PLATFORM_EC_CHARGER_DEFAULT_CURRENT_LIMIT
int "Charger input current in mA"
depends on PLATFORM_EC_CHARGE_MANAGER
diff --git a/zephyr/Kconfig.usbc_ss_mux b/zephyr/Kconfig.usbc_ss_mux
index a5832a2375..6b8b689816 100644
--- a/zephyr/Kconfig.usbc_ss_mux
+++ b/zephyr/Kconfig.usbc_ss_mux
@@ -48,7 +48,6 @@ config PLATFORM_EC_USB_MUX_VIRTUAL
config PLATFORM_EC_USBC_RETIMER_FW_UPDATE
bool "Support firmware update of USB Type-C retimers"
- default y
depends on PLATFORM_EC_USBC_SS_MUX
help
Enable this to support USB Type-C retimer firmware update. Each
diff --git a/zephyr/Makefile.cq b/zephyr/Makefile.cq
index ae12f5604e..3f02dea325 100644
--- a/zephyr/Makefile.cq
+++ b/zephyr/Makefile.cq
@@ -39,9 +39,12 @@ TEST_PATTERNS='$(PLATFORM_EC)/test/**' \
'$(PLATFORM_EC)/zephyr/mock/**' \
'$(THIRD_PARTY)/zephyr/main/subsys/emul/**' \
'$(THIRD_PARTY)/zephyr/main/arch/posix/**' \
+ '**/*_benchmark.cc' \
'**/*_test.c' \
+ '**/*_test.cc' \
'**/*_test.h' \
'**/*_emul.c' \
+ '**/*_emul.cc' \
'**/*_emul.h' \
'$(PLATFORM_EC)/include/test_util.h' \
'$(PLATFORM_EC)/common/test_util.c' \
@@ -119,7 +122,6 @@ $(BUILD)/zephyr/%_final.info: $(BUILD)/zephyr/%_stenciled.info
'$(THIRD_PARTY)/**' \
'$(PLATFORM_EC)/zephyr/drivers/**' \
'$(PLATFORM_EC)/zephyr/include/drivers/**' \
- '$(PLATFORM_EC)/zephyr/program/**' \
'$(PLATFORM_EC)/zephyr/shim/chip/**' \
'$(PLATFORM_EC)/zephyr/shim/chip/npcx/npcx_monitor/**' \
'$(PLATFORM_EC)/zephyr/shim/core/**' \
diff --git a/zephyr/app/ec/Kconfig b/zephyr/app/ec/Kconfig
index 72c80f5d3a..d0962d4c7f 100644
--- a/zephyr/app/ec/Kconfig
+++ b/zephyr/app/ec/Kconfig
@@ -135,6 +135,7 @@ config CROS_EC_RO_MEM_OFF
config CROS_EC_RO_SIZE
hex "The size of the RO region."
default 0xb000 if ARCH_POSIX
+ default $(dt_node_int_prop_hex,/binman/wp-ro,size)
help
This will be used (along with SYSTEM_RO_MEM_OFF) to determine if the
current PC is in the RO section.
@@ -148,6 +149,7 @@ config CROS_EC_RW_MEM_OFF
config CROS_EC_RW_SIZE
hex "The size of the RW region."
default 0x75000 if ARCH_POSIX
+ default $(dt_node_int_prop_hex,/binman/ec-rw,size)
help
This will be used (along with SYSTEM_RW_MEM_OFF) to determine if the
current PC is in the RW section.
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 bfcfeb8235..ba4b795ca9 100644
--- a/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x
+++ b/zephyr/app/ec/chip/arm/microchip_xec/Kconfig.xec_mec172x
@@ -33,13 +33,11 @@ config CROS_EC_DATA_RAM_SIZE
config CROS_EC_RAM_SIZE
default 0x00f800
-config FLASH_SIZE
- default 512
-
config CROS_EC_RO_MEM_OFF
default 0x0
# was 0x40000
+# TODO(b/268254046): mchp Zephyr: MEC172x: verify RO flash size.
config CROS_EC_RO_SIZE
default 0x3F000
@@ -48,7 +46,4 @@ config CROS_EC_RO_SIZE
config CROS_EC_RW_MEM_OFF
default 0x0
-config CROS_EC_RW_SIZE
- default 0x40000
-
endif # SOC_SERIES_MEC172X
diff --git a/zephyr/app/ec/chip/arm/st_stm32/Kconfig.stm32 b/zephyr/app/ec/chip/arm/st_stm32/Kconfig.stm32
new file mode 100644
index 0000000000..17f712028e
--- /dev/null
+++ b/zephyr/app/ec/chip/arm/st_stm32/Kconfig.stm32
@@ -0,0 +1,32 @@
+# Copyright 2023 The ChromiumOS Authors.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+if SOC_FAMILY_STM32
+
+DT_CHOSEN_Z_SRAM := zephyr,sram
+
+config CROS_EC_PROGRAM_MEMORY_BASE
+ default FLASH_BASE_ADDRESS
+
+config CROS_EC_RAM_BASE
+ default SRAM_BASE_ADDRESS
+
+config CROS_EC_DATA_RAM_SIZE
+ default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_SRAM))
+
+config CROS_EC_RAM_SIZE
+ default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_SRAM))
+
+config CROS_EC_RO_MEM_OFF
+ default $(dt_node_int_prop_hex,/binman/wp-ro,offset)
+
+config CROS_EC_RW_MEM_OFF
+ default $(dt_node_int_prop_hex,/binman/ec-rw,offset)
+
+# Tell the linker where the RO/RW part is.
+config FLASH_LOAD_OFFSET
+ default CROS_EC_RO_MEM_OFF if CROS_EC_RO
+ default CROS_EC_RW_MEM_OFF if CROS_EC_RW
+
+endif # SOC_FAMILY_STM32
diff --git a/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2 b/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2
index e0ea15c5b7..d559c8378c 100644
--- a/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2
+++ b/zephyr/app/ec/chip/riscv/riscv-ite/Kconfig.it8xxx2
@@ -20,21 +20,14 @@ config CROS_EC_DATA_RAM_SIZE
config CROS_EC_RAM_SIZE
default 0x0000e000
-# The 768KB flash space layout are as the below:
-# - RO image starts at the first 384k of flash.
-# - RW image starts at the second 384k of flash.
+# Image size is configured with binman's property.
+# (CROS_EC_RO_SIZE and CROS_EC_RW_SIZE)
config CROS_EC_RO_MEM_OFF
default 0x0
-config CROS_EC_RO_SIZE
- default 0x60000
-
config CROS_EC_RW_MEM_OFF
default 0x60000
-config CROS_EC_RW_SIZE
- default 0x60000
-
config FLASH_LOAD_OFFSET
default CROS_EC_RW_MEM_OFF if CROS_EC_RW
diff --git a/zephyr/app/ec/ec_app_main.c b/zephyr/app/ec/ec_app_main.c
index 160156f7bb..120003b7bc 100644
--- a/zephyr/app/ec/ec_app_main.c
+++ b/zephyr/app/ec/ec_app_main.c
@@ -22,8 +22,8 @@
#include <zephyr/shell/shell_uart.h>
#include <zephyr/sys/printk.h>
-static struct k_timer timer;
-static void console_allow_sleep(struct k_timer *timer)
+static struct k_timer no_sleep_boot_timer;
+static void boot_allow_sleep(struct k_timer *timer)
{
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
@@ -53,8 +53,8 @@ void ec_app_main(void)
k_timeout_t duration =
K_MSEC(CONFIG_PLATFORM_EC_BOOT_NO_SLEEP_MS);
- k_timer_init(&timer, console_allow_sleep, NULL);
- k_timer_start(&timer, duration, K_NO_WAIT);
+ k_timer_init(&no_sleep_boot_timer, boot_allow_sleep, NULL);
+ k_timer_start(&no_sleep_boot_timer, duration, K_NO_WAIT);
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE,
PM_ALL_SUBSTATES);
diff --git a/zephyr/app/ec/soc/Kconfig b/zephyr/app/ec/soc/Kconfig
index 3dccfa3a2a..f3da740ccf 100644
--- a/zephyr/app/ec/soc/Kconfig
+++ b/zephyr/app/ec/soc/Kconfig
@@ -56,6 +56,12 @@ config AP_ARM_MTK_MT8186
help
The application processor is a MediaTek MT8186 processor.
+config AP_ARM_MTK_MT8188
+ bool "MediaTek MT8188"
+ select AP_AARCH64
+ help
+ The application processor is a MediaTek MT8188 processor.
+
config AP_ARM_QUALCOMM_SC7180
bool "Qualcomm Snapdragon SC7180"
select AP_AARCH64
diff --git a/zephyr/boards/arm/mec1727/mec1727.dts b/zephyr/boards/arm/mec1727/mec1727.dts
index f0861e4b61..7c8c3b5d36 100644
--- a/zephyr/boards/arm/mec1727/mec1727.dts
+++ b/zephyr/boards/arm/mec1727/mec1727.dts
@@ -24,6 +24,11 @@
zephyr,flash-controller = &int_flash;
};
+ /* MEC172x Chrome design - 256KB code size */
+ flash0: flash@c0000 {
+ reg = <0x000C0000 0x40000>;
+ };
+
named-pwms {
compatible = "named-pwms";
};
diff --git a/zephyr/boards/arm/npcx7/npcx7.dts b/zephyr/boards/arm/npcx7/npcx7.dts
index cfe67a1b66..a4f0646001 100644
--- a/zephyr/boards/arm/npcx7/npcx7.dts
+++ b/zephyr/boards/arm/npcx7/npcx7.dts
@@ -45,19 +45,6 @@
/* Override keyboard scanning */
soc {
/delete-node/ kscan@400a3000;
- /* TODO(b/265198571): Migrate Zephyr EC builds to upstream SHI
- * drivers.
- */
- /delete-node/ shi@4000f000;
- shi: shi@4000f000 {
- compatible = "nuvoton,npcx-cros-shi";
- reg = <0x4000f000 0x120>;
- interrupts = <18 1>;
- clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 1>;
- shi-cs-wui =<&wui_io53>;
- label = "SHI";
- status = "disabled";
- };
};
};
diff --git a/zephyr/boards/arm/npcx9/npcx9.dtsi b/zephyr/boards/arm/npcx9/npcx9.dtsi
index 8f630ae86b..113cecc173 100644
--- a/zephyr/boards/arm/npcx9/npcx9.dtsi
+++ b/zephyr/boards/arm/npcx9/npcx9.dtsi
@@ -40,19 +40,6 @@
/* Override keyboard scanning */
soc {
/delete-node/ kscan@400a3000;
- /* TODO(b/265198571): Migrate Zephyr EC builds to upstream SHI
- * drivers.
- */
- /delete-node/ shi@4000f000;
- shi: shi@4000f000 {
- compatible = "nuvoton,npcx-cros-shi";
- reg = <0x4000f000 0x120>;
- interrupts = <18 1>;
- clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 1>;
- shi-cs-wui =<&wui_io53>;
- label = "SHI";
- status = "disabled";
- };
};
};
diff --git a/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi
index 1f7eb98356..5debb86381 100644
--- a/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi
+++ b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi
@@ -70,19 +70,6 @@
/* Override keyboard scanning */
soc {
/delete-node/ kscan@400a3000;
- /* TODO(b/265198571): Migrate Zephyr EC builds to upstream SHI
- * drivers.
- */
- /delete-node/ shi@4000f000;
- shi: shi@4000f000 {
- compatible = "nuvoton,npcx-cros-shi";
- reg = <0x4000f000 0x120>;
- interrupts = <18 1>;
- clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 1>;
- shi-cs-wui =<&wui_io53>;
- label = "SHI";
- status = "disabled";
- };
};
};
diff --git a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
index 9567ffaad3..422821d478 100644
--- a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
+++ b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts
@@ -40,10 +40,6 @@
pinctrl-names = "default";
};
-&cros_kb_raw {
- status = "okay"; /* Override in project dts if not required */
-};
-
&espi0 {
status = "okay";
};
diff --git a/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c b/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c
index 2d34a21523..ee687c8f61 100644
--- a/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c
+++ b/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c
@@ -209,7 +209,7 @@ static int cros_flash_it8xxx2_erase(const struct device *dev, int offset,
*/
if (IS_ENABLED(HAS_TASK_HOSTCMD) &&
IS_ENABLED(CONFIG_HOST_COMMAND_STATUS)) {
- irq_enable(DT_IRQN(DT_NODELABEL(shi)));
+ irq_enable(DT_IRQN(DT_NODELABEL(shi0)));
}
/* Always use sector erase command */
for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE) {
diff --git a/zephyr/drivers/cros_flash/cros_flash_xec.c b/zephyr/drivers/cros_flash/cros_flash_xec.c
index 610a79c971..6cb36bce66 100644
--- a/zephyr/drivers/cros_flash/cros_flash_xec.c
+++ b/zephyr/drivers/cros_flash/cros_flash_xec.c
@@ -32,7 +32,11 @@ struct cros_flash_xec_data {
const struct device *spi_ctrl_dev;
};
-static struct spi_config spi_cfg;
+/* initialize spi_cfg, SPI driver checks "SPI word size" field */
+static struct spi_config spi_cfg = {
+ .operation = SPI_WORD_SET(8) | SPI_LINES_SINGLE,
+ .frequency = DT_PROP(DT_NODELABEL(int_flash), spi_max_frequency)
+};
#define FLASH_DEV DT_NODELABEL(int_flash)
#define SPI_CONTROLLER_DEV DT_NODELABEL(spi0)
diff --git a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
index f824d1d90c..7de488b059 100644
--- a/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
+++ b/zephyr/drivers/cros_kb_raw/cros_kb_raw_ite.c
@@ -14,6 +14,7 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
+#include <zephyr/drivers/pinctrl.h>
#include <zephyr/dt-bindings/interrupt-controller/it8xxx2-wuc.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
@@ -42,6 +43,8 @@ struct cros_kb_raw_ite_config {
int irq;
/* KSI[7:0] wake-up input source configuration list */
const struct cros_kb_raw_wuc_map_cfg *wuc_map_list;
+ /* KSI/KSO keyboard scan alternate configuration */
+ const struct pinctrl_dev_config *pcfg;
};
struct cros_kb_raw_ite_data {
@@ -128,6 +131,33 @@ static int cros_kb_raw_ite_drive_column(const struct device *dev, int col)
return 0;
}
+#ifdef CONFIG_PLATFORM_EC_KEYBOARD_FACTORY_TEST
+static int cros_kb_raw_ite_config_alt(const struct device *dev, bool enable)
+{
+ const struct cros_kb_raw_ite_config *config = dev->config;
+ int status = 0;
+
+ if (enable) {
+ /* Set KSI/KSO pins of cros_kb_raw node to kbs mode */
+ status = pinctrl_apply_state(config->pcfg,
+ PINCTRL_STATE_DEFAULT);
+ if (status < 0) {
+ LOG_ERR("Failed to enable KSI and KSO kbs mode");
+ return status;
+ }
+ } else {
+ /* Set KSI/KSO pins of cros_kb_raw node to gpio mode */
+ status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
+ if (status < 0) {
+ LOG_ERR("Failed to enable KSI and KSO gpio mode");
+ return status;
+ }
+ }
+
+ return 0;
+}
+#endif
+
static void cros_kb_raw_ite_ksi_isr(const struct device *dev)
{
const struct cros_kb_raw_ite_config *config = dev->config;
@@ -156,19 +186,22 @@ static int cros_kb_raw_ite_init(const struct device *dev)
const struct cros_kb_raw_ite_config *config = dev->config;
struct cros_kb_raw_ite_data *data = dev->data;
struct kscan_it8xxx2_regs *const inst = config->base;
+ int status;
/* Ensure top-level interrupt is disabled */
cros_kb_raw_ite_enable_interrupt(dev, 0);
/*
- * bit2, Setting 1 enables the internal pull-up of the KSO[15:0] pins.
- * To pull up KSO[17:16], set the GPCR registers of their
- * corresponding GPIO ports.
- * bit0, Setting 1 enables the open-drain mode of the KSO[17:0] pins.
+ * Enable the internal pull-up and kbs mode of the KSI[7:0] pins.
+ * Enable the internal pull-up and kbs mode of the KSO[15:0] pins.
+ * Enable the open-drain mode of the KSO[17:0] pins.
*/
- inst->KBS_KSOCTRL = (IT8XXX2_KBS_KSOPU | IT8XXX2_KBS_KSOOD);
- /* bit2, 1 enables the internal pull-up of the KSI[7:0] pins. */
- inst->KBS_KSICTRL = IT8XXX2_KBS_KSIPU;
+ status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
+ if (status < 0) {
+ LOG_ERR("Failed to configure KSI[7:0] and KSO[15:0] pins");
+ return status;
+ }
+
#ifdef CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED
/* KSO[2] output high, others output low. */
inst->KBS_KSOL = BIT(2);
@@ -231,15 +264,21 @@ static const struct cros_kb_raw_driver_api cros_kb_raw_ite_driver_api = {
.drive_colum = cros_kb_raw_ite_drive_column,
.read_rows = cros_kb_raw_ite_read_row,
.enable_interrupt = cros_kb_raw_ite_enable_interrupt,
+#ifdef CONFIG_PLATFORM_EC_KEYBOARD_FACTORY_TEST
+ .config_alt = cros_kb_raw_ite_config_alt,
+#endif
};
static const struct cros_kb_raw_wuc_map_cfg
cros_kb_raw_wuc_0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] =
IT8XXX2_DT_WUC_ITEMS_LIST(0);
+PINCTRL_DT_INST_DEFINE(0);
+
static const struct cros_kb_raw_ite_config cros_kb_raw_cfg = {
.base = (struct kscan_it8xxx2_regs *)DT_INST_REG_ADDR(0),
.irq = DT_INST_IRQN(0),
.wuc_map_list = cros_kb_raw_wuc_0,
+ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
};
static struct cros_kb_raw_ite_data cros_kb_raw_data;
diff --git a/zephyr/drivers/cros_shi/Kconfig b/zephyr/drivers/cros_shi/Kconfig
index 3b93ad48ee..8f9475ea6d 100644
--- a/zephyr/drivers/cros_shi/Kconfig
+++ b/zephyr/drivers/cros_shi/Kconfig
@@ -7,7 +7,7 @@ if PLATFORM_EC_HOST_INTERFACE_SHI
config CROS_SHI_NPCX
bool
default y
- depends on DT_HAS_NUVOTON_NPCX_CROS_SHI_ENABLED
+ depends on DT_HAS_NUVOTON_NPCX_SHI_ENABLED
help
This option enables Serial Host Interface driver for the NPCX family
of processors. This is used for host-command communication on the
@@ -41,7 +41,7 @@ endif # CROS_SHI_NPCX
config CROS_SHI_IT8XXX2
bool
default y
- depends on DT_HAS_ITE_IT8XXX2_CROS_SHI_ENABLED
+ depends on DT_HAS_ITE_IT8XXX2_SHI_ENABLED
help
This option enables spi host interface driver which is required to
communicate with the EC when the CPU is the ARM processor.
diff --git a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
index 92c279037a..75d94f49d1 100644
--- a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
+++ b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-#define DT_DRV_COMPAT ite_it8xxx2_cros_shi
+#define DT_DRV_COMPAT ite_it8xxx2_shi
#include "chipset.h"
#include "console.h"
diff --git a/zephyr/drivers/cros_shi/cros_shi_npcx.c b/zephyr/drivers/cros_shi/cros_shi_npcx.c
index 8bddb7b85d..39485ecced 100644
--- a/zephyr/drivers/cros_shi/cros_shi_npcx.c
+++ b/zephyr/drivers/cros_shi/cros_shi_npcx.c
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-#define DT_DRV_COMPAT nuvoton_npcx_cros_shi
+#define DT_DRV_COMPAT nuvoton_npcx_shi
#include "host_command.h"
#include "soc_miwu.h"
@@ -33,7 +33,7 @@
LOG_MODULE_REGISTER(cros_shi, LOG_LEVEL_DBG);
-#define SHI_NODE DT_NODELABEL(shi)
+#define SHI_NODE DT_NODELABEL(shi0)
#define SHI_VER_CTRL_PH DT_PHANDLE_BY_IDX(SHI_NODE, ver_ctrl, 0)
#define SHI_VER_CTRL_ALT_FILED(f) DT_PHA_BY_IDX(SHI_VER_CTRL_PH, alts, 0, f)
@@ -175,13 +175,13 @@ struct cros_shi_npcx_data {
/* Driver convenience defines */
#define DRV_CONFIG(dev) ((const struct cros_shi_npcx_config *)(dev)->config)
#define DRV_DATA(dev) ((struct cros_shi_npcx_data *)(dev)->data)
-#define HAL_INSTANCE(dev) (struct cros_shi_reg *)(DRV_CONFIG(dev)->base)
+#define HAL_INSTANCE(dev) (struct shi_reg *)(DRV_CONFIG(dev)->base)
/* Forward declaration */
-static void cros_shi_npcx_reset_prepare(struct cros_shi_reg *const inst);
+static void cros_shi_npcx_reset_prepare(struct shi_reg *const inst);
/* Read pointer of input or output buffer by consecutive reading */
-static uint32_t shi_read_buf_pointer(struct cros_shi_reg *const inst)
+static uint32_t shi_read_buf_pointer(struct shi_reg *const inst)
{
uint8_t stat;
@@ -197,7 +197,7 @@ static uint32_t shi_read_buf_pointer(struct cros_shi_reg *const inst)
* Valid offset of SHI output buffer to write.
* When SIMUL bit is set, IBUFPTR can be used instead of OBUFPTR
*/
-static uint32_t shi_valid_obuf_offset(struct cros_shi_reg *const inst)
+static uint32_t shi_valid_obuf_offset(struct shi_reg *const inst)
{
return (shi_read_buf_pointer(inst) + SHI_OUT_PREAMBLE_LENGTH) %
SHI_OBUF_FULL_SIZE;
@@ -228,8 +228,7 @@ static void shi_write_half_outbuf(void)
* This routine read SHI input buffer to msg buffer until
* we have received a certain number of bytes
*/
-static int shi_read_inbuf_wait(struct cros_shi_reg *const inst,
- uint32_t szbytes)
+static int shi_read_inbuf_wait(struct shi_reg *const inst, uint32_t szbytes)
{
/* Copy data to msg buffer from input buffer */
for (uint32_t i = 0; i < szbytes; i++, shi_params.sz_received++) {
@@ -250,7 +249,7 @@ static int shi_read_inbuf_wait(struct cros_shi_reg *const inst,
}
/* This routine fills out all SHI output buffer with status byte */
-static void shi_fill_out_status(struct cros_shi_reg *const inst, uint8_t status)
+static void shi_fill_out_status(struct shi_reg *const inst, uint8_t status)
{
uint8_t start, end;
volatile uint8_t *fill_ptr;
@@ -288,7 +287,7 @@ static void shi_fill_out_status(struct cros_shi_reg *const inst, uint8_t status)
}
/* This routine handles shi received unexpected data */
-static void shi_bad_received_data(struct cros_shi_reg *const inst)
+static void shi_bad_received_data(struct shi_reg *const inst)
{
/* State machine mismatch, timeout, or protocol we can't handle. */
shi_fill_out_status(inst, EC_SPI_RX_BAD_DATA);
@@ -310,7 +309,7 @@ static void shi_bad_received_data(struct cros_shi_reg *const inst)
* This routine write SHI output buffer from msg buffer over halt of it.
* It make sure we have enough time to handle next operations.
*/
-static void shi_write_first_pkg_outbuf(struct cros_shi_reg *const inst,
+static void shi_write_first_pkg_outbuf(struct shi_reg *const inst,
uint16_t szbytes)
{
uint8_t size, offset;
@@ -359,8 +358,7 @@ static void shi_write_first_pkg_outbuf(struct cros_shi_reg *const inst,
*/
static void shi_send_response_packet(struct host_packet *pkt)
{
- struct cros_shi_reg *const inst =
- (struct cros_shi_reg *)(cros_shi_cfg.base);
+ struct shi_reg *const inst = (struct shi_reg *)(cros_shi_cfg.base);
/*
* Disable interrupts. This routine is not called from interrupt
@@ -399,7 +397,7 @@ static void shi_send_response_packet(struct host_packet *pkt)
__enable_irq();
}
-void shi_handle_host_package(struct cros_shi_reg *const inst)
+void shi_handle_host_package(struct shi_reg *const inst)
{
uint32_t sz_inbuf_int = shi_params.sz_request / SHI_IBUF_HALF_SIZE;
uint32_t cnt_inbuf_int = shi_params.sz_received / SHI_IBUF_HALF_SIZE;
@@ -441,7 +439,7 @@ void shi_handle_host_package(struct cros_shi_reg *const inst)
host_packet_receive(&shi_packet);
}
-static void shi_parse_header(struct cros_shi_reg *const inst)
+static void shi_parse_header(struct shi_reg *const inst)
{
/* We're now inside a transaction */
state = SHI_STATE_RECEIVING;
@@ -484,7 +482,7 @@ static void shi_parse_header(struct cros_shi_reg *const inst)
}
}
-static void shi_sec_ibf_int_enable(struct cros_shi_reg *const inst, int enable)
+static void shi_sec_ibf_int_enable(struct shi_reg *const inst, int enable)
{
if (enable) {
/* Setup IBUFLVL2 threshold and enable it */
@@ -531,7 +529,7 @@ static void log_unexpected_state(char *isr_name)
last_error_state = state;
}
-static void shi_handle_cs_assert(struct cros_shi_reg *const inst)
+static void shi_handle_cs_assert(struct shi_reg *const inst)
{
/* If not enabled, ignore glitches on SHI_CS_L */
if (state == SHI_STATE_DISABLED)
@@ -560,7 +558,7 @@ static void shi_handle_cs_assert(struct cros_shi_reg *const inst)
disable_sleep(SLEEP_MASK_SPI);
}
-static void shi_handle_cs_deassert(struct cros_shi_reg *const inst)
+static void shi_handle_cs_deassert(struct shi_reg *const inst)
{
/*
* If the buffer is still used by the host command.
@@ -598,7 +596,7 @@ static void shi_handle_cs_deassert(struct cros_shi_reg *const inst)
DEBUG_CPRINTF("END\n");
}
-static void shi_handle_input_buf_half_full(struct cros_shi_reg *const inst)
+static void shi_handle_input_buf_half_full(struct shi_reg *const inst)
{
if (state == SHI_STATE_RECEIVING) {
/* Read data from input to msg buffer */
@@ -620,7 +618,7 @@ static void shi_handle_input_buf_half_full(struct cros_shi_reg *const inst)
}
}
-static void shi_handle_input_buf_full(struct cros_shi_reg *const inst)
+static void shi_handle_input_buf_full(struct shi_reg *const inst)
{
if (state == SHI_STATE_RECEIVING) {
/* read data from input to msg buffer */
@@ -646,7 +644,7 @@ static void cros_shi_npcx_isr(const struct device *dev)
{
uint8_t stat;
uint8_t stat2;
- struct cros_shi_reg *const inst = HAL_INSTANCE(dev);
+ struct shi_reg *const inst = HAL_INSTANCE(dev);
/* Read status register and clear interrupt status early */
stat = inst->EVSTAT;
@@ -719,7 +717,7 @@ static void cros_shi_npcx_isr(const struct device *dev)
}
}
-static void cros_shi_npcx_reset_prepare(struct cros_shi_reg *const inst)
+static void cros_shi_npcx_reset_prepare(struct shi_reg *const inst)
{
uint32_t i;
@@ -768,7 +766,7 @@ static int cros_shi_npcx_enable(const struct device *dev)
{
const struct cros_shi_npcx_config *const config = DRV_CONFIG(dev);
const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
- struct cros_shi_reg *const inst = HAL_INSTANCE(dev);
+ struct shi_reg *const inst = HAL_INSTANCE(dev);
int ret;
ret = clock_control_on(clk_dev,
@@ -833,7 +831,7 @@ static int shi_npcx_init(const struct device *dev)
{
int ret;
const struct cros_shi_npcx_config *const config = DRV_CONFIG(dev);
- struct cros_shi_reg *const inst = HAL_INSTANCE(dev);
+ struct shi_reg *const inst = HAL_INSTANCE(dev);
const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
/* Turn on shi device clock first */
@@ -920,10 +918,10 @@ DEVICE_DT_INST_DEFINE(0, shi_npcx_init, /* pm_control_fn= */ NULL,
&cros_shi_npcx_driver_api);
/* KBS register structure check */
-NPCX_REG_SIZE_CHECK(cros_shi_reg, 0x120);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, SHICFG1, 0x001);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, EVENABLE, 0x005);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, IBUFSTAT, 0x00a);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, EVENABLE2, 0x010);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, OBUF, 0x020);
-NPCX_REG_OFFSET_CHECK(cros_shi_reg, IBUF, 0x0A0);
+NPCX_REG_SIZE_CHECK(shi_reg, 0x120);
+NPCX_REG_OFFSET_CHECK(shi_reg, SHICFG1, 0x001);
+NPCX_REG_OFFSET_CHECK(shi_reg, EVENABLE, 0x005);
+NPCX_REG_OFFSET_CHECK(shi_reg, IBUFSTAT, 0x00a);
+NPCX_REG_OFFSET_CHECK(shi_reg, EVENABLE2, 0x010);
+NPCX_REG_OFFSET_CHECK(shi_reg, OBUF, 0x020);
+NPCX_REG_OFFSET_CHECK(shi_reg, IBUF, 0x0A0);
diff --git a/zephyr/drivers/cros_system/CMakeLists.txt b/zephyr/drivers/cros_system/CMakeLists.txt
index 79d320f9a1..526255c370 100644
--- a/zephyr/drivers/cros_system/CMakeLists.txt
+++ b/zephyr/drivers/cros_system/CMakeLists.txt
@@ -6,3 +6,4 @@ zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_IT8XXX2 cros_system_it8xxx2.c)
zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_NPCX cros_system_npcx.c)
zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_XEC cros_system_xec.c)
zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_NATIVE_POSIX cros_system_native_posix.c)
+zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_STM32 cros_system_stm32.c)
diff --git a/zephyr/drivers/cros_system/Kconfig b/zephyr/drivers/cros_system/Kconfig
index 79e1499b2c..254e870179 100644
--- a/zephyr/drivers/cros_system/Kconfig
+++ b/zephyr/drivers/cros_system/Kconfig
@@ -92,3 +92,26 @@ config CROS_SYSTEM_NATIVE_POSIX_INIT_PRIORITY
than CONFIG_SYSTEM_PRE_INIT_PRIORITY.
endif # CROS_SYSTEM_NATIVE_POSIX
+
+menuconfig CROS_SYSTEM_STM32
+ bool "ST STM32 cros system driver"
+ depends on SOC_FAMILY_STM32 && IWDG_STM32 && HWINFO
+ select REBOOT
+ default y
+ help
+ This option enables the cros system driver for the STM32 family of
+ processors. The cros system driver provides the low-level driver
+ related to chromium ec system functionality.
+
+if CROS_SYSTEM_STM32
+
+config CROS_SYSTEM_STM32_INIT_PRIORITY
+ int "cros_system STM32 initialization priority"
+ default 10
+ help
+ This sets the STM32 cros_system driver initialization priority.
+ The cros_system driver provides access to the STM32 reset cause
+ and must be higher priority than
+ CONFIG_PLATFORM_EC_SYSTEM_PRE_INIT_PRIORITY.
+
+endif # CONFIG_CROS_SYSTEM_STM32
diff --git a/zephyr/drivers/cros_system/cros_system_stm32.c b/zephyr/drivers/cros_system/cros_system_stm32.c
new file mode 100644
index 0000000000..bc42909666
--- /dev/null
+++ b/zephyr/drivers/cros_system/cros_system_stm32.c
@@ -0,0 +1,150 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#define DT_DRV_COMPAT st_stm32_rcc
+
+#include "drivers/cros_system.h"
+#include "system.h"
+
+#include <zephyr/device.h>
+#include <zephyr/drivers/hwinfo.h>
+#include <zephyr/drivers/watchdog.h>
+#include <zephyr/sys/reboot.h>
+
+/* Driver data */
+struct cros_system_stm32_data {
+ int reset; /* reset cause */
+};
+
+#define DRV_DATA(dev) ((struct cros_system_stm32_data *)(dev)->data)
+
+static const struct device *const watchdog =
+ DEVICE_DT_GET(DT_CHOSEN(cros_ec_watchdog));
+
+static const char *cros_system_stm32_get_chip_vendor(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ return "st";
+}
+
+static const char *cros_system_stm32_get_chip_name(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ return CONFIG_SOC;
+}
+
+static const char *cros_system_stm32_get_chip_revision(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ return "";
+}
+
+static int cros_system_stm32_get_reset_cause(const struct device *dev)
+{
+ struct cros_system_stm32_data *data = DRV_DATA(dev);
+
+ return data->reset;
+}
+
+static int cros_system_stm32_soc_reset(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ uint32_t chip_reset_flags = chip_read_reset_flags();
+
+ /*
+ * We are going to reboot MCU here, so we need to disable caches here.
+ * SCB_DisableDCache also flushes data cache lines.
+ */
+#ifdef CONFIG_DCACHE
+ SCB_DisableDCache();
+#endif
+
+#ifdef CONFIG_ICACHE
+ SCB_DisableICache();
+#endif
+
+ if (chip_reset_flags & EC_RESET_FLAG_HARD) {
+ /*
+ * Set minimal watchdog timeout - 1 millisecond.
+ * STM32 IWDG can be set for lower value, but we are limited by
+ * Zephyr API.
+ */
+ struct wdt_timeout_cfg minimal_timeout = { .window.max = 1 };
+
+ /* Setup watchdog */
+ wdt_install_timeout(watchdog, &minimal_timeout);
+
+ /* Apply the changes (the driver will reload watchdog) */
+ wdt_setup(watchdog, 0);
+
+ /* Spin and wait for reboot */
+ while (1)
+ ;
+ } else {
+ /* Reset implementation for ARM ignores the reset type */
+ sys_reboot(0);
+ }
+
+ /* Should never return */
+ return 0;
+}
+
+static uint64_t cros_system_stm32_deep_sleep_ticks(const struct device *dev)
+{
+ /* Deep sleep is not supported for now */
+ return 0;
+}
+
+static int cros_system_stm32_init(const struct device *dev)
+{
+ struct cros_system_stm32_data *data = DRV_DATA(dev);
+ uint32_t reset_cause;
+
+ data->reset = UNKNOWN_RST;
+ hwinfo_get_reset_cause(&reset_cause);
+
+ /* Clear the hardware reset cause. */
+ hwinfo_clear_reset_cause();
+
+ if (reset_cause & RESET_WATCHDOG) {
+ data->reset = WATCHDOG_RST;
+ } else if (reset_cause & RESET_SOFTWARE) {
+ /* Use DEBUG_RST because it maps to EC_RESET_FLAG_SOFT. */
+ data->reset = DEBUG_RST;
+ } else if (reset_cause & RESET_POR) {
+ data->reset = POWERUP;
+ } else if (reset_cause & RESET_PIN) {
+ data->reset = VCC1_RST_PIN;
+ }
+
+ return 0;
+}
+
+static struct cros_system_stm32_data cros_system_stm32_dev_data;
+
+static const struct cros_system_driver_api cros_system_driver_stm32_api = {
+ .get_reset_cause = cros_system_stm32_get_reset_cause,
+ .soc_reset = cros_system_stm32_soc_reset,
+ .chip_vendor = cros_system_stm32_get_chip_vendor,
+ .chip_name = cros_system_stm32_get_chip_name,
+ .chip_revision = cros_system_stm32_get_chip_revision,
+#ifdef CONFIG_PM
+ .deep_sleep_ticks = cros_system_stm32_deep_sleep_ticks,
+#endif
+};
+
+DEVICE_DEFINE(cros_system_stm32_0, "CROS_SYSTEM", cros_system_stm32_init, NULL,
+ &cros_system_stm32_dev_data, NULL, PRE_KERNEL_1,
+ CONFIG_CROS_SYSTEM_STM32_INIT_PRIORITY,
+ &cros_system_driver_stm32_api);
+
+#if CONFIG_CROS_SYSTEM_STM32_INIT_PRIORITY >= \
+ CONFIG_PLATFORM_EC_SYSTEM_PRE_INIT_PRIORITY
+#error "CROS_SYSTEM must initialize before the SYSTEM_PRE initialization"
+#endif
diff --git a/zephyr/dts/bindings/battery/battery-smart.yaml b/zephyr/dts/bindings/battery/battery-smart.yaml
index 60c7360460..74deb224b2 100644
--- a/zephyr/dts/bindings/battery/battery-smart.yaml
+++ b/zephyr/dts/bindings/battery/battery-smart.yaml
@@ -13,6 +13,7 @@ properties:
enum:
- "aec,5477109"
- "atl,cfd72"
+ - "bms-gf,cr50"
- "byd,l22b3pg0"
- "byd,wv3k8"
- "cdt,c340152"
@@ -54,6 +55,7 @@ properties:
- "smp,l20m3pg0"
- "smp,l20m3pg1"
- "smp,l20m3pg2"
+ - "smp,l21m4pg0"
- "smp,l22m3pg0"
- "smp,l22m3pg1"
- "smp,pc-vp-bp153"
diff --git a/zephyr/dts/bindings/battery/bms-gf,cr50.yaml b/zephyr/dts/bindings/battery/bms-gf,cr50.yaml
new file mode 100644
index 0000000000..cd5cc8c05a
--- /dev/null
+++ b/zephyr/dts/bindings/battery/bms-gf,cr50.yaml
@@ -0,0 +1,53 @@
+description: "BMS-GF CR50"
+compatible: "bms-gf,cr50"
+
+include: battery-smart.yaml
+
+properties:
+ enum-name:
+ type: string
+ default: "bms-gf,cr50"
+
+ # Fuel gauge
+ manuf_name:
+ default: "BMS-GF"
+ device_name:
+ default: "CR50"
+ ship_mode_reg_addr:
+ default: 0x00
+ ship_mode_reg_data:
+ default: [0x0010, 0x0010]
+ fet_mfgacc_support:
+ default: 0
+ fet_reg_addr:
+ default: 0x43
+ fet_reg_mask:
+ default: 0x0001
+ fet_disconnect_val:
+ default: 0x0000
+ fet_cfet_mask:
+ default: 0x0002
+ fet_cfet_off_val:
+ default: 0x0000
+
+ # Battery info
+ voltage_max:
+ default: 17600
+ voltage_normal:
+ default: 15000
+ voltage_min:
+ default: 12000
+ precharge_current:
+ default: 256
+ start_charging_min_c:
+ default: 0
+ start_charging_max_c:
+ default: 50
+ charging_min_c:
+ default: 0
+ charging_max_c:
+ default: 60
+ discharging_min_c:
+ default: -20
+ discharging_max_c:
+ default: 60
diff --git a/zephyr/dts/bindings/battery/smp,l21m4pg0.yaml b/zephyr/dts/bindings/battery/smp,l21m4pg0.yaml
new file mode 100644
index 0000000000..6f3f093fa8
--- /dev/null
+++ b/zephyr/dts/bindings/battery/smp,l21m4pg0.yaml
@@ -0,0 +1,53 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description: "SMP L21M4PG0"
+compatible: "smp,l21m4pg0"
+
+include: battery-smart.yaml
+
+properties:
+ enum-name:
+ type: string
+ default: "smp,l21m4pg0"
+
+ # Fuel gauge
+ manuf_name:
+ default: "SMP"
+ device_name:
+ default: "L21M4PG0"
+ ship_mode_reg_addr:
+ default: 0x34
+ ship_mode_reg_data:
+ default: [0x0000, 0x1000]
+ fet_mfgacc_support:
+ default: 0
+ fet_reg_addr:
+ default: 0x34
+ fet_reg_mask:
+ default: 0x0100
+ fet_disconnect_val:
+ default: 0x0100
+
+ # Battery info
+ voltage_max:
+ default: 8900
+ voltage_normal:
+ default: 7720
+ voltage_min:
+ default: 6000
+ precharge_current:
+ default: 274
+ start_charging_min_c:
+ default: 0
+ start_charging_max_c:
+ default: 50
+ charging_min_c:
+ default: 0
+ charging_max_c:
+ default: 60
+ discharging_min_c:
+ default: -20
+ discharging_max_c:
+ default: 60
diff --git a/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml
index 2b50f09474..134a036dbd 100644
--- a/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml
+++ b/zephyr/dts/bindings/cros_kb_raw/ite,it8xxx2-cros-kb-raw.yaml
@@ -5,7 +5,7 @@ description: ITE, it8xxx2-cros-kb-raw node
compatible: "ite,it8xxx2-cros-kb-raw"
-include: base.yaml
+include: [base.yaml, pinctrl-device.yaml]
properties:
reg:
@@ -22,3 +22,9 @@ properties:
EC or not. Via this controller, we set the wakeup trigger edge,
enable, disable, and clear wakeup status for the specific pin which
may be gpio pins or alternate pins.
+
+ pinctrl-0:
+ required: true
+
+ pinctrl-names:
+ required: true
diff --git a/zephyr/dts/bindings/cros_pwr_signal/mediatek,mt8188-power-signal-list.yaml b/zephyr/dts/bindings/cros_pwr_signal/mediatek,mt8188-power-signal-list.yaml
new file mode 100644
index 0000000000..9c782d13d3
--- /dev/null
+++ b/zephyr/dts/bindings/cros_pwr_signal/mediatek,mt8188-power-signal-list.yaml
@@ -0,0 +1,21 @@
+# Copyright 2023 Google LLC
+# SPDX-License-Identifier: Apache-2.0
+
+description: MediaTek MT8188, Power Signal List
+compatible: "mediatek,mt8188-power-signal-list"
+
+include: power-signal-list.yaml
+
+properties:
+ power-signals-required:
+ default: 5
+
+child-binding:
+ properties:
+ power-enum-name:
+ enum:
+ - AP_IN_RST
+ - AP_IN_S3
+ - AP_WDT_ASSERTED
+ - AP_WARM_RST_REQ
+ - PG_PP4200_S5
diff --git a/zephyr/dts/bindings/cros_shi/ite,it8xxx2-cros-shi.yaml b/zephyr/dts/bindings/cros_shi/ite,it8xxx2-cros-shi.yaml
deleted file mode 100644
index 6ac4c501f9..0000000000
--- a/zephyr/dts/bindings/cros_shi/ite,it8xxx2-cros-shi.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2021 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-description: ITE, IT8XXX2 Serial Host Interface (SHI) node
-
-compatible: "ite,it8xxx2-cros-shi"
-
-include: [base.yaml, pinctrl-device.yaml]
-
-properties:
- reg:
- required: true
-
- pinctrl-0:
- required: true
-
- pinctrl-names:
- required: true
diff --git a/zephyr/dts/bindings/cros_shi/nuvoton,npcx-cros-shi.yaml b/zephyr/dts/bindings/cros_shi/nuvoton,npcx-cros-shi.yaml
deleted file mode 100644
index af7f98f9bb..0000000000
--- a/zephyr/dts/bindings/cros_shi/nuvoton,npcx-cros-shi.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2021 Google LLC
-# SPDX-License-Identifier: Apache-2.0
-
-description: Nuvoton, NPCX Serial Host Interface (SHI) node
-
-compatible: "nuvoton,npcx-cros-shi"
-
-include: [base.yaml, pinctrl-device.yaml]
-
-properties:
- reg:
- description: mmio register space
- required: true
-
- clocks:
- required: true
- description: configurations of device source clock controller
-
- pinctrl-0:
- required: true
-
- pinctrl-1:
- required: false
-
- pinctrl-names:
- required: true
-
- shi-cs-wui:
- type: phandle
- required: true
- description: |
- Mapping table between Wake-Up Input (WUI) and SHI_CS signal.
-
- For example the WUI mapping on NPCX7 would be
- shi-cs-wui = <&wui_io53>;
diff --git a/zephyr/dts/bindings/emul/tcpci.yaml b/zephyr/dts/bindings/emul/tcpci.yaml
index 899a6ebea4..2a10209fdd 100644
--- a/zephyr/dts/bindings/emul/tcpci.yaml
+++ b/zephyr/dts/bindings/emul/tcpci.yaml
@@ -7,8 +7,14 @@ description: Common TCPCI properties
include: base.yaml
properties:
- alert_gpio:
- type: phandle
+ irq-gpios:
+ type: phandle-array
required: false
- description:
- Reference to Alert# GPIO.
+ description: |
+ Interrupt from TCPC using shim driver
+
+ int-pin:
+ type: phandles
+ required: false
+ description: |
+ Interrupt from TCPC using gpio-int
diff --git a/zephyr/dts/bindings/gpio/gpio-enum-name.yaml b/zephyr/dts/bindings/gpio/gpio-enum-name.yaml
index 5041b0646a..74b40f2acc 100644
--- a/zephyr/dts/bindings/gpio/gpio-enum-name.yaml
+++ b/zephyr/dts/bindings/gpio/gpio-enum-name.yaml
@@ -72,6 +72,7 @@ properties:
- GPIO_PG_EC_ALL_SYS_PWRGD
- GPIO_PG_EC_DSW_PWROK
- GPIO_PG_EC_RSMRST_ODL
+ - GPIO_PG_PP4200_S5_OD
- GPIO_PMIC_EC_PWRGD
- GPIO_PMIC_KPD_PWR_ODL
- GPIO_PMIC_RESIN_L
diff --git a/zephyr/dts/bindings/power/ap-pwrseq-sub-states.yaml b/zephyr/dts/bindings/power/ap-pwrseq-sub-states.yaml
new file mode 100644
index 0000000000..8632b7e7b5
--- /dev/null
+++ b/zephyr/dts/bindings/power/ap-pwrseq-sub-states.yaml
@@ -0,0 +1,21 @@
+# Copyright 2022 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+description: |
+ Define additional substates to be included in state machine. Use corresponding
+ macros to provide action handlers.
+compatible: "ap-pwrseq-sub-states"
+
+properties:
+ chipset:
+ type: string-array
+ required: false
+ description: |
+ User defined power subtstates, use AP_POWER_CHIPSET_SUB_STATE_DEFINE, to define
+ substate action handler functions.
+ application:
+ type: string-array
+ required: false
+ description: |
+ User defined power subtstates, use AP_POWER_APP_SUB_STATE_DEFINE, to define
+ substate action handler functions.
diff --git a/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml b/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml
index 645ce7303b..ba25ccd683 100644
--- a/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/analogix,anx7447-tcpc.yaml
@@ -10,7 +10,8 @@ properties:
default: 0
description: |
TCPC configuration flags
- int-pin:
- type: phandle
+ irq-gpios:
+ type: phandle-array
required: false
- description: Interrupt from TCPC
+ description: |
+ Interrupt from TCPC
diff --git a/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml b/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml
index 3e06ed38b6..89f1f78b63 100644
--- a/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/cypress,ccgxxf.yaml
@@ -14,7 +14,16 @@ properties:
default: 0
description: |
TCPC configuration flags
+ irq-gpios:
+ type: phandle-array
+ required: false
+ description: |
+ Interrupt from TCPC using shim driver
int-pin:
- type: phandle
+ type: phandles
required: false
- description: Interrupt from TCPC
+ deprecated: true
+ description: |
+ Interrupt from TCPC using gpio-int. This property should only be used when
+ CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n and should be removed when the chip
+ uses the common TCPC driver.
diff --git a/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml b/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml
index 79b0df470e..c3f353cbf2 100644
--- a/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/fairchild,fusb302.yaml
@@ -10,7 +10,16 @@ properties:
default: 0
description: |
TCPC configuration flags
+ irq-gpios:
+ type: phandle-array
+ required: false
+ description: |
+ Interrupt from TCPC using shim driver
int-pin:
- type: phandle
+ type: phandles
required: false
- description: Interrupt from TCPC
+ deprecated: true
+ description: |
+ Interrupt from TCPC using gpio-int. This property should only be used when
+ CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n and should be removed when the chip
+ uses the common TCPC driver.
diff --git a/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml b/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml
index 78e1fbf7da..cfbe5a748f 100644
--- a/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/nuvoton,nct38xx.yaml
@@ -21,7 +21,17 @@ properties:
description: |
TCPC configuration flags
+ irq-gpios:
+ type: phandle-array
+ required: false
+ description: |
+ Interrupt from TCPC using shim driver
+
int-pin:
- type: phandle
+ type: phandles
required: false
- description: Interrupt from TCPC
+ deprecated: true
+ description: |
+ Interrupt from TCPC using gpio-int. This property should only be used when
+ CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n and should be removed when the chip
+ uses the common TCPC driver.
diff --git a/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml b/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml
index f77d4a0c28..e6c2a9bbcb 100644
--- a/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/parade,ps8xxx.yaml
@@ -10,7 +10,8 @@ properties:
default: 0
description: |
TCPC configuration flags
- int-pin:
- type: phandle
+ irq-gpios:
+ type: phandle-array
required: false
- description: Interrupt from TCPC
+ description: |
+ Interrupt from TCPC
diff --git a/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml b/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml
index f8dd9807ed..de6402d4ee 100644
--- a/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/renesas,raa489000.yaml
@@ -14,3 +14,8 @@ properties:
default: 0
description: |
TCPC configuration flags
+ irq-gpios:
+ type: phandle-array
+ required: false
+ description: |
+ Interrupt from TCPC
diff --git a/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml b/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml
index 0fed6b6380..8baa3ee550 100644
--- a/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml
+++ b/zephyr/dts/bindings/usbc/tcpc/richtek,rt1718s-tcpc.yaml
@@ -14,7 +14,8 @@ properties:
default: 0
description: |
TCPC configuration flags
- int-pin:
- type: phandle
+ irq-gpios:
+ type: phandle-array
required: false
- description: Interrupt from TCPC
+ description: |
+ Interrupt from TCPC
diff --git a/zephyr/dts/bindings/vendor-prefixes.txt b/zephyr/dts/bindings/vendor-prefixes.txt
index 53dd2d4cfc..c04ca3b546 100644
--- a/zephyr/dts/bindings/vendor-prefixes.txt
+++ b/zephyr/dts/bindings/vendor-prefixes.txt
@@ -19,4 +19,5 @@ celxpert Battery vendor
sunwoda Battery vendor
cosmx Battery vendor
dynapack Battery vendor
-atl Battery vendor \ No newline at end of file
+atl Battery vendor
+bms-gf Battery vendor \ No newline at end of file
diff --git a/zephyr/emul/emul_isl923x.c b/zephyr/emul/emul_isl923x.c
index 42401b94f9..92bff73656 100644
--- a/zephyr/emul/emul_isl923x.c
+++ b/zephyr/emul/emul_isl923x.c
@@ -200,6 +200,17 @@ void raa489000_emul_set_acok_pin(const struct emul *emulator, uint16_t value)
data->info_2_reg &= ~RAA489000_INFO2_ACOK;
}
+void raa489000_emul_set_state_machine_state(const struct emul *emulator,
+ uint16_t value)
+{
+ struct isl923x_emul_data *data = emulator->data;
+
+ data->info_2_reg &=
+ ~(RAA489000_INFO2_STATE_MASK << RAA489000_INFO2_STATE_SHIFT);
+ data->info_2_reg |= (value & RAA489000_INFO2_STATE_MASK)
+ << RAA489000_INFO2_STATE_SHIFT;
+}
+
/** Convenience macro for reading 16-bit registers */
#define READ_REG_16(REG, BYTES, OUT) \
do { \
diff --git a/zephyr/emul/tcpc/emul_tcpci.c b/zephyr/emul/tcpc/emul_tcpci.c
index e5dcf78bdc..0deb0c2727 100644
--- a/zephyr/emul/tcpc/emul_tcpci.c
+++ b/zephyr/emul/tcpc/emul_tcpci.c
@@ -221,11 +221,10 @@ static int tcpci_emul_alert_changed(const struct emul *emul)
bool alert_is_active = tcpci_emul_check_int(ctx);
/** Trigger GPIO. */
- if (ctx->alert_gpio_port != NULL) {
+ if (ctx->irq_gpio.port != NULL) {
/* Triggers on edge falling, so set to 0 when there is an alert.
*/
- rc = gpio_emul_input_set(ctx->alert_gpio_port,
- ctx->alert_gpio_pin,
+ rc = gpio_emul_input_set(ctx->irq_gpio.port, ctx->irq_gpio.pin,
alert_is_active ? 0 : 1);
if (rc != 0)
return rc;
diff --git a/zephyr/firmware_builder.py b/zephyr/firmware_builder.py
index aa470ea583..d481487afa 100755
--- a/zephyr/firmware_builder.py
+++ b/zephyr/firmware_builder.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python3.8
# -*- coding: utf-8 -*-
# Copyright 2021 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
@@ -16,15 +16,25 @@ import shlex
import subprocess
import sys
+from google.protobuf import json_format # pylint: disable=import-error
import zmake.project
+
from chromite.api.gen_sdk.chromite.api import firmware_pb2
-from google.protobuf import json_format # pylint: disable=import-error
+
DEFAULT_BUNDLE_DIRECTORY = "/tmp/artifact_bundles"
DEFAULT_BUNDLE_METADATA_FILE = "/tmp/artifact_bundle_metadata"
# Boards that we want to track the coverage of our own files specifically.
-SPECIAL_BOARDS = ["herobrine", "krabby", "nivviks", "skyrim", "kingler", "rex"]
+SPECIAL_BOARDS = [
+ "herobrine",
+ "krabby",
+ "nivviks",
+ "skyrim",
+ "kingler",
+ "rex",
+ "geralt",
+]
BINARY_SIZE_REGIONS = [
"RO_FLASH",
diff --git a/zephyr/include/ap_power/ap_pwrseq.h b/zephyr/include/ap_power/ap_pwrseq.h
index 9e1ffd27e8..86c5f051e6 100644
--- a/zephyr/include/ap_power/ap_pwrseq.h
+++ b/zephyr/include/ap_power/ap_pwrseq.h
@@ -3,11 +3,202 @@
* found in the LICENSE file.
*/
-#ifndef __AP_POWER_AP_PWRSEQ_H__
-#define __AP_POWER_AP_PWRSEQ_H__
+#ifndef _AP_PWRSEQ_H_
+#define _AP_PWRSEQ_H_
+#include <zephyr/device.h>
+#include <zephyr/kernel.h>
/** Starts the AP power sequence thread */
void ap_pwrseq_task_start(void);
void ap_pwrseq_wake(void);
-#endif /* __AP_POWER_AP_PWRSEQ_H__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AP_POWER_SUB_STATE_ENUM_DEF_WITH_COMMA(node_id, prop, idx) \
+ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN),
+
+#define AP_PWRSEQ_EACH_SUB_STATE_ENUM_DEF(node_id) \
+ COND_CODE_1( \
+ DT_NODE_HAS_PROP(node_id, chipset), \
+ (DT_FOREACH_PROP_ELEM(node_id, chipset, \
+ AP_POWER_SUB_STATE_ENUM_DEF_WITH_COMMA)), \
+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, application), \
+ (DT_FOREACH_PROP_ELEM( \
+ node_id, application, \
+ AP_POWER_SUB_STATE_ENUM_DEF_WITH_COMMA)), \
+ ())))
+
+/** @brief AP power sequence valid power states. */
+enum ap_pwrseq_state {
+ AP_POWER_STATE_UNINIT, /* EC and AP are Uninitialized */
+ AP_POWER_STATE_G3, /* AP is OFF */
+ AP_POWER_STATE_S5, /* AP is on soft off state */
+ AP_POWER_STATE_S4, /* AP is suspended to Non-volatile disk */
+ AP_POWER_STATE_S3, /* AP is suspended to RAM */
+ AP_POWER_STATE_S2, /* AP is low wake-latency sleep */
+ AP_POWER_STATE_S1, /* AP is in suspend state */
+ AP_POWER_STATE_S0, /* AP is in active state */
+ DT_FOREACH_STATUS_OKAY(ap_pwrseq_sub_states,
+ AP_PWRSEQ_EACH_SUB_STATE_ENUM_DEF)
+ AP_POWER_STATE_COUNT,
+ AP_POWER_STATE_UNDEF = 0xFFFE,
+ AP_POWER_STATE_ERROR = 0xFFFF,
+};
+
+/** @brief AP power sequence events. */
+enum ap_pwrseq_event {
+ AP_PWRSEQ_EVENT_POWER_STARTUP,
+ AP_PWRSEQ_EVENT_POWER_SIGNAL,
+ AP_PWRSEQ_EVENT_POWER_TIMEOUT,
+ AP_PWRSEQ_EVENT_POWER_SHUTDOWN,
+ AP_PWRSEQ_EVENT_HOST,
+ AP_PWRSEQ_EVENT_COUNT,
+};
+
+/** @brief The signature for callback notification from AP power seqeuce driver.
+ *
+ * This function will be invoked by AP power sequence driver as configured by
+ * functions `ap_pwrseq_register_state_entry_callback` or
+ * `ap_pwrseq_register_state_entry_callback` for power state transitions.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @param entry Entering state in transition.
+ *
+ * @param exit Exiting state in transition.
+ *
+ * @retval None.
+ */
+typedef void (*ap_pwrseq_callback)(const struct device *dev,
+ enum ap_pwrseq_state entry,
+ enum ap_pwrseq_state exit);
+
+struct ap_pwrseq_state_callback {
+ /* Node used to link notifications. This is for internal use only */
+ sys_snode_t node;
+ /**
+ * Callback function, this will be invoked when AP power sequence
+ * enters or exits states selected by `states_bit_mask`.
+ **/
+ ap_pwrseq_callback cb;
+ /* Bitfield of states to invoke callback */
+ uint32_t states_bit_mask;
+};
+
+/**
+ * @brief Get AP power sequence device driver pointer.
+ *
+ * @param None.
+ *
+ * @retval AP power sequence device driver pointer.
+ **/
+const struct device *ap_pwrseq_get_instance(void);
+
+/**
+ * @brief Starts AP power sequence driver thread execution.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @param init_state state that will be executed when staring.
+ *
+ * @retval SUCCESS Driver starts execution.
+ * @retval -EINVAL State provided is invalid.
+ * @retval -EPERM Driver is already started.
+ **/
+int ap_pwrseq_start(const struct device *dev, enum ap_pwrseq_state init_state);
+
+/**
+ * @brief Post event for AP power sequence driver.
+ *
+ * State machine is executed within AP power sequence thread, this thread goes
+ * to sleep when state machine is idle and state transition is completed.
+ * Events are posted to wake up AP power sequence thread and made available to
+ * state machine only for the following iteration.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @param event Event posted to AP power seuqence driver.
+ *
+ * @retval None.
+ **/
+void ap_pwrseq_post_event(const struct device *dev, enum ap_pwrseq_event event);
+
+/**
+ * @brief Get enumeration value of current state of AP power sequence driver.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @retval Valid state enumeration value.
+ * @retval AP_POWER_STATE_UNDEF if error.
+ **/
+enum ap_pwrseq_state ap_pwrseq_get_current_state(const struct device *dev);
+
+/**
+ * @brief Get null terminated string of selected state.
+ *
+ * @param state AP power sequence valid state.
+ *
+ * @retval String showing selected state name.
+ * @retval NULL if state is invalid.
+ **/
+const char *const ap_pwrseq_get_state_str(enum ap_pwrseq_state state);
+
+/**
+ * @brief Lock current AP power sequence state.
+ *
+ * Once state machine is locked, it will not change its state until unlocked.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @retval SUCCESS Driver has been successfully locked, non-zero otherwise.
+ **/
+int ap_pwrseq_state_lock(const struct device *dev);
+
+/**
+ * @brief Unlock AP power sequence state.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @retval SUCCESS Driver has been successfully unlocked, non-zero otherwise.
+ **/
+int ap_pwrseq_state_unlock(const struct device *dev);
+
+/**
+ * @brief Register callback into AP power sequence driver.
+ *
+ * Callback function will be called by AP power sequence driver when entering
+ * into selected states.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @param state_cb Pointer of `ap_pwrseq_state_callback` structure.
+ *
+ * @retval SUCCESS Callback was successfully registered.
+ * @retval -EINVAL On error.
+ **/
+int ap_pwrseq_register_state_entry_callback(
+ const struct device *dev, struct ap_pwrseq_state_callback *state_cb);
+
+/**
+ * @brief Register callback into AP power sequence driver.
+ *
+ * Callback function will be called by AP power sequence driver when exiting
+ * from selected states.
+ *
+ * @param dev Pointer of AP power sequence device driver.
+ *
+ * @param state_cb Pointer of `ap_pwrseq_state_callback` structure.
+ *
+ * @retval SUCCESS Callback was successfully registered.
+ * @retval -EINVAL On error.
+ **/
+int ap_pwrseq_register_state_exit_callback(
+ const struct device *dev, struct ap_pwrseq_state_callback *state_cb);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _AP_PWRSEQ_H_ */
diff --git a/zephyr/include/ap_power/ap_pwrseq_sm.h b/zephyr/include/ap_power/ap_pwrseq_sm.h
new file mode 100644
index 0000000000..e1558ccd6f
--- /dev/null
+++ b/zephyr/include/ap_power/ap_pwrseq_sm.h
@@ -0,0 +1,390 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef _AP_PWRSEQ_SM_H_
+#define _AP_PWRSEQ_SM_H_
+#include "ap_power/ap_pwrseq_sm_defs.h"
+
+/**
+ * AP power sequence state machine API
+ * -----------------------------------
+ *
+ * State machine is integrated into the AP power sequence driver by wrapping
+ * Zephyr State Machine Framework (SMF), each SMF state is represented by three
+ * functions or action handlers that define operations performed on state entry,
+ * run and exit.
+ *
+ * ACPI’s global state (G3) and its six sleep power states (S0, S1, S2, S3, S4,
+ * S5) are present within this state machine domain. All these ACPI states are
+ * are divided in three levels, each level is a SMF state with a hierarchical
+ * relation with others action handlers of the same ACPI state, state handlers
+ * at higher levels performes the most common task of corresponding ACPI power
+ * states.
+ *
+ * Architecture is the highest level of the hierarchy, SMF states this level
+ * must do operations that are specific to AP CPU architecture, example:
+ * X86 (intel), ARM.
+ *
+ * Middle level is the chipset; these SMF action handlers carry out operations
+ * to drive power of components that are required for the AP chip. Any bus
+ * signal or internal power rail that is vital for chip execution is a good fit
+ * to be handled in these action handlers. Examples of chipsets are: Tiger Lake
+ * and Jasper Lake, these are Intel chipsets that use X86 architecture, and
+ * MT8186 and MT8192 are Mediatek chipsets using ARM architecture.
+ *
+ * Application is the bottom level of the hierarchy and these SMF action
+ * handlers are reserved to address board or application specific computations.
+ *
+ * Hierarchical SMF will coordinate execution of entry, run & exit functions
+ * accordingly. Given that implementation is responsible for doing state
+ * transitions, the following considerations should be taken when implementing
+ * action state handlers:
+ *
+ * - Higher level `entry` actions are executed before the lower level `entry`
+ * actions.
+ * - Transitioning from one substate to another with a shared upper level state
+ * does not re-execute the upper level `entry` action or execute the `exit`
+ * action.
+ * - Upper level `exit` actions are executed after the substate `exit` actions.
+ * - Lower level `run` actions are executed before upper level.
+ * - Upper level `run` actions only executes if no state transition has been
+ * made from lower level `run` action.
+ *
+ * Please refer to Zephyr SMF documentation.
+ *
+ * This file exports macros that help to provide action handlers implementation
+ * for all states, and any substate that is declared in devicetree. It also
+ * declares functions to do power state transitions.
+ *
+ * Macros AP_POWER_ACRH_STATE_DEFINE, AP_POWER_CHIPSET_STATE_DEFINE and
+ * AP_POWER_APP_STATE_DEFINE statically declare action handlers for each power
+ * state.
+ *
+ * State Machine Workflow
+ * ----------------------
+ *
+ * State machine execution is done within AP power sequence driver thread
+ * context. Driver sets initial state upon initialization.
+ *
+ * On each driver thread loop ieration, current state `run` action handler is
+ * called following hierarchical order as set in zephyr SMF.
+ *
+ * State machine implements Ultimate Hook pattern, this allows upper level
+ * action handlers to finalize hierarchical execution flow by setting its
+ * returning value to anything different than zero.
+ *
+ * `ap_pwrseq_sm_set_state` must be used to do state transition, this will
+ * execute current state `exit` action handlers followed by next state `entry`
+ * action handlers, completing state transtion on next thread loop iteration
+ * when new state `run` action is called.
+ *
+ * State transitions are only permited to be done by implementation within
+ * corresponding AP power sequence driver context, and only one state transition
+ * is allowed per driver thread loop iteration.
+ *
+ * Example of wrong use of `ap_pwrseq_sm_set_state`:
+ *
+ * @code{.c}
+ * int arch_s0_run(void *data)
+ * {
+ * // Transition started `entry` and `exit` functions called
+ * ap_pwrseq_sm_set_state(data, AP_POWER_STATE_S5);
+ * ...
+ * // Nothing happens `ap_pwrseq_sm_set_state` returns -EINVAL.
+ * ap_pwrseq_sm_set_state(data, AP_POWER_STATE_G3);
+ * }
+ * @endcode
+ *
+ * Example of correct use of `ap_pwrseq_sm_set_state`:
+ *
+ * @code{.c}
+ * int arch_s0_run(void *data)
+ * {
+ * if (...) {
+ * return ap_pwrseq_sm_set_state(data, AP_POWER_STATE_S5);
+ * } else if (...) {
+ * return ap_pwrseq_sm_set_state(data, AP_POWER_STATE_G3);
+ * }
+ * return 0;
+ * }
+ * @endcod
+ *
+ * For this same reason, `ap_pwrseq_sm_set_state` should not be called within
+ * `entry` or `exit` action handler.
+ */
+
+/*
+ * This is required to ensure macro AP_POWER_SM_DEF_STATE_HANDLER handles
+ * passing `NULL` properly.
+ */
+#ifdef NULL
+#undef NULL
+#define NULL 0
+#else
+#define NULL 0
+#endif
+
+/* User define action handler, each action handler must follow this type. */
+typedef int (*ap_pwr_state_action_handler)(void *data);
+
+#define AP_POWER_SM_HANDLER_DECL(action) \
+ void ap_pwrseq_sm_exec_##action##_handler( \
+ void *const data, ap_pwr_state_action_handler handler)
+
+AP_POWER_SM_HANDLER_DECL(entry);
+AP_POWER_SM_HANDLER_DECL(run);
+AP_POWER_SM_HANDLER_DECL(exit);
+
+/**
+ * @brief Macro to define action handler wrapper function.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param level One of the three AP power sequence levels: arch, chipset or app.
+ *
+ * @param action One of the three SMF action handlers: entry, run or exit.
+ *
+ * @param handler Action handler function of type `ap_pwr_state_action_handler`.
+ *
+ * @retval Defines static wrapper function of handler to be called by AP power
+ * sequence state machine.
+ **/
+#define AP_POWER_SM_DEF_STATE_HANDLER(name, level, action, handler) \
+ static void ap_pwr_##name##_##level##_##action##_##handler(void *data) \
+ { \
+ ap_pwrseq_sm_exec_##action##_handler(data, handler); \
+ }
+
+/**
+ * @brief Macro to define action handler wrapper function for a single level.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param level One of the three AP power sequence levels: arch, chipset or app.
+ *
+ * @param _entry Function called when entering into this state.
+ *
+ * @param _run Action handler function called when run operation is invoked.
+ *
+ * @param _exit Function called when exiting this state.
+ *
+ * @param handler Action handler function of type `ap_pwr_state_action_handler`.
+ *
+ * @retval Defines static wrapper function of handler to be called by AP power
+ * sequence state machine.
+ **/
+#define AP_POWER_SM_DEF_STATE_HANDLERS(name, level, _entry, _run, _exit) \
+ AP_POWER_SM_DEF_STATE_HANDLER(name, level, entry, _entry) \
+ AP_POWER_SM_DEF_STATE_HANDLER(name, level, run, _run) \
+ AP_POWER_SM_DEF_STATE_HANDLER(name, level, exit, _exit)
+
+/**
+ * @brief Macro to assemble action handler wrapper function name.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param level One of the three AP power sequence levels: arch, chipset or app.
+ *
+ * @param action One of the three SMF action handlers: entry, run or exit.
+ *
+ * @param handler Action handler function of type `ap_pwr_state_action_handler`.
+ *
+ * @retval Constructs static name of handler wrapper function to be called by
+ * AP power sequence state machine.
+ **/
+#define AP_POWER_SM_ACTION(name, level, action, handler) \
+ ap_pwr_##name##_##level##_##action##_##handler
+
+/**
+ * @brief Macro to create SMF state following AP power sequence.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param level One of the three AP power sequence levels: arch, chipset or app.
+ *
+ * @param _entry Function to be called when entrying state.
+ *
+ * @param _run Function to be called when executing `run` operation.
+ *
+ * @param _exit Function to be called when exiting state.
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_SM_CREATE_STATE(name, level, _entry, _run, _exit, parent) \
+ SMF_CREATE_STATE(AP_POWER_SM_ACTION(name, level, entry, _entry), \
+ AP_POWER_SM_ACTION(name, level, run, _run), \
+ AP_POWER_SM_ACTION(name, level, exit, _exit), parent)
+
+/**
+ * @brief Define architecture level state action handlers.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param entry Function to be called when entrying state.
+ *
+ * @param run Function to be called when executing `run` operation.
+ *
+ * @param exit Function to be called when exiting state.
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_ARCH_STATE_DEFINE(name, entry, run, exit) \
+ AP_POWER_SM_DEF_STATE_HANDLERS(name, arch, entry, run, exit) \
+ const struct smf_state arch_##name##_actions = \
+ AP_POWER_SM_CREATE_STATE(name, arch, entry, run, exit, NULL)
+
+/**
+ * @brief Define chipset level state action handlers.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param entry Function to be called when entrying state.
+ *
+ * @param run Function to be called when executing `run` operation.
+ *
+ * @param exit Function to be called when exiting state.
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_CHIPSET_STATE_DEFINE(name, entry, run, exit) \
+ AP_POWER_SM_DEF_STATE_HANDLERS(name, chipset, entry, run, exit) \
+ const struct smf_state chipset_##name##_actions = \
+ AP_POWER_SM_CREATE_STATE(name, chipset, entry, run, exit, \
+ &arch_##name##_actions)
+
+/**
+ * @brief Define application level state action handlers.
+ *
+ * @param name Valid enumaration value of state.
+ *
+ * @param entry Function to be called when entrying state.
+ *
+ * @param run Function to be called when executing `run` operation.
+ *
+ * @param exit Function to be called when exiting state.
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_APP_STATE_DEFINE(name, entry, run, exit) \
+ AP_POWER_SM_DEF_STATE_HANDLERS(name, app, entry, run, exit) \
+ const struct ap_pwrseq_smf app_state_##name = { \
+ .actions = \
+ AP_POWER_SM_CREATE_STATE(name, app, entry, run, exit, \
+ &chipset_##name##_actions), \
+ .state = name \
+ }
+
+/**
+ * @brief Define chipset level substate action handlers.
+ *
+ * @param name Valid enumaration value of state, as provided by devicetree
+ * compatible with "ap-pwrseq-sub-states".
+ *
+ * @param entry Function to be called when entrying state.
+ *
+ * @param run Function to be called when executing `run` operation.
+ *
+ * @param exit Function to be called when exiting state.
+ *
+ * @param parent Valid enumaration value of parent state,
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_CHIPSET_SUB_STATE_DEFINE(name, entry, run, exit, parent) \
+ AP_POWER_SM_DEF_STATE_HANDLERS(name, chipset, entry, run, exit) \
+ const struct ap_pwrseq_smf chipset_##name##_actions = { \
+ .actions = AP_POWER_SM_CREATE_STATE(name, chipset, entry, run, \
+ exit, \
+ &arch_##parent##_actions), \
+ .state = name \
+ }
+
+/**
+ * @brief Define application level substate action handlers.
+ *
+ * @param name Valid enumaration value of state, as provided by devicetree
+ * compatible with "ap-pwrseq-sub-states".
+ *
+ * @param entry Function to be called when entrying state.
+ *
+ * @param run Function to be called when executing `run` operation.
+ *
+ * @param exit Function to be called when exiting state.
+ *
+ * @param parent Valid enumaration value of parent state,
+ *
+ * @retval Defines global structure with action handlers to be used by AP
+ * power sequence state machine.
+ **/
+#define AP_POWER_APP_SUB_STATE_DEFINE(name, entry, run, exit, parent) \
+ AP_POWER_SM_DEF_STATE_HANDLERS(name, app, entry, run, exit) \
+ const struct ap_pwrseq_smf app_state_##name = { \
+ .actions = \
+ AP_POWER_SM_CREATE_STATE(name, app, entry, run, exit, \
+ &chipset_##parent##_actions), \
+ .state = name \
+ }
+
+/**
+ * @brief Sets AP power sequence state machine to provided state.
+ *
+ * This function is meant to be executed only within AP power sequence driver
+ * thread context. `tid` was given in `ap_pwrseq_sm_init`.
+ *
+ * Only one state transition is permited within `run` iterations.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @param state Enum value of next state to be executed.
+ *
+ * @retval SUCCESS Upon success, current state `exit` action handler and next
+ * state `entry` action handler will be executed.
+ * @retval -EINVAL State provided is invalid.
+ **/
+int ap_pwrseq_sm_set_state(void *const data, enum ap_pwrseq_state state);
+
+/**
+ * @brief Check if events is set for current AP power sequence state machine
+ * `run` iteration.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @param event Enum of test to be tested.
+ *
+ * @retval True If event is set, False otherwise.
+ **/
+bool ap_pwrseq_sm_is_event_set(void *const data, enum ap_pwrseq_event event);
+
+/**
+ * @brief Get state machine is entering.
+ *
+ * This function is meant to be executed only within AP power sequence driver
+ * thread context. `tid` was given in `ap_pwrseq_sm_init`.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @retval Enum value Upon success.
+ * @retval AP_POWER_STATE_UNDEF If state machine is not doing state transition.
+ **/
+enum ap_pwrseq_state ap_pwrseq_sm_get_entry_state(void *const data);
+
+/**
+ * @brief Get state machine is exiting.
+ *
+ * This function is meant to be executed only within AP power sequence driver
+ * thread context. `tid` was given in `ap_pwrseq_sm_init`.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @retval Enum value Upon success.
+ * @retval AP_POWER_STATE_UNDEF If state machine is not doing state transition.
+ **/
+enum ap_pwrseq_state ap_pwrseq_sm_get_exit_state(void *const data);
+#endif /* _AP_PWRSEQ_SM_H_ */
diff --git a/zephyr/include/ap_power/ap_pwrseq_sm_defs.h b/zephyr/include/ap_power/ap_pwrseq_sm_defs.h
new file mode 100644
index 0000000000..b34a730801
--- /dev/null
+++ b/zephyr/include/ap_power/ap_pwrseq_sm_defs.h
@@ -0,0 +1,78 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef _AP_PWRSEQ_SM_DEFS_H_
+#define _AP_PWRSEQ_SM_DEFS_H_
+#include "ap_power/ap_pwrseq.h"
+
+#include <zephyr/smf.h>
+
+struct ap_pwrseq_smf {
+ /* Zephyr SMF state actions */
+ const struct smf_state actions;
+ /* Enumeration value of power state */
+ enum ap_pwrseq_state state;
+};
+
+/**
+ * Makes structures declarations of ACPI states for every level visible
+ * throughout state machine domain, definition will be completed by build system
+ * and appended to array `ap_pwrseq_states`.
+ **/
+#define AP_POWER_STATE_DECL(state) \
+ extern const struct smf_state arch_##state##_actions; \
+ extern const struct smf_state chipset_##state##_actions; \
+ extern const struct ap_pwrseq_smf app_state_##name;
+
+AP_POWER_STATE_DECL(AP_POWER_STATE_G3)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S5)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S4)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S3)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S2)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S1)
+AP_POWER_STATE_DECL(AP_POWER_STATE_S0)
+
+/**
+ * Makes visible `struct ap_pwrseq_smf` declarations for defined substates
+ * throughout the state machine domain, definition will be completed by build
+ * system and appended to array `ap_pwrseq_states`.
+ **/
+#define AP_PWRSEQ_CHIPSET_SUB_STATE_DECL(state, prefix) \
+ extern const struct ap_pwrseq_smf chipset_##state##_actions;
+
+#define AP_PWRSEQ_CHIPSET_SUB_STATE_DECL_(state) \
+ AP_PWRSEQ_CHIPSET_SUB_STATE_DECL(state, prefix)
+
+#define AP_PWRSEQ_CHIPSET_SUB_STATE_DECL__(node_id, prop, idx) \
+ AP_PWRSEQ_CHIPSET_SUB_STATE_DECL_( \
+ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN))
+
+#define AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_DECL(node_id) \
+ COND_CODE_1( \
+ DT_NODE_HAS_PROP(node_id, chipset), \
+ (DT_FOREACH_PROP_ELEM(node_id, chipset, \
+ AP_PWRSEQ_CHIPSET_SUB_STATE_DECL__)), \
+ ())
+
+#define AP_PWRSEQ_APP_SUB_STATE_DECL(state) \
+ extern const struct ap_pwrseq_smf app_state_##state;
+
+#define AP_PWRSEQ_APP_SUB_STATE_DECL_(state) AP_PWRSEQ_APP_SUB_STATE_DECL(state)
+
+#define AP_PWRSEQ_APP_SUB_STATE_DECL__(node_id, prop, idx) \
+ AP_PWRSEQ_APP_SUB_STATE_DECL_( \
+ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN))
+
+#define AP_PWRSEQ_EACH_APP_SUB_STATE_DECL(node_id) \
+ COND_CODE_1(DT_NODE_HAS_PROP(node_id, application), \
+ (DT_FOREACH_PROP_ELEM(node_id, application, \
+ AP_PWRSEQ_APP_SUB_STATE_DECL__)), \
+ ())
+
+DT_FOREACH_STATUS_OKAY(ap_pwrseq_sub_states,
+ AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_DECL)
+DT_FOREACH_STATUS_OKAY(ap_pwrseq_sub_states, AP_PWRSEQ_EACH_APP_SUB_STATE_DECL)
+
+#endif /* _AP_PWRSEQ_SM_DEFS_H_ */
diff --git a/zephyr/include/cros/ite/it8xxx2.dtsi b/zephyr/include/cros/ite/it8xxx2.dtsi
index 05c81b6896..983bf46663 100644
--- a/zephyr/include/cros/ite/it8xxx2.dtsi
+++ b/zephyr/include/cros/ite/it8xxx2.dtsi
@@ -49,18 +49,6 @@
};
soc {
- /* TODO(b/265198571): Migrate Zephyr EC builds to upstream SHI
- * drivers.
- */
- /delete-node/ shi@f03a00;
- shi: shi@f03a00 {
- compatible = "ite,it8xxx2-cros-shi";
- reg = <0x00f03a00 0x30>;
- interrupts = <171 0>;
- interrupt-parent = <&intc>;
- status = "disabled";
- };
-
fiu0: cros-flash@80000000 {
compatible = "ite,it8xxx2-cros-flash";
reg = <0x80000000 0x100000>;
diff --git a/zephyr/include/cros/nuvoton/npcx.dtsi b/zephyr/include/cros/nuvoton/npcx.dtsi
index 1237581158..46f719b03e 100644
--- a/zephyr/include/cros/nuvoton/npcx.dtsi
+++ b/zephyr/include/cros/nuvoton/npcx.dtsi
@@ -116,3 +116,7 @@
&mdc {
status = "okay";
};
+
+&shi0 {
+ shi-cs-wui =<&wui_io53>;
+};
diff --git a/zephyr/include/emul/emul_isl923x.h b/zephyr/include/emul/emul_isl923x.h
index 7d085658cf..96be6b6773 100644
--- a/zephyr/include/emul/emul_isl923x.h
+++ b/zephyr/include/emul/emul_isl923x.h
@@ -86,6 +86,14 @@ void isl923x_emul_set_adc_vbus(const struct emul *emulator, uint16_t vbus_mv);
void raa489000_emul_set_acok_pin(const struct emul *emulator, uint16_t value);
/**
+ * @brief Set the value of the state machine status bits in the INFO2 register.
+ *
+ * @param value State machine state, such as RAA489000_INFO2_STATE_OTG
+ */
+void raa489000_emul_set_state_machine_state(const struct emul *emulator,
+ uint16_t value);
+
+/**
* @brief Peek at a register value. This function will assert if the requested
* register does is unimplemented.
*
diff --git a/zephyr/include/emul/tcpc/emul_tcpci.h b/zephyr/include/emul/tcpc/emul_tcpci.h
index 5a7777d6ad..1df40b2c1a 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci.h
@@ -80,8 +80,7 @@ struct tcpci_ctx {
const struct tcpci_emul_partner_ops *partner;
/** Reference to Alert# GPIO emulator. */
- const struct device *alert_gpio_port;
- gpio_pin_t alert_gpio_pin;
+ struct gpio_dt_spec irq_gpio;
};
/** Run-time data used by the emulator */
@@ -105,15 +104,7 @@ struct tcpc_emul_data {
.tx_msg = &tcpci_emul_tx_msg_##n, \
.error_on_ro_write = true, \
.error_on_rsvd_write = true, \
- .alert_gpio_port = COND_CODE_1( \
- DT_INST_NODE_HAS_PROP(n, alert_gpio), \
- (DEVICE_DT_GET(DT_GPIO_CTLR( \
- DT_INST_PROP(n, alert_gpio), gpios))), \
- (NULL)), \
- .alert_gpio_pin = COND_CODE_1( \
- DT_INST_NODE_HAS_PROP(n, alert_gpio), \
- (DT_GPIO_PIN(DT_INST_PROP(n, alert_gpio), gpios)), \
- (0)), \
+ .irq_gpio = GPIO_DT_SPEC_INST_GET_OR(n, irq_gpios, {}), \
}; \
static struct tcpc_emul_data tcpc_emul_data_##n = { \
.tcpci_ctx = &tcpci_ctx##n, \
diff --git a/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h b/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
index ef3051e3de..16012c083e 100644
--- a/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
+++ b/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
@@ -25,87 +25,4 @@ struct mtc_reg {
#define NPCX_WTC_PTO 30
#define NPCX_WTC_WIE 31
-/* SHI (Serial Host Interface) registers */
-struct cros_shi_reg {
- volatile uint8_t reserved1;
- /* 0x001: SHI Configuration 1 */
- volatile uint8_t SHICFG1;
- /* 0x002: SHI Configuration 2 */
- volatile uint8_t SHICFG2;
- volatile uint8_t reserved2[2];
- /* 0x005: Event Enable */
- volatile uint8_t EVENABLE;
- /* 0x006: Event Status */
- volatile uint8_t EVSTAT;
- /* 0x007: SHI Capabilities */
- volatile uint8_t CAPABILITY;
- /* 0x008: Status */
- volatile uint8_t STATUS;
- volatile uint8_t reserved3;
- /* 0x00A: Input Buffer Status */
- volatile uint8_t IBUFSTAT;
- /* 0x00B: Output Buffer Status */
- volatile uint8_t OBUFSTAT;
- /* 0x00C: SHI Configuration 3 */
- volatile uint8_t SHICFG3;
- /* 0x00D: SHI Configuration 4 */
- volatile uint8_t SHICFG4;
- /* 0x00E: SHI Configuration 5 */
- volatile uint8_t SHICFG5;
- /* 0x00F: Event Status 2 */
- volatile uint8_t EVSTAT2;
- /* 0x010: Event Enable 2 */
- volatile uint8_t EVENABLE2;
- volatile uint8_t reserved4[15];
- /* 0x20~0x9F: Output Buffer */
- volatile uint8_t OBUF[128];
- /* 0xA0~0x11F: Input Buffer */
- volatile uint8_t IBUF[128];
-};
-
-/* SHI register fields */
-#define NPCX_SHICFG1_EN 0
-#define NPCX_SHICFG1_MODE 1
-#define NPCX_SHICFG1_WEN 2
-#define NPCX_SHICFG1_AUTIBF 3
-#define NPCX_SHICFG1_AUTOBE 4
-#define NPCX_SHICFG1_DAS 5
-#define NPCX_SHICFG1_CPOL 6
-#define NPCX_SHICFG1_IWRAP 7
-#define NPCX_SHICFG2_SIMUL 0
-#define NPCX_SHICFG2_BUSY 1
-#define NPCX_SHICFG2_ONESHOT 2
-#define NPCX_SHICFG2_SLWU 3
-#define NPCX_SHICFG2_REEN 4
-#define NPCX_SHICFG2_RESTART 5
-#define NPCX_SHICFG2_REEVEN 6
-#define NPCX_EVENABLE_OBEEN 0
-#define NPCX_EVENABLE_OBHEEN 1
-#define NPCX_EVENABLE_IBFEN 2
-#define NPCX_EVENABLE_IBHFEN 3
-#define NPCX_EVENABLE_EOREN 4
-#define NPCX_EVENABLE_EOWEN 5
-#define NPCX_EVENABLE_STSREN 6
-#define NPCX_EVENABLE_IBOREN 7
-#define NPCX_EVSTAT_OBE 0
-#define NPCX_EVSTAT_OBHE 1
-#define NPCX_EVSTAT_IBF 2
-#define NPCX_EVSTAT_IBHF 3
-#define NPCX_EVSTAT_EOR 4
-#define NPCX_EVSTAT_EOW 5
-#define NPCX_EVSTAT_STSR 6
-#define NPCX_EVSTAT_IBOR 7
-#define NPCX_STATUS_OBES 6
-#define NPCX_STATUS_IBFS 7
-#define NPCX_SHICFG3_OBUFLVLDIS 7
-#define NPCX_SHICFG4_IBUFLVLDIS 7
-#define NPCX_SHICFG5_IBUFLVL2 FIELD(0, 6)
-#define NPCX_SHICFG5_IBUFLVL2DIS 7
-#define NPCX_EVSTAT2_IBHF2 0
-#define NPCX_EVSTAT2_CSNRE 1
-#define NPCX_EVSTAT2_CSNFE 2
-#define NPCX_EVENABLE2_IBHF2EN 0
-#define NPCX_EVENABLE2_CSNREEN 1
-#define NPCX_EVENABLE2_CSNFEEN 2
-
#endif /* _NUVOTON_NPCX_REG_DEF_CROS_H */
diff --git a/zephyr/program/brya/i2c.dts b/zephyr/program/brya/i2c.dts
index 1926fd61e3..b87a53f600 100644
--- a/zephyr/program/brya/i2c.dts
+++ b/zephyr/program/brya/i2c.dts
@@ -73,7 +73,11 @@
tcpc-flags = <(
TCPC_FLAGS_TCPCI_REV2_0 |
TCPC_FLAGS_NO_DEBUG_ACC_CONTROL)>;
- int-pin = <&gpio_usb_c0_c2_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_c2_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
nct3808_0_P1: nct3808_0_P1@70 {
@@ -100,7 +104,11 @@
reg = <0x74>;
gpio-dev = <&nct3808_0_P2>;
tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>;
- int-pin = <&gpio_usb_c0_c2_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_c2_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
nct3808_0_P2: nct3808_0_P2@74 {
@@ -216,7 +224,11 @@
TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V |
TCPC_FLAGS_CONTROL_VCONN |
TCPC_FLAGS_CONTROL_FRS)>;
- int-pin = <&gpio_usb_c1_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioa 2 GPIO_ACTIVE_LOW>;
};
};
diff --git a/zephyr/program/brya/interrupts.dts b/zephyr/program/brya/interrupts.dts
index 1adca3e035..ea5bcc542a 100644
--- a/zephyr/program/brya/interrupts.dts
+++ b/zephyr/program/brya/interrupts.dts
@@ -96,16 +96,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "throttle_ap_prochot_input_interrupt";
};
- int_usb_c0_c2_tcpc: usb_c0_c2_tcpc {
- irq-pin = <&gpio_usb_c0_c2_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1_tcpc: usb_c1_tcpc {
- irq-pin = <&gpio_usb_c1_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_ppc: usb_c0_ppc {
irq-pin = <&gpio_usb_c0_ppc_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/program/corsola/ite_keyboard.dtsi b/zephyr/program/corsola/ite_keyboard.dtsi
index 8d2a345ff0..0bd6887ddb 100644
--- a/zephyr/program/corsola/ite_keyboard.dtsi
+++ b/zephyr/program/corsola/ite_keyboard.dtsi
@@ -26,3 +26,29 @@
>;
};
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <&ksi0_default
+ &ksi1_default
+ &ksi2_default
+ &ksi3_default
+ &ksi4_default
+ &ksi5_default
+ &ksi6_default
+ &ksi7_default
+ &kso0_default
+ &kso1_default
+ &kso3_default
+ &kso4_default
+ &kso5_default
+ &kso6_default
+ &kso7_default
+ &kso8_default
+ &kso9_default
+ &kso10_default
+ &kso11_default
+ &kso12_default>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/program/corsola/ite_program.conf b/zephyr/program/corsola/ite_program.conf
index e6851580db..3e981dee81 100644
--- a/zephyr/program/corsola/ite_program.conf
+++ b/zephyr/program/corsola/ite_program.conf
@@ -70,8 +70,6 @@ CONFIG_PLATFORM_EC_USB_PD_DUAL_ROLE_AUTO_TOGGLE=n
CONFIG_PLATFORM_EC_CONFIG_USB_PD_3A_PORTS=0
CONFIG_PLATFORM_EC_USB_PD_PULLUP=1
-CONFIG_PLATFORM_EC_SHA256_UNROLLED=y
-
# TODO(b/180980668): bring these features up
CONFIG_LTO=n
CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
diff --git a/zephyr/program/corsola/ite_shi.dtsi b/zephyr/program/corsola/ite_shi.dtsi
index 12c0c6ca5b..cf531f7418 100644
--- a/zephyr/program/corsola/ite_shi.dtsi
+++ b/zephyr/program/corsola/ite_shi.dtsi
@@ -5,9 +5,10 @@
#include <ite/it8xxx2-pinctrl-map.dtsi>
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_mosi_gpm0_default &shi_miso_gpm1_default
&shi_clk_gpm4_default &shi_cs_gpm5_default>;
pinctrl-names = "default";
+ cs-gpios = <&gpiom 5 0>; /* unused but needed by dt binding */
};
diff --git a/zephyr/program/corsola/npcx_host_interface.dtsi b/zephyr/program/corsola/npcx_host_interface.dtsi
index 14efa3c6b2..b691893854 100644
--- a/zephyr/program/corsola/npcx_host_interface.dtsi
+++ b/zephyr/program/corsola/npcx_host_interface.dtsi
@@ -4,7 +4,7 @@
*/
/* host interface */
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_gp46_47_53_55>;
pinctrl-1 = <&shi_gpio_gp46_47_53_55>;
diff --git a/zephyr/program/corsola/npcx_i2c.dtsi b/zephyr/program/corsola/npcx_i2c.dtsi
index ce41937ed2..2fd56fab53 100644
--- a/zephyr/program/corsola/npcx_i2c.dtsi
+++ b/zephyr/program/corsola/npcx_i2c.dtsi
@@ -77,7 +77,11 @@
TCPC_FLAGS_ALERT_OD |
TCPC_FLAGS_CONTROL_VCONN |
TCPC_FLAGS_CONTROL_FRS)>;
- int-pin = <&gpio_usb_c0_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
};
ppc_port0: nx20p348x@72 {
@@ -111,7 +115,11 @@
TCPC_FLAGS_ALERT_OD |
TCPC_FLAGS_CONTROL_VCONN |
TCPC_FLAGS_CONTROL_FRS)>;
- int-pin = <&gpio_usb_c1_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 1 GPIO_ACTIVE_LOW>;
};
ppc_port1: nx20p348x@72 {
diff --git a/zephyr/program/corsola/npcx_interrupts.dtsi b/zephyr/program/corsola/npcx_interrupts.dtsi
index f3da785a60..130f4501dd 100644
--- a/zephyr/program/corsola/npcx_interrupts.dtsi
+++ b/zephyr/program/corsola/npcx_interrupts.dtsi
@@ -70,16 +70,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "switch_interrupt";
};
- int_usb_c0_tcpc: usb_c0_tcpc {
- irq-pin = <&gpio_usb_c0_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1_tcpc: usb_c1_tcpc {
- irq-pin = <&gpio_usb_c1_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_ppc: usb_c0_ppc {
irq-pin = <&gpio_usb_c0_ppc_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/program/corsola/src/npcx_usbc.c b/zephyr/program/corsola/src/npcx_usbc.c
index eead9fa528..b22f42897d 100644
--- a/zephyr/program/corsola/src/npcx_usbc.c
+++ b/zephyr/program/corsola/src/npcx_usbc.c
@@ -59,11 +59,9 @@ void board_tcpc_init(void)
board_reset_pd_mcu();
}
- /* Enable TCPC interrupts */
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_tcpc));
- if (corsola_get_db_type() == CORSOLA_DB_TYPEC) {
- gpio_enable_dt_interrupt(
- GPIO_INT_FROM_NODELABEL(int_usb_c1_tcpc));
+ /* Do not enable TCPC interrupt on port 1 if not type-c */
+ if (corsola_get_db_type() != CORSOLA_DB_TYPEC) {
+ tcpc_config[USBC_PORT_C1].irq_gpio.port = NULL;
}
/* Enable BC1.2 interrupts. */
diff --git a/zephyr/program/corsola/tentacruel/project.conf b/zephyr/program/corsola/tentacruel/project.conf
index 587e3932ba..8229e23f9f 100644
--- a/zephyr/program/corsola/tentacruel/project.conf
+++ b/zephyr/program/corsola/tentacruel/project.conf
@@ -20,6 +20,8 @@ CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y
# Battery
CONFIG_PLATFORM_EC_CHARGER_PROFILE_OVERRIDE=y
+CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT=10
+CONFIG_PLATFORM_EC_SMBUS_PEC=y
# Remove bring up options for FW QUAL
CONFIG_PLATFORM_EC_BRINGUP=n
diff --git a/zephyr/program/geralt/geralt/battery.dtsi b/zephyr/program/geralt/geralt/battery.dtsi
index fc1e5268e1..7c194ca918 100644
--- a/zephyr/program/geralt/geralt/battery.dtsi
+++ b/zephyr/program/geralt/geralt/battery.dtsi
@@ -4,10 +4,9 @@
*/
/ {
- /* TODO: update this after we got the real battery */
batteries {
- default_battery: dynapack_c140254 {
- compatible = "dynapack,c140254", "battery-smart";
+ default_battery: smp_l21m4pg0 {
+ compatible = "smp,l21m4pg0", "battery-smart";
};
};
};
diff --git a/zephyr/program/geralt/geralt/project.overlay b/zephyr/program/geralt/geralt/project.overlay
index b54d181c38..76ed8c0a6a 100644
--- a/zephyr/program/geralt/geralt/project.overlay
+++ b/zephyr/program/geralt/geralt/project.overlay
@@ -9,6 +9,7 @@
#include "../gpio.dtsi"
#include "../i2c.dtsi"
#include "../interrupts.dtsi"
+#include "../keyboard.dtsi"
#include "../mkbp.dtsi"
#include "../motionsense.dtsi"
#include "../power_signal.dtsi"
diff --git a/zephyr/program/geralt/gpio.dtsi b/zephyr/program/geralt/gpio.dtsi
index 2f9b7b9f35..4374b444c5 100644
--- a/zephyr/program/geralt/gpio.dtsi
+++ b/zephyr/program/geralt/gpio.dtsi
@@ -129,7 +129,11 @@
gpios = <&gpiog 0 GPIO_OUTPUT_HIGH>;
};
en_pp4200_s5: en-pp4200-s5 {
- gpios = <&gpiob 7 GPIO_OUTPUT_HIGH>;
+ gpios = <&gpiob 7 GPIO_OUTPUT_LOW>;
+ };
+ pg_pp4200_s5_od: pg-pp4200-s5-od {
+ gpios = <&gpioc 5 GPIO_INPUT>;
+ enum-name = "GPIO_PG_PP4200_S5_OD";
};
sys_rst_odl: sys-rst-odl {
gpios = <&gpiog 1 GPIO_ODR_LOW>;
@@ -182,8 +186,6 @@
unused-gpios =
/* pg_pp5000_z1_od */
<&gpiod 2 GPIO_INPUT>,
- /* pg_pp4200_s5_od */
- <&gpioc 5 GPIO_INPUT>,
/* charge_en */
<&gpioe 1 GPIO_INPUT>,
/* unnamed nc pins */
diff --git a/zephyr/program/geralt/i2c.dtsi b/zephyr/program/geralt/i2c.dtsi
index cc2e6f6bdf..cf36d68ef9 100644
--- a/zephyr/program/geralt/i2c.dtsi
+++ b/zephyr/program/geralt/i2c.dtsi
@@ -64,7 +64,6 @@
compatible = "richtek,rt9490";
status = "okay";
reg = <0x53>;
- irq = <&int_usb_c1_bc12_charger>;
};
};
diff --git a/zephyr/program/geralt/interrupts.dtsi b/zephyr/program/geralt/interrupts.dtsi
index 99c3cb7e56..dd48aa8977 100644
--- a/zephyr/program/geralt/interrupts.dtsi
+++ b/zephyr/program/geralt/interrupts.dtsi
@@ -51,11 +51,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "extpower_interrupt";
};
- int_usb_c1_bc12_charger: usb-c1-bc12-charger {
- irq-pin = <&usb_c1_bc12_charger_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "rt9490_bc12_dt_interrupt";
- };
int_lid_open: lid-open {
irq-pin = <&lid_open>;
flags = <GPIO_INT_EDGE_BOTH>;
@@ -66,6 +61,11 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "power_button_interrupt";
};
+ int_pg_pp4200_s5: pg-pp4200-s5 {
+ irq-pin = <&pg_pp4200_s5_od>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "power_signal_interrupt";
+ };
int_warm_rst: warm-rst {
irq-pin = <&ap_ec_warm_rst_req>;
flags = <GPIO_INT_EDGE_RISING>;
@@ -96,5 +96,10 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "ccd_interrupt";
};
+ int_ap_xhci_init_done: ap-xhci-init-done {
+ irq-pin = <&ap_xhci_init_done>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "xhci_interrupt";
+ };
};
};
diff --git a/zephyr/program/geralt/keyboard.dtsi b/zephyr/program/geralt/keyboard.dtsi
new file mode 100644
index 0000000000..9541c4aa81
--- /dev/null
+++ b/zephyr/program/geralt/keyboard.dtsi
@@ -0,0 +1,30 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <&ksi0_default
+ &ksi1_default
+ &ksi2_default
+ &ksi3_default
+ &ksi4_default
+ &ksi5_default
+ &ksi6_default
+ &ksi7_default
+ &kso0_default
+ &kso1_default
+ &kso3_default
+ &kso4_default
+ &kso5_default
+ &kso6_default
+ &kso7_default
+ &kso8_default
+ &kso9_default
+ &kso10_default
+ &kso11_default
+ &kso12_default>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/program/geralt/power_signal.dtsi b/zephyr/program/geralt/power_signal.dtsi
index 268b068a21..38ec8a19a2 100644
--- a/zephyr/program/geralt/power_signal.dtsi
+++ b/zephyr/program/geralt/power_signal.dtsi
@@ -5,7 +5,7 @@
/ {
power_signal_list: power-signal-list {
- compatible = "mediatek,mt8186-power-signal-list";
+ compatible = "mediatek,mt8188-power-signal-list";
ap_in_rst {
power-enum-name = "AP_IN_RST";
@@ -23,5 +23,9 @@
power-enum-name = "AP_WARM_RST_REQ";
power-gpio-pin = <&ap_ec_warm_rst_req>;
};
+ pg_pp4200_s5 {
+ power-enum-name = "PG_PP4200_S5";
+ power-gpio-pin = <&pg_pp4200_s5_od>;
+ };
};
};
diff --git a/zephyr/program/geralt/program.conf b/zephyr/program/geralt/program.conf
index 501afdee7c..3394f85b82 100644
--- a/zephyr/program/geralt/program.conf
+++ b/zephyr/program/geralt/program.conf
@@ -20,7 +20,7 @@ CONFIG_SHIMMED_TASKS=y
# AP SoC configuration
CONFIG_AP=y
-CONFIG_AP_ARM_MTK_MT8186=y
+CONFIG_AP_ARM_MTK_MT8188=y
# Shell features
CONFIG_KERNEL_SHELL=y
@@ -87,6 +87,8 @@ CONFIG_PLATFORM_EC_BATTERY_SMART=y
CONFIG_PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV=9000
CONFIG_PLATFORM_EC_I2C_PASSTHRU_RESTRICTED=y
CONFIG_PLATFORM_EC_I2C_VIRTUAL_BATTERY=y
+CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT=5
+CONFIG_PLATFORM_EC_SMBUS_PEC=y
# Charger
CONFIG_PLATFORM_EC_CHARGE_MANAGER=y
@@ -125,7 +127,6 @@ CONFIG_PLATFORM_EC_HOST_COMMAND_STATUS=y
CONFIG_PWM=y
# Sensors
-CONFIG_PLATFORM_EC_MOTIONSENSE=y
CONFIG_PLATFORM_EC_ACCEL_FIFO=y
CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y
CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y
@@ -144,7 +145,7 @@ CONFIG_TASK_MOTIONSENSE_STACK_SIZE=1024
CONFIG_TASK_PD_STACK_SIZE=1280
# USB-C
-CONFIG_PLATFORM_EC_BC12_SINGLE_DRIVER=n
+CONFIG_PLATFORM_EC_USB_CHARGER=n
CONFIG_PLATFORM_EC_USBC_PPC_SYV682C=y
CONFIG_PLATFORM_EC_USB_MUX_TUSB546=y
CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_PPC=y
diff --git a/zephyr/program/geralt/shi.dtsi b/zephyr/program/geralt/shi.dtsi
index 12c0c6ca5b..cf531f7418 100644
--- a/zephyr/program/geralt/shi.dtsi
+++ b/zephyr/program/geralt/shi.dtsi
@@ -5,9 +5,10 @@
#include <ite/it8xxx2-pinctrl-map.dtsi>
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_mosi_gpm0_default &shi_miso_gpm1_default
&shi_clk_gpm4_default &shi_cs_gpm5_default>;
pinctrl-names = "default";
+ cs-gpios = <&gpiom 5 0>; /* unused but needed by dt binding */
};
diff --git a/zephyr/program/geralt/src/hibernate.c b/zephyr/program/geralt/src/hibernate.c
index c83d37cc91..fb70248338 100644
--- a/zephyr/program/geralt/src/hibernate.c
+++ b/zephyr/program/geralt/src/hibernate.c
@@ -9,5 +9,8 @@
/* Geralt board specific hibernate implementation */
__override void board_hibernate_late(void)
{
+ gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_pp5000_z1_l), 1);
+ /* It takes around 30ms to release the PP5000 capacitance. */
+ udelay(30 * MSEC);
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_ulp), 1);
}
diff --git a/zephyr/program/geralt/src/hooks.c b/zephyr/program/geralt/src/hooks.c
index 628ecdd0f8..bc21babe66 100644
--- a/zephyr/program/geralt/src/hooks.c
+++ b/zephyr/program/geralt/src/hooks.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "gpio/gpio_int.h"
#include "gpio_signal.h"
#include "hooks.h"
@@ -31,6 +32,13 @@ static void board_i2c3_ctrl(bool enable)
}
}
+static void geralt_common_init(void)
+{
+ gpio_enable_dt_interrupt(
+ GPIO_INT_FROM_NODELABEL(int_ap_xhci_init_done));
+}
+DECLARE_HOOK(HOOK_INIT, geralt_common_init, HOOK_PRIO_PRE_DEFAULT);
+
static void board_enable_i2c3(void)
{
board_i2c3_ctrl(1);
diff --git a/zephyr/program/geralt/src/usb_pd_policy.c b/zephyr/program/geralt/src/usb_pd_policy.c
index c445fc0e22..72558b50d6 100644
--- a/zephyr/program/geralt/src/usb_pd_policy.c
+++ b/zephyr/program/geralt/src/usb_pd_policy.c
@@ -18,7 +18,7 @@ int pd_check_vconn_swap(int port)
int pd_snk_is_vbus_provided(int port)
{
- static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT];
+ __maybe_unused static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT];
int vbus;
/*
diff --git a/zephyr/program/geralt/src/usbc_config.c b/zephyr/program/geralt/src/usbc_config.c
index 7c49f58237..21a6f88d0b 100644
--- a/zephyr/program/geralt/src/usbc_config.c
+++ b/zephyr/program/geralt/src/usbc_config.c
@@ -9,10 +9,16 @@
#include "charge_state_v2.h"
#include "console.h"
#include "driver/tcpm/it83xx_pd.h"
+#include "gpio.h"
+#include "gpio_signal.h"
+#include "usb_charge.h"
#include "usb_pd.h"
+#include "usb_tc_sm.h"
#include "usbc_ppc.h"
#include "zephyr_adc.h"
+#include <zephyr/drivers/gpio.h>
+
#include <ap_power/ap_power.h>
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args)
@@ -129,3 +135,43 @@ enum adc_channel board_get_vbus_adc(int port)
return ADC_VBUS_C0;
}
#endif /* CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT */
+
+/* USB-A */
+void xhci_interrupt(enum gpio_signal signal)
+{
+ enum usb_charge_mode mode =
+ gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(ap_xhci_init_done)) ?
+ USB_CHARGE_MODE_ENABLED :
+ USB_CHARGE_MODE_DISABLED;
+
+ const int xhci_stat = gpio_get_level(signal);
+
+ for (int i = 0; i < USB_PORT_COUNT; i++) {
+ usb_charge_set_mode(i, mode, USB_ALLOW_SUSPEND_CHARGE);
+ }
+
+ for (int i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ /*
+ * Enable DRP toggle after XHCI inited. This is used to follow
+ * USB 3.2 spec 10.3.1.1.
+ */
+ if (xhci_stat) {
+ pd_set_dual_role(i, PD_DRP_TOGGLE_ON);
+ } else if (tc_is_attached_src(i)) {
+ /*
+ * This is a AP reset S0->S0 transition.
+ * We should set the role back to sink.
+ */
+ pd_set_dual_role(i, PD_DRP_FORCE_SINK);
+ }
+ }
+}
+
+__override enum pd_dual_role_states pd_get_drp_state_in_s0(void)
+{
+ if (gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(ap_xhci_init_done))) {
+ return PD_DRP_TOGGLE_ON;
+ } else {
+ return PD_DRP_FORCE_SINK;
+ }
+}
diff --git a/zephyr/program/geralt/usbc.dtsi b/zephyr/program/geralt/usbc.dtsi
index 88e29a6b27..fd26638873 100644
--- a/zephyr/program/geralt/usbc.dtsi
+++ b/zephyr/program/geralt/usbc.dtsi
@@ -11,7 +11,6 @@
port0@0 {
compatible = "named-usbc-port";
reg = <0>;
- bc12 = <&bc12_ppc_port0>;
ppc = <&bc12_ppc_port0>;
tcpc = <&usbpd0>;
chg = <&charger_bc12_port1>;
@@ -29,7 +28,6 @@
port1@1 {
compatible = "named-usbc-port";
reg = <1>;
- bc12 = <&charger_bc12_port1>;
ppc = <&ppc_port1>;
tcpc = <&usbpd1>;
usb-mux-chain-1 {
diff --git a/zephyr/program/herobrine/common.dtsi b/zephyr/program/herobrine/common.dtsi
index d4e92830bb..0fbde24a54 100644
--- a/zephyr/program/herobrine/common.dtsi
+++ b/zephyr/program/herobrine/common.dtsi
@@ -36,7 +36,7 @@
};
};
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_gp46_47_53_55>;
pinctrl-1 = <&shi_gpio_gp46_47_53_55>;
diff --git a/zephyr/program/herobrine/hoglin/project.overlay b/zephyr/program/herobrine/hoglin/project.overlay
index cabc9cbeda..dd192d22f9 100644
--- a/zephyr/program/herobrine/hoglin/project.overlay
+++ b/zephyr/program/herobrine/hoglin/project.overlay
@@ -42,7 +42,11 @@
tcpc_port0: ps8xxx@1b {
compatible = "parade,ps8xxx";
reg = <0x1b>;
- int-pin = <&gpio_usb_c0_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
};
@@ -51,6 +55,10 @@
tcpc_port1: ps8xxx@1b {
compatible = "parade,ps8xxx";
reg = <0x1b>;
- int-pin = <&gpio_usb_c1_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpiof 5 GPIO_ACTIVE_LOW>;
};
};
diff --git a/zephyr/program/herobrine/i2c.dtsi b/zephyr/program/herobrine/i2c.dtsi
index c5526afa9f..fa4c1c2960 100644
--- a/zephyr/program/herobrine/i2c.dtsi
+++ b/zephyr/program/herobrine/i2c.dtsi
@@ -95,7 +95,11 @@
tcpc_port0: ps8xxx@b {
compatible = "parade,ps8xxx";
reg = <0xb>;
- int-pin = <&gpio_usb_c0_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
};
@@ -120,7 +124,11 @@
tcpc_port1: ps8xxx@b {
compatible = "parade,ps8xxx";
reg = <0xb>;
- int-pin = <&gpio_usb_c1_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpiof 5 GPIO_ACTIVE_LOW>;
};
};
diff --git a/zephyr/program/herobrine/interrupts.dtsi b/zephyr/program/herobrine/interrupts.dtsi
index 82650bfc51..36d31cfffe 100644
--- a/zephyr/program/herobrine/interrupts.dtsi
+++ b/zephyr/program/herobrine/interrupts.dtsi
@@ -66,16 +66,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "power_signal_interrupt";
};
- int_usb_c0_pd: usb_c0_pd {
- irq-pin = <&gpio_usb_c0_pd_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1_pd: usb_c1_pd {
- irq-pin = <&gpio_usb_c1_pd_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_swctl: usb_c0_swctl {
irq-pin = <&gpio_usb_c0_swctl_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/program/herobrine/program.conf b/zephyr/program/herobrine/program.conf
index b18dd9bed1..0bdfde796d 100644
--- a/zephyr/program/herobrine/program.conf
+++ b/zephyr/program/herobrine/program.conf
@@ -77,7 +77,6 @@ CONFIG_PLATFORM_EC_USB_PD_FRS=y
CONFIG_PLATFORM_EC_USB_PD_USB32_DRD=n
CONFIG_PLATFORM_EC_USBC_PPC_SYV682C=y
CONFIG_PLATFORM_EC_USB_PD_FRS_PPC=y
-CONFIG_PLATFORM_EC_USBC_RETIMER_FW_UPDATE=n
CONFIG_PLATFORM_EC_USBC_SS_MUX_DFP_ONLY=y
CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC=y
CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y
diff --git a/zephyr/program/herobrine/src/usbc_config.c b/zephyr/program/herobrine/src/usbc_config.c
index 40c603d304..69620a02b4 100644
--- a/zephyr/program/herobrine/src/usbc_config.c
+++ b/zephyr/program/herobrine/src/usbc_config.c
@@ -130,10 +130,6 @@ void board_tcpc_init(void)
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_swctl));
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_swctl));
- /* Enable TCPC interrupts */
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_pd));
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_pd));
-
/*
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
diff --git a/zephyr/program/intelrvp/adlrvp/adlrvp_mchp/prj.conf b/zephyr/program/intelrvp/adlrvp/adlrvp_mchp/prj.conf
index 2dee48d99f..bf170e0594 100644
--- a/zephyr/program/intelrvp/adlrvp/adlrvp_mchp/prj.conf
+++ b/zephyr/program/intelrvp/adlrvp/adlrvp_mchp/prj.conf
@@ -19,9 +19,6 @@ CONFIG_ESPI_PERIPHERAL_KBC_IBF_EVT_DATA=y
CONFIG_MCHP_MEC_UNSIGNED_HEADER=y
CONFIG_MCHP_MEC_HEADER_FLASH_SIZE_256K=y
-# Support Zephyr SPI NOR driver to work with MCHP SPI driver
-CONFIG_SPI_XEC_QMSPI_FULL_DUPLEX=y
-
# Sensors - MCHP TACH driver under sensor
CONFIG_SENSOR=n
diff --git a/zephyr/program/intelrvp/adlrvp/adlrvp_npcx/prj.conf b/zephyr/program/intelrvp/adlrvp/adlrvp_npcx/prj.conf
index eef09c8277..d04abada31 100644
--- a/zephyr/program/intelrvp/adlrvp/adlrvp_npcx/prj.conf
+++ b/zephyr/program/intelrvp/adlrvp/adlrvp_npcx/prj.conf
@@ -11,6 +11,3 @@ CONFIG_PLATFORM_EC_DEDICATED_CHARGE_PORT=y
# RTC
CONFIG_PLATFORM_EC_RTC=y
-
-# Keyboard
-CONFIG_CROS_KB_RAW_NPCX=y
diff --git a/zephyr/program/intelrvp/mtlrvp/mtlrvpp_mchp/prj.conf b/zephyr/program/intelrvp/mtlrvp/mtlrvpp_mchp/prj.conf
index 88ae4248df..7a83dd61fc 100644
--- a/zephyr/program/intelrvp/mtlrvp/mtlrvpp_mchp/prj.conf
+++ b/zephyr/program/intelrvp/mtlrvp/mtlrvpp_mchp/prj.conf
@@ -24,9 +24,6 @@ CONFIG_EEPROM=n
CONFIG_MCHP_MEC_UNSIGNED_HEADER=y
CONFIG_MCHP_MEC_HEADER_FLASH_SIZE_256K=y
-# Support Zephyr SPI NOR driver to work with MCHP SPI driver
-CONFIG_SPI_XEC_QMSPI_FULL_DUPLEX=y
-
# PWM
CONFIG_PWM=y
CONFIG_PWM_SHELL=n
diff --git a/zephyr/program/intelrvp/prj.conf b/zephyr/program/intelrvp/prj.conf
index 6b90fcebc1..859567736d 100644
--- a/zephyr/program/intelrvp/prj.conf
+++ b/zephyr/program/intelrvp/prj.conf
@@ -32,6 +32,7 @@ CONFIG_PLATFORM_EC_PORT80=y
CONFIG_PLATFORM_EC_USB_VID=0x18d1
CONFIG_PLATFORM_EC_USB_PID=0x8086
CONFIG_PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY=y
+CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n
# eSPI
CONFIG_ESPI=y
diff --git a/zephyr/program/it8xxx2_evb/shi.dts b/zephyr/program/it8xxx2_evb/shi.dts
index 12c0c6ca5b..cf531f7418 100644
--- a/zephyr/program/it8xxx2_evb/shi.dts
+++ b/zephyr/program/it8xxx2_evb/shi.dts
@@ -5,9 +5,10 @@
#include <ite/it8xxx2-pinctrl-map.dtsi>
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_mosi_gpm0_default &shi_miso_gpm1_default
&shi_clk_gpm4_default &shi_cs_gpm5_default>;
pinctrl-names = "default";
+ cs-gpios = <&gpiom 5 0>; /* unused but needed by dt binding */
};
diff --git a/zephyr/program/nissa/craask/project.conf b/zephyr/program/nissa/craask/project.conf
index f530f0f54e..7bcc64e6a5 100644
--- a/zephyr/program/nissa/craask/project.conf
+++ b/zephyr/program/nissa/craask/project.conf
@@ -14,6 +14,11 @@ CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y
CONFIG_PLATFORM_EC_BUTTONS_RUNTIME_CONFIG=y
+# Increase PD max power from default
+CONFIG_PLATFORM_EC_PD_MAX_POWER_MW=65000
+CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=20000
+CONFIG_PLATFORM_EC_PD_MAX_CURRENT_MA=3250
+
# Flash space saving
# Turning off extended console help saves ~3500 bytes
CONFIG_SHELL_HELP=n
diff --git a/zephyr/program/nissa/craask/src/usbc.c b/zephyr/program/nissa/craask/src/usbc.c
index 8655bde95b..1304ae03bb 100644
--- a/zephyr/program/nissa/craask/src/usbc.c
+++ b/zephyr/program/nissa/craask/src/usbc.c
@@ -208,6 +208,10 @@ static void usbc_interrupt_trigger(int port)
static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio,
const struct deferred_data *ud)
{
+ /*
+ * TODO(b/267537103): Migrate named-gpios to Zephyr's GPIO hogs. Verify
+ * the active high/active low setting once GPIO hogs are used.
+ */
if (!gpio_pin_get_dt(gpio)) {
usbc_interrupt_trigger(port);
hook_call_deferred(ud, USBC_INT_POLL_DELAY_US);
diff --git a/zephyr/program/nissa/joxer/keyboard.dtsi b/zephyr/program/nissa/joxer/keyboard.dtsi
index 04a620767a..1742e1a50f 100644
--- a/zephyr/program/nissa/joxer/keyboard.dtsi
+++ b/zephyr/program/nissa/joxer/keyboard.dtsi
@@ -20,3 +20,29 @@
pinctrl-0 = <&pwm0_gpa0_default>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <&ksi0_default
+ &ksi1_default
+ &ksi2_default
+ &ksi3_default
+ &ksi4_default
+ &ksi5_default
+ &ksi6_default
+ &ksi7_default
+ &kso0_default
+ &kso1_default
+ &kso3_default
+ &kso4_default
+ &kso5_default
+ &kso6_default
+ &kso7_default
+ &kso8_default
+ &kso9_default
+ &kso10_default
+ &kso11_default
+ &kso12_default>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/program/nissa/nereid/keyboard.dtsi b/zephyr/program/nissa/nereid/keyboard.dtsi
index 04a620767a..1742e1a50f 100644
--- a/zephyr/program/nissa/nereid/keyboard.dtsi
+++ b/zephyr/program/nissa/nereid/keyboard.dtsi
@@ -20,3 +20,29 @@
pinctrl-0 = <&pwm0_gpa0_default>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <&ksi0_default
+ &ksi1_default
+ &ksi2_default
+ &ksi3_default
+ &ksi4_default
+ &ksi5_default
+ &ksi6_default
+ &ksi7_default
+ &kso0_default
+ &kso1_default
+ &kso3_default
+ &kso4_default
+ &kso5_default
+ &kso6_default
+ &kso7_default
+ &kso8_default
+ &kso9_default
+ &kso10_default
+ &kso11_default
+ &kso12_default>;
+ pinctrl-names = "default";
+};
diff --git a/zephyr/program/nissa/program.conf b/zephyr/program/nissa/program.conf
index e22cbb4c0c..d773f4f690 100644
--- a/zephyr/program/nissa/program.conf
+++ b/zephyr/program/nissa/program.conf
@@ -94,6 +94,9 @@ CONFIG_PLATFORM_EC_USB_PID=0x505a
CONFIG_PLATFORM_EC_USB_PD_USB4=n
CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n
CONFIG_PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY=n
+# TCPC interrupts are shared with BC1.2 and require additional processing
+# to ensure interrupts can't be lost due to shared use.
+CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n
CONFIG_PLATFORM_EC_USB_MUX_RUNTIME_CONFIG=y
# ADL integrated muxes are slow: unblock PD
diff --git a/zephyr/program/nissa/shi.dtsi b/zephyr/program/nissa/shi.dtsi
index 12c0c6ca5b..cf531f7418 100644
--- a/zephyr/program/nissa/shi.dtsi
+++ b/zephyr/program/nissa/shi.dtsi
@@ -5,9 +5,10 @@
#include <ite/it8xxx2-pinctrl-map.dtsi>
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_mosi_gpm0_default &shi_miso_gpm1_default
&shi_clk_gpm4_default &shi_cs_gpm5_default>;
pinctrl-names = "default";
+ cs-gpios = <&gpiom 5 0>; /* unused but needed by dt binding */
};
diff --git a/zephyr/program/nissa/src/common.c b/zephyr/program/nissa/src/common.c
index e03b82bca3..435ef95e29 100644
--- a/zephyr/program/nissa/src/common.c
+++ b/zephyr/program/nissa/src/common.c
@@ -131,3 +131,14 @@ __override void board_hibernate_late(void)
* a small delay, so return.
*/
}
+
+#ifdef CONFIG_OCPC
+__override void board_ocpc_init(struct ocpc_data *ocpc)
+{
+ /* Ensure board has at least 2 charger chips. */
+ if (board_get_charger_chip_count() > 1) {
+ /* There's no provision to measure Isys */
+ ocpc->chg_flags[CHARGER_SECONDARY] |= OCPC_NO_ISYS_MEAS_CAP;
+ }
+}
+#endif
diff --git a/zephyr/program/nissa/xivur/project.conf b/zephyr/program/nissa/xivur/project.conf
index 1cc6230d06..f6e1adf93c 100644
--- a/zephyr/program/nissa/xivur/project.conf
+++ b/zephyr/program/nissa/xivur/project.conf
@@ -4,7 +4,6 @@
CONFIG_BOARD_XIVUR=y
CONFIG_PLATFORM_EC_OCPC=y
-CONFIG_PLATFORM_EC_FAN=y
CONFIG_NISSA_SUB_BOARD=n
# Battery Configuration
diff --git a/zephyr/program/nissa/yaviks/fan.dtsi b/zephyr/program/nissa/yaviks/fan.dtsi
index 24e551f43b..6a3fc0288a 100644
--- a/zephyr/program/nissa/yaviks/fan.dtsi
+++ b/zephyr/program/nissa/yaviks/fan.dtsi
@@ -23,33 +23,33 @@
rpm_target = <0>;
};
level_1 {
- temp_on = <45 48 0>;
- temp_off = <34 45 99>;
+ temp_on = <46 48 0>;
+ temp_off = <40 45 99>;
rpm_target = <2600>;
};
level_2 {
- temp_on = <47 49 0>;
- temp_off = <41 46 99>;
+ temp_on = <49 49 0>;
+ temp_off = <44 46 99>;
rpm_target = <2800>;
};
level_3 {
- temp_on = <49 50 54>;
- temp_off = <44 47 51>;
+ temp_on = <53 50 54>;
+ temp_off = <47 47 51>;
rpm_target = <3100>;
};
level_4 {
- temp_on = <50 56 60>;
- temp_off = <46 48 52>;
+ temp_on = <56 56 60>;
+ temp_off = <51 48 52>;
rpm_target = <3300>;
};
level_5 {
- temp_on = <52 60 64>;
- temp_off = <48 52 56>;
+ temp_on = <60 60 64>;
+ temp_off = <54 52 56>;
rpm_target = <3600>;
};
level_6 {
temp_on = <100 100 100>;
- temp_off = <49 54 58>;
+ temp_off = <58 54 58>;
rpm_target = <4000>;
};
};
diff --git a/zephyr/program/nissa/yaviks/gpio.dtsi b/zephyr/program/nissa/yaviks/gpio.dtsi
index 1ce123b42f..d063b897d9 100644
--- a/zephyr/program/nissa/yaviks/gpio.dtsi
+++ b/zephyr/program/nissa/yaviks/gpio.dtsi
@@ -209,6 +209,10 @@
gpio_c0_charger_led_amber_l: c0_charger_led_amber_l {
gpios = <&gpioj 7 GPIO_OUTPUT_HIGH>;
};
+ gpio_ec_kso_02_inv: ec_kso_02_inv {
+ gpios = <&gpioksol 2 GPIO_OUTPUT_HIGH>;
+ enum-name = "GPIO_KBD_KSO2";
+ };
};
named-i2c-ports {
diff --git a/zephyr/program/nissa/yaviks/keyboard.dtsi b/zephyr/program/nissa/yaviks/keyboard.dtsi
index 04a620767a..87d7d718fa 100644
--- a/zephyr/program/nissa/yaviks/keyboard.dtsi
+++ b/zephyr/program/nissa/yaviks/keyboard.dtsi
@@ -20,3 +20,53 @@
pinctrl-0 = <&pwm0_gpa0_default>;
pinctrl-names = "default";
};
+
+&cros_kb_raw {
+ status = "okay";
+ /* No KSO2 (it's inverted and implemented by GPIO) */
+ pinctrl-0 = <&ksi0_default
+ &ksi1_default
+ &ksi2_default
+ &ksi3_default
+ &ksi4_default
+ &ksi5_default
+ &ksi6_default
+ &ksi7_default
+ &kso0_default
+ &kso1_default
+ &kso3_default
+ &kso4_default
+ &kso5_default
+ &kso6_default
+ &kso7_default
+ &kso8_default
+ &kso9_default
+ &kso10_default
+ &kso11_default
+ &kso12_default
+ &kso13_default
+ &kso14_default>;
+ pinctrl-1 = <&ksi0_sleep
+ &ksi1_sleep
+ &ksi2_sleep
+ &ksi3_sleep
+ &ksi4_sleep
+ &ksi5_sleep
+ &ksi6_sleep
+ &ksi7_sleep
+ &kso0_sleep
+ &kso1_sleep
+ &kso3_sleep
+ &kso4_sleep
+ &kso5_sleep
+ &kso6_sleep
+ &kso7_sleep
+ &kso8_sleep
+ &kso9_sleep
+ &kso10_sleep
+ &kso11_sleep
+ &kso12_sleep
+ &kso13_sleep
+ &kso14_sleep>;
+ pinctrl-names = "default", "sleep";
+};
diff --git a/zephyr/program/nissa/yaviks/overlay.dtsi b/zephyr/program/nissa/yaviks/overlay.dtsi
index 00fb132fab..663b538953 100644
--- a/zephyr/program/nissa/yaviks/overlay.dtsi
+++ b/zephyr/program/nissa/yaviks/overlay.dtsi
@@ -213,6 +213,24 @@
};
};
};
+
+ binman {
+ ec-rw {
+ size = <0x50000>;
+ rw-fw {
+ rw-fwid {
+ /* Fix the lcoation of the FWID to the
+ * last 32 bytes of the flash. This
+ * ensures the RW entries in the FMAP
+ * stored in the RO section of flash
+ * are always correct.
+ */
+ offset = <(0x50000 - 32)>;
+ };
+ };
+ };
+ pad-after = <0x50000>;
+ };
};
&thermistor_3V3_51K1_47K_4050B {
diff --git a/zephyr/program/nissa/yaviks/project.conf b/zephyr/program/nissa/yaviks/project.conf
index 4c83972b8c..2e52005cad 100644
--- a/zephyr/program/nissa/yaviks/project.conf
+++ b/zephyr/program/nissa/yaviks/project.conf
@@ -4,6 +4,11 @@
CONFIG_BOARD_YAVIKS=y
+# FW image
+# TODO: Once this configuration is configured with binman's size property
+# by default, it can be removed.
+CONFIG_CROS_EC_RW_SIZE=0x50000
+
# Ensure recovery key combination (esc+refresh+power) is reliable: b/236580049
CONFIG_PLATFORM_EC_KEYBOARD_PWRBTN_ASSERTS_KSI3=y
CONFIG_PLATFORM_EC_KEYBOARD_REFRESH_ROW3=y
@@ -24,6 +29,7 @@ CONFIG_PLATFORM_EC_MAX_SENSOR_FREQ_MILLIHZ=100000
# Keyboard
CONFIG_PLATFORM_EC_KEYBOARD_KEYPAD=y
CONFIG_PLATFORM_EC_KBLIGHT_ENABLE_PIN=n
+CONFIG_PLATFORM_EC_KEYBOARD_FACTORY_TEST=y
# Fan
CONFIG_PLATFORM_EC_CUSTOM_FAN_CONTROL=y
diff --git a/zephyr/program/nissa/yaviks/src/keyboard.c b/zephyr/program/nissa/yaviks/src/keyboard.c
index 54f8750e98..22fa2df996 100644
--- a/zephyr/program/nissa/yaviks/src/keyboard.c
+++ b/zephyr/program/nissa/yaviks/src/keyboard.c
@@ -4,6 +4,7 @@
*/
#include "cros_cbi.h"
#include "ec_commands.h"
+#include "gpio_it8xxx2.h"
#include "hooks.h"
#include "keyboard_8042_sharedlib.h"
#include "keyboard_scan.h"
@@ -104,3 +105,21 @@ static void kb_layout_init(void)
set_scancode_set2(4, 0, get_scancode_set2(2, 7));
}
DECLARE_HOOK(HOOK_INIT, kb_layout_init, HOOK_PRIO_POST_FIRST);
+
+/*
+ * Map keyboard connector pins to EC GPIO pins for factory test.
+ * Pins mapped to {-1, -1} are skipped.
+ * The connector has 30 pins total, and there is no pin 0.
+ */
+const int keyboard_factory_scan_pins[][2] = {
+ { -1, -1 }, { GPIO_KSOH, 4 }, { GPIO_KSOH, 0 }, { GPIO_KSOH, 1 },
+ { GPIO_KSOH, 3 }, { GPIO_KSOH, 2 }, { -1, -1 }, { -1, -1 },
+ { GPIO_KSOL, 5 }, { GPIO_KSOL, 6 }, { -1, -1 }, { GPIO_KSOL, 3 },
+ { GPIO_KSOL, 2 }, { GPIO_KSI, 0 }, { GPIO_KSOL, 1 }, { GPIO_KSOL, 4 },
+ { GPIO_KSI, 3 }, { GPIO_KSI, 2 }, { GPIO_KSOL, 0 }, { GPIO_KSI, 5 },
+ { GPIO_KSI, 4 }, { GPIO_KSOL, 7 }, { GPIO_KSI, 6 }, { GPIO_KSI, 7 },
+ { GPIO_KSI, 1 }, { -1, -1 }, { GPIO_KSOH, 5 }, { -1, -1 },
+ { GPIO_KSOH, 6 }, { -1, -1 }, { -1, -1 },
+};
+const int keyboard_factory_scan_pins_used =
+ ARRAY_SIZE(keyboard_factory_scan_pins);
diff --git a/zephyr/program/rex/interrupts.dtsi b/zephyr/program/rex/interrupts.dtsi
index a4532c3e95..f8cd156720 100644
--- a/zephyr/program/rex/interrupts.dtsi
+++ b/zephyr/program/rex/interrupts.dtsi
@@ -27,11 +27,6 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "sbu_fault_interrupt";
};
- int_usb_c0_tcpc: usb_c0_tcpc {
- irq-pin = <&gpio_usb_c0_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_ppc: usb_c0_ppc {
irq-pin = <&gpio_usb_c0_ppc_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
@@ -42,11 +37,6 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "bc12_interrupt";
};
- int_usb_c1_tcpc: usb_c1_tcpc {
- irq-pin = <&gpio_usb_c1_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c1_ppc: usb_c1_ppc {
irq-pin = <&gpio_usb_c1_ppc_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
@@ -87,4 +77,3 @@
/* Required node label that doesn't is named differently on Rex */
gpio_ec_pch_wake_odl: &gpio_ec_soc_wake_r_odl {};
-
diff --git a/zephyr/program/rex/rex.dtsi b/zephyr/program/rex/rex.dtsi
index 3c3df257ea..0bb7bebced 100644
--- a/zephyr/program/rex/rex.dtsi
+++ b/zephyr/program/rex/rex.dtsi
@@ -115,7 +115,11 @@
gpio-dev = <&nct3807_C0>;
reg = <0x70>;
tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>;
- int-pin = <&gpio_usb_c0_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
nct3807_C0: nct3807_C0@70 {
@@ -207,7 +211,11 @@
TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V |
TCPC_FLAGS_CONTROL_VCONN |
TCPC_FLAGS_CONTROL_FRS)>;
- int-pin = <&gpio_usb_c1_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
};
};
diff --git a/zephyr/program/rex/src/usbc_config.c b/zephyr/program/rex/src/usbc_config.c
index 795ffc4db4..0401b6892b 100644
--- a/zephyr/program/rex/src/usbc_config.c
+++ b/zephyr/program/rex/src/usbc_config.c
@@ -48,10 +48,6 @@ static void usbc_interrupt_init(void)
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_ppc));
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_ppc));
- /* Enable TCPC interrupts. */
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_tcpc));
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_tcpc));
-
/* Enable BC 1.2 interrupts */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_bc12));
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_bc12));
diff --git a/zephyr/program/skyrim/crystaldrift/CMakeLists.txt b/zephyr/program/skyrim/crystaldrift/CMakeLists.txt
index 6e50c3d40e..f097c85c9b 100644
--- a/zephyr/program/skyrim/crystaldrift/CMakeLists.txt
+++ b/zephyr/program/skyrim/crystaldrift/CMakeLists.txt
@@ -8,5 +8,6 @@ zephyr_library_sources(
"src/ppc_config.c"
"src/form_factor.c"
"src/alt_charger.c"
+ "src/keyboard.c"
)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "src/fan.c")
diff --git a/zephyr/program/skyrim/crystaldrift/project.overlay b/zephyr/program/skyrim/crystaldrift/project.overlay
index ba4d5ea549..e39c18c5a6 100644
--- a/zephyr/program/skyrim/crystaldrift/project.overlay
+++ b/zephyr/program/skyrim/crystaldrift/project.overlay
@@ -21,11 +21,8 @@
/ {
/* battery overrides */
batteries {
- default_battery: aec_5477109 {
- compatible = "aec,5477109", "battery-smart";
- };
- smp_l20m3pg1 {
- compatible = "smp,l20m3pg1", "battery-smart";
+ default_battery: bms-gf_cr50 {
+ compatible = "bms-gf,cr50", "battery-smart";
};
};
@@ -168,4 +165,14 @@
/* i2c overrides */
&i2c0_0 {
/delete-node/ nx20p348x@71;
+ /delete-node/ anx7483@3e;
+};
+&amd_fp6_port0 {
+ board-set = "board_c0_amd_fp6_mux_set";
+};
+/* usbc overrides */
+&usbc_port0 {
+ usb-mux-chain-0 {
+ usb-muxes = <&amd_fp6_port0>;
+ };
};
diff --git a/zephyr/program/skyrim/crystaldrift/src/alt_charger.c b/zephyr/program/skyrim/crystaldrift/src/alt_charger.c
index a429457136..83e827ca5f 100644
--- a/zephyr/program/skyrim/crystaldrift/src/alt_charger.c
+++ b/zephyr/program/skyrim/crystaldrift/src/alt_charger.c
@@ -12,9 +12,15 @@
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
+#ifdef CONFIG_ZTEST
+#undef CHG_ENABLE_ALTERNATE
+void chg_enable_alternate_test(int port);
+#define CHG_ENABLE_ALTERNATE(x) chg_enable_alternate_test(x)
+#endif /* CONFIG_ZTEST */
+
LOG_MODULE_DECLARE(crystaldrift, CONFIG_SKYRIM_LOG_LEVEL);
-static void alt_charger_init(void)
+test_export_static void alt_charger_init(void)
{
int ret;
uint32_t val;
diff --git a/zephyr/program/skyrim/crystaldrift/src/fan.c b/zephyr/program/skyrim/crystaldrift/src/fan.c
index 6645e2a495..21f9d66daa 100644
--- a/zephyr/program/skyrim/crystaldrift/src/fan.c
+++ b/zephyr/program/skyrim/crystaldrift/src/fan.c
@@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(crystaldrift, CONFIG_SKYRIM_LOG_LEVEL);
/*
* Skyrim fan support
*/
-static void fan_init(void)
+test_export_static void fan_init(void)
{
int ret;
uint32_t val;
diff --git a/zephyr/program/skyrim/crystaldrift/src/keyboard.c b/zephyr/program/skyrim/crystaldrift/src/keyboard.c
new file mode 100644
index 0000000000..fafdd40c0a
--- /dev/null
+++ b/zephyr/program/skyrim/crystaldrift/src/keyboard.c
@@ -0,0 +1,29 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ec_commands.h"
+
+static const struct ec_response_keybd_config skyrim_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 &skyrim_kb;
+}
diff --git a/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c b/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c
index 0e08431360..9b6d5f9462 100644
--- a/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c
+++ b/zephyr/program/skyrim/crystaldrift/src/usb_mux_config.c
@@ -48,12 +48,12 @@ static int ioex_set_flip(int port, mux_state_t mux_state)
return EC_SUCCESS;
}
-int board_anx7483_c0_mux_set(const struct usb_mux *me, mux_state_t mux_state)
+int board_c0_amd_fp6_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
/* Set the SBU polarity mux */
RETURN_ERROR(ioex_set_flip(me->usb_port, mux_state));
- return anx7483_set_default_tuning(me, mux_state);
+ return EC_SUCCESS;
}
int board_anx7483_c1_mux_set(const struct usb_mux *me, mux_state_t mux_state)
diff --git a/zephyr/program/skyrim/frostflow/project.conf b/zephyr/program/skyrim/frostflow/project.conf
index 072cb8ddd0..7f06ff2ca4 100644
--- a/zephyr/program/skyrim/frostflow/project.conf
+++ b/zephyr/program/skyrim/frostflow/project.conf
@@ -6,8 +6,6 @@
CONFIG_BOARD_FROSTFLOW=y
CONFIG_PLATFORM_EC_CHARGER_INPUT_CURRENT_DERATE_PCT=10
-# TODO(b/215404321): Remove later in board development
-CONFIG_PLATFORM_EC_EEPROM_CBI_WP=y
CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=n
# Frostflow is capable of sinking 45W
diff --git a/zephyr/program/skyrim/frostflow/project.overlay b/zephyr/program/skyrim/frostflow/project.overlay
index f43c789ce0..55aa7b69fa 100644
--- a/zephyr/program/skyrim/frostflow/project.overlay
+++ b/zephyr/program/skyrim/frostflow/project.overlay
@@ -76,33 +76,38 @@
fan_steps_clamshell: fan-steps-clamshell {
compatible = "cros-ec,fan-steps";
level_0 {
- temp_on = <(-1) (-1) (-1) (-1) 31>;
- temp_off = <(-1) (-1) (-1) (-1) 99>;
+ temp_on = <(-1) 37 (-1) (-1) (-1)>;
+ temp_off = <(-1) 99 (-1) (-1) (-1)>;
rpm_target = <0>;
};
level_1 {
- temp_on = <(-1) (-1) (-1) (-1) 32>;
- temp_off = <(-1) (-1) (-1) (-1) 30>;
+ temp_on = <(-1) 38 (-1) (-1) (-1)>;
+ temp_off = <(-1) 36 (-1) (-1) (-1)>;
rpm_target = <2600>;
};
level_2 {
- temp_on = <(-1) (-1) (-1) (-1) 34>;
- temp_off = <(-1) (-1) (-1) (-1) 31>;
- rpm_target = <2900>;
+ temp_on = <(-1) 42 (-1) (-1) (-1)>;
+ temp_off = <(-1) 37 (-1) (-1) (-1)>;
+ rpm_target = <3200>;
};
level_3 {
- temp_on = <(-1) (-1) (-1) (-1) 36>;
- temp_off = <(-1) (-1) (-1) (-1) 33>;
- rpm_target = <3600>;
+ temp_on = <(-1) 44 (-1) (-1) (-1)>;
+ temp_off = <(-1) 41 (-1) (-1) (-1)>;
+ rpm_target = <3500>;
};
level_4 {
- temp_on = <(-1) (-1) (-1) (-1) 38>;
- temp_off = <(-1) (-1) (-1) (-1) 35>;
- rpm_target = <4200>;
+ temp_on = <(-1) 47 (-1) (-1) (-1)>;
+ temp_off = <(-1) 43 (-1) (-1) (-1)>;
+ rpm_target = <3700>;
};
level_5 {
- temp_on = <(-1) (-1) (-1) (-1) 45>;
- temp_off = <(-1) (-1) (-1) (-1) 37>;
+ temp_on = <(-1) 50 (-1) (-1) (-1)>;
+ temp_off = <(-1) 46 (-1) (-1) (-1)>;
+ rpm_target = <4200>;
+ };
+ level_6 {
+ temp_on = <(-1) 56 (-1) (-1) (-1)>;
+ temp_off = <(-1) 49 (-1) (-1) (-1)>;
rpm_target = <4600>;
};
};
@@ -110,33 +115,38 @@
fan_steps_tablet: fan-steps-tablet {
compatible = "cros-ec,fan-steps";
level_0 {
- temp_on = <(-1) (-1) (-1) (-1) 31>;
- temp_off = <(-1) (-1) (-1) (-1) 99>;
+ temp_on = <(-1) 38 (-1) (-1) (-1)>;
+ temp_off = <(-1) 99 (-1) (-1) (-1)>;
rpm_target = <0>;
};
level_1 {
- temp_on = <(-1) (-1) (-1) (-1) 32>;
- temp_off = <(-1) (-1) (-1) (-1) 30>;
+ temp_on = <(-1) 39 (-1) (-1) (-1)>;
+ temp_off = <(-1) 37 (-1) (-1) (-1)>;
rpm_target = <2600>;
};
level_2 {
- temp_on = <(-1) (-1) (-1) (-1) 34>;
- temp_off = <(-1) (-1) (-1) (-1) 31>;
- rpm_target = <2900>;
+ temp_on = <(-1) 45 (-1) (-1) (-1)>;
+ temp_off = <(-1) 38 (-1) (-1) (-1)>;
+ rpm_target = <3200>;
};
level_3 {
- temp_on = <(-1) (-1) (-1) (-1) 36>;
- temp_off = <(-1) (-1) (-1) (-1) 33>;
- rpm_target = <3600>;
+ temp_on = <(-1) 48 (-1) (-1) (-1)>;
+ temp_off = <(-1) 44 (-1) (-1) (-1)>;
+ rpm_target = <3500>;
};
level_4 {
- temp_on = <(-1) (-1) (-1) (-1) 38>;
- temp_off = <(-1) (-1) (-1) (-1) 35>;
- rpm_target = <4200>;
+ temp_on = <(-1) 50 (-1) (-1) (-1)>;
+ temp_off = <(-1) 47 (-1) (-1) (-1)>;
+ rpm_target = <3700>;
};
level_5 {
- temp_on = <(-1) (-1) (-1) (-1) 45>;
- temp_off = <(-1) (-1) (-1) (-1) 37>;
+ temp_on = <(-1) 53 (-1) (-1) (-1)>;
+ temp_off = <(-1) 49 (-1) (-1) (-1)>;
+ rpm_target = <4200>;
+ };
+ level_6 {
+ temp_on = <(-1) 58 (-1) (-1) (-1)>;
+ temp_off = <(-1) 52 (-1) (-1) (-1)>;
rpm_target = <4600>;
};
};
@@ -280,4 +290,5 @@
rpm_min = <2400>;
rpm_start = <2600>;
rpm_max = <4600>;
+ rpm_deviation = <2>;
};
diff --git a/zephyr/program/skyrim/frostflow/src/thermal.c b/zephyr/program/skyrim/frostflow/src/thermal.c
index 59110dd35e..101823cc26 100644
--- a/zephyr/program/skyrim/frostflow/src/thermal.c
+++ b/zephyr/program/skyrim/frostflow/src/thermal.c
@@ -12,7 +12,7 @@
#include "thermal.h"
#include "util.h"
-#define TEMP_AMB TEMP_SENSOR_ID(DT_NODELABEL(temp_amb))
+#define TEMP_MEM TEMP_SENSOR_ID(DT_NODELABEL(temp_sensor_memory))
struct fan_step {
/*
@@ -68,17 +68,17 @@ int fan_table_to_rpm(int fan, int *temp)
* 3. invariant path. (return the current RPM)
*/
- if (temp[TEMP_AMB] < prev_tmp[TEMP_AMB]) {
+ if (temp[TEMP_MEM] < prev_tmp[TEMP_MEM]) {
for (i = current_level; i > 0; i--) {
- if (temp[TEMP_AMB] < fan_step_table[i].off[TEMP_AMB])
+ if (temp[TEMP_MEM] <= fan_step_table[i].off[TEMP_MEM])
current_level = i - 1;
else
break;
}
- } else if (temp[TEMP_AMB] > prev_tmp[TEMP_AMB]) {
+ } else if (temp[TEMP_MEM] > prev_tmp[TEMP_MEM]) {
for (i = current_level; i < NUM_FAN_LEVELS; i++) {
- if (temp[TEMP_AMB] > fan_step_table[i].on[TEMP_AMB])
- current_level = i + 1;
+ if (temp[TEMP_MEM] >= fan_step_table[i].on[TEMP_MEM])
+ current_level = i;
else
break;
}
diff --git a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c
index 2ec1dda0be..f2c5bd2444 100644
--- a/zephyr/program/skyrim/frostflow/src/usb_mux_config.c
+++ b/zephyr/program/skyrim/frostflow/src/usb_mux_config.c
@@ -5,12 +5,26 @@
/* Frostflow board-specific USB-C mux configuration */
+#include "chipset.h"
+#include "common.h"
+#include "console.h"
+#include "driver/retimer/ps8811.h"
+#include "hooks.h"
+#include "i2c.h"
#include "ioexpander.h"
+#include "timer.h"
+#include "usb_mux.h"
#include "usbc/usb_muxes.h"
+#include "util.h"
#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ##args)
#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ##args)
+struct ps8811_reg_val {
+ uint8_t reg;
+ uint16_t val;
+};
+
/*
* USB C0 (general) and C1 (just ps8815 DB) use IOEX pins to
* indicate flipped polarity to a protection switch.
@@ -60,3 +74,108 @@ int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state)
return 0;
}
+
+const static struct ps8811_reg_val equalizer_wwan_table[] = {
+ {
+ /* Set channel A EQ setting */
+ .reg = PS8811_REG1_USB_AEQ_LEVEL,
+ .val = (PS8811_AEQ_I2C_LEVEL_UP_13DB
+ << PS8811_AEQ_I2C_LEVEL_UP_SHIFT) |
+ (PS8811_AEQ_PIN_LEVEL_UP_18DB
+ << PS8811_AEQ_PIN_LEVEL_UP_SHIFT),
+ },
+ {
+ /* Set ADE pin setting */
+ .reg = PS8811_REG1_USB_ADE_CONFIG,
+ .val = (PS8811_ADE_PIN_MID_LEVEL_3DB
+ << PS8811_ADE_PIN_MID_LEVEL_SHIFT) |
+ PS8811_AEQ_CONFIG_REG_ENABLE,
+ },
+ {
+ /* Set channel B EQ setting */
+ .reg = PS8811_REG1_USB_BEQ_LEVEL,
+ .val = (PS8811_BEQ_I2C_LEVEL_UP_10P5DB
+ << PS8811_BEQ_I2C_LEVEL_UP_SHIFT) |
+ (PS8811_BEQ_PIN_LEVEL_UP_18DB
+ << PS8811_BEQ_PIN_LEVEL_UP_SHIFT),
+ },
+ {
+ /* Set BDE pin setting */
+ .reg = PS8811_REG1_USB_BDE_CONFIG,
+ .val = (PS8811_BDE_PIN_MID_LEVEL_3DB
+ << PS8811_BDE_PIN_MID_LEVEL_SHIFT) |
+ PS8811_BEQ_CONFIG_REG_ENABLE,
+ },
+};
+
+#define NUM_EQ_WWAN_ARRAY ARRAY_SIZE(equalizer_wwan_table)
+
+const static struct ps8811_reg_val equalizer_wlan_table[] = {
+ {
+ /* Set 50ohm adjust for B channel */
+ .reg = PS8811_REG1_50OHM_ADJUST_CHAN_B,
+ .val = (PS8811_50OHM_ADJUST_CHAN_B_MINUS_14PCT
+ << PS8811_50OHM_ADJUST_CHAN_B_SHIFT),
+ },
+};
+
+#define NUM_EQ_WLAN_ARRAY ARRAY_SIZE(equalizer_wlan_table)
+/* USB-A ports */
+enum usba_port { USBA_PORT_A1, USBA_PORT_COUNT };
+const struct usb_mux usba_ps8811[] = {
+ [USBA_PORT_A1] = {
+ .usb_port = USBA_PORT_A1,
+ .i2c_port = I2C_PORT_NODELABEL(i2c1_0),
+ .i2c_addr_flags = PS8811_I2C_ADDR_FLAGS3,
+ },
+};
+
+static int usba_retimer_init(int port)
+{
+ int rv;
+ int val;
+ int i;
+ const struct usb_mux *me = &usba_ps8811[port];
+
+ rv = ps8811_i2c_read(me, PS8811_REG_PAGE1, PS8811_REG1_USB_BEQ_LEVEL,
+ &val);
+
+ if (rv) {
+ CPRINTSUSB("A1: PS8811 retimer response fail!");
+ return rv;
+ }
+ CPRINTSUSB("A1: PS8811 retimer detected");
+
+ if (chipset_in_state(CHIPSET_STATE_ON)) {
+ /* Set channel A output swing */
+ rv = ps8811_i2c_field_update(me, PS8811_REG_PAGE1,
+ PS8811_REG1_USB_CHAN_A_SWING,
+ PS8811_CHAN_A_SWING_MASK,
+ 0x3 << PS8811_CHAN_A_SWING_SHIFT);
+
+ for (i = 0; i < NUM_EQ_WWAN_ARRAY; i++)
+ rv |= ps8811_i2c_write(me, PS8811_REG_PAGE1,
+ equalizer_wwan_table[i].reg,
+ equalizer_wwan_table[i].val);
+ for (i = 0; i < NUM_EQ_WLAN_ARRAY; i++)
+ rv |= ps8811_i2c_write(me, PS8811_REG_PAGE1,
+ equalizer_wlan_table[i].reg,
+ equalizer_wlan_table[i].val);
+ }
+ return rv;
+}
+
+void baseboard_a1_retimer_setup(void)
+{
+ int i;
+
+ for (i = 0; i < USBA_PORT_COUNT; ++i)
+ usba_retimer_init(i);
+}
+DECLARE_DEFERRED(baseboard_a1_retimer_setup);
+
+void board_chipset_startup(void)
+{
+ hook_call_deferred(&baseboard_a1_retimer_setup_data, 500 * MSEC);
+}
+DECLARE_HOOK(HOOK_INIT, board_chipset_startup, HOOK_PRIO_DEFAULT);
diff --git a/zephyr/program/skyrim/i2c.dtsi b/zephyr/program/skyrim/i2c.dtsi
index 8568ff5f49..c1f3d2d0f6 100644
--- a/zephyr/program/skyrim/i2c.dtsi
+++ b/zephyr/program/skyrim/i2c.dtsi
@@ -84,7 +84,11 @@
reg = <0x70>;
gpio-dev = <&nct3807_C0>;
tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>;
- int-pin = <&gpio_usb_c0_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
nct3807_C0: nct3807_C0@70 {
@@ -159,7 +163,11 @@
reg = <0x70>;
gpio-dev = <&nct3807_C1>;
tcpc-flags = <(TCPC_FLAGS_TCPCI_REV2_0)>;
- int-pin = <&gpio_usb_c1_tcpc_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_tcpc_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioc 7 GPIO_ACTIVE_LOW>;
};
nct3807_C1: nct3807_C1@70 {
diff --git a/zephyr/program/skyrim/interrupts.dtsi b/zephyr/program/skyrim/interrupts.dtsi
index 03af135e8b..0e25a147f7 100644
--- a/zephyr/program/skyrim/interrupts.dtsi
+++ b/zephyr/program/skyrim/interrupts.dtsi
@@ -97,16 +97,6 @@
flags = <GPIO_INT_EDGE_FALLING>;
handler = "sbu_fault_interrupt";
};
- int_usb_c0_tcpc: usb_c0_tcpc {
- irq-pin = <&gpio_usb_c0_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1_tcpc: usb_c1_tcpc {
- irq-pin = <&gpio_usb_c1_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_ppc: usb_c0_ppc {
irq-pin = <&gpio_usb_c0_ppc_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/program/skyrim/markarth/CMakeLists.txt b/zephyr/program/skyrim/markarth/CMakeLists.txt
index 37907d80d4..de0269c5f0 100644
--- a/zephyr/program/skyrim/markarth/CMakeLists.txt
+++ b/zephyr/program/skyrim/markarth/CMakeLists.txt
@@ -10,3 +10,7 @@ zephyr_library_sources(
"src/keyboard.c"
)
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN "src/fan.c")
+zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_KEYBOARD_CUSTOMIZATION
+ "src/keyboard.c"
+ "src/keyboard_customization.c"
+)
diff --git a/zephyr/program/skyrim/markarth/include/keyboard_customization.h b/zephyr/program/skyrim/markarth/include/keyboard_customization.h
new file mode 100644
index 0000000000..8e7e3ee2c1
--- /dev/null
+++ b/zephyr/program/skyrim/markarth/include/keyboard_customization.h
@@ -0,0 +1,80 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Keyboard configuration */
+
+#ifndef __KEYBOARD_CUSTOMIZATION_H
+#define __KEYBOARD_CUSTOMIZATION_H
+
+#define KEYBOARD_MASK_PWRBTN KEYBOARD_ROW_TO_MASK(3)
+
+/*
+ * KEYBOARD_COLS_MAX has the build time column size. It's used to allocate
+ * exact spaces for arrays. Actual keyboard scanning is done using
+ * keyboard_cols, which holds a runtime column size.
+ */
+#ifdef CONFIG_KEYBOARD_CUSTOMIZATION
+#undef KEYBOARD_COLS_MAX
+#undef KEYBOARD_ROWS
+
+#define KEYBOARD_COLS_MAX 13
+#define KEYBOARD_ROWS 8
+#endif
+
+/*
+ * WARNING: Do not directly modify it. You should call keyboard_raw_set_cols,
+ * instead. It checks whether you're eligible or not.
+ */
+extern uint8_t keyboard_cols;
+
+#define KEYBOARD_ROW_TO_MASK(r) (1 << (r))
+
+/* Columns and masks for keys we particularly care about */
+#define KEYBOARD_COL_DOWN 11
+#define KEYBOARD_ROW_DOWN 6
+#define KEYBOARD_MASK_DOWN KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_DOWN)
+#define KEYBOARD_COL_ESC 1
+#define KEYBOARD_ROW_ESC 1
+#define KEYBOARD_MASK_ESC KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_ESC)
+#define KEYBOARD_COL_KEY_H 6
+#define KEYBOARD_ROW_KEY_H 1
+#define KEYBOARD_MASK_KEY_H KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_H)
+#define KEYBOARD_COL_KEY_R 3
+#define KEYBOARD_ROW_KEY_R 7
+#define KEYBOARD_MASK_KEY_R KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_R)
+#define KEYBOARD_COL_LEFT_ALT 10
+#define KEYBOARD_ROW_LEFT_ALT 6
+#define KEYBOARD_MASK_LEFT_ALT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_ALT)
+#define KEYBOARD_COL_REFRESH 2
+#define KEYBOARD_ROW_REFRESH 3
+#define KEYBOARD_MASK_REFRESH KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_REFRESH)
+#define KEYBOARD_COL_RIGHT_ALT 10
+#define KEYBOARD_ROW_RIGHT_ALT 0
+#define KEYBOARD_MASK_RIGHT_ALT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_RIGHT_ALT)
+#define KEYBOARD_DEFAULT_COL_VOL_UP 4
+#define KEYBOARD_DEFAULT_ROW_VOL_UP 0
+#define KEYBOARD_COL_LEFT_CTRL 0
+#define KEYBOARD_ROW_LEFT_CTRL 2
+#define KEYBOARD_MASK_LEFT_CTRL KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_CTRL)
+#define KEYBOARD_COL_RIGHT_CTRL 0
+#define KEYBOARD_ROW_RIGHT_CTRL 4
+#define KEYBOARD_MASK_RIGHT_CTRL KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_RIGHT_CTRL)
+#define KEYBOARD_COL_SEARCH 1
+#define KEYBOARD_ROW_SEARCH 0
+#define KEYBOARD_MASK_SEARCH KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_SEARCH)
+#define KEYBOARD_COL_KEY_0 8
+#define KEYBOARD_ROW_KEY_0 6
+#define KEYBOARD_MASK_KEY_0 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_0)
+#define KEYBOARD_COL_KEY_1 1
+#define KEYBOARD_ROW_KEY_1 6
+#define KEYBOARD_MASK_KEY_1 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_1)
+#define KEYBOARD_COL_KEY_2 4
+#define KEYBOARD_ROW_KEY_2 6
+#define KEYBOARD_MASK_KEY_2 KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_KEY_2)
+#define KEYBOARD_COL_LEFT_SHIFT 7
+#define KEYBOARD_ROW_LEFT_SHIFT 5
+#define KEYBOARD_MASK_LEFT_SHIFT KEYBOARD_ROW_TO_MASK(KEYBOARD_ROW_LEFT_SHIFT)
+
+#endif /* __KEYBOARD_CUSTOMIZATION_H */
diff --git a/zephyr/program/skyrim/markarth/project.conf b/zephyr/program/skyrim/markarth/project.conf
index a3f67befd0..cf6c391ffc 100644
--- a/zephyr/program/skyrim/markarth/project.conf
+++ b/zephyr/program/skyrim/markarth/project.conf
@@ -8,9 +8,9 @@ CONFIG_BOARD_MARKARTH=y
# CBI WP pin present
CONFIG_PLATFORM_EC_EEPROM_CBI_WP=y
-# Markarth is capable of sinking 100W
-CONFIG_PLATFORM_EC_PD_MAX_POWER_MW=100000
-CONFIG_PLATFORM_EC_PD_MAX_CURRENT_MA=5000
+# Markarth is capable of sinking 65W
+CONFIG_PLATFORM_EC_PD_MAX_POWER_MW=65000
+CONFIG_PLATFORM_EC_PD_MAX_CURRENT_MA=3250
CONFIG_PLATFORM_EC_PD_MAX_VOLTAGE_MV=20000
# Battery
@@ -18,3 +18,6 @@ CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y
#Disable BC12
CONFIG_PLATFORM_EC_USB_CHARGER=n
+
+# Keyboard
+CONFIG_PLATFORM_EC_KEYBOARD_CUSTOMIZATION=y
diff --git a/zephyr/program/skyrim/markarth/project.overlay b/zephyr/program/skyrim/markarth/project.overlay
index 4f4ce9fd7a..89c49fa8c1 100644
--- a/zephyr/program/skyrim/markarth/project.overlay
+++ b/zephyr/program/skyrim/markarth/project.overlay
@@ -202,4 +202,30 @@
&i2c_sensor {
/delete-node/ enum-names;
enum-names = "I2C_PORT_THERMAL";
-}; \ No newline at end of file
+};
+
+&cros_kb_raw {
+ status = "okay";
+ 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
+ >;
+};
diff --git a/zephyr/program/skyrim/markarth/src/fan.c b/zephyr/program/skyrim/markarth/src/fan.c
index 182463f846..7dc667a6fc 100644
--- a/zephyr/program/skyrim/markarth/src/fan.c
+++ b/zephyr/program/skyrim/markarth/src/fan.c
@@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(markarth, CONFIG_SKYRIM_LOG_LEVEL);
/*
* Skyrim fan support
*/
-static void fan_init(void)
+test_export_static void fan_init(void)
{
int ret;
uint32_t val;
diff --git a/zephyr/program/skyrim/markarth/src/keyboard.c b/zephyr/program/skyrim/markarth/src/keyboard.c
index db9e5d3b69..9a3baaaebe 100644
--- a/zephyr/program/skyrim/markarth/src/keyboard.c
+++ b/zephyr/program/skyrim/markarth/src/keyboard.c
@@ -4,6 +4,24 @@
*/
#include "ec_commands.h"
+#include "keyboard_scan.h"
+#include "timer.h"
+
+/* Keyboard scan setting */
+__override struct keyboard_scan_config keyscan_config = {
+ /* Increase from 50 us, because KSO_02 passes through the H1. */
+ .output_settle_us = 80,
+ /* Other values should be the same as the default configuration. */
+ .debounce_down_us = 9 * MSEC,
+ .debounce_up_us = 30 * MSEC,
+ .scan_period_us = 3 * MSEC,
+ .min_post_scan_delay_us = 1000,
+ .poll_timeout_us = 100 * MSEC,
+ .actual_key_mask = {
+ 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xa4, 0xff, 0xf7, 0x55, 0xfb, 0xca,
+ },
+};
static const struct ec_response_keybd_config markarth_kb = {
.num_top_row_keys = 10,
@@ -27,3 +45,30 @@ board_vivaldi_keybd_config(void)
{
return &markarth_kb;
}
+
+/*
+ * Row Column info for Top row keys T1 - T10.
+ * on markarth_kb keyboard Row Column is customization
+ * need define row col to mapping matrix layout.
+ */
+__override const struct key {
+ uint8_t row;
+ uint8_t col;
+} vivaldi_keys[] = {
+ { .row = 0, .col = 2 }, /* T1 */
+ { .row = 3, .col = 2 }, /* T2 */
+ { .row = 2, .col = 2 }, /* T3 */
+ { .row = 1, .col = 2 }, /* T4 */
+ { .row = 3, .col = 4 }, /* T5 */
+ { .row = 2, .col = 4 }, /* T6 */
+ { .row = 1, .col = 4 }, /* T7 */
+ { .row = 2, .col = 9 }, /* T8 */
+ { .row = 1, .col = 9 }, /* T9 */
+ { .row = 0, .col = 4 }, /* T10 */
+ { .row = 3, .col = 0 }, /* T11 */
+ { .row = 1, .col = 5 }, /* T12 */
+ { .row = 3, .col = 5 }, /* T13 */
+ { .row = 0, .col = 9 }, /* T14 */
+ { .row = 0, .col = 11 }, /* T15 */
+};
+BUILD_ASSERT(ARRAY_SIZE(vivaldi_keys) == MAX_TOP_ROW_KEYS);
diff --git a/zephyr/program/skyrim/markarth/src/keyboard_customization.c b/zephyr/program/skyrim/markarth/src/keyboard_customization.c
new file mode 100644
index 0000000000..6ba279666f
--- /dev/null
+++ b/zephyr/program/skyrim/markarth/src/keyboard_customization.c
@@ -0,0 +1,83 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "keyboard_customization.h"
+#include "keyboard_protocol.h"
+#include "keyboard_raw.h"
+
+#include <zephyr/drivers/gpio.h>
+
+static uint16_t scancode_set2[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = {
+ { 0x0000, 0x0000, 0x0014, 0x0000, 0xe014, 0x0000, 0x0000, 0x0000 },
+ { 0x0058, 0x0076, 0x000d, 0x000e, 0x001c, 0x001a, 0x0016, 0x0015 },
+ { 0x0005, 0x000c, 0x0004, 0x0006, 0x0023, 0x0021, 0x0026, 0x0024 },
+ { 0x0032, 0x0034, 0x002c, 0x002e, 0x002b, 0x002a, 0x0025, 0x002d },
+ { 0x000a, 0x0083, 0x000b, 0x0003, 0x001b, 0x0022, 0x001e, 0x001d },
+ { 0x0051, 0x0000, 0x005b, 0x0000, 0x0042, 0x0041, 0x003e, 0x0043 },
+ { 0x0031, 0x0033, 0x0035, 0x0036, 0x003b, 0x003a, 0x003d, 0x003c },
+ { 0x0000, 0x0000, 0x0061, 0x0000, 0x0000, 0x0012, 0x0000, 0x0059 },
+ { 0x0055, 0x0052, 0x0054, 0x004e, 0x004c, 0x004a, 0x0045, 0x004d },
+ { 0x0000, 0x0078, 0x0009, 0x0000, 0x004b, 0x0049, 0x0046, 0x0044 },
+ { 0xe011, 0x0000, 0x006a, 0x0000, 0x005d, 0x0000, 0x0011, 0x0000 },
+ { 0x0000, 0x0066, 0x0000, 0x005d, 0x005a, 0x0029, 0xe072, 0xe075 },
+ { 0x0000, 0xe064, 0x0000, 0x0067, 0x0000, 0x0000, 0xe074, 0xe06b },
+};
+
+uint16_t get_scancode_set2(uint8_t row, uint8_t col)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ return scancode_set2[col][row];
+ return 0;
+}
+
+void set_scancode_set2(uint8_t row, uint8_t col, uint16_t val)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ scancode_set2[col][row] = val;
+}
+
+#ifdef CONFIG_KEYBOARD_DEBUG
+static uint8_t keycap_label[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = {
+ { 'c', KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO },
+ { KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { 'q', KLLI_UNKNO, KLLI_UNKNO, KLLI_TAB, '`', '1', KLLI_UNKNO, 'a' },
+ { KLLI_R_ALT, KLLI_L_ALT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { KLLI_UNKNO, KLLI_SPACE, 'e', KLLI_F4, KLLI_SEARC, '3', KLLI_F3,
+ KLLI_UNKNO },
+ { 'x', 'z', KLLI_F2, KLLI_F1, 's', '2', 'w', KLLI_ESC },
+ { 'v', 'b', 'g', 't', '5', '4', 'r', 'f' },
+ { 'm', 'n', 'h', 'y', '6', '7', 'u', 'j' },
+ { '.', KLLI_DOWN, '\\', 'o', KLLI_F10, '9', KLLI_UNKNO, 'l' },
+ { KLLI_R_SHT, KLLI_L_SHT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { ',', KLLI_UNKNO, KLLI_F7, KLLI_F6, KLLI_F5, '8', 'i', 'k' },
+ { KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO, KLLI_F9, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_LEFT, KLLI_UNKNO },
+ { KLLI_R_CTR, KLLI_L_CTR, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO },
+ { '/', KLLI_UP, '-', KLLI_UNKNO, '0', 'p', '[', ';' },
+ { '\'', KLLI_ENTER, KLLI_UNKNO, KLLI_UNKNO, '=', KLLI_B_SPC, ']', 'd' },
+ { KLLI_UNKNO, KLLI_F8, KLLI_RIGHT, KLLI_UNKNO, KLLI_UNKNO, KLLI_UNKNO,
+ KLLI_UNKNO, KLLI_UNKNO },
+};
+
+uint8_t get_keycap_label(uint8_t row, uint8_t col)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ return keycap_label[col][row];
+ return KLLI_UNKNO;
+}
+
+void set_keycap_label(uint8_t row, uint8_t col, uint8_t val)
+{
+ if (col < KEYBOARD_COLS_MAX && row < KEYBOARD_ROWS)
+ keycap_label[col][row] = val;
+}
+#endif
diff --git a/zephyr/program/skyrim/skyrim/src/alt_charger.c b/zephyr/program/skyrim/skyrim/src/alt_charger.c
index 91e5af8426..e6e5076c09 100644
--- a/zephyr/program/skyrim/skyrim/src/alt_charger.c
+++ b/zephyr/program/skyrim/skyrim/src/alt_charger.c
@@ -12,9 +12,15 @@
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
+#ifdef CONFIG_ZTEST
+#undef CHG_ENABLE_ALTERNATE
+void chg_enable_alternate_test(int port);
+#define CHG_ENABLE_ALTERNATE(x) chg_enable_alternate_test(x)
+#endif /* CONFIG_ZTEST */
+
LOG_MODULE_DECLARE(skyrim, CONFIG_SKYRIM_LOG_LEVEL);
-static void alt_charger_init(void)
+test_export_static void alt_charger_init(void)
{
int ret;
uint32_t val;
diff --git a/zephyr/program/skyrim/skyrim/src/fan.c b/zephyr/program/skyrim/skyrim/src/fan.c
index c584022a92..a33a2dc151 100644
--- a/zephyr/program/skyrim/skyrim/src/fan.c
+++ b/zephyr/program/skyrim/skyrim/src/fan.c
@@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(skyrim, CONFIG_SKYRIM_LOG_LEVEL);
/*
* Skyrim fan support
*/
-static void fan_init(void)
+test_export_static void fan_init(void)
{
int ret;
uint32_t val;
diff --git a/zephyr/program/skyrim/src/usbc_config.c b/zephyr/program/skyrim/src/usbc_config.c
index 14502cc670..c8f56c455f 100644
--- a/zephyr/program/skyrim/src/usbc_config.c
+++ b/zephyr/program/skyrim/src/usbc_config.c
@@ -51,10 +51,6 @@ static void usbc_interrupt_init(void)
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_ppc));
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_ppc));
- /* Enable TCPC interrupts. */
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_tcpc));
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_tcpc));
-
#ifdef CONFIG_PLATFORM_EC_USB_CHARGER
/* Enable BC 1.2 interrupts */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_bc12));
diff --git a/zephyr/program/skyrim/winterhold/project.conf b/zephyr/program/skyrim/winterhold/project.conf
index 9938196f0c..dda21dba09 100644
--- a/zephyr/program/skyrim/winterhold/project.conf
+++ b/zephyr/program/skyrim/winterhold/project.conf
@@ -5,10 +5,6 @@
# Winterhold reference-board-specific Kconfig settings.
CONFIG_BOARD_WINTERHOLD=y
-# TODO(b/215404321): Remove later in board development
-CONFIG_PLATFORM_EC_EEPROM_CBI_WP=y
-CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y
-
# Enable charger chip
CONFIG_PLATFORM_EC_CHARGER_ISL9238=y
CONFIG_PLATFORM_EC_CHARGER_ISL9241=n
diff --git a/zephyr/program/skyrim/winterhold/project.overlay b/zephyr/program/skyrim/winterhold/project.overlay
index fbbc1f2b88..447c9587f9 100644
--- a/zephyr/program/skyrim/winterhold/project.overlay
+++ b/zephyr/program/skyrim/winterhold/project.overlay
@@ -59,7 +59,7 @@
temp_host_release_high = <95>;
temp_host_release_halt = <100>;
temp_fan_off = <55>;
- temp_fan_max = <75>;
+ temp_fan_max = <72>;
power-good-pin = <&gpio_pg_pwr_s5>;
sensor = <&soc_pct2075>;
};
@@ -213,8 +213,8 @@
/delete-property/ temp_host_high;
/delete-property/ temp_host_halt;
/delete-property/ temp_host_release_high;
- temp_fan_off = <62>;
- temp_fan_max = <72>;
+ temp_fan_off = <76>;
+ temp_fan_max = <82>;
};
/* handler overrides */
diff --git a/zephyr/program/skyrim/winterhold/src/sensor.c b/zephyr/program/skyrim/winterhold/src/sensor.c
index a0d89e56ce..e609d806b0 100644
--- a/zephyr/program/skyrim/winterhold/src/sensor.c
+++ b/zephyr/program/skyrim/winterhold/src/sensor.c
@@ -24,7 +24,7 @@ void base_accel_interrupt(enum gpio_signal signal)
bmi3xx_interrupt(signal);
else if (val == 1)
lis2dw12_interrupt(signal);
- else if (val == 2) {
+ else if (val >= 2) {
if (fw_val == FW_BASE_BMI323)
bmi3xx_interrupt(signal);
else if (fw_val == FW_BASE_LIS2DW12)
@@ -43,7 +43,7 @@ static void motionsense_init(void)
if (ret == EC_SUCCESS && val < 1) {
MOTIONSENSE_ENABLE_ALTERNATE(alt_base_accel);
- } else if (val == 2) {
+ } else if (val >= 2) {
if (fw_val == FW_BASE_BMI323) {
MOTIONSENSE_ENABLE_ALTERNATE(alt_base_accel);
ccprints("BASE ACCEL is BMI323");
diff --git a/zephyr/program/skyrim/winterhold/src/thermal.c b/zephyr/program/skyrim/winterhold/src/thermal.c
index e2c5e13298..9bbc85333c 100644
--- a/zephyr/program/skyrim/winterhold/src/thermal.c
+++ b/zephyr/program/skyrim/winterhold/src/thermal.c
@@ -25,12 +25,12 @@
#define THERMAL_DESKTOP_LID_OPEN \
{ \
.temp_host = { \
- [EC_TEMP_THRESH_WARN] = C_TO_K(44), \
+ [EC_TEMP_THRESH_WARN] = C_TO_K(43), \
[EC_TEMP_THRESH_HIGH] = C_TO_K(105), \
[EC_TEMP_THRESH_HALT] = C_TO_K(110), \
}, \
.temp_host_release = { \
- [EC_TEMP_THRESH_WARN] = C_TO_K(40), \
+ [EC_TEMP_THRESH_WARN] = C_TO_K(39), \
[EC_TEMP_THRESH_HIGH] = C_TO_K(95), \
[EC_TEMP_THRESH_HALT] = C_TO_K(100), \
}, \
@@ -90,7 +90,7 @@ __maybe_unused static const struct ec_thermal_config thermal_laptop =
[EC_TEMP_THRESH_HALT] = C_TO_K(100), \
}, \
.temp_fan_off = C_TO_K(55), \
- .temp_fan_max = C_TO_K(75), \
+ .temp_fan_max = C_TO_K(72), \
}
__maybe_unused static const struct ec_thermal_config fan_soc_desktop_lid_open =
FAN_SOC_DESKTOP_LID_OPEN;
@@ -109,7 +109,7 @@ __maybe_unused static const struct ec_thermal_config fan_soc_desktop_lid_open =
[EC_TEMP_THRESH_HALT] = C_TO_K(100), \
}, \
.temp_fan_off = C_TO_K(55), \
- .temp_fan_max = C_TO_K(75), \
+ .temp_fan_max = C_TO_K(72), \
}
__maybe_unused static const struct ec_thermal_config fan_soc_desktop_lid_close =
FAN_SOC_DESKTOP_LID_CLOSE;
@@ -128,7 +128,7 @@ __maybe_unused static const struct ec_thermal_config fan_soc_desktop_lid_close =
[EC_TEMP_THRESH_HALT] = C_TO_K(100), \
}, \
.temp_fan_off = C_TO_K(51), \
- .temp_fan_max = C_TO_K(71), \
+ .temp_fan_max = C_TO_K(68), \
}
__maybe_unused static const struct ec_thermal_config fan_soc_laptop =
FAN_SOC_LAPTOP;
@@ -138,7 +138,7 @@ __maybe_unused static const struct ec_thermal_config fan_soc_laptop =
*/
#define FAN_CPU_DESKTOP_LID_OPEN \
{ \
- .temp_fan_off = C_TO_K(62), .temp_fan_max = C_TO_K(72), \
+ .temp_fan_off = C_TO_K(76), .temp_fan_max = C_TO_K(82), \
}
__maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_open =
FAN_CPU_DESKTOP_LID_OPEN;
@@ -148,7 +148,7 @@ __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_open =
*/
#define FAN_CPU_DESKTOP_LID_CLOSE \
{ \
- .temp_fan_off = C_TO_K(62), .temp_fan_max = C_TO_K(72), \
+ .temp_fan_off = C_TO_K(76), .temp_fan_max = C_TO_K(82), \
}
__maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_close =
FAN_CPU_DESKTOP_LID_CLOSE;
@@ -158,7 +158,7 @@ __maybe_unused static const struct ec_thermal_config fan_cpu_desktop_lid_close =
*/
#define FAN_CPU_LAPTOP \
{ \
- .temp_fan_off = C_TO_K(58), .temp_fan_max = C_TO_K(68), \
+ .temp_fan_off = C_TO_K(76), .temp_fan_max = C_TO_K(82), \
}
__maybe_unused static const struct ec_thermal_config fan_cpu_laptop =
FAN_CPU_LAPTOP;
diff --git a/zephyr/program/skyrim/winterhold/src/usb_mux_config.c b/zephyr/program/skyrim/winterhold/src/usb_mux_config.c
index 2d834bcfdf..8a4bf861d1 100644
--- a/zephyr/program/skyrim/winterhold/src/usb_mux_config.c
+++ b/zephyr/program/skyrim/winterhold/src/usb_mux_config.c
@@ -149,7 +149,7 @@ int board_anx7483_c1_mux_set(const struct usb_mux *me, mux_state_t mux_state)
int charger_profile_override(struct charge_state_data *curr)
{
if (chipset_in_state(CHIPSET_STATE_ON)) {
- curr->requested_current = MIN(curr->requested_current, 1000);
+ curr->requested_current = MIN(curr->requested_current, 1152);
}
return 0;
diff --git a/zephyr/program/trogdor/lazor/host_interface_npcx.dts b/zephyr/program/trogdor/lazor/host_interface_npcx.dts
index 14efa3c6b2..b691893854 100644
--- a/zephyr/program/trogdor/lazor/host_interface_npcx.dts
+++ b/zephyr/program/trogdor/lazor/host_interface_npcx.dts
@@ -4,7 +4,7 @@
*/
/* host interface */
-&shi {
+&shi0 {
status = "okay";
pinctrl-0 = <&shi_gp46_47_53_55>;
pinctrl-1 = <&shi_gpio_gp46_47_53_55>;
diff --git a/zephyr/program/trogdor/lazor/i2c.dts b/zephyr/program/trogdor/lazor/i2c.dts
index 8d11d4c90a..595bae59c7 100644
--- a/zephyr/program/trogdor/lazor/i2c.dts
+++ b/zephyr/program/trogdor/lazor/i2c.dts
@@ -76,7 +76,11 @@
compatible = "parade,ps8xxx";
status = "okay";
reg = <0xb>;
- int-pin = <&gpio_usb_c0_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c0_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpioe 0 GPIO_ACTIVE_LOW>;
};
};
@@ -100,7 +104,11 @@
compatible = "parade,ps8xxx";
status = "okay";
reg = <0xb>;
- int-pin = <&gpio_usb_c1_pd_int_odl>;
+ /* a duplicate of the <&gpio_usb_c1_pd_int_odl> node in
+ * "named-gpios". This is the Zephyr preferred style,
+ * the "named-gpios" node will be dealt with at a later date.
+ */
+ irq-gpios = <&gpiof 5 GPIO_ACTIVE_LOW>;
};
};
diff --git a/zephyr/program/trogdor/lazor/interrupts.dts b/zephyr/program/trogdor/lazor/interrupts.dts
index 5c2ed35e90..90e20b8e48 100644
--- a/zephyr/program/trogdor/lazor/interrupts.dts
+++ b/zephyr/program/trogdor/lazor/interrupts.dts
@@ -81,16 +81,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "chipset_warm_reset_interrupt";
};
- int_usb_c0_tcpc: usb_c0_tcpc {
- irq-pin = <&gpio_usb_c0_pd_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1_tcpc: usb_c1_tcpc {
- irq-pin = <&gpio_usb_c1_pd_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_swctl: usb_c0_swctl {
irq-pin = <&gpio_usb_c0_swctl_int_odl>;
flags = <GPIO_INT_EDGE_FALLING>;
diff --git a/zephyr/program/trogdor/lazor/prj.conf b/zephyr/program/trogdor/lazor/prj.conf
index 958c854bd9..9dd83cefe8 100644
--- a/zephyr/program/trogdor/lazor/prj.conf
+++ b/zephyr/program/trogdor/lazor/prj.conf
@@ -78,7 +78,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=y
# USB-C
CONFIG_PLATFORM_EC_USB_PD_USB32_DRD=n
-CONFIG_PLATFORM_EC_USBC_RETIMER_FW_UPDATE=n
CONFIG_PLATFORM_EC_USBC_SS_MUX_DFP_ONLY=y
CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC=y
CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y
diff --git a/zephyr/program/trogdor/lazor/src/usbc_config.c b/zephyr/program/trogdor/lazor/src/usbc_config.c
index 5cb96be7eb..d8cafee7a3 100644
--- a/zephyr/program/trogdor/lazor/src/usbc_config.c
+++ b/zephyr/program/trogdor/lazor/src/usbc_config.c
@@ -176,10 +176,6 @@ void board_tcpc_init(void)
/* Enable PPC interrupts */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_swctl));
- /* Enable TCPC interrupts */
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0_tcpc));
- gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1_tcpc));
-
/*
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
diff --git a/zephyr/shim/chip/CMakeLists.txt b/zephyr/shim/chip/CMakeLists.txt
index 1d58857c11..0236570ddd 100644
--- a/zephyr/shim/chip/CMakeLists.txt
+++ b/zephyr/shim/chip/CMakeLists.txt
@@ -8,5 +8,7 @@ elseif (DEFINED CONFIG_SOC_FAMILY_RISCV_ITE)
add_subdirectory(it8xxx2)
elseif (DEFINED CONFIG_SOC_FAMILY_MEC)
add_subdirectory(mchp)
+elseif (DEFINED CONFIG_SOC_FAMILY_STM32)
+ add_subdirectory(stm32)
endif()
diff --git a/zephyr/shim/chip/it8xxx2/gpio.c b/zephyr/shim/chip/it8xxx2/gpio.c
index 16eb7a3963..78aa504140 100644
--- a/zephyr/shim/chip/it8xxx2/gpio.c
+++ b/zephyr/shim/chip/it8xxx2/gpio.c
@@ -4,6 +4,9 @@
*/
#include "gpio/gpio.h"
+#include "gpio_it8xxx2.h"
+
+#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
@@ -52,3 +55,72 @@ int gpio_config_unused_pins(void)
return 0;
}
+
+int gpio_configure_port_pin(int port, int id, int flags)
+{
+ const struct device *dev;
+
+ /*
+ * Port number mapping to node
+ * 0 gpioa
+ * ... ...
+ * 50 gpioksi
+ * 51 gpioksoh
+ * 52 gpioksol
+ */
+ switch ((enum gpio_port_to_node)port) {
+ case GPIO_A:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioa));
+ break;
+ case GPIO_B:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiob));
+ break;
+ case GPIO_C:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioc));
+ break;
+ case GPIO_D:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiod));
+ break;
+ case GPIO_E:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioe));
+ break;
+ case GPIO_F:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiof));
+ break;
+ case GPIO_G:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiog));
+ break;
+ case GPIO_H:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioh));
+ break;
+ case GPIO_I:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioi));
+ break;
+ case GPIO_J:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioj));
+ break;
+ case GPIO_K:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiok));
+ break;
+ case GPIO_L:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiol));
+ break;
+ case GPIO_M:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpiom));
+ break;
+ case GPIO_KSI:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksi));
+ break;
+ case GPIO_KSOH:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksoh));
+ break;
+ case GPIO_KSOL:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksol));
+ break;
+ default:
+ printk("Error port number %d\n", port);
+ return -EINVAL;
+ }
+
+ return gpio_pin_configure(dev, id, flags);
+}
diff --git a/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h b/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h
new file mode 100644
index 0000000000..7abf9f560a
--- /dev/null
+++ b/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h
@@ -0,0 +1,28 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_GPIO_IT8XXX2_H
+#define __CROS_EC_GPIO_IT8XXX2_H
+
+enum gpio_port_to_node {
+ GPIO_A,
+ GPIO_B,
+ GPIO_C,
+ GPIO_D,
+ GPIO_E,
+ GPIO_F,
+ GPIO_G,
+ GPIO_H,
+ GPIO_I,
+ GPIO_J,
+ GPIO_K,
+ GPIO_L,
+ GPIO_M,
+ GPIO_KSI = 50,
+ GPIO_KSOH = 51,
+ GPIO_KSOL = 52
+};
+
+#endif /* __CROS_EC_GPIO_IT8XXX2_H */
diff --git a/zephyr/shim/chip/it8xxx2/keyboard_raw.c b/zephyr/shim/chip/it8xxx2/keyboard_raw.c
index 5fe99b7efa..442b51a59a 100644
--- a/zephyr/shim/chip/it8xxx2/keyboard_raw.c
+++ b/zephyr/shim/chip/it8xxx2/keyboard_raw.c
@@ -6,6 +6,7 @@
/* Functions needed by keyboard scanner module for Chrome EC */
#include "drivers/cros_kb_raw.h"
+#include "gpio_it8xxx2.h"
#include "keyboard_raw.h"
#include <zephyr/device.h>
@@ -15,13 +16,27 @@
#include <soc.h>
/**
- * Return true if the current value of the given input GPIO port is zero
+ * Return true if the current value of the given gpioksi/gpioksoh/gpioksol
+ * port is zero
*/
int keyboard_raw_is_input_low(int port, int id)
{
- /*
- * TODO: implement for factory testing KSI and KSO pin as GPIO
- * function.
- */
- return 0;
+ const struct device *dev;
+
+ switch ((enum gpio_port_to_node)port) {
+ case GPIO_KSI:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksi));
+ break;
+ case GPIO_KSOH:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksoh));
+ break;
+ case GPIO_KSOL:
+ dev = DEVICE_DT_GET(DT_NODELABEL(gpioksol));
+ break;
+ default:
+ printk("Error port number %d, return 0\n", port);
+ return 0;
+ }
+
+ return (gpio_pin_get_raw(dev, id) == 0);
}
diff --git a/zephyr/shim/chip/npcx/shi.c b/zephyr/shim/chip/npcx/shi.c
index 0cecc2c56e..4e0535b91f 100644
--- a/zephyr/shim/chip/npcx/shi.c
+++ b/zephyr/shim/chip/npcx/shi.c
@@ -21,7 +21,7 @@
LOG_MODULE_REGISTER(shim_cros_shi, LOG_LEVEL_DBG);
-#define SHI_NODE DT_NODELABEL(shi)
+#define SHI_NODE DT_NODELABEL(shi0)
static void shi_enable(void)
{
diff --git a/zephyr/shim/chip/stm32/CMakeLists.txt b/zephyr/shim/chip/stm32/CMakeLists.txt
new file mode 100644
index 0000000000..52787ce656
--- /dev/null
+++ b/zephyr/shim/chip/stm32/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+cros_ec_library_include_directories(include)
diff --git a/zephyr/shim/chip/stm32/include/flash_chip.h b/zephyr/shim/chip/stm32/include/flash_chip.h
new file mode 100644
index 0000000000..cd896eca9a
--- /dev/null
+++ b/zephyr/shim/chip/stm32/include/flash_chip.h
@@ -0,0 +1,22 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_FLASH_CHIP_H
+#define __CROS_EC_FLASH_CHIP_H
+
+/* Minimum write size */
+#define CONFIG_FLASH_WRITE_SIZE \
+ DT_PROP(DT_INST(0, soc_nv_flash), write_block_size)
+
+/* No page mode, so use minimum write size */
+#define CONFIG_FLASH_WRITE_IDEAL_SIZE CONFIG_FLASH_WRITE_SIZE
+
+/* RO image offset inside protected storage (RO part) */
+#define CONFIG_RO_STORAGE_OFF 0x0
+
+/* RW image offset inside writable storage (RW part) */
+#define CONFIG_RW_STORAGE_OFF 0x0
+
+#endif /* __CROS_EC_FLASH_CHIP_H */
diff --git a/zephyr/shim/include/builtin/assert.h b/zephyr/shim/include/builtin/assert.h
index 27dce8f2c4..e5e4a34b21 100644
--- a/zephyr/shim/include/builtin/assert.h
+++ b/zephyr/shim/include/builtin/assert.h
@@ -13,4 +13,9 @@
#define ASSERT __ASSERT_NO_MSG
#define assert __ASSERT_NO_MSG
+/* TODO(b/269175417): This should be handled in Zephyr __assert.h */
+#ifndef __ASSERT_UNREACHABLE
+#define __ASSERT_UNREACHABLE CODE_UNREACHABLE
+#endif
+
#endif /* __CROS_EC_ASSERT_H */
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 7ecb3b0f13..fd97a9d72a 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -718,6 +718,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE];
#define CONFIG_SMBUS_PEC
#endif
+#undef CONFIG_I2C_NACK_RETRY_COUNT
+#ifdef CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT
+#define CONFIG_I2C_NACK_RETRY_COUNT CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT
+#endif
+
#undef CONFIG_KEYBOARD_PROTOCOL_8042
#ifdef CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_PROTOCOL_8042
@@ -1543,9 +1548,19 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE];
#undef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2
#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT8XXX2
#define CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2
+#if defined(CONFIG_SOC_IT81202_CX) || defined(CONFIG_SOC_IT81302_CX)
+/* CCGCR 04h bit[3,2,1] Rp 3A value is changed to 000b. */
+#define IT8XXX2_USBPD_RP_3A0_VALUE_IS_ZERO
+/*
+ * CCGCR 04h bit[7] is reserved, so we control the power of cc analog module
+ * by CCCSR 05h bit[7,3].
+ */
+#define IT8XXX2_USBPD_CCGCR_BIT7_RESERVED
+#else
/* Individual setting CC1 and CC2 resistance. */
#define IT83XX_USBPD_CC1_CC2_RESISTANCE_SEPARATE
#endif
+#endif
#undef CONFIG_USB_PD_TCPM_DRIVER_IT83XX
#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT83XX
@@ -1722,6 +1737,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE];
#define CONFIG_USB_PD_ALT_MODE_UFP
#endif
+#undef CONFIG_USB_PD_DISCOVERY
+#ifdef CONFIG_PLATFORM_EC_USB_PD_DISCOVERY
+#define CONFIG_USB_PD_DISCOVERY
+#endif
+
#undef CONFIG_USB_PD_DPS
#ifdef CONFIG_PLATFORM_EC_USB_PD_DPS
#define CONFIG_USB_PD_DPS
@@ -1988,6 +2008,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE];
#define CONFIG_CMD_USB_PD_CABLE
#endif
+#undef CONFIG_USB_PD_DP_MODE
+#ifdef CONFIG_PLATFORM_EC_USB_PD_DP_MODE
+#define CONFIG_USB_PD_DP_MODE
+#endif
+
#undef CONFIG_USB_PD_TBT_COMPAT_MODE
#ifdef CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE
#define CONFIG_USB_PD_TBT_COMPAT_MODE
diff --git a/zephyr/shim/include/ec_tasks.h b/zephyr/shim/include/ec_tasks.h
index 793beb25ae..2b65b4f056 100644
--- a/zephyr/shim/include/ec_tasks.h
+++ b/zephyr/shim/include/ec_tasks.h
@@ -6,9 +6,27 @@
#ifndef __CROS_EC_EC_TASKS_H
#define __CROS_EC_EC_TASKS_H
+#include "task.h"
+
+#include <zephyr/kernel.h>
+
/** Starts all of the shimmed EC tasks. Requires CONFIG_SHIMMED_TASKS=y. */
void start_ec_tasks(void);
+/**
+ * Maps an EC task id to a Zephyr thread id.
+ *
+ * @returns Thread id OR NULL if mapping fails
+ */
+k_tid_t task_id_to_thread_id(task_id_t task_id);
+
+/**
+ * Maps a Zephyr thread id to an EC task id.
+ *
+ * @returns Task id OR TASK_ID_INVALID if mapping fails
+ */
+task_id_t thread_id_to_task_id(k_tid_t thread_id);
+
#ifdef TEST_BUILD
/**
* Set TASK_ID_TEST_RUNNER to current thread tid. Some functions that are tested
diff --git a/zephyr/shim/include/shimmed_task_id.h b/zephyr/shim/include/shimmed_task_id.h
index a0295ad764..4cccd51b73 100644
--- a/zephyr/shim/include/shimmed_task_id.h
+++ b/zephyr/shim/include/shimmed_task_id.h
@@ -213,7 +213,6 @@ enum {
#define CROS_EC_TASK(name, ...) TASK_ID_##name,
#define TASK_TEST(name, ...) CROS_EC_TASK(name)
enum {
- TASK_ID_IDLE = -1, /* We don't shim the idle task */
CROS_EC_TASK_LIST
#ifdef TEST_BUILD
TASK_ID_TEST_RUNNER,
@@ -226,11 +225,16 @@ enum {
/*
* Additional task IDs for features that runs on non shimmed threads,
- * task_get_current() needs to be updated to identify these ones.
+ * thread_id_to_task_id() and task_id_to_thread_id() need to be updated
+ * to identify these tasks.
*/
+/* clang-format off */
#define CROS_EC_EXTRA_TASKS(fn) \
- COND_CODE_1(CONFIG_TASK_HOSTCMD_THREAD_MAIN, (fn(HOSTCMD)), ()) \
- fn(SYSWORKQ)
+ COND_CODE_1(CONFIG_TASK_HOSTCMD_THREAD_MAIN, (fn(HOSTCMD)), \
+ (fn(MAIN))) \
+ fn(SYSWORKQ) \
+ fn(IDLE)
+/* clang-format on */
#define EXTRA_TASK_INTERNAL_ID(name) EXTRA_TASK_##name,
enum {
diff --git a/zephyr/shim/include/shimmed_tasks.h b/zephyr/shim/include/shimmed_tasks.h
index 75be968f4a..7a55531180 100644
--- a/zephyr/shim/include/shimmed_tasks.h
+++ b/zephyr/shim/include/shimmed_tasks.h
@@ -47,4 +47,12 @@
#define HAS_TASK_USB_MUX 1
#endif /* CONFIG_PLATFORM_EC_USB_MUX_TASK */
+#ifndef CONFIG_TASK_HOSTCMD_THREAD_MAIN
+#define HAS_TASK_MAIN 1
+#endif /* CONFIG_TASK_HOSTCMD_THREAD_DEDICATED */
+
+/* These non-shimmed (extra) tasks are always present */
+#define HAS_TASK_IDLE 1
+#define HAS_TASK_SYSWORKQ 1
+
#endif /* __CROS_EC_SHIMMED_TASKS_H */
diff --git a/zephyr/shim/include/usbc/tcpc_anx7447.h b/zephyr/shim/include/usbc/tcpc_anx7447.h
index 38fcd536a5..53312cd0ea 100644
--- a/zephyr/shim/include/usbc/tcpc_anx7447.h
+++ b/zephyr/shim/include/usbc/tcpc_anx7447.h
@@ -18,7 +18,5 @@
}, \
.drv = &anx7447_tcpm_drv, \
.flags = DT_PROP(id, tcpc_flags), \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \
},
diff --git a/zephyr/shim/include/usbc/tcpc_anx7447_emul.h b/zephyr/shim/include/usbc/tcpc_anx7447_emul.h
index 900ca6f48e..be39ee36d9 100644
--- a/zephyr/shim/include/usbc/tcpc_anx7447_emul.h
+++ b/zephyr/shim/include/usbc/tcpc_anx7447_emul.h
@@ -17,7 +17,5 @@
.addr_flags = DT_REG_ADDR(id), \
}, \
.drv = &anx7447_tcpm_drv, \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \
- (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \
- (GPIO_LIMIT)), \
+ .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \
},
diff --git a/zephyr/shim/include/usbc/tcpc_ccgxxf.h b/zephyr/shim/include/usbc/tcpc_ccgxxf.h
index 731ffcbc80..d28033e053 100644
--- a/zephyr/shim/include/usbc/tcpc_ccgxxf.h
+++ b/zephyr/shim/include/usbc/tcpc_ccgxxf.h
@@ -18,7 +18,10 @@
}, \
.drv = &ccgxxf_tcpm_drv, \
.flags = TCPC_FLAGS_TCPCI_REV2_0, \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT)))), \
},
diff --git a/zephyr/shim/include/usbc/tcpc_fusb302.h b/zephyr/shim/include/usbc/tcpc_fusb302.h
index 2a7e684564..6989dbd21e 100644
--- a/zephyr/shim/include/usbc/tcpc_fusb302.h
+++ b/zephyr/shim/include/usbc/tcpc_fusb302.h
@@ -4,6 +4,7 @@
*/
#include "driver/tcpm/fusb302.h"
+#include "usbc/utils.h"
#include <zephyr/devicetree.h>
@@ -17,7 +18,13 @@
.addr_flags = DT_REG_ADDR(id), \
}, \
.drv = &fusb302_tcpm_drv, \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT)))), \
},
+
+DT_FOREACH_STATUS_OKAY(FUSB302_TCPC_COMPAT,
+ TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH)
diff --git a/zephyr/shim/include/usbc/tcpc_generic_emul.h b/zephyr/shim/include/usbc/tcpc_generic_emul.h
index 9d2216cb6e..95905b6818 100644
--- a/zephyr/shim/include/usbc/tcpc_generic_emul.h
+++ b/zephyr/shim/include/usbc/tcpc_generic_emul.h
@@ -17,7 +17,10 @@
.addr_flags = DT_REG_ADDR(id), \
}, \
.drv = &tcpci_tcpm_drv, \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \
- (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT)))), \
},
diff --git a/zephyr/shim/include/usbc/tcpc_nct38xx.h b/zephyr/shim/include/usbc/tcpc_nct38xx.h
index f34fc75863..797993750c 100644
--- a/zephyr/shim/include/usbc/tcpc_nct38xx.h
+++ b/zephyr/shim/include/usbc/tcpc_nct38xx.h
@@ -21,9 +21,12 @@
}, \
.drv = &nct38xx_tcpm_drv, \
.flags = DT_PROP(id, tcpc_flags), \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT)))), \
},
/**
diff --git a/zephyr/shim/include/usbc/tcpc_ps8xxx.h b/zephyr/shim/include/usbc/tcpc_ps8xxx.h
index 1caab08a5d..621d4ab016 100644
--- a/zephyr/shim/include/usbc/tcpc_ps8xxx.h
+++ b/zephyr/shim/include/usbc/tcpc_ps8xxx.h
@@ -4,6 +4,7 @@
*/
#include "driver/tcpm/ps8xxx_public.h"
+#include "usbc/utils.h"
#include <zephyr/devicetree.h>
@@ -18,7 +19,13 @@
}, \
.drv = &ps8xxx_tcpm_drv, \
.flags = DT_PROP(id, tcpc_flags), \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT))) \
+ ), \
},
+
+DT_FOREACH_STATUS_OKAY(PS8XXX_COMPAT, TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH)
diff --git a/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h b/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h
index fa294802dc..09a31b9598 100644
--- a/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h
+++ b/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h
@@ -17,7 +17,10 @@
.addr_flags = DT_REG_ADDR(id), \
}, \
.drv = &ps8xxx_tcpm_drv, \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \
- (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \
- (GPIO_LIMIT)), \
+ COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \
+ (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \
+ (.alert_signal = COND_CODE_1( \
+ DT_NODE_HAS_PROP(id, int_pin), \
+ (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
+ (GPIO_LIMIT)))), \
},
diff --git a/zephyr/shim/include/usbc/tcpc_rt1718s.h b/zephyr/shim/include/usbc/tcpc_rt1718s.h
index 20d75482a3..489e00a144 100644
--- a/zephyr/shim/include/usbc/tcpc_rt1718s.h
+++ b/zephyr/shim/include/usbc/tcpc_rt1718s.h
@@ -4,6 +4,7 @@
*/
#include "tcpm/rt1718s_public.h"
+#include "usbc/utils.h"
#include <zephyr/devicetree.h>
@@ -18,7 +19,8 @@
}, \
.drv = &rt1718s_tcpm_drv, \
.flags = DT_PROP(id, tcpc_flags), \
- .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \
- (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \
- (GPIO_LIMIT)), \
+ .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \
},
+
+DT_FOREACH_STATUS_OKAY(RT1718S_TCPC_COMPAT,
+ TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH)
diff --git a/zephyr/shim/include/usbc/utils.h b/zephyr/shim/include/usbc/utils.h
index 53e9a34856..72a2173463 100644
--- a/zephyr/shim/include/usbc/utils.h
+++ b/zephyr/shim/include/usbc/utils.h
@@ -36,4 +36,16 @@
*/
#define USBC_PORT_FROM_INST(inst) USBC_PORT(DT_DRV_INST(inst))
+/*
+ * Check that the TCPC interrupt flag defined in the devicetree is the same as
+ * the hardware.
+ *
+ * @param id: node id of the tcpc port
+ */
+#define TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH(id) \
+ BUILD_ASSERT( \
+ (DT_PROP(id, tcpc_flags) & TCPC_FLAGS_ALERT_ACTIVE_HIGH) == 0, \
+ "TCPC interrupt configuration error for " DT_NODE_FULL_NAME( \
+ id));
+
#endif /* __CROS_EC_ZEPHYR_SHIM_USBC_UTIL */
diff --git a/zephyr/shim/include/zephyr_hooks_shim.h b/zephyr/shim/include/zephyr_hooks_shim.h
index f1c25c6e8f..3e0c43088f 100644
--- a/zephyr/shim/include/zephyr_hooks_shim.h
+++ b/zephyr/shim/include/zephyr_hooks_shim.h
@@ -55,7 +55,7 @@ struct zephyr_shim_hook_list {
* See include/hooks.h for documentation.
*/
#define DECLARE_HOOK(_hooktype, _routine, _priority) \
- STRUCT_SECTION_ITERABLE_ALTERNATE( \
+ static const STRUCT_SECTION_ITERABLE_ALTERNATE( \
zephyr_shim_hook_##_hooktype, zephyr_shim_hook_info, \
_cros_hook_##_hooktype##_##_routine) = { \
.routine = _routine, \
diff --git a/zephyr/shim/include/zephyr_host_command.h b/zephyr/shim/include/zephyr_host_command.h
index 9271c6c368..844f9ae395 100644
--- a/zephyr/shim/include/zephyr_host_command.h
+++ b/zephyr/shim/include/zephyr_host_command.h
@@ -13,6 +13,7 @@
#include <stdbool.h>
#include <zephyr/init.h>
+#include <zephyr/kernel.h>
/* Initializes and runs the host command handler loop. */
void host_command_task(void *u);
@@ -20,19 +21,29 @@ void host_command_task(void *u);
/* Takes over the main thread and runs the host command loop. */
void host_command_main(void);
-/* True if running in the main thread. */
-bool in_host_command_main(void);
+/*
+ * Returns the main thread id. Will be the same as the HOSTCMD thread
+ * when CONFIG_TASK_HOSTCMD_THREAD_MAIN is enabled.
+ */
+k_tid_t get_main_thread(void);
+
+/*
+ * Returns the HOSTCMD thread id. Will be different than the main thread
+ * when CONFIG_TASK_HOSTCMD_THREAD_DEDICATED is enabled.
+ */
+k_tid_t get_hostcmd_thread(void);
#ifdef CONFIG_PLATFORM_EC_HOSTCMD
/**
* See include/host_command.h for documentation.
*/
-#define DECLARE_HOST_COMMAND(_command, _routine, _version_mask) \
- STRUCT_SECTION_ITERABLE(host_command, _cros_hcmd_##_command) = { \
- .command = _command, \
- .handler = _routine, \
- .version_mask = _version_mask, \
+#define DECLARE_HOST_COMMAND(_command, _routine, _version_mask) \
+ static const STRUCT_SECTION_ITERABLE(host_command, \
+ _cros_hcmd_##_command) = { \
+ .command = _command, \
+ .handler = _routine, \
+ .version_mask = _version_mask, \
}
#else /* !CONFIG_PLATFORM_EC_HOSTCMD */
diff --git a/zephyr/shim/include/zephyr_mkbp_event.h b/zephyr/shim/include/zephyr_mkbp_event.h
index b8cb88029d..0221be81d4 100644
--- a/zephyr/shim/include/zephyr_mkbp_event.h
+++ b/zephyr/shim/include/zephyr_mkbp_event.h
@@ -15,8 +15,9 @@ zephyr_find_mkbp_event_source(uint8_t event_type);
/**
* See include/mkbp_event.h for documentation.
*/
-#define DECLARE_EVENT_SOURCE(_type, _func) \
- STRUCT_SECTION_ITERABLE(mkbp_event_source, _cros_evtsrc_##_func) = { \
- .event_type = _type, \
- .get_data = _func, \
+#define DECLARE_EVENT_SOURCE(_type, _func) \
+ static const STRUCT_SECTION_ITERABLE(mkbp_event_source, \
+ _cros_evtsrc_##_func) = { \
+ .event_type = _type, \
+ .get_data = _func, \
}
diff --git a/zephyr/shim/src/host_command.c b/zephyr/shim/src/host_command.c
index 16f5ae66d8..5ca84c944a 100644
--- a/zephyr/shim/src/host_command.c
+++ b/zephyr/shim/src/host_command.c
@@ -19,18 +19,10 @@ struct host_command *zephyr_find_host_command(int command)
return NULL;
}
-/* Pointer to the main thread, defined in kernel/init.c */
-extern struct k_thread z_main_thread;
-
void host_command_main(void)
{
- k_thread_priority_set(&z_main_thread,
+ k_thread_priority_set(get_main_thread(),
EC_TASK_PRIORITY(EC_TASK_HOSTCMD_PRIO));
- k_thread_name_set(&z_main_thread, "HOSTCMD");
+ k_thread_name_set(get_main_thread(), "HOSTCMD");
host_command_task(NULL);
}
-
-bool in_host_command_main(void)
-{
- return (k_current_get() == &z_main_thread);
-}
diff --git a/zephyr/shim/src/panic.c b/zephyr/shim/src/panic.c
index 1a9d7478e4..2e9068078b 100644
--- a/zephyr/shim/src/panic.c
+++ b/zephyr/shim/src/panic.c
@@ -3,8 +3,8 @@
* found in the LICENSE file.
*/
+#include "builtin/assert.h"
#include "common.h"
-#include "host_command.h"
#include "panic.h"
#include "system_safe_mode.h"
@@ -151,9 +151,6 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
LOG_PANIC();
- if (IS_ENABLED(CONFIG_HOSTCMD_EVENTS))
- host_set_single_event(EC_HOST_EVENT_PANIC);
-
/* Start system safe mode if possible */
if (IS_ENABLED(CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE)) {
if (reason != K_ERR_KERNEL_PANIC &&
@@ -173,9 +170,7 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
* the watchdog will overwrite this panic.
*/
panic_reboot();
-#ifndef TEST_BUILD
- CODE_UNREACHABLE;
-#endif
+ __ASSERT_UNREACHABLE;
}
void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception)
diff --git a/zephyr/shim/src/rtc.c b/zephyr/shim/src/rtc.c
index 3acf6a3bb6..6e694d48e4 100644
--- a/zephyr/shim/src/rtc.c
+++ b/zephyr/shim/src/rtc.c
@@ -95,7 +95,13 @@ void system_set_rtc_alarm(uint32_t seconds, uint32_t microseconds)
return;
}
- seconds += system_get_rtc_sec();
+ /*
+ * Adding 1 additional second because system_get_rtc_sec
+ * returns the number of seconds truncated to the nearest
+ * integer. This results in missed alarms if the actual
+ * value is 7.99 seconds and 7 seconds is returned.
+ */
+ seconds += system_get_rtc_sec() + 1;
cros_rtc_set_alarm(cros_rtc_dev, seconds, microseconds);
}
diff --git a/zephyr/shim/src/tasks.c b/zephyr/shim/src/tasks.c
index 68ebbbc482..d283671f98 100644
--- a/zephyr/shim/src/tasks.c
+++ b/zephyr/shim/src/tasks.c
@@ -4,6 +4,7 @@
*/
#include "common.h"
+#include "ec_tasks.h"
#include "host_command.h"
#include "task.h"
#include "timer.h"
@@ -78,25 +79,114 @@ static struct task_ctx_base_data *task_get_base_data(task_id_t cros_task_id)
return &shimmed_tasks_data[cros_task_id];
}
-task_id_t task_get_current(void)
+test_export_static k_tid_t get_idle_thread(void)
+{
+ extern struct k_thread z_idle_threads[];
+
+ if (!IS_ENABLED(CONFIG_SMP)) {
+ return &z_idle_threads[0];
+ }
+ __ASSERT(false, "%s does not support SMP", __func__);
+ return NULL;
+}
+
+test_export_static k_tid_t get_sysworkq_thread(void)
+{
+ return &k_sys_work_q.thread;
+}
+
+k_tid_t get_main_thread(void)
+{
+ /* Pointer to the main thread, defined in kernel/init.c */
+ extern struct k_thread z_main_thread;
+
+ return &z_main_thread;
+}
+
+test_mockable k_tid_t get_hostcmd_thread(void)
+{
+#if IS_ENABLED(HAS_TASK_HOSTCMD)
+ if (IS_ENABLED(CONFIG_TASK_HOSTCMD_THREAD_MAIN)) {
+ return get_main_thread();
+ }
+ return task_to_k_tid[TASK_ID_HOSTCMD];
+#endif /* HAS_TASK_HOSTCMD */
+ __ASSERT(false, "HOSTCMD task is not enabled");
+ return NULL;
+}
+
+k_tid_t task_id_to_thread_id(task_id_t task_id)
+{
+ if (task_id < 0) {
+ __ASSERT(false, "Invalid task id %d", task_id);
+ return NULL;
+ }
+ if (task_id < TASK_ID_COUNT) {
+ return task_to_k_tid[task_id];
+ }
+ if (task_id < TASK_ID_COUNT + EXTRA_TASK_COUNT) {
+ switch (task_id) {
+ case TASK_ID_SYSWORKQ:
+ return get_sysworkq_thread();
+
+#if IS_ENABLED(HAS_TASK_HOSTCMD)
+ case TASK_ID_HOSTCMD:
+ return get_hostcmd_thread();
+#endif /* HAS_TASK_HOSTCMD */
+
+#if IS_ENABLED(HAS_TASK_MAIN)
+ case TASK_ID_MAIN:
+ return get_main_thread();
+#endif /* HAS_TASK_MAIN */
+
+ case TASK_ID_IDLE:
+ return get_idle_thread();
+ }
+ }
+ __ASSERT(false, "Failed to map task %d to thread", task_id);
+ return NULL;
+}
+
+task_id_t thread_id_to_task_id(k_tid_t thread_id)
{
- if (in_deferred_context()) {
+ if (thread_id == NULL) {
+ __ASSERT(false, "Invalid thread_id");
+ return TASK_ID_INVALID;
+ }
+
+ if (get_sysworkq_thread() == thread_id) {
return TASK_ID_SYSWORKQ;
}
-#ifdef CONFIG_TASK_HOSTCMD_THREAD_MAIN
- if (in_host_command_main()) {
+#if IS_ENABLED(HAS_TASK_HOSTCMD)
+ if (get_hostcmd_thread() == thread_id) {
return TASK_ID_HOSTCMD;
}
-#endif
+#endif /* HAS_TASK_HOSTCMD */
+
+#if IS_ENABLED(HAS_TASK_MAIN)
+ if (get_main_thread() == thread_id) {
+ return TASK_ID_MAIN;
+ }
+#endif /* HAS_TASK_MAIN */
+
+ if (get_idle_thread() == thread_id) {
+ return TASK_ID_IDLE;
+ }
for (size_t i = 0; i < TASK_ID_COUNT; ++i) {
- if (task_to_k_tid[i] == k_current_get())
+ if (task_to_k_tid[i] == thread_id) {
return i;
+ }
}
- __ASSERT(false, "Task index out of bound");
- return 0;
+ __ASSERT(false, "Failed to map thread to task");
+ return TASK_ID_INVALID;
+}
+
+task_id_t task_get_current(void)
+{
+ return thread_id_to_task_id(k_current_get());
}
atomic_t *task_get_event_bitmap(task_id_t cros_task_id)
@@ -349,5 +439,5 @@ inline bool in_deferred_context(void)
/*
* Deferred calls run in the sysworkq.
*/
- return (k_current_get() == &k_sys_work_q.thread);
+ return (k_current_get() == get_sysworkq_thread());
}
diff --git a/zephyr/shim/src/tcpc.c b/zephyr/shim/src/tcpc.c
index c4682fce85..98a3cd880b 100644
--- a/zephyr/shim/src/tcpc.c
+++ b/zephyr/shim/src/tcpc.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "hooks.h"
#include "usb_pd.h"
#include "usb_pd_tcpm.h"
#include "usbc/tcpc_anx7447.h"
@@ -20,8 +21,11 @@
#include "usbc/utils.h"
#include <zephyr/devicetree.h>
+#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
+LOG_MODULE_REGISTER(tcpc, CONFIG_GPIO_LOG_LEVEL);
+
#define HAS_TCPC_PROP(usbc_id) \
COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, tcpc), (|| 1), ())
@@ -77,14 +81,86 @@
MAYBE_CONST struct tcpc_config_t tcpc_config[] = { DT_FOREACH_STATUS_OKAY(
named_usbc_port, TCPC_CHIP) };
+#ifdef CONFIG_PLATFORM_EC_TCPC_INTERRUPT
+
+BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == CONFIG_USB_PD_PORT_MAX_COUNT);
+
+struct gpio_callback int_gpio_cb[CONFIG_USB_PD_PORT_MAX_COUNT];
+
+static void tcpc_int_gpio_callback(const struct device *dev,
+ struct gpio_callback *cb, uint32_t pins)
+{
+ /*
+ * Retrieve the array index from the callback pointer, and
+ * use that to get the port number.
+ */
+ int port = cb - &int_gpio_cb[0];
+
+ schedule_deferred_pd_interrupt(port);
+}
+
+/*
+ * Enable all tcpc interrupts from devicetree bindings.
+ * Check whether the callback is already installed, and if
+ * not, init and add the callback before enabling the
+ * interrupt.
+ */
+void tcpc_enable_interrupt(void)
+{
+ gpio_flags_t flags;
+
+ for (int i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ /*
+ * Check whether the interrupt pin has been configured
+ * by the devicetree.
+ */
+ if (!tcpc_config[i].irq_gpio.port)
+ continue;
+ /*
+ * Check whether the gpio pin is ready
+ */
+ if (!gpio_is_ready_dt(&tcpc_config[i].irq_gpio)) {
+ LOG_ERR("tcpc port #%i interrupt not ready.", i);
+ return;
+ }
+ /*
+ * TODO(b/267537103): Once named-gpios support is dropped,
+ * evaluate if this code should call gpio_pin_configure_dt()
+ *
+ * Check whether callback has been initialised
+ */
+ if (!int_gpio_cb[i].handler) {
+ /*
+ * Initialise and add the callback.
+ */
+ gpio_init_callback(&int_gpio_cb[i],
+ tcpc_int_gpio_callback,
+ BIT(tcpc_config[i].irq_gpio.pin));
+ gpio_add_callback(tcpc_config[i].irq_gpio.port,
+ &int_gpio_cb[i]);
+ }
+ flags = tcpc_config[i].flags & TCPC_FLAGS_ALERT_ACTIVE_HIGH ?
+ GPIO_INT_EDGE_RISING :
+ GPIO_INT_EDGE_FALLING;
+ flags = (flags | GPIO_INT_ENABLE) & ~GPIO_INT_DISABLE;
+ gpio_pin_interrupt_configure_dt(&tcpc_config[i].irq_gpio,
+ flags);
+ }
+}
+/*
+ * priority set to POST_I2C + 1 so projects can make local edits to
+ * tcpc_config as needed at POST_I2C before the interrupts are enabled.
+ */
+DECLARE_HOOK(HOOK_INIT, tcpc_enable_interrupt, HOOK_PRIO_POST_I2C + 1);
+
+#else /* CONFIG_PLATFORM_EC_TCPC_INTERRUPT */
+
/* TCPC GPIO Interrupt Handlers */
void tcpc_alert_event(enum gpio_signal signal)
{
for (int i = 0; i < ARRAY_SIZE(tcpc_config); i++) {
- /* No alerts for embedded TCPC */
/* No alerts if the alert pin is not set in the devicetree */
- if (tcpc_config[i].bus_type == EC_BUS_TYPE_EMBEDDED ||
- tcpc_config[i].alert_signal == GPIO_LIMIT) {
+ if (tcpc_config[i].alert_signal == GPIO_LIMIT) {
continue;
}
@@ -95,4 +171,5 @@ void tcpc_alert_event(enum gpio_signal signal)
}
}
+#endif /* CONFIG_PLATFORM_EC_TCPC_INTERRUPT */
#endif /* DT_HAS_COMPAT_STATUS_OKAY */
diff --git a/zephyr/subsys/ap_pwrseq/CMakeLists.txt b/zephyr/subsys/ap_pwrseq/CMakeLists.txt
index e4b4ad1df9..a3f183f02b 100644
--- a/zephyr/subsys/ap_pwrseq/CMakeLists.txt
+++ b/zephyr/subsys/ap_pwrseq/CMakeLists.txt
@@ -14,6 +14,9 @@ zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_SIGNAL_GPIO signal_gpio.c)
zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_SIGNAL_VW signal_vw.c)
zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_SIGNAL_ADC signal_adc.c)
+zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_DRIVER ap_pwrseq.c)
+zephyr_library_sources_ifdef(CONFIG_AP_PWRSEQ_DRIVER ap_pwrseq_sm.c)
+
zephyr_library_sources_ifdef(CONFIG_X86_NON_DSX_PWRSEQ
x86_non_dsx_common_pwrseq_sm_handler.c
x86_non_dsx_chipset_power_state.c)
diff --git a/zephyr/subsys/ap_pwrseq/Kconfig b/zephyr/subsys/ap_pwrseq/Kconfig
index eabb45fab8..32d18e12cb 100644
--- a/zephyr/subsys/ap_pwrseq/Kconfig
+++ b/zephyr/subsys/ap_pwrseq/Kconfig
@@ -23,6 +23,16 @@ module = AP_PWRSEQ
module-str = AP power sequencing
source "subsys/logging/Kconfig.template.log_config"
+config AP_PWRSEQ_DRIVER
+ bool "AP Power sequencing driver support"
+ select SMF
+ select SMF_ANCESTOR_SUPPORT
+ select EVENTS
+ help
+ AP power sequence driver establishes an underlaying framework to
+ easily add or extend AP Power Sequence action handler routines, it is
+ designed to follow the zephyr's State Machine Framework (SMF).
+
config AP_PWRSEQ_SIGNAL_ADC
bool
default y
diff --git a/zephyr/subsys/ap_pwrseq/ap_pwrseq.c b/zephyr/subsys/ap_pwrseq/ap_pwrseq.c
new file mode 100644
index 0000000000..c02ec88363
--- /dev/null
+++ b/zephyr/subsys/ap_pwrseq/ap_pwrseq.c
@@ -0,0 +1,314 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ap_pwrseq_drv_sm.h"
+
+#include <zephyr/kernel.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/sys/atomic.h>
+
+LOG_MODULE_DECLARE(ap_pwrseq, CONFIG_AP_PWRSEQ_LOG_LEVEL);
+
+#define AP_PWRSEQ_EVENT_MASK GENMASK(AP_PWRSEQ_EVENT_COUNT - 1, 0)
+#define AP_PWRSEQ_STATES_MASK GENMASK(AP_POWER_STATE_COUNT - 1, 0)
+
+struct ap_pwrseq_cb_list {
+ uint32_t states;
+ sys_slist_t list;
+ struct k_spinlock lock;
+};
+
+struct ap_pwrseq_data {
+ /* State machine data reference. */
+ void *sm_data;
+ /* Driver event object to receive events posted. */
+ struct k_event evt;
+ /*
+ * This mutex object blocks state machine transitions to prevent race
+ * condition when doing power state related tasks. Must be held when
+ * accessing `sm_data`.
+ */
+ struct k_mutex mux;
+ /* State entry notification list. */
+ struct ap_pwrseq_cb_list entry_list;
+ /* State exit notification list. */
+ struct ap_pwrseq_cb_list exit_list;
+};
+
+/* Resolve into substate name string */
+#define AP_PWRSEQ_SUB_STATE_STR_DEFINE_WITH_COMA(state) state,
+
+#define AP_PWRSEQ_EACH_SUB_STATE_STR_DEFINE(node_id, prop, idx) \
+ AP_PWRSEQ_SUB_STATE_STR_DEFINE_WITH_COMA( \
+ DT_CAT5(node_id, _P_, prop, _IDX_, idx))
+
+#define AP_PWRSEQ_EACH_SUB_STATE_STR_DEF_NODE_CHILD_DEFINE(node_id) \
+ COND_CODE_1( \
+ DT_NODE_HAS_PROP(node_id, application), \
+ (DT_FOREACH_PROP_ELEM(node_id, application, \
+ AP_PWRSEQ_EACH_SUB_STATE_STR_DEFINE)), \
+ (COND_CODE_1(DT_NODE_HAS_PROP(node_id, chipset), \
+ (DT_FOREACH_PROP_ELEM( \
+ node_id, chipset, \
+ AP_PWRSEQ_EACH_SUB_STATE_STR_DEFINE)), \
+ ())))
+
+static const char *const ap_pwrseq_state_str[AP_POWER_STATE_COUNT] = {
+ "AP_POWER_STATE_UNINIT",
+ "AP_POWER_STATE_G3",
+ "AP_POWER_STATE_S5",
+ "AP_POWER_STATE_S4",
+ "AP_POWER_STATE_S3",
+ "AP_POWER_STATE_S2",
+ "AP_POWER_STATE_S1",
+ "AP_POWER_STATE_S0",
+ DT_FOREACH_STATUS_OKAY(
+ ap_pwrseq_sub_states,
+ AP_PWRSEQ_EACH_SUB_STATE_STR_DEF_NODE_CHILD_DEFINE)
+};
+BUILD_ASSERT(ARRAY_SIZE(ap_pwrseq_state_str) == AP_POWER_STATE_COUNT);
+
+static struct ap_pwrseq_data ap_pwrseq_task_data;
+
+static void ap_pwrseq_add_state_callback(struct ap_pwrseq_cb_list *cb_list,
+ sys_snode_t *node)
+{
+ if (!sys_slist_is_empty(&cb_list->list)) {
+ sys_slist_find_and_remove(&cb_list->list, node);
+ }
+
+ sys_slist_prepend(&cb_list->list, node);
+}
+
+static int
+ap_pwrseq_register_state_callback(struct ap_pwrseq_state_callback *state_cb,
+ struct ap_pwrseq_cb_list *cb_list)
+{
+ if (!(state_cb->states_bit_mask & AP_PWRSEQ_STATES_MASK)) {
+ return -EINVAL;
+ }
+
+ __ASSERT(state_cb->cb, "Callback pointer should not be NULL");
+
+ k_spinlock_key_t key = k_spin_lock(&cb_list->lock);
+
+ ap_pwrseq_add_state_callback(cb_list, &state_cb->node);
+
+ cb_list->states |= AP_PWRSEQ_STATES_MASK & state_cb->states_bit_mask;
+ k_spin_unlock(&cb_list->lock, key);
+
+ return 0;
+}
+
+static void ap_pwrseq_send_callback(const struct device *dev,
+ const enum ap_pwrseq_state entry,
+ const enum ap_pwrseq_state exit,
+ bool is_entry)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+ struct ap_pwrseq_cb_list *cb_list = is_entry ? &data->entry_list :
+ &data->exit_list;
+ const enum ap_pwrseq_state *state = is_entry ? &entry : &exit;
+ struct ap_pwrseq_state_callback *state_cb, *tmp;
+
+ if (!(cb_list->states & BIT(*state))) {
+ return;
+ }
+ SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cb_list->list, state_cb, tmp, node)
+ {
+ if (state_cb->states_bit_mask & BIT(*state)) {
+ state_cb->cb(dev, entry, exit);
+ }
+ }
+}
+
+static void ap_pwrseq_send_entry_callback(const struct device *dev,
+ const enum ap_pwrseq_state entry,
+ const enum ap_pwrseq_state exit)
+{
+ ap_pwrseq_send_callback(dev, entry, exit, true);
+}
+
+static void ap_pwrseq_send_exit_callback(const struct device *dev,
+ const enum ap_pwrseq_state entry,
+ const enum ap_pwrseq_state exit)
+{
+ ap_pwrseq_send_callback(dev, entry, exit, false);
+}
+
+static uint32_t ap_pwrseq_wait_event(const struct device *dev)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+ uint32_t events;
+
+ events = k_event_wait(&data->evt, AP_PWRSEQ_EVENT_MASK, false,
+ Z_FOREVER);
+ /* Clear all events posted */
+ k_event_clear(&data->evt, events);
+
+ return events & AP_PWRSEQ_EVENT_MASK;
+}
+
+static void ap_pwrseq_thread(void *arg, void *unused1, void *unused2)
+{
+ struct device *const dev = (struct device *)arg;
+ struct ap_pwrseq_data *const data = dev->data;
+ enum ap_pwrseq_state cur_state, new_state;
+ int run_status;
+ uint32_t events;
+
+ LOG_INF("Power Sequence thread start");
+ while (true) {
+ events = ap_pwrseq_wait_event(dev);
+ if (!events) {
+ continue;
+ }
+ LOG_DBG("Events posted: %0#x", events);
+
+ /**
+ * Process generated events and keep looping while state
+ * transitions are occurring.
+ **/
+ while (true) {
+ ap_pwrseq_state_lock(dev);
+
+ cur_state = ap_pwrseq_sm_get_cur_state(data->sm_data);
+ run_status =
+ ap_pwrseq_sm_run_state(data->sm_data, events);
+ new_state = ap_pwrseq_sm_get_cur_state(data->sm_data);
+
+ ap_pwrseq_state_unlock(dev);
+ if (run_status) {
+ /* Was this terminated? */
+ return;
+ }
+
+ /* Check if state transition took place */
+ if (cur_state == new_state) {
+ break;
+ }
+ LOG_INF("%s -> %s", ap_pwrseq_get_state_str(cur_state),
+ ap_pwrseq_get_state_str(new_state));
+
+ ap_pwrseq_send_exit_callback(dev, new_state, cur_state);
+
+ ap_pwrseq_send_entry_callback(dev, new_state,
+ cur_state);
+ }
+ }
+}
+
+static int ap_pwrseq_driver_init(const struct device *dev);
+
+DEVICE_DEFINE(ap_pwrseq_dev, "ap_pwrseq_drv", ap_pwrseq_driver_init, NULL,
+ &ap_pwrseq_task_data, NULL, APPLICATION,
+ CONFIG_APPLICATION_INIT_PRIORITY, NULL);
+
+K_THREAD_DEFINE(ap_pwrseq_tid, CONFIG_AP_PWRSEQ_STACK_SIZE, ap_pwrseq_thread,
+ DEVICE_GET(ap_pwrseq_dev), NULL, NULL,
+ CONFIG_AP_PWRSEQ_THREAD_PRIORITY, 0, K_TICKS_FOREVER);
+
+static int ap_pwrseq_driver_init(const struct device *dev)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+
+ data->sm_data = ap_pwrseq_sm_get_instance();
+
+ k_mutex_init(&data->mux);
+ k_event_init(&data->evt);
+
+ return 0;
+}
+
+/**
+ * Global functions definition.
+ **/
+const struct device *ap_pwrseq_get_instance(void)
+{
+ return DEVICE_GET(ap_pwrseq_dev);
+}
+
+int ap_pwrseq_start(const struct device *dev, enum ap_pwrseq_state init_state)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+ int ret;
+
+ ap_pwrseq_state_lock(dev);
+ ret = ap_pwrseq_sm_init(data->sm_data, ap_pwrseq_tid, init_state);
+ ap_pwrseq_state_unlock(dev);
+ if (ret) {
+ return ret;
+ }
+
+ k_thread_start(ap_pwrseq_tid);
+
+ return 0;
+}
+
+void ap_pwrseq_post_event(const struct device *dev, enum ap_pwrseq_event event)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+
+ if (event >= AP_PWRSEQ_EVENT_COUNT) {
+ return;
+ }
+
+ LOG_DBG("Posting Event: %0#lx", BIT(event));
+ k_event_post(&data->evt, BIT(event));
+}
+
+enum ap_pwrseq_state ap_pwrseq_get_current_state(const struct device *dev)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+ enum ap_pwrseq_state ret_state;
+
+ ap_pwrseq_state_lock(dev);
+
+ ret_state = ap_pwrseq_sm_get_cur_state(data->sm_data);
+
+ ap_pwrseq_state_unlock(dev);
+
+ return ret_state;
+}
+
+const char *const ap_pwrseq_get_state_str(enum ap_pwrseq_state state)
+{
+ if (state >= AP_POWER_STATE_COUNT) {
+ return NULL;
+ }
+
+ return ap_pwrseq_state_str[state];
+}
+
+int ap_pwrseq_state_lock(const struct device *dev)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+
+ /* Acquire lock to ensure no `run` operation is in progress. */
+ return k_mutex_lock(&data->mux, K_FOREVER);
+}
+
+int ap_pwrseq_state_unlock(const struct device *dev)
+{
+ struct ap_pwrseq_data *const data = dev->data;
+
+ return k_mutex_unlock(&data->mux);
+}
+
+int ap_pwrseq_register_state_entry_callback(
+ const struct device *dev, struct ap_pwrseq_state_callback *state_cb)
+{
+ struct ap_pwrseq_data *data = dev->data;
+
+ return ap_pwrseq_register_state_callback(state_cb, &data->entry_list);
+}
+
+int ap_pwrseq_register_state_exit_callback(
+ const struct device *dev, struct ap_pwrseq_state_callback *state_cb)
+{
+ struct ap_pwrseq_data *data = dev->data;
+
+ return ap_pwrseq_register_state_callback(state_cb, &data->exit_list);
+}
diff --git a/zephyr/subsys/ap_pwrseq/ap_pwrseq_drv_sm.h b/zephyr/subsys/ap_pwrseq/ap_pwrseq_drv_sm.h
new file mode 100644
index 0000000000..b2c71bf20d
--- /dev/null
+++ b/zephyr/subsys/ap_pwrseq/ap_pwrseq_drv_sm.h
@@ -0,0 +1,71 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef _AP_PWRSEQ_INT_SM_H_
+#define _AP_PWRSEQ_INT_SM_H_
+#include "ap_power/ap_pwrseq.h"
+
+#include <zephyr/kernel/thread.h>
+
+/**
+ * This following AP Power Sequence state machine functions are only available
+ * for subsystem driver.
+ **/
+
+/**
+ * @brief Obtain AP power sequence state machine instance.
+ *
+ * @param None.
+ *
+ * @retval Return instance data of the state machine, only one instance is
+ * allowed per application.
+ **/
+void *ap_pwrseq_sm_get_instance(void);
+
+/**
+ * @brief Sets AP power sequence state machine initial state.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @param tid AP power sequence instance thread associated to this state
+ * machine. Functions `ap_pwrseq_sm_set_state` and `ap_pwrseq_sm_run_state` are
+ * meant to be executed only within this thread context.
+ *
+ * @param init_state State machine initial state.
+ *
+ * @retval SUCCESS Upon success, init_state ‘entry’ action handlers on all
+ * implemented levels will be invoked.
+ * @retval -EINVAL State provided is invalid.
+ * @retval -EPERM State machine is already initialized.
+ **/
+int ap_pwrseq_sm_init(void *const data, k_tid_t tid,
+ enum ap_pwrseq_state init_state);
+
+/**
+ * @brief Execute current state `run` action handlers.
+ *
+ * This function is meant to be executed only within AP power sequence driver
+ * thread context. `tid` was given in `ap_pwrseq_sm_init`.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @param events Events to be processed in current `run` iteration.
+ *
+ * @retval SUCCESS Upon success, provided `run` action handlers will be executed
+ * for all levels in current state.
+ * @retval -EINVAL State machine has not been initialized.
+ **/
+int ap_pwrseq_sm_run_state(void *const data, uint32_t events);
+
+/**
+ * @brief Get current state enumeration value.
+ *
+ * @param data Pointer to AP power sequence state machine instance data.
+ *
+ * @retval Enum value Upon success.
+ * @retval AP_POWER_STATE_UNDEF If state machine has not been initialized.
+ **/
+enum ap_pwrseq_state ap_pwrseq_sm_get_cur_state(void *const data);
+#endif /* _AP_PWRSEQ_INT_SM_H_ */
diff --git a/zephyr/subsys/ap_pwrseq/ap_pwrseq_sm.c b/zephyr/subsys/ap_pwrseq/ap_pwrseq_sm.c
new file mode 100644
index 0000000000..538aae8bc7
--- /dev/null
+++ b/zephyr/subsys/ap_pwrseq/ap_pwrseq_sm.c
@@ -0,0 +1,262 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ap_power/ap_pwrseq_sm.h"
+
+#include <zephyr/logging/log.h>
+
+LOG_MODULE_DECLARE(ap_pwrseq, CONFIG_AP_PWRSEQ_LOG_LEVEL);
+
+struct ap_pwrseq_sm_data {
+ /* Zephyr SMF context */
+ struct smf_ctx smf;
+ /* Pointer to array of states structures */
+ const struct ap_pwrseq_smf **states;
+ /* Bitfiled of events */
+ uint32_t events;
+ /* Id of current thread executing state machine */
+ k_tid_t tid;
+ /* State entering during state transition */
+ enum ap_pwrseq_state entry;
+ /* State exiting during state transition */
+ enum ap_pwrseq_state exit;
+ /* Flag to inform if current `run` action has been handled */
+ bool run_handled;
+ /* Flag to inform if current `entry` action has been handled */
+ bool entry_handled;
+ /* Flag to inform if current `exit` action has been handled */
+ bool exit_handled;
+ /* Flag to inform that state transition is in progress */
+ bool in_transition;
+};
+
+/**
+ * Declare weak `struct smf_state` definitions of all ACPI states for
+ * architecture and chipset level. These are used as placeholder to keep AP
+ * power sequence state machine hierarchy in case corresponding state action
+ * handlers are not provided by implementation.
+ **/
+#define AP_POWER_ARCH_STATE_WEAK_DEFINE(name) \
+ const struct smf_state __weak arch_##name##_actions = \
+ SMF_CREATE_STATE(NULL, NULL, NULL, NULL);
+
+#define AP_POWER_CHIPSET_STATE_WEAK_DEFINE(name) \
+ const struct smf_state __weak chipset_##name##_actions = \
+ SMF_CREATE_STATE(NULL, NULL, NULL, &arch_##name##_actions);
+
+/**
+ * Declare weak `struct ap_pwrseq_smf` definitions of all ACPI states for
+ * application level. These are used as placeholder to keep AP
+ * power sequence state machine hierarchy in case corresponding state action
+ * handlers are not provided by implementation.
+ **/
+#define AP_POWER_APP_STATE_WEAK_DEFINE(name) \
+ const struct ap_pwrseq_smf __weak app_state_##name = { \
+ .actions = SMF_CREATE_STATE(NULL, NULL, NULL, \
+ &chipset_##name##_actions), \
+ .state = name \
+ };
+
+#define AP_POWER_STATE_WEAK_DEFINE(name) \
+ AP_POWER_ARCH_STATE_WEAK_DEFINE(name) \
+ AP_POWER_CHIPSET_STATE_WEAK_DEFINE(name) \
+ AP_POWER_APP_STATE_WEAK_DEFINE(name)
+
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_G3)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S5)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S4)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S3)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S2)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S1)
+AP_POWER_STATE_WEAK_DEFINE(AP_POWER_STATE_S0)
+
+#define AP_PWRSEQ_STATE_DEFINE(name) [name] = &app_state_##name
+
+/* Sub States defines */
+#define AP_PWRSEQ_APP_SUB_STATE_DEFINE(state) [state] = &app_state_##state,
+
+#define AP_PWRSEQ_APP_SUB_STATE_DEFINE_(state) \
+ AP_PWRSEQ_APP_SUB_STATE_DEFINE(state)
+
+#define AP_PWRSEQ_EACH_APP_SUB_STATE_NODE_DEFINE__(node_id, prop, idx) \
+ AP_PWRSEQ_APP_SUB_STATE_DEFINE_( \
+ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN))
+
+#define AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE(state) \
+ [state] = &chipset_##state##_actions,
+
+#define AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE_(state) \
+ AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE(state)
+
+#define AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE__(node_id, prop, idx) \
+ AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE_( \
+ DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN))
+
+#define AP_PWRSEQ_EACH_SUB_STATE_NODE_CHILD_DEFINE(node_id) \
+ COND_CODE_1( \
+ DT_NODE_HAS_PROP(node_id, chipset), \
+ (DT_FOREACH_PROP_ELEM( \
+ node_id, chipset, \
+ AP_PWRSEQ_EACH_CHIPSET_SUB_STATE_NODE_DEFINE__)), \
+ (COND_CODE_1( \
+ DT_NODE_HAS_PROP(node_id, application), \
+ (DT_FOREACH_PROP_ELEM( \
+ node_id, application, \
+ AP_PWRSEQ_EACH_APP_SUB_STATE_NODE_DEFINE__)), \
+ ())))
+
+/**
+ * @brief Array containing power state action handlers for all state and
+ * and substates available for AP power sequence state machine, these items
+ * correspond to `enum ap_pwrseq_state`.
+ **/
+static const struct ap_pwrseq_smf *ap_pwrseq_states[AP_POWER_STATE_COUNT] = {
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_G3),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S5),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S4),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S3),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S2),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S1),
+ AP_PWRSEQ_STATE_DEFINE(AP_POWER_STATE_S0),
+ DT_FOREACH_STATUS_OKAY(ap_pwrseq_sub_states,
+ AP_PWRSEQ_EACH_SUB_STATE_NODE_CHILD_DEFINE)
+};
+
+static struct ap_pwrseq_sm_data sm_data_0 = {
+ .states = ap_pwrseq_states,
+};
+
+/* Private functions available only for AP Power Sequence subsystem driver. */
+void *ap_pwrseq_sm_get_instance(void)
+{
+ return &sm_data_0;
+}
+
+int ap_pwrseq_sm_init(void *const data, k_tid_t tid,
+ enum ap_pwrseq_state init_state)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ if (sm_data->smf.current || sm_data->tid) {
+ return -EPERM;
+ }
+
+ if (init_state >= AP_POWER_STATE_COUNT) {
+ return -EINVAL;
+ }
+
+ sm_data->entry = sm_data->exit = AP_POWER_STATE_UNDEF;
+ smf_set_initial(&sm_data->smf,
+ (const struct smf_state *)sm_data->states[init_state]);
+ sm_data->tid = tid;
+
+ return 0;
+}
+
+int ap_pwrseq_sm_run_state(void *const data, uint32_t events)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+ int ret;
+
+ if (sm_data->tid != k_current_get()) {
+ /* Called by wrong thread */
+ return -EPERM;
+ }
+
+ if (sm_data->smf.current == NULL) {
+ return -EINVAL;
+ }
+
+ sm_data->in_transition = false;
+ sm_data->entry = sm_data->exit = AP_POWER_STATE_UNDEF;
+ sm_data->run_handled = false;
+ sm_data->events = events;
+
+ ret = smf_run_state((struct smf_ctx *const)sm_data);
+
+ return ret;
+}
+
+enum ap_pwrseq_state ap_pwrseq_sm_get_cur_state(void *const data)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ if (!sm_data->smf.current) {
+ return AP_POWER_STATE_UNDEF;
+ }
+
+ return ((struct ap_pwrseq_smf *)sm_data->smf.current)->state;
+}
+
+/* Public functions for action handlers implementation. */
+int ap_pwrseq_sm_set_state(void *const data, enum ap_pwrseq_state state)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ if (sm_data->tid != k_current_get()) {
+ /* Called by wrong thread */
+ return -EPERM;
+ }
+
+ if (state >= AP_POWER_STATE_COUNT ||
+ /* Only one state transition is permited within `run` iterations */
+ sm_data->in_transition) {
+ return -EINVAL;
+ }
+
+ /* Transition has started, update corresponding flags */
+ sm_data->in_transition = true;
+ sm_data->entry_handled = sm_data->exit_handled = false;
+ sm_data->entry = state;
+ sm_data->exit = ((struct ap_pwrseq_smf *)sm_data->smf.current)->state;
+ smf_set_state((struct smf_ctx *const)&sm_data->smf,
+ (const struct smf_state *)sm_data->states[state]);
+
+ return 0;
+}
+
+bool ap_pwrseq_sm_is_event_set(void *const data, enum ap_pwrseq_event event)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ return ((sm_data->events & BIT(event)) == BIT(event));
+}
+
+enum ap_pwrseq_state ap_pwrseq_sm_get_entry_state(void *const data)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ if (sm_data->tid != k_current_get()) {
+ /* Called by wrong thread */
+ return -EPERM;
+ }
+
+ return sm_data->entry;
+}
+
+enum ap_pwrseq_state ap_pwrseq_sm_get_exit_state(void *const data)
+{
+ struct ap_pwrseq_sm_data *sm_data = data;
+
+ if (sm_data->tid != k_current_get()) {
+ /* Called by wrong thread */
+ return -EPERM;
+ }
+
+ return sm_data->exit;
+}
+
+#define AP_POWER_SM_HANDLER_DEF(action) \
+ void ap_pwrseq_sm_exec_##action##_handler( \
+ void *const data, ap_pwr_state_action_handler handler) \
+ { \
+ struct ap_pwrseq_sm_data *sm_data = data; \
+ if (handler && !sm_data->action##_handled) \
+ sm_data->action##_handled = !!handler(data); \
+ }
+
+AP_POWER_SM_HANDLER_DEF(entry)
+AP_POWER_SM_HANDLER_DEF(run)
+AP_POWER_SM_HANDLER_DEF(exit)
diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt
index aab3db65e0..96e1126711 100644
--- a/zephyr/test/drivers/CMakeLists.txt
+++ b/zephyr/test/drivers/CMakeLists.txt
@@ -17,6 +17,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_DEFAULT_CONSOLE_CMDS default/src/c
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_ANX7447 anx7447)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_AP_MUX_CONTROL ap_mux_control)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_AP_VDM_CONTROL ap_vdm_control)
+add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_CONSOLE_CMD_CRASH console_cmd_crash)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_COMMON_CBI common_cbi)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_COMMON_CBI_GPIO common_cbi_gpio)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_COMMON_CHARGER common_charger)
@@ -28,7 +29,6 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_IT8XXX2_HW_SHA256 it8xxx2_hw_sha25
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_KEYBOARD_SCAN keyboard_scan)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_LED_DRIVER led_driver)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_MKBP mkbp)
-add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PANIC_EVENT panic_event)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PANIC_OUTPUT panic_output)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_POWER_HOST_SLEEP power_host_sleep)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_RT9490 rt9490)
@@ -63,6 +63,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PI3USB9201 bc12_pi3usb9201)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_MEMMAP memmap)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_LED_COMMON led_common)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_PS8XXX ps8xxx)
+add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_GPIO_UNHOOK gpio_unhook)
get_target_property(TEST_SOURCES_NEW app SOURCES)
diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig
index 321db83508..65c881de1a 100644
--- a/zephyr/test/drivers/Kconfig
+++ b/zephyr/test/drivers/Kconfig
@@ -11,6 +11,9 @@ config LINK_TEST_SUITE_DEFAULT
config LINK_TEST_SUITE_DEFAULT_CONSOLE_CMDS
bool "Link and test the default console commands test suite"
+config LINK_TEST_SUITE_CONSOLE_CMD_CRASH
+ bool "Link and test the console command crash test suite"
+
config LINK_TEST_SUITE_ANX7447
bool "Link and test the anx7447 tests"
@@ -40,6 +43,9 @@ config LINK_TEST_SUITE_FLASH
help
Include the test suite exercising flash-related code in the binary.
+config LINK_TEST_SUITE_GPIO_UNHOOK
+ bool "Link and execute the unhooked gpio tests"
+
config LINK_TEST_SUITE_HOST_COMMANDS
select PLATFORM_EC_CHARGE_STATE_DEBUG
bool "Link and test the host command tests"
@@ -76,9 +82,6 @@ config LINK_TEST_SUITE_LOCATE_CHIP_ALTS
config LINK_TEST_SUITE_MKBP
bool "Link and test the mkbp tests"
-config LINK_TEST_SUITE_PANIC_EVENT
- bool "Link and test the panic_event tests"
-
config LINK_TEST_SUITE_PANIC_OUTPUT
bool "Link and test the panic_output tests"
diff --git a/zephyr/test/drivers/ap_vdm_control/prj.conf b/zephyr/test/drivers/ap_vdm_control/prj.conf
index 685fa4c15d..215a8ab36d 100644
--- a/zephyr/test/drivers/ap_vdm_control/prj.conf
+++ b/zephyr/test/drivers/ap_vdm_control/prj.conf
@@ -5,3 +5,6 @@
CONFIG_PLATFORM_EC_USB_MUX_AP_CONTROL=y
CONFIG_PLATFORM_EC_USB_MUX_TASK=y
CONFIG_PLATFORM_EC_USB_PD_VDM_AP_CONTROL=y
+
+CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n
+CONFIG_PLATFORM_EC_USB_PD_USB4=n
diff --git a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
index 2758b5bc52..897155485c 100644
--- a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
+++ b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
@@ -7,6 +7,7 @@
#include "test/drivers/stubs.h"
#include "test/drivers/test_state.h"
#include "test/drivers/utils.h"
+#include "usb_dp_alt_mode.h"
#include "usb_mux.h"
#include "usb_pd_vdo.h"
@@ -154,6 +155,39 @@ static void verify_vdm_req(struct ap_vdm_control_fixture *fixture,
zassert_true(message_seen, "Expected message not found");
}
+static void verify_no_vdms(struct ap_vdm_control_fixture *fixture)
+{
+ struct tcpci_partner_log_msg *msg;
+
+ /* LCOV_EXCL_START */
+ /*
+ * Code is not expected to be reached, but this check is
+ * written to be tolerant of unrelated messages coming through
+ * during the test run to avoid needlessly brittle test code.
+ */
+ SYS_SLIST_FOR_EACH_CONTAINER(&fixture->partner.msg_log, msg, node)
+ {
+ uint16_t header = sys_get_le16(msg->buf);
+
+ /* Ignore messages from ourselves */
+ if (msg->sender == TCPCI_PARTNER_SENDER_PARTNER)
+ continue;
+
+ /*
+ * Control messages, non-VDMs, and extended messages are not of
+ * interest
+ */
+ if ((PD_HEADER_CNT(header) == 0) ||
+ (PD_HEADER_TYPE(header) != PD_DATA_VENDOR_DEF) ||
+ (PD_HEADER_EXT(header) != 0)) {
+ continue;
+ }
+
+ zassert_unreachable();
+ }
+ /* LCOV_EXCL_STOP */
+}
+
static void *ap_vdm_control_setup(void)
{
static struct ap_vdm_control_fixture fixture;
@@ -765,3 +799,87 @@ ZTEST_F(ap_vdm_control, test_vdm_attention_disconnect_clear)
zassert_equal(vdm_resp.vdm_attention_left, 0,
"Failed to see no more messages");
}
+
+ZTEST_F(ap_vdm_control, test_no_ec_dp_enter)
+{
+ struct ec_params_typec_control params = {
+ .port = TEST_PORT,
+ .command = TYPEC_CONTROL_COMMAND_ENTER_MODE,
+ .mode_to_enter = TYPEC_MODE_DP,
+ };
+ struct host_cmd_handler_args args =
+ BUILD_HOST_COMMAND_PARAMS(EC_CMD_TYPEC_CONTROL, 0, params);
+
+ /*
+ * Confirm that the EC doesn't try to send EnterMode messages for DP on
+ * its own through the EC DPM logic
+ */
+ tcpci_partner_common_enable_pd_logging(&fixture->partner, true);
+ zassert_equal(host_command_process(&args), EC_RES_INVALID_PARAM);
+ k_sleep(K_SECONDS(1));
+
+ tcpci_partner_common_enable_pd_logging(&fixture->partner, false);
+
+ verify_no_vdms(fixture);
+}
+
+ZTEST_F(ap_vdm_control, test_no_ec_dp_exit)
+{
+ /*
+ * Confirm that the EC won't try to exit DP mode on its own through the
+ * EC's DPM logic
+ */
+ run_verify_dp_entry(fixture, 1);
+
+ tcpci_partner_common_enable_pd_logging(&fixture->partner, true);
+ host_cmd_typec_control_exit_modes(TEST_PORT);
+ k_sleep(K_SECONDS(1));
+
+ tcpci_partner_common_enable_pd_logging(&fixture->partner, false);
+
+ verify_no_vdms(fixture);
+}
+
+ZTEST_F(ap_vdm_control, test_dp_stub_returns)
+{
+ int temp;
+ uint32_t data[2];
+
+ /*
+ * Confirm that the DP stubs return what we expect them to without
+ * the EC running its DP module
+ */
+ run_verify_dp_entry(fixture, 1);
+
+ zassert_false(dp_is_active(TEST_PORT));
+ zassert_true(dp_is_idle(TEST_PORT));
+ zassert_false(dp_entry_is_done(TEST_PORT));
+ zassert_equal(dp_setup_next_vdm(TEST_PORT, &temp, data),
+ MSG_SETUP_ERROR);
+}
+
+ZTEST_F(ap_vdm_control, test_no_ec_dp_mode)
+{
+ struct ec_response_typec_status status;
+ struct ec_response_usb_pd_control_v2 legacy_status;
+ struct ec_params_usb_pd_control params = {
+ .port = TEST_PORT,
+ .role = USB_PD_CTRL_ROLE_NO_CHANGE,
+ .mux = USB_PD_CTRL_MUX_NO_CHANGE,
+ .swap = USB_PD_CTRL_SWAP_NONE
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_USB_PD_CONTROL, 2, legacy_status, params);
+
+ /*
+ * Confirm that neither old nor new APIs see the EC selecting a DP pin
+ * mode
+ */
+ run_verify_dp_entry(fixture, 1);
+
+ zassert_ok(host_command_process(&args));
+ zassert_equal(legacy_status.dp_mode, 0);
+
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal(status.dp_pin, 0);
+}
diff --git a/zephyr/test/drivers/boards/native_posix.overlay b/zephyr/test/drivers/boards/native_posix.overlay
index d36f19f15c..f2b41b0df0 100644
--- a/zephyr/test/drivers/boards/native_posix.overlay
+++ b/zephyr/test/drivers/boards/native_posix.overlay
@@ -300,16 +300,6 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "extpower_interrupt";
};
- int_usb_c0: usb_c0 {
- irq-pin = <&usb_c0_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
- int_usb_c1: usb_c1 {
- irq-pin = <&usb_c1_tcpc_int_odl>;
- flags = <GPIO_INT_EDGE_FALLING>;
- handler = "tcpc_alert_event";
- };
int_usb_c0_ppc: usb_c0_ppc {
irq-pin = <&gpio_usb_c0_ppc_int>;
flags = <GPIO_INT_EDGE_FALLING>;
@@ -857,7 +847,7 @@
compatible = "cros,tcpci-generic-emul";
status = "okay";
reg = <0x82>;
- alert_gpio = <&usb_c0_tcpc_int_odl>;
+ irq-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
};
};
@@ -892,7 +882,7 @@
ps8xxx_emul: ps8xxx_emul@b {
compatible = "cros,ps8xxx-emul";
reg = <0xb>;
- alert_gpio = <&usb_c1_tcpc_int_odl>;
+ irq-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
p0-i2c-addr = <0x8>;
p1-i2c-addr = <0x9>;
gpio-i2c-addr = <0x1a>;
diff --git a/zephyr/test/drivers/common/include/test/drivers/utils.h b/zephyr/test/drivers/common/include/test/drivers/utils.h
index 0a811eecd5..98f65bf966 100644
--- a/zephyr/test/drivers/common/include/test/drivers/utils.h
+++ b/zephyr/test/drivers/common/include/test/drivers/utils.h
@@ -493,17 +493,6 @@ int host_cmd_motion_sense_tablet_mode_lid_angle(
*/
void host_cmd_typec_discovery(int port, enum typec_partner_type partner_type,
void *response, size_t response_size);
-/**
- * @brief Run the host command to get the PD alternative mode response.
- *
- * @param port The USB-C port number
- * @param response Destination for command response.
- * @param response_size Destination of response size from request params.
- */
-void host_cmd_usb_pd_get_amode(
- uint8_t port, uint16_t svid_idx,
- struct ec_params_usb_pd_get_mode_response *response,
- int *response_size);
/**
* @brief Run the host command to get the PD chip information.
diff --git a/zephyr/test/drivers/common/src/stubs.c b/zephyr/test/drivers/common/src/stubs.c
index cb0e915017..9943164417 100644
--- a/zephyr/test/drivers/common/src/stubs.c
+++ b/zephyr/test/drivers/common/src/stubs.c
@@ -188,12 +188,14 @@ void ppc_alert(enum gpio_signal signal)
*/
static void stubs_interrupt_init(void)
{
+ cprints(CC_USB, "Resetting TCPCs...");
+ cflush();
+
+#if !(CONFIG_PLATFORM_EC_TCPC_INTERRUPT)
/* Enable TCPC interrupts. */
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c0));
gpio_enable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_usb_c1));
-
- cprints(CC_USB, "Resetting TCPCs...");
- cflush();
+#endif
/* Reset generic TCPCI on port 0. */
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(usb_c0_tcpc_rst_l), 0);
diff --git a/zephyr/test/drivers/common/src/utils.c b/zephyr/test/drivers/common/src/utils.c
index dda855ebba..000348df9e 100644
--- a/zephyr/test/drivers/common/src/utils.c
+++ b/zephyr/test/drivers/common/src/utils.c
@@ -618,23 +618,6 @@ struct ec_response_typec_vdm_response host_cmd_typec_vdm_response(int port)
return response;
}
-void host_cmd_usb_pd_get_amode(
- uint8_t port, uint16_t svid_idx,
- struct ec_params_usb_pd_get_mode_response *response, int *response_size)
-{
- struct ec_params_usb_pd_get_mode_request params = {
- .port = port,
- .svid_idx = svid_idx,
- };
- struct host_cmd_handler_args args =
- BUILD_HOST_COMMAND_PARAMS(EC_CMD_USB_PD_GET_AMODE, 0, params);
- args.response = response;
-
- zassert_ok(host_command_process(&args),
- "Failed to get alternate-mode info for port %d", port);
- *response_size = args.response_size;
-}
-
int host_cmd_usb_pd_dev_info(uint8_t port,
struct ec_params_usb_pd_rw_hash_entry *response)
{
diff --git a/zephyr/test/drivers/console_cmd_crash/CMakeLists.txt b/zephyr/test/drivers/console_cmd_crash/CMakeLists.txt
new file mode 100644
index 0000000000..dc9eea08d0
--- /dev/null
+++ b/zephyr/test/drivers/console_cmd_crash/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+target_sources(app
+ PRIVATE
+ src/crash.c
+) \ No newline at end of file
diff --git a/zephyr/test/drivers/default/src/console_cmd/crash.c b/zephyr/test/drivers/console_cmd_crash/src/crash.c
index 4218aa74d6..4218aa74d6 100644
--- a/zephyr/test/drivers/default/src/console_cmd/crash.c
+++ b/zephyr/test/drivers/console_cmd_crash/src/crash.c
diff --git a/zephyr/test/drivers/default/src/console_cmd/CMakeLists.txt b/zephyr/test/drivers/default/src/console_cmd/CMakeLists.txt
index 7fdabd1c52..b4ed741430 100644
--- a/zephyr/test/drivers/default/src/console_cmd/CMakeLists.txt
+++ b/zephyr/test/drivers/default/src/console_cmd/CMakeLists.txt
@@ -18,7 +18,6 @@ target_sources(app PRIVATE
accelread.c
accelres.c
button.c
- crash.c
cutoff.c
ec_features.c
gpio.c
diff --git a/zephyr/test/drivers/default/src/espi.c b/zephyr/test/drivers/default/src/espi.c
index e526980ef1..d81718d422 100644
--- a/zephyr/test/drivers/default/src/espi.c
+++ b/zephyr/test/drivers/default/src/espi.c
@@ -77,25 +77,6 @@ ZTEST_USER(espi, test_host_command_typec_status)
zassert_equal(args.response_size, sizeof(response));
}
-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));
- zassert_ok(args.result);
- /* 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
- */
- zassert_equal(args.response_size, sizeof(response.svid));
-}
-
ZTEST_USER(espi, test_host_command_gpio_get_v0)
{
struct ec_params_gpio_get p = {
diff --git a/zephyr/test/drivers/default/src/integration/usbc/usb_pd_ctrl_msg.c b/zephyr/test/drivers/default/src/integration/usbc/usb_pd_ctrl_msg.c
index 1d3da4921f..0e5d3eecad 100644
--- a/zephyr/test/drivers/default/src/integration/usbc/usb_pd_ctrl_msg.c
+++ b/zephyr/test/drivers/default/src/integration/usbc/usb_pd_ctrl_msg.c
@@ -213,6 +213,9 @@ ZTEST_F(usb_pd_ctrl_msg_test_sink, verify_pr_swap)
snk_resp = host_cmd_typec_status(TEST_USB_PORT);
zassert_equal(PD_ROLE_SOURCE, snk_resp.power_role,
"SNK Returned power_role=%u", snk_resp.power_role);
+
+ tcpci_partner_common_handler_mask_msg(&super_fixture->partner_emul,
+ PD_CTRL_ACCEPT, false);
}
/**
diff --git a/zephyr/test/drivers/default/src/isl923x.c b/zephyr/test/drivers/default/src/isl923x.c
index 1393466c76..8dbfdf530b 100644
--- a/zephyr/test/drivers/default/src/isl923x.c
+++ b/zephyr/test/drivers/default/src/isl923x.c
@@ -720,6 +720,18 @@ ZTEST(isl923x, test_isl923x_is_acok)
rv = raa489000_is_acok(CHARGER_NUM, &acok);
zassert_equal(EC_SUCCESS, rv, "AC OK check did not return success");
zassert_false(acok, "AC OK is true");
+
+ /*
+ * Charger is sourcing - ACOK is always false,
+ * even if the pin is asserted.
+ */
+ raa489000_emul_set_acok_pin(isl923x_emul, 1);
+ raa489000_emul_set_state_machine_state(isl923x_emul,
+ RAA489000_INFO2_STATE_OTG);
+
+ rv = raa489000_is_acok(CHARGER_NUM, &acok);
+ zassert_equal(EC_SUCCESS, rv, "AC OK check did not return success");
+ zassert_false(acok, "ACOK is true when sourcing, expected false");
}
ZTEST(isl923x, test_isl923x_enable_asgate)
diff --git a/zephyr/test/drivers/flash/src/flash.c b/zephyr/test/drivers/flash/src/flash.c
index 753983cd6c..c0b0d9ef4f 100644
--- a/zephyr/test/drivers/flash/src/flash.c
+++ b/zephyr/test/drivers/flash/src/flash.c
@@ -9,12 +9,14 @@
#include "host_command.h"
#include "system.h"
#include "test/drivers/test_state.h"
+#include "test/drivers/utils.h"
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_emul.h>
#include <zephyr/kernel.h>
#include <zephyr/shell/shell_dummy.h>
+#include <zephyr/sys/byteorder.h>
#include <zephyr/ztest.h>
#define WP_L_GPIO_PATH NAMED_GPIOS_GPIO_NODE(wp_l)
@@ -497,6 +499,194 @@ ZTEST_USER(flash, test_console_cmd_flashwp__bad_param)
zassert_ok(!shell_execute_cmd(get_ec_shell(), "flashwp xyz"), NULL);
}
+ZTEST_USER(flash, test_console_cmd_flash_erase__flash_locked)
+{
+ /* Force write protection on */
+ zassert_ok(crec_flash_physical_protect_now(1));
+
+ CHECK_CONSOLE_CMD("flasherase 0x1000 0x1000", NULL,
+ EC_ERROR_ACCESS_DENIED);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__bad_args)
+{
+ /* No args*/
+ CHECK_CONSOLE_CMD("flasherase", NULL, EC_ERROR_PARAM_COUNT);
+
+ /* Check for 1 of 2 required args */
+ CHECK_CONSOLE_CMD("flasherase 0x1000", NULL, EC_ERROR_PARAM_COUNT);
+
+ /* Check for alpha arg instead of number*/
+ CHECK_CONSOLE_CMD("flasherase xyz 100", NULL, EC_ERROR_PARAM1);
+ CHECK_CONSOLE_CMD("flasherase 100 xyz", NULL, EC_ERROR_PARAM2);
+}
+
+/**
+ * @brief Writes a 32-bit word at a specific location in flash memory. Uses Host
+ * Command interface to communicate with flash driver.
+ *
+ * @param offset Address to begin writing at.
+ * @param data A 32-bit word to write.
+ * @return uint16_t Host command return status.
+ */
+static uint16_t write_flash_helper32(uint32_t offset, uint32_t data)
+{
+ uint8_t out_buf[sizeof(struct ec_params_flash_write) + sizeof(data)];
+
+ /* The write host command structs need to be filled run-time */
+ struct ec_params_flash_write *write_params =
+ (struct ec_params_flash_write *)out_buf;
+ struct host_cmd_handler_args write_args =
+ BUILD_HOST_COMMAND_SIMPLE(EC_CMD_FLASH_WRITE, 0);
+
+ write_params->offset = offset;
+ write_params->size = sizeof(data);
+ write_args.params = write_params;
+ write_args.params_size = sizeof(*write_params) + sizeof(data);
+
+ /* Flash write `data` */
+ memcpy(write_params + 1, &data, sizeof(data));
+ return host_command_process(&write_args);
+}
+
+/**
+ * @brief Reads a 32-bit word at a specific location in flash memory. Uses Host
+ * Command interface to communicate with flash driver.
+ *
+ * @param offset Address to begin reading from.
+ * @param data Output param for 32-bit read data.
+ * @return uint16_t Host command return status.
+ */
+static uint16_t read_flash_helper32(uint32_t offset, uint32_t *output)
+{
+ struct ec_params_flash_read read_params = {
+ .offset = offset,
+ .size = sizeof(*output),
+ };
+ struct host_cmd_handler_args read_args =
+ BUILD_HOST_COMMAND(EC_CMD_FLASH_READ, 0, *output, read_params);
+
+ /* Flash read and compare the readback data */
+ return host_command_process(&read_args);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_erase__happy)
+{
+ /* Immediately before the region to erase */
+ zassert_ok(write_flash_helper32(0x40000 - 4, 0x5A5A5A5A));
+
+ /* Start and end of the region we will erase */
+ zassert_ok(write_flash_helper32(0x40000, 0xA1B2C3D4));
+ zassert_ok(write_flash_helper32(0x50000 - 4, 0x1A2B3C4D));
+
+ /* Immediately after the region to erase */
+ zassert_ok(write_flash_helper32(0x50000, 0xA5A5A5A5));
+
+ CHECK_CONSOLE_CMD("flasherase 0x40000 0x10000", NULL, EC_SUCCESS);
+
+ uint32_t output;
+
+ /* These should remain untouched */
+ zassert_ok(read_flash_helper32(0x40000 - 4, &output));
+ zassert_equal(output, 0x5A5A5A5A, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x50000, &output));
+ zassert_equal(output, 0xA5A5A5A5, "Got %08x", output);
+
+ /* These are within the erase region and should be reset to all FF */
+ zassert_ok(read_flash_helper32(0x40000, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+ zassert_ok(read_flash_helper32(0x50000 - 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_write__flash_locked)
+{
+ /* Force write protection on */
+ zassert_ok(crec_flash_physical_protect_now(1));
+
+ CHECK_CONSOLE_CMD("flashwrite 0x1000 0x1000", NULL,
+ EC_ERROR_ACCESS_DENIED);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_write__bad_args)
+{
+ /* No args*/
+ CHECK_CONSOLE_CMD("flashwrite", NULL, EC_ERROR_PARAM_COUNT);
+
+ /* Check for 1 of 2 required args */
+ CHECK_CONSOLE_CMD("flashwrite 0x1000", NULL, EC_ERROR_PARAM_COUNT);
+
+ /* Check for alpha arg instead of number*/
+ CHECK_CONSOLE_CMD("flashwrite xyz 100", NULL, EC_ERROR_PARAM1);
+ CHECK_CONSOLE_CMD("flashwrite 100 xyz", NULL, EC_ERROR_PARAM2);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_write__too_big)
+{
+ CHECK_CONSOLE_CMD("flashwrite 0x10000 " STRINGIFY(INT_MAX), NULL,
+ EC_ERROR_INVAL);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_write__happy)
+{
+ /* Write 4 bytes. The bytes written are autogenerated and just the
+ * pattern 00 01 02 03.
+ */
+ CHECK_CONSOLE_CMD("flashwrite 0x10000 4", NULL, EC_SUCCESS);
+
+ uint32_t output;
+ static const uint8_t expected[] = { 0x00, 0x01, 0x02, 0x03 };
+
+ /* Check for pattern */
+ zassert_ok(read_flash_helper32(0x10000, &output));
+ zassert_mem_equal(&output, &expected, sizeof(expected));
+
+ /* Check the space after to ensure it is still erased. */
+ zassert_ok(read_flash_helper32(0x10000 + 4, &output));
+ zassert_equal(output, 0xFFFFFFFF, "Got %08x", output);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_read__bad_args)
+{
+ /* No args*/
+ CHECK_CONSOLE_CMD("flashread", NULL, EC_ERROR_PARAM_COUNT);
+
+ /* Check for alpha arg instead of number*/
+ CHECK_CONSOLE_CMD("flashread xyz 100", NULL, EC_ERROR_PARAM1);
+ CHECK_CONSOLE_CMD("flashread 100 xyz", NULL, EC_ERROR_PARAM2);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_read__too_big)
+{
+ CHECK_CONSOLE_CMD("flashread 0x10000 " STRINGIFY(INT_MAX), NULL,
+ EC_ERROR_INVAL);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_read__happy_4_bytes)
+{
+ /* Write some bytes to read */
+ zassert_ok(write_flash_helper32(0x10000, sys_cpu_to_be32(0xA1B2C3D4)));
+
+ static const char *expected = "\r\n\r\n"
+ "00010000: a1 b2 c3 d4\r\n";
+ CHECK_CONSOLE_CMD("flashread 0x10000 4", expected, EC_SUCCESS);
+}
+
+ZTEST_USER(flash, test_console_cmd_flash_read__happy_17_bytes)
+{
+ /* Test 16-byte column wrapping behavior */
+
+ /* Write some bytes to read */
+ zassert_ok(write_flash_helper32(0x10000, sys_cpu_to_be32(0xA1B2C3D4)));
+
+ static const char *expected =
+ "\r\n\r\n"
+ "00010000: a1 b2 c3 d4 ff ff ff ff ff ff ff ff ff ff ff ff\r\n"
+ "00010010: ff\r\n";
+
+ CHECK_CONSOLE_CMD("flashread 0x10000 17", expected, EC_SUCCESS);
+}
+
/**
* @brief Prepare a region of flash for the test_crec_flash_is_erased* tests
*
@@ -561,29 +751,23 @@ ZTEST_USER(flash, test_crec_flash_is_erased__not_erased)
NULL);
}
-static void flash_reset(void)
+static void flash_reset(void *data)
{
+ ARG_UNUSED(data);
+
/* Set the GPIO WP_L to default */
- gpio_wp_l_set(0);
+ zassert_ok(gpio_wp_l_set(0));
/* Reset the protection flags */
cros_flash_emul_protect_reset();
-}
-
-static void flash_before(void *data)
-{
- ARG_UNUSED(data);
- flash_reset();
-}
-
-static void flash_after(void *data)
-{
- ARG_UNUSED(data);
- flash_reset();
+ zassert_ok(crec_flash_physical_protect_now(0));
- /* The test modifies this bank. Erase it in case of failure. */
- crec_flash_erase(0x10000, 0x10000);
+ /* Tests modify these banks. Erase them. */
+ zassert_ok(crec_flash_erase(0x10000, 0x10000));
+ zassert_ok(crec_flash_erase(0x30000, 0x10000));
+ zassert_ok(crec_flash_erase(0x40000, 0x10000));
+ zassert_ok(crec_flash_erase(0x50000, 0x10000));
}
-ZTEST_SUITE(flash, drivers_predicate_post_main, NULL, flash_before, flash_after,
+ZTEST_SUITE(flash, drivers_predicate_post_main, NULL, flash_reset, flash_reset,
NULL);
diff --git a/zephyr/test/drivers/gpio_unhook/CMakeLists.txt b/zephyr/test/drivers/gpio_unhook/CMakeLists.txt
new file mode 100644
index 0000000000..7487caac88
--- /dev/null
+++ b/zephyr/test/drivers/gpio_unhook/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Add source files
+target_sources(app PRIVATE src/un_init_hooks.c)
+target_sources(app PRIVATE src/is_not_ready.c)
diff --git a/zephyr/test/drivers/gpio_unhook/src/is_not_ready.c b/zephyr/test/drivers/gpio_unhook/src/is_not_ready.c
new file mode 100644
index 0000000000..ad0e41aa57
--- /dev/null
+++ b/zephyr/test/drivers/gpio_unhook/src/is_not_ready.c
@@ -0,0 +1,30 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "driver/tcpm/tcpci.h"
+#include "tcpm/tcpm.h"
+#include "test/drivers/stubs.h"
+#include "test/drivers/test_state.h"
+#include "test/drivers/utils.h"
+
+#include <zephyr/ztest.h>
+
+ZTEST_SUITE(not_ready, drivers_predicate_post_main, NULL, NULL, NULL, NULL);
+
+ZTEST(not_ready, bad_tcpc)
+{
+ for (int i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ gpio_flags_t flags;
+
+ zassert_ok(gpio_pin_get_config_dt(&tcpc_config[i].irq_gpio,
+ &flags),
+ "error accessing tcpc port %i", i);
+
+ zassert_false(
+ flags & GPIO_INT_ENABLE,
+ "error port %i flag should not be enabled but is 0x%X",
+ i, flags);
+ }
+}
diff --git a/zephyr/test/drivers/gpio_unhook/src/un_init_hooks.c b/zephyr/test/drivers/gpio_unhook/src/un_init_hooks.c
new file mode 100644
index 0000000000..d4c999df38
--- /dev/null
+++ b/zephyr/test/drivers/gpio_unhook/src/un_init_hooks.c
@@ -0,0 +1,15 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "driver/tcpm/tcpci.h"
+#include "hooks.h"
+#include "tcpm/tcpm.h"
+#include "test/drivers/stubs.h"
+
+void tcpc_un_init(void)
+{
+ tcpc_config[USBC_PORT_C0].irq_gpio.port->state->initialized = 0;
+}
+DECLARE_HOOK(HOOK_INIT, tcpc_un_init, HOOK_PRIO_INIT_I2C);
diff --git a/zephyr/test/drivers/host_command_thread/src/main.c b/zephyr/test/drivers/host_command_thread/src/main.c
index 8b315dd950..bcd1b97074 100644
--- a/zephyr/test/drivers/host_command_thread/src/main.c
+++ b/zephyr/test/drivers/host_command_thread/src/main.c
@@ -21,15 +21,16 @@
#define CUSTOM_COMMAND_ID 0x0088
-/* Pointer to the main thread, defined in kernel/init.c */
-extern struct k_thread z_main_thread;
+/* Thread id of fake main thread */
+static k_tid_t fake_main_tid;
/* 0 - did not run, 1 - true, -1 - false */
static int last_check_main_thread_result;
static enum ec_status check_main_thread(struct host_cmd_handler_args *args)
{
- last_check_main_thread_result = in_host_command_main() ? 1 : -1;
+ last_check_main_thread_result =
+ (k_current_get() == get_main_thread() ? 1 : -1);
return EC_RES_SUCCESS;
}
@@ -42,6 +43,15 @@ static void fake_main_thread(void *a, void *b, void *c)
K_THREAD_STACK_DEFINE(fake_main_thread_stack, 4000);
+/* Override get_hostcmd_thread() from shim/src/tasks.c so
+ * task_get_current() returns TASK_ID_HOSTCMD when fake main thread
+ * is running.
+ */
+k_tid_t get_hostcmd_thread(void)
+{
+ return fake_main_tid;
+}
+
ZTEST_SUITE(host_cmd_thread, drivers_predicate_post_main, NULL, NULL, NULL,
NULL);
@@ -51,7 +61,8 @@ ZTEST(host_cmd_thread, test_takeover)
BUILD_HOST_COMMAND_SIMPLE(CUSTOM_COMMAND_ID, 0);
const char expected_thread_name[] = "HOSTCMD";
struct k_thread fake_main_thread_data;
- k_tid_t tid = k_thread_create(
+
+ fake_main_tid = k_thread_create(
&fake_main_thread_data, fake_main_thread_stack,
K_THREAD_STACK_SIZEOF(fake_main_thread_stack), fake_main_thread,
NULL, NULL, NULL, 1, 0, K_NO_WAIT);
@@ -60,11 +71,11 @@ ZTEST(host_cmd_thread, test_takeover)
k_msleep(500);
/* Get the name of the thread (must be done after the sleep) */
- const char *main_thread_name = k_thread_name_get(&z_main_thread);
+ const char *main_thread_name = k_thread_name_get(get_main_thread());
/* Verify that the thread is not the hostcmd thread */
zassert_equal(EC_TASK_PRIORITY(EC_TASK_HOSTCMD_PRIO),
- k_thread_priority_get(&z_main_thread));
+ k_thread_priority_get(get_main_thread()));
zassert_equal(strlen(expected_thread_name), strlen(main_thread_name));
zassert_mem_equal(expected_thread_name, main_thread_name,
strlen(expected_thread_name));
@@ -79,5 +90,5 @@ ZTEST(host_cmd_thread, test_takeover)
zassert_equal(-1, last_check_main_thread_result);
/* Kill the extra thread */
- k_thread_abort(tid);
+ k_thread_abort(fake_main_tid);
}
diff --git a/zephyr/test/drivers/panic_event/CMakeLists.txt b/zephyr/test/drivers/panic_event/CMakeLists.txt
deleted file mode 100644
index 25ea751d53..0000000000
--- a/zephyr/test/drivers/panic_event/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2022 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Add source files
-target_sources(app PRIVATE src/panic_event.c)
diff --git a/zephyr/test/drivers/panic_event/src/panic_event.c b/zephyr/test/drivers/panic_event/src/panic_event.c
deleted file mode 100644
index 09796d355f..0000000000
--- a/zephyr/test/drivers/panic_event/src/panic_event.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2022 The ChromiumOS Authors
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @file
- * @brief Unit Tests for panic event.
- */
-
-#include "common.h"
-#include "ec_tasks.h"
-#include "panic.h"
-#include "system.h"
-#include "test/drivers/stubs.h"
-#include "test/drivers/test_state.h"
-#include "test/drivers/utils.h"
-
-#include <zephyr/device.h>
-#include <zephyr/fff.h>
-#include <zephyr/kernel.h>
-#include <zephyr/logging/log.h>
-#include <zephyr/ztest.h>
-
-struct host_events_ctx events_ctx;
-
-static void before(void *unused)
-{
- ARG_UNUSED(unused);
- host_events_save(&events_ctx);
- host_clear_events(0xffffffff);
-}
-
-static void after(void *unused)
-{
- ARG_UNUSED(unused);
- host_events_restore(&events_ctx);
-}
-
-/**
- * @brief Test Suite: Verifies panic event functionality.
- */
-ZTEST_SUITE(panic_event, NULL, NULL, before, after, NULL);
-
-/**
- * @brief TestPurpose: Verify EC_HOST_EVENT_PANIC event is asserted on panic
- *
- * Expected Results
- * - Success
- */
-ZTEST_USER(panic_event, test_panic_event_notify)
-{
-#ifdef CONFIG_HOSTCMD_X86
- /* Enable the EC_HOST_EVENT_PANIC event in the lpc mask */
- host_event_t lpc_event_mask;
- host_event_t mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_PANIC);
-
- lpc_event_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, lpc_event_mask | mask);
-#endif
-
- zassert_false(host_is_event_set(EC_HOST_EVENT_PANIC));
- k_sys_fatal_error_handler(K_ERR_CPU_EXCEPTION, NULL);
- zassert_true(host_is_event_set(EC_HOST_EVENT_PANIC));
-}
diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf
index 00fc806d3b..555be472f1 100644
--- a/zephyr/test/drivers/prj.conf
+++ b/zephyr/test/drivers/prj.conf
@@ -13,7 +13,9 @@ CONFIG_ZTEST_NEW_API=y
CONFIG_ZTEST_PARAMETER_COUNT=24
CONFIG_TEST=y
CONFIG_ASSERT=y
-CONFIG_ASSERT_TEST=y
+# Do not set CONFIG_ASSERT_TEST=y here, it will mask assert failures.
+# Instead set CONFIG_ASSERT_TEST=y only on specific tests that require it.
+CONFIG_ASSERT_TEST=n
CONFIG_SHELL_VT100_COMMANDS=n
# Print logs from Zephyr LOG_MODULE to stdout
diff --git a/zephyr/test/drivers/shim_rtc/src/test_shim_rtc.c b/zephyr/test/drivers/shim_rtc/src/test_shim_rtc.c
index 9c411bb433..ded293d80a 100644
--- a/zephyr/test/drivers/shim_rtc/src/test_shim_rtc.c
+++ b/zephyr/test/drivers/shim_rtc/src/test_shim_rtc.c
@@ -55,7 +55,13 @@ ZTEST_USER(rtc_shim, test_hc_rtc_set_get_alarm)
set_value.time = 1776;
zassert_ok(host_command_process(&set_args));
zassert_ok(host_command_process(&get_args));
- zassert_equal(get_value.time, set_value.time);
+ /*
+ * The RTC driver adds 1 second to the alarm time to compensate for
+ * truncation error. For example, 7 seconds is returned when the
+ * actual time is 7.9 seconds. "get_value.time - 1" removes the
+ * additional seconded for this test.
+ */
+ zassert_equal(get_value.time - 1, set_value.time);
}
ZTEST(rtc_shim, test_hc_rtc_set_alarm_can_fire_cb)
@@ -84,7 +90,14 @@ ZTEST(rtc_shim, test_hc_rtc_set_alarm_can_fire_cb)
set_value.time = 2;
zassert_ok(host_command_process(&set_args));
/* Set fake driver time forward to hit the alarm in 2 seconds */
- system_set_rtc(4);
+
+ /*
+ * The RTC driver adds 1 second to the alarm time to compensate for
+ * truncation error. For example, 7 seconds is returned when the
+ * actual time is 7.9 seconds. So, RTC seconds is set to 5 instead
+ * of 4.
+ */
+ system_set_rtc(5);
/* Wait for irq to finish */
k_sleep(K_SECONDS(1));
diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml
index 5565bddf94..e13692cce7 100644
--- a/zephyr/test/drivers/testcase.yaml
+++ b/zephyr/test/drivers/testcase.yaml
@@ -101,6 +101,13 @@ tests:
drivers.console:
extra_configs:
- CONFIG_LINK_TEST_SUITE_CONSOLE=y
+ drivers.console_cmd_crash:
+ extra_args: CONF_FILE="prj.conf;default/prj.conf"
+ DTC_OVERLAY_FILE="default/boards/native_posix.overlay"
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_CONSOLE_CMD_CRASH=y
+ - CONFIG_PLATFORM_EC_CONSOLE_CMD_CRASH=y
+ - CONFIG_ASSERT_TEST=y
drivers.dps:
extra_args: CONF_FILE="prj.conf;dps/prj.conf"
extra_configs:
@@ -108,11 +115,17 @@ tests:
drivers.flash:
extra_configs:
- CONFIG_LINK_TEST_SUITE_FLASH=y
+ - CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y
drivers.flash.page_layout:
extra_configs:
- CONFIG_LINK_TEST_SUITE_FLASH=y
- CONFIG_SHELL_BACKEND_DUMMY_BUF_SIZE=500
+ - CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y
- CONFIG_PLATFORM_EC_USE_ZEPHYR_FLASH_PAGE_LAYOUT=y
+ drivers.gpio_unhook:
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_GPIO_UNHOOK=y
+ - CONFIG_GPIO_GET_CONFIG=y
drivers.host_cmd:
extra_configs:
- CONFIG_LINK_TEST_SUITE_HOST_COMMANDS=y
@@ -179,9 +192,6 @@ tests:
- CONFIG_LINK_TEST_SUITE_PANIC_OUTPUT=y
- CONFIG_PLATFORM_EC_CONSOLE_CMD_CRASH=y
- CONFIG_ZTEST_THREAD_PRIORITY=1
- drivers.panic_event:
- extra_configs:
- - CONFIG_LINK_TEST_SUITE_PANIC_EVENT=y
drivers.power_host_sleep:
extra_configs:
- CONFIG_LINK_TEST_SUITE_POWER_HOST_SLEEP=y
@@ -192,7 +202,9 @@ tests:
- CONFIG_POWER_SEQUENCE_MOCK=y
- CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y
drivers.ps8xxx:
- extra_args: CONF_FILE="prj.conf;ps8xxx/prj.conf" DTC_OVERLAY_FILE="./boards/native_posix.overlay;./ps8xxx/usbc.dts"
+ extra_args: >
+ CONF_FILE="prj.conf;ps8xxx/prj.conf"
+ DTC_OVERLAY_FILE="./boards/native_posix.overlay;./ps8xxx/usbc.dts"
extra_configs:
- CONFIG_LINK_TEST_SUITE_PS8XXX=y
drivers.rt9490:
@@ -269,6 +281,12 @@ tests:
drivers.usbc_console_pd:
extra_configs:
- CONFIG_LINK_TEST_SUITE_USBC_CONSOLE_PD=y
+ drivers.usbc_console_pd_legacy:
+ extra_args: >
+ DTC_OVERLAY_FILE="default/boards/native_posix.overlay;./usbc_console_pd/usbc_legacy.dts"
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_USBC_CONSOLE_PD=y
+ - CONFIG_PLATFORM_EC_TCPC_INTERRUPT=n
drivers.usbc_ctvpd:
extra_configs:
- CONFIG_LINK_TEST_SUITE_USBC_CTVPD=y
@@ -303,6 +321,7 @@ tests:
drivers.host_cmd_thread:
extra_configs:
- CONFIG_LINK_TEST_SUITE_HOST_CMD_THREAD=y
+ - CONFIG_TASK_HOSTCMD_THREAD_MAIN=y
drivers.pi3usb9201:
extra_configs:
- CONFIG_LINK_TEST_SUITE_PI3USB9201=y
diff --git a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode.c b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode.c
index c6387aae64..e966878a74 100644
--- a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode.c
+++ b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode.c
@@ -258,16 +258,6 @@ ZTEST_F(usbc_alt_mode, verify_displayport_mode_entry)
/* Verify host command when VDOs are present. */
struct ec_response_typec_status status;
- struct ec_params_usb_pd_get_mode_response response;
- int response_size;
-
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &response, &response_size);
-
- /* Response should be populated with a DisplayPort VDO */
- zassert_equal(response_size, sizeof(response));
- zassert_equal(response.svid, USB_SID_DISPLAYPORT);
- zassert_equal(response.vdo[0],
- fixture->partner.modes_vdm[response.opos], NULL);
/* DPM configures the partner on DP mode entry */
/* Verify port partner thinks its configured for DisplayPort */
@@ -480,16 +470,6 @@ ZTEST_F(usbc_alt_mode_minus_dp_configure, test_dp_mode_entry_minus_config)
/* Verify host command when VDOs are present. */
struct ec_response_typec_status status;
- struct ec_params_usb_pd_get_mode_response response;
- int response_size;
-
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &response, &response_size);
-
- /* Response should be populated with a DisplayPort VDO */
- zassert_equal(response_size, sizeof(response));
- zassert_equal(response.svid, USB_SID_DISPLAYPORT);
- zassert_equal(response.vdo[0],
- fixture->partner.modes_vdm[response.opos], NULL);
/* DPM configures the partner on DP mode entry */
/* Verify port partner thinks it's *NOT* configured for DisplayPort */
diff --git a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode__require_ap_mode_entry.c b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode__require_ap_mode_entry.c
index 597aac4179..a4c406a054 100644
--- a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode__require_ap_mode_entry.c
+++ b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode__require_ap_mode_entry.c
@@ -32,50 +32,15 @@ ZTEST_F(usbc_alt_mode, verify_displayport_mode_reentry)
k_sleep(K_SECONDS(1));
zassert_true(fixture->partner.displayport_configured);
- /* Verify that DisplayPort is the active alternate mode. */
- struct ec_params_usb_pd_get_mode_response response;
- int response_size;
-
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &response, &response_size);
-
- /* Response should be populated with a DisplayPort VDO */
- zassert_equal(response_size, sizeof(response));
- zassert_equal(response.svid, USB_SID_DISPLAYPORT);
- zassert_equal(response.vdo[0],
- fixture->partner.modes_vdm[response.opos]);
-}
-
-ZTEST_F(usbc_alt_mode, verify_mode_entry_via_pd_host_cmd)
-{
- if (!IS_ENABLED(CONFIG_PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY)) {
- ztest_test_skip();
- }
-
- /* Verify entering mode */
- struct ec_params_usb_pd_set_mode_request set_mode_params = {
- .cmd = PD_ENTER_MODE,
- .port = TEST_PORT,
- .opos = 1, /* Second VDO (after Discovery Responses) */
- .svid = USB_SID_DISPLAYPORT,
- };
-
- struct host_cmd_handler_args set_mode_args = BUILD_HOST_COMMAND_PARAMS(
- EC_CMD_USB_PD_SET_AMODE, 0, set_mode_params);
-
- zassert_ok(host_command_process(&set_mode_args));
-
- /* Verify that DisplayPort is the active alternate mode. */
- struct ec_params_usb_pd_get_mode_response get_mode_response;
- int response_size;
-
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &get_mode_response,
- &response_size);
+ /*
+ * Verify that DisplayPort is the active alternate mode by checking our
+ * MUX settings
+ */
+ struct ec_response_typec_status status;
- /* Response should be populated with a DisplayPort VDO */
- zassert_equal(response_size, sizeof(get_mode_response));
- zassert_equal(get_mode_response.svid, USB_SID_DISPLAYPORT);
- zassert_equal(get_mode_response.vdo[0],
- fixture->partner.modes_vdm[get_mode_response.opos]);
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_PD_MUX_DP_ENABLED),
+ USB_PD_MUX_DP_ENABLED, "Failed to see DP mux set");
}
ZTEST_F(usbc_alt_mode, verify_mode_exit_via_pd_host_cmd)
@@ -87,36 +52,16 @@ ZTEST_F(usbc_alt_mode, verify_mode_exit_via_pd_host_cmd)
host_cmd_typec_control_enter_mode(TEST_PORT, TYPEC_MODE_DP);
k_sleep(K_SECONDS(1));
- struct ec_params_usb_pd_get_mode_response get_mode_response;
- int response_size;
-
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &get_mode_response,
- &response_size);
+ host_cmd_typec_control_exit_modes(TEST_PORT);
+ k_sleep(K_SECONDS(1));
+ zassert_false(fixture->partner.displayport_configured);
- /* We require an the active alternate mode (DisplayPort in this case),
- * entering an alternate most (DisplayPort specifically) has already
- * been verified in another test
+ /*
+ * Verify that DisplayPort is no longer active by checking our
+ * MUX settings
*/
- zassert_equal(response_size, sizeof(get_mode_response));
- zassert_equal(get_mode_response.svid, USB_SID_DISPLAYPORT);
- zassert_equal(get_mode_response.vdo[0],
- fixture->partner.modes_vdm[get_mode_response.opos]);
-
- struct ec_params_usb_pd_set_mode_request set_mode_params = {
- .cmd = PD_EXIT_MODE,
- .port = TEST_PORT,
- .opos = get_mode_response.opos,
- .svid = get_mode_response.svid,
- };
-
- struct host_cmd_handler_args set_mode_args = BUILD_HOST_COMMAND_PARAMS(
- EC_CMD_USB_PD_SET_AMODE, 0, set_mode_params);
-
- zassert_ok(host_command_process(&set_mode_args));
+ struct ec_response_typec_status status;
- /* Verify mode was exited using get_amode command */
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &get_mode_response,
- &response_size);
- zassert_not_equal(get_mode_response.vdo[0],
- fixture->partner.modes_vdm[get_mode_response.opos]);
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_PD_MUX_DP_ENABLED), 0);
}
diff --git a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode_ec_mode_entry.c b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode_ec_mode_entry.c
index ef56332f55..e36ba57e26 100644
--- a/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode_ec_mode_entry.c
+++ b/zephyr/test/drivers/usbc_alt_mode/src/usbc_alt_mode_ec_mode_entry.c
@@ -19,26 +19,27 @@
ZTEST_F(usbc_alt_mode, verify_displayport_mode_power_cycle)
{
+ struct ec_response_typec_status status;
+
/* Verify that the TCPM enters DP mode on attach, exits on AP power-off,
* and enters again on AP power on.
*/
zassert_true(fixture->partner.displayport_configured, NULL);
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_PD_MUX_DP_ENABLED),
+ USB_PD_MUX_DP_ENABLED);
mock_power_request(POWER_REQ_SOFT_OFF);
zassert_false(fixture->partner.displayport_configured, NULL);
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_PD_MUX_DP_ENABLED), 0);
mock_power_request(POWER_REQ_ON);
- zassert_true(fixture->partner.displayport_configured, NULL);
-
- struct ec_params_usb_pd_get_mode_response response;
- int response_size;
- host_cmd_usb_pd_get_amode(TEST_PORT, 0, &response, &response_size);
-
- zassert_equal(response_size, sizeof(response), NULL);
- zassert_equal(response.svid, USB_SID_DISPLAYPORT, NULL);
- zassert_equal(response.vdo[0],
- fixture->partner.modes_vdm[response.opos], NULL);
+ zassert_true(fixture->partner.displayport_configured, NULL);
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_PD_MUX_DP_ENABLED),
+ USB_PD_MUX_DP_ENABLED);
}
diff --git a/zephyr/test/drivers/usbc_console_pd/usbc_legacy.dts b/zephyr/test/drivers/usbc_console_pd/usbc_legacy.dts
new file mode 100644
index 0000000000..c07f379f77
--- /dev/null
+++ b/zephyr/test/drivers/usbc_console_pd/usbc_legacy.dts
@@ -0,0 +1,25 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+&{/gpio-interrupts} {
+ int_usb_c0: usb_c0 {
+ irq-pin = <&usb_c0_tcpc_int_odl>;
+ flags = <GPIO_INT_EDGE_FALLING>;
+ handler = "tcpc_alert_event";
+ };
+ int_usb_c1: usb_c1 {
+ irq-pin = <&usb_c1_tcpc_int_odl>;
+ flags = <GPIO_INT_EDGE_FALLING>;
+ handler = "tcpc_alert_event";
+ };
+};
+
+&tcpci_emul {
+ int-pin = <&usb_c0_tcpc_int_odl>;
+};
+
+&ps8xxx_emul {
+ int-pin = <&usb_c1_tcpc_int_odl>;
+};
diff --git a/zephyr/test/ec_app/boards/native_posix.overlay b/zephyr/test/ec_app/boards/native_posix.overlay
index 69bf044ec6..1afbdd4f4c 100644
--- a/zephyr/test/ec_app/boards/native_posix.overlay
+++ b/zephyr/test/ec_app/boards/native_posix.overlay
@@ -30,6 +30,22 @@
flash1: flash@64000000 {
reg = <0x64000000 DT_SIZE_K(512)>;
};
+
+ power-states {
+ suspend_to_idle_instant: suspend_to_idle_instant {
+ compatible = "zephyr,power-state";
+ power-state-name = "suspend-to-idle";
+ substate-id = <0>;
+ min-residency-us = <500>;
+ };
+
+ suspend_to_idle_normal: suspend_to_idle_normal {
+ compatible = "zephyr,power-state";
+ power-state-name = "suspend-to-idle";
+ substate-id = <1>;
+ min-residency-us = <200100>;
+ };
+ };
};
&gpio0 {
diff --git a/zephyr/test/ec_app/prj.conf b/zephyr/test/ec_app/prj.conf
index 502f5bbdc6..8bbe96b8dc 100644
--- a/zephyr/test/ec_app/prj.conf
+++ b/zephyr/test/ec_app/prj.conf
@@ -13,8 +13,11 @@ CONFIG_SHELL_BACKEND_SERIAL=n
CONFIG_SERIAL=y
CONFIG_RING_BUFFER=y
+CONFIG_PM=y
CONFIG_PLATFORM_EC_VBOOT_EFS2=y
CONFIG_PLATFORM_EC_VBOOT_HASH=y
CONFIG_PLATFORM_EC_HOSTCMD=y
CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
CONFIG_PLATFORM_EC_SWITCH=n
+CONFIG_PLATFORM_EC_BOOT_NO_SLEEP=y
+CONFIG_PLATFORM_EC_BOOT_NO_SLEEP_MS=1000 \ No newline at end of file
diff --git a/zephyr/test/ec_app/src/main.c b/zephyr/test/ec_app/src/main.c
index 52a19f131c..2e3cd7efa9 100644
--- a/zephyr/test/ec_app/src/main.c
+++ b/zephyr/test/ec_app/src/main.c
@@ -6,7 +6,9 @@
#include "ec_app_main.h"
#include "hooks.h"
#include "task.h"
+#include "timer.h"
+#include <zephyr/pm/policy.h>
#include <zephyr/shell/shell_dummy.h>
#include <zephyr/ztest_assert.h>
#include <zephyr/ztest_test_new.h>
@@ -99,6 +101,17 @@ ZTEST(ec_app_tests, test_start_ec_tasks)
}
#endif
+ZTEST(ec_app_tests, test_ec_boot_sleep_disable)
+{
+#ifdef CONFIG_PLATFORM_EC_BOOT_NO_SLEEP_MS
+ zassert_true(pm_policy_state_lock_is_active(PM_STATE_SUSPEND_TO_IDLE,
+ PM_ALL_SUBSTATES));
+ k_msleep(2 * CONFIG_PLATFORM_EC_BOOT_NO_SLEEP_MS);
+#endif
+ zassert_false(pm_policy_state_lock_is_active(PM_STATE_SUSPEND_TO_IDLE,
+ PM_ALL_SUBSTATES));
+}
+
/* Does setup for all of the test cases. */
void *ec_app_setup(void)
{
diff --git a/zephyr/test/skyrim/CMakeLists.txt b/zephyr/test/skyrim/CMakeLists.txt
index 8fbcc78432..72f995d0c0 100644
--- a/zephyr/test/skyrim/CMakeLists.txt
+++ b/zephyr/test/skyrim/CMakeLists.txt
@@ -10,6 +10,10 @@ zephyr_include_directories("${PLATFORM_EC_PROGRAM_DIR}/skyrim/include")
add_subdirectory(${PLATFORM_EC}/zephyr/test/test_utils test_utils)
-target_sources(app PRIVATE src/${CONFIG_TEST_BOARD_NAME}/common.c)
+target_sources(app PRIVATE src/common.c src/${CONFIG_TEST_BOARD_NAME}/common.c)
-target_sources_ifdef(CONFIG_TEST_BOARD_USB_PD_POLICY app PRIVATE src/baseboard/usb_pd_policy.c ${PLATFORM_EC_PROGRAM_DIR}/skyrim/src/usb_pd_policy.c) \ No newline at end of file
+target_sources_ifdef(CONFIG_TEST_BOARD_ALT_CHARGER app PRIVATE src/${CONFIG_TEST_BOARD_ALT_CHARGER_SRC} ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/alt_charger.c)
+target_sources_ifdef(CONFIG_TEST_BOARD_FAN app PRIVATE src/${CONFIG_TEST_BOARD_FAN_SRC} ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/fan.c)
+target_sources_ifdef(CONFIG_TEST_BOARD_PPC_CONFIG app PRIVATE src/${CONFIG_TEST_BOARD_PPC_CONFIG_SRC} ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/ppc_config.c)
+target_sources_ifdef(CONFIG_TEST_BOARD_USB_PD_POLICY app PRIVATE src/baseboard/usb_pd_policy.c ${PLATFORM_EC_PROGRAM_DIR}/skyrim/src/usb_pd_policy.c)
+target_sources_ifdef(CONFIG_TEST_BOARD_USB_MUX_CONFIG app PRIVATE src/${TEST_BOARD_USB_MUX_CONFIG_SRC} ${PLATFORM_EC_PROGRAM_DIR}/skyrim/${CONFIG_TEST_BOARD_NAME}/src/usb_mux_config.c)
diff --git a/zephyr/test/skyrim/Kconfig b/zephyr/test/skyrim/Kconfig
index 41685834be..99013c0f6f 100644
--- a/zephyr/test/skyrim/Kconfig
+++ b/zephyr/test/skyrim/Kconfig
@@ -48,11 +48,49 @@ config TEST_BOARD_NAME
default "skyrim" if TEST_BOARD_SKYRIM
default "winterhold" if TEST_BOARD_WINTERHOLD
+config TEST_BOARD_ALT_CHARGER
+ bool "Enable alt charger specific tests"
+
+config TEST_BOARD_ALT_CHARGER_SRC
+ string "Source file to use for this test"
+ default "common/alt_charger.c"
+ depends on TEST_BOARD_ALT_CHARGER
+
+config TEST_BOARD_FAN
+ bool "Enable fan tests"
+
+config TEST_BOARD_FAN_SRC
+ string "Source file to use for this test"
+ default "common/fan.c"
+ depends on TEST_BOARD_FAN
+
config TEST_BOARD_USB_PD_POLICY
bool "Enable USB PD policy specific tests"
select TEST_ENABLE_USB_PD_HOST_CMD
default n
+config TEST_BOARD_PPC_CONFIG
+ bool "Enable PPC config tests"
+ default n
+
+config TEST_BOARD_PPC_CONFIG_SRC
+ string "Source file to use for this test"
+ default "common/ppc_config.c"
+ depends on TEST_BOARD_PPC
+
+config TEST_BOARD_USB_MUX_CONFIG
+ bool "Enable USB mux config tests"
+ default n
+
+config TEST_BOARD_USB_MUX_CONFIG_SRC
+ string "Source file to use for this test"
+ default "common/usb_mux_config.c"
+ depends on TEST_BOARD_USB_MUX_CONFIG
+
+config SKYRIM_LOG_LEVEL
+ int "Fake config to allow building"
+ default 4 # Log level debug by default
+
config TEST_ENABLE_USB_PD_HOST_CMD
bool "Fake config to enable this feature"
default n
diff --git a/zephyr/test/skyrim/boards/native_posix.overlay b/zephyr/test/skyrim/boards/native_posix.overlay
index 7328610584..5bf8c86ec7 100644
--- a/zephyr/test/skyrim/boards/native_posix.overlay
+++ b/zephyr/test/skyrim/boards/native_posix.overlay
@@ -25,6 +25,79 @@
gpios = <&gpio0 2 GPIO_OUTPUT_LOW>;
enum-name = "IOEX_USB_C1_TCPC_FASTSW_CTL_EN";
};
+
+ gpio_usb_c0_ppc_int_odl: usb_c0_ppc_int_odl {
+ gpios = <&gpio0 3 GPIO_INPUT>;
+ enum-name = "GPIO_USB_C0_PPC_INT_ODL";
+ };
+ gpio_usb_c1_ppc_int_odl: usb_c1_ppc_int_odl {
+ gpios = <&gpio0 4 GPIO_INPUT>;
+ enum-name = "GPIO_USB_C1_PPC_INT_ODL";
+ };
+
+ ioex_usb_c0_ilim_3a_en: usb_c0_ppc_ilim_3a_en {
+ gpios = <&gpio0 5 GPIO_OUTPUT_LOW>;
+ enum-name = "IOEX_USB_C0_PPC_ILIM_3A_EN";
+ };
+
+ gpio_usb_c1_in_hpd: usb_c1_in_hpd {
+ gpios = <&gpio0 6 GPIO_OUTPUT_LOW>;
+ enum-name = "IOEX_USB_C1_HPD_IN_DB";
+ };
+
+ ioex_usb_c1_sbu_flip: usb_c1_sbu_flip {
+ gpios = <&gpio0 7 GPIO_OUTPUT_LOW>;
+ enum-name = "IOEX_USB_C1_SBU_FLIP";
+ };
+
+ ioex_usb_c0_sbu_flip: usb_c0_sbu_flip {
+ gpios = <&gpio0 8 GPIO_OUTPUT_LOW>;
+ enum-name = "IOEX_USB_C0_SBU_FLIP";
+ };
+ };
+
+ skyrim-fw-config {
+ compatible = "cros-ec,cbi-fw-config";
+
+ fan {
+ enum-name = "FW_FAN";
+ start = <10>;
+ size = <1>;
+
+ no-fan {
+ compatible = "cros-ec,cbi-fw-config-value";
+ enum-name = "FW_FAN_NOT_PRESENT";
+ value = <0>;
+ };
+ fan-present {
+ compatible = "cros-ec,cbi-fw-config-value";
+ enum-name = "FW_FAN_PRESENT";
+ value = <1>;
+ /*
+ * Set as default so that unprovisioned
+ * configs will run the fan regardless.
+ */
+ default;
+ };
+ };
+
+ charger-option {
+ enum-name = "FW_CHARGER";
+ start = <11>;
+ size = <2>;
+
+ charger-option-isl9241 {
+ compatible = "cros-ec,cbi-fw-config-value";
+ enum-name = "FW_CHARGER_ISL9241";
+ value = <0>;
+ default;
+ };
+ charger-option-isl9538 {
+ compatible = "cros-ec,cbi-fw-config-value";
+ enum-name = "FW_CHARGER_ISL9538";
+ value = <1>;
+ };
+ };
};
};
diff --git a/zephyr/test/skyrim/prj.conf b/zephyr/test/skyrim/prj.conf
index 77f7eab5a2..d9b3ba4ab9 100644
--- a/zephyr/test/skyrim/prj.conf
+++ b/zephyr/test/skyrim/prj.conf
@@ -7,7 +7,9 @@ CONFIG_ZTEST_ASSERT_VERBOSE=1
CONFIG_ZTEST_NEW_API=y
CONFIG_ASSERT=y
+CONFIG_PLATFORM_EC_CBI=y
CONFIG_CROS_EC=y
CONFIG_PLATFORM_EC=y
+CONFIG_PLATFORM_EC_HOOKS=y
CONFIG_EMUL=y
CONFIG_GPIO=y
diff --git a/zephyr/test/skyrim/src/common.c b/zephyr/test/skyrim/src/common.c
new file mode 100644
index 0000000000..b369d0bdaa
--- /dev/null
+++ b/zephyr/test/skyrim/src/common.c
@@ -0,0 +1,7 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/logging/log.h>
+
+LOG_MODULE_REGISTER(skyrim, CONFIG_SKYRIM_LOG_LEVEL);
diff --git a/zephyr/test/skyrim/src/common/alt_charger.c b/zephyr/test/skyrim/src/common/alt_charger.c
new file mode 100644
index 0000000000..c03d31aaeb
--- /dev/null
+++ b/zephyr/test/skyrim/src/common/alt_charger.c
@@ -0,0 +1,55 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/devicetree.h>
+#include <zephyr/fff.h>
+#include <zephyr/ztest.h>
+
+#include <charger.h>
+#include <cros_cbi.h>
+#include <hooks.h>
+
+FAKE_VALUE_FUNC(int, cros_cbi_get_fw_config, enum cbi_fw_config_field_id,
+ uint32_t *);
+FAKE_VOID_FUNC(chg_enable_alternate_test, int);
+
+void alt_charger_init(void);
+
+static bool alt_charger;
+static int cros_cbi_get_fw_config_mock(enum cbi_fw_config_field_id field_id,
+ uint32_t *value)
+{
+ if (field_id != FW_CHARGER)
+ return -EINVAL;
+
+ *value = alt_charger ? FW_CHARGER_ISL9538 : FW_CHARGER_ISL9241;
+ return 0;
+}
+
+static void alt_charger_before(void *fixture)
+{
+ ARG_UNUSED(fixture);
+ RESET_FAKE(cros_cbi_get_fw_config);
+ RESET_FAKE(chg_enable_alternate_test);
+
+ cros_cbi_get_fw_config_fake.custom_fake = cros_cbi_get_fw_config_mock;
+}
+
+ZTEST_SUITE(alt_charger, NULL, NULL, alt_charger_before, NULL, NULL);
+
+ZTEST(alt_charger, normal_charger)
+{
+ alt_charger = false;
+ alt_charger_init();
+ /* Test that the alternative charger wasn't enabled. */
+ zassert_equal(chg_enable_alternate_test_fake.call_count, 0);
+}
+
+ZTEST(alt_charger, alt_charger)
+{
+ alt_charger = true;
+ alt_charger_init();
+ zassert_equal(chg_enable_alternate_test_fake.call_count, 1);
+ zassert_equal(chg_enable_alternate_test_fake.arg0_val, 0);
+}
diff --git a/zephyr/test/skyrim/src/common/fan.c b/zephyr/test/skyrim/src/common/fan.c
new file mode 100644
index 0000000000..4968938298
--- /dev/null
+++ b/zephyr/test/skyrim/src/common/fan.c
@@ -0,0 +1,92 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/devicetree.h>
+#include <zephyr/fff.h>
+#include <zephyr/ztest.h>
+
+#include <cros_board_info.h>
+#include <cros_cbi.h>
+#include <fan.h>
+#include <hooks.h>
+
+FAKE_VOID_FUNC(fan_set_count, int);
+FAKE_VALUE_FUNC(int, cros_cbi_get_fw_config, enum cbi_fw_config_field_id,
+ uint32_t *);
+FAKE_VALUE_FUNC(int, cbi_get_board_version, uint32_t *);
+
+void fan_init(void);
+bool board_supports_pcore_ocp(void);
+
+static bool fan_present;
+static int board_version;
+
+static int cros_cbi_get_fw_config_mock(enum cbi_fw_config_field_id field_id,
+ uint32_t *value)
+{
+ if (field_id != FW_FAN)
+ return -EINVAL;
+
+ *value = fan_present ? FW_FAN_PRESENT : FW_FAN_NOT_PRESENT;
+ return 0;
+}
+
+static int cbi_get_board_version_mock(uint32_t *value)
+{
+ *value = board_version;
+ return EC_SUCCESS;
+}
+
+static void fan_before(void *fixture)
+{
+ ARG_UNUSED(fixture);
+ RESET_FAKE(fan_set_count);
+ RESET_FAKE(cros_cbi_get_fw_config);
+ RESET_FAKE(cbi_get_board_version);
+
+ cros_cbi_get_fw_config_fake.custom_fake = cros_cbi_get_fw_config_mock;
+ cbi_get_board_version_fake.custom_fake = cbi_get_board_version_mock;
+}
+
+ZTEST_SUITE(fan, NULL, NULL, fan_before, NULL, NULL);
+
+ZTEST(fan, board_supports_pcore_ocp)
+{
+ /* Only supported for board version > 3. */
+ board_version = 2;
+ zassert_false(board_supports_pcore_ocp());
+ board_version = 3;
+ zassert_false(board_supports_pcore_ocp());
+ board_version = 4;
+ zassert_true(board_supports_pcore_ocp());
+}
+
+ZTEST(fan, fan_init)
+{
+ /* Only disable fans on board version >= 3. */
+ fan_present = false;
+ board_version = 2;
+ fan_init();
+ zassert_equal(fan_set_count_fake.call_count, 0);
+
+ fan_present = true;
+ board_version = 3;
+ fan_init();
+ zassert_equal(fan_set_count_fake.call_count, 0);
+
+ fan_present = true;
+ board_version = 4;
+ fan_init();
+ zassert_equal(fan_set_count_fake.call_count, 0);
+
+ fan_present = false;
+ board_version = 3;
+ fan_init();
+ zassert_equal(fan_set_count_fake.call_count, 1);
+
+ fan_present = false;
+ board_version = 4;
+ fan_init();
+ zassert_equal(fan_set_count_fake.call_count, 2);
+}
diff --git a/zephyr/test/skyrim/src/common/ppc_config.c b/zephyr/test/skyrim/src/common/ppc_config.c
new file mode 100644
index 0000000000..0721e9c313
--- /dev/null
+++ b/zephyr/test/skyrim/src/common/ppc_config.c
@@ -0,0 +1,58 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/fff.h>
+#include <zephyr/ztest.h>
+
+#include <gpio.h>
+#include <usbc_ppc.h>
+
+FAKE_VOID_FUNC(aoz1380_interrupt, int);
+FAKE_VOID_FUNC(nx20p348x_interrupt, int);
+
+static void ppc_config_before(void *fixture)
+{
+ ARG_UNUSED(fixture);
+ RESET_FAKE(aoz1380_interrupt);
+ RESET_FAKE(nx20p348x_interrupt);
+}
+
+void ppc_interrupt(enum gpio_signal signal);
+int board_aoz1380_set_vbus_source_current_limit(int port,
+ enum tcpc_rp_value rp);
+
+ZTEST_SUITE(ppc_config, NULL, NULL, ppc_config_before, NULL, NULL);
+
+ZTEST(ppc_config, board_aoz1380_set_vbus_source_current_limit)
+{
+ int rv;
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(ioex_usb_c0_ilim_3a_en);
+
+ /*
+ * board_aoz1380_set_vbus_source_current_limit should set
+ * ioex_usb_c0_ilim_3a_en to 1 for 3A, 0 otherwise.
+ */
+ rv = board_aoz1380_set_vbus_source_current_limit(0, TYPEC_RP_3A0);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1);
+
+ rv = board_aoz1380_set_vbus_source_current_limit(0, TYPEC_RP_1A5);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+}
+
+ZTEST(ppc_config, ppc_interrupt)
+{
+ ppc_interrupt(GPIO_USB_C0_PPC_INT_ODL);
+ zassert_equal(aoz1380_interrupt_fake.call_count, 1);
+ /* port */
+ zassert_equal(aoz1380_interrupt_fake.arg0_val, 0);
+
+ ppc_interrupt(GPIO_USB_C1_PPC_INT_ODL);
+ zassert_equal(nx20p348x_interrupt_fake.call_count, 1);
+ /* port */
+ zassert_equal(nx20p348x_interrupt_fake.arg0_val, 1);
+}
diff --git a/zephyr/test/skyrim/src/crystaldrift/common.c b/zephyr/test/skyrim/src/crystaldrift/common.c
index 841b7db140..9fa7864859 100644
--- a/zephyr/test/skyrim/src/crystaldrift/common.c
+++ b/zephyr/test/skyrim/src/crystaldrift/common.c
@@ -2,6 +2,9 @@
* 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 <zephyr/ztest.h>
+LOG_MODULE_REGISTER(crystaldrift, CONFIG_SKYRIM_LOG_LEVEL);
+
ZTEST_SUITE(common, NULL, NULL, NULL, NULL, NULL);
diff --git a/zephyr/test/skyrim/src/frostflow/usb_mux_config.c b/zephyr/test/skyrim/src/frostflow/usb_mux_config.c
new file mode 100644
index 0000000000..929bd318d4
--- /dev/null
+++ b/zephyr/test/skyrim/src/frostflow/usb_mux_config.c
@@ -0,0 +1,60 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/drivers/gpio/gpio_emul.h>
+#include <zephyr/fff.h>
+#include <zephyr/ztest.h>
+
+#include <gpio.h>
+#include <usbc/usb_muxes.h>
+
+int board_c0_amd_fp6_mux_set(const struct usb_mux *me, mux_state_t mux_state);
+int board_c1_ps8818_mux_set(const struct usb_mux *me, mux_state_t mux_state);
+
+ZTEST_SUITE(usb_mux_config, NULL, NULL, NULL, NULL, NULL);
+
+ZTEST(usb_mux_config, board_c0_amd_fp6_mux_set)
+{
+ const struct gpio_dt_spec *c0 =
+ GPIO_DT_FROM_NODELABEL(ioex_usb_c0_sbu_flip);
+ const struct gpio_dt_spec *c1 =
+ GPIO_DT_FROM_NODELABEL(ioex_usb_c1_sbu_flip);
+ struct usb_mux mux;
+ int rv;
+
+ /* Output for each port should match inverted status. */
+ mux.usb_port = 0;
+ rv = board_c0_amd_fp6_mux_set(&mux, 0);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(c0->port, c0->pin), 0);
+
+ rv = board_c0_amd_fp6_mux_set(&mux, USB_PD_MUX_POLARITY_INVERTED);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(c0->port, c0->pin), 1);
+
+ mux.usb_port = 1;
+ rv = board_c0_amd_fp6_mux_set(&mux, 0);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(c1->port, c1->pin), 0);
+
+ rv = board_c0_amd_fp6_mux_set(&mux, USB_PD_MUX_POLARITY_INVERTED);
+ zassert_equal(rv, EC_SUCCESS);
+ zassert_equal(gpio_emul_output_get(c1->port, c1->pin), 1);
+}
+
+ZTEST(usb_mux_config, board_c1_ps8818_mux_set)
+{
+ const struct gpio_dt_spec *gpio =
+ GPIO_DT_FROM_NODELABEL(gpio_usb_c1_in_hpd);
+ struct usb_mux mux;
+
+ /* gpio_usb_c1_in_hpd should match if DP is enabled. */
+ mux.usb_port = 0;
+ zassert_ok(board_c1_ps8818_mux_set(&mux, 0));
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 0);
+
+ mux.usb_port = 1;
+ zassert_ok(board_c1_ps8818_mux_set(&mux, USB_PD_MUX_DP_ENABLED));
+ zassert_equal(gpio_emul_output_get(gpio->port, gpio->pin), 1);
+}
diff --git a/zephyr/test/skyrim/src/markarth/common.c b/zephyr/test/skyrim/src/markarth/common.c
index 841b7db140..b302042761 100644
--- a/zephyr/test/skyrim/src/markarth/common.c
+++ b/zephyr/test/skyrim/src/markarth/common.c
@@ -2,6 +2,9 @@
* 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 <zephyr/ztest.h>
+LOG_MODULE_REGISTER(markarth, CONFIG_SKYRIM_LOG_LEVEL);
+
ZTEST_SUITE(common, NULL, NULL, NULL, NULL, NULL);
diff --git a/zephyr/test/skyrim/src/winterhold/ppc_config.c b/zephyr/test/skyrim/src/winterhold/ppc_config.c
new file mode 100644
index 0000000000..131a74855e
--- /dev/null
+++ b/zephyr/test/skyrim/src/winterhold/ppc_config.c
@@ -0,0 +1,38 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <zephyr/fff.h>
+#include <zephyr/ztest.h>
+
+#include <gpio.h>
+#include <usbc_ppc.h>
+
+FAKE_VOID_FUNC(nx20p348x_interrupt, int);
+DEFINE_FAKE_VOID_FUNC(nx20p348x_interrupt, int);
+
+static void ppc_config_before(void *fixture)
+{
+ ARG_UNUSED(fixture);
+ RESET_FAKE(nx20p348x_interrupt);
+}
+
+void ppc_interrupt(enum gpio_signal signal);
+
+ZTEST_SUITE(ppc_config, NULL, NULL, ppc_config_before, NULL, NULL);
+
+ZTEST(ppc_config, ppc_interrupt_c0)
+{
+ ppc_interrupt(GPIO_USB_C0_PPC_INT_ODL);
+ zassert_equal(nx20p348x_interrupt_fake.call_count, 1);
+ /* port */
+ zassert_equal(nx20p348x_interrupt_fake.arg0_val, 0);
+}
+
+ZTEST(ppc_config, ppc_interrupt_c1)
+{
+ ppc_interrupt(GPIO_USB_C1_PPC_INT_ODL);
+ zassert_equal(nx20p348x_interrupt_fake.call_count, 1);
+ /* port */
+ zassert_equal(nx20p348x_interrupt_fake.arg0_val, 1);
+}
diff --git a/zephyr/test/skyrim/testcase.yaml b/zephyr/test/skyrim/testcase.yaml
index 29d22a2fcd..d2330c740b 100644
--- a/zephyr/test/skyrim/testcase.yaml
+++ b/zephyr/test/skyrim/testcase.yaml
@@ -26,22 +26,79 @@ tests:
extra_configs:
- CONFIG_TEST_BOARD_CRYSTALDRIFT=y
+ skyrim.crystaldrift.alt_charger:
+ extra_configs:
+ - CONFIG_TEST_BOARD_CRYSTALDRIFT=y
+ - CONFIG_TEST_BOARD_ALT_CHARGER=y
+
+ skyrim.crystaldrift.fan:
+ extra_configs:
+ - CONFIG_TEST_BOARD_CRYSTALDRIFT=y
+ - CONFIG_TEST_BOARD_FAN=y
+
+ skyrim.crystaldrift.ppc_config:
+ extra_configs:
+ - CONFIG_TEST_BOARD_CRYSTALDRIFT=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG=y
+
# Frostflow tests
skyrim.frostflow:
extra_configs:
- CONFIG_TEST_BOARD_FROSTFLOW=y
+ skyrim.frostflow.ppc_config:
+ extra_configs:
+ - CONFIG_TEST_BOARD_FROSTFLOW=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG=y
+
+ # skyrim.frostflow.usb_mux_config:
+ # extra_configs:
+ # - CONFIG_TEST_BOARD_FROSTFLOW=y
+ # - CONFIG_TEST_BOARD_USB_MUX_CONFIG=y
+ # - CONFIG_TEST_BOARD_USB_MUX_CONFIG_SRC="frostflow/usb_mux_config.c"
+
# Markarth tests
skyrim.markarth:
extra_configs:
- CONFIG_TEST_BOARD_MARKARTH=y
+ skyrim.markarth.fan:
+ extra_configs:
+ - CONFIG_TEST_BOARD_MARKARTH=y
+ - CONFIG_TEST_BOARD_FAN=y
+
+ skyrim.markarth.ppc_config:
+ extra_configs:
+ - CONFIG_TEST_BOARD_MARKARTH=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG=y
+
# Skyrim tests
skyrim.skyrim:
extra_configs:
- CONFIG_TEST_BOARD_SKYRIM=y
+ skyrim.skyrim.alt_charger:
+ extra_configs:
+ - CONFIG_TEST_BOARD_SKYRIM=y
+ - CONFIG_TEST_BOARD_ALT_CHARGER=y
+
+ skyrim.skyrim.fan:
+ extra_configs:
+ - CONFIG_TEST_BOARD_SKYRIM=y
+ - CONFIG_TEST_BOARD_FAN=y
+
+ skyrim.skyrim.ppc_config:
+ extra_configs:
+ - CONFIG_TEST_BOARD_SKYRIM=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG=y
+
# Winterhold tests
skyrim.winterhold:
extra_configs:
- CONFIG_TEST_BOARD_WINTERHOLD=y
+
+ skyrim.winterhold.ppc_config:
+ extra_configs:
+ - CONFIG_TEST_BOARD_WINTERHOLD=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG=y
+ - CONFIG_TEST_BOARD_PPC_CONFIG_SRC="winterhold/ppc_config.c"
diff --git a/zephyr/test/system_safe_mode/prj.conf b/zephyr/test/system_safe_mode/prj.conf
index 22294e85d3..f7aeb4b776 100644
--- a/zephyr/test/system_safe_mode/prj.conf
+++ b/zephyr/test/system_safe_mode/prj.conf
@@ -11,6 +11,7 @@ CONFIG_SYSTEM_FAKE=y
CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE=y
CONFIG_TASK_HOSTCMD_THREAD_DEDICATED=y
CONFIG_PLATFORM_EC_HOSTCMD=y
+CONFIG_ASSERT_TEST=y
# Disable because not needed
CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
diff --git a/zephyr/test/system_safe_mode/src/system_safe_mode.c b/zephyr/test/system_safe_mode/src/system_safe_mode.c
index 2b861f2e5b..f286a45124 100644
--- a/zephyr/test/system_safe_mode/src/system_safe_mode.c
+++ b/zephyr/test/system_safe_mode/src/system_safe_mode.c
@@ -140,4 +140,22 @@ ZTEST_USER(system_safe_mode, test_blocked_command_in_safe_mode)
zassert_true(host_command_process(&args));
}
+ZTEST_USER(system_safe_mode, test_panic_event_notify)
+{
+#ifdef CONFIG_HOSTCMD_X86
+ /* Enable the EC_HOST_EVENT_PANIC event in the lpc mask */
+ host_event_t lpc_event_mask;
+ host_event_t mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_PANIC);
+
+ lpc_event_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, lpc_event_mask | mask);
+#endif
+
+ zassert_false(host_is_event_set(EC_HOST_EVENT_PANIC));
+ k_sys_fatal_error_handler(K_ERR_CPU_EXCEPTION, NULL);
+ /* Short sleep to allow hook task to run */
+ k_msleep(1);
+ zassert_true(host_is_event_set(EC_HOST_EVENT_PANIC));
+}
+
ZTEST_SUITE(system_safe_mode, NULL, NULL, system_before, NULL, NULL);
diff --git a/zephyr/test/tasks/CMakeLists.txt b/zephyr/test/tasks/CMakeLists.txt
index b0b59e7c99..52e6723652 100644
--- a/zephyr/test/tasks/CMakeLists.txt
+++ b/zephyr/test/tasks/CMakeLists.txt
@@ -9,6 +9,9 @@ project(tasks)
# Include the local test directory for shimmed_test_tasks.h
zephyr_include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
-target_sources(app PRIVATE
+target_sources_ifdef(CONFIG_HAS_TEST_TASKS app PRIVATE
main.c
"${CMAKE_CURRENT_SOURCE_DIR}/../../shim/src/tasks.c")
+
+target_sources_ifdef(CONFIG_SHIMMED_TASKS app PRIVATE
+ extra_tasks.c)
diff --git a/zephyr/test/tasks/extra_tasks.c b/zephyr/test/tasks/extra_tasks.c
new file mode 100644
index 0000000000..d9c75f4cfe
--- /dev/null
+++ b/zephyr/test/tasks/extra_tasks.c
@@ -0,0 +1,149 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ec_tasks.h"
+#include "host_command.h"
+#include "task.h"
+
+#include <zephyr/kernel.h>
+#include <zephyr/kernel/thread.h>
+#include <zephyr/ztest.h>
+
+k_tid_t get_sysworkq_thread(void);
+k_tid_t get_idle_thread(void);
+
+/* Utilities for finding a Zephyr thread by name */
+static k_tid_t found_thread;
+static void find_thread_by_name_cb(const struct k_thread *thread,
+ void *user_data)
+{
+ const char *name = (const char *)user_data;
+
+ if (strcmp(k_thread_name_get((k_tid_t)thread), name) == 0) {
+ found_thread = (k_tid_t)thread;
+ }
+}
+
+static k_tid_t find_thread_by_name(const char *name)
+{
+ found_thread = NULL;
+ k_thread_foreach_unlocked(find_thread_by_name_cb, (void *)name);
+ return found_thread;
+}
+
+/* Utilities for checking asserts */
+static bool expect_assert;
+static int num_asserts;
+void assert_post_action(const char *file, unsigned int line)
+{
+ num_asserts += 1;
+ if (!expect_assert) {
+ ztest_test_fail();
+ }
+}
+
+#define EXPECT_ASSERT(test) \
+ do { \
+ expect_assert = true; \
+ num_asserts = 0; \
+ (test); \
+ expect_assert = false; \
+ zassert_equal(num_asserts, 1); \
+ } while (0)
+
+ZTEST_USER(extra_tasks, test_hostcmd_thread_mapping)
+{
+ k_tid_t hostcmd_thread;
+ k_tid_t main_thread;
+
+#if IS_ENABLED(HAS_TASK_HOSTCMD)
+#ifdef CONFIG_TASK_HOSTCMD_THREAD_MAIN
+ k_thread_name_set(get_main_thread(), "HOSTCMD");
+#endif /* CONFIG_TASK_HOSTCMD_THREAD_MAIN */
+
+ hostcmd_thread = find_thread_by_name("HOSTCMD");
+ zassert_not_null(hostcmd_thread);
+ zassert_equal(hostcmd_thread, get_hostcmd_thread());
+ zassert_equal(TASK_ID_HOSTCMD, thread_id_to_task_id(hostcmd_thread));
+ zassert_equal(task_id_to_thread_id(TASK_ID_HOSTCMD), hostcmd_thread);
+
+#ifdef CONFIG_TASK_HOSTCMD_THREAD_DEDICATED
+ main_thread = find_thread_by_name("main");
+ zassert_not_null(main_thread);
+ zassert_equal(main_thread, get_main_thread());
+ zassert_not_equal(main_thread, hostcmd_thread);
+ zassert_equal(TASK_ID_MAIN, thread_id_to_task_id(main_thread));
+ zassert_equal(task_id_to_thread_id(TASK_ID_MAIN), main_thread);
+#else
+ main_thread = get_main_thread();
+ zassert_not_null(main_thread);
+ zassert_equal(main_thread, hostcmd_thread);
+#endif /* CONFIG_TASK_HOSTCMD_THREAD_DEDICATED */
+
+#else /* !HAS_TASK_HOSTCMD */
+ hostcmd_thread = find_thread_by_name("HOSTCMD");
+ zassert_is_null(hostcmd_thread);
+ EXPECT_ASSERT(hostcmd_thread = get_hostcmd_thread());
+ zassert_is_null(hostcmd_thread);
+
+ main_thread = find_thread_by_name("main");
+ zassert_not_null(main_thread);
+ zassert_equal(main_thread, get_main_thread());
+#endif /* HAS_TASK_HOSTCMD */
+}
+
+ZTEST_USER(extra_tasks, test_sysworkq_thread_mapping)
+{
+ k_tid_t sysworkq_thread;
+
+ sysworkq_thread = find_thread_by_name("sysworkq");
+ zassert_not_null(sysworkq_thread);
+ zassert_equal(sysworkq_thread, get_sysworkq_thread());
+ zassert_equal(TASK_ID_SYSWORKQ, thread_id_to_task_id(sysworkq_thread));
+ zassert_equal(task_id_to_thread_id(TASK_ID_SYSWORKQ), sysworkq_thread);
+}
+
+ZTEST_USER(extra_tasks, test_idle_thread_mapping)
+{
+ k_tid_t idle_thread;
+
+ idle_thread = find_thread_by_name("idle");
+ zassert_not_null(idle_thread);
+ zassert_equal(idle_thread, get_idle_thread());
+ zassert_equal(TASK_ID_IDLE, thread_id_to_task_id(idle_thread));
+ zassert_equal(task_id_to_thread_id(TASK_ID_IDLE), idle_thread);
+}
+
+ZTEST_USER(extra_tasks, test_invalid_task_id)
+{
+ k_tid_t thread_id;
+
+ EXPECT_ASSERT(thread_id = task_id_to_thread_id(TASK_ID_INVALID));
+ zassert_is_null(thread_id);
+
+ EXPECT_ASSERT(thread_id = task_id_to_thread_id(-1));
+ zassert_is_null(thread_id);
+}
+
+ZTEST_USER(extra_tasks, test_invalid_thread_id)
+{
+ task_id_t task_id;
+
+ EXPECT_ASSERT(task_id = thread_id_to_task_id(NULL));
+ zassert_equal(task_id, TASK_ID_INVALID);
+
+ EXPECT_ASSERT(task_id = thread_id_to_task_id((k_tid_t)0x1234));
+ zassert_equal(task_id, TASK_ID_INVALID);
+}
+
+ZTEST_USER(extra_tasks, test_extra_task_enumeration)
+{
+ for (task_id_t task_id = 0; task_id < TASK_ID_COUNT + EXTRA_TASK_COUNT;
+ task_id++) {
+ zassert_not_null(task_id_to_thread_id(task_id));
+ }
+}
+
+ZTEST_SUITE(extra_tasks, NULL, NULL, NULL, NULL, NULL);
diff --git a/zephyr/test/tasks/main.c b/zephyr/test/tasks/main.c
index bbf752c656..dc3df59ca7 100644
--- a/zephyr/test/tasks/main.c
+++ b/zephyr/test/tasks/main.c
@@ -10,6 +10,7 @@
#include <stdbool.h>
#include <zephyr/kernel.h>
+#include <zephyr/kernel/thread.h>
#include <zephyr/ztest.h>
/* Second for platform/ec task API (in microseconds). */
@@ -273,6 +274,23 @@ static void empty_set_mask2(void)
zassert_within(end_ms - start_ms, 2000, 100, "Timeout for 2 seconds");
}
+static void check_task_1_mapping(void)
+{
+ zassert_equal(TASK_ID_TASK_1, thread_id_to_task_id(k_current_get()));
+ zassert_equal(k_current_get(), task_id_to_thread_id(TASK_ID_TASK_1));
+}
+
+static void check_task_2_mapping(void)
+{
+ zassert_equal(TASK_ID_TASK_2, thread_id_to_task_id(k_current_get()));
+ zassert_equal(k_current_get(), task_id_to_thread_id(TASK_ID_TASK_2));
+}
+
+static void test_thread_to_task_mapping(void)
+{
+ run_test(&check_task_1_mapping, &check_task_2_mapping);
+}
+
static void test_empty_set_mask(void)
{
run_test(&empty_set_mask1, &empty_set_mask2);
@@ -289,6 +307,7 @@ void test_main(void)
ztest_unit_test(test_event_delivered),
ztest_unit_test(test_event_mask_not_delivered),
ztest_unit_test(test_event_mask_extra),
- ztest_unit_test(test_empty_set_mask));
+ ztest_unit_test(test_empty_set_mask),
+ ztest_unit_test(test_thread_to_task_mapping));
ztest_run_test_suite(test_task_shim);
}
diff --git a/zephyr/test/tasks/prj.conf b/zephyr/test/tasks/prj.conf
index 6c8e2fbc90..67deb38144 100644
--- a/zephyr/test/tasks/prj.conf
+++ b/zephyr/test/tasks/prj.conf
@@ -3,7 +3,9 @@
# found in the LICENSE file.
CONFIG_ZTEST=y
-CONFIG_HAS_TEST_TASKS=y
CONFIG_PLATFORM_EC=y
CONFIG_CROS_EC=y
-CONFIG_PLATFORM_EC_HOOKS=n
+CONFIG_TASKS_SET_TEST_RUNNER_TID_RULE=y
+CONFIG_PLATFORM_EC_VBOOT_HASH=n
+CONFIG_PLATFORM_EC_BACKLIGHT_LID=n
+CONFIG_PLATFORM_EC_SWITCH=n
diff --git a/zephyr/test/tasks/testcase.yaml b/zephyr/test/tasks/testcase.yaml
index a72199a14a..c079930c6c 100644
--- a/zephyr/test/tasks/testcase.yaml
+++ b/zephyr/test/tasks/testcase.yaml
@@ -5,4 +5,26 @@
common:
platform_allow: native_posix
tests:
- tasks.default: {}
+ tasks.default:
+ extra_configs:
+ - CONFIG_HAS_TEST_TASKS=y
+ tasks.extra_tasks:
+ extra_configs:
+ - CONFIG_ZTEST_NEW_API=y
+ - CONFIG_SHIMMED_TASKS=y
+ - CONFIG_ASSERT_TEST=y
+ - CONFIG_PLATFORM_EC_HOSTCMD=n
+ tasks.extra_tasks.hostcmd_main:
+ extra_configs:
+ - CONFIG_ZTEST_NEW_API=y
+ - CONFIG_SHIMMED_TASKS=y
+ - CONFIG_ASSERT_TEST=y
+ - CONFIG_PLATFORM_EC_HOSTCMD=y
+ - CONFIG_TASK_HOSTCMD_THREAD_MAIN=y
+ tasks.extra_tasks.hostcmd_dedicated:
+ extra_configs:
+ - CONFIG_ZTEST_NEW_API=y
+ - CONFIG_SHIMMED_TASKS=y
+ - CONFIG_ASSERT_TEST=y
+ - CONFIG_PLATFORM_EC_HOSTCMD=y
+ - CONFIG_TASK_HOSTCMD_THREAD_DEDICATED=y
diff --git a/zephyr/test/vboot_efs2/boards/native_posix.overlay b/zephyr/test/vboot_efs2/boards/native_posix.overlay
index 83b9e9b365..54bc09ace0 100644
--- a/zephyr/test/vboot_efs2/boards/native_posix.overlay
+++ b/zephyr/test/vboot_efs2/boards/native_posix.overlay
@@ -89,7 +89,7 @@
compatible = "cros,tcpci-generic-emul";
status = "okay";
reg = <0x82>;
- alert_gpio = <&usb_c0_tcpc_int_odl>;
+ irq-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
};
};
adc0: adc {
diff --git a/zephyr/zmake/bazel_main.py b/zephyr/zmake/bazel_main.py
new file mode 100644
index 0000000000..3df8636c1a
--- /dev/null
+++ b/zephyr/zmake/bazel_main.py
@@ -0,0 +1,16 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Entry point for Bazel execution.
+
+Bazel can't use zmake/__main__.py as it puts the main in PYTHONPATH.
+"""
+
+import sys
+
+from zmake import __main__
+
+
+if __name__ == "__main__":
+ sys.exit(__main__.main())
diff --git a/zephyr/zmake/setup.py b/zephyr/zmake/setup.py
index b7e58ef803..6e986ef8d0 100644
--- a/zephyr/zmake/setup.py
+++ b/zephyr/zmake/setup.py
@@ -5,6 +5,7 @@
"""Configuration to allow pip install."""
import setuptools
+
setuptools.setup(
name="zephyr-chrome-utils",
version="0.1",
diff --git a/zephyr/zmake/tests/conftest.py b/zephyr/zmake/tests/conftest.py
index dfea10457c..af56f794cc 100644
--- a/zephyr/zmake/tests/conftest.py
+++ b/zephyr/zmake/tests/conftest.py
@@ -11,6 +11,7 @@ import hypothesis # pylint:disable=import-error
import pytest # pylint:disable=import-error
import zmake.zmake as zm
+
hypothesis.settings.register_profile(
"cq", suppress_health_check=hypothesis.HealthCheck.all()
)
diff --git a/zephyr/zmake/tests/test_build_config.py b/zephyr/zmake/tests/test_build_config.py
index f0497fc4d5..6b4ab203b6 100644
--- a/zephyr/zmake/tests/test_build_config.py
+++ b/zephyr/zmake/tests/test_build_config.py
@@ -13,9 +13,10 @@ import tempfile
import hypothesis # pylint:disable=import-error
import hypothesis.strategies as st # pylint:disable=import-error
import pytest # pylint:disable=import-error
+from zmake.build_config import BuildConfig
import zmake.jobserver
import zmake.util as util
-from zmake.build_config import BuildConfig
+
# pylint:disable=redefined-outer-name,unused-argument
diff --git a/zephyr/zmake/tests/test_jobserver.py b/zephyr/zmake/tests/test_jobserver.py
index a79e6dc280..d9f4f63163 100644
--- a/zephyr/zmake/tests/test_jobserver.py
+++ b/zephyr/zmake/tests/test_jobserver.py
@@ -4,10 +4,10 @@
"""Test jobserver functionality."""
+from asyncio import subprocess
import logging
import os
import threading
-from asyncio import subprocess
import pytest # pylint:disable=import-error
import zmake.jobserver
diff --git a/zephyr/zmake/tests/test_modules.py b/zephyr/zmake/tests/test_modules.py
index dc4c170535..a42192d789 100644
--- a/zephyr/zmake/tests/test_modules.py
+++ b/zephyr/zmake/tests/test_modules.py
@@ -11,6 +11,7 @@ import hypothesis # pylint:disable=import-error
import hypothesis.strategies as st # pylint:disable=import-error
import zmake.modules
+
module_lists = st.lists(
st.one_of(*map(st.just, zmake.modules.known_modules)), unique=True
)
diff --git a/zephyr/zmake/tests/test_packers.py b/zephyr/zmake/tests/test_packers.py
index 23bdb2bf6b..441e5db7e6 100644
--- a/zephyr/zmake/tests/test_packers.py
+++ b/zephyr/zmake/tests/test_packers.py
@@ -12,6 +12,7 @@ import hypothesis.strategies as st # pylint:disable=import-error
import pytest # pylint:disable=import-error
import zmake.output_packers as packers
+
# Strategies for use with hypothesis
absolute_path = st.from_regex(regex=r"\A/[\w/]*\Z")
diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py
index 3225de1d75..661072959d 100644
--- a/zephyr/zmake/tests/test_project.py
+++ b/zephyr/zmake/tests/test_project.py
@@ -15,6 +15,7 @@ import zmake.modules
import zmake.output_packers
import zmake.project
+
board_names = st.text(alphabet=set(string.ascii_lowercase) | {"_"}, min_size=1)
sets_of_board_names = st.lists(st.lists(board_names, unique=True))
diff --git a/zephyr/zmake/tests/test_toolchains.py b/zephyr/zmake/tests/test_toolchains.py
index 703149179c..2a71fd0d60 100644
--- a/zephyr/zmake/tests/test_toolchains.py
+++ b/zephyr/zmake/tests/test_toolchains.py
@@ -12,6 +12,7 @@ import zmake.output_packers
import zmake.project as project
import zmake.toolchains as toolchains
+
# pylint:disable=redefined-outer-name,unused-argument
diff --git a/zephyr/zmake/tests/test_util.py b/zephyr/zmake/tests/test_util.py
index c5efa2d18e..70378073d4 100644
--- a/zephyr/zmake/tests/test_util.py
+++ b/zephyr/zmake/tests/test_util.py
@@ -12,6 +12,7 @@ import hypothesis.strategies as st # pylint:disable=import-error
import pytest # pylint:disable=import-error
import zmake.util as util
+
# Strategies for use with hypothesis
version_integers = st.integers(min_value=0)
version_tuples = st.tuples(version_integers, version_integers, version_integers)
diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py
index d6202c0d85..8881522e4b 100644
--- a/zephyr/zmake/tests/test_version.py
+++ b/zephyr/zmake/tests/test_version.py
@@ -13,6 +13,7 @@ import zmake.output_packers
import zmake.project
import zmake.version as version
+
# pylint:disable=redefined-outer-name,unused-argument
diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py
index ff528edb8f..8fd39f1e9e 100644
--- a/zephyr/zmake/tests/test_zmake.py
+++ b/zephyr/zmake/tests/test_zmake.py
@@ -11,13 +11,14 @@ import re
import unittest.mock
import pytest # pylint:disable=import-error
+from testfixtures import LogCapture # pylint:disable=import-error
import zmake.build_config
import zmake.jobserver
import zmake.multiproc as multiproc
import zmake.output_packers
import zmake.project
import zmake.toolchains
-from testfixtures import LogCapture # pylint:disable=import-error
+
OUR_PATH = os.path.dirname(os.path.realpath(__file__))
diff --git a/zephyr/zmake/zmake/configlib.py b/zephyr/zmake/zmake/configlib.py
index 139394745f..2affaf08f5 100644
--- a/zephyr/zmake/zmake/configlib.py
+++ b/zephyr/zmake/zmake/configlib.py
@@ -48,9 +48,11 @@ def register_binman_project(**kwargs):
def register_npcx_project(**kwargs):
"""Register a project that uses NpcxPacker."""
kwargs.setdefault("output_packer", zmake.output_packers.NpcxPacker)
+ kwargs.setdefault("modules", ["ec", "cmsis"])
return register_binman_project(**kwargs)
def register_mchp_project(**kwargs):
kwargs.setdefault("output_packer", zmake.output_packers.MchpPacker)
+ kwargs.setdefault("modules", ["ec", "cmsis"])
return register_binman_project(**kwargs)
diff --git a/zephyr/zmake/zmake/multiproc.py b/zephyr/zmake/zmake/multiproc.py
index a668bcb961..61163b2df5 100644
--- a/zephyr/zmake/zmake/multiproc.py
+++ b/zephyr/zmake/zmake/multiproc.py
@@ -18,6 +18,7 @@ import select
import threading
from typing import Any, ClassVar, Dict, List
+
# Should we log job names or not
LOG_JOB_NAMES = True
diff --git a/zephyr/zmake/zmake/output_packers.py b/zephyr/zmake/zmake/output_packers.py
index e0e342fd66..ce3099077c 100644
--- a/zephyr/zmake/zmake/output_packers.py
+++ b/zephyr/zmake/zmake/output_packers.py
@@ -3,9 +3,9 @@
# found in the LICENSE file.
"""Types which provide many builds and composite them into a single binary."""
import logging
+from pathlib import Path
import shutil
import subprocess
-from pathlib import Path
from typing import Dict, Optional
import zmake.build_config as build_config
diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py
index a707da2462..15974af723 100644
--- a/zephyr/zmake/zmake/project.py
+++ b/zephyr/zmake/zmake/project.py
@@ -1,6 +1,7 @@
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+
"""Module for project config wrapper object."""
import dataclasses
@@ -43,8 +44,8 @@ class ProjectConfig:
zephyr_board: str
supported_toolchains: "list[str]"
output_packer: type
- modules: "dict[str, typing.Any]" = dataclasses.field(
- default_factory=lambda: zmake.modules.known_modules,
+ modules: typing.Iterable[str] = dataclasses.field(
+ default_factory=lambda: ["ec"],
)
is_test: bool = dataclasses.field(default=False)
test_args: typing.List[str] = dataclasses.field(default_factory=list)
diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py
index 30d56cc08f..731a409268 100644
--- a/zephyr/zmake/zmake/zmake.py
+++ b/zephyr/zmake/zmake/zmake.py
@@ -25,6 +25,7 @@ import zmake.project
import zmake.util as util
import zmake.version
+
ninja_warnings = re.compile(r"^(\S*: )?warning:.*")
ninja_errors = re.compile(r"error:.*")