diff options
author | Aseda Aboagye <aaboagye@google.com> | 2022-01-10 17:26:56 -0600 |
---|---|---|
committer | Aseda Aboagye <aaboagye@google.com> | 2022-01-10 17:26:56 -0600 |
commit | dc11829e169a9c425860ec5cca949ef80df9e0b7 (patch) | |
tree | 0517b0831c6e52b347926a1b727741df380e908c | |
parent | c5bd23a4b204565dab616f7fa4ee8a0b7b433d4c (diff) | |
parent | b44d10f8f79cadb259cc7ab79714a0919fc0c4c8 (diff) | |
download | chrome-ec-firmware-keeby-14119.B-main.tar.gz |
Merge remote-tracking branch cros/main into firmware-keeby-14119.B-mainfirmware-keeby-14119.B-main
Relevant changes:
git log --oneline c5bd23a4b..b44d10f8f -- baseboard/dedede board/cappy2
board/corori board/driblee board/gooey board/haboki board/lalala
board/waddledoo2 common/charge_state_v2.c common/mkbp_* common/ocpc.c
common/usbc/usb_tc_drp_acc_trysrc_sm.c common/usbc/usb_sm.c
common/usbc/*_pd_* common/usbc/dp_alt_mode.c common/usbc/usb_prl_sm.c
common/usbc/usb_pe_drp_sm.c common/usb_charger.c common/usb_common.c
common/usbc_ocp.c driver/charger/sm5803.* driver/charger/isl923x.*
driver/tcpm/raa489000.* driver/tcpm/it83* include/power/icelake.h
include/intel_x86.h power/icelake.c power/intel_x86.c util/getversion.sh
42d03a001 config: change temp_sensor_power from config to gpio
e296efb28 usb_common: Fix CONFIG_USB_PD_DISCHARGE_TCPC typo
c346481f4 atomic: cast to unsigned when shifting
9b972a0f2 driver/tcpm/it83xx, it8xxx2: ITE inactive port return from HOOK
a499d8fd4 driver/tcpm/it83xx, it8xxx2: set sleep mask for mixed TCPC case
ed62e2583 TCPMv2: don't set the sleep mask for TCPC embedded in EC
c962696e8 motion_sensor: Remove |int_signal| field
86b216794 ocpc: modify pre-charge target condition
6f8336eb4 dedede: Set MKBP event wake mask to 0
02d034df0 dedede: add stylus fw_config
4f7cd7509 atomic: use atomic_t where it is possible
e3ffa0519 mkbp: change the type fifo_entries to atomic_t
bb4c47af0 usb: use atomic_t where possible
c6e513ee2 power/icelake: Add SLP_S5 as a watched power signal
d89e49b20 power: Introduce S4 as a real power state
ba8a3c9c0 chgstv2: Use chipset_in_state instead of naming states
23a975d12 i2c: Use declared initializers for i2c_ports: boards a-l
35865dbec TCPMv2: Guard DATA_RESET using CONFIG_USB_PD_DATA_RESET_MSG
d4d8243ed i2c: Use declared initializers for i2c_ports: baseboards
eba8d0305 RAA489000: Fixed RAA489000 max charging current
e78b83e0f TCPMv2: Delay Data Reset until mode entry request
6230e60fc TCPMv2: Support Data Reset as DFP, initiator
412246836 intel_x86: Apply chipset resume init and suspend complete hooks
f2809b72c config: rename CONFIG_HOSTCMD_ESPI to CONFIG_HOST_INTERFACE_ESPI
BRANCH=None
BUG=b:202796060 b:207805856 b:167983049 b:208318528 b:181983966
BUG=b:207328258 b:195416058 b:205285137 b:199919093 b:207055975
BUG=b:129159505 b:204947672 b:141363146 b:207082842 b:205675485
TEST=`make -j buildall`
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Change-Id: I980351977e11088a130e478df0701be4715f049b
1087 files changed, 34310 insertions, 9243 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8936070470..845c7bd654 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ cache: - .cache/pip - venv/ - modules/ - - zephyr/main + - zephyr/ # The directory structure is: @@ -34,11 +34,9 @@ cache: before_script: - export MODULES_DIR="$CI_PROJECT_DIR/modules" - mkdir -p "${MODULES_DIR}" - - export ZEPHYR_ROOT="$CI_PROJECT_DIR/zephyr/main" - - mkdir -p "${ZEPHYR_ROOT}" - - test -d "${ZEPHYR_ROOT}/v2.6" || git clone --depth 1 -b chromeos-v2.6 https://chromium.googlesource.com/chromiumos/third_party/zephyr "${ZEPHYR_ROOT}/v2.6" - - test -d "${ZEPHYR_ROOT}/v2.7" || git clone --depth 1 -b chromeos-v2.7 https://chromium.googlesource.com/chromiumos/third_party/zephyr "${ZEPHYR_ROOT}/v2.7" - - test -d "${ZEPHYR_ROOT}/v2.8" || git clone --depth 1 -b chromeos-v2.8 https://chromium.googlesource.com/chromiumos/third_party/zephyr "${ZEPHYR_ROOT}/v2.8" + - export ZEPHYR_BASE="${CI_PROJECT_DIR}/zephyr/main" + - mkdir -p "${ZEPHYR_BASE}" + - test -d "${ZEPHYR_BASE}/.git" || git clone --depth 1 -b main https://chromium.googlesource.com/chromiumos/third_party/zephyr "${ZEPHYR_BASE}" - test -d "${MODULES_DIR}/cmsis" || git clone --depth 1 -b chromeos-main https://chromium.googlesource.com/chromiumos/third_party/zephyr/cmsis "${MODULES_DIR}/cmsis" - test -d "${MODULES_DIR}/hal_stm32" || git clone --depth 1 -b chromeos-main https://chromium.googlesource.com/chromiumos/third_party/zephyr/hal_stm32 "${MODULES_DIR}/hal_stm32" - test -d "${MODULES_DIR}/nanopb" || git clone --depth 1 -b main https://chromium.googlesource.com/chromiumos/third_party/zephyr/nanopb "${MODULES_DIR}/nanopb" @@ -46,9 +44,8 @@ before_script: - ln -s "$(pwd)" "${MODULES_DIR}/ec" - python3 -V # Print out python version for debugging - python3 -m pip install zephyr/zmake --user - - python3 -m pip install pyyaml + - python3 -m pip install pyyaml packaging - export BUILD_DIR=build - - export ZEPHYR_DIR=/zephyr - export PATH="$PATH:$HOME/.local/bin" - export PYTHONIOENCODING=utf-8 - export EC_DIR=/builds/zephyr-ec/ec @@ -62,10 +59,10 @@ seed_cache: - .cache/pip - venv/ - modules/ - - zephyr/main + - zephyr/ policy: push script: - - ls "${MODULES_DIR}" "${ZEPHYR_ROOT}" + - ls "${MODULES_DIR}" "${ZEPHYR_BASE}" # Users of this template must set: # $PROJECT to the project to build. E.g., "lazor" @@ -73,7 +70,7 @@ seed_cache: stage: build needs: ["seed_cache"] script: - - zmake --zephyr-root "${ZEPHYR_ROOT}" + - zmake --zephyr-base "${ZEPHYR_BASE}" --modules-dir "${MODULES_DIR}" -l DEBUG configure -b -B "${BUILD_DIR}/${PROJECT}" -t ${TOOLCHAIN:-zephyr} "${PROJECT}" @@ -92,17 +89,48 @@ seed_cache: # Users of this template must set: # $PROJECT to the project to build. E.g., "lazor" +# Builds the project with coverage enabled, removes the non-ec files. +# Then merges with the tests, excludes all files not used by this project, +# and generates a report. .coverage_template: &coverage_template stage: test - needs: ["merged_coverage", "zephyr_coverage"] + needs: ["merged_coverage", "zephyr_coverage", "twister_coverage"] script: - - grep "SF:" "build/zcoverage/${PROJECT}.info" | sort -u | sed -e 's|^SF:||' | xargs lcov -o build/no_zephyr_${PROJECT}.info -e build/merged_no_zephyr.info - - /usr/bin/genhtml -q -o build/no_zephyr_${PROJECT}_rpt -t "${PROJECT} coverage w/o zephyr" -p ${EC_DIR} -s build/no_zephyr_${PROJECT}.info + - zmake --zephyr-base "${ZEPHYR_BASE}" + --modules-dir "${MODULES_DIR}" -l DEBUG configure -b --coverage + -B "${BUILD_DIR}/${PROJECT}" -t ${TOOLCHAIN:-zephyr} + "${PROJECT}" + - lcov -o "${BUILD_DIR}/${PROJECT}/merged_twister.info" -a "${BUILD_DIR}/${PROJECT}/lcov.info" -a "${BUILD_DIR}/zephyr_codecov/fixed.info" + - lcov -o "${BUILD_DIR}/${PROJECT}/merged_twister_no_ec.info" -e "${BUILD_DIR}/${PROJECT}/merged_twister.info" "${ZEPHYR_BASE}/**" "${MODULES_DIR}/**" + - grep "SF:" "${BUILD_DIR}/${PROJECT}/lcov.info" | sort -u | + sed -e 's|^SF:||' | xargs lcov + -o "${BUILD_DIR}/${PROJECT}/filtered_twister.info" + -e "${BUILD_DIR}/${PROJECT}/merged_twister_no_ec.info" + - /usr/bin/genhtml -q -o "${BUILD_DIR}/${PROJECT}/filtered_twister_rpt" + -t "${PROJECT} coverage of twister tests" + -s "${BUILD_DIR}/${PROJECT}/filtered_twister.info" + - lcov -o "${BUILD_DIR}/${PROJECT}/merged.info" + -a "${BUILD_DIR}/${PROJECT}/lcov.info" -a build/merged.info + - lcov -o "${BUILD_DIR}/${PROJECT}/no_zephyr.info" + -r "${BUILD_DIR}/${PROJECT}/lcov.info" "${ZEPHYR_BASE}/**" + "${MODULES_DIR}/*" "${EC_DIR}/zephyr/drivers/*" '/usr/include/x86_64-linux-gnu/*' + - lcov -o "${BUILD_DIR}/${PROJECT}/merged_no_zephyr.info" + -r "${BUILD_DIR}/${PROJECT}/merged.info" "${ZEPHYR_BASE}/**" + "${MODULES_DIR}/*" "${EC_DIR}/zephyr/drivers/*" '/usr/include/x86_64-linux-gnu/*' + - grep "SF:" "${BUILD_DIR}/${PROJECT}/no_zephyr.info" | sort -u | + sed -e 's|^SF:||' | xargs lcov + -o "${BUILD_DIR}/${PROJECT}/filtered_no_zephyr.info" + -e "${BUILD_DIR}/${PROJECT}/merged_no_zephyr.info" + - /usr/bin/genhtml -q -o "${BUILD_DIR}/${PROJECT}/filtered_no_zephyr_rpt" + -t "${PROJECT} coverage w/o zephyr" + -p ${EC_DIR} + -s "${BUILD_DIR}/${PROJECT}/filtered_no_zephyr.info" artifacts: paths: - - build/*.info - - build/*_rpt + - build/${PROJECT}/*.info + - build/${PROJECT}/*_rpt expire_in: 1 week + when: always coverage: '/lines\.*: \d+\.\d+%/' delbin: @@ -115,6 +143,11 @@ hayato: PROJECT: "hayato" <<: *build_template +hayato_coverage: + variables: + PROJECT: "hayato" + <<: *coverage_template + herobrine_npcx9: variables: PROJECT: "herobrine_npcx9" @@ -130,6 +163,26 @@ it8xxx2_evb: PROJECT: "it8xxx2_evb" <<: *build_template +kingler: + variables: + PROJECT: "kingler" + <<: *build_template + +kingler_coverage: + variables: + PROJECT: "kingler" + <<: *coverage_template + +krabby: + variables: + PROJECT: "krabby" + <<: *build_template + +krabby_coverage: + variables: + PROJECT: "krabby" + <<: *coverage_template + lazor: variables: PROJECT: "lazor" @@ -141,6 +194,16 @@ native_posix: TOOLCHAIN: "host" <<: *build_template +skyrim: + variables: + PROJECT: "skyrim" + <<: *build_template + +skyrim_coverage: + variables: + PROJECT: "skyrim" + <<: *coverage_template + volteer: variables: PROJECT: "volteer" @@ -165,7 +228,7 @@ zephyr_coverage: stage: test needs: ["seed_cache"] script: - - zmake --zephyr-root "${ZEPHYR_ROOT}" + - zmake --zephyr-base "${ZEPHYR_BASE}" --modules-dir "${MODULES_DIR}" -l DEBUG coverage "${BUILD_DIR}/zcoverage" artifacts: @@ -180,7 +243,12 @@ merged_coverage: needs: ["ec_coverage", "zephyr_coverage"] script: - lcov -o build/merged.info -a build/coverage/lcov.info -a build/zcoverage/lcov.info - - lcov -o build/merged_no_zephyr.info -r build/merged.info "${ZEPHYR_ROOT}/*" "${MODULES_DIR}/*" "zephyr/drivers/*" '/usr/include/x86_64-linux-gnu/*' + - lcov -o build/merged_no_zephyr.info -r build/merged.info + "${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/projects/**" + '/usr/include/x86_64-linux-gnu/**' artifacts: paths: - build/*.info @@ -192,6 +260,31 @@ testall: stage: test needs: ["seed_cache"] script: - - zmake --zephyr-root "${ZEPHYR_ROOT}" + - zmake --zephyr-base "${ZEPHYR_BASE}" --modules-dir "${MODULES_DIR}" -l DEBUG testall +twister_coverage: + stage: test + needs: ["seed_cache"] + script: + - mkdir -p build/zephyr_codecov + - for commitid in $(cd "${ZEPHYR_BASE}" ; git fetch --depth=100 ; git log | awk '/GitOrigin-RevId:/ {print $2}') ; do + echo "COMMITID = ${commitid?}" ; + if wget -O /tmp/coverage.html "https://codecov.io/gh/zephyrproject-rtos/zephyr/commit/${commitid?}/build" ; then + downloadurl=$(sed -e '/download\/build/!d' -e 's|^.*href="|https://codecov.io|' -e 's|".*$||' /tmp/coverage.html | head -1) ; + echo "DOWNLOADURL = ${downloadurl?}" ; + wget -O build/zephyr_codecov/merged.info.raw "${downloadurl?}" ; + sed <build/zephyr_codecov/merged.info.raw >build/zephyr_codecov/merged.info + -e '1,/<<<<<< network/d' -e '/<<<<<< EOF/,$d' ; + sed <build/zephyr_codecov/merged.info >build/zephyr_codecov/fixed.info + -e "s|/__w/zephyr/zephyr|${ZEPHYR_BASE}|" + -e "s|/__w/zephyr/modules/hal/cmsis|${MODULES_DIR}/cmsis|" + -e "s|/__w/zephyr/modules|${MODULES_DIR}|" ; + break ; + fi ; + done + - lcov --summary build/zephyr_codecov/fixed.info + artifacts: + paths: + - build/zephyr_codecov/fixed.info + expire_in: 1 week diff --git a/Makefile.toolchain b/Makefile.toolchain index a56193201a..ddb6e82ffa 100644 --- a/Makefile.toolchain +++ b/Makefile.toolchain @@ -95,8 +95,7 @@ CFLAGS_TEST=$(if $(TEST_BUILD),-DTEST_BUILD=$(EMPTY) \ $(if $(TEST_ASAN),-fsanitize=address) \ $(if $(TEST_MSAN),-fsanitize=memory) \ $(if $(TEST_UBSAN),$(UBSAN_FLAGS)) \ - $(if $(TEST_FUZZ),-fsanitize=fuzzer-no-link \ - -fno-experimental-new-pass-manager -DTEST_FUZZ=$(EMPTY)) + $(if $(TEST_FUZZ),-fsanitize=fuzzer-no-link -DTEST_FUZZ=$(EMPTY)) CFLAGS_COVERAGE=$(if $(TEST_COVERAGE),--coverage \ -DTEST_COVERAGE=$(EMPTY),) CFLAGS_HOSTTEST=$(if $(TEST_HOSTTEST),-DTEST_HOSTTEST=$(EMPTY),) -Iinclude/driver diff --git a/baseboard/asurada/baseboard.c b/baseboard/asurada/baseboard.c index c89348a562..c0ba896e61 100644 --- a/baseboard/asurada/baseboard.c +++ b/baseboard/asurada/baseboard.c @@ -71,10 +71,34 @@ int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"bat_chg", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, - {"sensor", IT83XX_I2C_CH_B, 400, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"usb0", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"usb1", IT83XX_I2C_CH_E, 400, GPIO_I2C_E_SCL, GPIO_I2C_E_SDA}, + { + .name = "bat_chg", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C_A_SCL, + .sda = GPIO_I2C_A_SDA + }, + { + .name = "sensor", + .port = IT83XX_I2C_CH_B, + .kbps = 400, + .scl = GPIO_I2C_B_SCL, + .sda = GPIO_I2C_B_SDA + }, + { + .name = "usb0", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C_C_SCL, + .sda = GPIO_I2C_C_SDA + }, + { + .name = "usb1", + .port = IT83XX_I2C_CH_E, + .kbps = 400, + .scl = GPIO_I2C_E_SCL, + .sda = GPIO_I2C_E_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/asurada/usb_pd_policy.c b/baseboard/asurada/usb_pd_policy.c index f9ba7e5a4d..6a7621f450 100644 --- a/baseboard/asurada/usb_pd_policy.c +++ b/baseboard/asurada/usb_pd_policy.c @@ -155,7 +155,7 @@ __override void svdm_exit_dp_mode(int port) int pd_snk_is_vbus_provided(int port) { - static int vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; + static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; int vbus; if ((IS_ENABLED(BOARD_HAYATO) && board_get_version() < 4) || diff --git a/baseboard/brask/baseboard.h b/baseboard/brask/baseboard.h index 19f8aef126..66a10c7197 100644 --- a/baseboard/brask/baseboard.h +++ b/baseboard/brask/baseboard.h @@ -41,8 +41,9 @@ #define CONFIG_BOARD_RESET_AFTER_POWER_ON /* Host communication */ -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S5 #define CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST /* LED */ @@ -72,6 +73,7 @@ #define CONFIG_CPU_PROCHOT_ACTIVE_LOW #define CONFIG_EXTPOWER_GPIO #define CONFIG_POWER_S0IX +#define CONFIG_POWER_S4_RESIDENCY #define CONFIG_POWER_SLEEP_FAILURE_DETECTION #define CONFIG_POWER_TRACK_HOST_SLEEP_STATE diff --git a/baseboard/brya/baseboard.h b/baseboard/brya/baseboard.h index 9d12792dbe..98c8f3dbd6 100644 --- a/baseboard/brya/baseboard.h +++ b/baseboard/brya/baseboard.h @@ -45,8 +45,9 @@ #define CONFIG_BOARD_RESET_AFTER_POWER_ON /* Host communication */ -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S5 /* * TODO(b/179648721): implement sensors @@ -105,6 +106,7 @@ #define CONFIG_POWER_BUTTON #define CONFIG_POWER_BUTTON_X86 #define CONFIG_POWER_S0IX +#define CONFIG_POWER_S4_RESIDENCY #define CONFIG_POWER_SLEEP_FAILURE_DETECTION #define CONFIG_POWER_TRACK_HOST_SLEEP_STATE #define CONFIG_LOW_POWER_IDLE diff --git a/baseboard/brya/cbi.c b/baseboard/brya/cbi.c index 6d9e2b93fa..791abbab88 100644 --- a/baseboard/brya/cbi.c +++ b/baseboard/brya/cbi.c @@ -10,8 +10,8 @@ #include "cros_board_info.h" #include "hooks.h" -#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args) +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) static uint8_t board_id; diff --git a/baseboard/cherry/baseboard.c b/baseboard/cherry/baseboard.c index 9cd2ccbef5..d48e0d7d35 100644 --- a/baseboard/cherry/baseboard.c +++ b/baseboard/cherry/baseboard.c @@ -148,7 +148,7 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, { .i2c_port = I2C_PORT_PPC1, - .i2c_addr_flags = RT1718S_I2C_ADDR_FLAGS, + .i2c_addr_flags = RT1718S_I2C_ADDR1_FLAGS, .drv = &rt1718s_ppc_drv, }, }; @@ -282,7 +282,7 @@ const struct usb_mux usbc1_virtual_mux = { .hpd_update = &virtual_hpd_update, }; -static int board_ps8802_mux_set(const struct usb_mux *me, +static int board_ps8762_mux_set(const struct usb_mux *me, mux_state_t mux_state) { /* Make sure the PS8802 is awake */ @@ -311,6 +311,15 @@ static int board_ps8802_mux_set(const struct usb_mux *me, return EC_SUCCESS; } +static int board_ps8762_mux_init(const struct usb_mux *me) +{ + return ps8802_i2c_field_update8( + me, PS8802_REG_PAGE1, + PS8802_REG_DCIRX, + PS8802_AUTO_DCI_MODE_DISABLE | PS8802_FORCE_DCI_MODE, + PS8802_AUTO_DCI_MODE_DISABLE); +} + static int board_anx3443_mux_set(const struct usb_mux *me, mux_state_t mux_state) { @@ -326,7 +335,8 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_addr_flags = PS8802_I2C_ADDR_FLAGS, .driver = &ps8802_usb_mux_driver, .next_mux = &usbc0_virtual_mux, - .board_set = &board_ps8802_mux_set, + .board_init = &board_ps8762_mux_init, + .board_set = &board_ps8762_mux_set, }, { .usb_port = 1, @@ -357,10 +367,34 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"bat_chg", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, - {"sensor", IT83XX_I2C_CH_B, 400, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"usb0", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"usb1", IT83XX_I2C_CH_E, 1000, GPIO_I2C_E_SCL, GPIO_I2C_E_SDA}, + { + .name = "bat_chg", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C_A_SCL, + .sda = GPIO_I2C_A_SDA + }, + { + .name = "sensor", + .port = IT83XX_I2C_CH_B, + .kbps = 400, + .scl = GPIO_I2C_B_SCL, + .sda = GPIO_I2C_B_SDA + }, + { + .name = "usb0", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C_C_SCL, + .sda = GPIO_I2C_C_SDA + }, + { + .name = "usb1", + .port = IT83XX_I2C_CH_E, + .kbps = 1000, + .scl = GPIO_I2C_E_SCL, + .sda = GPIO_I2C_E_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -382,7 +416,7 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { .port = I2C_PORT_USB1, - .addr_flags = RT1718S_I2C_ADDR_FLAGS, + .addr_flags = RT1718S_I2C_ADDR1_FLAGS, }, .drv = &rt1718s_tcpm_drv, }, diff --git a/baseboard/cherry/baseboard.h b/baseboard/cherry/baseboard.h index 2a4705e541..d810b1d7b7 100644 --- a/baseboard/cherry/baseboard.h +++ b/baseboard/cherry/baseboard.h @@ -14,6 +14,7 @@ * connect to 1.8v on other versions. */ #define CONFIG_IT83XX_VCC_1P8V +#define CONFIG_IT83XX_I2C_CMD_QUEUE /* * On power-on, H1 releases the EC from reset but then quickly asserts and @@ -109,7 +110,6 @@ #define CONFIG_LED_COMMON /* PD / USB-C / PPC */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 #define CONFIG_CMD_PPC_DUMP #define CONFIG_HOSTCMD_PD_CONTROL #define CONFIG_IT83XX_TUNE_CC_PHY @@ -208,6 +208,11 @@ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) | \ EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON)) +/* And the MKBP events */ +#define CONFIG_MKBP_EVENT_WAKEUP_MASK \ + (BIT(EC_MKBP_EVENT_KEY_MATRIX) | \ + BIT(EC_MKBP_EVENT_HOST_EVENT)) + #ifndef __ASSEMBLER__ #include "gpio_signal.h" diff --git a/baseboard/cherry/usb_pd_policy.c b/baseboard/cherry/usb_pd_policy.c index 0c7f4dcee5..cae89bffcf 100644 --- a/baseboard/cherry/usb_pd_policy.c +++ b/baseboard/cherry/usb_pd_policy.c @@ -28,21 +28,6 @@ static enum { AUX_PORT_C1HDMI = 1, } aux_port = AUX_PORT_NONE; -int svdm_get_hpd_gpio(int port) -{ - /* HPD is low active, inverse the result */ - return !gpio_get_level(GPIO_EC_AP_DP_HPD_ODL); -} - -void svdm_set_hpd_gpio(int port, int en) -{ - /* - * HPD is low active, inverse the en - * TODO: C0&C1 shares the same HPD, implement FCFS policy. - */ - gpio_set_level(GPIO_EC_AP_DP_HPD_ODL, !en); -} - static void aux_switch_port(int port) { if (port != AUX_PORT_NONE) @@ -66,6 +51,33 @@ static void aux_display_disconnected(int port) aux_switch_port(AUX_PORT_NONE); } +int svdm_get_hpd_gpio(int port) +{ + /* HPD is low active, inverse the result */ + return !gpio_get_level(GPIO_EC_AP_DP_HPD_ODL); +} + +void svdm_set_hpd_gpio(int port, int en) +{ + /* + * Cherry can only output to 1 display port at a time. + * This implements FCFS policy by changing the aux channel. If a + * display is connected to the either port (says A), and the port A + * will be served until the display is disconnected from port A. + * It won't output to the other display which connects to port B. + */ + if (en) { + if (aux_port == AUX_PORT_NONE) + aux_switch_port(port); + } else { + aux_display_disconnected(port); + } + /* + * HPD is low active, inverse the en + */ + gpio_set_level_verbose(CC_USBPD, GPIO_EC_AP_DP_HPD_ODL, !en); +} + __override int svdm_dp_attention(int port, uint32_t *payload) { int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -115,6 +127,9 @@ __override int svdm_dp_attention(int port, uint32_t *payload) * b/171172053#comment14: since the HPD_DSTREAM_DEBOUNCE_IRQ is * very short (500us), we can use udelay instead of usleep for * more stable pulse period. + * + * Note that this should be the only difference between our code + * and common code. */ udelay(HPD_DSTREAM_DEBOUNCE_IRQ); svdm_set_hpd_gpio(port, 1); @@ -122,23 +137,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload) svdm_set_hpd_gpio(port, lvl); } - /* - * Cherry can only output to 1 display port at a time. - * This implements FCFS policy by changing the aux channel. If a - * display is connected to the either port (says A), and the port A - * will be served until the display is disconnected from port A. - * It won't output to the other display which connects to port B. - */ - if (lvl && aux_port == AUX_PORT_NONE) - /* - * A display is connected, and no display was plugged on either - * port. - */ - aux_switch_port(port); - else if (!lvl) - aux_display_disconnected(port); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; #endif /* CONFIG_USB_PD_DP_HPD_GPIO */ @@ -156,22 +154,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload) return 1; } -__override void svdm_exit_dp_mode(int port) -{ -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - svdm_set_hpd_gpio(port, 0); -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL_DEASSERTED | - USB_PD_MUX_HPD_IRQ_DEASSERTED); - - aux_display_disconnected(port); - -#ifdef USB_PD_PORT_TCPC_MST - if (port == USB_PD_PORT_TCPC_MST) - baseboard_mst_enable_control(port, 0); -#endif -} - int pd_snk_is_vbus_provided(int port) { static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; diff --git a/baseboard/corsola/baseboard.c b/baseboard/corsola/baseboard.c deleted file mode 100644 index 4d8fea6c7c..0000000000 --- a/baseboard/corsola/baseboard.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Corsola baseboard-specific configuration */ - -#include "adc.h" -#include "button.h" -#include "charge_manager.h" -#include "charger.h" -#include "charger.h" -#include "charge_state.h" -#include "charge_state_v2.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "driver/accel_lis2dw12.h" -#include "driver/accelgyro_icm426xx.h" -#include "driver/bc12/mt6360.h" -#include "driver/charger/isl923x.h" -#include "driver/ppc/syv682x.h" -#include "driver/tcpm/it83xx_pd.h" -#include "driver/temp_sensor/thermistor.h" -#include "extpower.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "keyboard_scan.h" -#include "lid_switch.h" -#include "motion_sense.h" -#include "power_button.h" -#include "power.h" -#include "regulator.h" -#include "spi.h" -#include "switch.h" -#include "tablet_mode.h" -#include "task.h" -#include "temp_sensor.h" -#include "timer.h" -#include "uart.h" - -#include "gpio_list.h" - -/* Wake-up pins for hibernate */ -enum gpio_signal hibernate_wake_pins[] = { - GPIO_AC_PRESENT, - GPIO_LID_OPEN, - GPIO_POWER_BUTTON_L, -}; -int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); - -/* - * I2C channels (A, B, and C) are using the same timing registers (00h~07h) - * at default. - * In order to set frequency independently for each channels, - * We use timing registers 09h~0Bh, and the supported frequency will be: - * 50KHz, 100KHz, 400KHz, or 1MHz. - * I2C channels (D, E and F) can be set different frequency on different ports. - * The I2C(D/E/F) frequency depend on the frequency of SMBus Module and - * the individual prescale register. - * The frequency of SMBus module is 24MHz on default. - * The allowed range of I2C(D/E/F) frequency is as following setting. - * SMBus Module Freq = PLL_CLOCK / ((IT83XX_ECPM_SCDCR2 & 0x0F) + 1) - * (SMBus Module Freq / 510) <= I2C Freq <= (SMBus Module Freq / 8) - * Channel D has multi-function and can be used as UART interface. - * Channel F is reserved for EC debug. - */ - -/* I2C ports */ -const struct i2c_port_t i2c_ports[] = { - {"bat_chg", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, - {"sensor", IT83XX_I2C_CH_B, 400, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"usb0", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"usb1", IT83XX_I2C_CH_E, 400, GPIO_I2C_E_SCL, GPIO_I2C_E_SDA}, -}; -const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); - -int board_allow_i2c_passthru(int port) -{ - return (port == I2C_PORT_VIRTUAL_BATTERY); -} diff --git a/baseboard/corsola/baseboard.h b/baseboard/corsola/baseboard.h deleted file mode 100644 index 95d3b1d20c..0000000000 --- a/baseboard/corsola/baseboard.h +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Corsola board configuration */ - -#ifndef __CROS_EC_BASEBOARD_H -#define __CROS_EC_BASEBOARD_H - -/* IT81202-bx config */ -/* - * NOTE: we need to make correct VCC voltage selection here if EC's VCC isn't - * connect to 1.8v on other versions. - */ -#define CONFIG_IT83XX_VCC_1P8V - -/* - * On power-on, H1 releases the EC from reset but then quickly asserts and - * releases the reset a second time. This means the EC sees 2 resets: - * (1) power-on reset, (2) reset-pin reset. This config will - * allow the second reset to be treated as a power-on. - */ -#define CONFIG_BOARD_RESET_AFTER_POWER_ON -#define CONFIG_CHIPSET_MT8192 -#define CONFIG_EXTPOWER_GPIO -#define CONFIG_HIBERNATE_WAKE_PINS_DYNAMIC -#define CONFIG_POWER_SLEEP_FAILURE_DETECTION -#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE - -/* Chipset */ -#define CONFIG_CMD_AP_RESET_LOG -#define CONFIG_CMD_POWERINDEBUG -#define CONFIG_HOST_COMMAND_STATUS -#define CONFIG_LOW_POWER_IDLE -#define CONFIG_LOW_POWER_S0 -#define CONFIG_POWER_BUTTON -#define CONFIG_POWER_COMMON -#define CONFIG_PWM -#define CONFIG_VBOOT_HASH -#define CONFIG_VOLUME_BUTTONS -#define CONFIG_WP_ACTIVE_HIGH - -/* Battery */ -#define CONFIG_BATTERY_CUT_OFF -#define CONFIG_BATTERY_FUEL_GAUGE -#define CONFIG_BATTERY_PRESENT_GPIO GPIO_EC_BATT_PRES_ODL -#define CONFIG_BATTERY_SMART - -/* BC12 */ -#define CONFIG_BC12_DETECT_MT6360 -#define CONFIG_BC12_DETECT_PI3USB9201 -#undef CONFIG_BC12_SINGLE_DRIVER -#define CONFIG_USB_CHARGER - -/* Charger */ -#define ADC_AMON_BMON ADC_CHARGER_AMON_R /* ADC name remap */ -#define ADC_PSYS ADC_CHARGER_PMON /* ADC name remap */ -#define CONFIG_CHARGE_MANAGER -#define CONFIG_CHARGER -#define CONFIG_CHARGE_RAMP_HW -#define CONFIG_CHARGER_DISCHARGE_ON_AC -#define CONFIG_CHARGER_INPUT_CURRENT 512 -#define CONFIG_CHARGER_ISL9238C -#define CONFIG_CHARGER_MAINTAIN_VBAT -#define CONFIG_CHARGER_OTG -#define CONFIG_CHARGER_PSYS -#define CONFIG_CHARGER_PSYS_READ -#define CONFIG_CHARGER_SENSE_RESISTOR 10 /* BOARD_RS2 */ -#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 /* BOARD_RS1 */ -#define CONFIG_CMD_CHARGER_ADC_AMON_BMON - -/* Keyboard */ -#define CONFIG_CMD_KEYBOARD -#define CONFIG_KEYBOARD_COL2_INVERTED -#define CONFIG_KEYBOARD_PROTOCOL_MKBP -#define CONFIG_MKBP_USE_GPIO - -/* I2C */ -#define CONFIG_I2C -#define CONFIG_I2C_CONTROLLER -#define CONFIG_I2C_PASSTHRU_RESTRICTED -#define CONFIG_I2C_VIRTUAL_BATTERY -#define I2C_PORT_CHARGER IT83XX_I2C_CH_A -#define I2C_PORT_BATTERY IT83XX_I2C_CH_A -#define I2C_PORT_POWER IT83XX_I2C_CH_A -#define I2C_PORT_ACCEL IT83XX_I2C_CH_B -#define I2C_PORT_PPC0 IT83XX_I2C_CH_C -#define I2C_PORT_PPC1 IT83XX_I2C_CH_E -#define I2C_PORT_USB_MUX0 IT83XX_I2C_CH_C -#define I2C_PORT_USB_MUX1 IT83XX_I2C_CH_E -#define I2C_PORT_VIRTUAL_BATTERY I2C_PORT_BATTERY -#define CONFIG_SMBUS_PEC - -/* LED */ -#define CONFIG_LED_COMMON - -/* PD / USB-C / PPC */ -#define CONFIG_CMD_PPC_DUMP -#define CONFIG_HOSTCMD_PD_CONTROL -#define CONFIG_IT83XX_TUNE_CC_PHY -#define CONFIG_USB_MUX_VIRTUAL -#define CONFIG_USBC_PPC -#define CONFIG_USBC_PPC_DEDICATED_INT -#define CONFIG_USBC_PPC_POLARITY -#define CONFIG_USBC_PPC_SYV682C -#define CONFIG_USBC_PPC_VCONN -#define CONFIG_USBC_SS_MUX -#define CONFIG_USBC_VCONN -#define CONFIG_USBC_VCONN_SWAP -#define CONFIG_USB_DRP_ACC_TRYSRC -#define CONFIG_USB_MUX_IT5205 /* C0 */ -#define CONFIG_USB_MUX_PS8743 /* C1 */ -#define CONFIG_USB_PD_ALT_MODE -#define CONFIG_USB_PD_ALT_MODE_DFP -#define CONFIG_USB_PD_DECODE_SOP -#define CONFIG_USB_PD_DISCHARGE -#define CONFIG_USB_PD_DISCHARGE_PPC -#define CONFIG_USB_PD_DP_HPD_GPIO -#define CONFIG_USB_PD_DP_HPD_GPIO_CUSTOM -#define CONFIG_USB_PD_DUAL_ROLE -#define CONFIG_USB_PD_FRS_PPC -#define CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT 2 -#define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_PORT_MAX_COUNT 2 -#define CONFIG_USB_PD_REV30 -#define CONFIG_USB_PD_TCPC_LOW_POWER -#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP -#define CONFIG_USB_PD_TCPM_TCPCI -#define CONFIG_USB_PD_TCPMV2 -#define CONFIG_USB_PD_TRY_SRC -#define CONFIG_USB_PD_VBUS_DETECT_PPC -#define CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT -#define CONFIG_USB_PID 0x5053 -#define CONFIG_USB_POWER_DELIVERY - -/* USB-A */ -#define CONFIG_USB_PORT_POWER_DUMB -#define CONFIG_USB_PORT_POWER_DUMB_CUSTOM_HOOK -#define USB_PORT_COUNT USBA_PORT_COUNT - -/* UART */ -#undef CONFIG_UART_TX_BUF_SIZE -#define CONFIG_UART_TX_BUF_SIZE 4096 - -/* Sensor */ -#ifdef HAS_TASK_MOTIONSENSE -#define CONFIG_CMD_ACCEL_INFO -#define CONFIG_CMD_ACCELS - -#define CONFIG_ACCEL_FIFO -#define CONFIG_ACCEL_FIFO_SIZE 256 -#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) -#define CONFIG_ACCEL_INTERRUPTS -#endif - -/* SPI / Host Command */ -#define CONFIG_SPI - -/* MKBP */ -#define CONFIG_MKBP_EVENT - -#define CONFIG_KEYBOARD_PROTOCOL_MKBP -#define CONFIG_MKBP_USE_GPIO - -/* Voltage regulator control */ -#define CONFIG_HOSTCMD_REGULATOR - -/* Define the host events which are allowed to wakeup AP in S3. */ -#define CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK \ - (EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) | \ - EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) | \ - EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \ - EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT) | \ - EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) | \ - EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON)) - -/* And the MKBP events */ -#define CONFIG_MKBP_EVENT_WAKEUP_MASK \ - (BIT(EC_MKBP_EVENT_KEY_MATRIX) | \ - BIT(EC_MKBP_EVENT_HOST_EVENT)) - -#include "baseboard_common.h" - -#ifndef __ASSEMBLER__ - -#include "gpio_signal.h" -#include "registers.h" -#include "power/mt8192.h" - -void board_reset_pd_mcu(void); -enum board_sub_board board_get_sub_board(void); -void usb_a0_interrupt(enum gpio_signal signal); - -#endif /* !__ASSEMBLER__ */ -#endif /* __CROS_EC_BASEBOARD_H */ diff --git a/baseboard/corsola/baseboard_common.h b/baseboard/corsola/baseboard_common.h deleted file mode 100644 index c0328ba4e1..0000000000 --- a/baseboard/corsola/baseboard_common.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Corsola baseboard-specific onfiguration common to ECOS and Zephyr */ - -#ifndef __CROS_EC_BASEBOARD_COMMON_H -#define __CROS_EC_BASEBOARD_COMMON_H - -/* GPIO name remapping */ -#define GPIO_EN_HDMI_PWR GPIO_EC_X_GPIO1 -#define GPIO_USB_C1_FRS_EN GPIO_EC_X_GPIO1 -#define GPIO_USB_C1_PPC_INT_ODL GPIO_X_EC_GPIO2 -#define GPIO_PS185_EC_DP_HPD GPIO_X_EC_GPIO2 -#define GPIO_USB_C1_DP_IN_HPD GPIO_EC_X_GPIO3 -#define GPIO_PS185_PWRDN_ODL GPIO_EC_X_GPIO3 - -#ifndef __ASSEMBLER__ - -#include "gpio_signal.h" - -enum board_sub_board { - SUB_BOARD_NONE = -1, - SUB_BOARD_TYPEC, - SUB_BOARD_HDMI, - SUB_BOARD_COUNT, -}; - -/** - * board_get_version() - Get the board version - * - * Read the ADC to obtain the board version - * - * @return board version in the range 0 to 14 inclusive - */ -int board_get_version(void); - -void ppc_interrupt(enum gpio_signal signal); -void bc12_interrupt(enum gpio_signal signal); -void x_ec_interrupt(enum gpio_signal signal); - -#endif /* !__ASSEMBLER__ */ -#endif /* __CROS_EC_BASEBOARD_COMMON_H */ diff --git a/baseboard/corsola/board_id.c b/baseboard/corsola/board_id.c deleted file mode 100644 index c39cf050a8..0000000000 --- a/baseboard/corsola/board_id.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "adc.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "timer.h" -#include "util.h" - -/** - * Conversion based on following table: - * - * ID | Rp | Rd | Voltage - * | kOhm | kOhm | mV - * ---+------+------+-------- - * 0 | 51.1 | 2.2 | 136.2 - * 1 | 51.1 | 6.81 | 388.1 - * 2 | 51.1 | 11 | 584.5 - * 3 | 57.6 | 18 | 785.7 - * 4 | 51.1 | 22 | 993.2 - * 5 | 51.1 | 30 | 1220.7 - * 6 | 51.1 | 39.2 | 1432.6 - * 7 | 56 | 56 | 1650.0 - * 8 | 47 | 61.9 | 1875.8 - * 9 | 47 | 80.6 | 2084.5 - * 10 | 56 | 124 | 2273.3 - * 11 | 51.1 | 150 | 2461.5 - * 12 | 47 | 200 | 2672.1 - * 13 | 47 | 330 | 2888.6 - * 14 | 47 | 680 | 3086.7 - */ -const static int voltage_map[] = { - 136, - 388, - 584, - 785, - 993, - 1220, - 1432, - 1650, - 1875, - 2084, - 2273, - 2461, - 2672, - 2888, - 3086, -}; - -const int threshold_mv = 100; - -/** - * Convert ADC value to board id using the voltage table above. - * - * @param ch ADC channel to read, usually ADC_BOARD_ID_0 or ADC_BOARD_ID_1. - * - * @return a non-negative board id, or negative value if error. - */ -static int adc_value_to_numeric_id(enum adc_channel ch) -{ - int mv; - - gpio_set_level(GPIO_EN_EC_ID_ODL, 0); - /* Wait to allow cap charge */ - msleep(10); - - mv = adc_read_channel(ch); - if (mv == ADC_READ_ERROR) - mv = adc_read_channel(ch); - - gpio_set_level(GPIO_EN_EC_ID_ODL, 1); - - if (mv == ADC_READ_ERROR) - return -EC_ERROR_UNKNOWN; - - for (int i = 0; i < ARRAY_SIZE(voltage_map); i++) { - if (IN_RANGE(mv, voltage_map[i] - threshold_mv, - voltage_map[i] + threshold_mv)) - return i; - } - - return -EC_ERROR_UNKNOWN; -} - -static int version = -1; - -/* b/163963220: Cache ADC value before board_hibernate_late() reads it */ -static void board_version_init(void) -{ - version = adc_value_to_numeric_id(ADC_BOARD_ID_0); - if (version < 0) { - ccprints("WARN:BOARD_ID_0"); - ccprints("Assuming board id = 0"); - - version = 0; - } -} -DECLARE_HOOK(HOOK_INIT, board_version_init, HOOK_PRIO_INIT_ADC + 1); - -__override int board_get_version(void) -{ - return version; -} diff --git a/baseboard/corsola/build.mk b/baseboard/corsola/build.mk deleted file mode 100644 index ce7b7272bd..0000000000 --- a/baseboard/corsola/build.mk +++ /dev/null @@ -1,15 +0,0 @@ -# -*- makefile -*- -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Baseboard specific files build -# - -baseboard-y=baseboard.o -baseboard-y+=board_chipset.o -baseboard-y+=board_id.o -baseboard-y+=hibernate.o -baseboard-y+=regulator.o -baseboard-y+=usbc_config.o -baseboard-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/baseboard/dedede/baseboard.c b/baseboard/dedede/baseboard.c index 5bd80ca53b..7b68b755ae 100644 --- a/baseboard/dedede/baseboard.c +++ b/baseboard/dedede/baseboard.c @@ -118,7 +118,7 @@ __override void board_check_extpower(void) last_extpower_present = extpower_present; } -uint32_t pp3300_a_pgood; +atomic_t pp3300_a_pgood; __override int intel_x86_get_pg_ec_dsw_pwrok(void) { /* @@ -185,7 +185,7 @@ __override int power_signal_get_level(enum gpio_signal signal) if (signal == GPIO_PG_EC_ALL_SYS_PWRGD) return intel_x86_get_pg_ec_all_sys_pwrgd(); - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) { /* Check signal is from GPIOs or VWs */ if (espi_signal_is_vw(signal)) return espi_vw_get_wire((enum espi_vw_signal)signal); diff --git a/baseboard/dedede/baseboard.h b/baseboard/dedede/baseboard.h index 7357b1a5ce..c14f22b6d0 100644 --- a/baseboard/dedede/baseboard.h +++ b/baseboard/dedede/baseboard.h @@ -121,7 +121,7 @@ /* EC Modules */ #define CONFIG_ADC #define CONFIG_CRC8 -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_EVENTS #define CONFIG_I2C #define CONFIG_I2C_CONTROLLER @@ -176,6 +176,7 @@ /* Sensors */ #define CONFIG_MKBP_EVENT +#define CONFIG_MKBP_EVENT_WAKEUP_MASK 0 #define CONFIG_MKBP_USE_GPIO_AND_HOST_EVENT /* SoC */ @@ -198,7 +199,8 @@ #define CONFIG_USBC_VCONN_SWAP /* Temp Sensor */ -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_PP3300_A +#define CONFIG_TEMP_SENSOR_POWER +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_PP3300_A #define CONFIG_TEMP_SENSOR_FIRST_READ_DELAY_MS 500 /* USB PD */ @@ -241,6 +243,7 @@ #ifndef __ASSEMBLER__ +#include "atomic_t.h" #include "common.h" #include "gpio_signal.h" @@ -265,7 +268,7 @@ void board_reset_pd_mcu(void); * Bit to indicate if the PP3000_A rail's power is good. Will be updated by ADC * interrupt. */ -extern uint32_t pp3300_a_pgood; +extern atomic_t pp3300_a_pgood; #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BASEBOARD_H */ diff --git a/baseboard/dedede/cbi_fw_config.c b/baseboard/dedede/cbi_fw_config.c index 27d23733de..65a8cbaad9 100644 --- a/baseboard/dedede/cbi_fw_config.c +++ b/baseboard/dedede/cbi_fw_config.c @@ -33,6 +33,12 @@ enum fw_config_db get_cbi_fw_config_db(void) return ((cached_fw_config & FW_CONFIG_DB_MASK) >> FW_CONFIG_DB_OFFSET); } +enum fw_config_stylus get_cbi_fw_config_stylus(void) +{ + return ((cached_fw_config & FW_CONFIG_STYLUS_MASK) + >> FW_CONFIG_STYLUS_OFFSET); +} + enum fw_config_kblight_type get_cbi_fw_config_kblight(void) { return ((cached_fw_config & FW_CONFIG_KB_BL_MASK) diff --git a/baseboard/dedede/cbi_fw_config.h b/baseboard/dedede/cbi_fw_config.h index c9782522fa..90cc5e5fbe 100644 --- a/baseboard/dedede/cbi_fw_config.h +++ b/baseboard/dedede/cbi_fw_config.h @@ -28,6 +28,16 @@ enum fw_config_db { #define FW_CONFIG_DB_MASK GENMASK(3, 0) /* + * Stylus (1 bit) + */ +enum fw_config_stylus { + STYLUS_ABSENT = 0, + STYLUS_PRESENT = 1, +}; +#define FW_CONFIG_STYLUS_OFFSET 4 +#define FW_CONFIG_STYLUS_MASK GENMASK(4, 4) + +/* * Keyboard backlight (1 bit) */ enum fw_config_kblight_type { @@ -71,6 +81,7 @@ enum fw_config_hdmi_type { #define FW_CONFIG_HDMI_MASK GENMASK(17, 17) enum fw_config_db get_cbi_fw_config_db(void); +enum fw_config_stylus get_cbi_fw_config_stylus(void); enum fw_config_kblight_type get_cbi_fw_config_kblight(void); enum fw_config_tablet_mode_type get_cbi_fw_config_tablet_mode(void); enum fw_config_numeric_pad_type get_cbi_fw_config_numeric_pad(void); diff --git a/baseboard/dedede/variant_ec_it8320.c b/baseboard/dedede/variant_ec_it8320.c index e8560a8bc0..29c7758c6a 100644 --- a/baseboard/dedede/variant_ec_it8320.c +++ b/baseboard/dedede/variant_ec_it8320.c @@ -76,31 +76,46 @@ BUILD_ASSERT(ARRAY_SIZE(vcmp_list) == VCMP_COUNT); /* I2C Ports */ const struct i2c_port_t i2c_ports[] = { { - "eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA }, { - "battery", I2C_PORT_BATTERY, 100, GPIO_EC_I2C_BATTERY_SCL, - GPIO_EC_I2C_BATTERY_SDA + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BATTERY_SCL, + .sda = GPIO_EC_I2C_BATTERY_SDA }, #ifdef HAS_TASK_MOTIONSENSE { - "sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA }, #endif #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 { - "sub_usbc1", I2C_PORT_SUB_USB_C1, 1000, - GPIO_EC_I2C_SUB_USB_C1_SCL, GPIO_EC_I2C_SUB_USB_C1_SDA + .name = "sub_usbc1", + .port = I2C_PORT_SUB_USB_C1, + .kbps = 1000, + .scl = GPIO_EC_I2C_SUB_USB_C1_SCL, + .sda = GPIO_EC_I2C_SUB_USB_C1_SDA }, #endif { - "usbc0", I2C_PORT_USB_C0, 1000, GPIO_EC_I2C_USB_C0_SCL, - GPIO_EC_I2C_USB_C0_SDA + .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_SCL, + .sda = GPIO_EC_I2C_USB_C0_SDA }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/dedede/variant_ec_npcx796fc.c b/baseboard/dedede/variant_ec_npcx796fc.c index c34de929a7..aa2709b33b 100644 --- a/baseboard/dedede/variant_ec_npcx796fc.c +++ b/baseboard/dedede/variant_ec_npcx796fc.c @@ -163,36 +163,54 @@ DECLARE_HOOK(HOOK_LID_CHANGE, enable_adc_irqs_via_lid, HOOK_PRIO_DEFAULT); /* I2C Ports */ __attribute__((weak)) const struct i2c_port_t i2c_ports[] = { { - "eeprom", I2C_PORT_EEPROM, 1000, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 1000, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA }, { - "battery", I2C_PORT_BATTERY, 100, GPIO_EC_I2C_BATTERY_SCL, - GPIO_EC_I2C_BATTERY_SDA + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BATTERY_SCL, + .sda = GPIO_EC_I2C_BATTERY_SDA }, #ifdef HAS_TASK_MOTIONSENSE { - "sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA }, #endif { - "usbc0", I2C_PORT_USB_C0, 1000, GPIO_EC_I2C_USB_C0_SCL, - GPIO_EC_I2C_USB_C0_SDA + .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_SCL, + .sda = GPIO_EC_I2C_USB_C0_SDA }, #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 { - "sub_usbc1", I2C_PORT_SUB_USB_C1, 1000, - GPIO_EC_I2C_SUB_USB_C1_SCL, GPIO_EC_I2C_SUB_USB_C1_SDA + .name = "sub_usbc1", + .port = I2C_PORT_SUB_USB_C1, + .kbps = 1000, + .scl = GPIO_EC_I2C_SUB_USB_C1_SCL, + .sda = GPIO_EC_I2C_SUB_USB_C1_SDA }, #endif #ifdef BOARD_BUGZZY { - "lcd", I2C_PORT_LCD, 400, GPIO_EC_I2C_LCD_SCL, - GPIO_EC_I2C_LCD_SDA + .name = "lcd", + .port = I2C_PORT_LCD, + .kbps = 400, + .scl = GPIO_EC_I2C_LCD_SCL, + .sda = GPIO_EC_I2C_LCD_SDA }, #endif }; diff --git a/baseboard/goroh/baseboard.c b/baseboard/goroh/baseboard.c index ee88d1e713..8fd32b315c 100644 --- a/baseboard/goroh/baseboard.c +++ b/baseboard/goroh/baseboard.c @@ -109,10 +109,34 @@ DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"bat_chg", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, - {"sensor", IT83XX_I2C_CH_B, 400, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"usb0", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"usb1", IT83XX_I2C_CH_E, 400, GPIO_I2C_E_SCL, GPIO_I2C_E_SDA}, + { + .name = "bat_chg", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C_A_SCL, + .sda = GPIO_I2C_A_SDA + }, + { + .name = "sensor", + .port = IT83XX_I2C_CH_B, + .kbps = 400, + .scl = GPIO_I2C_B_SCL, + .sda = GPIO_I2C_B_SDA + }, + { + .name = "usb0", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C_C_SCL, + .sda = GPIO_I2C_C_SDA + }, + { + .name = "usb1", + .port = IT83XX_I2C_CH_E, + .kbps = 400, + .scl = GPIO_I2C_E_SCL, + .sda = GPIO_I2C_E_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -243,3 +267,17 @@ void lid_angle_peripheral_enable(int enable) } } #endif + +/* Called on AP S5 -> S3 transition */ +static void board_chipset_startup(void) +{ + gpio_set_level(GPIO_EN_USB_C1_MUX_PWR, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); + +/* Called on AP S3 -> S5 transition */ +static void board_chipset_shutdown(void) +{ + gpio_set_level(GPIO_EN_USB_C1_MUX_PWR, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); diff --git a/baseboard/goroh/baseboard.h b/baseboard/goroh/baseboard.h index 812d102d74..e4d854537b 100644 --- a/baseboard/goroh/baseboard.h +++ b/baseboard/goroh/baseboard.h @@ -30,6 +30,8 @@ #define CONFIG_CBI_EEPROM /* Chipset */ +#define CONFIG_CMD_AP_RESET_LOG +#define CONFIG_HOSTCMD_AP_RESET #define CONFIG_HOST_COMMAND_STATUS #define CONFIG_LOW_POWER_IDLE #define CONFIG_LOW_POWER_S0 @@ -104,7 +106,6 @@ #define CONFIG_USBC_VCONN #define CONFIG_USBC_VCONN_SWAP #define CONFIG_USB_DRP_ACC_TRYSRC -#define CONFIG_USB_MUX_IT5205 /* C0 */ #define CONFIG_USBC_RETIMER_PS8818 /* C1 */ #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP diff --git a/baseboard/goroh/usbc_config.c b/baseboard/goroh/usbc_config.c index 4c02528285..5a49d2ee2d 100644 --- a/baseboard/goroh/usbc_config.c +++ b/baseboard/goroh/usbc_config.c @@ -45,34 +45,57 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); /* USB Mux */ - -__overridable int board_c1_ps8818_mux_init(const struct usb_mux *me) +static int goroh_usb_c0_init_mux(const struct usb_mux *me) { - /* enable C1 mux power */ - GPIO_SET_LEVEL(GPIO_EN_USB_C1_MUX_PWR, 1); - return 0; + return virtual_usb_mux_driver.init(me); } -__overridable int board_c1_ps8818_mux_set(const struct usb_mux *me, - mux_state_t mux_state) +static int goroh_usb_c0_set_mux(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { - if (mux_state == USB_PD_MUX_NONE) - GPIO_SET_LEVEL(GPIO_EN_USB_C1_MUX_PWR, 0); + /* + * b/188376636: Inverse C0 polarity. + * Goroh rev0 CC1/CC2 SBU1/SBU2 are reversed. + * We report inversed polarity to the SoC and SoC we reverse the SBU + * accordingly. + */ + mux_state = mux_state ^ USB_PD_MUX_POLARITY_INVERTED; - return 0; + return virtual_usb_mux_driver.set(me, mux_state, ack_required); + +} + +static int goroh_usb_c0_get_mux(const struct usb_mux *me, + mux_state_t *mux_state) +{ + return virtual_usb_mux_driver.get(me, mux_state); } +static struct usb_mux_driver goroh_usb_c0_mux_driver = { + .init = goroh_usb_c0_init_mux, + .set = goroh_usb_c0_set_mux, + .get = goroh_usb_c0_get_mux, +}; + +static const struct usb_mux goroh_usb_c1_ps8818_retimer = { + .usb_port = USBC_PORT_C1, + .i2c_port = I2C_PORT_USB_C1, + .i2c_addr_flags = PS8818_I2C_ADDR_FLAGS, + .driver = &ps8818_usb_retimer_driver, + .next_mux = NULL, +}; + const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { - { - /* C0 no mux */ + [USBC_PORT_C0] = { + .usb_port = USBC_PORT_C0, + .driver = &goroh_usb_c0_mux_driver, + .hpd_update = &virtual_hpd_update, }, - { + [USBC_PORT_C1] = { .usb_port = USBC_PORT_C1, - .i2c_port = I2C_PORT_USB_C1, - .i2c_addr_flags = PS8818_I2C_ADDR_FLAGS, - .driver = &ps8818_usb_retimer_driver, - .board_init = &board_c1_ps8818_mux_init, - .board_set = &board_c1_ps8818_mux_set, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + .next_mux = &goroh_usb_c1_ps8818_retimer, }, }; BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT); diff --git a/baseboard/grunt/baseboard.h b/baseboard/grunt/baseboard.h index c97ece285f..5a79c48c63 100644 --- a/baseboard/grunt/baseboard.h +++ b/baseboard/grunt/baseboard.h @@ -36,7 +36,7 @@ #define CONFIG_BACKLIGHT_LID_ACTIVE_LOW #define CONFIG_CMD_AP_RESET_LOG #define CONFIG_HIBERNATE_PSL -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_HOSTCMD_SKUID #define CONFIG_I2C #define CONFIG_I2C_BUS_MAY_BE_UNPOWERED diff --git a/baseboard/guybrush/baseboard.c b/baseboard/guybrush/baseboard.c index 26f212e986..dd44c5feb5 100644 --- a/baseboard/guybrush/baseboard.c +++ b/baseboard/guybrush/baseboard.c @@ -373,25 +373,6 @@ const struct mft_t mft_channels[] = { }; BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); -const struct fan_conf fan_conf_0 = { - .flags = FAN_USE_RPM_MODE, - .ch = MFT_CH_0, /* Use MFT id to control fan */ - .pgood_gpio = GPIO_S0_PGOOD, - .enable_gpio = -1, -}; -const struct fan_rpm fan_rpm_0 = { - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 6500, -}; -const struct fan_t fans[] = { - [FAN_CH_0] = { - .conf = &fan_conf_0, - .rpm = &fan_rpm_0, - }, -}; -BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); - /* * USB C0 port SBU mux use standalone FSUSB42UMX * chip and it needs a board specific driver. @@ -611,14 +592,22 @@ void tcpc_alert_event(enum gpio_signal signal) static void reset_nct38xx_port(int port) { enum gpio_signal reset_gpio_l; + int a_vbus, a_limit_sdp, a1_retimer_en; - if (port == USBC_PORT_C0) + /* Save type-A GPIO values to restore after reset */ + if (port == USBC_PORT_C0) { reset_gpio_l = GPIO_USB_C0_TCPC_RST_L; - else if (port == USBC_PORT_C1) + ioex_get_level(IOEX_EN_PP5000_USB_A0_VBUS, &a_vbus); + ioex_get_level(IOEX_USB_A0_LIMIT_SDP, &a_limit_sdp); + } else if (port == USBC_PORT_C1) { reset_gpio_l = GPIO_USB_C1_TCPC_RST_L; - else + ioex_get_level(IOEX_EN_PP5000_USB_A1_VBUS_DB, &a_vbus); + ioex_get_level(IOEX_USB_A1_LIMIT_SDP_DB, &a_limit_sdp); + ioex_get_level(IOEX_USB_A1_RETIMER_EN, &a1_retimer_en); + } else { /* Invalid port: do nothing */ return; + } gpio_set_level(reset_gpio_l, 0); msleep(NCT38XX_RESET_HOLD_DELAY_MS); @@ -626,6 +615,17 @@ static void reset_nct38xx_port(int port) nct38xx_reset_notify(port); if (NCT3807_RESET_POST_DELAY_MS != 0) msleep(NCT3807_RESET_POST_DELAY_MS); + + /* Re-init ioex after resetting the TCPC */ + ioex_init(port); + if (port == USBC_PORT_C0) { + ioex_set_level(IOEX_EN_PP5000_USB_A0_VBUS, a_vbus); + ioex_set_level(IOEX_USB_A0_LIMIT_SDP, a_limit_sdp); + } else { + ioex_set_level(IOEX_EN_PP5000_USB_A1_VBUS_DB, a_vbus); + ioex_set_level(IOEX_USB_A1_LIMIT_SDP_DB, a_limit_sdp); + ioex_set_level(IOEX_USB_A1_RETIMER_EN, a1_retimer_en); + } } diff --git a/baseboard/guybrush/baseboard.h b/baseboard/guybrush/baseboard.h index 6960524822..9f010c2bf3 100644 --- a/baseboard/guybrush/baseboard.h +++ b/baseboard/guybrush/baseboard.h @@ -80,7 +80,6 @@ #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP #define CONFIG_TEMP_SENSOR_SB_TSI -#define CONFIG_TEMP_SENSOR_TMP112 #define CONFIG_THERMISTOR #define CONFIG_CPU_PROCHOT_ACTIVE_LOW #define GPIO_CPU_PROCHOT GPIO_PROCHOT_ODL @@ -92,7 +91,7 @@ /* Host communication */ #define CONFIG_CMD_CHARGEN -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_MKBP_EVENT #define CONFIG_MKBP_USE_GPIO_AND_HOST_EVENT #define GPIO_EC_INT_L GPIO_EC_SOC_INT_L diff --git a/baseboard/hatch/baseboard.c b/baseboard/hatch/baseboard.c index dd93e581cf..683df43251 100644 --- a/baseboard/hatch/baseboard.c +++ b/baseboard/hatch/baseboard.c @@ -52,25 +52,85 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { #ifdef CONFIG_ACCEL_FIFO - {"sensor", I2C_PORT_SENSOR, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, #endif - {"ppc0", I2C_PORT_PPC0, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, #endif - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, #ifdef BOARD_AKEMI - {"thermal", I2C_PORT_THERMAL, 400, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, + { + .name = "thermal", + .port = I2C_PORT_THERMAL, + .kbps = 400, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, #endif #ifdef BOARD_JINLON - {"thermal", I2C_PORT_THERMAL, 100, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, + { + .name = "thermal", + .port = I2C_PORT_THERMAL, + .kbps = 100, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, #endif #ifdef BOARD_MUSHU - {"f75303_temp", I2C_PORT_THERMAL, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"gpu_temp", I2C_PORT_GPU, 100, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, + { + .name = "f75303_temp", + .port = I2C_PORT_THERMAL, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "gpu_temp", + .port = I2C_PORT_GPU, + .kbps = 100, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, #endif - {"power", I2C_PORT_POWER, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 100, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 100, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -324,7 +384,7 @@ void board_set_charge_limit(int port, int supplier, int charge_ma, #ifdef USB_PD_PORT_TCPC_MST void baseboard_mst_enable_control(enum mst_source src, int level) { - static uint32_t mst_input_levels; + static atomic_t mst_input_levels; if (level) atomic_or(&mst_input_levels, 1 << src); diff --git a/baseboard/herobrine/baseboard.h b/baseboard/herobrine/baseboard.h index 108f7f8cf5..ae5b2a3d33 100644 --- a/baseboard/herobrine/baseboard.h +++ b/baseboard/herobrine/baseboard.h @@ -42,7 +42,7 @@ #undef CONFIG_PECI -#define CONFIG_HOSTCMD_SHI +#define CONFIG_HOST_INTERFACE_SHI #define CONFIG_HOST_COMMAND_STATUS #define CONFIG_HOSTCMD_SECTION_SORTED #define CONFIG_KEYBOARD_COL2_INVERTED diff --git a/baseboard/honeybuns/baseboard.c b/baseboard/honeybuns/baseboard.c index df56697fbf..e7df1b6ef4 100644 --- a/baseboard/honeybuns/baseboard.c +++ b/baseboard/honeybuns/baseboard.c @@ -89,8 +89,20 @@ __maybe_unused static void board_power_sequence(int enable) /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"i2c1", I2C_PORT_I2C1, 400, GPIO_EC_I2C1_SCL, GPIO_EC_I2C1_SDA}, - {"i2c3", I2C_PORT_I2C3, 400, GPIO_EC_I2C3_SCL, GPIO_EC_I2C3_SDA}, + { + .name = "i2c1", + .port = I2C_PORT_I2C1, + .kbps = 400, + .scl = GPIO_EC_I2C1_SCL, + .sda = GPIO_EC_I2C1_SDA + }, + { + .name = "i2c3", + .port = I2C_PORT_I2C3, + .kbps = 400, + .scl = GPIO_EC_I2C3_SCL, + .sda = GPIO_EC_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/honeybuns/usb_pd_policy.c b/baseboard/honeybuns/usb_pd_policy.c index ef2350a03d..faaef9083f 100644 --- a/baseboard/honeybuns/usb_pd_policy.c +++ b/baseboard/honeybuns/usb_pd_policy.c @@ -369,20 +369,16 @@ static void usb_tc_connect(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* Clear data role swap attempt counter at each usbc attach */ + pd_dr_swap_attempt_count[port] = 0; + /* * The EC needs to indicate to the USB hub when the host port is * attached so that the USB-EP can be properly enumerated. GPIO_BPWR_DET * is used for this purpose. */ - if (port == USB_PD_PORT_HOST) { + if (port == USB_PD_PORT_HOST) gpio_set_level(GPIO_BPWR_DET, 1); -#ifdef GPIO_UFP_PLUG_DET - gpio_set_level(GPIO_UFP_PLUG_DET, 0); -#endif - } - - /* Clear data role swap attempt counter at each usbc attach */ - pd_dr_swap_attempt_count[port] = 0; } DECLARE_HOOK(HOOK_USB_PD_CONNECT, usb_tc_connect, HOOK_PRIO_DEFAULT); @@ -391,12 +387,8 @@ static void usb_tc_disconnect(void) int port = TASK_ID_TO_PD_PORT(task_get_current()); /* Only the host port disconnect is relevant */ - if (port == USB_PD_PORT_HOST) { + if (port == USB_PD_PORT_HOST) gpio_set_level(GPIO_BPWR_DET, 0); -#ifdef GPIO_UFP_PLUG_DET - gpio_set_level(GPIO_UFP_PLUG_DET, 1); -#endif - } } DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, usb_tc_disconnect, HOOK_PRIO_DEFAULT); diff --git a/baseboard/intelrvp/adlrvp.c b/baseboard/intelrvp/adlrvp.c index 8ec1b820b2..b2f12fbd7e 100644 --- a/baseboard/intelrvp/adlrvp.c +++ b/baseboard/intelrvp/adlrvp.c @@ -5,6 +5,7 @@ /* Intel ADLRVP board-specific common configuration */ +#include "battery_fuel_gauge.h" #include "charger.h" #include "bq25710.h" #include "common.h" @@ -388,6 +389,28 @@ static void configure_retimer_usbmux(void) } } +static void configure_battery_type(void) +{ + int bat_cell_type; + + switch (ADL_RVP_BOARD_ID(board_get_version())) { + case ADLM_LP4_RVP1_SKU_BOARD_ID: + case ADLM_LP5_RVP2_SKU_BOARD_ID: + case ADLM_LP5_RVP3_SKU_BOARD_ID: + case ADLN_LP5_ERB_SKU_BOARD_ID: + case ADLN_LP5_RVP_SKU_BOARD_ID: + /* configure Battery to 2S based */ + bat_cell_type = BATTERY_GETAC_SMP_HHP_408_2S; + break; + default: + /* configure Battery to 3S based */ + bat_cell_type = BATTERY_GETAC_SMP_HHP_408_3S; + break; + } + + /* Set the fixed battery type */ + battery_set_fixed_battery_type(bat_cell_type); +} /******************************************************************************/ /* PWROK signal configuration */ /* @@ -483,4 +506,7 @@ __override void board_pre_task_i2c_peripheral_init(void) /* Configure board specific retimer & mux */ configure_retimer_usbmux(); + + /* Configure battery type */ + configure_battery_type(); } diff --git a/baseboard/intelrvp/adlrvp.h b/baseboard/intelrvp/adlrvp.h index 4edc9a9da3..c85f2633c7 100644 --- a/baseboard/intelrvp/adlrvp.h +++ b/baseboard/intelrvp/adlrvp.h @@ -15,6 +15,9 @@ /* RVP Board ids */ #define CONFIG_BOARD_VERSION_GPIO +#define ADLM_LP4_RVP1_SKU_BOARD_ID 0x01 +#define ADLM_LP5_RVP2_SKU_BOARD_ID 0x02 +#define ADLM_LP5_RVP3_SKU_BOARD_ID 0x03 #define ADLN_LP5_ERB_SKU_BOARD_ID 0x06 #define ADLN_LP5_RVP_SKU_BOARD_ID 0x07 #define ADLP_DDR5_RVP_SKU_BOARD_ID 0x12 @@ -155,6 +158,9 @@ #define CONFIG_BATTERY_COUNT 1 #define CONFIG_HOSTCMD_BATTERY_V2 +/* Config to indicate battery type doesn't auto detect */ +#define CONFIG_BATTERY_TYPE_NO_AUTO_DETECT + #ifndef __ASSEMBLER__ enum adlrvp_charge_ports { @@ -186,7 +192,8 @@ enum ioex_port { #define CONFIG_IO_EXPANDER_PORT_COUNT IOEX_PORT_COUNT enum battery_type { - BATTERY_GETAC_SMP_HHP_408, + BATTERY_GETAC_SMP_HHP_408_3S, + BATTERY_GETAC_SMP_HHP_408_2S, BATTERY_TYPE_COUNT, }; diff --git a/baseboard/intelrvp/adlrvp_battery3s.c b/baseboard/intelrvp/adlrvp_battery.c index 612a542aea..e5bf95827e 100644 --- a/baseboard/intelrvp/adlrvp_battery3s.c +++ b/baseboard/intelrvp/adlrvp_battery.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -10,18 +10,22 @@ #include "common.h" #include "util.h" +#ifdef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT +/* Battery configuration */ const struct board_batt_params board_battery_info[] = { /* + * 3S based battery configuration * Getac Battery (Getac SMP-HHP-408) Information * Fuel gauge: BQ40Z50-R3 */ - [BATTERY_GETAC_SMP_HHP_408] = { + [BATTERY_GETAC_SMP_HHP_408_3S] = { .fuel_gauge = { .manuf_name = "Getac", .ship_mode = { .reg_addr = 0x00, .reg_data = { 0x0010, 0x0010 }, }, + .fet = { .reg_addr = 0x0, .reg_mask = 0x6000, @@ -41,7 +45,39 @@ const struct board_batt_params board_battery_info[] = { .discharging_max_c = 60, }, }, + /* + * 2S based battery configuration + * Getac Battery (Getac SMP-HHP-408) Information + * Fuel gauge: BQ40Z50-R3 + */ + [BATTERY_GETAC_SMP_HHP_408_2S] = { + .fuel_gauge = { + .manuf_name = "Getac", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x6000, + .disconnect_val = 0x6000, + } + }, + .batt_info = { + .voltage_max = 8800, /* mV */ + .voltage_normal = 7700, + .voltage_min = 6000, + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 45, + .discharging_min_c = 0, + .discharging_max_c = 60, + }, + }, }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_GETAC_SMP_HHP_408; +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_GETAC_SMP_HHP_408_3S; +#endif /* CONFIG_BATTERY_TYPE_NO_AUTO_DETECT */ diff --git a/baseboard/intelrvp/adlrvp_battery2s.c b/baseboard/intelrvp/adlrvp_battery2s.c deleted file mode 100644 index 84465426e3..0000000000 --- a/baseboard/intelrvp/adlrvp_battery2s.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Battery pack vendor provided charging profile - */ - -#include "battery_fuel_gauge.h" -#include "battery_smart.h" -#include "common.h" -#include "util.h" - -const struct board_batt_params board_battery_info[] = { - /* - * Getac Battery (Getac SMP-HHP-408) Information - * Fuel gauge: BQ40Z50-R3 - */ - [BATTERY_GETAC_SMP_HHP_408] = { - .fuel_gauge = { - .manuf_name = "Getac", - .ship_mode = { - .reg_addr = 0x00, - .reg_data = { 0x0010, 0x0010 }, - }, - .fet = { - .reg_addr = 0x0, - .reg_mask = 0x6000, - .disconnect_val = 0x6000, - } - }, - .batt_info = { - .voltage_max = 8800, /* mV */ - .voltage_normal = 7700, - .voltage_min = 6000, - .precharge_current = 256, /* mA */ - .start_charging_min_c = 0, - .start_charging_max_c = 45, - .charging_min_c = 0, - .charging_max_c = 45, - .discharging_min_c = 0, - .discharging_max_c = 60, - }, - }, -}; -BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); - -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_GETAC_SMP_HHP_408; diff --git a/baseboard/intelrvp/adlrvp_ioex_gpio.inc b/baseboard/intelrvp/adlrvp_ioex_gpio.inc index e5522b02b3..4519d3d853 100644 --- a/baseboard/intelrvp/adlrvp_ioex_gpio.inc +++ b/baseboard/intelrvp/adlrvp_ioex_gpio.inc @@ -12,6 +12,7 @@ IOEX(USB_C0_USB_MUX_CNTRL_0, EXPIN(IOEX_C0_PCA9675, 0, PCA9675_IO_P05), GPIO_OUT IOEX(USB_C1_BB_RETIMER_RST, EXPIN(IOEX_C1_PCA9675, 0, PCA9675_IO_P00), GPIO_OUT_LOW) IOEX(USB_C1_BB_RETIMER_LS_EN, EXPIN(IOEX_C1_PCA9675, 0, PCA9675_IO_P01), GPIO_OUT_LOW) +IOEX(USB_C1_HPD, EXPIN(IOEX_C1_PCA9675, 0, PCA9675_IO_P02), GPIO_OUT_LOW) IOEX(USB_C0_C1_OC, EXPIN(IOEX_C1_PCA9675, 0, PCA9675_IO_P10), GPIO_OUT_HIGH) #if defined(HAS_TASK_PD_C2) diff --git a/baseboard/intelrvp/baseboard.h b/baseboard/intelrvp/baseboard.h index 853c1e30ff..50eb6ff1f2 100644 --- a/baseboard/intelrvp/baseboard.h +++ b/baseboard/intelrvp/baseboard.h @@ -122,15 +122,17 @@ /* SoC / PCH */ #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S5 #define CONFIG_MKBP_EVENT #define CONFIG_MKBP_USE_HOST_EVENT #define CONFIG_POWER_BUTTON #define CONFIG_POWER_BUTTON_X86 #define CONFIG_POWER_COMMON #define CONFIG_POWER_S0IX +#define CONFIG_POWER_S4_RESIDENCY #define CONFIG_POWER_TRACK_HOST_SLEEP_STATE /* EC */ @@ -158,7 +160,8 @@ /* Temperature sensor */ #ifdef CONFIG_TEMP_SENSOR #define CONFIG_STEINHART_HART_3V0_22K6_47K_4050B - #define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_PP3300_A + #define CONFIG_TEMP_SENSOR_POWER + #define GPIO_TEMP_SENSOR_POWER GPIO_EN_PP3300_A #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #ifdef CONFIG_PECI diff --git a/baseboard/intelrvp/build.mk b/baseboard/intelrvp/build.mk index 6abf8bbe0c..9f92896cfc 100644 --- a/baseboard/intelrvp/build.mk +++ b/baseboard/intelrvp/build.mk @@ -31,9 +31,5 @@ ifneq ($(filter y,$(BOARD_ADLRVPP_ITE) $(BOARD_ADLRVPM_ITE) \ $(BOARD_ADLRVPP_MCHP1521) $(BOARD_ADLRVPP_NPCX) \ $(BOARD_ADLRVPP_MCHP1727)),) baseboard-y+=adlrvp.o -ifneq ($(BOARD_ADLRVPM_ITE),) -baseboard-$(CONFIG_BATTERY_SMART)+=adlrvp_battery2s.o -else -baseboard-$(CONFIG_BATTERY_SMART)+=adlrvp_battery3s.o -endif +baseboard-$(CONFIG_BATTERY_SMART)+=adlrvp_battery.o endif diff --git a/baseboard/ite_evb/baseboard.h b/baseboard/ite_evb/baseboard.h index 7fe309491c..23b3f80fba 100644 --- a/baseboard/ite_evb/baseboard.h +++ b/baseboard/ite_evb/baseboard.h @@ -30,7 +30,7 @@ #define CONFIG_SPI_CONTROLLER #define CONFIG_SPI_FLASH_PORT 0 #define CONFIG_UART_HOST -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC /* Optional console commands */ #define CONFIG_CMD_FLASH diff --git a/baseboard/kalista/baseboard.c b/baseboard/kalista/baseboard.c index f6a6b23110..b06547106a 100644 --- a/baseboard/kalista/baseboard.c +++ b/baseboard/kalista/baseboard.c @@ -128,11 +128,41 @@ const struct mft_t mft_channels[] = { BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); const struct i2c_port_t i2c_ports[] = { - {"tcpc", I2C_PORT_TCPC0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"backlight", I2C_PORT_BACKLIGHT, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"pmic", I2C_PORT_PMIC, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "backlight", + .port = I2C_PORT_BACKLIGHT, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "pmic", + .port = I2C_PORT_PMIC, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/kalista/baseboard.h b/baseboard/kalista/baseboard.h index 94ced2f989..717d26b313 100644 --- a/baseboard/kalista/baseboard.h +++ b/baseboard/kalista/baseboard.h @@ -63,7 +63,7 @@ #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/baseboard/kukui/emmc_ite.c b/baseboard/kukui/emmc_ite.c index 8c3e63064c..b0e1f6b3de 100644 --- a/baseboard/kukui/emmc_ite.c +++ b/baseboard/kukui/emmc_ite.c @@ -101,7 +101,7 @@ static void emmc_send_data_over_spi(uint8_t *tx, int tx_size, int rst_tx) IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(tx + i); /* * After writing data to TX FIFO is finished, this bit will - * be to indicate the SPI slave controller. + * be to indicate the SPI peripheral controller. */ IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS; /* End CPU access TX FIFO */ diff --git a/baseboard/octopus/baseboard.h b/baseboard/octopus/baseboard.h index f0ecab4d87..cb75bd0c1e 100644 --- a/baseboard/octopus/baseboard.h +++ b/baseboard/octopus/baseboard.h @@ -249,7 +249,7 @@ /* Common SoC / PCH defines */ #define CONFIG_CHIPSET_GEMINILAKE #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI /* TODO(b/74123961): Enable Virtual Wires after bringup */ #define CONFIG_POWER_COMMON #define CONFIG_POWER_S0IX diff --git a/baseboard/octopus/variant_ec_ite8320.c b/baseboard/octopus/variant_ec_ite8320.c index 459ea113b3..72c0021e89 100644 --- a/baseboard/octopus/variant_ec_ite8320.c +++ b/baseboard/octopus/variant_ec_ite8320.c @@ -28,10 +28,40 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"power", IT83XX_I2C_CH_A, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"sensor", IT83XX_I2C_CH_B, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"usbc0", IT83XX_I2C_CH_C, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"usbc1", IT83XX_I2C_CH_E, 400, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, - {"eeprom", IT83XX_I2C_CH_F, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, + { + .name = "power", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "sensor", + .port = IT83XX_I2C_CH_B, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "usbc0", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "usbc1", + .port = IT83XX_I2C_CH_E, + .kbps = 400, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, + { + .name = "eeprom", + .port = IT83XX_I2C_CH_F, + .kbps = 100, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/octopus/variant_ec_npcx796fb.c b/baseboard/octopus/variant_ec_npcx796fb.c index bccb360563..8c3cbd2460 100644 --- a/baseboard/octopus/variant_ec_npcx796fb.c +++ b/baseboard/octopus/variant_ec_npcx796fb.c @@ -31,13 +31,49 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"battery", I2C_PORT_BATTERY, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"eeprom", I2C_PORT_EEPROM, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"charger", I2C_PORT_CHARGER, 100, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, + { + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "charger", + .port = I2C_PORT_CHARGER, + .kbps = 100, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, #ifndef VARIANT_OCTOPUS_NO_SENSORS - {"sensor", I2C_PORT_SENSOR, 100, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 100, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, #endif }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/baseboard/octopus/variant_usbc_ec_tcpcs.c b/baseboard/octopus/variant_usbc_ec_tcpcs.c index 2e3248410f..8fa5f513e3 100644 --- a/baseboard/octopus/variant_usbc_ec_tcpcs.c +++ b/baseboard/octopus/variant_usbc_ec_tcpcs.c @@ -49,13 +49,17 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { /* TODO(crbug.com/826441): Consolidate this logic with other impls */ static void board_it83xx_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; enum gpio_signal gpio = me->usb_port ? GPIO_USB_C1_HPD_1V8_ODL : GPIO_USB_C0_HPD_1V8_ODL; + /* This driver does not use host command ACKs */ + *ack_required = false; + /* Invert HPD level since GPIOs are active low. */ hpd_lvl = !hpd_lvl; diff --git a/baseboard/trogdor/baseboard.c b/baseboard/trogdor/baseboard.c index de01d58211..21fb7cd9e1 100644 --- a/baseboard/trogdor/baseboard.c +++ b/baseboard/trogdor/baseboard.c @@ -8,13 +8,14 @@ #include "i2c.h" /* Wake-up pins for hibernate */ -const enum gpio_signal hibernate_wake_pins[] = { +enum gpio_signal hibernate_wake_pins[] = { GPIO_LID_OPEN, GPIO_AC_PRESENT, GPIO_POWER_BUTTON_L, GPIO_EC_RST_ODL, }; -const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); +int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); +BUILD_ASSERT(ARRAY_SIZE(hibernate_wake_pins) >= 3); int board_allow_i2c_passthru(int port) { diff --git a/baseboard/trogdor/baseboard.h b/baseboard/trogdor/baseboard.h index 32d797e03a..d65fb2dc1e 100644 --- a/baseboard/trogdor/baseboard.h +++ b/baseboard/trogdor/baseboard.h @@ -41,7 +41,7 @@ #undef CONFIG_PECI -#define CONFIG_HOSTCMD_SHI +#define CONFIG_HOST_INTERFACE_SHI #define CONFIG_HOST_COMMAND_STATUS #define CONFIG_HOSTCMD_SECTION_SORTED #define CONFIG_KEYBOARD_COL2_INVERTED @@ -56,6 +56,8 @@ #define CONFIG_LID_SWITCH #define CONFIG_EXTPOWER_GPIO +#define CONFIG_HIBERNATE_WAKE_PINS_DYNAMIC + /* * On power-on, H1 releases the EC from reset but then quickly asserts and * releases the reset a second time. This means the EC sees 2 resets: diff --git a/baseboard/trogdor/build.mk b/baseboard/trogdor/build.mk index 0f36051eee..a51c7c7e17 100644 --- a/baseboard/trogdor/build.mk +++ b/baseboard/trogdor/build.mk @@ -9,5 +9,4 @@ baseboard-y+=baseboard.o baseboard-y+=hibernate.o baseboard-y+=power.o -baseboard-y+=usbc_config.o baseboard-y+=usb_pd_policy.o diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h index 31764d9c12..75165d0cbc 100644 --- a/baseboard/volteer/baseboard.h +++ b/baseboard/volteer/baseboard.h @@ -43,8 +43,9 @@ #define CONFIG_BOARD_RESET_AFTER_POWER_ON /* Host communication */ -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S5 /* Chipset config */ #define CONFIG_CHIPSET_TIGERLAKE @@ -58,6 +59,7 @@ #define CONFIG_POWER_BUTTON_X86 #define CONFIG_POWER_COMMON #define CONFIG_POWER_S0IX +#define CONFIG_POWER_S4_RESIDENCY #define CONFIG_POWER_SLEEP_FAILURE_DETECTION #define CONFIG_POWER_TRACK_HOST_SLEEP_STATE #define CONFIG_BOARD_HAS_RTC_RESET @@ -95,7 +97,8 @@ /* Thermal features */ #define CONFIG_FANS FAN_CH_COUNT #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_PG_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER +#define GPIO_TEMP_SENSOR_POWER GPIO_PG_EC_DSW_PWROK #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP diff --git a/baseboard/zork/baseboard.h b/baseboard/zork/baseboard.h index d84ebbcef8..e97bcb4e45 100644 --- a/baseboard/zork/baseboard.h +++ b/baseboard/zork/baseboard.h @@ -38,7 +38,7 @@ #define CONFIG_CMD_AP_RESET_LOG #define CONFIG_CPU_PROCHOT_ACTIVE_LOW #define CONFIG_HIBERNATE_PSL -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_I2C #define CONFIG_I2C_CONTROLLER #define CONFIG_I2C_UPDATE_IF_CHANGED diff --git a/board/adlrvpp_ite/gpio.inc b/board/adlrvpp_ite/gpio.inc index 59af6cf877..00b4aefa3e 100644 --- a/board/adlrvpp_ite/gpio.inc +++ b/board/adlrvpp_ite/gpio.inc @@ -77,11 +77,11 @@ GPIO(USBC_TCPC_ALRT_P3, PIN(J, 3), GPIO_INPUT) GPIO(USBC_TCPC_PPC_ALRT_P3, PIN(E, 6), GPIO_INPUT) #endif -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(ESPI_RST_R, PIN(D, 2), GPIO_INPUT) #endif -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ GPIO_INT(ESPI_RST_R, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ #endif @@ -112,7 +112,7 @@ GPIO(SYS_PWROK_EC, PIN(D, 1), GPIO_OUT_LOW) GPIO(DSW_PWROK_EC, PIN(L, 6), GPIO_OUT_LOW) /* Host communication GPIOs */ -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(PLT_RST_L, PIN(H, 6), GPIO_INPUT | GPIO_PULL_UP) /* PCH_PLTRST_L */ #endif GPIO(PCH_WAKE_N, PIN(J, 0), GPIO_ODR_HIGH) diff --git a/board/adlrvpp_mchp1521/gpio.inc b/board/adlrvpp_mchp1521/gpio.inc index fd20e16568..5ec398903e 100644 --- a/board/adlrvpp_mchp1521/gpio.inc +++ b/board/adlrvpp_mchp1521/gpio.inc @@ -105,7 +105,7 @@ UNIMPLEMENTED(EN_PP5000) GPIO(SMC_WAKE_SCI_N, PIN(0114), GPIO_ODR_HIGH) /* EC_INT_L pin */ GPIO(EC_TRACE_DATA_0, PIN(0200), GPIO_ODR_HIGH) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(ESPI_RST_EC_R_N, PIN(061), GPIO_INPUT) #endif diff --git a/board/adlrvpp_mchp1727/board.c b/board/adlrvpp_mchp1727/board.c index 05ff3664c4..5d850c8e10 100644 --- a/board/adlrvpp_mchp1727/board.c +++ b/board/adlrvpp_mchp1727/board.c @@ -64,6 +64,8 @@ const struct i2c_port_t i2c_ports[] = { BUILD_ASSERT(ARRAY_SIZE(i2c_ports) == I2C_CHAN_COUNT); const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); +/* I2C access in polling mode before task is initialized */ +#ifdef CONFIG_I2C_BITBANG const struct i2c_port_t i2c_bitbang_ports[] = { [I2C_BITBANG_CHAN_BRD_ID] = { .name = "bitbang_brd_id", @@ -84,6 +86,7 @@ const struct i2c_port_t i2c_bitbang_ports[] = { }; BUILD_ASSERT(ARRAY_SIZE(i2c_bitbang_ports) == I2C_BITBANG_CHAN_COUNT); const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); +#endif /* USB-C TCPC Configuration */ const struct tcpc_config_t tcpc_config[] = { diff --git a/board/adlrvpp_mchp1727/board.h b/board/adlrvpp_mchp1727/board.h index 2ec76f1fe2..f3854090cd 100644 --- a/board/adlrvpp_mchp1727/board.h +++ b/board/adlrvpp_mchp1727/board.h @@ -17,6 +17,10 @@ #include "adlrvp.h" +/* Heavy I2C communication as POR, increase WDT expired time */ +#undef CONFIG_WATCHDOG_PERIOD_MS +#define CONFIG_WATCHDOG_PERIOD_MS 5000 + /* * External parallel crystal between XTAL1 and XTAL2 pins. * #define CONFIG_CLOCK_SRC_EXTERNAL diff --git a/board/adlrvpp_mchp1727/gpio.inc b/board/adlrvpp_mchp1727/gpio.inc index 1eea86462c..42973648b4 100644 --- a/board/adlrvpp_mchp1727/gpio.inc +++ b/board/adlrvpp_mchp1727/gpio.inc @@ -83,7 +83,7 @@ GPIO(USBC_TCPC_PPC_ALRT_P3, PIN(0142), GPIO_INPUT) /* Host communication GPIOs */ GPIO(SMC_WAKE_SCI_N_MECC, PIN(051), GPIO_ODR_HIGH) GPIO(EC_PCH_MKBP_INT_ODL, PIN(0127), GPIO_ODR_HIGH) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(LPC_ESPI_RST_N, PIN(061), GPIO_INPUT) GPIO(PLT_RST_L, PIN(052), GPIO_INPUT) /* PCH_PLTRST_L */ #endif diff --git a/board/adlrvpp_npcx/gpio.inc b/board/adlrvpp_npcx/gpio.inc index a059b1c6b6..4a696e4c09 100644 --- a/board/adlrvpp_npcx/gpio.inc +++ b/board/adlrvpp_npcx/gpio.inc @@ -62,7 +62,7 @@ GPIO(USBC_TCPC_PPC_ALRT_P3, PIN(F, 3), GPIO_INPUT) /* Host communication GPIOs */ GPIO(SMC_WAKE_SCI_N_MECC, PIN(A, 4), GPIO_ODR_HIGH) GPIO(EC_PCH_MKBP_INT_ODL, PIN(F, 5), GPIO_ODR_HIGH) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(LPC_ESPI_RST_N, PIN(5, 4), GPIO_INPUT | GPIO_SEL_1P8V) GPIO(PLT_RST_L, PIN(A, 2), GPIO_INPUT | GPIO_SEL_1P8V) /* PCH_PLTRST_L */ #endif diff --git a/board/akemi/board.c b/board/akemi/board.c index 1cfdedb626..e591e862b0 100644 --- a/board/akemi/board.c +++ b/board/akemi/board.c @@ -227,8 +227,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -259,8 +257,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/akemi/board.h b/board/akemi/board.h index 524607d8bb..49bb8b2837 100644 --- a/board/akemi/board.h +++ b/board/akemi/board.h @@ -16,7 +16,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -91,7 +91,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B @@ -111,6 +111,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/aleena/board.c b/board/aleena/board.c index 0343a399c5..460c73fcdd 100644 --- a/board/aleena/board.c +++ b/board/aleena/board.c @@ -35,12 +35,48 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"kblight", I2C_PORT_KBLIGHT, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "kblight", + .port = I2C_PORT_KBLIGHT, + .kbps = 100, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/ambassador/board.c b/board/ambassador/board.c index 698acf70bb..a5abbaa130 100644 --- a/board/ambassador/board.c +++ b/board/ambassador/board.c @@ -286,11 +286,41 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/ambassador/board.h b/board/ambassador/board.h index 4ca9966873..c6aac262c5 100644 --- a/board/ambassador/board.h +++ b/board/ambassador/board.h @@ -38,7 +38,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -119,7 +119,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -278,6 +278,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/ambassador/gpio.inc b/board/ambassador/gpio.inc index 9d718bb110..871031ebf9 100644 --- a/board/ambassador/gpio.inc +++ b/board/ambassador/gpio.inc @@ -64,7 +64,7 @@ GPIO_INT(USB_A4_OC_ODL, PIN(B, 0), GPIO_OUT_LOW | GPIO_INT_BOTH, port_ocp GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) diff --git a/board/ampton/battery.c b/board/ampton/battery.c index ee9b9b96e9..f52f0d5d7a 100644 --- a/board/ampton/battery.c +++ b/board/ampton/battery.c @@ -116,6 +116,34 @@ const struct board_batt_params board_battery_info[] = { .discharging_max_c = 60, }, }, + [BATTERY_C204_SECOND] = { + .fuel_gauge = { + .manuf_name = "AS3FXXd3KB", + .device_name = "C214-43", + .ship_mode = { + .reg_addr = 0x0, + .reg_data = { 0x10, 0x10 }, + }, + .fet = { + .reg_addr = 0x99, + .reg_mask = 0x000C, + .disconnect_val = 0x000C, + .cfet_mask = 0x0004, + .cfet_off_val = 0x0004 + }, + }, + .batt_info = { + .voltage_max = 13200, + .voltage_normal = 11550, + .voltage_min = 9000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); diff --git a/board/ampton/board.c b/board/ampton/board.c index 1634f02991..588cc72485 100644 --- a/board/ampton/board.c +++ b/board/ampton/board.c @@ -13,6 +13,8 @@ #include "driver/accel_bma2x2.h" #include "driver/accel_kionix.h" #include "driver/accelgyro_bmi_common.h" +#include "driver/accelgyro_icm_common.h" +#include "driver/accelgyro_icm42607.h" #include "driver/ppc/sn5s330.h" #include "driver/sync.h" #include "driver/tcpm/it83xx_pd.h" @@ -172,9 +174,21 @@ const mat33_fp_t gyro_standard_ref = { { 0, 0, FLOAT_TO_FP(1)} }; +const mat33_fp_t base_standard_ref_icm42607 = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; + +const mat33_fp_t lid_standard_ref_sku57 = { + { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(-1), 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; /* sensor private data */ static struct kionix_accel_data g_kx022_data; static struct bmi_drv_data_t g_bmi160_data; +static struct icm_drv_data_t g_icm42607_data; /* BMA253 private data */ static struct accelgyro_saved_data_t g_bma253_data; @@ -208,6 +222,49 @@ static const struct motion_sensor_t motion_sensor_bma253 = { }, }; +struct motion_sensor_t motion_sensor_accel_icm42607 = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM42607, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm42607_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm42607_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = ICM42607_ADDR0_FLAGS, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs. */ + .rot_standard_ref = &base_standard_ref_icm42607, + .min_frequency = ICM42607_ACCEL_MIN_FREQ, + .max_frequency = ICM42607_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, +}; + +struct motion_sensor_t motion_sensor_gyro_icm42607 = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM42607, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm42607_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm42607_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = ICM42607_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref_icm42607, + .min_frequency = ICM42607_GYRO_MIN_FREQ, + .max_frequency = ICM42607_GYRO_MAX_FREQ, +}; + /* Drivers */ struct motion_sensor_t motion_sensors[] = { [LID_ACCEL] = { @@ -299,7 +356,7 @@ static int board_is_convertible(void) { /* SKU IDs of Ampton & unprovisioned: 1, 2, 3, 4, 255 */ return sku_id == 1 || sku_id == 2 || sku_id == 3 || sku_id == 4 - || sku_id == 255; + || sku_id == 57 || sku_id == 255; } static int board_with_sensor_bma253(void) @@ -308,6 +365,20 @@ static int board_with_sensor_bma253(void) return sku_id == 3 || sku_id == 4; } +static int board_with_sensor_icm42607(void) +{ + /* SKU ID 3 and 4 of Ampton with BMA253 */ + return sku_id == 57; +} + +void motion_interrupt(enum gpio_signal signal) +{ + if (board_with_sensor_icm42607()) + icm42607_interrupt(signal); + else + bmi160_interrupt(signal); +} + static void board_update_sensor_config_from_sku(void) { if (board_is_convertible()) { @@ -315,6 +386,16 @@ static void board_update_sensor_config_from_sku(void) if (board_with_sensor_bma253()) motion_sensors[LID_ACCEL] = motion_sensor_bma253; + if (board_with_sensor_icm42607()) { + motion_sensors[BASE_ACCEL] = + motion_sensor_accel_icm42607; + motion_sensors[BASE_GYRO] = + motion_sensor_gyro_icm42607; + ccprints("Gyro sensor: ICM-42607"); + } + if (sku_id == 57) + motion_sensors[LID_ACCEL].rot_standard_ref = + &lid_standard_ref_sku57; /* Enable Base Accel interrupt */ gpio_enable_interrupt(GPIO_BASE_SIXAXIS_INT_L); diff --git a/board/ampton/board.h b/board/ampton/board.h index 697e7221bc..d0a3cf5bc0 100644 --- a/board/ampton/board.h +++ b/board/ampton/board.h @@ -35,11 +35,13 @@ #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_PP3300 +#define CONFIG_TEMP_SENSOR_POWER +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_PP3300 #define CONFIG_ACCEL_BMA255 /* Lid accel */ #define CONFIG_ACCEL_KX022 /* Lid accel */ #define CONFIG_ACCELGYRO_BMI160 /* Base accel */ +#define CONFIG_ACCELGYRO_ICM42607 /* Base accel */ #define CONFIG_SYNC /* Camera VSYNC */ #define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT @@ -53,6 +55,8 @@ #define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#define CONFIG_ACCELGYRO_ICM42607_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) #define CONFIG_SYNC_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(VSYNC) @@ -99,9 +103,12 @@ enum battery_type { BATTERY_C214, BATTERY_C204EE, BATTERY_C424, + BATTERY_C204_SECOND, BATTERY_TYPE_COUNT, }; +void motion_interrupt(enum gpio_signal signal); + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/ampton/gpio.inc b/board/ampton/gpio.inc index 724d9a98d9..854a28655d 100644 --- a/board/ampton/gpio.inc +++ b/board/ampton/gpio.inc @@ -32,7 +32,7 @@ GPIO_INT(RSMRST_L_PGOOD, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt) /* PM GPIO_INT(ALL_SYS_PGOOD, PIN(F, 0), GPIO_INT_BOTH, power_signal_interrupt) /* PMIC_EC_PWROK_OD */ GPIO_INT(AC_PRESENT, PIN(A, 7), GPIO_INT_BOTH, extpower_interrupt) /* ACOK_OD */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ #endif @@ -41,7 +41,7 @@ GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset GPIO_INT(TABLET_MODE_L, PIN(H, 4), GPIO_INT_BOTH, gmr_tablet_switch_isr) GPIO_INT(EC_VOLDN_BTN_ODL, PIN(D, 6), GPIO_INT_BOTH, button_interrupt) GPIO_INT(EC_VOLUP_BTN_ODL, PIN(D, 5), GPIO_INT_BOTH, button_interrupt) -GPIO_INT(BASE_SIXAXIS_INT_L, PIN(J, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, bmi160_interrupt) +GPIO_INT(BASE_SIXAXIS_INT_L, PIN(J, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, motion_interrupt) GPIO(LID_ACCEL_INT_L, PIN(J, 3), GPIO_INPUT | GPIO_SEL_1P8V) GPIO(PCH_PLTRST_L, PIN(E, 3), GPIO_INPUT) /* PLT_RST_L: Platform Reset from SoC */ diff --git a/board/anahera/board.c b/board/anahera/board.c index c1de2df6ac..dfa4e73846 100644 --- a/board/anahera/board.c +++ b/board/anahera/board.c @@ -6,6 +6,7 @@ #include "battery.h" #include "button.h" #include "charge_ramp.h" +#include "charge_state_v2.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" @@ -61,3 +62,16 @@ enum battery_present battery_hw_present(void) /* The GPIO is low when the battery is physically present */ return gpio_get_level(GPIO_EC_BATT_PRES_ODL) ? BP_NO : BP_YES; } + +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* + * Limit the input current to 95% negotiated limit, + * to account for the charger chip margin. + */ + charge_ma = charge_ma * 95 / 100; + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} diff --git a/board/anahera/board.h b/board/anahera/board.h index 591e18bced..ab362edbf7 100644 --- a/board/anahera/board.h +++ b/board/anahera/board.h @@ -71,6 +71,7 @@ #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 @@ -126,7 +127,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* Fan features */ diff --git a/board/anahera/ec.tasklist b/board/anahera/ec.tasklist index bfcf0a6416..187609f36e 100644 --- a/board/anahera/ec.tasklist +++ b/board/anahera/ec.tasklist @@ -18,6 +18,7 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, BASEBOARD_CHARGER_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/anahera/gpio.inc b/board/anahera/gpio.inc index ceb5087bd4..9aba64311c 100644 --- a/board/anahera/gpio.inc +++ b/board/anahera/gpio.inc @@ -76,7 +76,6 @@ GPIO(C0_CHARGE_LED_AMBER_L, PIN(C, 4), GPIO_OUT_HIGH) /* Amber C0 port GPIO(C0_CHARGE_LED_WHITE_L, PIN(C, 3), GPIO_OUT_HIGH) /* White C0 port */ GPIO(C1_CHARGE_LED_AMBER_L, PIN(5, 7), GPIO_OUT_HIGH) /* Amber C1 port */ GPIO(C1_CHARGE_LED_WHITE_L, PIN(9, 4), GPIO_OUT_HIGH) /* White C1 port */ -GPIO(PWR_LED_WHITE_L, PIN(C, 2), GPIO_OUT_HIGH) /* Power LED */ /* UART alternate functions */ ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* GPIO64/CR_SIN1, GPO65/CR_SOUT1/FLPRG1_L */ @@ -128,6 +127,7 @@ UNUSED(PIN(8, 1)) /* GPIO81/PECI_DATA */ UNUSED(PIN(9, 5)) /* GPIO95/SPIP_MISO */ UNUSED(PIN(B, 4)) /* GPIOB4/I2C0_SDA0 */ UNUSED(PIN(B, 5)) /* GPIOB5/I2C0_SCL0 */ +UNUSED(PIN(C, 2)) /* GPIOC2/PWM1/I2C6_SCL0 */ UNUSED(PIN(D, 4)) /* GPIOD4/CR_SIN3 */ UNUSED(PIN(F, 5)) /* GPIOF5/I2C5_SCL1 */ diff --git a/board/anahera/i2c.c b/board/anahera/i2c.c index 74208f4575..8c648416ab 100644 --- a/board/anahera/i2c.c +++ b/board/anahera/i2c.c @@ -38,7 +38,7 @@ const struct i2c_port_t i2c_ports[] = { /* I2C4 C1 TCPC */ .name = "tcpc1", .port = I2C_PORT_USB_C1_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, }, @@ -54,7 +54,7 @@ const struct i2c_port_t i2c_ports[] = { /* I2C6 */ .name = "ppc1,retimer1", .port = I2C_PORT_USB_C1_PPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_MIX_SCL, .sda = GPIO_EC_I2C_USB_C1_MIX_SDA, }, diff --git a/board/anahera/led.c b/board/anahera/led.c index c794bc8b5f..64c9ff7ba9 100644 --- a/board/anahera/led.c +++ b/board/anahera/led.c @@ -31,8 +31,7 @@ const enum ec_led_id supported_led_ids[] = { EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED, - EC_LED_ID_POWER_LED + EC_LED_ID_RIGHT_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); @@ -76,20 +75,6 @@ static void led_set_color_battery(int port, enum led_color color) } } -void led_set_color_power(enum led_color color) -{ - switch (color) { - case LED_OFF: - gpio_set_level(GPIO_PWR_LED_WHITE_L, POWER_LED_OFF); - break; - case LED_WHITE: - gpio_set_level(GPIO_PWR_LED_WHITE_L, POWER_LED_ON); - break; - default: - break; - } -} - void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { switch (led_id) { @@ -101,9 +86,6 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) brightness_range[EC_LED_COLOR_WHITE] = 1; brightness_range[EC_LED_COLOR_AMBER] = 1; break; - case EC_LED_ID_POWER_LED: - brightness_range[EC_LED_COLOR_WHITE] = 1; - break; default: break; } @@ -128,12 +110,6 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) else led_set_color_battery(RIGHT_PORT, LED_OFF); break; - case EC_LED_ID_POWER_LED: - if (brightness[EC_LED_COLOR_WHITE] != 0) - led_set_color_power(LED_WHITE); - else - led_set_color_power(LED_OFF); - break; default: return EC_ERROR_PARAM1; } @@ -160,10 +136,32 @@ static void set_active_port_color(enum led_color color) static void led_set_battery(void) { static unsigned int battery_ticks; + static unsigned int suspend_ticks; uint32_t chflags = charge_get_flags(); battery_ticks++; + /* + * Override battery LEDs for Anahera, Anahera doesn't have power LED, + * blinking both two side battery white LEDs to indicate + * system suspend without charging state. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + charge_get_state() != PWR_STATE_CHARGE) { + + suspend_ticks++; + + led_set_color_battery(RIGHT_PORT, (suspend_ticks % + LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? + LED_WHITE : LED_OFF); + led_set_color_battery(LEFT_PORT, (suspend_ticks % + LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? + LED_WHITE : LED_OFF); + return; + } + + suspend_ticks = 0; + switch (charge_get_state()) { case PWR_STATE_CHARGE: /* Always indicate when charging, even in suspend. */ @@ -203,22 +201,6 @@ static void led_set_battery(void) } } -static void led_set_power(void) -{ - static unsigned int power_tick; - - power_tick++; - - if (chipset_in_state(CHIPSET_STATE_ON)) - led_set_color_power(LED_WHITE); - else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - led_set_color_power((power_tick % - LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? - LED_WHITE : LED_OFF); - else - led_set_color_power(LED_OFF); -} - void led_task(void *u) { uint32_t start_time; @@ -227,9 +209,6 @@ void led_task(void *u) while (1) { start_time = get_time().le.lo; - if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) - led_set_power(); - led_set_battery(); /* Compute time for this iteration */ diff --git a/board/anahera/sensors.c b/board/anahera/sensors.c index 7f388579e2..7ec78642e7 100644 --- a/board/anahera/sensors.c +++ b/board/anahera/sensors.c @@ -72,15 +72,12 @@ const struct temp_sensor_t temp_sensors[] = { BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); /* - * TODO(b/199246802): Need to update for Alder Lake/anahera - */ -/* * TODO(b/202062363): Remove when clang is fixed. */ #define THERMAL_FAN \ { \ .temp_host = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), \ [EC_TEMP_THRESH_HALT] = C_TO_K(80), \ }, \ .temp_host_release = { \ @@ -90,8 +87,6 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); __maybe_unused static const struct ec_thermal_config thermal_fan = THERMAL_FAN; /* - * TODO(b/199246802): Need to update for Alder Lake/anahera - * * Tiger Lake specifies 100 C as maximum TDP temperature. THRMTRIP# occurs at * 130 C. However, sensor is located next to SOC, so we need to use the lower * SOC temperature limit (85 C) @@ -102,7 +97,7 @@ __maybe_unused static const struct ec_thermal_config thermal_fan = THERMAL_FAN; #define THERMAL_CPU \ { \ .temp_host = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), \ [EC_TEMP_THRESH_HALT] = C_TO_K(80), \ }, \ .temp_host_release = { \ @@ -112,9 +107,6 @@ __maybe_unused static const struct ec_thermal_config thermal_fan = THERMAL_FAN; __maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; /* - * TODO(b/199246802): Need to update for Alder Lake/anahera - */ -/* * TODO(b/202062363): Remove when clang is fixed. */ #define THERMAL_CHARGER \ @@ -131,19 +123,16 @@ __maybe_unused static const struct ec_thermal_config thermal_charger = THERMAL_CHARGER; /* - * TODO(b/199246802): Need to update for Alder Lake/anahera - */ -/* * TODO(b/202062363): Remove when clang is fixed. */ #define THERMAL_REGULATOR \ { \ .temp_host = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ - [EC_TEMP_THRESH_HALT] = C_TO_K(85), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(52), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(55), \ }, \ .temp_host_release = { \ - [EC_TEMP_THRESH_HIGH] = C_TO_K(75), \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(47), \ }, \ } __maybe_unused static const struct ec_thermal_config thermal_regulator = diff --git a/board/anahera/thermal.c b/board/anahera/thermal.c index c26379e356..03f3f789e8 100644 --- a/board/anahera/thermal.c +++ b/board/anahera/thermal.c @@ -37,45 +37,45 @@ struct fan_step { static const struct fan_step fan_table[] = { { /* level 0 */ - .on = {51, 51, 0, -1}, + .on = {53, 52, 0, -1}, .off = {99, 99, 99, -1}, .rpm = {0}, }, { /* level 1 */ - .on = {52, 52, 0, -1}, - .off = {50, 50, 99, -1}, - .rpm = {3000}, + .on = {54, 53, 0, -1}, + .off = {52, 51, 99, -1}, + .rpm = {3100}, }, { /* level 2 */ - .on = {53, 53, 0, -1}, - .off = {51, 51, 99, -1}, - .rpm = {3200}, + .on = {55, 54, 0, -1}, + .off = {53, 52, 99, -1}, + .rpm = {3500}, }, { /* level 3 */ - .on = {54, 54, 0, -1}, - .off = {52, 52, 99, -1}, - .rpm = {3600}, + .on = {56, 55, 0, -1}, + .off = {54, 53, 99, -1}, + .rpm = {3800}, }, { /* level 4 */ - .on = {55, 56, 56, -1}, - .off = {53, 53, 54, -1}, - .rpm = {3900}, + .on = {58, 57, 56, -1}, + .off = {55, 54, 54, -1}, + .rpm = {4100}, }, { /* level 5 */ - .on = {56, 57, 58, -1}, - .off = {54, 55, 55, -1}, - .rpm = {4200}, + .on = {59, 58, 58, -1}, + .off = {57, 56, 55, -1}, + .rpm = {4400}, }, { /* level 6 */ .on = {100, 100, 100, -1}, - .off = {55, 56, 57, -1}, - .rpm = {4600}, + .off = {58, 57, 57, -1}, + .rpm = {4900}, }, }; diff --git a/board/anahera/usbc_config.c b/board/anahera/usbc_config.c index 00b6589a46..aae3a4493b 100644 --- a/board/anahera/usbc_config.c +++ b/board/anahera/usbc_config.c @@ -208,12 +208,16 @@ static void board_tcpc_init(void) int i; /* Don't reset TCPCs after initial reset */ - if (!system_jumped_late()) { + if (!system_jumped_late()) board_reset_pd_mcu(); - for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i) - ioex_init(i); - } + /* + * These IO expander pins are implemented using the + * C0/C1 TCPCs, so they must be set up after the TCPCs has + * been taken out of reset. + */ + for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i) + ioex_init(i); /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); diff --git a/board/arcada_ish/board.c b/board/arcada_ish/board.c index 624a376dca..d4a8dbddbf 100644 --- a/board/arcada_ish/board.c +++ b/board/arcada_ish/board.c @@ -60,8 +60,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_lid_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_a_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_ACCEL_GYRO_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR1_FLAGS, .rot_standard_ref = &lid_rot_ref, @@ -90,8 +88,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_lid_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_a_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_ACCEL_GYRO_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR1_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/arcada_ish/board.h b/board/arcada_ish/board.h index ce735bd268..0064086619 100644 --- a/board/arcada_ish/board.h +++ b/board/arcada_ish/board.h @@ -62,7 +62,7 @@ #define CONFIG_DMA_PAGING /* Host command over HECI */ -#define CONFIG_HOSTCMD_HECI +#define CONFIG_HOST_INTERFACE_HECI /* I2C ports */ #define I2C_PORT_SENSOR ISH_I2C0 diff --git a/board/asurada/board.c b/board/asurada/board.c index ea7da39fa6..4d2cb81239 100644 --- a/board/asurada/board.c +++ b/board/asurada/board.c @@ -262,10 +262,8 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lis2dw12_drv, .mutex = &g_lid_mutex, .drv_data = &g_lis2dwl_data, - .int_signal = GPIO_LID_ACCEL_INT_L, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LIS2DWL_ADDR1_FLAGS, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .rot_standard_ref = NULL, /* identity matrix */ .default_range = 2, /* g */ .min_frequency = LIS2DW12_ODR_MIN_VAL, diff --git a/board/asurada/usbc_config.c b/board/asurada/usbc_config.c index 2f35816abb..63552980c3 100644 --- a/board/asurada/usbc_config.c +++ b/board/asurada/usbc_config.c @@ -23,6 +23,10 @@ void board_usb_mux_init(void) ps8743_write(&usb_muxes[1], PS8743_REG_HS_DET_THRESHOLD, PS8743_USB_HS_THRESH_NEG_10); + ps8743_field_update(&usb_muxes[1], + PS8743_REG_DCI_CONFIG_2, + PS8743_AUTO_DCI_MODE_MASK, + PS8743_AUTO_DCI_MODE_FORCE_USB); } } DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/board/atlas/board.c b/board/atlas/board.c index 4881ed6898..64d0789dd9 100644 --- a/board/atlas/board.c +++ b/board/atlas/board.c @@ -139,16 +139,41 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, - GPIO_EC_I2C0_POWER_SCL, GPIO_EC_I2C0_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, - GPIO_EC_I2C1_USB_C0_SCL, GPIO_EC_I2C1_USB_C0_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, - GPIO_EC_I2C2_USB_C1_SCL, GPIO_EC_I2C2_USB_C1_SDA}, - {"sensor", I2C_PORT_SENSOR, 100, - GPIO_EC_I2C3_SENSOR_3V3_SCL, GPIO_EC_I2C3_SENSOR_3V3_SDA}, - {"battery", I2C_PORT_BATTERY, 100, - GPIO_EC_I2C4_BATTERY_SCL, GPIO_EC_I2C4_BATTERY_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C0_POWER_SCL, + .sda = GPIO_EC_I2C0_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C1_USB_C0_SCL, + .sda = GPIO_EC_I2C1_USB_C0_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C2_USB_C1_SCL, + .sda = GPIO_EC_I2C2_USB_C1_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 100, + .scl = GPIO_EC_I2C3_SENSOR_3V3_SCL, + .sda = GPIO_EC_I2C3_SENSOR_3V3_SDA + }, + { + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C4_BATTERY_SCL, + .sda = GPIO_EC_I2C4_BATTERY_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/atlas/board.h b/board/atlas/board.h index df2a2ee2c2..6fdf77b0f0 100644 --- a/board/atlas/board.h +++ b/board/atlas/board.h @@ -54,7 +54,7 @@ #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_RESET_HOOK #define CONFIG_CPU_PROCHOT_ACTIVE_LOW -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 diff --git a/board/baklava/board.c b/board/baklava/board.c index 35a27d0c21..12365e0ff6 100644 --- a/board/baklava/board.c +++ b/board/baklava/board.c @@ -262,6 +262,31 @@ int dock_get_mf_preference(void) { return MF_ON; } + +static void board_usb_tc_connect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* + * The EC needs to indicate to the MST hub when the host port is + * attached. GPIO_UFP_PLUG_DET is used for this purpose. + */ + if (port == USB_PD_PORT_HOST) + gpio_set_level(GPIO_UFP_PLUG_DET, 0); +} +DECLARE_HOOK(HOOK_USB_PD_CONNECT, board_usb_tc_connect, HOOK_PRIO_DEFAULT); + +static void board_usb_tc_disconnect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* Only the host port disconnect is relevant */ + if (port == USB_PD_PORT_HOST) + gpio_set_level(GPIO_UFP_PLUG_DET, 1); +} +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, board_usb_tc_disconnect, \ + HOOK_PRIO_DEFAULT); + #endif /* SECTION_IS_RW */ static void board_init(void) diff --git a/board/bds/board.c b/board/bds/board.c index 91da893a52..aedc570d51 100644 --- a/board/bds/board.c +++ b/board/bds/board.c @@ -33,7 +33,11 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"lightbar", 5, 400}, + { + .name = "lightbar", + .port = 5, + .kbps = 400 + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/bds/board.h b/board/bds/board.h index c859089f04..21dc2ad598 100644 --- a/board/bds/board.h +++ b/board/bds/board.h @@ -19,7 +19,7 @@ /* Modules we want to exclude */ #undef CONFIG_LID_SWITCH -#undef CONFIG_HOSTCMD_LPC +#undef CONFIG_HOST_INTERFACE_LPC #undef CONFIG_PECI #undef CONFIG_SWITCH diff --git a/board/beadrix/battery.c b/board/beadrix/battery.c new file mode 100644 index 0000000000..8ebdaf466d --- /dev/null +++ b/board/beadrix/battery.c @@ -0,0 +1,66 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_fuel_gauge.h" +#include "charge_state.h" +#include "common.h" + +/* + * Battery info for all beadrix battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* GanFeng SG20 Battery Information */ + [BATTERY_GANFENG] = { + .fuel_gauge = { + .manuf_name = "Ganfeng", + .device_name = "SG20", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x43, + .reg_mask = 0x0003, + .disconnect_val = 0x0000, + } + }, + .batt_info = { + .voltage_max = 8700, /* mV */ + .voltage_normal = 7600, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_GANFENG; diff --git a/board/beadrix/board.c b/board/beadrix/board.c new file mode 100644 index 0000000000..4312141fe7 --- /dev/null +++ b/board/beadrix/board.c @@ -0,0 +1,589 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Waddledee board-specific configuration */ + +#include "adc_chip.h" +#include "button.h" +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "driver/accel_kionix.h" +#include "driver/accelgyro_lsm6dsm.h" +#include "driver/bc12/pi3usb9201.h" +#include "driver/charger/sm5803.h" +#include "driver/retimer/tusb544.h" +#include "driver/temp_sensor/thermistor.h" +#include "driver/tcpm/anx7447.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/usb_mux/it5205.h" +#include "gpio.h" +#include "hooks.h" +#include "intc.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "switch.h" +#include "system.h" +#include "tablet_mode.h" +#include "task.h" +#include "tcpm/tcpci.h" +#include "temp_sensor.h" +#include "uart.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" + +#define CPRINTUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) + +#define INT_RECHECK_US 5000 + +/* C1 interrupt line swapped between board versions, track it in a variable */ +static enum gpio_signal c1_int_line; + +/* C0 interrupt line shared by BC 1.2 and charger */ +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) +{ + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); + sm5803_interrupt(0); +} + +static void check_c0_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips + */ + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +static void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12); + sm5803_interrupt(1); +} + +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_get_level(c1_int_line)) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +static void usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); +} + +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); +} + +/* Must come after other header files and interrupt handler declarations */ +#include "gpio_list.h" + +/* ADC channels */ +const struct adc_t adc_channels[] = { + [ADC_VSNS_PP3300_A] = { + .name = "PP3300_A_PGOOD", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH0 + }, + [ADC_TEMP_SENSOR_1] = { + .name = "TEMP_SENSOR1", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH2 + }, + [ADC_TEMP_SENSOR_2] = { + .name = "TEMP_SENSOR2", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH3 + }, + [ADC_SUB_ANALOG] = { + .name = "SUB_ANALOG", + .factor_mul = ADC_MAX_MVOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + .channel = CHIP_ADC_CH13 + }, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +/* BC 1.2 chips */ +const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { + { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + .flags = PI3USB9201_ALWAYS_POWERED, + }, + { + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + .flags = PI3USB9201_ALWAYS_POWERED, + }, +}; + +/* Charger chips */ +const struct charger_config_t chg_chips[] = { + [CHARGER_PRIMARY] = { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = SM5803_ADDR_CHARGER_FLAGS, + .drv = &sm5803_drv, + }, + [CHARGER_SECONDARY] = { + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = SM5803_ADDR_CHARGER_FLAGS, + .drv = &sm5803_drv, + }, +}; + +/* TCPCs */ +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + .drv = &it83xx_tcpm_drv, + }, + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_SUB_USB_C1, + .addr_flags = AN7447_TCPC0_I2C_ADDR_FLAGS, + }, + .drv = &anx7447_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, +}; + +/* USB Retimer */ +const struct usb_mux usbc1_retimer = { + .usb_port = 1, + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = TUSB544_I2C_ADDR_FLAGS0, + .driver = &tusb544_drv, +}; + +/* USB Muxes */ +const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .usb_port = 0, + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS, + .driver = &it5205_usb_mux_driver, + }, + { + .usb_port = 1, + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = AN7447_TCPC0_I2C_ADDR_FLAGS, + .driver = &anx7447_usb_mux_driver, + .next_mux = &usbc1_retimer, + }, +}; + +void board_init(void) +{ + int on; + + if (system_get_board_version() <= 0) { + pd_set_max_voltage(5000); + c1_int_line = GPIO_USB_C1_INT_V0_ODL; + } else { + c1_int_line = GPIO_USB_C1_INT_V1_ODL; + } + + + gpio_enable_interrupt(GPIO_USB_C0_INT_ODL); + gpio_enable_interrupt(c1_int_line); + + /* + * If interrupt lines are already low, schedule them to be processed + * after inits are completed. + */ + check_c0_line(); + check_c1_line(); + + gpio_enable_interrupt(GPIO_USB_C0_CCSBU_OVP_ODL); + /* Enable Base Accel interrupt */ + gpio_enable_interrupt(GPIO_BASE_SIXAXIS_INT_L); + + /* Charger on the MB will be outputting PROCHOT_ODL and OD CHG_DET */ + sm5803_configure_gpio0(CHARGER_PRIMARY, GPIO0_MODE_PROCHOT, 1); + sm5803_configure_chg_det_od(CHARGER_PRIMARY, 1); + + /* Charger on the sub-board will be a push-pull GPIO */ + sm5803_configure_gpio0(CHARGER_SECONDARY, GPIO0_MODE_OUTPUT, 0); + + /* Turn on 5V if the system is on, otherwise turn it off */ + on = chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_ANY_SUSPEND | + CHIPSET_STATE_SOFT_OFF); + board_power_5v_enable(on); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +static void board_resume(void) +{ + sm5803_disable_low_power_mode(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + sm5803_disable_low_power_mode(CHARGER_SECONDARY); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_resume, HOOK_PRIO_DEFAULT); + +static void board_suspend(void) +{ + sm5803_enable_low_power_mode(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + sm5803_enable_low_power_mode(CHARGER_SECONDARY); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_suspend, HOOK_PRIO_DEFAULT); + +void board_hibernate(void) +{ + /* + * Put all charger ICs present into low power mode before entering + * z-state. + */ + sm5803_hibernate(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + sm5803_hibernate(CHARGER_SECONDARY); +} + +__override void board_ocpc_init(struct ocpc_data *ocpc) +{ + /* There's no provision to measure Isys */ + ocpc->chg_flags[CHARGER_SECONDARY] |= OCPC_NO_ISYS_MEAS_CAP; +} + +void board_reset_pd_mcu(void) +{ + /* + * Nothing to do. TCPC C0 is internal, TCPC C1 reset pin is not + * connected to the EC. + */ +} + +__override void board_power_5v_enable(int enable) +{ + /* + * Motherboard has a GPIO to turn on the 5V regulator, but the sub-board + * sets it through the charger GPIO. + */ + gpio_set_level(GPIO_EN_PP5000, !!enable); + gpio_set_level(GPIO_EN_USB_A0_VBUS, !!enable); + if (sm5803_set_gpio0_level(1, !!enable)) + CPRINTUSB("Failed to %sable sub rails!", enable ? "en" : "dis"); +} + +uint16_t tcpc_get_alert_status(void) +{ + /* + * TCPC 0 is embedded in the EC and processes interrupts in the chip + * code (it83xx/intc.c) + */ + + uint16_t status = 0; + int regval; + + /* Check whether TCPC 1 pulled the shared interrupt line */ + if (!gpio_get_level(c1_int_line)) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + if (regval) + status = PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, + int charge_mv) +{ + int icl = MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT); + + /* + * TODO(b/151955431): Characterize the input current limit in case a + * scaling needs to be applied here + */ + charge_set_input_current_limit(icl, charge_mv); +} + +int board_set_active_charge_port(int port) +{ + int is_valid_port = (port >= 0 && port < board_get_usb_pd_port_count()); + + if (!is_valid_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + if (port == CHARGE_PORT_NONE) { + CPRINTUSB("Disabling all charge ports"); + + sm5803_vbus_sink_enable(CHARGER_PRIMARY, 0); + + if (board_get_charger_chip_count() > 1) + sm5803_vbus_sink_enable(CHARGER_SECONDARY, 0); + + return EC_SUCCESS; + } + + CPRINTUSB("New chg p%d", port); + + /* + * Ensure other port is turned off, then enable new charge port + */ + if (port == 0) { + if (board_get_charger_chip_count() > 1) + sm5803_vbus_sink_enable(CHARGER_SECONDARY, 0); + sm5803_vbus_sink_enable(CHARGER_PRIMARY, 1); + + } else { + sm5803_vbus_sink_enable(CHARGER_PRIMARY, 0); + sm5803_vbus_sink_enable(CHARGER_SECONDARY, 1); + } + + return EC_SUCCESS; +} + +/* 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); +} + +__override void ocpc_get_pid_constants(int *kp, int *kp_div, + int *ki, int *ki_div, + int *kd, int *kd_div) +{ + *kp = 3; + *kp_div = 14; + + *ki = 3; + *ki_div = 500; + + *kd = 4; + *kd_div = 40; +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + int current; + + if (port < 0 || port > CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + current = (rp == TYPEC_RP_3A0) ? 3000 : 1500; + + charger_set_otg_current_voltage(port, current, 5000); +} + +/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ +const struct pwm_t pwm_channels[] = { + [PWM_CH_KBLIGHT] = { + .channel = 0, + .flags = PWM_CONFIG_DSLEEP, + .freq_hz = 10000, + } +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +/* Sensor Mutexes */ +static struct mutex g_lid_mutex; +static struct mutex g_base_mutex; + +/* Sensor Data */ +static struct kionix_accel_data g_kx022_data; +static struct lsm6dsm_data lsm6dsm_data = LSM6DSM_DATA; + +/* Drivers */ +struct motion_sensor_t motion_sensors[] = { + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_KX022, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &kionix_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_kx022_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = KX022_ADDR1_FLAGS, + .rot_standard_ref = NULL, + .default_range = 2, /* g */ + /* We only use 2g because its resolution is only 8-bits */ + .min_frequency = KX022_ACCEL_MIN_FREQ, + .max_frequency = KX022_ACCEL_MAX_FREQ, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSM, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dsm_drv, + .mutex = &g_base_mutex, + .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, + MOTIONSENSE_TYPE_ACCEL), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, + .rot_standard_ref = NULL, + .default_range = 4, /* g */ + .min_frequency = LSM6DSM_ODR_MIN_VAL, + .max_frequency = LSM6DSM_ODR_MAX_VAL, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSM, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dsm_drv, + .mutex = &g_base_mutex, + .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, + MOTIONSENSE_TYPE_GYRO), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, + .default_range = 1000 | ROUND_UP_FLAG, /* dps */ + .rot_standard_ref = NULL, + .min_frequency = LSM6DSM_ODR_MIN_VAL, + .max_frequency = LSM6DSM_ODR_MAX_VAL, + }, +}; + +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +/* Thermistors */ +const struct temp_sensor_t temp_sensors[] = { + [TEMP_SENSOR_1] = {.name = "Memory", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_1}, + [TEMP_SENSOR_2] = {.name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_2}, +}; +BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +/* This callback disables keyboard when convertibles are fully open */ +__override void lid_angle_peripheral_enable(int enable) +{ + int chipset_in_s0 = chipset_in_state(CHIPSET_STATE_ON); + + /* + * If the lid is in tablet position via other sensors, + * ignore the lid angle, which might be faulty then + * disable keyboard. + */ + if (tablet_get_mode()) + enable = 0; + + if (enable) { + keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE); + } else { + /* + * Ensure that the chipset is off before disabling the keyboard. + * When the chipset is on, the EC keeps the keyboard enabled and + * the AP decides whether to ignore input devices or not. + */ + if (!chipset_in_s0) + keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE); + } +} + +static const struct ec_response_keybd_config keybd1 = { + .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 */ + }, + /* No function keys, no numeric keypad and no screenlock key */ +}; + +__override const struct ec_response_keybd_config +*board_vivaldi_keybd_config(void) +{ + /* + * Future boards should use fw_config if needed. + */ + + return &keybd1; +} diff --git a/board/beadrix/board.h b/board/beadrix/board.h new file mode 100644 index 0000000000..e9787c9373 --- /dev/null +++ b/board/beadrix/board.h @@ -0,0 +1,131 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Waddledee board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* Select Baseboard features */ +#define VARIANT_DEDEDE_EC_IT8320 +#include "baseboard.h" + +/* System unlocked in early development */ +#define CONFIG_SYSTEM_UNLOCKED + +#define CONFIG_CMD_CHARGER_DUMP + +/* Battery */ +#define CONFIG_BATTERY_FUEL_GAUGE + +/* BC 1.2 */ +#define CONFIG_BC12_DETECT_PI3USB9201 + +/* Charger */ +#define CONFIG_CHARGER_SM5803 /* C0 and C1: Charger */ +#define CONFIG_USB_PD_VBUS_DETECT_CHARGER +#define CONFIG_USB_PD_5V_CHARGER_CTRL +#define CONFIG_CHARGER_OTG +#undef CONFIG_CHARGER_SINGLE_CHIP +#define CONFIG_OCPC +#define CONFIG_OCPC_DEF_RBATT_MOHMS 21 /* R_DS(on) 10.7mOhm + 10mOhm sns rstr */ + +/* + * GPIO for C1 interrupts, for baseboard use + * + * Note this will only be valid for board revision 1 + */ +#define GPIO_USB_C1_INT_ODL GPIO_USB_C1_INT_V1_ODL + +/* PWM */ +#define CONFIG_PWM + +/* Sensors */ +#define CONFIG_ACCEL_KX022 /* Lid accel */ +#define CONFIG_ACCELGYRO_LSM6DSM /* Base accel */ +/* Sensors without hardware FIFO are in forced mode */ +#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) + +#define CONFIG_ACCEL_INTERRUPTS +/* Enable sensor fifo, must also define the _SIZE and _THRES */ +#define CONFIG_ACCEL_FIFO +/* Power of 2 - Too large of a fifo causes too much timestamp jitter */ +#define CONFIG_ACCEL_FIFO_SIZE 256 +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) + +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL + +#define CONFIG_TABLET_MODE +#define CONFIG_TABLET_MODE_SWITCH +#define CONFIG_GMR_TABLET_MODE + +/* TCPC */ +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP /* C0: ITE EC TCPC */ +#define CONFIG_USB_PD_TCPM_ANX7447 /* C1: ANX TCPC + Mux */ +#define CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT 1 + +/* Thermistors */ +#define CONFIG_TEMP_SENSOR +#define CONFIG_THERMISTOR +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B + +/* USB Mux and Retimer */ +#define CONFIG_USB_MUX_IT5205 /* C1: ITE Mux */ +#define I2C_PORT_USB_MUX I2C_PORT_USB_C0 /* Required for ITE Mux */ + +#define CONFIG_USBC_RETIMER_TUSB544 /* C1 Redriver: TUSB544 */ + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +enum chg_id { + CHARGER_PRIMARY, + CHARGER_SECONDARY, + CHARGER_NUM, +}; + +enum pwm_channel { + PWM_CH_KBLIGHT, + PWM_CH_COUNT, +}; + +/* Motion sensors */ +enum sensor_id { + LID_ACCEL, + BASE_ACCEL, + BASE_GYRO, + SENSOR_COUNT +}; + +/* ADC channels */ +enum adc_channel { + ADC_VSNS_PP3300_A, /* ADC0 */ + ADC_TEMP_SENSOR_1, /* ADC2 */ + ADC_TEMP_SENSOR_2, /* ADC3 */ + ADC_SUB_ANALOG, /* ADC13 */ + ADC_CH_COUNT +}; + +enum temp_sensor_id { + TEMP_SENSOR_1, + TEMP_SENSOR_2, + TEMP_SENSOR_COUNT +}; + +/* List of possible batteries */ +enum battery_type { + BATTERY_GANFENG, + BATTERY_TYPE_COUNT, +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/krabby/build.mk b/board/beadrix/build.mk index 86903344a1..8167ca9966 100644 --- a/board/krabby/build.mk +++ b/board/beadrix/build.mk @@ -4,13 +4,12 @@ # found in the LICENSE file. # # Board specific files build +# -# the IC is ITE IT8xxx2 CHIP:=it83xx -CHIP_FAMILY:=it8xxx2 -CHIP_VARIANT:=it81202bx_1024 -BASEBOARD:=corsola +CHIP_FAMILY:=it8320 +CHIP_VARIANT:=it8320dx +BASEBOARD:=dedede -board-y=led.o -board-y+=battery.o board.o hooks.o -board-y+=usbc_config.o +board-y=board.o cbi_ssfc.o led.o usb_pd_policy.o +board-$(CONFIG_BATTERY_SMART)+=battery.o diff --git a/board/beadrix/cbi_ssfc.c b/board/beadrix/cbi_ssfc.c new file mode 100644 index 0000000000..c4b859f133 --- /dev/null +++ b/board/beadrix/cbi_ssfc.c @@ -0,0 +1,36 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "cbi_ssfc.h" +#include "common.h" +#include "console.h" +#include "cros_board_info.h" +#include "hooks.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) + +/* Cache SSFC on init since we don't expect it to change in runtime */ +static union dedede_cbi_ssfc cached_ssfc; +BUILD_ASSERT(sizeof(cached_ssfc) == sizeof(uint32_t)); + +static void cbi_ssfc_init(void) +{ + if (cbi_get_ssfc(&cached_ssfc.raw_value) != EC_SUCCESS) + /* Default to 0 when CBI isn't populated */ + cached_ssfc.raw_value = 0; + + CPRINTS("Read CBI SSFC : 0x%04X", cached_ssfc.raw_value); +} +DECLARE_HOOK(HOOK_INIT, cbi_ssfc_init, HOOK_PRIO_FIRST); + +enum ec_ssfc_base_sensor get_cbi_ssfc_base_sensor(void) +{ + return (enum ec_ssfc_base_sensor) cached_ssfc.base_sensor; +} + +enum ec_ssfc_lid_sensor get_cbi_ssfc_lid_sensor(void) +{ + return (enum ec_ssfc_lid_sensor) cached_ssfc.lid_sensor; +} diff --git a/board/beadrix/cbi_ssfc.h b/board/beadrix/cbi_ssfc.h new file mode 100644 index 0000000000..935049b6ae --- /dev/null +++ b/board/beadrix/cbi_ssfc.h @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef _DEDEDE_CBI_SSFC__H_ +#define _DEDEDE_CBI_SSFC__H_ + +#include "stdint.h" + +/**************************************************************************** + * Dedede CBI Second Source Factory Cache + */ + +/* + * Base Sensor (Bits 0-2) + */ +enum ec_ssfc_base_sensor { + SSFC_SENSOR_BASE_DEFAULT = 0, + SSFC_SENSOR_BMI160 = 1, + SSFC_SENSOR_ICM426XX = 2, + SSFC_SENSOR_LSM6DSM = 3, + SSFC_SENSOR_ICM42607 = 4 +}; + +/* + * Lid Sensor (Bits 3-5) + */ +enum ec_ssfc_lid_sensor { + SSFC_SENSOR_LID_DEFAULT = 0, + SSFC_SENSOR_BMA255 = 1, + SSFC_SENSOR_KX022 = 2, + SSFC_SENSOR_LIS2DWL = 3 +}; + +union dedede_cbi_ssfc { + struct { + uint32_t base_sensor : 3; + uint32_t lid_sensor : 3; + uint32_t reserved_2 : 26; + }; + uint32_t raw_value; +}; + +/** + * Get the Base sensor type from SSFC_CONFIG. + * + * @return the Base sensor board type. + */ +enum ec_ssfc_base_sensor get_cbi_ssfc_base_sensor(void); + +/** + * Get the Lid sensor type from SSFC_CONFIG. + * + * @return the Lid sensor board type. + */ +enum ec_ssfc_lid_sensor get_cbi_ssfc_lid_sensor(void); + + +#endif /* _DEDEDE_CBI_SSFC__H_ */ diff --git a/board/beadrix/ec.tasklist b/board/beadrix/ec.tasklist new file mode 100644 index 0000000000..5c9a2d1a01 --- /dev/null +++ b/board/beadrix/ec.tasklist @@ -0,0 +1,24 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * See CONFIG_TASK_LIST in config.h for details. + */ + +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CHARGER, charger_task, NULL, TRENTA_TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, ULTRA_TASK_STACK_SIZE) diff --git a/board/beadrix/gpio.inc b/board/beadrix/gpio.inc new file mode 100644 index 0000000000..7b14151e12 --- /dev/null +++ b/board/beadrix/gpio.inc @@ -0,0 +1,142 @@ +/* -*- mode:c -*- + * + * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Declare symbolic names for all the GPIOs that we care about. + * Note: Those with interrupt handlers must be declared first. */ + +/* Power State interrupts */ +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(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(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(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 */ +#endif + +/* USB-C interrupts */ +GPIO_INT(USB_C0_INT_ODL, PIN(K, 0), GPIO_INT_FALLING | GPIO_PULL_UP, usb_c0_interrupt) /* BC12 and charger */ +GPIO_INT(USB_C1_INT_V0_ODL, PIN(B, 5), GPIO_INT_FALLING | GPIO_PULL_UP, usb_c1_interrupt) /* TCPC, charger, BC12 - board version 0 */ +GPIO_INT(USB_C1_INT_V1_ODL, PIN(E, 6), GPIO_INT_FALLING | GPIO_PULL_UP, usb_c1_interrupt) /* TCPC, charger, BC12 - board version 1 */ +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(LID_OPEN, PIN(F, 3), GPIO_INT_BOTH, lid_interrupt) +GPIO_INT(LID_360_L, PIN(A, 7), GPIO_INT_BOTH, gmr_tablet_switch_isr) +GPIO_INT(VOLDN_BTN_ODL, PIN(I, 6), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(VOLUP_BTN_ODL, PIN(I, 7), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(BASE_SIXAXIS_INT_L, PIN(J, 0), GPIO_INT_FALLING | GPIO_SEL_1P8V, lsm6dsm_interrupt) +GPIO_INT(EC_WP_OD, PIN(A, 6), GPIO_INT_BOTH, switch_interrupt) + +/* Power sequence GPIOs */ +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) +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(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_SLP_Z, PIN(K, 3), GPIO_OUT_LOW) + +/* Required for icelake chipset code, but implemented through other means for dedede */ +UNIMPLEMENTED(AC_PRESENT) +UNIMPLEMENTED(PG_EC_DSW_PWROK) +UNIMPLEMENTED(PG_EC_ALL_SYS_PWRGD) + +/* 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_SUB_USB_C1_SCL, PIN(E, 0), GPIO_INPUT) +GPIO(EC_I2C_SUB_USB_C1_SDA, PIN(E, 7), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SCL, PIN(A, 4), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SDA, PIN(A, 5), 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(EC_AP_USB_C1_HDMI_HPD, PIN(K, 7), GPIO_OUT_LOW) +GPIO(USB_C0_FRS, PIN(C, 4), GPIO_OUT_LOW) +GPIO(HDMI_SEL_L, PIN(C, 6), GPIO_OUT_HIGH) +GPIO(EN_USB_A0_VBUS, PIN(L, 6), GPIO_OUT_LOW) /* Board rev 1, NC board rev 0 */ + +/* MKBP event synchronization */ +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) + +/* Misc */ +GPIO(EN_BL_OD, PIN(K, 4), GPIO_ODR_LOW) +GPIO(EC_ENTERING_RW, PIN(G, 0), GPIO_OUT_LOW) +GPIO(CCD_MODE_ODL, PIN(H, 5), GPIO_ODR_HIGH) +GPIO(EC_BATTERY_PRES_ODL, PIN(I, 4), GPIO_INPUT) +GPIO(PEN_DET_ODL, PIN(J, 1), GPIO_INPUT | GPIO_PULL_UP) +GPIO(EN_KB_BL, PIN(J, 3), GPIO_OUT_LOW) /* Currently unused */ +GPIO(ECH1_PACKET_MODE, PIN(H, 1), GPIO_OUT_LOW) + +/* LEDs */ +GPIO(EC_LED_R_ODL, PIN(A, 1), GPIO_OUT_LOW) +GPIO(EC_LED_B_ODL, PIN(A, 3), GPIO_OUT_LOW) + +/* 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(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(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(GPIOM6_NC, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) + +/* 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 */ + +/* ADC */ +ALTERNATE(PIN_MASK(L, BIT(0)), 0, MODULE_ADC, 0) /* ADC13: EC_SUB_ANALOG */ +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 */ + +/* PWM */ +ALTERNATE(PIN_MASK(A, BIT(0)), 0, MODULE_PWM, 0) /* KB_BL_PWM */ diff --git a/board/beadrix/led.c b/board/beadrix/led.c new file mode 100644 index 0000000000..ab011d49d4 --- /dev/null +++ b/board/beadrix/led.c @@ -0,0 +1,154 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Beadrix specific LED settings. */ + +#include "battery.h" +#include "charge_manager.h" +#include "charge_state.h" +#include "chipset.h" +#include "common.h" +#include "ec_commands.h" +#include "gpio.h" +#include "hooks.h" +#include "host_command.h" +#include "led_common.h" +#include "system.h" +#include "util.h" + +#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS) +#define BAT_LED_ON 0 +#define BAT_LED_OFF 1 + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED +}; +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +enum led_color { + LED_OFF = 0, + LED_RED, + LED_BLUE, + LED_COLOR_COUNT /* Number of colors, not a color itself */ +}; + +static void led_set_color(enum led_color color) +{ + gpio_set_level(GPIO_EC_LED_R_ODL, + (color == LED_RED) ? BAT_LED_ON : BAT_LED_OFF); + gpio_set_level(GPIO_EC_LED_B_ODL, + (color == LED_BLUE) ? BAT_LED_ON : BAT_LED_OFF); +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + brightness_range[EC_LED_COLOR_RED] = 1; + brightness_range[EC_LED_COLOR_BLUE] = 1; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (brightness[EC_LED_COLOR_BLUE] != 0) + led_set_color(LED_BLUE); + else if (brightness[EC_LED_COLOR_RED] != 0) + led_set_color(LED_RED); + else + led_set_color(LED_OFF); + + return EC_SUCCESS; +} + +static void board_led_set_battery(void) +{ + static int battery_ticks; + enum led_color color = LED_OFF; + int period = 0; + uint32_t chflags = charge_get_flags(); + + battery_ticks++; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + /* Always indicate amber on when charging. */ + color = LED_RED; + break; + case PWR_STATE_DISCHARGE: + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) { + /* Discharging in S3: Red 1 sec, off 3 sec */ + period = (1 + 3) * LED_ONE_SEC; + battery_ticks = battery_ticks % period; + if (battery_ticks < 1 * LED_ONE_SEC) + color = LED_RED; + else + color = LED_OFF; + } else if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + /* Discharging in S5: off */ + color = LED_OFF; + } else if (chipset_in_state(CHIPSET_STATE_ON)) { + /* Discharging in S0: Blue on */ + color = LED_BLUE; + } + break; + case PWR_STATE_ERROR: + /* Battery error: Red 1 sec, off 1 sec */ + period = (1 + 1) * LED_ONE_SEC; + battery_ticks = battery_ticks % period; + if (battery_ticks < 1 * LED_ONE_SEC) + color = LED_RED; + else + color = LED_OFF; + break; + case PWR_STATE_CHARGE_NEAR_FULL: + /* Full Charged: Blue on */ + color = LED_BLUE; + break; + case PWR_STATE_IDLE: /* External power connected in IDLE */ + if (chflags & CHARGE_FLAG_FORCE_IDLE) { + /* Factory mode: Blue 2 sec, Red 2 sec */ + period = (2 + 2) * LED_ONE_SEC; + battery_ticks = battery_ticks % period; + if (battery_ticks < 2 * LED_ONE_SEC) + color = LED_BLUE; + else + color = LED_RED; + } else + color = LED_BLUE; + break; + default: + /* Other states don't alter LED behavior */ + break; + } + + led_set_color(color); +} + +/* Called by hook task every TICK */ +static void led_tick(void) +{ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + board_led_set_battery(); +} +DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); + +void led_control(enum ec_led_id led_id, enum ec_led_state state) +{ + enum led_color color; + + if ((led_id != EC_LED_ID_RECOVERY_HW_REINIT_LED) && + (led_id != EC_LED_ID_SYSRQ_DEBUG_LED)) + return; + + if (state == LED_STATE_RESET) { + led_auto_control(EC_LED_ID_BATTERY_LED, 1); + board_led_set_battery(); + return; + } + + color = state ? LED_BLUE : LED_OFF; + + led_auto_control(EC_LED_ID_BATTERY_LED, 0); + + led_set_color(color); +} diff --git a/board/beadrix/usb_pd_policy.c b/board/beadrix/usb_pd_policy.c new file mode 100644 index 0000000000..3ff7152541 --- /dev/null +++ b/board/beadrix/usb_pd_policy.c @@ -0,0 +1,85 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery_smart.h" +#include "charge_manager.h" +#include "charger.h" +#include "chipset.h" +#include "common.h" +#include "console.h" +#include "driver/charger/sm5803.h" +#include "driver/tcpm/tcpci.h" +#include "usb_pd.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on */ + return chipset_in_state(CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_ON); +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + if (port < 0 || port >= board_get_usb_pd_port_count()) + return; + + prev_en = charger_is_sourcing_otg_power(port); + + /* Disable Vbus */ + charger_enable_otg_power(port, 0); + + /* Discharge Vbus if previously enabled */ + if (prev_en) + sm5803_set_vbus_disch(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + enum ec_error_list rv; + + /* Disable sinking */ + rv = sm5803_vbus_sink_enable(port, 0); + if (rv) + return rv; + + /* Disable Vbus discharge */ + sm5803_set_vbus_disch(port, 0); + + /* Provide Vbus */ + charger_enable_otg_power(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +__override bool pd_check_vbus_level(int port, enum vbus_level level) +{ + int vbus_voltage; + + /* If we're unable to speak to the charger, best to guess false */ + if (charger_get_vbus_voltage(port, &vbus_voltage)) + return false; + + if (level == VBUS_SAFE0V) + return vbus_voltage < PD_V_SAFE0V_MAX; + else if (level == VBUS_PRESENT) + return vbus_voltage > PD_V_SAFE5V_MIN; + else + return vbus_voltage < PD_V_SINK_DISCONNECT_MAX; +} + +int pd_snk_is_vbus_provided(int port) +{ + return sm5803_is_vbus_present(port); +} diff --git a/board/kingler/vif_override.xml b/board/beadrix/vif_override.xml index 32736caf64..32736caf64 100644 --- a/board/kingler/vif_override.xml +++ b/board/beadrix/vif_override.xml diff --git a/board/beetley/board.c b/board/beetley/board.c index 08c9ba5066..096e590a70 100644 --- a/board/beetley/board.c +++ b/board/beetley/board.c @@ -266,8 +266,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_lsm6dsm_ref, @@ -295,8 +293,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/blipper/board.c b/board/blipper/board.c index 0f19763ebd..047e28f277 100644 --- a/board/blipper/board.c +++ b/board/blipper/board.c @@ -273,8 +273,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = NULL, /* identity matrix */ @@ -302,8 +300,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -454,9 +450,11 @@ void board_init(void) gpio_set_flags(GPIO_BASE_SIXAXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN); + /* Disable Volume keys for blipper */ + button_disable_gpio(BUTTON_VOLUME_UP); + button_disable_gpio(BUTTON_VOLUME_DOWN); gpio_set_flags(GPIO_VOLDN_BTN_ODL, GPIO_INPUT | GPIO_PULL_DOWN); - gpio_set_flags(GPIO_VOLUP_BTN_ODL, GPIO_INPUT | GPIO_PULL_DOWN); } else { diff --git a/board/blipper/board.h b/board/blipper/board.h index 9f0865b66b..b4dc85d9fa 100644 --- a/board/blipper/board.h +++ b/board/blipper/board.h @@ -110,6 +110,9 @@ #define USB_PORT_COUNT 1 #define CONFIG_USB_PORT_POWER_DUMB +/* Button Config*/ +#define CONFIG_BUTTONS_RUNTIME_CONFIG + #ifndef __ASSEMBLER__ #include "gpio_signal.h" diff --git a/board/bloog/board.c b/board/bloog/board.c index dfad4ab281..47802bf584 100644 --- a/board/bloog/board.c +++ b/board/bloog/board.c @@ -167,8 +167,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -199,8 +197,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/boldar/ec.tasklist b/board/boldar/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/boldar/ec.tasklist +++ b/board/boldar/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/boten/board.c b/board/boten/board.c index 17436a0091..f4c951a7c4 100644 --- a/board/boten/board.c +++ b/board/boten/board.c @@ -397,8 +397,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -426,8 +424,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -472,6 +468,8 @@ void board_init(void) gpio_set_flags(GPIO_LID_360_L, GPIO_INPUT | GPIO_PULL_DOWN); gpio_set_flags(GPIO_VOLUP_BTN_ODL, GPIO_INPUT | GPIO_PULL_DOWN); gpio_set_flags(GPIO_VOLDN_BTN_ODL, GPIO_INPUT | GPIO_PULL_DOWN); + button_disable_gpio(BUTTON_VOLUME_UP); + button_disable_gpio(BUTTON_VOLUME_DOWN); } /* Set LEDs luminance */ diff --git a/board/boten/board.h b/board/boten/board.h index 8c2b1d4417..bebc7d37c5 100644 --- a/board/boten/board.h +++ b/board/boten/board.h @@ -94,6 +94,7 @@ #define CONFIG_USB_PORT_POWER_DUMB #define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT +#define CONFIG_BUTTONS_RUNTIME_CONFIG #ifndef __ASSEMBLER__ diff --git a/board/brask/board.h b/board/brask/board.h index df15615bdd..a9bb47c3b0 100644 --- a/board/brask/board.h +++ b/board/brask/board.h @@ -38,11 +38,12 @@ #define CONFIG_USB_PD_PPC #define CONFIG_USB_PD_TCPM_RT1715 #define CONFIG_USBC_RETIMER_INTEL_BB -/* TODO: Do not add CONFIG_KB800X_CUSTOM_XBAR until find out how - * to config ss_lane. - */ + #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 */ @@ -74,6 +75,7 @@ #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 @@ -128,7 +130,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* ADC */ @@ -138,7 +140,7 @@ * 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 */ + #define CONFIG_FANS FAN_CH_COUNT /* Include math_util for bitmask_uint64 used in pd_timers */ #define CONFIG_MATH_UTIL diff --git a/board/brask/build.mk b/board/brask/build.mk index 442a708d78..81ecfa4164 100644 --- a/board/brask/build.mk +++ b/board/brask/build.mk @@ -13,6 +13,7 @@ BASEBOARD:=brask board-y= board-y+=board.o +board-y+=fans.o board-y+=i2c.o board-y+=led.o board-y+=pwm.o diff --git a/board/brask/fans.c b/board/brask/fans.c new file mode 100644 index 0000000000..f2a70636d0 --- /dev/null +++ b/board/brask/fans.c @@ -0,0 +1,50 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Physical fans. These are logically separate from pwm_channels. */ + +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "fan_chip.h" +#include "fan.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/brask/gpio.inc b/board/brask/gpio.inc index 49403519c6..fddf0ee837 100644 --- a/board/brask/gpio.inc +++ b/board/brask/gpio.inc @@ -73,6 +73,7 @@ GPIO(GSC_EC_RECOVERY_BTN_OD, PIN(2, 2), GPIO_INPUT) 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 */ /* TODO(b/191418683): Implement Qi Driver */ @@ -82,7 +83,7 @@ GPIO(EC_I2C_QI_INT_ODL, PIN(9, 6), GPIO_INPUT) /* HDMI CEC */ /* TODO(b/197474873): Enable HDMI CEC */ -GPIO(HDMI_CEC_IN, PIN(7, 3), GPIO_INPUT) +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) @@ -106,7 +107,7 @@ 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_OC_ODL, PIN(3, 1), GPIO_INPUT) +GPIO(USB_A0_OC_ODL, PIN(3, 1), GPIO_INPUT | GPIO_PULL_UP) GPIO(USB_A1_OC_ODL, PIN(3, 0), GPIO_INPUT | GPIO_PULL_UP) GPIO(USB_A2_OC_ODL, PIN(2, 7), GPIO_INPUT | GPIO_PULL_UP) GPIO(USB_A3_OC_ODL, PIN(2, 6), GPIO_INPUT | GPIO_PULL_UP) @@ -118,6 +119,7 @@ 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 */ @@ -128,7 +130,7 @@ GPIO(LED_RED_L, PIN(C, 4), GPIO_OUT_LOW) 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_ODL, PIN(0, 2), GPIO_ODR_LOW) +GPIO(USB_C1_RT_RST_R_L, PIN(0, 2), GPIO_OUT_LOW) /* GPIO02_P2 to PU */ /* GPIO03_P2 to PU */ @@ -156,7 +158,7 @@ ALTERNATE(PIN_MASK(E, 0x18), 0, MODULE_I2C, 0) /* GPIOE4/I2C6_SCL1 ALTERNATE(PIN_MASK(F, 0x0c), 0, MODULE_I2C, 0) /* GPIOF3/I2C4_SCL1, GPIOF2/I2C4_SDA1 */ /* PWM alternate functions */ -ALTERNATE(PIN_MASK(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ +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 */ @@ -177,6 +179,4 @@ 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, 5)) /* KSO12/GPIO05 */ -UNUSED(PIN(0, 4)) /* KSO13/GPIO04 */ -UNUSED(PIN(8, 0)) /* GPIO80/PWM3 */ +UNUSED(PIN(0, 4)) /* KSO13/GPIO04 */
\ No newline at end of file diff --git a/board/brask/usbc_config.c b/board/brask/usbc_config.c index 8363c71f88..6e5ac609f3 100644 --- a/board/brask/usbc_config.c +++ b/board/brask/usbc_config.c @@ -111,7 +111,13 @@ struct kb800x_control_t kb800x_control[] = { [USBC_PORT_C0] = { }, [USBC_PORT_C1] = { - .retimer_rst_gpio = GPIO_USB_C1_RT_RST_R_ODL, + .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] = { }, @@ -249,7 +255,7 @@ void board_reset_pd_mcu(void) */ gpio_set_level(tcpc_rst, 0); - gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0); + gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 0); /* * delay for power-on to reset-off and min. assertion time @@ -258,7 +264,7 @@ void board_reset_pd_mcu(void) msleep(20); gpio_set_level(tcpc_rst, 1); - gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1); + gpio_set_level(GPIO_USB_C1_RT_RST_R_L, 1); /* wait for chips to come up */ diff --git a/board/brya/board.h b/board/brya/board.h index f7ce860fe9..a599476530 100644 --- a/board/brya/board.h +++ b/board/brya/board.h @@ -132,6 +132,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -196,7 +197,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_FANS FAN_CH_COUNT diff --git a/board/brya/ec.tasklist b/board/brya/ec.tasklist index e4ad7a05a8..260f6561d9 100644 --- a/board/brya/ec.tasklist +++ b/board/brya/ec.tasklist @@ -20,6 +20,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/brya/fw_config.c b/board/brya/fw_config.c index 9c28c3ca58..414908a1f1 100644 --- a/board/brya/fw_config.c +++ b/board/brya/fw_config.c @@ -10,7 +10,7 @@ #include "cros_board_info.h" #include "fw_config.h" -#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) static union brya_cbi_fw_config fw_config; BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t)); diff --git a/board/brya/generated-gpio.inc b/board/brya/generated-gpio.inc index 4daa60c5c9..f4772188a5 100644 --- a/board/brya/generated-gpio.inc +++ b/board/brya/generated-gpio.inc @@ -120,5 +120,6 @@ 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(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/brya/sensors.c b/board/brya/sensors.c index 0a4b0198bd..b68a2b6d3d 100644 --- a/board/brya/sensors.c +++ b/board/brya/sensors.c @@ -131,10 +131,8 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lis2dw12_drv, .mutex = &g_lid_accel_mutex, .drv_data = &g_lis2dw12_data, - .int_signal = GPIO_EC_ACCEL_INT_R_L, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LIS2DW12_ADDR0, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .rot_standard_ref = &lid_standard_ref, /* identity matrix */ .default_range = 2, /* g */ .min_frequency = LIS2DW12_ODR_MIN_VAL, @@ -161,8 +159,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -191,8 +187,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/brya/usbc_config.c b/board/brya/usbc_config.c index f653a93d1f..7f54cde5a5 100644 --- a/board/brya/usbc_config.c +++ b/board/brya/usbc_config.c @@ -354,29 +354,23 @@ void board_reset_pd_mcu(void) 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()) { + 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. - */ - if (get_board_id() == 1) { - enable_ioex(IOEX_ID_1_C0_NCT38XX); - enable_ioex(IOEX_ID_1_C2_NCT38XX); - } else { - enable_ioex(IOEX_C0_NCT38XX); - enable_ioex(IOEX_C2_NCT38XX); - } + /* + * 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. + */ + if (get_board_id() == 1) { + ioex_init(IOEX_ID_1_C0_NCT38XX); + ioex_init(IOEX_ID_1_C2_NCT38XX); + } else { + ioex_init(IOEX_C0_NCT38XX); + ioex_init(IOEX_C2_NCT38XX); } /* Enable PPC interrupts. */ diff --git a/board/bugzzy/board.c b/board/bugzzy/board.c index 315f3a738b..64a24f0618 100644 --- a/board/bugzzy/board.c +++ b/board/bugzzy/board.c @@ -438,6 +438,12 @@ static const mat33_fp_t base_standard_ref = { { 0, 0, FLOAT_TO_FP(-1)} }; +static const mat33_fp_t base_standard_ref_lsm = { + { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(-1), 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; + struct motion_sensor_t ldm6dsm_base_accel = { .name = "Base Accel", .active_mask = SENSOR_ACTIVE_S0_S3, @@ -448,11 +454,9 @@ struct motion_sensor_t ldm6dsm_base_accel = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &base_standard_ref_lsm, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ .min_frequency = LSM6DSM_ODR_MIN_VAL, .max_frequency = LSM6DSM_ODR_MAX_VAL, @@ -479,12 +483,10 @@ struct motion_sensor_t ldm6dsm_base_gyro = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &base_standard_ref_lsm, .min_frequency = LSM6DSM_ODR_MIN_VAL, .max_frequency = LSM6DSM_ODR_MAX_VAL, @@ -871,6 +873,11 @@ static void lcd_reset_change_deferred(void) if (signal != 0) return; + signal = gpio_get_level(GPIO_EN_PP1800_PANEL_S0); + + if (signal == 0) + return; + i2c_write8(I2C_PORT_LCD, I2C_ADDR_ISL98607_FLAGS, ISL98607_REG_ENABLE, ISL97607_VP_VN_VBST_DIS); @@ -878,7 +885,7 @@ static void lcd_reset_change_deferred(void) DECLARE_DEFERRED(lcd_reset_change_deferred); void lcd_reset_change_interrupt(enum gpio_signal signal) { - hook_call_deferred(&lcd_reset_change_deferred_data, 10 * MSEC); + hook_call_deferred(&lcd_reset_change_deferred_data, 45 * MSEC); } /** @@ -921,7 +928,7 @@ void backlit_gpio_tick(void) if (board_id >= 4 && signal == 1) i2c_write16(I2C_PORT_LCD, I2C_ADDR_MP3372_FLAGS, MP3372_REG_ISET_CHEN, - MP3372_ISET_19P4_CHEN_ALL); + MP3372_ISET_15P3_CHEN_ALL); } DECLARE_HOOK(HOOK_TICK, backlit_gpio_tick, HOOK_PRIO_DEFAULT); diff --git a/board/bugzzy/board.h b/board/bugzzy/board.h index 9b9f6cf015..7782cecbe0 100644 --- a/board/bugzzy/board.h +++ b/board/bugzzy/board.h @@ -11,12 +11,7 @@ #define VARIANT_DEDEDE_EC_NPCX796FC #include "baseboard.h" -/* - * Keep the system unlocked in early development. - * TODO(b/151264302): Make sure to remove this before production! - */ -#define CONFIG_SYSTEM_UNLOCKED - +#undef CONFIG_I2C_DEBUG /* * The RAM and flash size combination on the the NPCX797FC does not leave * any unused flash space that can be used to store the .init_rom section. @@ -147,6 +142,9 @@ #define MP3372_REG_ISET_CHEN 0x00 #define MP3372_ISET_21P8_CHEN_ALL 0x70ff #define MP3372_ISET_19P4_CHEN_ALL 0x63ff +#define MP3372_ISET_18P0_CHEN_ALL 0x5cff +#define MP3372_ISET_15P8_CHEN_ALL 0x50ff +#define MP3372_ISET_15P3_CHEN_ALL 0x4eff /* * I2C pin names for baseboard * diff --git a/board/bugzzy/led.c b/board/bugzzy/led.c index d04026e0f0..17da244534 100644 --- a/board/bugzzy/led.c +++ b/board/bugzzy/led.c @@ -53,12 +53,23 @@ const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); __override void led_set_color_power(enum ec_led_colors color) { + static enum ec_led_colors prev_color = EC_LED_COLOR_COUNT; + /* Don't set led if led_auto_control is disabled. */ if (!led_auto_control_is_enabled(EC_LED_ID_POWER_LED) || !led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) { return; } + /* + * Sometimes system wakes and sleeps automatically. + * Add LED debounce time to prevent blinking led by this. + */ + if (prev_color != color) { + prev_color = color; + return; + } + if (color == EC_LED_COLOR_BLUE) { gpio_set_level(GPIO_BAT_LED_RED_L, LED_OFF_LVL); @@ -72,6 +83,8 @@ __override void led_set_color_power(enum ec_led_colors color) __override void led_set_color_battery(enum ec_led_colors color) { + static enum ec_led_colors prev_color = EC_LED_COLOR_COUNT; + /* Don't set led if led_auto_control is disabled. */ if (!led_auto_control_is_enabled(EC_LED_ID_POWER_LED) || !led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) { @@ -79,6 +92,14 @@ __override void led_set_color_battery(enum ec_led_colors color) } /* + * Sometimes system wakes and sleeps automatically. + * Add LED debounce time to prevent blinking led by this. + */ + if (prev_color != color) { + prev_color = color; + return; + } + /* * Battery leds must be turn off when blue led is on * because bugzzy has 3-in-1 led. */ diff --git a/board/burnet/board.c b/board/burnet/board.c index f98955a19d..5ee2ad3965 100644 --- a/board/burnet/board.c +++ b/board/burnet/board.c @@ -69,13 +69,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -141,8 +160,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/burnet/board.h b/board/burnet/board.h index 3f92864907..f59d3d5972 100644 --- a/board/burnet/board.h +++ b/board/burnet/board.h @@ -89,7 +89,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/c2d2/board.c b/board/c2d2/board.c index 3327ea43b6..7e83c58013 100644 --- a/board/c2d2/board.c +++ b/board/c2d2/board.c @@ -155,6 +155,7 @@ const void *const usb_strings[] = { [USB_STR_USART4_STREAM_NAME] = USB_STRING_DESC("CR50"), [USB_STR_UPDATE_NAME] = USB_STRING_DESC("Firmware update"), [USB_STR_CONSOLE_NAME] = USB_STRING_DESC("C2D2 Shell"), + [USB_STR_SPI_NAME] = USB_STRING_DESC("SPI"), [USB_STR_I2C_NAME] = USB_STRING_DESC("I2C"), [USB_STR_USART3_STREAM_NAME] = USB_STRING_DESC("CPU"), [USB_STR_USART1_STREAM_NAME] = USB_STRING_DESC("EC"), diff --git a/board/c2d2/board.h b/board/c2d2/board.h index a8095ece4d..ada5b01ab6 100644 --- a/board/c2d2/board.h +++ b/board/c2d2/board.h @@ -128,6 +128,7 @@ enum usb_strings { USB_STR_USART4_STREAM_NAME, USB_STR_UPDATE_NAME, USB_STR_CONSOLE_NAME, + USB_STR_SPI_NAME, USB_STR_I2C_NAME, USB_STR_USART3_STREAM_NAME, USB_STR_USART1_STREAM_NAME, diff --git a/board/cappy2/board.h b/board/cappy2/board.h index be34d2b906..5a2fa75bba 100644 --- a/board/cappy2/board.h +++ b/board/cappy2/board.h @@ -77,7 +77,8 @@ #define CONFIG_TEMP_SENSOR #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_PP3300_A +#define CONFIG_TEMP_SENSOR_POWER +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_PP3300_A /* I2C configuration */ #define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 diff --git a/board/careena/board.c b/board/careena/board.c index ea2a886c03..e8171b1be0 100644 --- a/board/careena/board.c +++ b/board/careena/board.c @@ -30,11 +30,41 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/cerise/board.c b/board/cerise/board.c index 78ab8f6de8..9f2f93e12d 100644 --- a/board/cerise/board.c +++ b/board/cerise/board.c @@ -67,13 +67,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -139,8 +158,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/cerise/board.h b/board/cerise/board.h index 5cf8c06f01..ce2b692ae8 100644 --- a/board/cerise/board.h +++ b/board/cerise/board.h @@ -86,7 +86,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/cherry/board.h b/board/cherry/board.h index 9db5042085..1c52eac8ba 100644 --- a/board/cherry/board.h +++ b/board/cherry/board.h @@ -15,6 +15,7 @@ /* Optional features */ #define CONFIG_SYSTEM_UNLOCKED #define CONFIG_LTO +#define CONFIG_PRESERVE_LOGS /* * TODO: Remove this option once the VBAT no longer keeps high when @@ -29,7 +30,7 @@ #define CONFIG_LED_ONOFF_STATES_BAT_LOW 10 /* PD / USB-C / PPC */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 +#define CONFIG_USB_PD_DEBUG_LEVEL 0 /* Optional console commands */ #define CONFIG_CMD_FLASH diff --git a/board/cherry_scp/board.h b/board/cherry_scp/board.h index a698ff2bb3..dcf7f09a6f 100644 --- a/board/cherry_scp/board.h +++ b/board/cherry_scp/board.h @@ -14,7 +14,7 @@ * RW only, no flash * +-------------------- 0x0 * | ROM vectortable, .text, .rodata, .data LMA - * +-------------------- 0x58000 + * +-------------------- 0x68000 * | RAM .bss, .data * +-------------------- 0xbfc00 * | Reserved (padding for 1k-alignment) diff --git a/board/chronicler/battery.c b/board/chronicler/battery.c index 82347953ba..aee0095765 100644 --- a/board/chronicler/battery.c +++ b/board/chronicler/battery.c @@ -32,41 +32,7 @@ * address, mask, and disconnect value need to be provided. */ const struct board_batt_params board_battery_info[] = { - /* Fujitsu CP813907-01 Battery Information */ - [BATTERY_FUJITSU_CP813907] = { - .fuel_gauge = { - .manuf_name = "Fujitsu", - .device_name = "CP813907-01", - .ship_mode = { - .reg_addr = 0x00, - .reg_data = { 0x10, 0x10 }, - }, - .fet = { - .reg_addr = 0x00, - .reg_mask = 0x2000, - .disconnect_val = 0x2000, - } - }, - .batt_info = { - .voltage_max = 13200, /* mV */ - .voltage_normal = 11550, /* mV */ - .voltage_min = 9000, /* mV */ - .precharge_current = 128, /* mA */ - .start_charging_min_c = 0, - .start_charging_max_c = 45, - .charging_min_c = 0, - .charging_max_c = 55, - .discharging_min_c = -20, - .discharging_max_c = 60, - }, - }, - /* NVT CP813907-01 Battery Information */ - /* - * NVT CP813907-01 Battery only use to support early - * stage battery, all battery for PVT will update - * manufacturer name to Fujitsu. See b/190685811. - */ [BATTERY_NVT_CP813907] = { .fuel_gauge = { .manuf_name = "NVT", @@ -97,4 +63,4 @@ const struct board_batt_params board_battery_info[] = { }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_FUJITSU_CP813907; +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_NVT_CP813907; diff --git a/board/chronicler/board.h b/board/chronicler/board.h index 1a205d06ae..87d1c2a21f 100644 --- a/board/chronicler/board.h +++ b/board/chronicler/board.h @@ -137,7 +137,6 @@ #include "usbc_config.h" enum battery_type { - BATTERY_FUJITSU_CP813907, BATTERY_NVT_CP813907, BATTERY_TYPE_COUNT }; diff --git a/board/chronicler/ec.tasklist b/board/chronicler/ec.tasklist index c7a977f0ff..df7495f2a1 100644 --- a/board/chronicler/ec.tasklist +++ b/board/chronicler/ec.tasklist @@ -15,6 +15,7 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/coachz/board.c b/board/coachz/board.c index 81a749c1d1..01c4d85b95 100644 --- a/board/coachz/board.c +++ b/board/coachz/board.c @@ -191,18 +191,48 @@ static void ks_interrupt(enum gpio_signal s) /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"wlc", I2C_PORT_WLC, 400, GPIO_EC_I2C_WLC_SCL, - GPIO_EC_I2C_WLC_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "wlc", + .port = I2C_PORT_WLC, + .kbps = 400, + .scl = GPIO_EC_I2C_WLC_SCL, + .sda = GPIO_EC_I2C_WLC_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/coachz/build.mk b/board/coachz/build.mk index 5b6ecb0398..e8e293064e 100644 --- a/board/coachz/build.mk +++ b/board/coachz/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o base_detect.o +board-y=battery.o board.o led.o base_detect.o usbc_config.o diff --git a/baseboard/trogdor/usbc_config.c b/board/coachz/usbc_config.c index 8f3fb02c30..8f3fb02c30 100644 --- a/baseboard/trogdor/usbc_config.c +++ b/board/coachz/usbc_config.c diff --git a/board/coffeecake/board.c b/board/coffeecake/board.c index 2939a65125..b344a5f745 100644 --- a/board/coffeecake/board.c +++ b/board/coffeecake/board.c @@ -31,7 +31,13 @@ void vbus_event(enum gpio_signal signal); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"charger", I2C_PORT_SY21612, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, + { + .name = "charger", + .port = I2C_PORT_SY21612, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/coffeecake/board.h b/board/coffeecake/board.h index d655466a14..cabbb0bf4e 100644 --- a/board/coffeecake/board.h +++ b/board/coffeecake/board.h @@ -32,7 +32,7 @@ #define CONFIG_RWSIG #define CONFIG_RWSIG_TYPE_USBPD1 #define CONFIG_SHA256 -/* TODO(tbroch) Re-enable once STM spi master can be inhibited at boot so it +/* TODO(tbroch) Re-enable once STM spi controller can be inhibited at boot so it doesn't interfere with HDMI loading its f/w */ #undef CONFIG_SPI_FLASH #define CONFIG_SPI_CS_GPIO GPIO_PD_MCDP_SPI_CS_L diff --git a/board/collis/ec.tasklist b/board/collis/ec.tasklist index e76bd368eb..ca6d9fbf14 100644 --- a/board/collis/ec.tasklist +++ b/board/collis/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/copano/ec.tasklist b/board/copano/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/copano/ec.tasklist +++ b/board/copano/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/coral/board.c b/board/coral/board.c index a563071294..17fd01da0e 100644 --- a/board/coral/board.c +++ b/board/coral/board.c @@ -154,16 +154,41 @@ const struct pwm_t pwm_channels[] = { BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); const struct i2c_port_t i2c_ports[] = { - {"tcpc0", NPCX_I2C_PORT0_0, 400, - GPIO_EC_I2C_USB_C0_PD_SCL, GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", NPCX_I2C_PORT0_1, 400, - GPIO_EC_I2C_USB_C1_PD_SCL, GPIO_EC_I2C_USB_C1_PD_SDA}, - {"accelgyro", I2C_PORT_GYRO, 400, - GPIO_EC_I2C_GYRO_SCL, GPIO_EC_I2C_GYRO_SDA}, - {"sensors", NPCX_I2C_PORT2, 400, - GPIO_EC_I2C_SENSOR_SCL, GPIO_EC_I2C_SENSOR_SDA}, - {"batt", NPCX_I2C_PORT3, 100, - GPIO_EC_I2C_POWER_SCL, GPIO_EC_I2C_POWER_SDA}, + { + .name = "tcpc0", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "accelgyro", + .port = I2C_PORT_GYRO, + .kbps = 400, + .scl = GPIO_EC_I2C_GYRO_SCL, + .sda = GPIO_EC_I2C_GYRO_SDA + }, + { + .name = "sensors", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, + { + .name = "batt", + .port = NPCX_I2C_PORT3, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/coral/board.h b/board/coral/board.h index 0def402993..bac1a2c5f5 100644 --- a/board/coral/board.h +++ b/board/coral/board.h @@ -105,7 +105,7 @@ #define CONFIG_USBC_VCONN_SWAP /* SoC / PCH */ -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_CHIPSET_APOLLOLAKE #define CONFIG_CHIPSET_RESET_HOOK #define CONFIG_POWER_BUTTON diff --git a/board/coral/gpio.inc b/board/coral/gpio.inc index 0f3acc3375..da15615c86 100644 --- a/board/coral/gpio.inc +++ b/board/coral/gpio.inc @@ -62,7 +62,7 @@ GPIO(EC_I2C_POWER_SCL, PIN(D, 1), GPIO_INPUT) * Pin 57 (SER_IRQ) defaults to LPC mode, but we also have EC_PCH_KB_INT_ODL * (Pin B0) in case it doesn't work (Set CONFIG_KEYBOARD_IRQ_GPIO in this case). * - * See also the NO_LPC_ESPI bit in DEVALT1 and the CONFIG_HOSTCMD_SHI option. + * See also the NO_LPC_ESPI bit in DEVALT1 and the CONFIG_HOST_INTERFACE_SHI option. */ GPIO(PCH_SMI_L, PIN(A, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_SMI_ODL */ diff --git a/board/corori/board.c b/board/corori/board.c index 03f9641d9f..dc946fa4f9 100644 --- a/board/corori/board.c +++ b/board/corori/board.c @@ -447,30 +447,45 @@ DECLARE_HOOK(HOOK_AC_CHANGE, board_extpower, HOOK_PRIO_DEFAULT); const struct i2c_port_t i2c_ports[] = { { - "eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA }, { - "battery", I2C_PORT_BATTERY, 100, GPIO_EC_I2C_BATTERY_SCL, - GPIO_EC_I2C_BATTERY_SDA + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BATTERY_SCL, + .sda = GPIO_EC_I2C_BATTERY_SDA }, #ifdef HAS_TASK_MOTIONSENSE { - "sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA }, #endif { - "usbc0", I2C_PORT_USB_C0, 1000, GPIO_EC_I2C_USB_C0_SCL, - GPIO_EC_I2C_USB_C0_SDA + .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_SCL, + .sda = GPIO_EC_I2C_USB_C0_SDA }, #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 { - "sub_usbc1", I2C_PORT_SUB_USB_C1, 1000, - GPIO_EC_I2C_SUB_USB_C1_SCL, GPIO_EC_I2C_SUB_USB_C1_SDA + .name = "sub_usbc1", + .port = I2C_PORT_SUB_USB_C1, + .kbps = 1000, + .scl = GPIO_EC_I2C_SUB_USB_C1_SCL, + .sda = GPIO_EC_I2C_SUB_USB_C1_SDA }, #endif }; diff --git a/board/corori2/battery.c b/board/corori2/battery.c new file mode 100644 index 0000000000..1263e4cef0 --- /dev/null +++ b/board/corori2/battery.c @@ -0,0 +1,100 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery.h" +#include "battery_fuel_gauge.h" +#include "charge_state.h" +#include "common.h" +#include "util.h" + +/* + * Battery info for all waddledoo battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* C21N2018 Battery Information*/ + [BATTERY_C21N2018] = { + .fuel_gauge = { + .manuf_name = "AS3GXXD3KA", + .device_name = "C110160", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + .cfet_mask = 0x4000, + .cfet_off_val = 0x4000, + }, + }, + .batt_info = { + .voltage_max = 8800, + .voltage_normal = 7890, + .voltage_min = 6000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, + /* C21N2018 second Battery Information*/ + [BATTERY_C21N2018_2ND] = { + .fuel_gauge = { + .manuf_name = "AS3FXXD3KA", + .device_name = "C110160", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + .cfet_mask = 0x4000, + .cfet_off_val = 0x4000, + }, + }, + .batt_info = { + .voltage_max = 8800, + .voltage_normal = 7890, + .voltage_min = 6000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_C21N2018; diff --git a/board/corori2/board.c b/board/corori2/board.c new file mode 100644 index 0000000000..df2fac683f --- /dev/null +++ b/board/corori2/board.c @@ -0,0 +1,745 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Waddledoo board-specific configuration */ + +#include "adc_chip.h" +#include "button.h" +#include "cbi_fw_config.h" +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "chipset.h" +#include "common.h" +#include "compile_time_macros.h" +#include "driver/temp_sensor/thermistor.h" +#include "temp_sensor.h" +#include "driver/accel_bma2x2.h" +#include "driver/accelgyro_bmi_common.h" +#include "driver/bc12/pi3usb9201.h" +#include "driver/charger/isl923x.h" +#include "driver/retimer/nb7v904m.h" +#include "driver/tcpm/raa489000.h" +#include "driver/tcpm/tcpci.h" +#include "driver/usb_mux/pi3usb3x532.h" +#include "extpower.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "motion_sense.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "stdbool.h" +#include "switch.h" +#include "system.h" +#include "tablet_mode.h" +#include "task.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +#define INT_RECHECK_US 5000 + +/* C0 interrupt line shared by BC 1.2 and charger */ +static void check_c0_line(void); +DECLARE_DEFERRED(check_c0_line); + +static void notify_c0_chips(void) +{ + /* + * The interrupt line is shared between the TCPC and BC 1.2 detection + * chip. Therefore we'll need to check both ICs. + */ + schedule_deferred_pd_interrupt(0); + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); +} + +static void check_c0_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips + */ + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) { + notify_c0_chips(); + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + } +} + +static void usb_c0_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c0_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c0_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c0_line_data, INT_RECHECK_US); + +} + +/* C1 interrupt line shared by BC 1.2, TCPC, and charger */ +static void check_c1_line(void); +DECLARE_DEFERRED(check_c1_line); + +static void notify_c1_chips(void) +{ + schedule_deferred_pd_interrupt(1); + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12); +} + +static void check_c1_line(void) +{ + /* + * If line is still being held low, see if there's more to process from + * one of the chips. + */ + if (!gpio_get_level(GPIO_SUB_C1_INT_EN_RAILS_ODL)) { + notify_c1_chips(); + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + } +} + +static void sub_usb_c1_interrupt(enum gpio_signal s) +{ + /* Cancel any previous calls to check the interrupt line */ + hook_call_deferred(&check_c1_line_data, -1); + + /* Notify all chips using this line that an interrupt came in */ + notify_c1_chips(); + + /* Check the line again in 5ms */ + hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); + +} + +static void sub_hdmi_hpd_interrupt(enum gpio_signal s) +{ + int hdmi_hpd_odl = gpio_get_level(GPIO_EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL); + + gpio_set_level(GPIO_EC_AP_USB_C1_HDMI_HPD, !hdmi_hpd_odl); +} + +#include "gpio_list.h" + +/* ADC channels */ +const struct adc_t adc_channels[] = { + [ADC_TEMP_SENSOR_1] = { + .name = "TEMP_SENSOR1", + .input_ch = NPCX_ADC_CH0, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_2] = { + .name = "TEMP_SENSOR2", + .input_ch = NPCX_ADC_CH1, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_SUB_ANALOG] = { + .name = "SUB_ANALOG", + .input_ch = NPCX_ADC_CH2, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_VSNS_PP3300_A] = { + .name = "PP3300_A_PGOOD", + .input_ch = NPCX_ADC_CH9, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +/* Thermistors */ +const struct temp_sensor_t temp_sensors[] = { + [ADC_TEMP_SENSOR_1] = {.name = "Memory", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_1}, + [ADC_TEMP_SENSOR_2] = {.name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_2}, +}; +BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_MEMORY \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_WARN] = 0, \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(95), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_WARN] = 0, \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(70), \ + [EC_TEMP_THRESH_HALT] = 0, \ + }, \ + } +__maybe_unused static const struct ec_thermal_config thermal_memory = + THERMAL_MEMORY; + +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_CHARGER \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_WARN] = 0, \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(85), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_WARN] = 0, \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(55), \ + [EC_TEMP_THRESH_HALT] = 0, \ + }, \ + } +__maybe_unused static const struct ec_thermal_config thermal_charger = + THERMAL_CHARGER; + +struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT]; + +static void setup_thermal(void) +{ + thermal_params[ADC_TEMP_SENSOR_1] = thermal_memory; + thermal_params[ADC_TEMP_SENSOR_2] = thermal_charger; +} + +void board_init(void) +{ + int on; + + /* Enable C0 interrupt and check if it needs processing */ + gpio_enable_interrupt(GPIO_USB_C0_INT_ODL); + check_c0_line(); + + if (get_cbi_fw_config_db() == DB_1A_HDMI) { + /* Disable i2c on HDMI pins */ + gpio_config_pin(MODULE_I2C, + GPIO_EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL, 0); + gpio_config_pin(MODULE_I2C, + GPIO_EC_I2C_SUB_C1_SCL_HDMI_EN_ODL, 0); + + /* Set HDMI and sub-rail enables to output */ + gpio_set_flags(GPIO_EC_I2C_SUB_C1_SCL_HDMI_EN_ODL, + chipset_in_state(CHIPSET_STATE_ON) ? + GPIO_ODR_LOW : GPIO_ODR_HIGH); + gpio_set_flags(GPIO_SUB_C1_INT_EN_RAILS_ODL, GPIO_ODR_HIGH); + + /* Select HDMI option */ + gpio_set_level(GPIO_HDMI_SEL_L, 0); + + /* Enable interrupt for passing through HPD */ + gpio_enable_interrupt(GPIO_EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL); + } else { + /* Set SDA as an input */ + gpio_set_flags(GPIO_EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL, + GPIO_INPUT); + + /* Enable C1 interrupt and check if it needs processing */ + gpio_enable_interrupt(GPIO_SUB_C1_INT_EN_RAILS_ODL); + check_c1_line(); + } + /* Enable gpio interrupt for base accelgyro sensor */ + gpio_enable_interrupt(GPIO_BASE_SIXAXIS_INT_L); + + /* Turn on 5V if the system is on, otherwise turn it off. */ + on = chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_ANY_SUSPEND | + CHIPSET_STATE_SOFT_OFF); + board_power_5v_enable(on); + + /* Initialize THERMAL */ + setup_thermal(); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +/* Enable HDMI any time the SoC is on */ +static void hdmi_enable(void) +{ + if (get_cbi_fw_config_db() == DB_1A_HDMI) + gpio_set_level(GPIO_EC_I2C_SUB_C1_SCL_HDMI_EN_ODL, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, hdmi_enable, HOOK_PRIO_DEFAULT); + +static void hdmi_disable(void) +{ + if (get_cbi_fw_config_db() == DB_1A_HDMI) + gpio_set_level(GPIO_EC_I2C_SUB_C1_SCL_HDMI_EN_ODL, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, hdmi_disable, HOOK_PRIO_DEFAULT); + +void board_hibernate(void) +{ + /* + * Both charger ICs need to be put into their "low power mode" before + * entering the Z-state. + */ + if (board_get_charger_chip_count() > 1) + raa489000_hibernate(1, true); + raa489000_hibernate(0, true); +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): Here we could issue a digital reset to the IC, + * unsure if we actually want to do that or not yet. + */ +} + +#ifdef BOARD_WADDLEDOO +static void reconfigure_5v_gpio(void) +{ + /* + * b/147257497: On early waddledoo boards, GPIO_EN_PP5000 was swapped + * with GPIO_VOLUP_BTN_ODL. Therefore, we'll actually need to set that + * GPIO instead for those boards. Note that this breaks the volume up + * button functionality. + */ + if (system_get_board_version() < 0) { + CPRINTS("old board - remapping 5V en"); + gpio_set_flags(GPIO_VOLUP_BTN_ODL, GPIO_OUT_LOW); + } +} +DECLARE_HOOK(HOOK_INIT, reconfigure_5v_gpio, HOOK_PRIO_INIT_I2C+1); +#endif /* BOARD_WADDLEDOO */ + +static void set_5v_gpio(int level) +{ + int version; + enum gpio_signal gpio = GPIO_EN_PP5000; + + /* + * b/147257497: On early waddledoo boards, GPIO_EN_PP5000 was swapped + * with GPIO_VOLUP_BTN_ODL. Therefore, we'll actually need to set that + * GPIO instead for those boards. Note that this breaks the volume up + * button functionality. + */ + if (IS_ENABLED(BOARD_WADDLEDOO)) { + version = system_get_board_version(); + + /* + * If the CBI EEPROM wasn't formatted, assume it's a very early + * board. + */ + gpio = version < 0 ? GPIO_VOLUP_BTN_ODL : GPIO_EN_PP5000; + } + + gpio_set_level(gpio, level); +} + +__override void board_power_5v_enable(int enable) +{ + /* + * Port 0 simply has a GPIO to turn on the 5V regulator, however, 5V is + * generated locally on the sub board and we need to set the comparator + * polarity on the sub board charger IC, or send enable signal to HDMI + * DB. + */ + set_5v_gpio(!!enable); + + if (get_cbi_fw_config_db() == DB_1A_HDMI) { + gpio_set_level(GPIO_SUB_C1_INT_EN_RAILS_ODL, !enable); + } else { + if (isl923x_set_comparator_inversion(1, !!enable)) + CPRINTS("Failed to %sable sub rails!", enable ? + "en" : "dis"); + } + +} + +__override uint8_t board_get_usb_pd_port_count(void) +{ + if (get_cbi_fw_config_db() == DB_1A_HDMI) + return CONFIG_USB_PD_PORT_MAX_COUNT - 1; + else + return CONFIG_USB_PD_PORT_MAX_COUNT; +} + +__override uint8_t board_get_charger_chip_count(void) +{ + if (get_cbi_fw_config_db() == DB_1A_HDMI) + return CHARGER_NUM - 1; + else + return CHARGER_NUM; +} + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); + +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && + port < board_get_usb_pd_port_count()); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + CPRINTS("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + CPRINTS("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + CPRINTS("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + CPRINTS("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + int icl = MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT); + + /* + * b/147463641: The charger IC seems to overdraw ~4%, therefore we + * reduce our target accordingly. + */ + icl = icl * 96 / 100; + charge_set_input_current_limit(icl, charge_mv); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port > board_get_usb_pd_port_count()) + return; + + raa489000_set_output_current(port, rp); +} + +/* Sensors */ +static struct mutex g_lid_mutex; +static struct mutex g_base_mutex; + +/* Matrices to rotate accelerometers into the standard reference. */ +static const mat33_fp_t lid_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +static const mat33_fp_t base_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +static struct accelgyro_saved_data_t g_bma253_data; +static struct bmi_drv_data_t g_bmi160_data; + +struct motion_sensor_t motion_sensors[] = { + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMA255, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &bma2x2_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_bma253_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMA2x2_I2C_ADDR1_FLAGS, + .rot_standard_ref = &lid_standard_ref, + .default_range = 2, + .min_frequency = BMA255_ACCEL_MIN_FREQ, + .max_frequency = BMA255_ACCEL_MAX_FREQ, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .default_range = 4, + .min_frequency = BMI_ACCEL_MIN_FREQ, + .max_frequency = BMI_ACCEL_MAX_FREQ, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_GYRO_MIN_FREQ, + .max_frequency = BMI_GYRO_MAX_FREQ, + }, +}; + +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +__override void ocpc_get_pid_constants(int *kp, int *kp_div, + int *ki, int *ki_div, + int *kd, int *kd_div) +{ + *kp = 1; + *kp_div = 20; + *ki = 1; + *ki_div = 250; + *kd = 0; + *kd_div = 1; +} + +int pd_snk_is_vbus_provided(int port) +{ + return pd_check_vbus_level(port, VBUS_PRESENT); +} + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, + + { + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { + { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + .flags = PI3USB9201_ALWAYS_POWERED, + }, + + { + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + .flags = PI3USB9201_ALWAYS_POWERED, + }, +}; + +/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ +const struct pwm_t pwm_channels[] = { + [PWM_CH_KBLIGHT] = { + .channel = 3, + .flags = PWM_CONFIG_DSLEEP, + .freq = 10000, + }, + + [PWM_CH_LED1_AMBER] = { + .channel = 2, + .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, + .freq = 2400, + }, + + [PWM_CH_LED2_WHITE] = { + .channel = 0, + .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, + .freq = 2400, + } +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .flags = TCPC_FLAGS_TCPCI_REV2_0, + .drv = &raa489000_tcpm_drv, + }, + + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_SUB_USB_C1, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .flags = TCPC_FLAGS_TCPCI_REV2_0, + .drv = &raa489000_tcpm_drv, + }, +}; + +const struct usb_mux usbc1_retimer = { + .usb_port = 1, + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = NB7V904M_I2C_ADDR0, + .driver = &nb7v904m_usb_redriver_drv, +}; +const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .usb_port = 0, + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = PI3USB3X532_I2C_ADDR0, + .driver = &pi3usb3x532_usb_mux_driver, + }, + { + .usb_port = 1, + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = PI3USB3X532_I2C_ADDR0, + .driver = &pi3usb3x532_usb_mux_driver, + .next_mux = &usbc1_retimer, + } +}; + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() > 1 && + !gpio_get_level(GPIO_SUB_C1_INT_EN_RAILS_ODL)) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +/* This callback disables keyboard when convertibles are fully open */ +__override void lid_angle_peripheral_enable(int enable) +{ + int chipset_in_s0 = chipset_in_state(CHIPSET_STATE_ON); + + /* + * If the lid is in tablet position via other sensors, + * ignore the lid angle, which might be faulty then + * disable keyboard. + */ + if (tablet_get_mode()) + enable = 0; + + if (enable) { + keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_ANGLE); + } else { + /* + * Ensure that the chipset is off before disabling the keyboard. + * When the chipset is on, the EC keeps the keyboard enabled and + * the AP decides whether to ignore input devices or not. + */ + if (!chipset_in_s0) + keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_ANGLE); + } +} diff --git a/board/corori2/board.h b/board/corori2/board.h new file mode 100644 index 0000000000..35bfd0d3da --- /dev/null +++ b/board/corori2/board.h @@ -0,0 +1,203 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Waddledoo board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#define VARIANT_DEDEDE_EC_NPCX796FC +#include "baseboard.h" + +/* + * Keep the system unlocked in early development. + * TODO(b/151264302): Make sure to remove this before production! + */ +#define CONFIG_SYSTEM_UNLOCKED + +/* Save some flash space */ +#define CONFIG_CHIP_INIT_ROM_REGION +#undef CONFIG_CONSOLE_CMDHELP +#define CONFIG_DEBUG_ASSERT_BRIEF +#define CONFIG_USB_PD_DEBUG_LEVEL 2 + +/* EC console commands */ +#define CONFIG_CMD_CHARGER_DUMP + +/* Remove default commands to free flash space */ +#undef CONFIG_CMD_ACCELSPOOF +#undef CONFIG_CMD_BATTFAKE + +/* Battery */ +#define CONFIG_BATTERY_FUEL_GAUGE + +/* Charger */ +#define CONFIG_CHARGER_RAA489000 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10 +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_OCPC_DEF_RBATT_MOHMS 22 /* R_DS(on) 11.6mOhm + 10mOhm sns rstr */ +#define CONFIG_OCPC +#undef CONFIG_CHARGER_SINGLE_CHIP +#undef CONFIG_USB_PD_TCPC_LPM_EXIT_DEBOUNCE +#define CONFIG_USB_PD_TCPC_LPM_EXIT_DEBOUNCE (100 * MSEC) + +/* + * GPIO for C1 interrupts, for baseboard use + * + * Note this line might already have its pull up disabled for HDMI DBs, but + * it should be fine to set again before z-state. + */ +#define GPIO_USB_C1_INT_ODL GPIO_SUB_C1_INT_EN_RAILS_ODL + +/* Keyboard */ +#define CONFIG_PWM_KBLIGHT + +/* LED */ +#define CONFIG_LED_PWM +#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 +#undef CONFIG_LED_PWM_LOW_BATT_COLOR +#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER + +/* PWM */ +#define CONFIG_PWM +#define NPCX7_PWM1_SEL 1 /* GPIO C2 is used as PWM1. */ + +/* Temp sensor */ +#define CONFIG_TEMP_SENSOR +#define CONFIG_THERMISTOR +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B +#define CONFIG_THROTTLE_AP +#define CONFIG_CHIPSET_CAN_THROTTLE + +/* USB */ +#define CONFIG_BC12_DETECT_PI3USB9201 +#define CONFIG_USBC_RETIMER_NB7V904M + +/* USB PD */ +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 +#define CONFIG_USB_PD_TCPM_RAA489000 + +/* USB defines specific to external TCPCs */ +#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define CONFIG_USB_PD_VBUS_DETECT_TCPC +#define CONFIG_USB_PD_DISCHARGE_TCPC +#define CONFIG_USB_PD_TCPC_LOW_POWER + +/* Variant references the TCPCs to determine Vbus sourcing */ +#define CONFIG_USB_PD_5V_EN_CUSTOM + +#undef PD_POWER_SUPPLY_TURN_ON_DELAY +#undef PD_POWER_SUPPLY_TURN_OFF_DELAY +#undef CONFIG_USBC_VCONN_SWAP_DELAY_US +/* 20% margin added for these timings */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 13080 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 16080 /* us */ +#undef CONFIG_USBC_VCONN_SWAP_DELAY_US +#define CONFIG_USBC_VCONN_SWAP_DELAY_US 787 /* us */ + + +/* I2C configuration */ +#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 +#define I2C_PORT_BATTERY NPCX_I2C_PORT5_0 +#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0 +#define I2C_PORT_USB_C0 NPCX_I2C_PORT1_0 +#define I2C_PORT_SUB_USB_C1 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_MUX I2C_PORT_USB_C0 +/* TODO(b:147440290): Need to handle multiple charger ICs */ +#define I2C_PORT_CHARGER I2C_PORT_USB_C0 + +#define I2C_PORT_ACCEL I2C_PORT_SENSOR + +#define I2C_ADDR_EEPROM_FLAGS 0x50 /* 7b address */ + +/* + * I2C pin names for baseboard + * + * Note: these lines will be set as i2c on start-up, but this should be + * okay since they're ODL. + */ +#define GPIO_EC_I2C_SUB_USB_C1_SCL GPIO_EC_I2C_SUB_C1_SCL_HDMI_EN_ODL +#define GPIO_EC_I2C_SUB_USB_C1_SDA GPIO_EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL + +/* Sensors */ +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO + +#define CONFIG_ACCEL_BMA255 /* Lid accel */ +#define CONFIG_ACCELGYRO_BMI160 /* Base accel */ + +/* Lid operates in forced mode, base in FIFO */ +#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) +#define CONFIG_ACCEL_FIFO +#define CONFIG_ACCEL_FIFO_SIZE 256 /* Must be a power of 2 */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) + +#define CONFIG_ACCEL_INTERRUPTS +#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) + +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL + +#define CONFIG_TABLET_MODE +#define CONFIG_TABLET_MODE_SWITCH +#define CONFIG_GMR_TABLET_MODE + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +enum chg_id { + CHARGER_PRIMARY, + CHARGER_SECONDARY, + CHARGER_NUM, +}; + +enum adc_channel { + ADC_TEMP_SENSOR_1, /* ADC0 */ + ADC_TEMP_SENSOR_2, /* ADC1 */ + ADC_SUB_ANALOG, /* ADC2 */ + ADC_VSNS_PP3300_A, /* ADC9 */ + ADC_CH_COUNT +}; + +enum temp_sensor_id { + TEMP_SENSOR_1, + TEMP_SENSOR_2, + TEMP_SENSOR_COUNT +}; + +enum sensor_id { + LID_ACCEL, + BASE_ACCEL, + BASE_GYRO, + SENSOR_COUNT +}; + +enum pwm_channel { + PWM_CH_KBLIGHT, + PWM_CH_LED1_AMBER, + PWM_CH_LED2_WHITE, + PWM_CH_COUNT, +}; + +/* List of possible batteries */ +enum battery_type { + BATTERY_C21N2018, + BATTERY_C21N2018_2ND, + BATTERY_TYPE_COUNT, +}; + +#endif /* !__ASSEMBLER__ */ +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/corori2/build.mk b/board/corori2/build.mk new file mode 100644 index 0000000000..af526189dd --- /dev/null +++ b/board/corori2/build.mk @@ -0,0 +1,14 @@ +# -*- makefile -*- +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Board specific files build +# + +CHIP:=npcx +CHIP_FAMILY:=npcx7 +CHIP_VARIANT:=npcx7m6fc +BASEBOARD:=dedede + +board-y=board.o battery.o cbi_ssfc.o led.o usb_pd_policy.o diff --git a/board/corori2/cbi_ssfc.c b/board/corori2/cbi_ssfc.c new file mode 100644 index 0000000000..c4b859f133 --- /dev/null +++ b/board/corori2/cbi_ssfc.c @@ -0,0 +1,36 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "cbi_ssfc.h" +#include "common.h" +#include "console.h" +#include "cros_board_info.h" +#include "hooks.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) + +/* Cache SSFC on init since we don't expect it to change in runtime */ +static union dedede_cbi_ssfc cached_ssfc; +BUILD_ASSERT(sizeof(cached_ssfc) == sizeof(uint32_t)); + +static void cbi_ssfc_init(void) +{ + if (cbi_get_ssfc(&cached_ssfc.raw_value) != EC_SUCCESS) + /* Default to 0 when CBI isn't populated */ + cached_ssfc.raw_value = 0; + + CPRINTS("Read CBI SSFC : 0x%04X", cached_ssfc.raw_value); +} +DECLARE_HOOK(HOOK_INIT, cbi_ssfc_init, HOOK_PRIO_FIRST); + +enum ec_ssfc_base_sensor get_cbi_ssfc_base_sensor(void) +{ + return (enum ec_ssfc_base_sensor) cached_ssfc.base_sensor; +} + +enum ec_ssfc_lid_sensor get_cbi_ssfc_lid_sensor(void) +{ + return (enum ec_ssfc_lid_sensor) cached_ssfc.lid_sensor; +} diff --git a/board/corori2/cbi_ssfc.h b/board/corori2/cbi_ssfc.h new file mode 100644 index 0000000000..935049b6ae --- /dev/null +++ b/board/corori2/cbi_ssfc.h @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef _DEDEDE_CBI_SSFC__H_ +#define _DEDEDE_CBI_SSFC__H_ + +#include "stdint.h" + +/**************************************************************************** + * Dedede CBI Second Source Factory Cache + */ + +/* + * Base Sensor (Bits 0-2) + */ +enum ec_ssfc_base_sensor { + SSFC_SENSOR_BASE_DEFAULT = 0, + SSFC_SENSOR_BMI160 = 1, + SSFC_SENSOR_ICM426XX = 2, + SSFC_SENSOR_LSM6DSM = 3, + SSFC_SENSOR_ICM42607 = 4 +}; + +/* + * Lid Sensor (Bits 3-5) + */ +enum ec_ssfc_lid_sensor { + SSFC_SENSOR_LID_DEFAULT = 0, + SSFC_SENSOR_BMA255 = 1, + SSFC_SENSOR_KX022 = 2, + SSFC_SENSOR_LIS2DWL = 3 +}; + +union dedede_cbi_ssfc { + struct { + uint32_t base_sensor : 3; + uint32_t lid_sensor : 3; + uint32_t reserved_2 : 26; + }; + uint32_t raw_value; +}; + +/** + * Get the Base sensor type from SSFC_CONFIG. + * + * @return the Base sensor board type. + */ +enum ec_ssfc_base_sensor get_cbi_ssfc_base_sensor(void); + +/** + * Get the Lid sensor type from SSFC_CONFIG. + * + * @return the Lid sensor board type. + */ +enum ec_ssfc_lid_sensor get_cbi_ssfc_lid_sensor(void); + + +#endif /* _DEDEDE_CBI_SSFC__H_ */ diff --git a/board/corori2/ec.tasklist b/board/corori2/ec.tasklist new file mode 100644 index 0000000000..d4fb416bce --- /dev/null +++ b/board/corori2/ec.tasklist @@ -0,0 +1,25 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * See CONFIG_TASK_LIST in config.h for details. + */ + +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, ULTRA_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, ULTRA_TASK_STACK_SIZE) diff --git a/board/corori2/gpio.inc b/board/corori2/gpio.inc new file mode 100644 index 0000000000..78d41aab16 --- /dev/null +++ b/board/corori2/gpio.inc @@ -0,0 +1,139 @@ +/* -*- mode:c -*- + * + * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * Declare symbolic names for all the GPIOs that we care about. + * Note: Those with interrupt handlers must be declared first. + */ + +/* Power Interrupts */ +GPIO_INT(SLP_S0_L, PIN(D, 5), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SLP_S3_L, PIN(A, 5), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt) +GPIO_INT(SLP_S4_L, PIN(D, 4), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SLP_SUS_L, PIN(D, 7), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(RSMRST_PWRGD_L, PIN(C, 6), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(VCCIN_AUX_VID1, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(CPU_C10_GATE_L, PIN(6, 7), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(VCCIN_AUX_VID0, PIN(F, 4), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) +GPIO_INT(PG_VCCIO_EXT_OD, PIN(B, 0), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt) +GPIO_INT(PG_PP5000_U_OD, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PG_DRAM_OD, PIN(E, 4), GPIO_INT_BOTH, baseboard_all_sys_pgood_interrupt) +GPIO_INT(PG_PP1050_ST_OD, PIN(4, 2), GPIO_INT_BOTH, power_signal_interrupt) + +/* USB-C interrupts */ +GPIO_INT(USB_C0_INT_ODL, PIN(6, 2), GPIO_INT_FALLING | GPIO_PULL_UP, usb_c0_interrupt) +GPIO_INT(SUB_C1_INT_EN_RAILS_ODL, PIN(F, 5), GPIO_INT_FALLING | GPIO_PULL_UP, sub_usb_c1_interrupt) /* C1 interrupt OR 5V power en */ +GPIO_INT(EC_I2C_SUB_C1_SDA_HDMI_HPD_ODL, PIN(9, 1), GPIO_INT_BOTH, sub_hdmi_hpd_interrupt) /* C1 I2C SDA OR HDMI_HPD */ + +/* Button interrupts */ +GPIO_INT(H1_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt) +GPIO_INT(VOLDN_BTN_ODL, PIN(4, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(VOLUP_BTN_ODL, PIN(7, 3), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) + +/* Other interrupts */ +GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH, lid_interrupt) +GPIO_INT(EC_WP_OD, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) +GPIO_INT(BASE_SIXAXIS_INT_L, PIN(5, 6), GPIO_INT_FALLING | GPIO_SEL_1P8V, bmi160_interrupt) +GPIO_INT(LID_360_L, PIN(9, 5), GPIO_INT_BOTH, gmr_tablet_switch_isr) + +/* I2C Ports */ +GPIO(EC_I2C_EEPROM_SCL, PIN(B, 3), GPIO_INPUT) +GPIO(EC_I2C_EEPROM_SDA, PIN(B, 2), GPIO_INPUT) +GPIO(EC_I2C_BATTERY_SCL, PIN(3, 3), GPIO_INPUT) +GPIO(EC_I2C_BATTERY_SDA, PIN(3, 6), GPIO_INPUT) +GPIO(EC_I2C_SENSOR_SCL, PIN(B, 5), GPIO_INPUT) +GPIO(EC_I2C_SENSOR_SDA, PIN(B, 4), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SCL, PIN(9, 0), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_SDA, PIN(8, 7), GPIO_INPUT) +GPIO(EC_I2C_SUB_C1_SCL_HDMI_EN_ODL, PIN(9, 2), GPIO_INPUT) /* C1 I2C SCL OR HDMI en */ + +/* Extra Sub-board I/O pins */ +GPIO(EC_SUB_IO_1, PIN(3, 7), GPIO_OUT_LOW) +GPIO(EC_SUB_IO_2, PIN(3, 4), GPIO_OUT_LOW) + +/* Misc Enables */ +GPIO(EN_VCCIO_EXT, PIN(6, 1), GPIO_OUT_LOW) +/* TODO(b:149775160) - Modify if needed if we ever use this signal. */ +GPIO(EN_VCCST, PIN(A, 7), GPIO_INPUT) +GPIO(EN_PP3300_PEN, PIN(6, 3), GPIO_OUT_LOW) +GPIO(EN_PP3300_A, PIN(0, 3), GPIO_OUT_LOW) +GPIO(EN_PP5000_U, PIN(A, 4), GPIO_OUT_LOW) +GPIO(EN_SLP_Z, PIN(8, 3), GPIO_OUT_LOW) +GPIO(EN_KB_BL, PIN(6, 0), GPIO_OUT_LOW) +GPIO(EN_BL_OD, PIN(D, 3), GPIO_ODR_LOW) +GPIO(IMVP9_PE, PIN(E, 0), GPIO_OUT_LOW) +GPIO(ECH1_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW) + +/* Power Sequencing */ +GPIO(EC_AP_PSYS, PIN(B, 7), GPIO_OUT_LOW) +GPIO(EC_AP_RSMRST_L, PIN(A, 6), GPIO_OUT_LOW) +GPIO(EC_AP_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) +GPIO(EC_AP_RTCRST, PIN(7, 6), GPIO_OUT_LOW) +GPIO(EC_AP_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) +GPIO(EC_AP_DPWROK, PIN(A, 3), GPIO_OUT_LOW) +GPIO(EC_AP_PCH_PWROK_OD, PIN(9, 4), GPIO_ODR_LOW) +GPIO(EC_AP_VCCST_PWRGD_OD, PIN(B, 1), GPIO_ODR_LOW) +GPIO(EC_AP_SYS_PWROK, PIN(0, 2), GPIO_OUT_LOW) +GPIO(EC_AP_MKBP_INT_L, PIN(7, 0), GPIO_ODR_HIGH) +GPIO(EC_PROCHOT_ODL, PIN(F, 1), GPIO_ODR_HIGH | GPIO_SEL_1P8V) +GPIO(EC_ENTERING_RW, PIN(E, 3), GPIO_OUT_LOW) +GPIO(ALL_SYS_PWRGD, PIN(A, 0), GPIO_OUT_LOW) +GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) +GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_ODR_HIGH) + +GPIO(USB_C0_RST_ODL, PIN(9, 7), GPIO_OUT_HIGH) /* currently unused */ +GPIO(EC_AP_USB_C1_HDMI_HPD, PIN(9, 6), GPIO_OUT_LOW) +GPIO(EC_AP_USB_C0_HPD, PIN(9, 3), GPIO_OUT_LOW) +GPIO(HDMI_SEL_L, PIN(7, 2), GPIO_OUT_HIGH) +GPIO(EC_BATTERY_PRES_ODL, PIN(E, 1), GPIO_INPUT) + +/* + * Waddledoo doesn't have these physical pins coming to the EC but uses other + * logic. + */ +UNIMPLEMENTED(AC_PRESENT) +UNIMPLEMENTED(PG_EC_DSW_PWROK) +UNIMPLEMENTED(PG_EC_ALL_SYS_PWRGD) + +/* Alternate Functions */ +/* ADC */ +ALTERNATE(PIN_MASK(F, BIT(0)), 0, MODULE_ADC, 0) /* ADC9 */ +ALTERNATE(PIN_MASK(4, 0x38), 0, MODULE_ADC, 0) /* ADC0-2 */ + +/* Keyboard */ +ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_INPUT | GPIO_PULL_UP) /* KSI0, KSI1 */ +ALTERNATE(PIN_MASK(2, 0xFC), 0, MODULE_KEYBOARD_SCAN, GPIO_INPUT | GPIO_PULL_UP) /* KSI2-7 */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO0, KSO1 */ +ALTERNATE(PIN_MASK(1, 0x7F), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO3-9 */ +ALTERNATE(PIN_MASK(0, 0xF0), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO10-13 */ +ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO14 */ +GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) /* KSO2 inverted */ + +/* PWM */ +ALTERNATE(PIN_MASK(C, 0x1C), 0, MODULE_PWM, 0) /* PWM0-2 */ +ALTERNATE(PIN_MASK(8, BIT(0)), 0, MODULE_PWM, 0) /* PWM3 */ + +/* UART */ +ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* UART1 */ + +/* I2C */ +ALTERNATE(PIN_MASK(B, 0x3C), 0, MODULE_I2C, 0) /* I2C7,I2C0 */ +ALTERNATE(PIN_MASK(3, 0x48), 0, MODULE_I2C, 0) /* I2C5 */ +ALTERNATE(PIN_MASK(9, 0x07), 0, MODULE_I2C, 0) /* I2C2, I2C1 SCL */ +ALTERNATE(PIN_MASK(8, 0x80), 0, MODULE_I2C, 0) /* I2C1 SDA */ + +/* NC pins, enable internal pull-up to avoid floating state. */ +GPIO(GPIO32_NC, PIN(3, 2), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIO35_NC, PIN(3, 5), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIO41_NC, PIN(4, 1), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIO57_NC, PIN(5, 7), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIO81_NC, PIN(8, 1), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIO86_NC, PIN(8, 6), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIOC0_NC, PIN(C, 0), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIOD0_NC, PIN(D, 0), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIOD1_NC, PIN(D, 1), GPIO_INPUT | GPIO_PULL_UP) +GPIO(GPIOD6_NC, PIN(D, 6), GPIO_INPUT | GPIO_PULL_UP) diff --git a/board/corori2/led.c b/board/corori2/led.c new file mode 100644 index 0000000000..3c27bf0f8e --- /dev/null +++ b/board/corori2/led.c @@ -0,0 +1,70 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Waddledoo specific PWM LED settings. */ + +#include "common.h" +#include "ec_commands.h" +#include "led_pwm.h" +#include "pwm.h" +#include "util.h" + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_POWER_LED, +}; +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); +/* + * We only have a white and an amber LED, so setting any other colour results in + * both LEDs being off. + */ +struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { + /* Amber, White */ + [EC_LED_COLOR_RED] = { 0, 0 }, + [EC_LED_COLOR_GREEN] = { 0, 0 }, + [EC_LED_COLOR_BLUE] = { 0, 0 }, + [EC_LED_COLOR_YELLOW] = { 0, 0 }, + [EC_LED_COLOR_WHITE] = { 0, 100 }, + [EC_LED_COLOR_AMBER] = { 100, 0 }, +}; + +/* One logical LED with amber and white channels. */ +struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { + { + .ch0 = PWM_CH_LED1_AMBER, + .ch1 = PWM_CH_LED2_WHITE, + .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) +{ + memset(brightness_range, '\0', + sizeof(*brightness_range) * EC_LED_COLOR_COUNT); + brightness_range[EC_LED_COLOR_AMBER] = 100; + brightness_range[EC_LED_COLOR_WHITE] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + enum pwm_led_id pwm_id; + + /* Convert ec_led_id to pwm_led_id. */ + if (led_id == EC_LED_ID_POWER_LED) + pwm_id = PWM_LED0; + else + return EC_ERROR_UNKNOWN; + + if (brightness[EC_LED_COLOR_WHITE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); + else + /* Otherwise, the "color" is "off". */ + set_pwm_led_color(pwm_id, -1); + + return EC_SUCCESS; +} diff --git a/board/corori2/usb_pd_policy.c b/board/corori2/usb_pd_policy.c new file mode 100644 index 0000000000..15faf41ffc --- /dev/null +++ b/board/corori2/usb_pd_policy.c @@ -0,0 +1,61 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_manager.h" +#include "chipset.h" +#include "common.h" +#include "console.h" +#include "driver/charger/isl923x_public.h" +#include "driver/tcpm/tcpci.h" +#include "usb_pd.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on. */ + return chipset_in_state(CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_ON); +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= board_get_usb_pd_port_count()) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} diff --git a/board/krabby/vif_override.xml b/board/corori2/vif_override.xml index 32736caf64..32736caf64 100644 --- a/board/krabby/vif_override.xml +++ b/board/corori2/vif_override.xml diff --git a/board/cret/board.c b/board/cret/board.c index 34091c0518..b8deb52b10 100644 --- a/board/cret/board.c +++ b/board/cret/board.c @@ -384,8 +384,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -413,8 +411,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/dalboz/board.c b/board/dalboz/board.c index 5e65298b82..45eb468b2e 100644 --- a/board/dalboz/board.c +++ b/board/dalboz/board.c @@ -129,8 +129,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ @@ -161,8 +159,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/damu/board.c b/board/damu/board.c index ca3979949a..f66d05eb5b 100644 --- a/board/damu/board.c +++ b/board/damu/board.c @@ -67,13 +67,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -139,8 +158,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/damu/board.h b/board/damu/board.h index 6df8bb2a7a..f127df251f 100644 --- a/board/damu/board.h +++ b/board/damu/board.h @@ -85,7 +85,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/delbin/ec.tasklist b/board/delbin/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/delbin/ec.tasklist +++ b/board/delbin/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/dewatt/board.c b/board/dewatt/board.c index 60c2bba17a..54af97b342 100644 --- a/board/dewatt/board.c +++ b/board/dewatt/board.c @@ -12,13 +12,12 @@ #include "common.h" #include "cros_board_info.h" #include "driver/accelgyro_bmi_common.h" -#include "driver/accelgyro_bmi160.h" -#include "driver/accelgyro_bmi323.h" +#include "driver/accelgyro_bmi260.h" #include "driver/accel_bma422.h" #include "driver/retimer/ps8811.h" #include "driver/retimer/ps8818.h" #include "driver/temp_sensor/sb_tsi.h" -#include "driver/temp_sensor/tmp112.h" +#include "driver/temp_sensor/pct2075.h" #include "extpower.h" #include "gpio.h" #include "hooks.h" @@ -31,7 +30,7 @@ #include "tablet_mode.h" #include "temp_sensor.h" #include "temp_sensor/thermistor.h" -#include "temp_sensor/tmp112.h" +#include "temp_sensor/pct2075.h" #include "thermal.h" #include "usb_mux.h" @@ -48,14 +47,14 @@ static struct accelgyro_saved_data_t g_bma422_data; /* Matrix to rotate accelrator into standard reference frame */ 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)} + { 0, FLOAT_TO_FP(1), 0}, + { 0, 0, FLOAT_TO_FP(-1)} }; const mat33_fp_t lid_standard_ref = { - { 0, FLOAT_TO_FP(-1), 0}, { FLOAT_TO_FP(-1), 0, 0}, - { 0, 0, FLOAT_TO_FP(-1)} + { 0, FLOAT_TO_FP(-1), 0}, + { 0, 0, FLOAT_TO_FP(1)} }; /* @@ -79,14 +78,14 @@ struct motion_sensor_t motion_sensors[] = { [BASE_ACCEL] = { .name = "Base Accel", .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_BMI323, + .chip = MOTIONSENSE_CHIP_BMI260, .type = MOTIONSENSE_TYPE_ACCEL, .location = MOTIONSENSE_LOC_BASE, - .drv = &bmi3xx_drv, + .drv = &bmi260_drv, .mutex = &g_base_mutex, .drv_data = &g_bmi_data, .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = BMI3_ADDR_I2C_PRIM, + .i2c_spi_addr_flags = BMI260_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, .min_frequency = BMI_ACCEL_MIN_FREQ, .max_frequency = BMI_ACCEL_MAX_FREQ, @@ -94,12 +93,12 @@ struct motion_sensor_t motion_sensors[] = { .config = { /* EC use accel for angle detection */ [SENSOR_CONFIG_EC_S0] = { - .odr = 12500 | ROUND_UP_FLAG, + .odr = 10000 | ROUND_UP_FLAG, .ec_rate = 100 * MSEC, }, /* Sensor on in S3 */ [SENSOR_CONFIG_EC_S3] = { - .odr = 12500 | ROUND_UP_FLAG, + .odr = 10000 | ROUND_UP_FLAG, .ec_rate = 0, }, }, @@ -135,14 +134,14 @@ struct motion_sensor_t motion_sensors[] = { [BASE_GYRO] = { .name = "Base Gyro", .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_BMI323, + .chip = MOTIONSENSE_CHIP_BMI260, .type = MOTIONSENSE_TYPE_GYRO, .location = MOTIONSENSE_LOC_BASE, - .drv = &bmi3xx_drv, + .drv = &bmi260_drv, .mutex = &g_base_mutex, .drv_data = &g_bmi_data, .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = BMI3_ADDR_I2C_PRIM, + .i2c_spi_addr_flags = BMI260_ADDR0_FLAGS, .default_range = 1000, /* dps */ .rot_standard_ref = &base_standard_ref, .min_frequency = BMI_GYRO_MIN_FREQ, @@ -151,52 +150,6 @@ struct motion_sensor_t motion_sensors[] = { }; unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); -struct motion_sensor_t bmi160_base_accel = { - .name = "Base Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_BMI160, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_BASE, - .drv = &bmi160_drv, - .mutex = &g_base_mutex, - .drv_data = &g_bmi_data, - .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, - .rot_standard_ref = &base_standard_ref, - .min_frequency = BMI_ACCEL_MIN_FREQ, - .max_frequency = BMI_ACCEL_MAX_FREQ, - .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 100 * MSEC, - }, - /* Sensor on in S3 */ - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 0, - }, - }, -}; - -struct motion_sensor_t bmi160_base_gyro = { - .name = "Base Gyro", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_BMI160, - .type = MOTIONSENSE_TYPE_GYRO, - .location = MOTIONSENSE_LOC_BASE, - .drv = &bmi160_drv, - .mutex = &g_base_mutex, - .drv_data = &g_bmi_data, - .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, - .default_range = 1000, /* dps */ - .rot_standard_ref = &base_standard_ref, - .min_frequency = BMI_GYRO_MIN_FREQ, - .max_frequency = BMI_GYRO_MAX_FREQ, -}; - __override enum ec_error_list board_a1_ps8811_retimer_init(const struct usb_mux *me) { @@ -289,10 +242,10 @@ __override int board_c1_ps8818_mux_set(const struct usb_mux *me, return rv; /* Enable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 1); + ioex_set_level(IOEX_USB_C1_IN_HPD, 1); } else { /* Disable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 0); + ioex_set_level(IOEX_USB_C1_IN_HPD, 0); } return rv; @@ -317,15 +270,8 @@ static int base_gyro_config; static void board_update_motion_sensor_config(void) { if (board_is_convertible()) { - if (get_board_version() == 1) { - motion_sensors[BASE_ACCEL] = bmi160_base_accel; - motion_sensors[BASE_GYRO] = bmi160_base_gyro; - base_gyro_config = BASE_GYRO_BMI160; - ccprints("BASE GYRO is BMI160"); - } else { - base_gyro_config = BASE_GYRO_BMI323; - ccprints("BASE GYRO is BMI323"); - } + base_gyro_config = BASE_GYRO_BMI260; + ccprints("BASE GYRO is BMI260"); motion_sensor_count = ARRAY_SIZE(motion_sensors); /* Enable Base Accel and Gyro interrupt */ @@ -341,12 +287,9 @@ static void board_update_motion_sensor_config(void) void motion_interrupt(enum gpio_signal signal) { switch (base_gyro_config) { - case BASE_GYRO_BMI160: - bmi160_interrupt(signal); - break; - case BASE_GYRO_BMI323: + case BASE_GYRO_BMI260: default: - bmi3xx_interrupt(signal); + bmi260_interrupt(signal); break; } } @@ -360,7 +303,7 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); static void board_chipset_startup(void) { if (get_board_version() > 1) - tmp112_init(); + pct2075_init(); } DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); @@ -370,7 +313,7 @@ int board_get_soc_temp_k(int idx, int *temp_k) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_k(idx, temp_k); + return pct2075_get_val_k(idx, temp_k); } int board_get_soc_temp_mk(int *temp_mk) @@ -378,7 +321,7 @@ int board_get_soc_temp_mk(int *temp_mk) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_mk(TMP112_SOC, temp_mk); + return pct2075_get_val_mk(PCT2075_SOC, temp_mk); } int board_get_ambient_temp_mk(int *temp_mk) @@ -386,7 +329,7 @@ int board_get_ambient_temp_mk(int *temp_mk) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_mk(TMP112_AMB, temp_mk); + return pct2075_get_val_mk(PCT2075_AMB, temp_mk); } /* ADC Channels */ @@ -432,18 +375,18 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* Temp Sensors */ static int board_get_memory_temp(int, int *); -const struct tmp112_sensor_t tmp112_sensors[] = { - { I2C_PORT_SENSOR, TMP112_I2C_ADDR_FLAGS0 }, - { I2C_PORT_SENSOR, TMP112_I2C_ADDR_FLAGS1 }, +const struct pct2075_sensor_t pct2075_sensors[] = { + { I2C_PORT_SENSOR, PCT2075_I2C_ADDR_FLAGS0 }, + { I2C_PORT_SENSOR, PCT2075_I2C_ADDR_FLAGS7 }, }; -BUILD_ASSERT(ARRAY_SIZE(tmp112_sensors) == TMP112_COUNT); +BUILD_ASSERT(ARRAY_SIZE(pct2075_sensors) == PCT2075_COUNT); const struct temp_sensor_t temp_sensors[] = { [TEMP_SENSOR_SOC] = { .name = "SOC", .type = TEMP_SENSOR_TYPE_BOARD, .read = board_get_soc_temp_k, - .idx = TMP112_SOC, + .idx = PCT2075_SOC, }, [TEMP_SENSOR_CHARGER] = { .name = "Charger", @@ -466,69 +409,12 @@ const struct temp_sensor_t temp_sensors[] = { [TEMP_SENSOR_AMBIENT] = { .name = "Ambient", .type = TEMP_SENSOR_TYPE_BOARD, - .read = tmp112_get_val_k, - .idx = TMP112_AMB, + .read = pct2075_get_val_k, + .idx = PCT2075_AMB, }, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); -struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT] = { - [TEMP_SENSOR_SOC] = { - .temp_host = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(100), - [EC_TEMP_THRESH_HALT] = C_TO_K(105), - }, - .temp_host_release = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(80), - }, - /* TODO: Setting fan off to 0 so it's allways on */ - .temp_fan_off = C_TO_K(0), - .temp_fan_max = C_TO_K(70), - }, - [TEMP_SENSOR_CHARGER] = { - .temp_host = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(100), - [EC_TEMP_THRESH_HALT] = C_TO_K(105), - }, - .temp_host_release = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(80), - }, - .temp_fan_off = 0, - .temp_fan_max = 0, - }, - [TEMP_SENSOR_MEMORY] = { - .temp_host = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(100), - [EC_TEMP_THRESH_HALT] = C_TO_K(105), - }, - .temp_host_release = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(80), - }, - .temp_fan_off = 0, - .temp_fan_max = 0, - }, - [TEMP_SENSOR_CPU] = { - .temp_host = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(100), - [EC_TEMP_THRESH_HALT] = C_TO_K(105), - }, - .temp_host_release = { - [EC_TEMP_THRESH_HIGH] = C_TO_K(80), - }, - /* - * CPU temp sensor fan thresholds are high because they are a - * backup for the SOC temp sensor fan thresholds. - */ - .temp_fan_off = C_TO_K(60), - .temp_fan_max = C_TO_K(90), - }, - /* - * Note: Leave ambient entries at 0, both as it does not represent a - * hotspot and as not all boards have this sensor - */ -}; -BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); - static int board_get_memory_temp(int idx, int *temp_k) { if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) diff --git a/board/dewatt/board.h b/board/dewatt/board.h index 0743103a66..c89ce748ee 100644 --- a/board/dewatt/board.h +++ b/board/dewatt/board.h @@ -18,11 +18,8 @@ #define CONFIG_KEYBOARD_REFRESH_ROW3 /* Sensors */ -#define CONFIG_ACCELGYRO_BMI160 -#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) -#define CONFIG_ACCELGYRO_BMI3XX -#define CONFIG_ACCELGYRO_BMI3XX_INT_EVENT \ +#define CONFIG_ACCELGYRO_BMI260 +#define CONFIG_ACCELGYRO_BMI260_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) #define CONFIG_ACCEL_INTERRUPTS #define CONFIG_ACCEL_BMA4XX @@ -51,11 +48,15 @@ /* Volume Button feature */ /* Fan features */ +#define CONFIG_FAN_RPM_CUSTOM /* LED features */ #define CONFIG_LED_COMMON #define CONFIG_LED_ONOFF_STATES +/* Thermal Config */ +#define CONFIG_TEMP_SENSOR_PCT2075 + #ifndef __ASSEMBLER__ #include "gpio_signal.h" @@ -72,8 +73,7 @@ enum battery_type { enum base_accelgyro_type { BASE_GYRO_NONE = 0, - BASE_GYRO_BMI160 = 1, - BASE_GYRO_BMI323 = 2, + BASE_GYRO_BMI260 = 1, }; /* ADC Channels */ @@ -96,6 +96,13 @@ enum temp_sensor_id { TEMP_SENSOR_COUNT }; +/* PCT2075 sensors */ +enum pct2075_sensor { + PCT2075_SOC, + PCT2075_AMB, + PCT2075_COUNT, +}; + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/dewatt/board_fw_config.c b/board/dewatt/board_fw_config.c index c919d82851..e6dbcadb92 100644 --- a/board/dewatt/board_fw_config.c +++ b/board/dewatt/board_fw_config.c @@ -8,9 +8,7 @@ bool board_is_convertible(void) { - return (get_fw_config_field(FW_CONFIG_FORM_FACTOR_OFFSET, - FW_CONFIG_FORM_FACTOR_WIDTH) - == FW_CONFIG_FORM_FACTOR_CONVERTIBLE); + return 1; } bool board_has_kblight(void) @@ -21,22 +19,10 @@ bool board_has_kblight(void) enum board_usb_c1_mux board_get_usb_c1_mux(void) { - int usb_db = get_fw_config_field(FW_CONFIG_USB_DB_OFFSET, - FW_CONFIG_USB_DB_WIDTH); - if (usb_db == FW_CONFIG_USB_DB_A1_PS8811_C1_PS8818) - return USB_C1_MUX_PS8818; - if (usb_db == FW_CONFIG_USB_DB_A1_ANX7491_C1_ANX7451) - return USB_C1_MUX_ANX7451; - return USB_C1_MUX_UNKNOWN; + return USB_C1_MUX_PS8818; }; enum board_usb_a1_retimer board_get_usb_a1_retimer(void) { - int usb_db = get_fw_config_field(FW_CONFIG_USB_DB_OFFSET, - FW_CONFIG_USB_DB_WIDTH); - if (usb_db == FW_CONFIG_USB_DB_A1_PS8811_C1_PS8818) - return USB_A1_RETIMER_PS8811; - if (usb_db == FW_CONFIG_USB_DB_A1_ANX7491_C1_ANX7451) - return USB_A1_RETIMER_ANX7491; return USB_A1_RETIMER_UNKNOWN; }; diff --git a/board/dewatt/build.mk b/board/dewatt/build.mk index e4fdcf4afd..8f2b78ddc8 100644 --- a/board/dewatt/build.mk +++ b/board/dewatt/build.mk @@ -9,4 +9,4 @@ BASEBOARD:=guybrush board-y=board.o -board-y+=board_fw_config.o led.o battery.o +board-y+=board_fw_config.o led.o battery.o thermal.o diff --git a/board/dewatt/led.c b/board/dewatt/led.c index b17c8be488..7cbb9133bf 100644 --- a/board/dewatt/led.c +++ b/board/dewatt/led.c @@ -6,6 +6,8 @@ */ #include "common.h" +#include "cros_board_info.h" +#include "hooks.h" #include "led_onoff_states.h" #include "led_common.h" #include "gpio.h" @@ -21,19 +23,41 @@ __override const int led_charge_lvl_1 = 5; __override const int led_charge_lvl_2 = 97; +static enum pwm_channel pwm_ch_led_blue; +static enum pwm_channel pwm_ch_led_amber; + +static void led_pwm_ch_init(void) +{ + int val; + + pwm_ch_led_blue = PWM_CH_LED_FULL; + pwm_ch_led_amber = PWM_CH_LED_CHRG; + + /* + * Ver1: GPIOC4(PWM2) -> Blue LED + * GPIO80(PWM3) -> Amber LED + */ + if (cbi_get_board_version(&val) == EC_SUCCESS && val <= 1) { + pwm_ch_led_blue = PWM_CH_LED_CHRG; + pwm_ch_led_amber = PWM_CH_LED_FULL; + } +} +DECLARE_HOOK(HOOK_INIT, led_pwm_ch_init, HOOK_PRIO_INIT_PWM - 1); + __override struct led_descriptor led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, - [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, - [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, - [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, - {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_S5] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, [STATE_FACTORY_TEST] = {{EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC}, - {EC_LED_COLOR_WHITE, 2 * LED_ONE_SEC} }, + {EC_LED_COLOR_BLUE, 2 * LED_ONE_SEC} }, }; const enum ec_led_id supported_led_ids[] = { @@ -46,21 +70,21 @@ __override void led_set_color_battery(enum ec_led_colors color) { switch (color) { case EC_LED_COLOR_AMBER: - pwm_enable(PWM_CH_LED_CHRG, LED_ON_LVL); - pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + pwm_enable(pwm_ch_led_amber, LED_ON_LVL); + pwm_enable(pwm_ch_led_blue, LED_OFF_LVL); break; - case EC_LED_COLOR_WHITE: - pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); - pwm_enable(PWM_CH_LED_FULL, LED_ON_LVL); + case EC_LED_COLOR_BLUE: + pwm_enable(pwm_ch_led_amber, LED_OFF_LVL); + pwm_enable(pwm_ch_led_blue, LED_ON_LVL); break; case LED_OFF: - pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); - pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + pwm_enable(pwm_ch_led_amber, LED_OFF_LVL); + pwm_enable(pwm_ch_led_blue, LED_OFF_LVL); break; default: /* Unsupported colors */ CPRINTS("Unsupported LED color: %d", color); - pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); - pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + pwm_enable(pwm_ch_led_amber, LED_OFF_LVL); + pwm_enable(pwm_ch_led_blue, LED_OFF_LVL); break; } } @@ -69,15 +93,15 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { if (led_id == EC_LED_ID_BATTERY_LED) { brightness_range[EC_LED_COLOR_AMBER] = 1; - brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_BLUE] = 1; } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { if (led_id == EC_LED_ID_BATTERY_LED) { - if (brightness[EC_LED_COLOR_WHITE] != 0) - led_set_color_battery(EC_LED_COLOR_WHITE); + if (brightness[EC_LED_COLOR_BLUE] != 0) + led_set_color_battery(EC_LED_COLOR_BLUE); else if (brightness[EC_LED_COLOR_AMBER] != 0) led_set_color_battery(EC_LED_COLOR_AMBER); else diff --git a/board/dewatt/thermal.c b/board/dewatt/thermal.c new file mode 100644 index 0000000000..39be5bfd6b --- /dev/null +++ b/board/dewatt/thermal.c @@ -0,0 +1,145 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Guybrush board-specific configuration */ + +#include "console.h" +#include "fan.h" +#include "thermal.h" +#include "util.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_THERMAL, outstr) +#define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) + +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_S0_PGOOD, + .enable_gpio = -1, +}; +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 3000, + .rpm_start = 3000, + .rpm_max = 6000, +}; +const struct fan_t fans[] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); + +struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT] = { + [TEMP_SENSOR_SOC] = { + .temp_host = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), + [EC_TEMP_THRESH_HALT] = C_TO_K(85), + }, + .temp_host_release = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), + }, + .temp_fan_off = C_TO_K(27), + .temp_fan_max = C_TO_K(80), + }, + [TEMP_SENSOR_CHARGER] = { + .temp_host = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), + [EC_TEMP_THRESH_HALT] = C_TO_K(85), + }, + .temp_host_release = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), + }, + .temp_fan_off = 0, + .temp_fan_max = 0, + }, + [TEMP_SENSOR_MEMORY] = { + .temp_host = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), + [EC_TEMP_THRESH_HALT] = C_TO_K(85), + }, + .temp_host_release = { + [EC_TEMP_THRESH_HIGH] = C_TO_K(75), + }, + .temp_fan_off = 0, + .temp_fan_max = 0, + }, + [TEMP_SENSOR_CPU] = { + .temp_host = { + [EC_TEMP_THRESH_HIGH] = 0, + [EC_TEMP_THRESH_HALT] = 0, + }, + .temp_host_release = { + [EC_TEMP_THRESH_HIGH] = 0, + }, + .temp_fan_off = 0, + .temp_fan_max = 0, + }, + /* + * Note: Leave ambient entries at 0, both as it does not represent a + * hotspot and as not all boards have this sensor + */ +}; +BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); + +struct fan_step { + int on; + int off; + int rpm; +}; + +static const struct fan_step fan_table[] = { + {.on = 0, .off = 1, .rpm = 0}, + {.on = 6, .off = 2, .rpm = 3000}, + {.on = 28, .off = 15, .rpm = 3300}, + {.on = 34, .off = 26, .rpm = 3700}, + {.on = 39, .off = 32, .rpm = 4000}, + {.on = 45, .off = 38, .rpm = 4300}, + {.on = 51, .off = 43, .rpm = 4700}, + {.on = 74, .off = 62, .rpm = 5400}, +}; +#define NUM_FAN_LEVELS ARRAY_SIZE(fan_table) + +int fan_percent_to_rpm(int fan, int pct) +{ + static int current_level; + static int previous_pct; + int i; + + /* + * Compare the pct and previous pct, we have the three paths : + * 1. decreasing path. (check the off point) + * 2. increasing path. (check the on point) + * 3. invariant path. (return the current RPM) + */ + if (pct < previous_pct) { + for (i = current_level; i >= 0; i--) { + if (pct <= fan_table[i].off) + current_level = i - 1; + else + break; + } + } else if (pct > previous_pct) { + for (i = current_level + 1; i < NUM_FAN_LEVELS; i++) { + if (pct >= fan_table[i].on) + current_level = i; + else + break; + } + } + + if (current_level < 0) + current_level = 0; + + previous_pct = pct; + + if (fan_table[current_level].rpm != + fan_get_rpm_target(FAN_CH(fan))) + CPRINTS("Setting fan RPM to %d", + fan_table[current_level].rpm); + + return fan_table[current_level].rpm; +} diff --git a/board/discovery-stm32f072/board.c b/board/discovery-stm32f072/board.c index c7099f55d1..086e5260a2 100644 --- a/board/discovery-stm32f072/board.c +++ b/board/discovery-stm32f072/board.c @@ -141,6 +141,7 @@ const void *const usb_strings[] = { [USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32), [USB_STR_STREAM_NAME] = USB_STRING_DESC("Forward"), [USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Shell"), + [USB_STR_SPI_NAME] = USB_STRING_DESC("SPI"), }; BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); diff --git a/board/discovery-stm32f072/board.h b/board/discovery-stm32f072/board.h index d3f51f6691..b889ebc8fe 100644 --- a/board/discovery-stm32f072/board.h +++ b/board/discovery-stm32f072/board.h @@ -51,7 +51,7 @@ /* Enable control of SPI over USB */ #define CONFIG_SPI_CONTROLLER -#define CONFIG_SPI_FLASH_PORT 0 /* First SPI master port */ +#define CONFIG_SPI_FLASH_PORT 0 /* First SPI controller port */ #define CONFIG_USB_SPI @@ -80,6 +80,7 @@ enum usb_strings { USB_STR_VERSION, USB_STR_STREAM_NAME, USB_STR_CONSOLE_NAME, + USB_STR_SPI_NAME, USB_STR_COUNT }; diff --git a/board/dojo/battery.c b/board/dojo/battery.c new file mode 100644 index 0000000000..72daf4966d --- /dev/null +++ b/board/dojo/battery.c @@ -0,0 +1,126 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery.h" +#include "battery_fuel_gauge.h" +#include "battery_smart.h" + +const struct board_batt_params board_battery_info[] = { + /* Panasonic AP16L5J Battery Information */ + [BATTERY_PANASONIC_AC16L5J] = { + .fuel_gauge = { + .manuf_name = "PANASONIC", + .device_name = "AP16L5J", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x4000, + .disconnect_val = 0x0, + } + }, + .batt_info = { + .voltage_max = 8800, + .voltage_normal = 7700, + .voltage_min = 6000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + [BATTERY_PANASONIC_AC16L5J_KT00205009] = { + .fuel_gauge = { + .manuf_name = "PANASONIC KT00205009", + .device_name = "AP16L5J", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x4000, + .disconnect_val = 0x0, + } + }, + .batt_info = { + .voltage_max = 8800, + .voltage_normal = 7700, + .voltage_min = 6000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + /* AP16L8J */ + [BATTERY_AP16L8J] = { + .fuel_gauge = { + .manuf_name = "LGC KT0020G010", + .device_name = "AP16L8J", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .mfgacc_support = 1, + .reg_addr = 0x0, + .reg_mask = 0x0002, + .disconnect_val = 0x0, + } + }, + .batt_info = { + .voltage_max = 8700, + .voltage_normal = 7500, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + /* LGC AP18C8K Battery Information */ + [BATTERY_LGC_AP18C8K] = { + .fuel_gauge = { + .manuf_name = "LGC KT0030G020", + .device_name = "AP18C8K", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x43, + .reg_mask = 0x0001, + .disconnect_val = 0x0, + }, + }, + .batt_info = { + .voltage_max = 13050, + .voltage_normal = 11250, + .voltage_min = 9000, + .precharge_current = 256, + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_PANASONIC_AC16L5J; diff --git a/board/dojo/board.c b/board/dojo/board.c new file mode 100644 index 0000000000..35dae9ed36 --- /dev/null +++ b/board/dojo/board.c @@ -0,0 +1,179 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/* Cherry board configuration */ + +#include "common.h" +#include "console.h" +#include "driver/accel_bma422.h" +#include "driver/accel_kionix.h" +#include "driver/accel_kx022.h" +#include "driver/accelgyro_icm42607.h" +#include "driver/accelgyro_icm_common.h" +#include "gpio.h" +#include "hooks.h" +#include "motion_sense.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "system.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +/* Sensor */ +static struct mutex g_base_mutex; +static struct mutex g_lid_mutex; + +static struct icm_drv_data_t g_icm42607_data; +static struct kionix_accel_data g_kx022_data; +static struct accelgyro_saved_data_t g_bma422_data; + +/* Matrix to rotate accelrator into standard reference frame */ +static const mat33_fp_t base_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; + +static const mat33_fp_t lid_standard_ref = { + { FLOAT_TO_FP(-1), 0, 0}, + { 0, FLOAT_TO_FP(-1), 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +struct motion_sensor_t motion_sensors[] = { + /* + * Note: bmi160: supports accelerometer and gyro sensor + * Requirement: accelerometer sensor must init before gyro sensor + * DO NOT change the order of the following table. + */ + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM42607, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm42607_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm42607_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = ICM42607_ADDR0_FLAGS, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ + .rot_standard_ref = &base_standard_ref, + .min_frequency = ICM42607_ACCEL_MIN_FREQ, + .max_frequency = ICM42607_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM42607, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm42607_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm42607_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = ICM42607_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = ICM42607_GYRO_MIN_FREQ, + .max_frequency = ICM42607_GYRO_MAX_FREQ, + }, + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_KX022, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &kionix_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_kx022_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = KX022_ADDR1_FLAGS, + .rot_standard_ref = &lid_standard_ref, + .default_range = 2, /* g, enough for laptop. */ + .min_frequency = KX022_ACCEL_MIN_FREQ, + .max_frequency = KX022_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, +}; +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +struct motion_sensor_t bma422_lid_accel = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMA422, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &bma4_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_bma422_data, + .port = I2C_PORT_ACCEL, + .i2c_spi_addr_flags = BMA4_I2C_ADDR_PRIMARY, + .rot_standard_ref = &lid_standard_ref, + .min_frequency = BMA4_ACCEL_MIN_FREQ, + .max_frequency = BMA4_ACCEL_MAX_FREQ, + .default_range = 2, /* g, enough for laptop. */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 0, + }, + }, +}; + +static void board_update_motion_sensor_config(void) +{ + if (system_get_board_version() >= 2) { + motion_sensors[LID_ACCEL] = bma422_lid_accel; + ccprints("LID ACCEL is BMA422"); + } else { + ccprints("LID ACCEL is KX022"); + } +} + +/* Initialize board. */ +static void board_init(void) +{ + /* Enable motion sensor interrupt */ + gpio_enable_interrupt(GPIO_BASE_IMU_INT_L); + gpio_enable_interrupt(GPIO_LID_ACCEL_INT_L); + + /* Disable PWM_CH_LED2(Green) for unuse */ + pwm_enable(PWM_CH_LED2, 0); + + board_update_motion_sensor_config(); + + if (board_get_version() >= 2) { + gpio_set_flags(GPIO_I2C_H_SCL, GPIO_INPUT | GPIO_PULL_DOWN); + gpio_set_flags(GPIO_I2C_H_SDA, GPIO_INPUT | GPIO_PULL_DOWN); + } +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); diff --git a/board/krabby/board.h b/board/dojo/board.h index 4e3dfc43d6..1c52eac8ba 100644 --- a/board/krabby/board.h +++ b/board/dojo/board.h @@ -2,7 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -/* Krabby board configuration */ +/* Cherry board configuration */ #ifndef __CROS_EC_BOARD_H #define __CROS_EC_BOARD_H @@ -10,9 +10,12 @@ #include "baseboard.h" /* Chipset config */ +#define CONFIG_BRINGUP /* Optional features */ +#define CONFIG_SYSTEM_UNLOCKED #define CONFIG_LTO +#define CONFIG_PRESERVE_LOGS /* * TODO: Remove this option once the VBAT no longer keeps high when @@ -27,13 +30,7 @@ #define CONFIG_LED_ONOFF_STATES_BAT_LOW 10 /* PD / USB-C / PPC */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 -#define PD_MAX_CURRENT_MA 3000 -#define PD_OPERATING_POWER_MW 15000 -#define PD_MAX_VOLTAGE_MV 15000 -#define PD_MAX_POWER_MW 45000 -#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ -#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ +#define CONFIG_USB_PD_DEBUG_LEVEL 0 /* Optional console commands */ #define CONFIG_CMD_FLASH @@ -42,31 +39,34 @@ #define CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV 9000 +/* Keyboard */ +#define GPIO_EN_KEYBOARD_BACKLIGHT GPIO_EN_KB_BL +#define CONFIG_KEYBOARD_REFRESH_ROW3 + /* Sensor */ #define CONFIG_GMR_TABLET_MODE #define CONFIG_TABLET_MODE #define CONFIG_TABLET_MODE_SWITCH #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L -#define CONFIG_ACCELGYRO_BMI160 /* Base accel */ -#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) -#define CONFIG_ACCELGYRO_ICM426XX /* Base accel */ -#define CONFIG_ACCELGYRO_ICM426XX_INT_EVENT \ +/* ICM426XX Base accel/gyro */ +#define CONFIG_ACCELGYRO_ICM42607 +#define CONFIG_ACCELGYRO_ICM42607_INT_EVENT \ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) -#define CONFIG_ACCEL_LIS2DWL -#define CONFIG_ACCEL_LIS2DW_AS_BASE -#define CONFIG_ACCEL_LIS2DW12_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL) +/* KX022 Lid accel */ +#define CONFIG_ACCEL_KX022 + +/* BMA422 Lid accel */ +#define CONFIG_ACCEL_BMA4XX + +#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) #define CONFIG_LID_ANGLE #define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL #define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL #define CONFIG_LID_ANGLE_UPDATE -#define CONFIG_ACCEL_FORCE_MODE_MASK 0 - /* SPI / Host Command */ #undef CONFIG_HOSTCMD_DEBUG_MODE #define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_OFF @@ -74,13 +74,21 @@ /* USB-A */ #define USBA_PORT_COUNT 1 +/* Temperature */ +#define CONFIG_TEMP_SENSOR +#define CONFIG_THERMISTOR +#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B + #ifndef __ASSEMBLER__ #include "gpio_signal.h" #include "registers.h" enum battery_type { - BATTERY_C235, + BATTERY_PANASONIC_AC16L5J, + BATTERY_PANASONIC_AC16L5J_KT00205009, + BATTERY_AP16L8J, + BATTERY_LGC_AP18C8K, BATTERY_TYPE_COUNT, }; @@ -91,26 +99,7 @@ enum sensor_id { SENSOR_COUNT, }; -enum adc_channel { - ADC_VBUS_C0, /* ADC 0 */ - ADC_BOARD_ID_0, /* ADC 1 */ - ADC_BOARD_ID_1, /* ADC 2 */ - ADC_CHARGER_AMON_R, /* ADC 3 */ - ADC_VBUS_C1, /* ADC 5 */ - ADC_CHARGER_PMON, /* ADC 6 */ - - /* Number of ADC channels */ - ADC_CH_COUNT, -}; - -enum pwm_channel { - PWM_CH_LED1, - PWM_CH_LED2, - PWM_CH_LED3, - PWM_CH_COUNT, -}; - -void motion_interrupt(enum gpio_signal signal); +int board_accel_force_mode_mask(void); #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/kingler/build.mk b/board/dojo/build.mk index b355dfd90d..0b0569c6d8 100644 --- a/board/kingler/build.mk +++ b/board/dojo/build.mk @@ -9,8 +9,6 @@ CHIP:=it83xx CHIP_FAMILY:=it8xxx2 CHIP_VARIANT:=it81202bx_1024 -BASEBOARD:=corsola +BASEBOARD:=cherry -board-y=led.o -board-y+=battery.o board.o -board-y+=usbc_config.o +board-y+=led.o battery.o board.o diff --git a/board/krabby/ec.tasklist b/board/dojo/ec.tasklist index 75dbb1a828..f9050fef87 100644 --- a/board/krabby/ec.tasklist +++ b/board/dojo/ec.tasklist @@ -13,10 +13,11 @@ TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_NOTEST(PDCMD, pd_command_task, NULL, 1024) \ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, 1024) \ TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(DPS, dps_task, NULL, 1280) \ TASK_ALWAYS(PD_C0, pd_task, NULL, 1280) \ TASK_ALWAYS(PD_C1, pd_task, NULL, 1280) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, 1024) \ diff --git a/board/kingler/gpio.inc b/board/dojo/gpio.inc index 1d4700c1c1..296e3a418e 100644 --- a/board/kingler/gpio.inc +++ b/board/dojo/gpio.inc @@ -10,7 +10,7 @@ /* Wake Source interrupts */ GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH | GPIO_PULL_UP | - GPIO_HIB_WAKE_HIGH, power_button_interrupt) /* H1_EC_PWR_BTN_ODL */ + GPIO_HIB_WAKE_HIGH, power_button_interrupt) /* GSC_EC_PWR_BTN_ODL */ GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) GPIO_INT(TABLET_MODE_L, PIN(J, 7), GPIO_INT_BOTH, @@ -29,17 +29,18 @@ GPIO_INT(PMIC_EC_PWRGD, PIN(F, 3), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, power_signal_interrupt) /* Sensor Interrupts */ -GPIO_INT(BASE_IMU_INT_L, PIN(J, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, - motion_interrupt) -GPIO_INT(LID_ACCEL_INT_L, PIN(J, 3), GPIO_INT_FALLING | GPIO_SEL_1P8V, - lis2dw12_interrupt) -GPIO(ALS_RGB_INT_ODL, PIN(F, 0), GPIO_INPUT) - +GPIO_INT(BASE_IMU_INT_L, PIN(M, 3), GPIO_INT_FALLING | GPIO_SEL_1P8V, + icm42607_interrupt) /* USB-C interrupts */ -/* TODO: driver not ready */ -GPIO(USB_C0_PPC_INT_ODL, PIN(D, 1), GPIO_INT_BOTH) -GPIO_INT(USB_C0_BC12_INT_ODL,PIN(J, 6), GPIO_INT_FALLING, bc12_interrupt) -GPIO_INT(USB_C1_BC12_INT_L, PIN(J, 4), GPIO_INT_FALLING, bc12_interrupt) +GPIO_INT(USB_C0_PPC_INT_ODL, PIN(D, 1), GPIO_INT_BOTH, ppc_interrupt) +#ifdef BOARD_CHERRY +GPIO_INT(USB_C0_BC12_INT_ODL,PIN(J, 4), GPIO_INT_FALLING, bc12_interrupt) +#else /* TOMATO */ +GPIO_INT(USB_C0_BC12_INT_ODL,PIN(I, 5), GPIO_INT_FALLING, bc12_interrupt) +#endif +GPIO_INT(USB_C1_INT_ODL, PIN(B, 2), GPIO_INT_FALLING, rt1718s_tcpc_interrupt) +/* TODO: not used in other devices? */ +GPIO(LID_ACCEL_INT_L, PIN(M, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V) /* Volume button interrupts */ GPIO_INT(VOLUME_DOWN_L, PIN(D, 5), GPIO_INT_BOTH | GPIO_PULL_UP, @@ -48,8 +49,6 @@ GPIO_INT(VOLUME_UP_L, PIN(D, 6), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) /* EC_VOLUP_BTN_ODL */ /* Other interrupts */ -GPIO_INT(AP_XHCI_INIT_DONE, PIN(D, 2), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, - usb_a0_interrupt) GPIO_INT(AC_PRESENT, PIN(E, 5), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) /* AC_OK / AC_PRESENT in rev1+ */ GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING, @@ -58,16 +57,18 @@ GPIO_INT(WP, PIN(I, 4), GPIO_INT_BOTH | GPIO_SEL_1P8V, switch_interrupt) /* EC_FLASH_WP_OD */ GPIO_INT(SPI0_CS, PIN(M, 5), GPIO_INT_FALLING, spi_event) /* SPI slave Chip Select -- AP_SPI_EC_CS_L */ -GPIO_INT(X_EC_GPIO2, PIN(B, 2), GPIO_ODR_HIGH, x_ec_interrupt) +#ifndef BOARD_CHERRY +GPIO_INT(AP_XHCI_INIT_DONE, PIN(J, 5), GPIO_INT_BOTH | GPIO_PULL_DOWN | GPIO_SEL_1P8V, + xhci_init_done_interrupt) +#endif /* Power Sequencing Signals */ GPIO(EC_PMIC_EN_ODL, PIN(D, 0), GPIO_ODR_HIGH | GPIO_SEL_1P8V) GPIO(EC_PMIC_WATCHDOG_L, PIN(H, 0), GPIO_ODR_LOW | GPIO_SEL_1P8V) GPIO(EN_PP5000_A, PIN(C, 6), GPIO_OUT_HIGH) -GPIO(PG_MT6315_PROC_ODL, PIN(E, 1), GPIO_INPUT) +GPIO(PG_MT6315_PROC_B_ODL, PIN(E, 1), GPIO_INPUT) GPIO(PG_MT6360_ODL, PIN(F, 1), GPIO_INPUT) -GPIO(PG_PP5000_A_ODL, PIN(A, 6), GPIO_INPUT) -GPIO(EN_ULP, PIN(E, 3), GPIO_OUT_LOW) +GPIO(EN_SLP_Z, PIN(E, 3), GPIO_OUT_LOW) GPIO(SYS_RST_ODL, PIN(B, 6), GPIO_ODR_LOW) GPIO(EC_BL_EN_OD, PIN(B, 5), GPIO_ODR_LOW | GPIO_SEL_1P8V) @@ -75,17 +76,22 @@ GPIO(EC_BL_EN_OD, PIN(B, 5), GPIO_ODR_LOW | GPIO_SEL_1P8V) GPIO(EC_INT_L, PIN(E, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_AP_INT_ODL */ /* USB and USBC Signals */ -GPIO(DP_AUX_PATH_SEL, PIN(G, 0), GPIO_OUT_HIGH) -GPIO(EC_AP_DP_HPD_ODL, PIN(J, 0), GPIO_ODR_HIGH | GPIO_SEL_1P8V) -GPIO(EN_PP5000_USB_A0_VBUS, PIN(B, 7), GPIO_OUT_LOW) -GPIO(USB_C0_FRS_EN, PIN(H, 3), GPIO_OUT_LOW) +GPIO(DP_PATH_SEL, PIN(G, 0), GPIO_OUT_HIGH) +GPIO(DP_DEMUX_EN, PIN(G, 1), GPIO_OUT_LOW) +GPIO(EC_AP_DP_HPD_ODL, PIN(J, 0), GPIO_ODR_HIGH) +GPIO(EN_PP5000_USB_A0_VBUS_X,PIN(B, 7), GPIO_OUT_LOW) +GPIO(USB_C0_DP_IN_HPD, PIN(H, 4), GPIO_OUT_LOW) +GPIO(USB_C1_DP_IN_HPD, PIN(J, 1), GPIO_OUT_LOW) +GPIO(USB_C0_FRS_EN, PIN(F, 0), GPIO_OUT_LOW) /* Misc Signals */ +GPIO(EN_KB_BL, PIN(A, 6), GPIO_OUT_LOW) GPIO(EC_BATT_PRES_ODL, PIN(C, 0), GPIO_INPUT) -GPIO(BC12_DET_EN, PIN(J, 5), GPIO_OUT_LOW) /* EN_USB_C0_BC12_DET */ GPIO(EN_EC_ID_ODL, PIN(H, 5), GPIO_ODR_LOW) GPIO(ENTERING_RW, PIN(C, 5), GPIO_OUT_LOW) /* EC_ENTERING_RW */ -GPIO(EN_5V_USM, PIN(D, 7), GPIO_OUT_LOW) +GPIO(EN_5V_USM, PIN(G, 3), GPIO_OUT_LOW) +GPIO(USB_A0_FAULT_ODL, PIN(J, 6), GPIO_INPUT) +GPIO(PACKET_MODE_EN, PIN(D, 4), GPIO_OUT_LOW) /* EC_GSC_PACKET_MODE */ /* I2C pins - Alternate function below configures I2C module on these pins */ GPIO(I2C_A_SCL, PIN(B, 3), GPIO_INPUT) /* I2C_CHG_BATT_SCL */ @@ -93,19 +99,13 @@ GPIO(I2C_A_SDA, PIN(B, 4), GPIO_INPUT) /* I2C_CHG_BATT_SDA */ GPIO(I2C_B_SCL, PIN(C, 1), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_SENSOR_SCL */ GPIO(I2C_B_SDA, PIN(C, 2), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_SENSOR_SDA */ GPIO(I2C_C_SCL, PIN(F, 6), GPIO_INPUT) /* I2C_USB_C0_SCL */ -GPIO(I2C_C_SDA, PIN(F, 7), GPIO_INPUT) /* I2C_USB_C0_SCL */ +GPIO(I2C_C_SDA, PIN(F, 7), GPIO_INPUT) /* I2C_USB_C0_SDA */ GPIO(I2C_E_SCL, PIN(E, 0), GPIO_INPUT) /* I2C_USB_C1_SCL */ GPIO(I2C_E_SDA, PIN(E, 7), GPIO_INPUT) /* I2C_USB_C1_SDA */ - -/* SPI pins - Alternate function below configures SPI module on these pins */ - -/* NC / TP */ - -/* Keyboard pins */ - -/* Subboards HDMI/TYPEC */ -GPIO(EC_X_GPIO1, PIN(H, 4), GPIO_OUT_LOW) -GPIO(EC_X_GPIO3, PIN(J, 1), GPIO_INPUT) +GPIO(I2C_F_SCL, PIN(A, 4), GPIO_INPUT) /* Rev 2+ I2C_PROG_SCL */ +GPIO(I2C_F_SDA, PIN(A, 5), GPIO_INPUT) /* Rev 2+ I2C_PROG_SDA */ +GPIO(I2C_H_SCL, PIN(H, 1), GPIO_INPUT) /* Rev 0,1 I2C_PROG_SCL */ +GPIO(I2C_H_SDA, PIN(H, 2), GPIO_INPUT) /* Rev 0,1 I2C_PROG_SDA */ /* Alternate functions GPIO definitions */ ALTERNATE(PIN_MASK(B, 0x18), 1, MODULE_I2C, 0) /* I2C A */ @@ -117,44 +117,48 @@ ALTERNATE(PIN_MASK(E, 0x81), 1, MODULE_I2C, 0) /* I2C E */ ALTERNATE(PIN_MASK(B, 0x03), 1, MODULE_UART, 0) /* EC to Servo */ /* PWM */ -ALTERNATE(PIN_MASK(A, 0x07), 1, MODULE_PWM, 0) /* PWM 0~2 */ +ALTERNATE(PIN_MASK(A, 0b1111), 1, MODULE_PWM, 0) /* PWM 0,1,2,3 */ /* ADC */ -ALTERNATE(PIN_MASK(I, 0x6F), 0, MODULE_ADC, 0) /* ADC 0,1,2,3,5,6 */ +ALTERNATE(PIN_MASK(I, 0b11001001), 0, MODULE_ADC, 0) /* ADC 0,3,6,7 */ /* SPI */ ALTERNATE(PIN_MASK(M, 0x33), 0, MODULE_SPI, 0) /* SPI */ /* Unimplemented Pins */ -GPIO(SET_VMC_VOLT_AT_1V8, PIN(D, 4), GPIO_INPUT | GPIO_PULL_DOWN | GPIO_SEL_1P8V) -GPIO(PACKET_MODE_EN, PIN(A, 3), GPIO_INPUT | GPIO_PULL_DOWN) -/* b/160218054: behavior not defined */ +GPIO(PG_PP5000_S5_OD, PIN(D, 2), GPIO_INPUT) /* *_ODL pin has external pullup so don't pull it down. */ -GPIO(USB_A0_FAULT_ODL, PIN(A, 7), GPIO_INPUT) -GPIO(CHARGER_PROCHOT_ODL, PIN(C, 3), GPIO_INPUT) GPIO(PG_MT6315_GPU_ODL, PIN(H, 6), GPIO_INPUT) -GPIO(EN_PP3000_SD_U, PIN(G, 1), GPIO_INPUT | GPIO_PULL_DOWN | GPIO_SEL_1P8V) /* reserved for future use */ GPIO(CCD_MODE_ODL, PIN(C, 4), GPIO_INPUT) /* * ADC pins don't have internal pull-down capability, * so we set them as output low. */ -GPIO(NC_GPI7, PIN(I, 7), GPIO_OUT_LOW) +#ifdef BOARD_CHERRY +GPIO(NC_GPI5, PIN(I, 5), GPIO_OUT_LOW) +#else +GPIO(NC_GPJ4, PIN(J, 4), GPIO_INPUT | GPIO_PULL_DOWN) +#endif /* NC pins, enable internal pull-up/down to avoid floating state. */ -GPIO(NC_GPM2, PIN(M, 2), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPM3, PIN(M, 3), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPM6, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(NC_GPA1, PIN(A, 1), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(PWM7, PIN(A, 7), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(EC_NVME_PLN_ODL, PIN(D, 7), GPIO_INPUT | GPIO_PULL_DOWN) GPIO(SPI_CLK_GPG6, PIN(G, 6), GPIO_INPUT | GPIO_PULL_UP) +GPIO(PG_NVME_OD, PIN(H, 3), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(EN_PP2500_NVME_X, PIN(J, 2), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(EN_PP1200_NVME_X, PIN(J, 3), GPIO_INPUT | GPIO_PULL_DOWN) +GPIO(NC_GPM6, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) /* - * These 4 pins don't have internal pull-down capability, + * These pins don't have internal pull-down capability, * so we set them as output low. */ -GPIO(NC_GPG3, PIN(G, 3), GPIO_OUT_LOW) GPIO(SPI_MOSI_GPG4, PIN(G, 4), GPIO_OUT_LOW) GPIO(SPI_MISO_GPG5, PIN(G, 5), GPIO_OUT_LOW) GPIO(SPI_CS_GPG7, PIN(G, 7), GPIO_OUT_LOW) +GPIO(EC_ID0, PIN(I, 1), GPIO_OUT_LOW) +GPIO(EC_ID1, PIN(I, 2), GPIO_OUT_LOW) + +/* Other unused pins */ +GPIO(NVME_EC_PLA_S3_ODL, PIN(I, 7), GPIO_INPUT) -UNIMPLEMENTED(USB_C0_PPC_BC12_INT_ODL) -UNIMPLEMENTED(USB_C0_PPC_FRSINFO) -UNIMPLEMENTED(USB_C1_BC12_CHARGER_INT_ODL) diff --git a/board/dojo/led.c b/board/dojo/led.c new file mode 100644 index 0000000000..c177a1b48f --- /dev/null +++ b/board/dojo/led.c @@ -0,0 +1,87 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "chipset.h" +#include "common.h" +#include "gpio.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "pwm.h" + +#define LED_OFF_LVL 0 +#define LED_ON_LVL 1 + +__override const int led_charge_lvl_1 = 5; +__override const int led_charge_lvl_2 = 95; + +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_S5] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_BLUE, 2 * LED_ONE_SEC}, + {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, +}; + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, +}; +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + pwm_enable(PWM_CH_LED1, LED_ON_LVL); + pwm_enable(PWM_CH_LED3, LED_OFF_LVL); + break; + case EC_LED_COLOR_BLUE: + pwm_enable(PWM_CH_LED1, LED_OFF_LVL); + pwm_enable(PWM_CH_LED3, LED_ON_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + pwm_enable(PWM_CH_LED1, LED_OFF_LVL); + pwm_enable(PWM_CH_LED3, LED_OFF_LVL); + break; + } +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + brightness_range[EC_LED_COLOR_AMBER] = 1; + brightness_range[EC_LED_COLOR_BLUE] = 1; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else if (brightness[EC_LED_COLOR_BLUE] != 0) + led_set_color_battery(EC_LED_COLOR_BLUE); + else + led_set_color_battery(LED_OFF); + return EC_SUCCESS; +} + +__override enum led_states board_led_get_state(enum led_states desired_state) +{ + if (desired_state == STATE_BATTERY_ERROR) { + if (chipset_in_state(CHIPSET_STATE_ON)) + return desired_state; + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + return STATE_DISCHARGE_S3; + else + return STATE_DISCHARGE_S5; + } + return desired_state; +} diff --git a/board/dojo/vif_override.xml b/board/dojo/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/dojo/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/dooly/board.c b/board/dooly/board.c index 5f854ca647..06e479649d 100644 --- a/board/dooly/board.c +++ b/board/dooly/board.c @@ -18,6 +18,7 @@ #include "driver/als_tcs3400.h" #include "driver/ina3221.h" #include "driver/led/oz554.h" +#include "driver/led/mp3385.h" #include "driver/ppc/sn5s330.h" #include "driver/tcpm/anx7447.h" #include "driver/tcpm/ps8xxx.h" @@ -532,13 +533,55 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"ppc1", I2C_PORT_PPC1, 400, GPIO_I2C2_SCL, GPIO_I2C1_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C4_SCL, GPIO_I2C3_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "ppc1", + .port = I2C_PORT_PPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -663,6 +706,7 @@ const unsigned int ina3221_count = ARRAY_SIZE(ina3221); static uint16_t board_version; static uint32_t sku_id; static uint32_t fw_config; +static uint32_t ssfc; static void cbi_init(void) { @@ -680,8 +724,11 @@ static void cbi_init(void) sku_id = val; if (cbi_get_fw_config(&val) == EC_SUCCESS) fw_config = val; - CPRINTS("Board Version: %d, SKU ID: 0x%08x, F/W config: 0x%08x", - board_version, sku_id, fw_config); + if (cbi_get_ssfc(&val) == EC_SUCCESS) + ssfc = val; + CPRINTS("Board Version: %d, SKU ID: 0x%08x, " + "F/W config: 0x%08x, SSFC: 0x%08x ", + board_version, sku_id, fw_config, ssfc); } DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_INIT_I2C + 1); @@ -715,6 +762,13 @@ static void board_init(void) /* Always claim AC is online, because we don't have a battery. */ memmap_batt_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG); *memmap_batt_flags |= EC_BATT_FLAG_AC_PRESENT; + + /* Initial backlight ic setting by ssfc */ + if (ec_ssfc_get_led_ic() == SSFC_LED_MP3385) + mp3385_board_init(); + else + oz554_board_init(); + gpio_enable_interrupt(GPIO_PANEL_BACKLIGHT_EN); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); @@ -922,6 +976,11 @@ unsigned int ec_config_get_thermal_solution(void) return (fw_config & EC_CFG_THERMAL_MASK) >> EC_CFG_THERMAL_L; } +unsigned int ec_ssfc_get_led_ic(void) +{ + return (ssfc & EC_SSFC_LED_MASK) >> EC_SSFC_LED_L; +} + /* * Power monitoring and management. * @@ -1176,7 +1235,7 @@ static void power_monitor(void) hook_call_deferred(&power_monitor_data, delay); } -__override void oz554_board_init(void) +void oz554_board_init(void) { int pin_status = 0; @@ -1201,3 +1260,45 @@ __override void oz554_board_init(void) break; } } + +void mp3385_board_init(void) +{ + int pin_status = 0; + + pin_status |= gpio_get_level(GPIO_PANEL_ID0) << 0; + pin_status |= gpio_get_level(GPIO_PANEL_ID1) << 1; + + switch (pin_status) { + case 0x00: + CPRINTS("PANEL_HAN01.10A"); + mp3385_set_config(0, 0xF1); + mp3385_set_config(2, 0x4C); + mp3385_set_config(5, 0xB7); + break; + case 0x02: + CPRINTS("PANEL_WF9_SSA2"); + mp3385_set_config(0, 0xF1); + mp3385_set_config(2, 0x55); + mp3385_set_config(5, 0x87); + break; + default: + CPRINTS("PANEL UNKNOWN"); + break; + } +} + +void board_backlight_enable_interrupt(enum gpio_signal signal) +{ + switch (ec_ssfc_get_led_ic()) { + case SSFC_LED_OZ554: + oz554_interrupt(signal); + break; + case SSFC_LED_MP3385: + mp3385_interrupt(signal); + break; + default: + oz554_interrupt(signal); + break; + } + +} diff --git a/board/dooly/board.h b/board/dooly/board.h index 4e0f4a5481..55422449b8 100644 --- a/board/dooly/board.h +++ b/board/dooly/board.h @@ -73,7 +73,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -157,7 +157,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -224,6 +224,7 @@ * LED backlight controller */ #define CONFIG_LED_DRIVER_OZ554 +#define CONFIG_LED_DRIVER_MP3385 #define PP5000_PGOOD_POWER_SIGNAL_MASK POWER_SIGNAL_MASK(PP5000_A_PGOOD) @@ -280,6 +281,12 @@ enum sensor_id { SENSOR_COUNT, }; +enum ssfc_led_id { + SSFC_LED_OZ554 = 0, + SSFC_LED_MP3385, + SSFC_LED_COUNT, +}; + /* Board specific handlers */ void board_reset_pd_mcu(void); @@ -309,8 +316,22 @@ void show_critical_error(void); #define EC_CFG_THERMAL_H 7 #define EC_CFG_THERMAL_MASK GENMASK(EC_CFG_THERMAL_H, EC_CFG_THERMAL_L) +/* + * Second Source Factory Cache (SSFC) CBI field + */ +/* + * Led driver IC (2 bits). + */ +#define EC_SSFC_LED_L 0 +#define EC_SSFC_LED_H 1 +#define EC_SSFC_LED_MASK GENMASK(EC_SSFC_LED_H, EC_SSFC_LED_L) + + unsigned int ec_config_get_bj_power(void); unsigned int ec_config_get_thermal_solution(void); +unsigned int ec_ssfc_get_led_ic(void); + +void board_backlight_enable_interrupt(enum gpio_signal signal); #endif /* !__ASSEMBLER__ */ @@ -333,6 +354,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/dooly/gpio.inc b/board/dooly/gpio.inc index 1d9b143486..65488936b7 100644 --- a/board/dooly/gpio.inc +++ b/board/dooly/gpio.inc @@ -42,7 +42,7 @@ GPIO_INT(USB_C0_TCPPC_INT_ODL, PIN(E, 0), GPIO_INT_FALLING, ppc_interrupt) GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, tcpc_alert_event) GPIO_INT(USB_C1_TCPPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, ppc_interrupt) GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(E, 4), GPIO_INT_FALLING, tcpc_alert_event) -GPIO_INT(PANEL_BACKLIGHT_EN, PIN(B, 1), GPIO_INT_RISING, backlight_enable_interrupt) +GPIO_INT(PANEL_BACKLIGHT_EN, PIN(B, 1), GPIO_INT_RISING, board_backlight_enable_interrupt) /* Sensor Interrupts */ GPIO_INT(ALS_GSENSOR_INT_ODL, PIN(9, 6), GPIO_INT_FALLING, tcs3400_interrupt) @@ -69,7 +69,7 @@ GPIO_INT(EC_VOLUP_BTN_ODL, PIN(8, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_i GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) diff --git a/board/draco/battery.c b/board/draco/battery.c new file mode 100644 index 0000000000..fbada9a9f1 --- /dev/null +++ b/board/draco/battery.c @@ -0,0 +1,107 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_fuel_gauge.h" +#include "cbi.h" +#include "common.h" +#include "compile_time_macros.h" +#include "gpio.h" +/* + * Battery info for all Draco battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* DYNAPACK COSMAX Battery Information */ + [BATTERY_DYNAPACK_COSMX] = { + /* RAJ240045 Fuel Gauge */ + .fuel_gauge = { + .manuf_name = "333-2C-4C-A", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .mfgacc_support = 0, + .reg_addr = 0x43, + .reg_mask = 0x0003, + .disconnect_val = 0x0, + } + }, + .batt_info = { + .voltage_max = 17600, + .voltage_normal = 15400, /* mV */ + .voltage_min = 12000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 50, + .discharging_min_c = -10, + .discharging_max_c = 60, + }, + }, + /* DYNAPACK HIGHPOWER Battery Information */ + [BATTERY_DYNAPACK_HIGHPOWER] = { + /* RAJ240045 Fuel Gauge */ + .fuel_gauge = { + .manuf_name = "333-2D-4C-A", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .mfgacc_support = 0, + .reg_addr = 0x43, + .reg_mask = 0x0003, + .disconnect_val = 0x0, + } + }, + .batt_info = { + .voltage_max = 17600, + .voltage_normal = 15400, /* mV */ + .voltage_min = 12000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 50, + .discharging_min_c = -10, + .discharging_max_c = 60, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_DYNAPACK_COSMX; + +enum battery_present battery_hw_present(void) +{ + enum gpio_signal batt_pres; + + batt_pres = GPIO_EC_BATT_PRES_ODL; + + /* The GPIO is low when the battery is physically present */ + return gpio_get_level(batt_pres) ? BP_NO : BP_YES; +} diff --git a/board/draco/board.c b/board/draco/board.c new file mode 100644 index 0000000000..261aebf80c --- /dev/null +++ b/board/draco/board.c @@ -0,0 +1,51 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery.h" +#include "button.h" +#include "charge_ramp.h" +#include "charger.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "gpio.h" +#include "gpio_signal.h" +#include "hooks.h" +#include "fw_config.h" +#include "hooks.h" +#include "lid_switch.h" +#include "power_button.h" +#include "power.h" +#include "registers.h" +#include "switch.h" +#include "throttle_ap.h" +#include "usbc_config.h" + +#include "gpio_list.h" /* Must come after other header files. */ + +/* Console output macros */ +#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) +{ + /* Allow keyboard backlight to be enabled */ + gpio_set_level(GPIO_EC_KB_BL_EN_L, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); + +/* Called on AP S0 -> S3 transition */ +static void board_chipset_suspend(void) +{ + /* Turn off the keyboard backlight if it's on. */ + gpio_set_level(GPIO_EC_KB_BL_EN_L, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); diff --git a/board/draco/board.h b/board/draco/board.h new file mode 100644 index 0000000000..58abc1e694 --- /dev/null +++ b/board/draco/board.h @@ -0,0 +1,204 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Draco board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#include "compile_time_macros.h" + +/* + * Early draco boards are not set up for vivaldi + */ +#undef CONFIG_KEYBOARD_VIVALDI + +/* Baseboard features */ +#include "baseboard.h" + +/* + * This will happen automatically on NPCX9 ES2 and later. Do not remove + * until we can confirm all earlier chips are out of service. + */ +#define CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP + +/* LED */ +#define CONFIG_LED_PWM +#define CONFIG_LED_PWM_COUNT 2 +#undef CONFIG_LED_PWM_NEAR_FULL_COLOR +#undef CONFIG_LED_PWM_SOC_ON_COLOR +#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR +#undef CONFIG_LED_PWM_LOW_BATT_COLOR +#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER + +/* Sensors */ +#undef CONFIG_TABLET_MODE +#undef CONFIG_TABLET_MODE_SWITCH +#undef CONFIG_GMR_TABLET_MODE + +/* Buttons */ +#undef CONFIG_VOLUME_BUTTONS + +/* USB Type A Features */ +#define USB_PORT_COUNT 1 +#define CONFIG_USB_PORT_POWER_DUMB + +/* USB Type C and USB PD defines */ +#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY + +#define CONFIG_USB_PD_TCPM_PS8815 +#define CONFIG_USB_PD_TCPM_PS8815_FORCE_DID + +/* I2C speed console command */ +#define CONFIG_CMD_I2C_SPEED + +/* I2C control host command */ +#define CONFIG_HOSTCMD_I2C_CONTROL + +#define CONFIG_USBC_PPC_SYV682X +#define CONFIG_USBC_PPC_NX20P3483 + +#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 */ + +/* + * Passive USB-C cables only support up to 60W. + */ +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW 60000 +#define PD_MAX_CURRENT_MA 3000 +#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_ENABLE_BACKLIGHT GPIO_EC_EN_EDP_BL +#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW +#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV +#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 + +/* + * 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 + +/* System has back-lit keyboard */ +#define CONFIG_PWM_KBLIGHT + +/* I2C Bus Configuration */ + +#define I2C_PORT_SENSOR 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_BATTERY NPCX_I2C_PORT5_0 +#define I2C_PORT_CHARGER NPCX_I2C_PORT7_0 +#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 + +#define I2C_ADDR_EEPROM_FLAGS 0x50 + +/* Thermal features */ +#define CONFIG_THERMISTOR +#define CONFIG_TEMP_SENSOR +#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B + +#define CONFIG_FANS FAN_CH_COUNT + +/* Charger defines */ +#define CONFIG_CHARGER_ISL9241 +#define CONFIG_CHARGE_RAMP_SW +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10 + +/* + * Older boards have a different ADC assignment. + */ + +#define CONFIG_ADC_CHANNELS_RUNTIME_CONFIG + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" /* needed by registers.h */ +#include "registers.h" +#include "usbc_config.h" + +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 +}; + +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 battery_type { + BATTERY_DYNAPACK_COSMX, + BATTERY_DYNAPACK_HIGHPOWER, + 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 +}; + +enum fan_channel { + FAN_CH_0 = 0, + FAN_CH_COUNT +}; + +enum mft_channel { + MFT_CH_0 = 0, + MFT_CH_COUNT +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/draco/build.mk b/board/draco/build.mk new file mode 100644 index 0000000000..61485378cd --- /dev/null +++ b/board/draco/build.mk @@ -0,0 +1,25 @@ +# -*- makefile -*- +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Draco board specific files build +# + +CHIP:=npcx +CHIP_FAMILY:=npcx9 +CHIP_VARIANT:=npcx9m3f +BASEBOARD:=brya + +board-y= +board-y+=battery.o +board-y+=board.o +board-y+=charger_isl9241.o +board-y+=fans.o +board-y+=fw_config.o +board-y+=i2c.o +board-y+=keyboard.o +board-y+=led.o +board-y+=pwm.o +board-y+=sensors.o +board-y+=usbc_config.o diff --git a/board/draco/charger_isl9241.c b/board/draco/charger_isl9241.c new file mode 100644 index 0000000000..85e0de90fe --- /dev/null +++ b/board/draco/charger_isl9241.c @@ -0,0 +1,90 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" + +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "compile_time_macros.h" +#include "console.h" +#include "driver/charger/isl9241.h" +#include "usbc_ppc.h" +#include "usb_pd.h" +#include "util.h" + + +#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +/* Charger Chip Configuration */ +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL9241_ADDR_FLAGS, + .drv = &isl9241_drv, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(chg_chips) == CHARGER_NUM); + +int board_set_active_charge_port(int port) +{ + int is_valid_port = board_is_usb_pd_port_present(port); + int i; + + if (port == CHARGE_PORT_NONE) { + CPRINTSUSB("Disabling all charger ports"); + + /* Disable all ports. */ + for (i = 0; i < ppc_cnt; i++) { + /* + * Do not return early if one fails otherwise we can + * get into a boot loop assertion failure. + */ + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("Disabling C%d as sink failed.", i); + } + + return EC_SUCCESS; + } else if (!is_valid_port) { + return EC_ERROR_INVAL; + } + + /* Check if the port is sourcing VBUS. */ + if (ppc_is_sourcing_vbus(port)) { + CPRINTFUSB("Skip enable C%d", port); + return EC_ERROR_INVAL; + } + + CPRINTSUSB("New charge port: C%d", port); + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < ppc_cnt; i++) { + if (i == port) + continue; + + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("C%d: sink path disable failed.", i); + } + + /* Enable requested charge port. */ + if (ppc_vbus_sink_enable(port, 1)) { + CPRINTSUSB("C%d: sink path enable failed.", port); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +__overridable void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} diff --git a/board/draco/ec.tasklist b/board/draco/ec.tasklist new file mode 100644 index 0000000000..d866e2349e --- /dev/null +++ b/board/draco/ec.tasklist @@ -0,0 +1,31 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * 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, 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_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ + 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/draco/fans.c b/board/draco/fans.c new file mode 100644 index 0000000000..ca816af8ab --- /dev/null +++ b/board/draco/fans.c @@ -0,0 +1,74 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Physical fans. These are logically separate from pwm_channels. */ + +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "fan_chip.h" +#include "fan.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_1, + .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, +}; + +static const struct fan_rpm fan_rpm_0 = { + .rpm_min = 2200, + .rpm_start = 2200, + .rpm_max = 4200, +}; + +const struct fan_t fans[FAN_CH_COUNT] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; + +#ifndef CONFIG_FANS + +static void fan_slow(void) +{ + const int duty_pct = 33; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +static void fan_max(void) +{ + const int duty_pct = 100; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +DECLARE_HOOK(HOOK_INIT, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESET, fan_max, HOOK_PRIO_FIRST); +DECLARE_HOOK(HOOK_CHIPSET_RESUME, fan_max, HOOK_PRIO_DEFAULT); + +#endif /* CONFIG_FANS */ diff --git a/board/draco/fw_config.c b/board/draco/fw_config.c new file mode 100644 index 0000000000..7dd00954e8 --- /dev/null +++ b/board/draco/fw_config.c @@ -0,0 +1,46 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "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_CHIPSET, format, ## args) + +static union draco_cbi_fw_config fw_config; +BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t)); + +/* + * FW_CONFIG defaults for draco if the CBI.FW_CONFIG data is not + * initialized. + */ +static const union draco_cbi_fw_config fw_config_defaults = { + .usb_db = DB_USB3_PS8815, + .kb_bl = KEYBOARD_BACKLIGHT_ENABLED, +}; + +/**************************************************************************** + * Draco 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; + } +} + +union draco_cbi_fw_config get_fw_config(void) +{ + return fw_config; +} + +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void) +{ + return fw_config.usb_db; +} diff --git a/board/draco/fw_config.h b/board/draco/fw_config.h new file mode 100644 index 0000000000..eea18a6e14 --- /dev/null +++ b/board/draco/fw_config.h @@ -0,0 +1,54 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __BOARD_DRACO_FW_CONFIG_H_ +#define __BOARD_DRACO_FW_CONFIG_H_ + +#include <stdint.h> + +/**************************************************************************** + * CBI FW_CONFIG layout for Draco board. + * + * Source of truth is the project/brya/draco/config.star configuration file. + */ + +enum ec_cfg_usb_db_type { + DB_USB_ABSENT = 0, + DB_USB3_PS8815 = 1, + DB_USB_ABSENT2 = 15 +}; + +enum ec_cfg_keyboard_backlight_type { + KEYBOARD_BACKLIGHT_DISABLED = 0, + KEYBOARD_BACKLIGHT_ENABLED = 1 +}; + +union draco_cbi_fw_config { + struct { + enum ec_cfg_usb_db_type usb_db : 4; + uint32_t sd_db : 2; + uint32_t lte_db : 1; + enum ec_cfg_keyboard_backlight_type kb_bl : 1; + uint32_t audio : 3; + uint32_t reserved_1 : 21; + }; + uint32_t raw_value; +}; + +/** + * Read the cached FW_CONFIG. Guaranteed to have valid values. + * + * @return the FW_CONFIG for the board. + */ +union draco_cbi_fw_config get_fw_config(void); + +/** + * Get the USB daughter board type from FW_CONFIG. + * + * @return the USB daughter board type. + */ +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void); + +#endif /* __BOARD_DRACO_FW_CONFIG_H_ */ diff --git a/board/draco/gpio.inc b/board/draco/gpio.inc new file mode 100644 index 0000000000..715bff4f67 --- /dev/null +++ b/board/draco/gpio.inc @@ -0,0 +1,135 @@ +/* -*- mode:c -*- + * + * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define MODULE_KB MODULE_KEYBOARD_SCAN + +/* INTERRUPT GPIOs: */ +GPIO_INT(ACOK_OD, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, 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 | GPIO_HIB_WAKE_LOW, power_button_interrupt) +GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_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) + +/* USED GPIOs: */ +GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) +GPIO(CHARGER_VAP_OTG_EN, PIN(7, 3), GPIO_OUT_LOW) +GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) +GPIO(EC_BATT_PRES_ODL, PIN(A, 3), GPIO_INPUT) +GPIO(EC_ENTERING_RW, PIN(0, 3), GPIO_OUT_LOW) +GPIO(EC_EN_EDP_BL, PIN(D, 3), GPIO_OUT_HIGH) +GPIO(EC_GSC_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW) +GPIO(EC_I2C_BAT_SCL, PIN(3, 3), GPIO_INPUT) +GPIO(EC_I2C_BAT_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_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_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) +GPIO(EC_KB_BL_EN_L, PIN(8, 6), GPIO_OUT_HIGH) +GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT) +GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) +GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), 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_R_ODL, PIN(C, 0), GPIO_ODR_HIGH) +GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) +GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH) +GPIO(EN_PP5000_USBA_R, PIN(D, 7), GPIO_OUT_LOW) +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_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) + +/* + * The NPCX keyboard driver does not use named GPIOs to access + * keyboard scan pins, so we do not list them in *gpio.inc. However, when + * KEYBOARD_COL2_INVERTED is defined, this name is required. + */ +GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) + +/* 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, GPIO_SEL_1P8V) /* 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(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ +ALTERNATE(PIN_MASK(6, 0x01), 0, MODULE_PWM, 0) /* GPIO60/PWM7 */ +ALTERNATE(PIN_MASK(8, 0x01), 0, MODULE_PWM, 0) /* GPIO80/PWM3 */ +ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */ +ALTERNATE(PIN_MASK(C, 0x1c), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0, GPIOC2/PWM1/I2C6_SCL0 */ + +/* ADC alternate functions */ +ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ +ALTERNATE(PIN_MASK(4, 0x34), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1 */ +ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */ + +/* KB alternate functions */ +ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */ +ALTERNATE(PIN_MASK(1, 0x7f), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO06/GPO13/GP_SEL_L, KSO07/GPO12/JEN_L, KSO03/GPIO16/JTAG_TDO0_SWO, KSO04/GPIO15/XNOR, KSO05/GPIO14, KSO08/GPIO11/CR_SOUT1, KSO09/GPIO10/CR_SIN1 */ +ALTERNATE(PIN_MASK(2, 0xfc), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI2/GPIO27/TRACEDATA1, KSI3/GPIO26/TRACEDATA0, KSI4/GPIO25/TRACECLK/GP_SCLK, KSI5/GPIO24/GP_MISO, KSI6/GPIO23/S_SBUB, KSI7/GPIO22/S_SBUA */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO00/GPIO21/JTAG_TCK_SWCLK, KSO01/GPIO20/JTAG_TMS_SWIO */ +ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI0/GPIO31/TRACEDATA3/GP_MOSI, KSI1/GPIO30/TRACEDATA2/GP_CS_L */ +ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO14/GPIO82 */ + +/* PMU alternate functions */ +ALTERNATE(PIN_MASK(0, 0x01), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN2_L&GPI00/GPIO00 */ +ALTERNATE(PIN_MASK(0, 0x02), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW) /* GPIO01/PSL_IN3_L&GPI01 */ +ALTERNATE(PIN_MASK(D, 0x04), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN1_L&GPID2/GPIOD2 */ + +/* 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(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ +UNUSED(PIN(8, 1)) /* GPIO81 */ +UNUSED(PIN(D, 4)) /* GPIOD4 */ +UNUSED(PIN(5, 6)) /* GPIO56 */ +UNUSED(PIN(9, 3)) /* GPIO93 */ +UNUSED(PIN(9, 7)) /* GPIO97 */ +UNUSED(PIN(9, 5)) /* GPIO95 */ diff --git a/board/draco/i2c.c b/board/draco/i2c.c new file mode 100644 index 0000000000..3db2e0c17b --- /dev/null +++ b/board/draco/i2c.c @@ -0,0 +1,98 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "compile_time_macros.h" +#include "hooks.h" +#include "i2c.h" + +#define BOARD_ID_FAST_PLUS_CAPABLE 2 + +/* I2C port map configuration */ +const struct i2c_port_t i2c_ports[] = { + { + /* I2C0 */ + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_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_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, + }, + { + /* I2C4 C1 TCPC */ + .name = "tcpc1", + .port = I2C_PORT_USB_C1_TCPC, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, + .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + }, + { + /* I2C5 */ + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BAT_SCL, + .sda = GPIO_EC_I2C_BAT_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, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + }, + { + /* 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); + +/* + * I2C controllers are initialized in main.c. This sets the speed much + * later, but before I2C peripherals are initialized. + */ +static void set_board_legacy_i2c_speeds(void) +{ + if (get_board_id() >= BOARD_ID_FAST_PLUS_CAPABLE) + return; + + ccprints("setting USB DB I2C buses to 400 kHz\n"); + + i2c_set_freq(I2C_PORT_USB_C1_TCPC, I2C_FREQ_400KHZ); + i2c_set_freq(I2C_PORT_USB_C1_PPC, I2C_FREQ_400KHZ); +} +DECLARE_HOOK(HOOK_INIT, set_board_legacy_i2c_speeds, HOOK_PRIO_INIT_I2C - 1); diff --git a/board/draco/keyboard.c b/board/draco/keyboard.c new file mode 100644 index 0000000000..a9f033130d --- /dev/null +++ b/board/draco/keyboard.c @@ -0,0 +1,25 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.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 = { + 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ + }, +}; diff --git a/board/draco/led.c b/board/draco/led.c new file mode 100644 index 0000000000..74764a8ef4 --- /dev/null +++ b/board/draco/led.c @@ -0,0 +1,93 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Draco specific PWM LED settings: there are 2 LEDs on each side of the board, + * each one can be controlled separately. The LED colors are white or amber, + * and the default behavior is tied to the charging process: both sides are + * amber while charging the battery and white when the battery is charged. + */ + +#include <stdint.h> + +#include "common.h" +#include "compile_time_macros.h" +#include "ec_commands.h" +#include "led_pwm.h" +#include "pwm.h" +#include "util.h" + +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); + +/* + * We only have a white and an amber LED, so setting any other color results in + * both LEDs being off. Cap at 50% to save power. + */ +struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { + /* Amber, White */ + [EC_LED_COLOR_RED] = { 0, 0 }, + [EC_LED_COLOR_GREEN] = { 0, 0 }, + [EC_LED_COLOR_BLUE] = { 0, 0 }, + [EC_LED_COLOR_YELLOW] = { 0, 0 }, + [EC_LED_COLOR_WHITE] = { 0, 50 }, + [EC_LED_COLOR_AMBER] = { 50, 0 }, +}; + +/* Two logical LEDs with amber and white channels. */ +struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { + { + .ch0 = PWM_CH_LED1, + .ch1 = PWM_CH_LED2, + .ch2 = PWM_LED_NO_CHANNEL, + .enable = &pwm_enable, + .set_duty = &pwm_set_duty, + }, + { + .ch0 = PWM_CH_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) +{ + memset(brightness_range, '\0', + sizeof(*brightness_range) * EC_LED_COLOR_COUNT); + brightness_range[EC_LED_COLOR_AMBER] = 100; + brightness_range[EC_LED_COLOR_WHITE] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + enum pwm_led_id pwm_id; + + /* Convert ec_led_id to pwm_led_id. */ + switch (led_id) { + case EC_LED_ID_LEFT_LED: + pwm_id = PWM_LED0; + break; + case EC_LED_ID_RIGHT_LED: + pwm_id = PWM_LED1; + break; + default: + return EC_ERROR_UNKNOWN; + } + + if (brightness[EC_LED_COLOR_WHITE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); + else + /* Otherwise, the "color" is "off". */ + set_pwm_led_color(pwm_id, -1); + + return EC_SUCCESS; +} diff --git a/board/draco/pwm.c b/board/draco/pwm.c new file mode 100644 index 0000000000..2203f14c8d --- /dev/null +++ b/board/draco/pwm.c @@ -0,0 +1,71 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "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_LED2] = { + .channel = 0, + .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, + .freq = 4800, + }, + [PWM_CH_KBLIGHT] = { + .channel = 3, + .flags = 0, + /* + * Set PWM frequency to multiple of 50 Hz and 60 Hz to prevent + * flicker. Higher frequencies consume similar average power to + * lower PWM frequencies, but higher frequencies record a much + * lower maximum power. + */ + .freq = 2400, + }, + [PWM_CH_FAN] = { + .channel = 5, + .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP, + .freq = 1000 + }, + [PWM_CH_LED4] = { + .channel = 7, + .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, + .freq = 4800, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +static void board_pwm_init(void) +{ + /* + * Turn off all the LEDs. + * Turn on the fan at 100%. + */ + pwm_enable(PWM_CH_LED1, 1); + 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); +} +DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT); diff --git a/board/draco/sensors.c b/board/draco/sensors.c new file mode 100644 index 0000000000..b68984c95c --- /dev/null +++ b/board/draco/sensors.c @@ -0,0 +1,151 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "adc.h" +#include "hooks.h" +#include "temp_sensor.h" +#include "thermal.h" +#include "temp_sensor/thermistor.h" + +/* ADC configuration */ +struct adc_t adc_channels[] = { + [ADC_TEMP_SENSOR_1_DDR_SOC] = { + .name = "TEMP_DDR_SOC", + .input_ch = NPCX_ADC_CH0, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_2_AMBIENT] = { + .name = "TEMP_AMBIENT", + .input_ch = NPCX_ADC_CH1, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_3_CHARGER] = { + .name = "TEMP_CHARGER", + .input_ch = NPCX_ADC_CH6, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [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); + +/* Temperature sensor configuration */ +const struct temp_sensor_t temp_sensors[] = { + [TEMP_SENSOR_1_DDR_SOC] = { + .name = "DDR and SOC", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_1_DDR_SOC, + }, + [TEMP_SENSOR_2_AMBIENT] = { + .name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_2_AMBIENT, + }, + [TEMP_SENSOR_3_CHARGER] = { + .name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .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); + +#define THERMAL_CPU \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(90), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; + +#define THERMAL_AMBIENT \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(90), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_ambient = + THERMAL_AMBIENT; + +/* + * Inductor limits - used for both charger and PP3300 regulator + * + * Need to use the lower of the charger IC, PP3300 regulator, and the inductors + * + * Charger max recommended temperature 125C, max absolute temperature 150C + * PP3300 regulator: operating range -40 C to 125 C + * + * Inductors: limit of 125c + * PCB: limit is 80c + */ +#define THERMAL_CHARGER \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(105), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(120), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(65), \ + } +__maybe_unused static const struct ec_thermal_config thermal_charger = + THERMAL_CHARGER; + +#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/draco/usbc_config.c b/board/draco/usbc_config.c new file mode 100644 index 0000000000..1475e1f536 --- /dev/null +++ b/board/draco/usbc_config.c @@ -0,0 +1,367 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdint.h> +#include <stdbool.h> + +#include "cbi.h" +#include "charger.h" +#include "charge_ramp.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/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" +#include "system.h" +#include "task.h" +#include "task_id.h" +#include "timer.h" +#include "usbc_config.h" +#include "usbc_ppc.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.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 = PS8751_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, + }, + [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); + +/******************************************************************************/ +/* USB-A charging control */ + +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_PP5000_USBA_R, +}; +BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_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] = { + /* Compatible with Silicon Mitus SM536A0 */ + .i2c_port = I2C_PORT_USB_C1_PPC, + .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, + .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 usbc0_tcss_usb_mux = { + .usb_port = USBC_PORT_C0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; +static const struct usb_mux usbc2_tcss_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 + * and updates the TCSS configuration on state changes. + */ +static const struct usb_mux usbc1_usb3_db_retimer = { + .usb_port = USBC_PORT_C1, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, +}; + +const struct usb_mux usb_muxes[] = { + [USBC_PORT_C0] = { + .usb_port = USBC_PORT_C0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + .next_mux = &usbc0_tcss_usb_mux, + }, + [USBC_PORT_C1] = { + .usb_port = USBC_PORT_C1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + .next_mux = &usbc1_usb3_db_retimer, + }, + [USBC_PORT_C2] = { + .usb_port = USBC_PORT_C2, + .driver = &virtual_usb_mux_driver, + .hpd_update = virtual_hpd_update, + .next_mux = &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); + +#ifdef CONFIG_CHARGE_RAMP_SW + +#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(); + + CPRINTS("Configured USB DB type number is %d", db_type); +} + +void board_reset_pd_mcu(void) +{ + enum gpio_signal tcpc_rst; + + tcpc_rst = GPIO_USB_C0_C2_TCPC_RST_ODL; + + 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); + } + + /* + * delay for power-on to reset-off and min. assertion time + */ + + 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); + } + + /* wait for chips to come up */ + + msleep(50); +} + +static void board_tcpc_init(void) +{ + /* Don't reset TCPCs after initial reset */ + if (!system_jumped_late()) + board_reset_pd_mcu(); + + /* 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); + + /* Enable BC1.2 interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL); + + 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); + gpio_enable_interrupt(GPIO_USB_C1_BC12_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 ((ec_cfg_usb_db_type() != DB_USB_ABSENT) && + 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) && + (ec_cfg_usb_db_type() != DB_USB_ABSENT)) + 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: + if (ec_cfg_usb_db_type() == DB_USB_ABSENT) + break; + 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: + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); + break; + case GPIO_USB_C1_BC12_INT_ODL: + if (ec_cfg_usb_db_type() == DB_USB_ABSENT) + break; + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12); + break; + case GPIO_USB_C2_BC12_INT_ODL: + task_set_event(TASK_ID_USB_CHG_P2, 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: + 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); + break; + default: + break; + } +} + +void retimer_interrupt(enum gpio_signal signal) +{ +} + +__override bool board_is_dts_port(int port) +{ + return port == USBC_PORT_C0; +} + +__override bool board_is_tbt_usb4_port(int port) +{ + 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/draco/usbc_config.h b/board/draco/usbc_config.h new file mode 100644 index 0000000000..512580d704 --- /dev/null +++ b/board/draco/usbc_config.h @@ -0,0 +1,22 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Draco 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 +}; + +void config_usb_db_type(void); + +#endif /* __CROS_EC_USBC_CONFIG_H */ diff --git a/board/draco/vif_override.xml b/board/draco/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/draco/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/drallion_ish/board.c b/board/drallion_ish/board.c index c9a683e36d..fba8a622a9 100644 --- a/board/drallion_ish/board.c +++ b/board/drallion_ish/board.c @@ -61,8 +61,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_lid_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_a_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_ACCEL_GYRO_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = NULL, @@ -91,8 +89,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_lid_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_a_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_ACCEL_GYRO_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/drallion_ish/board.h b/board/drallion_ish/board.h index dab93426a6..53da677775 100644 --- a/board/drallion_ish/board.h +++ b/board/drallion_ish/board.h @@ -60,7 +60,7 @@ #define CONFIG_DMA_PAGING /* Host command over HECI */ -#define CONFIG_HOSTCMD_HECI +#define CONFIG_HOST_INTERFACE_HECI /* I2C ports */ #define I2C_PORT_SENSOR ISH_I2C0 diff --git a/board/dratini/board.h b/board/dratini/board.h index 12074e3447..c23cbd1f2d 100644 --- a/board/dratini/board.h +++ b/board/dratini/board.h @@ -17,7 +17,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 2048 @@ -95,7 +95,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 10 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -122,6 +122,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/drawcia/board.c b/board/drawcia/board.c index 80f93e4d1d..c6c581c436 100644 --- a/board/drawcia/board.c +++ b/board/drawcia/board.c @@ -135,14 +135,30 @@ static void usb_c1_interrupt(enum gpio_signal s) hook_call_deferred(&check_c1_line_data, INT_RECHECK_US); } +static void board_enable_hdmi_hpd(int enable) +{ + enum fw_config_db db = get_cbi_fw_config_db(); + int hdmi_hpd = gpio_get_level(GPIO_VOLUP_BTN_ODL_HDMI_HPD); + + if (db == DB_1A_HDMI || db == DB_LTE_HDMI || db == DB_1A_HDMI_LTE) { + /* Check if we can report HDMI_HPD signal to CPU */ + if (enable) + gpio_set_level(GPIO_EC_AP_USB_C1_HDMI_HPD, hdmi_hpd); + else + gpio_set_level(GPIO_EC_AP_USB_C1_HDMI_HPD, 0); + } +} + static void button_sub_hdmi_hpd_interrupt(enum gpio_signal s) { enum fw_config_db db = get_cbi_fw_config_db(); int hdmi_hpd = gpio_get_level(GPIO_VOLUP_BTN_ODL_HDMI_HPD); - if (db == DB_1A_HDMI || db == DB_LTE_HDMI || db == DB_1A_HDMI_LTE) - gpio_set_level(GPIO_EC_AP_USB_C1_HDMI_HPD, hdmi_hpd); - else + if (db == DB_1A_HDMI || db == DB_LTE_HDMI || db == DB_1A_HDMI_LTE) { + /* Do not report HDMI_HPD signal to CPU when system off. */ + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) + gpio_set_level(GPIO_EC_AP_USB_C1_HDMI_HPD, hdmi_hpd); + } else button_interrupt(s); } @@ -327,8 +343,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -356,8 +370,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -417,6 +429,9 @@ void board_init(void) if (!gpio_get_level(GPIO_PEN_DET_ODL)) gpio_set_level(GPIO_EN_PP5000_PEN, 1); + /* Make sure HDMI_HPD signal can be reported to CPU at sysjump */ + board_enable_hdmi_hpd(1); + /* Charger on the MB will be outputting PROCHOT_ODL and OD CHG_DET */ sm5803_configure_gpio0(CHARGER_PRIMARY, GPIO0_MODE_PROCHOT, 1); sm5803_configure_chg_det_od(CHARGER_PRIMARY, 1); @@ -438,6 +453,9 @@ static void board_resume(void) sm5803_disable_low_power_mode(CHARGER_PRIMARY); if (board_get_charger_chip_count() > 1) sm5803_disable_low_power_mode(CHARGER_SECONDARY); + + /* Enable reporting HDMI_HPD to CPU when system resume */ + board_enable_hdmi_hpd(1); } DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_resume, HOOK_PRIO_DEFAULT); @@ -449,6 +467,13 @@ static void board_suspend(void) } DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_suspend, HOOK_PRIO_DEFAULT); +static void board_shutdown(void) +{ + /* Disable reporting HDMI_HPD to CPU at shutdown */ + board_enable_hdmi_hpd(0); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_shutdown, HOOK_PRIO_DEFAULT); + void board_hibernate(void) { /* diff --git a/board/drawcia_riscv/board.c b/board/drawcia_riscv/board.c index ffa7da0bea..f57bc4e49f 100644 --- a/board/drawcia_riscv/board.c +++ b/board/drawcia_riscv/board.c @@ -328,8 +328,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -357,8 +355,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/drobit/ec.tasklist b/board/drobit/ec.tasklist index 2c9a9e8e32..c1b0295d37 100644 --- a/board/drobit/ec.tasklist +++ b/board/drobit/ec.tasklist @@ -15,6 +15,7 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/duck b/board/duck new file mode 120000 index 0000000000..7f4a914148 --- /dev/null +++ b/board/duck @@ -0,0 +1 @@ +hammer
\ No newline at end of file diff --git a/board/eldrid/ec.tasklist b/board/eldrid/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/eldrid/ec.tasklist +++ b/board/eldrid/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/elemi/ec.tasklist b/board/elemi/ec.tasklist index 2c9a9e8e32..c1b0295d37 100644 --- a/board/elemi/ec.tasklist +++ b/board/elemi/ec.tasklist @@ -15,6 +15,7 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/elm/board.c b/board/elm/board.c index f4f1e3be2e..4e1a680659 100644 --- a/board/elm/board.c +++ b/board/elm/board.c @@ -108,9 +108,21 @@ int anx7688_passthru_allowed(const struct i2c_port_t *port, /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"battery", I2C_PORT_BATTERY, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"pd", I2C_PORT_PD_MCU, 1000, GPIO_I2C1_SCL, GPIO_I2C1_SDA, - anx7688_passthru_allowed} + { + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "pd", + .port = I2C_PORT_PD_MCU, + .kbps = 1000, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA, + .passthru_allowed = anx7688_passthru_allowed + } }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/elm/board.h b/board/elm/board.h index 319241642c..8bb8c2bf15 100644 --- a/board/elm/board.h +++ b/board/elm/board.h @@ -16,6 +16,7 @@ /* Free up flash space */ #undef CONFIG_USB_PD_TCPMV1_DEBUG +#define CONFIG_LTO /* Accelero meter and gyro sensor */ #define CONFIG_ACCEL_KX022 @@ -170,7 +171,7 @@ #define I2C_PORT_TCPC 1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* First SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* First SPI controller port (SPI2) */ /* Timer selection */ #define TIM_CLOCK32 2 diff --git a/board/endeavour/board.c b/board/endeavour/board.c index f208da3819..98d805f60a 100644 --- a/board/endeavour/board.c +++ b/board/endeavour/board.c @@ -85,10 +85,34 @@ const struct mft_t mft_channels[] = { BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); const struct i2c_port_t i2c_ports[] = { - {"pse", I2C_PORT_PSE, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"pmic", I2C_PORT_PMIC, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "pse", + .port = I2C_PORT_PSE, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "pmic", + .port = I2C_PORT_PMIC, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/endeavour/board.h b/board/endeavour/board.h index fd1b3e5b9c..9b0107b2c4 100644 --- a/board/endeavour/board.h +++ b/board/endeavour/board.h @@ -58,7 +58,7 @@ #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/eve/board.c b/board/eve/board.c index f73118e8f2..a972cb4ebc 100644 --- a/board/eve/board.c +++ b/board/eve/board.c @@ -192,11 +192,41 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"accelgyro", I2C_PORT_GYRO, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"sensors", I2C_PORT_LID_ACCEL, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"batt", I2C_PORT_BATTERY, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "accelgyro", + .port = I2C_PORT_GYRO, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "sensors", + .port = I2C_PORT_LID_ACCEL, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "batt", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/eve/board.h b/board/eve/board.h index 64e299bc54..5dcb9fc32f 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -72,7 +72,7 @@ #define CONFIG_CHIPSET_SKYLAKE #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/felwinter/board.c b/board/felwinter/board.c index cd7768d0ea..8eac363159 100644 --- a/board/felwinter/board.c +++ b/board/felwinter/board.c @@ -63,6 +63,13 @@ static void board_chipset_suspend(void) } DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); +/* Called on AP S5 -> S3 transition */ +static void board_chipset_startup(void) +{ + pen_config(); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); + #ifdef CONFIG_CHARGE_RAMP_SW /* @@ -114,5 +121,50 @@ static void board_init(void) if (ec_cfg_usb_mb_type() == MB_USB4_TBT) mb_update_usb4_tbt_config_from_config(); + if (ec_cfg_stylus() == STYLUS_PRSENT) + gpio_enable_interrupt(GPIO_PEN_DET_ODL); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + + +/** + * Deferred function to handle pen detect change + */ +static void pendetect_deferred(void) +{ + static int debounced_pen_detect; + int pen_detect = !gpio_get_level(GPIO_PEN_DET_ODL); + + if (pen_detect == debounced_pen_detect) + return; + + debounced_pen_detect = pen_detect; + + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) + gpio_set_level(GPIO_EN_PP5000_PEN, debounced_pen_detect); +} +DECLARE_DEFERRED(pendetect_deferred); + +void pen_detect_interrupt(enum gpio_signal s) +{ + /* Trigger deferred notification of pen detect change */ + hook_call_deferred(&pendetect_deferred_data, + 500 * MSEC); +} + +void pen_config(void) +{ + if (ec_cfg_stylus() == STYLUS_PRSENT) { + /* Make sure pen detection is triggered or not at resume */ + if (!gpio_get_level(GPIO_PEN_DET_ODL)) + gpio_set_level(GPIO_EN_PP5000_PEN, 1); + else + gpio_set_level(GPIO_EN_PP5000_PEN, 0); + } +} + +static void board_chipset_shutdown(void) +{ + gpio_set_level(GPIO_EN_PP5000_PEN, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); diff --git a/board/felwinter/board.h b/board/felwinter/board.h index 8f7c03dfb7..064ce51e54 100644 --- a/board/felwinter/board.h +++ b/board/felwinter/board.h @@ -10,11 +10,6 @@ #include "compile_time_macros.h" -/* - * Early brya boards are not set up for vivaldi - */ -#undef CONFIG_KEYBOARD_VIVALDI - /* Baseboard features */ #include "baseboard.h" @@ -77,6 +72,9 @@ #define CONFIG_USB_PD_TCPM_PS8815 #define CONFIG_USBC_RETIMER_INTEL_BB +/* I2C control host command */ +#define CONFIG_HOSTCMD_I2C_CONTROL + #define CONFIG_USBC_PPC_SYV682X #define CONFIG_USBC_PPC_NX20P3483 @@ -111,6 +109,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -173,7 +172,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_FANS FAN_CH_COUNT @@ -239,6 +238,10 @@ enum mft_channel { MFT_CH_COUNT }; +void pen_detect_interrupt(enum gpio_signal s); + +void pen_config(void); + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/felwinter/ec.tasklist b/board/felwinter/ec.tasklist index 41d86da3d6..6d995d6b44 100644 --- a/board/felwinter/ec.tasklist +++ b/board/felwinter/ec.tasklist @@ -19,6 +19,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/felwinter/fans.c b/board/felwinter/fans.c index d966056331..9a29f0f1d1 100644 --- a/board/felwinter/fans.c +++ b/board/felwinter/fans.c @@ -30,16 +30,10 @@ static const struct fan_conf fan_conf_0 = { .enable_gpio = GPIO_EN_PP5000_FAN, }; -/* - * TOOD(b/180681346): 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, + .rpm_min = 2000, + .rpm_start = 2000, + .rpm_max = 5200, }; const struct fan_t fans[FAN_CH_COUNT] = { diff --git a/board/felwinter/fw_config.c b/board/felwinter/fw_config.c index d733df3208..4228394d5b 100644 --- a/board/felwinter/fw_config.c +++ b/board/felwinter/fw_config.c @@ -48,3 +48,8 @@ enum ec_cfg_usb_mb_type ec_cfg_usb_mb_type(void) { return fw_config.usb_mb; } + +enum ec_cfg_stylus_type ec_cfg_stylus(void) +{ + return fw_config.stylus; +} diff --git a/board/felwinter/fw_config.h b/board/felwinter/fw_config.h index fb5c374b5d..5f5f956b61 100644 --- a/board/felwinter/fw_config.h +++ b/board/felwinter/fw_config.h @@ -29,11 +29,16 @@ enum ec_cfg_usb_mb_type { MB_USB3_NON_TBT = 1 }; +enum ec_cfg_stylus_type { + STYLUS_ABSENT = 0, + STYLUS_PRSENT = 1 +}; + union brya_cbi_fw_config { struct { enum ec_cfg_usb_db_type usb_db : 3; uint32_t wifi : 2; - uint32_t stylus : 1; + enum ec_cfg_stylus_type stylus : 1; enum ec_cfg_keyboard_backlight_type kb_bl : 1; uint32_t audio : 3; uint32_t thermal : 2; @@ -66,3 +71,10 @@ enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void); enum ec_cfg_usb_mb_type ec_cfg_usb_mb_type(void); #endif /* __BOARD_BRYA_FW_CONFIG_H_ */ + +/** + * Get the stylus type from FW_CONFIG. + * + * @return the stylus type. + */ +enum ec_cfg_stylus_type ec_cfg_stylus(void); diff --git a/board/felwinter/gpio.inc b/board/felwinter/gpio.inc index ba7116847a..86f71a9ea3 100644 --- a/board/felwinter/gpio.inc +++ b/board/felwinter/gpio.inc @@ -31,6 +31,7 @@ GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert 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(PEN_DET_ODL, PIN(D, 4), GPIO_INT_BOTH, pen_detect_interrupt) /* USED GPIOs: */ GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) @@ -67,6 +68,7 @@ GPIO(EC_PCH_WAKE_R_ODL, PIN(C, 0), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH) GPIO(EN_PP5000_USBA_R, PIN(D, 7), GPIO_OUT_LOW) +GPIO(EN_PP5000_PEN, PIN(E, 1), GPIO_OUT_LOW) 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) @@ -124,11 +126,10 @@ UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */ UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */ UNUSED(PIN(6, 6)) /* GPIO66 */ UNUSED(PIN(C, 3)) /* GPIOC3 */ -UNUSED(PIN(E, 1)) /* GPIOE1 */ -UNUSED(PIN(D, 4)) /* GPIOD4 */ UNUSED(PIN(C, 6)) /* GPIOC6 */ UNUSED(PIN(6, 2)) /* GPIO62 */ UNUSED(PIN(B, 1)) /* GPIOB1 */ +UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ /* Pre-configured PSL balls: J8 K6 */ @@ -143,7 +144,9 @@ GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) /* GPIO02_P2 to PU */ /* GPIO03_P2 to PU */ +IOEX(USB_C1_RT_RST_ODL, EXPIN(IOEX_C1_NCT38XX, 0, 2), GPIO_ODR_LOW) IOEX(USB_C1_OC_ODL, EXPIN(IOEX_C1_NCT38XX, 0, 4), GPIO_ODR_HIGH) +IOEX(USB_C1_FRS_EN, EXPIN(IOEX_C1_NCT38XX, 0, 6), GPIO_LOW) IOEX(USB_C2_RT_RST_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 2), GPIO_ODR_LOW) IOEX(USB_C2_OC_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 4), GPIO_ODR_HIGH) diff --git a/board/felwinter/i2c.c b/board/felwinter/i2c.c index b54cc98de8..a850c12544 100644 --- a/board/felwinter/i2c.c +++ b/board/felwinter/i2c.c @@ -49,6 +49,7 @@ const struct i2c_port_t i2c_ports[] = { .kbps = 400, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, }, { /* I2C5 */ diff --git a/board/felwinter/pwm.c b/board/felwinter/pwm.c index 985305449b..1312135a2c 100644 --- a/board/felwinter/pwm.c +++ b/board/felwinter/pwm.c @@ -24,8 +24,8 @@ const struct pwm_t pwm_channels[] = { }, [PWM_CH_FAN] = { .channel = 5, - .flags = PWM_CONFIG_OPEN_DRAIN, - .freq = 25000 + .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP, + .freq = 1000 }, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/felwinter/sensors.c b/board/felwinter/sensors.c index b25d39f136..437fc8bcde 100644 --- a/board/felwinter/sensors.c +++ b/board/felwinter/sensors.c @@ -68,10 +68,8 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lis2dw12_drv, .mutex = &g_lid_accel_mutex, .drv_data = &g_lis2dw12_data, - .int_signal = GPIO_EC_ACCEL_INT_R_L, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LIS2DW12_ADDR0, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .rot_standard_ref = &lid_standard_ref, /* identity matrix */ .default_range = 2, /* g */ .min_frequency = LIS2DW12_ODR_MIN_VAL, @@ -98,8 +96,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -128,8 +124,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/felwinter/usbc_config.c b/board/felwinter/usbc_config.c index bb2e6c2218..5fa144e364 100644 --- a/board/felwinter/usbc_config.c +++ b/board/felwinter/usbc_config.c @@ -56,7 +56,8 @@ struct tcpc_config_t tcpc_config[] = { }, .drv = &ps8xxx_tcpm_drv, .flags = TCPC_FLAGS_TCPCI_REV2_0 | - TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V, + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, }, }; BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); @@ -210,7 +211,7 @@ __override int bb_retimer_power_enable(const struct usb_mux *me, bool enable) int rst_signal; if (me->usb_port == USBC_PORT_C1) - rst_signal = GPIO_USB_C1_RT_RST_R_ODL; + rst_signal = IOEX_USB_C1_RT_RST_ODL; else if (me->usb_port == USBC_PORT_C2) rst_signal = IOEX_USB_C2_RT_RST_ODL; else diff --git a/board/fennel/board.c b/board/fennel/board.c index 0706813592..3335c80240 100644 --- a/board/fennel/board.c +++ b/board/fennel/board.c @@ -68,13 +68,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -140,8 +159,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/fennel/board.h b/board/fennel/board.h index 697480770c..dc73b2e132 100644 --- a/board/fennel/board.h +++ b/board/fennel/board.h @@ -91,7 +91,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/fizz/board.c b/board/fizz/board.c index 5b830b9150..975401d5a1 100644 --- a/board/fizz/board.c +++ b/board/fizz/board.c @@ -164,11 +164,41 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"tcpc", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"eeprom", NPCX_I2C_PORT0_1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"charger", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"pmic", NPCX_I2C_PORT2, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", NPCX_I2C_PORT3, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "eeprom", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "charger", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "pmic", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = NPCX_I2C_PORT3, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/fizz/board.h b/board/fizz/board.h index 8e8cbcd823..ad1ca85cac 100644 --- a/board/fizz/board.h +++ b/board/fizz/board.h @@ -70,7 +70,7 @@ #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/fleex/board.c b/board/fleex/board.c index 7e11d671c6..4464d45730 100644 --- a/board/fleex/board.c +++ b/board/fleex/board.c @@ -199,8 +199,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -231,8 +229,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/foob/board.c b/board/foob/board.c index 3e7725ac2e..91d66d88d7 100644 --- a/board/foob/board.c +++ b/board/foob/board.c @@ -144,8 +144,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &standard_rot_ref, @@ -176,8 +174,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/fusb307bgevb/board.c b/board/fusb307bgevb/board.c index 41b12d5a82..f3f4da1a74 100644 --- a/board/fusb307bgevb/board.c +++ b/board/fusb307bgevb/board.c @@ -241,7 +241,13 @@ BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); * I2C interface. */ const struct i2c_port_t i2c_ports[] = { - {"tcpc", I2C_PORT_TCPC, 400 /* kHz */, GPIO_I2C2_SCL, GPIO_I2C2_SDA} + { + .name = "tcpc", + .port = I2C_PORT_TCPC, + .kbps = 400 /* kHz */, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + } }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/genesis/board.c b/board/genesis/board.c index a846478ecb..5305c8d630 100644 --- a/board/genesis/board.c +++ b/board/genesis/board.c @@ -133,12 +133,48 @@ const struct pwm_t pwm_channels[] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"pse", I2C_PORT_PSE, 400, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "pse", + .port = I2C_PORT_PSE, + .kbps = 400, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/genesis/board.h b/board/genesis/board.h index 7c32579440..9c9233590e 100644 --- a/board/genesis/board.h +++ b/board/genesis/board.h @@ -38,7 +38,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -103,7 +103,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -217,6 +217,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/genesis/gpio.inc b/board/genesis/gpio.inc index 6a905fdf04..d8f2989b8e 100644 --- a/board/genesis/gpio.inc +++ b/board/genesis/gpio.inc @@ -58,7 +58,7 @@ GPIO_INT(USB_A3_OC_ODL, PIN(0, 3), GPIO_INT_BOTH, port_ocp_interrupt) GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) diff --git a/board/gimble/board.h b/board/gimble/board.h index 96c8e6326d..561dfddab1 100644 --- a/board/gimble/board.h +++ b/board/gimble/board.h @@ -77,6 +77,12 @@ #define PD_POWER_SUPPLY_TURN_OFF_DELAY 30000 /* us */ #define PD_VCONN_SWAP_DELAY 5000 /* us */ +/* I2C speed console command */ +#define CONFIG_CMD_I2C_SPEED + +/* I2C control host command */ +#define CONFIG_HOSTCMD_I2C_CONTROL + /* * Passive USB-C cables only support up to 60W. */ @@ -103,6 +109,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -164,7 +171,7 @@ #define CONFIG_FANS FAN_CH_COUNT #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* LED defines */ @@ -184,6 +191,7 @@ #define CONFIG_CHARGE_RAMP_SW #define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR 10 #define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR_AC 10 +#define CONFIG_CHARGER_BQ25710_PSYS_SENSING /* PROCHOT defines */ #define BATT_MAX_CONTINUE_DISCHARGE_WATT 45 diff --git a/board/gimble/ec.tasklist b/board/gimble/ec.tasklist index 23753ee899..9207f8729d 100644 --- a/board/gimble/ec.tasklist +++ b/board/gimble/ec.tasklist @@ -19,6 +19,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/gimble/gpio.inc b/board/gimble/gpio.inc index faec39af08..dfd3b472a6 100644 --- a/board/gimble/gpio.inc +++ b/board/gimble/gpio.inc @@ -125,6 +125,7 @@ UNUSED(PIN(A, 0)) /* F_CS0_L/GPIOA0 */ UNUSED(PIN(9, 6)) /* F_DIO1/GPIO96 */ UNUSED(PIN(7, 0)) /* GPIO70/PS2_DAT0 */ UNUSED(PIN(8, 1)) /* PECI DATA/GPIO81 */ +UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/gimble/i2c.c b/board/gimble/i2c.c index ed763fffca..7bedcc05db 100644 --- a/board/gimble/i2c.c +++ b/board/gimble/i2c.c @@ -18,14 +18,10 @@ const struct i2c_port_t i2c_ports[] = { .sda = GPIO_EC_I2C_SENSOR_SDA, }, { - /* I2C1 - * TODO(b/194264003) Need to check the signals with a scope - * before raising to 1MHz. - */ /* I2C1 */ .name = "tcpc0", .port = I2C_PORT_USB_C0_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C0_C2_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C0_C2_TCPC_SDA, }, @@ -38,16 +34,13 @@ const struct i2c_port_t i2c_ports[] = { .sda = GPIO_EC_I2C_USB_C0_C2_PPC_BC_SDA, }, { - /* I2C4 - * TODO(b/194264003) Need to check the signals with a scope - * before raising to 1MHz. - */ /* I2C4 C1 TCPC */ .name = "tcpc1", .port = I2C_PORT_USB_C1_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, }, { /* I2C5 */ diff --git a/board/gimble/led.c b/board/gimble/led.c index 924aa53aff..4dc4e81759 100644 --- a/board/gimble/led.c +++ b/board/gimble/led.c @@ -33,12 +33,12 @@ __override struct led_descriptor [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, [STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} }, - [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, [STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} }, [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, [STATE_BATTERY_ERROR] = { - {EC_LED_COLOR_WHITE, 0.5 * LED_ONE_SEC}, + {EC_LED_COLOR_AMBER, 0.5 * LED_ONE_SEC}, {LED_OFF, 0.5 * LED_ONE_SEC} }, [STATE_FACTORY_TEST] = { diff --git a/board/gimble/sensors.c b/board/gimble/sensors.c index 07f18950f0..1620f3c348 100644 --- a/board/gimble/sensors.c +++ b/board/gimble/sensors.c @@ -206,8 +206,6 @@ struct motion_sensor_t lsm6dsm_base_accel = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref_id_1, @@ -236,8 +234,6 @@ struct motion_sensor_t lsm6dsm_base_gyro = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/gimble/usbc_config.c b/board/gimble/usbc_config.c index 312f735003..189f6419cf 100644 --- a/board/gimble/usbc_config.c +++ b/board/gimble/usbc_config.c @@ -55,7 +55,8 @@ const struct tcpc_config_t tcpc_config[] = { }, .drv = &ps8xxx_tcpm_drv, .flags = TCPC_FLAGS_TCPCI_REV2_0 | - TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V, + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, }, }; BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); diff --git a/board/gingerbread/board.c b/board/gingerbread/board.c index 6a2ae0c683..b32ed85459 100644 --- a/board/gingerbread/board.c +++ b/board/gingerbread/board.c @@ -152,6 +152,20 @@ struct ppc_config_t ppc_chips[] = { #endif #ifdef SECTION_IS_RW + +/* TUSB1064 set mux board tuning for DP Rx path */ +static int board_tusb1064_dp_rx_eq_set(const struct usb_mux *me, + mux_state_t mux_state) +{ + int rv = EC_SUCCESS; + + /* DP specific config */ + if (mux_state & USB_PD_MUX_DP_ENABLED) + rv = tusb1064_set_dp_rx_eq(me, TUSB1064_DP_EQ_RX_8_9_DB); + + return rv; +} + /* * TCPCs: 2 USBC/PD ports * port 0 -> host port -> STM32G4 UCPD @@ -178,6 +192,7 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_port = I2C_PORT_I2C1, .i2c_addr_flags = TUSB1064_I2C_ADDR0_FLAGS, .driver = &tusb1064_usb_mux_driver, + .board_set = &board_tusb1064_dp_rx_eq_set, }, [USB_PD_PORT_DP] = { .usb_port = USB_PD_PORT_DP, @@ -311,12 +326,46 @@ int dock_get_mf_preference(void) return mf; } +static void board_usb_tc_connect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* + * The EC needs to keep the USB hubs in reset until the host port is + * attached so that the USB-EP can be properly enumerated. + */ + if (port == USB_PD_PORT_HOST) { + gpio_set_level(GPIO_EC_HUB1_RESET_L, 1); + gpio_set_level(GPIO_EC_HUB2_RESET_L, 1); + } +} +DECLARE_HOOK(HOOK_USB_PD_CONNECT, board_usb_tc_connect, HOOK_PRIO_DEFAULT); + +static void board_usb_tc_disconnect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* Only the host port disconnect is relevant */ + if (port == USB_PD_PORT_HOST) { + gpio_set_level(GPIO_EC_HUB1_RESET_L, 0); + gpio_set_level(GPIO_EC_HUB2_RESET_L, 0); + } +} +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, board_usb_tc_disconnect, \ + HOOK_PRIO_DEFAULT); + #endif /* SECTION_IS_RW */ static void board_init(void) { #ifdef SECTION_IS_RW - + /* + * Set current limit for USB 3.1 Gen 2 ports to 1.5 A. Note, this is + * also done in gpio.inc, but needs to be in RW for platforms which + * shipped with RO that set these 2 lines to the 900 mA level. + */ + gpio_set_level(GPIO_USB3_P3_CDP_EN, 1); + gpio_set_level(GPIO_USB3_P4_CDP_EN, 1); #endif } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); diff --git a/board/gingerbread/gpio.inc b/board/gingerbread/gpio.inc index 5b7b3a9619..6226ff747e 100644 --- a/board/gingerbread/gpio.inc +++ b/board/gingerbread/gpio.inc @@ -57,8 +57,8 @@ GPIO(DEBUG_GPIO1, PIN(B, 13), GPIO_OUT_LOW) * USB CDP enables. */ GPIO(USB3_A1_CDP_EN, PIN(E, 7), GPIO_OUT_LOW) GPIO(USB3_A2_CDP_EN, PIN(E, 8), GPIO_OUT_LOW) -GPIO(USB3_P3_CDP_EN, PIN(D, 1), GPIO_OUT_LOW) -GPIO(USB3_P4_CDP_EN, PIN(E, 12), GPIO_OUT_LOW) +GPIO(USB3_P3_CDP_EN, PIN(D, 1), GPIO_OUT_HIGH) +GPIO(USB3_P4_CDP_EN, PIN(E, 12), GPIO_OUT_HIGH) /* Write protect */ GPIO(EC_FLASH_WP_ODL, PIN(A, 3), GPIO_ODR_HIGH) diff --git a/board/gooey/board.c b/board/gooey/board.c index 518e159f9d..0f610400b6 100644 --- a/board/gooey/board.c +++ b/board/gooey/board.c @@ -412,8 +412,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -441,8 +439,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/goroh/gpio.inc b/board/goroh/gpio.inc index fe454d035e..9d10ea37bd 100644 --- a/board/goroh/gpio.inc +++ b/board/goroh/gpio.inc @@ -81,8 +81,8 @@ GPIO(EN_PP1800_VDDIO_PMC_X, PIN(B, 7), GPIO_OUT_LOW) GPIO(EC_INT_L, PIN(E, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_AP_INT_ODL */ /* USB and USBC Signals */ -GPIO(USB_C0_HPD_3V3, PIN(J, 0), GPIO_OUT_LOW) -GPIO(USB_C1_HPD_3V3, PIN(J, 1), GPIO_OUT_LOW) +GPIO(USB_C1_HPD_3V3, PIN(J, 0), GPIO_OUT_LOW) +GPIO(USB_C0_HPD_3V3, PIN(J, 1), GPIO_OUT_LOW) GPIO(USB_C1_HPD_IN, PIN(J, 2), GPIO_OUT_LOW) GPIO(EN_USB_C1_MUX_PWR, PIN(F, 0), GPIO_OUT_LOW) GPIO(USB_C0_SBU1_DC, PIN(H, 4), GPIO_OUT_LOW) diff --git a/board/grunt/board.c b/board/grunt/board.c index 45aa4f4421..0efa8b9696 100644 --- a/board/grunt/board.c +++ b/board/grunt/board.c @@ -29,12 +29,48 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"kblight", I2C_PORT_KBLIGHT, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "kblight", + .port = I2C_PORT_KBLIGHT, + .kbps = 100, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/gumboz/board.c b/board/gumboz/board.c index 4428819415..fb4fdcee95 100644 --- a/board/gumboz/board.c +++ b/board/gumboz/board.c @@ -103,8 +103,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ @@ -135,8 +133,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/guybrush/board.c b/board/guybrush/board.c index 75fb5a8607..922be3ca21 100644 --- a/board/guybrush/board.c +++ b/board/guybrush/board.c @@ -288,10 +288,10 @@ __override int board_c1_ps8818_mux_set(const struct usb_mux *me, return rv; /* Enable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 1); + ioex_set_level(IOEX_USB_C1_IN_HPD, 1); } else { /* Disable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 0); + ioex_set_level(IOEX_USB_C1_IN_HPD, 0); } return rv; diff --git a/board/guybrush/board.h b/board/guybrush/board.h index f3900adc43..dc6a7e882a 100644 --- a/board/guybrush/board.h +++ b/board/guybrush/board.h @@ -55,6 +55,9 @@ #define CONFIG_LED_COMMON #define CONFIG_LED_ONOFF_STATES +/* Thermal Config */ +#define CONFIG_TEMP_SENSOR_TMP112 + #ifndef __ASSEMBLER__ #include "gpio_signal.h" diff --git a/board/guybrush/build.mk b/board/guybrush/build.mk index 5c8bde1a2b..a7865db889 100644 --- a/board/guybrush/build.mk +++ b/board/guybrush/build.mk @@ -9,4 +9,4 @@ BASEBOARD:=guybrush board-y=board.o -board-y+=board_fw_config.o led.o battery.o +board-y+=board_fw_config.o led.o battery.o thermal.o diff --git a/board/guybrush/thermal.c b/board/guybrush/thermal.c new file mode 100644 index 0000000000..606d21cfdf --- /dev/null +++ b/board/guybrush/thermal.c @@ -0,0 +1,34 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Guybrush board-specific configuration */ + +#include "console.h" +#include "fan.h" +#include "thermal.h" +#include "util.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_THERMAL, outstr) +#define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) + +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_S0_PGOOD, + .enable_gpio = -1, +}; +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 6500, +}; +const struct fan_t fans[] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); diff --git a/board/haboki/board.c b/board/haboki/board.c index f748cf90a6..84e22390e0 100644 --- a/board/haboki/board.c +++ b/board/haboki/board.c @@ -327,8 +327,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -356,8 +354,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/hammer/board.c b/board/hammer/board.c index b68498acfb..ad525f9e67 100644 --- a/board/hammer/board.c +++ b/board/hammer/board.c @@ -60,6 +60,7 @@ const void *const usb_strings[] = { [USB_STR_SERIALNO] = 0, [USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_SECTION ":" CROS_EC_VERSION32), + [USB_STR_SPI_NAME] = USB_STRING_DESC("SPI"), [USB_STR_I2C_NAME] = USB_STRING_DESC("I2C"), [USB_STR_UPDATE_NAME] = USB_STRING_DESC("Firmware update"), #ifdef CONFIG_USB_ISOCHRONOUS @@ -90,11 +91,21 @@ void usb_spi_board_disable(struct usb_spi_config const *config) {} #ifdef CONFIG_I2C /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 400, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 400, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, #ifdef BOARD_WAND - {"charger", I2C_PORT_CHARGER, 100, - GPIO_CHARGER_I2C_SCL, GPIO_CHARGER_I2C_SDA}, + { + .name = "charger", + .port = I2C_PORT_CHARGER, + .kbps = 100, + .scl = GPIO_CHARGER_I2C_SCL, + .sda = GPIO_CHARGER_I2C_SDA + }, #endif }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -362,6 +373,23 @@ static const struct ec_response_keybd_config bland_kb = { .capabilities = KEYBD_CAP_SCRNLOCK_KEY, }; +static const struct ec_response_keybd_config duck_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, + TK_FORWARD, + TK_REFRESH, + TK_FULLSCREEN, + TK_OVERVIEW, + TK_BRIGHTNESS_DOWN, + TK_BRIGHTNESS_UP, + TK_VOL_MUTE, + TK_VOL_DOWN, + TK_VOL_UP, + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + __override const struct ec_response_keybd_config *board_vivaldi_keybd_config(void) { @@ -369,6 +397,8 @@ const struct ec_response_keybd_config *board_vivaldi_keybd_config(void) return &zed_kb; if (IS_ENABLED(BOARD_BLAND) || IS_ENABLED(BOARD_EEL)) return &bland_kb; + if (IS_ENABLED(BOARD_DUCK)) + return &duck_kb; return NULL; } diff --git a/board/hammer/board.h b/board/hammer/board.h index 3282425d9e..dd5d8d1507 100644 --- a/board/hammer/board.h +++ b/board/hammer/board.h @@ -338,6 +338,7 @@ enum usb_strings { USB_STR_PRODUCT, USB_STR_SERIALNO, USB_STR_VERSION, + USB_STR_SPI_NAME, USB_STR_I2C_NAME, USB_STR_UPDATE_NAME, #ifdef CONFIG_USB_ISOCHRONOUS diff --git a/board/hammer/variants.h b/board/hammer/variants.h index 2a8c831ef5..5d928295ac 100644 --- a/board/hammer/variants.h +++ b/board/hammer/variants.h @@ -19,6 +19,8 @@ #define CONFIG_USB_PID 0x5056 #elif defined(BOARD_DON) #define CONFIG_USB_PID 0x5050 +#elif defined(BOARD_DUCK) +#define CONFIG_USB_PID 0x505b #elif defined(BOARD_EEL) #define CONFIG_USB_PID 0x5057 #elif defined(BOARD_MAGNEMITE) @@ -56,12 +58,11 @@ #define CONFIG_USB_HID_KEYBOARD_VIVALDI #define CONFIG_USB_HID_KB_NUM_TOP_ROW_KEYS 10 #define HAS_I2C_TOUCHPAD -/* TODO: update correct parameters */ -#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X 3282 -#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y 1793 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X 2644 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y 1440 #define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_PRESSURE 511 -#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 1042 /* tenth of mm */ -#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 569 /* tenth of mm */ +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 839 /* tenth of mm */ +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 457 /* tenth of mm */ #define CONFIG_TOUCHPAD_VIRTUAL_SIZE (64*1024) #elif defined(BOARD_DON) #define HAS_I2C_TOUCHPAD @@ -71,17 +72,27 @@ #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 929 /* tenth of mm */ #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 457 /* tenth of mm */ #define CONFIG_TOUCHPAD_VIRTUAL_SIZE (56*1024) -#elif defined(BOARD_EEL) +#elif defined(BOARD_DUCK) #define CONFIG_USB_HID_KEYBOARD_VIVALDI #define CONFIG_USB_HID_KB_NUM_TOP_ROW_KEYS 10 +/* b/208588161: update correct parameters */ #define HAS_I2C_TOUCHPAD -/* TODO: update correct parameters */ #define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X 3282 #define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y 1793 #define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_PRESSURE 511 #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 1042 /* tenth of mm */ #define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 569 /* tenth of mm */ #define CONFIG_TOUCHPAD_VIRTUAL_SIZE (64*1024) +#elif defined(BOARD_EEL) +#define CONFIG_USB_HID_KEYBOARD_VIVALDI +#define CONFIG_USB_HID_KB_NUM_TOP_ROW_KEYS 10 +#define HAS_I2C_TOUCHPAD +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X 2644 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y 1440 +#define CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_PRESSURE 511 +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X 839 /* tenth of mm */ +#define CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y 457 /* tenth of mm */ +#define CONFIG_TOUCHPAD_VIRTUAL_SIZE (64*1024) #elif defined(BOARD_MAGNEMITE) #define HAS_NO_TOUCHPAD #elif defined(BOARD_MASTERBALL) diff --git a/board/hatch/board.h b/board/hatch/board.h index 487c8c25eb..dd573212cd 100644 --- a/board/hatch/board.h +++ b/board/hatch/board.h @@ -16,7 +16,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -89,7 +89,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -116,6 +116,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/hatch_fp/board_rw.c b/board/hatch_fp/board_rw.c index 4c83c8723c..00a6b89b19 100644 --- a/board/hatch_fp/board_rw.c +++ b/board/hatch_fp/board_rw.c @@ -35,7 +35,9 @@ static void configure_fp_sensor_spi(void) /* Configure SPI GPIOs */ gpio_config_module(MODULE_SPI_CONTROLLER, 1); - /* Set all SPI master signal pins to very high speed: B12/13/14/15 */ + /* Set all SPI controller signal pins to very high speed: + * B12/13/14/15 + */ STM32_GPIO_OSPEEDR(GPIO_B) |= 0xff000000; /* Enable clocks to SPI2 module (master) */ diff --git a/board/helios/board.h b/board/helios/board.h index dcda6e01fe..fa65957ecc 100644 --- a/board/helios/board.h +++ b/board/helios/board.h @@ -16,7 +16,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -73,7 +73,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -95,6 +95,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/herobrine_npcx9/board.c b/board/herobrine_npcx9/board.c index f63f5c7991..fea8bf3a88 100644 --- a/board/herobrine_npcx9/board.c +++ b/board/herobrine_npcx9/board.c @@ -64,18 +64,48 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"rtc", I2C_PORT_RTC, 400, GPIO_EC_I2C_RTC_SCL, - GPIO_EC_I2C_RTC_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "rtc", + .port = I2C_PORT_RTC, + .kbps = 400, + .scl = GPIO_EC_I2C_RTC_SCL, + .sda = GPIO_EC_I2C_RTC_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/hoho/board.h b/board/hoho/board.h index 8e6ec34b3d..635abfbeda 100644 --- a/board/hoho/board.h +++ b/board/hoho/board.h @@ -24,7 +24,7 @@ #define CONFIG_RWSIG #define CONFIG_RWSIG_TYPE_USBPD1 #define CONFIG_SHA256 -/* TODO(tbroch) Re-enable once STM spi master can be inhibited at boot so it +/* TODO(tbroch) Re-enable once STM spi controller can be inhibited at boot so it doesn't interfere with HDMI loading its f/w */ #undef CONFIG_SPI_FLASH #define CONFIG_SPI_CS_GPIO GPIO_PD_MCDP_SPI_CS_L diff --git a/board/homestar/board.c b/board/homestar/board.c index 47ac34af2c..6fb748e168 100644 --- a/board/homestar/board.c +++ b/board/homestar/board.c @@ -119,16 +119,41 @@ static void switchcap_interrupt(enum gpio_signal signal) /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/homestar/build.mk b/board/homestar/build.mk index 74b6b95e4d..452abeb591 100644 --- a/board/homestar/build.mk +++ b/board/homestar/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o base_detect.o +board-y=battery.o board.o led.o base_detect.o usbc_config.o diff --git a/board/homestar/usbc_config.c b/board/homestar/usbc_config.c new file mode 100644 index 0000000000..8f3fb02c30 --- /dev/null +++ b/board/homestar/usbc_config.c @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "usb_pd.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/host/board.c b/board/host/board.c index 191fd832e1..b681ca98fb 100644 --- a/board/host/board.c +++ b/board/host/board.c @@ -62,15 +62,45 @@ test_mockable void fps_event(enum gpio_signal signal) /* I2C ports */ const struct i2c_port_t i2c_ports[] = { #ifdef I2C_PORT_BATTERY - {"battery", I2C_PORT_BATTERY, 100, 0, 0}, + { + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = 0, + .sda = 0 + }, #elif defined I2C_PORT_LIGHTBAR - {"lightbar", I2C_PORT_LIGHTBAR, 100, 0, 0}, + { + .name = "lightbar", + .port = I2C_PORT_LIGHTBAR, + .kbps = 100, + .scl = 0, + .sda = 0 + }, #elif defined I2C_PORT_HOST_TCPC - {"tcpc", I2C_PORT_HOST_TCPC, 100, 0, 0}, + { + .name = "tcpc", + .port = I2C_PORT_HOST_TCPC, + .kbps = 100, + .scl = 0, + .sda = 0 + }, #elif defined I2C_PORT_EEPROM - {"eeprom", I2C_PORT_EEPROM, 100, 0, 0}, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 100, + .scl = 0, + .sda = 0 + }, #elif defined I2C_PORT_WLC - {"wlc", I2C_PORT_WLC, 100, 0, 0}, + { + .name = "wlc", + .port = I2C_PORT_WLC, + .kbps = 100, + .scl = 0, + .sda = 0 + }, #endif }; diff --git a/board/icarus/board.c b/board/icarus/board.c index bffad091fa..a95b94c8c9 100644 --- a/board/icarus/board.c +++ b/board/icarus/board.c @@ -87,9 +87,27 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"other", IT83XX_I2C_CH_B, 100, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"battery", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, + { + .name = "typec", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C_C_SCL, + .sda = GPIO_I2C_C_SDA + }, + { + .name = "other", + .port = IT83XX_I2C_CH_B, + .kbps = 100, + .scl = GPIO_I2C_B_SCL, + .sda = GPIO_I2C_B_SDA + }, + { + .name = "battery", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C_A_SCL, + .sda = GPIO_I2C_A_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -122,8 +140,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/it83xx_evb/gpio.inc b/board/it83xx_evb/gpio.inc index 52df89e5cb..505f91ad64 100644 --- a/board/it83xx_evb/gpio.inc +++ b/board/it83xx_evb/gpio.inc @@ -9,7 +9,7 @@ * Note: Those with interrupt handlers must be declared first. */ GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(PCH_PLTRST_L, PIN(E, 3), GPIO_INT_BOTH | GPIO_PULL_UP, lpcrst_interrupt) #endif GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH | GPIO_PULL_DOWN, lid_interrupt) diff --git a/board/it8xxx2_evb/gpio.inc b/board/it8xxx2_evb/gpio.inc index 8a7f593ab6..e5e7d5e942 100644 --- a/board/it8xxx2_evb/gpio.inc +++ b/board/it8xxx2_evb/gpio.inc @@ -9,7 +9,7 @@ * Note: Those with interrupt handlers must be declared first. */ GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(PCH_PLTRST_L, PIN(E, 3), GPIO_INT_BOTH | GPIO_PULL_UP, lpcrst_interrupt) #endif GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH | GPIO_PULL_UP, lid_interrupt) diff --git a/board/it8xxx2_pdevb/board.h b/board/it8xxx2_pdevb/board.h index 8646c6c7b3..d23898f3aa 100644 --- a/board/it8xxx2_pdevb/board.h +++ b/board/it8xxx2_pdevb/board.h @@ -31,7 +31,7 @@ #undef CONFIG_SPI_CONTROLLER #undef CONFIG_SPI_FLASH_PORT #undef CONFIG_UART_HOST -#undef CONFIG_HOSTCMD_LPC +#undef CONFIG_HOST_INTERFACE_LPC #undef CONFIG_CMD_MMAPINFO #undef CONFIG_SWITCH diff --git a/board/jacuzzi/board.c b/board/jacuzzi/board.c index ec6515544d..4563bc2f2c 100644 --- a/board/jacuzzi/board.c +++ b/board/jacuzzi/board.c @@ -67,17 +67,42 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, #ifdef BOARD_JACUZZI - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, #else /* Juniper */ - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, #endif }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -143,8 +168,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. @@ -291,6 +320,9 @@ static void board_spi_disable(void) /* Set pins to a state calming the sensor down. */ gpio_set_flags(GPIO_EC_SENSOR_SPI_CK, GPIO_OUT_LOW); gpio_set_level(GPIO_EC_SENSOR_SPI_CK, 0); + /* Pull SPI_NSS pin to low to prevent a leakage. */ + gpio_set_flags(GPIO_EC_SENSOR_SPI_NSS, GPIO_OUT_LOW); + gpio_set_level(GPIO_EC_SENSOR_SPI_NSS, 0); gpio_config_module(MODULE_SPI_CONTROLLER, 0); /* Disable spi peripheral and clocks. */ diff --git a/board/jacuzzi/board.h b/board/jacuzzi/board.h index ef8a02a3dc..6270b308f6 100644 --- a/board/jacuzzi/board.h +++ b/board/jacuzzi/board.h @@ -102,7 +102,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/jinlon/board.h b/board/jinlon/board.h index 944413591b..c071bfc144 100644 --- a/board/jinlon/board.h +++ b/board/jinlon/board.h @@ -19,7 +19,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -100,7 +100,7 @@ #define CONFIG_FAN_INIT_SPEED 50 #define RPM_DEVIATION 1 #define CONFIG_TEMP_SENSOR_OTI502 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -127,6 +127,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/jslrvp_ite/gpio.inc b/board/jslrvp_ite/gpio.inc index 5c0219263e..387020100e 100644 --- a/board/jslrvp_ite/gpio.inc +++ b/board/jslrvp_ite/gpio.inc @@ -37,7 +37,7 @@ GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING, uart_deepsleep_interrupt) /* UAR GPIO_INT(WP_L, PIN(I, 4), GPIO_INT_BOTH, switch_interrupt) /* EC_WP_ODL */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ #endif @@ -72,7 +72,7 @@ UNIMPLEMENTED(EN_VCCIO_EXT) /* Host communication GPIOs */ GPIO(PCH_WAKE_L, PIN(J, 0), GPIO_ODR_HIGH) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(PCH_PLTRST_L, PIN(E, 3), GPIO_INPUT | GPIO_PULL_UP) #endif @@ -139,7 +139,7 @@ GPIO(NC_PMIC_EN, PIN(H, 3), GPIO_INPUT) /* Used if Base EC is present */ GPIO(NC_EC_BASE_DET, PIN(I, 3), GPIO_INPUT) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INPUT) #endif diff --git a/board/kakadu/board.c b/board/kakadu/board.c index 8d91d06832..89905aa4a3 100644 --- a/board/kakadu/board.c +++ b/board/kakadu/board.c @@ -71,8 +71,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -108,8 +120,12 @@ struct mt6370_thermal_bound thermal_bound = { }; static void board_hpd_update(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. @@ -519,3 +535,18 @@ void board_fill_source_power_info(int port, r->meas.current_lim = 1500; r->max_power = r->meas.voltage_now * r->meas.current_max; } + +/* b/207456334: bugged reserved bits causes device not charging */ +static void mt6370_reg_fix(void) +{ + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT946X_REG_CHGCTRL1, + BIT(3) | BIT(5), MASK_CLR); + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT946X_REG_CHGCTRL2, + BIT(5) | BIT(RT946X_SHIFT_BATDET_DIS_DLY), + MASK_CLR); +} +DECLARE_HOOK(HOOK_INIT, mt6370_reg_fix, HOOK_PRIO_DEFAULT); diff --git a/board/kano/board.h b/board/kano/board.h index 6b65edf174..4ed3d3f885 100644 --- a/board/kano/board.h +++ b/board/kano/board.h @@ -3,18 +3,13 @@ * found in the LICENSE file. */ -/* Brya board configuration */ +/* Kano board configuration */ #ifndef __CROS_EC_BOARD_H #define __CROS_EC_BOARD_H #include "compile_time_macros.h" -/* - * Early brya boards are not set up for vivaldi - */ -#undef CONFIG_KEYBOARD_VIVALDI - /* Baseboard features */ #include "baseboard.h" @@ -112,6 +107,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -177,13 +173,10 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B -/* - * TODO(b/181271666): no fan control loop until sensors are tuned - */ -/* #define CONFIG_FANS FAN_CH_COUNT */ +#define CONFIG_FANS FAN_CH_COUNT /* Charger defines */ #define CONFIG_CHARGER_ISL9241 diff --git a/board/kano/build.mk b/board/kano/build.mk index 6d1303a15a..df453187bf 100644 --- a/board/kano/build.mk +++ b/board/kano/build.mk @@ -22,5 +22,4 @@ board-y+=keyboard.o board-y+=led.o board-y+=pwm.o board-y+=sensors.o -board-y+=tune_mp2964.o board-y+=usbc_config.o diff --git a/board/kano/ec.tasklist b/board/kano/ec.tasklist index 7634667963..f52567d9fa 100644 --- a/board/kano/ec.tasklist +++ b/board/kano/ec.tasklist @@ -19,6 +19,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/kano/fans.c b/board/kano/fans.c index d966056331..a71758ea96 100644 --- a/board/kano/fans.c +++ b/board/kano/fans.c @@ -48,41 +48,3 @@ const struct fan_t fans[FAN_CH_COUNT] = { .rpm = &fan_rpm_0, }, }; - -#ifndef CONFIG_FANS - -/* - * TODO(b/181271666): use static fan speeds until fan and sensors are - * tuned. for now, use: - * - * AP off: 33% - * AP on: 100% - */ - -static void fan_slow(void) -{ - const int duty_pct = 33; - - ccprints("%s: speed %d%%", __func__, duty_pct); - - pwm_enable(PWM_CH_FAN, 1); - pwm_set_duty(PWM_CH_FAN, duty_pct); -} - -static void fan_max(void) -{ - const int duty_pct = 100; - - ccprints("%s: speed %d%%", __func__, duty_pct); - - pwm_enable(PWM_CH_FAN, 1); - pwm_set_duty(PWM_CH_FAN, duty_pct); -} - -DECLARE_HOOK(HOOK_INIT, fan_slow, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, fan_slow, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, fan_slow, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_RESET, fan_max, HOOK_PRIO_FIRST); -DECLARE_HOOK(HOOK_CHIPSET_RESUME, fan_max, HOOK_PRIO_DEFAULT); - -#endif /* CONFIG_FANS */ diff --git a/board/kano/fw_config.c b/board/kano/fw_config.c index fb8acb635d..a13dadeb5d 100644 --- a/board/kano/fw_config.c +++ b/board/kano/fw_config.c @@ -11,20 +11,19 @@ #define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) -static union brya_cbi_fw_config fw_config; +static union kano_cbi_fw_config fw_config; BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t)); /* - * FW_CONFIG defaults for brya if the CBI.FW_CONFIG data is not + * FW_CONFIG defaults for kano if the CBI.FW_CONFIG data is not * initialized. */ -static const union brya_cbi_fw_config fw_config_defaults = { - .usb_db = DB_USB3_PS8815, +static const union kano_cbi_fw_config fw_config_defaults = { .kb_bl = KEYBOARD_BACKLIGHT_ENABLED, }; /**************************************************************************** - * Brya FW_CONFIG access + * Kano FW_CONFIG access */ void board_init_fw_config(void) { @@ -36,25 +35,21 @@ void board_init_fw_config(void) if (get_board_id() == 0) { /* * Early boards have a zero'd out FW_CONFIG, so replace - * it with a sensible default value. If DB_USB_ABSENT2 - * was used as an alternate encoding of DB_USB_ABSENT to - * avoid the zero check, then fix it. + * it with a sensible default value. */ if (fw_config.raw_value == 0) { CPRINTS("CBI: FW_CONFIG is zero, using board defaults"); fw_config = fw_config_defaults; - } else if (fw_config.usb_db == DB_USB_ABSENT2) { - fw_config.usb_db = DB_USB_ABSENT; } } } -union brya_cbi_fw_config get_fw_config(void) +union kano_cbi_fw_config get_fw_config(void) { return fw_config; } -enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void) +bool ec_cfg_has_kblight(void) { - return fw_config.usb_db; + return (fw_config.kb_bl == KEYBOARD_BACKLIGHT_ENABLED); } diff --git a/board/kano/fw_config.h b/board/kano/fw_config.h index 6e4eb3ef58..8402b5568d 100644 --- a/board/kano/fw_config.h +++ b/board/kano/fw_config.h @@ -3,36 +3,28 @@ * found in the LICENSE file. */ -#ifndef __BOARD_BRYA_FW_CONFIG_H_ -#define __BOARD_BRYA_FW_CONFIG_H_ +#ifndef __BOARD_KANO_FW_CONFIG_H_ +#define __BOARD_KANO_FW_CONFIG_H_ #include <stdint.h> /**************************************************************************** - * CBI FW_CONFIG layout for Brya board. + * CBI FW_CONFIG layout for Kano board. * - * Source of truth is the project/brya/brya/config.star configuration file. + * Source of truth is the project/brya/kano/config.star configuration file. */ -enum ec_cfg_usb_db_type { - DB_USB_ABSENT = 0, - DB_USB3_PS8815 = 1, - DB_USB_ABSENT2 = 15 -}; - enum ec_cfg_keyboard_backlight_type { KEYBOARD_BACKLIGHT_DISABLED = 0, KEYBOARD_BACKLIGHT_ENABLED = 1 }; -union brya_cbi_fw_config { +union kano_cbi_fw_config { struct { - enum ec_cfg_usb_db_type usb_db : 4; - uint32_t sd_db : 2; - uint32_t lte_db : 1; enum ec_cfg_keyboard_backlight_type kb_bl : 1; uint32_t audio : 3; - uint32_t reserved_1 : 21; + uint32_t ufc : 2; + uint32_t reserved_1 : 26; }; uint32_t raw_value; }; @@ -42,13 +34,14 @@ union brya_cbi_fw_config { * * @return the FW_CONFIG for the board. */ -union brya_cbi_fw_config get_fw_config(void); +union kano_cbi_fw_config get_fw_config(void); /** - * Get the USB daughter board type from FW_CONFIG. + * Check if the FW_CONFIG has enabled keyboard backlight. * - * @return the USB daughter board type. + * @return true if board supports keyboard backlight, false if the board + * doesn't support it. */ -enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void); +bool ec_cfg_has_kblight(void); -#endif /* __BOARD_BRYA_FW_CONFIG_H_ */ +#endif /* __BOARD_KANO_FW_CONFIG_H_ */ diff --git a/board/kano/gpio.inc b/board/kano/gpio.inc index e5b452ced3..cfcc6bbd3f 100644 --- a/board/kano/gpio.inc +++ b/board/kano/gpio.inc @@ -117,6 +117,7 @@ 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(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/kano/sensors.c b/board/kano/sensors.c index 9a5812a9be..a47c9a782b 100644 --- a/board/kano/sensors.c +++ b/board/kano/sensors.c @@ -80,8 +80,8 @@ static const mat33_fp_t lid_bma422_standard_ref = { { 0, 0, FLOAT_TO_FP(-1)} }; static const mat33_fp_t base_bmi260_standard_ref = { - { 0, FLOAT_TO_FP(-1), 0}, - { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, { 0, 0, FLOAT_TO_FP(1)} }; @@ -172,7 +172,6 @@ struct motion_sensor_t motion_sensors[] = { .drv_data = &g_kx022_data, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = KX022_ADDR1_FLAGS, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .rot_standard_ref = &lid_standard_ref, /* identity matrix */ .default_range = 2, /* g */ .min_frequency = KX022_ACCEL_MIN_FREQ, @@ -198,8 +197,6 @@ struct motion_sensor_t motion_sensors[] = { .drv = &icm426xx_drv, .mutex = &g_base_accel_mutex, .drv_data = &g_icm426xx_data, - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -227,8 +224,6 @@ struct motion_sensor_t motion_sensors[] = { .drv = &icm426xx_drv, .mutex = &g_base_accel_mutex, .drv_data = &g_icm426xx_data, - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/kano/usbc_config.h b/board/kano/usbc_config.h index 87e601ee3e..38fce7d2cf 100644 --- a/board/kano/usbc_config.h +++ b/board/kano/usbc_config.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* Brya board-specific USB-C configuration */ +/* Kano board-specific USB-C configuration */ #ifndef __CROS_EC_USBC_CONFIG_H #define __CROS_EC_USBC_CONFIG_H diff --git a/board/kappa/board.c b/board/kappa/board.c index 963ade7430..e70054b18f 100644 --- a/board/kappa/board.c +++ b/board/kappa/board.c @@ -65,13 +65,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -137,8 +156,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/karma/board.c b/board/karma/board.c index 7bac35bd64..4e9f9166ff 100644 --- a/board/karma/board.c +++ b/board/karma/board.c @@ -5,12 +5,13 @@ #include "console.h" #include "gpio.h" +#include "hooks.h" #include "oz554.h" #define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) #define CPRINTF(format, args...) cprintf(CC_I2C, format, ## args) -__override void oz554_board_init(void) +void oz554_board_init(void) { int pin_status = 0; @@ -40,3 +41,10 @@ __override void oz554_board_init(void) break; } } + +static void init_oz554(void) +{ + oz554_board_init(); + gpio_enable_interrupt(GPIO_PANEL_BACKLIGHT_EN); +} +DECLARE_HOOK(HOOK_INIT, init_oz554, HOOK_PRIO_DEFAULT); diff --git a/board/karma/gpio.inc b/board/karma/gpio.inc index 1b265ed6ca..bdf0ab93be 100644 --- a/board/karma/gpio.inc +++ b/board/karma/gpio.inc @@ -11,7 +11,7 @@ GPIO_INT(USB_C0_PD_INT_ODL, PIN(3, 7), GPIO_INT_FALLING | GPIO_PULL_UP, tcpc_alert_event) GPIO_INT(AC_PRESENT, PIN(C, 1), GPIO_INT_BOTH, extpower_interrupt) GPIO_INT(POWER_BUTTON_L, PIN(0, 4), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt) /* MECH_PWR_BTN_ODL */ -GPIO_INT(PANEL_BACKLIGHT_EN, PIN(4, 4), GPIO_INT_RISING, backlight_enable_interrupt) +GPIO_INT(PANEL_BACKLIGHT_EN, PIN(4, 4), GPIO_INT_RISING, oz554_interrupt) GPIO_INT(PCH_SLP_S0_L, PIN(7, 5), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(PCH_SLP_SUS_L, PIN(6, 2), GPIO_INT_BOTH, power_signal_interrupt) diff --git a/board/katsu/board.c b/board/katsu/board.c index 6484778b13..5e1147c919 100644 --- a/board/katsu/board.c +++ b/board/katsu/board.c @@ -70,8 +70,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -107,8 +119,12 @@ struct mt6370_thermal_bound thermal_bound = { }; static void board_hpd_update(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. @@ -421,3 +437,18 @@ void board_fill_source_power_info(int port, r->meas.current_lim = 1500; r->max_power = r->meas.voltage_now * r->meas.current_max; } + +/* b/207456334: bugged reserved bits causes device not charging */ +static void mt6370_reg_fix(void) +{ + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT946X_REG_CHGCTRL1, + BIT(3) | BIT(5), MASK_CLR); + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT946X_REG_CHGCTRL2, + BIT(5) | BIT(RT946X_SHIFT_BATDET_DIS_DLY), + MASK_CLR); +} +DECLARE_HOOK(HOOK_INIT, mt6370_reg_fix, HOOK_PRIO_DEFAULT); diff --git a/board/kindred/board.h b/board/kindred/board.h index dd63efb390..efb325b3ab 100644 --- a/board/kindred/board.h +++ b/board/kindred/board.h @@ -18,7 +18,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -93,7 +93,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -120,6 +120,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/kingler/board.c b/board/kingler/board.c deleted file mode 100644 index e01d64c386..0000000000 --- a/board/kingler/board.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* Corsola board configuration */ - -#include "adc.h" -#include "button.h" -#include "charge_manager.h" -#include "charge_state_v2.h" -#include "charger.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "driver/accel_lis2dw12.h" -#include "driver/accelgyro_icm_common.h" -#include "driver/accelgyro_icm426xx.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "keyboard_scan.h" -#include "lid_switch.h" -#include "motion_sense.h" -#include "power.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "regulator.h" -#include "spi.h" -#include "switch.h" -#include "tablet_mode.h" -#include "task.h" -#include "timer.h" -#include "uart.h" - -/* Initialize board. */ -static void board_init(void) -{ - /* Enable motion sensor interrupt */ - gpio_enable_interrupt(GPIO_BASE_IMU_INT_L); - gpio_enable_interrupt(GPIO_LID_ACCEL_INT_L); -} -DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); - -/* Sensor */ -static struct mutex g_base_mutex; -static struct mutex g_lid_mutex; - -static struct stprivate_data g_lis2dwl_data; -static struct icm_drv_data_t g_icm426xx_data; - -struct motion_sensor_t motion_sensors[] = { - /* - * Note: icm426xx: supports accelerometer and gyro sensor - * Requirement: accelerometer sensor must init before gyro sensor - * DO NOT change the order of the following table. - */ - [BASE_ACCEL] = { - .name = "Base Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, - .mutex = &g_base_mutex, - .drv_data = &g_icm426xx_data, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, - .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs. */ - .rot_standard_ref = NULL, - .min_frequency = ICM426XX_ACCEL_MIN_FREQ, - .max_frequency = ICM426XX_ACCEL_MAX_FREQ, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 100 * MSEC, - }, - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, - [BASE_GYRO] = { - .name = "Base Gyro", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, - .type = MOTIONSENSE_TYPE_GYRO, - .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, - .mutex = &g_base_mutex, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, - .default_range = 1000, /* dps */ - .rot_standard_ref = NULL, - .min_frequency = ICM426XX_GYRO_MIN_FREQ, - .max_frequency = ICM426XX_GYRO_MAX_FREQ, - }, - [LID_ACCEL] = { - .name = "Lid Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_LIS2DWL, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_LID, - .drv = &lis2dw12_drv, - .mutex = &g_lid_mutex, - .drv_data = &g_lis2dwl_data, - .int_signal = GPIO_LID_ACCEL_INT_L, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = LIS2DWL_ADDR1_FLAGS, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .rot_standard_ref = NULL, /* identity matrix */ - .default_range = 2, /* g */ - .min_frequency = LIS2DW12_ODR_MIN_VAL, - .max_frequency = LIS2DW12_ODR_MAX_VAL, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 12500 | ROUND_UP_FLAG, - }, - /* Sensor on for lid angle detection */ - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, -}; -const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); - -void motion_interrupt(enum gpio_signal signal) -{ - icm426xx_interrupt(signal); -} - -/* ADC channels. Must be in the exactly same order as in enum adc_channel. */ -const struct adc_t adc_channels[] = { - /* Convert to mV (3000mV/1024). */ - {"VBUS_C0", ADC_MAX_MVOLT * 10, ADC_READ_MAX + 1, 0, CHIP_ADC_CH0}, - {"BOARD_ID_0", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH1}, - {"BOARD_ID_1", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH2}, - /* AMON/BMON gain = 17.97 */ - {"CHARGER_AMON_R", ADC_MAX_MVOLT * 1000 / 17.97, ADC_READ_MAX + 1, 0, - CHIP_ADC_CH3}, - {"VBUS_C1", ADC_MAX_MVOLT * 10, ADC_READ_MAX + 1, 0, CHIP_ADC_CH5}, - {"CHARGER_PMON", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH6}, -}; -BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); - -/* PWM */ - -/* - * PWM channels. Must be in the exactly same order as in enum pwm_channel. - * There total three 16 bits clock prescaler registers for all pwm channels, - * so use the same frequency and prescaler register setting is required if - * number of pwm channel greater than three. - */ -const struct pwm_t pwm_channels[] = { - [PWM_CH_LED1] = { - .channel = 0, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, - [PWM_CH_LED2] = { - .channel = 1, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, - [PWM_CH_LED3] = { - .channel = 2, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, -}; -BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); - -static void board_suspend(void) -{ - gpio_set_level(GPIO_EN_5V_USM, 0); -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_suspend, HOOK_PRIO_DEFAULT); - -static void board_resume(void) -{ - gpio_set_level(GPIO_EN_5V_USM, 1); -} -DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_resume, HOOK_PRIO_DEFAULT); diff --git a/board/kingler/board.h b/board/kingler/board.h deleted file mode 100644 index 857e654787..0000000000 --- a/board/kingler/board.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* Krabby board configuration */ - -#ifndef __CROS_EC_BOARD_H -#define __CROS_EC_BOARD_H - -#include "baseboard.h" - -/* Chipset config */ - -/* Optional features */ -#define CONFIG_LTO - -/* - * TODO: Remove this option once the VBAT no longer keeps high when - * system's power isn't presented. - */ -#define CONFIG_IT83XX_RESET_PD_CONTRACT_IN_BRAM - -/* BC12 */ -/* TODO(b/159583342): remove after rev0 deprecated */ -#define CONFIG_MT6360_BC12_GPIO - -/* LED */ -#define CONFIG_LED_ONOFF_STATES -#define CONFIG_LED_ONOFF_STATES_BAT_LOW 10 - -/* PD / USB-C / PPC */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 -#define PD_MAX_CURRENT_MA 3000 -#define PD_OPERATING_POWER_MW 15000 -#define PD_MAX_VOLTAGE_MV 15000 -#define PD_MAX_POWER_MW 45000 -#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ -#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ - -/* Optional console commands */ -#define CONFIG_CMD_FLASH -#define CONFIG_CMD_SCRATCHPAD -#define CONFIG_CMD_STACKOVERFLOW - -#define CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV 9000 - -/* Sensor */ -#define CONFIG_GMR_TABLET_MODE -#define CONFIG_TABLET_MODE -#define CONFIG_TABLET_MODE_SWITCH -#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L - -#define CONFIG_ACCELGYRO_BMI160 /* Base accel */ -#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) -#define CONFIG_ACCELGYRO_ICM426XX /* Base accel */ -#define CONFIG_ACCELGYRO_ICM426XX_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) - -#define CONFIG_ACCEL_LIS2DWL -#define CONFIG_ACCEL_LIS2DW_AS_BASE -#define CONFIG_ACCEL_LIS2DW12_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL) - -#define CONFIG_LID_ANGLE -#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL -#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL -#define CONFIG_LID_ANGLE_UPDATE - -#define CONFIG_ACCEL_FORCE_MODE_MASK 0 - -/* SPI / Host Command */ -#undef CONFIG_HOSTCMD_DEBUG_MODE -#define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_OFF - -/* USB-A */ -#define USBA_PORT_COUNT 1 - -#ifndef __ASSEMBLER__ - -#include "gpio_signal.h" -#include "registers.h" - -enum battery_type { - BATTERY_C235, - BATTERY_TYPE_COUNT, -}; - -enum sensor_id { - BASE_ACCEL = 0, - BASE_GYRO, - LID_ACCEL, - SENSOR_COUNT, -}; - -enum adc_channel { - ADC_VBUS_C0, /* ADC 0 */ - ADC_BOARD_ID_0, /* ADC 1 */ - ADC_BOARD_ID_1, /* ADC 2 */ - ADC_CHARGER_AMON_R, /* ADC 3 */ - ADC_VBUS_C1, /* ADC 5 */ - ADC_CHARGER_PMON, /* ADC 6 */ - - /* Number of ADC channels */ - ADC_CH_COUNT, -}; - -enum pwm_channel { - PWM_CH_LED1, - PWM_CH_LED2, - PWM_CH_LED3, - PWM_CH_COUNT, -}; - -void motion_interrupt(enum gpio_signal signal); - -#endif /* !__ASSEMBLER__ */ -#endif /* __CROS_EC_BOARD_H */ diff --git a/board/kingler/ec.tasklist b/board/kingler/ec.tasklist deleted file mode 100644 index 75dbb1a828..0000000000 --- a/board/kingler/ec.tasklist +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * See CONFIG_TASK_LIST in config.h for details. - */ -#define CONFIG_TASK_LIST \ - TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_NOTEST(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_NOTEST(PDCMD, pd_command_task, NULL, 1024) \ - TASK_ALWAYS(HOSTCMD, host_command_task, NULL, 1024) \ - TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \ - TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C0, pd_task, NULL, 1280) \ - TASK_ALWAYS(PD_C1, pd_task, NULL, 1280) \ - diff --git a/board/kingler/led.c b/board/kingler/led.c deleted file mode 100644 index 1d3108c47b..0000000000 --- a/board/kingler/led.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "ec_commands.h" -#include "gpio.h" -#include "led_common.h" -#include "led_onoff_states.h" -#include "chipset.h" -#include "driver/bc12/mt6360.h" - -__override const int led_charge_lvl_1 = 5; -__override const int led_charge_lvl_2 = 95; - -__override struct led_descriptor - led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { - [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, - [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, - [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, - [STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} }, - [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, - {LED_OFF, 3 * LED_ONE_SEC} }, - [STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} }, - [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, - [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, - {LED_OFF, 1 * LED_ONE_SEC} }, - [STATE_FACTORY_TEST] = {{EC_LED_COLOR_WHITE, 2 * LED_ONE_SEC}, - {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, -}; - -__override const struct led_descriptor - led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { - [PWR_LED_STATE_ON] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, - [PWR_LED_STATE_SUSPEND_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, - {LED_OFF, 3 * LED_ONE_SEC} }, - [PWR_LED_STATE_SUSPEND_NO_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, - {LED_OFF, 3 * LED_ONE_SEC} }, - [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} }, -}; - - -const enum ec_led_id supported_led_ids[] = { - EC_LED_ID_BATTERY_LED, - EC_LED_ID_POWER_LED, -}; - -const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); - -__override void led_set_color_battery(enum ec_led_colors color) -{ - mt6360_led_set_brightness(MT6360_LED_RGB2, 50); - mt6360_led_set_brightness(MT6360_LED_RGB3, 50); - - switch (color) { - case EC_LED_COLOR_AMBER: - mt6360_led_enable(MT6360_LED_RGB2, 0); - mt6360_led_enable(MT6360_LED_RGB3, 1); - break; - case EC_LED_COLOR_WHITE: - mt6360_led_enable(MT6360_LED_RGB2, 1); - mt6360_led_enable(MT6360_LED_RGB3, 0); - break; - default: /* LED_OFF and other unsupported colors */ - mt6360_led_enable(MT6360_LED_RGB2, 0); - mt6360_led_enable(MT6360_LED_RGB3, 0); - break; - } -} - -__override void led_set_color_power(enum ec_led_colors color) -{ - mt6360_led_set_brightness(MT6360_LED_RGB1, 1); - mt6360_led_enable(MT6360_LED_RGB1, color == EC_LED_COLOR_WHITE); -} - -void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) -{ - if (led_id == EC_LED_ID_BATTERY_LED) { - brightness_range[EC_LED_COLOR_AMBER] = - MT6360_LED_BRIGHTNESS_MAX; - brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - } else if (led_id == EC_LED_ID_POWER_LED) { - brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - } -} - -int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) -{ - if (led_id == EC_LED_ID_BATTERY_LED) { - if (brightness[EC_LED_COLOR_AMBER] != 0) - led_set_color_battery(EC_LED_COLOR_AMBER); - else if (brightness[EC_LED_COLOR_WHITE] != 0) - led_set_color_battery(EC_LED_COLOR_WHITE); - else - led_set_color_battery(LED_OFF); - } else if (led_id == EC_LED_ID_POWER_LED) { - if (brightness[EC_LED_COLOR_WHITE] != 0) - led_set_color_power(EC_LED_COLOR_WHITE); - else - led_set_color_power(LED_OFF); - } - - return EC_SUCCESS; -} - -__override enum led_states board_led_get_state(enum led_states desired_state) -{ - if (desired_state == STATE_BATTERY_ERROR) { - if (chipset_in_state(CHIPSET_STATE_ON)) - return desired_state; - else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - return STATE_DISCHARGE_S3; - else - return STATE_DISCHARGE_S5; - } - return desired_state; -} diff --git a/board/kingler/usbc_config.c b/board/kingler/usbc_config.c deleted file mode 100644 index 485a02c10f..0000000000 --- a/board/kingler/usbc_config.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Krabby board-specific USB-C configuration */ - -#include "driver/tcpm/it83xx_pd.h" -#include "driver/usb_mux/ps8743.h" -#include "hooks.h" - -void board_usb_mux_init(void) -{ - if (board_get_sub_board() == SUB_BOARD_TYPEC) { - ps8743_tune_usb_eq(&usb_muxes[1], - PS8743_USB_EQ_TX_12_8_DB, - PS8743_USB_EQ_RX_12_8_DB); - ps8743_write(&usb_muxes[1], - PS8743_REG_HS_DET_THRESHOLD, - PS8743_USB_HS_THRESH_NEG_10); - } -} -DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); - -const struct cc_para_t *board_get_cc_tuning_parameter(enum usbpd_port port) -{ - return NULL; -} diff --git a/board/kingoftown/board.c b/board/kingoftown/board.c index cc0005d775..cea9b9efe9 100644 --- a/board/kingoftown/board.c +++ b/board/kingoftown/board.c @@ -53,16 +53,41 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/kingoftown/board.h b/board/kingoftown/board.h index 1ba0ed0c34..ee773f8c7c 100644 --- a/board/kingoftown/board.h +++ b/board/kingoftown/board.h @@ -10,14 +10,6 @@ #include "baseboard.h" -/* TODO(waihong): Remove the following bringup features */ -#define CONFIG_BRINGUP -#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands. */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 -#define CONFIG_CMD_GPIO_EXTENDED -#define CONFIG_CMD_POWERINDEBUG -#define CONFIG_I2C_DEBUG - /* Internal SPI flash on NPCX7 */ #define CONFIG_FLASH_SIZE_BYTES (512 * 1024) /* 512KB internal spi flash */ diff --git a/board/kingoftown/led.c b/board/kingoftown/led.c index 09c1f89598..a543bb5403 100644 --- a/board/kingoftown/led.c +++ b/board/kingoftown/led.c @@ -127,25 +127,31 @@ static void board_led_set_battery(void) set_active_port_color(LED_AMBER); break; case PWR_STATE_DISCHARGE: - if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { - if (charge_get_percent() <= 10) { - led_blink_cycle = - battery_ticks % (2 * TIMES_TICK_ONE_SEC); + if (charge_get_percent() <= 10) { + led_blink_cycle = battery_ticks % (2 * TIMES_TICK_ONE_SEC); + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) side_led_set_color(1, (led_blink_cycle < TIMES_TICK_ONE_SEC) ? - LED_WHITE : LED_OFF); - } - else + LED_AMBER : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + side_led_set_color(0, + (led_blink_cycle < TIMES_TICK_ONE_SEC) ? + LED_AMBER : LED_OFF); + } else { + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) side_led_set_color(1, LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + side_led_set_color(0, LED_OFF); } - - if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) - side_led_set_color(0, LED_OFF); break; case PWR_STATE_ERROR: led_blink_cycle = battery_ticks % TIMES_TICK_ONE_SEC; - set_active_port_color((led_blink_cycle < TIMES_TICK_HALF_SEC) ? - LED_WHITE : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) + side_led_set_color(1, (led_blink_cycle < TIMES_TICK_HALF_SEC) ? + LED_AMBER : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + side_led_set_color(0, (led_blink_cycle < TIMES_TICK_HALF_SEC) ? + LED_AMBER : LED_OFF); break; case PWR_STATE_CHARGE_NEAR_FULL: set_active_port_color(LED_WHITE); diff --git a/board/kingoftown/usbc_config.c b/board/kingoftown/usbc_config.c index 81a63be9b3..3d13f6158e 100644 --- a/board/kingoftown/usbc_config.c +++ b/board/kingoftown/usbc_config.c @@ -6,6 +6,8 @@ /* Kingoftown board-specific USB-C configuration */ #include "bc12/pi3usb9201_public.h" +#include "charger.h" +#include "charger/isl923x_public.h" #include "charge_manager.h" #include "charge_state.h" #include "common.h" @@ -26,6 +28,52 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} + /* GPIO Interrupt Handlers */ void tcpc_alert_event(enum gpio_signal signal) { diff --git a/board/kodama/board.c b/board/kodama/board.c index 33ecbba384..2fa3ae8a3e 100644 --- a/board/kodama/board.c +++ b/board/kodama/board.c @@ -62,14 +62,33 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA, - .flags = I2C_PORT_FLAG_DYNAMIC_SPEED}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -104,8 +123,12 @@ struct mt6370_thermal_bound thermal_bound = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. @@ -322,8 +345,6 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lsm6dsm_drv, .mutex = &g_lid_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_ACCEL_INT_ODL, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &lid_standard_ref, diff --git a/board/kohaku/board.h b/board/kohaku/board.h index b8470d9ba7..4bc1f4a517 100644 --- a/board/kohaku/board.h +++ b/board/kohaku/board.h @@ -19,7 +19,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -120,7 +120,7 @@ #define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL /* Thermal features */ -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -139,6 +139,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/krabby/battery.c b/board/krabby/battery.c deleted file mode 100644 index f07c38e1b8..0000000000 --- a/board/krabby/battery.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "battery.h" -#include "battery_fuel_gauge.h" -#include "battery_smart.h" -#include "charge_manager.h" -#include "chipset.h" -#include "gpio.h" -#include "hooks.h" -#include "system.h" -#include "usb_pd.h" - -const struct board_batt_params board_battery_info[] = { - [BATTERY_C235] = { - .fuel_gauge = { - .manuf_name = "AS3GWRc3KA", - .device_name = "C235-41", - .ship_mode = { - .reg_addr = 0x0, - .reg_data = { 0x10, 0x10 }, - }, - .fet = { - .reg_addr = 0x99, - .reg_mask = 0x0c, - .disconnect_val = 0x0c, - } - }, - .batt_info = { - .voltage_max = 8800, - .voltage_normal = 7700, - .voltage_min = 6000, - .precharge_current = 256, - .start_charging_min_c = 0, - .start_charging_max_c = 45, - .charging_min_c = 0, - .charging_max_c = 60, - .discharging_min_c = 0, - .discharging_max_c = 60, - }, - }, -}; -BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); - -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_C235; diff --git a/board/krabby/board.c b/board/krabby/board.c deleted file mode 100644 index 1e81aed838..0000000000 --- a/board/krabby/board.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -/* Corsola board configuration */ - -#include "adc.h" -#include "button.h" -#include "charge_manager.h" -#include "charge_state_v2.h" -#include "charger.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "driver/accel_lis2dw12.h" -#include "driver/accelgyro_icm_common.h" -#include "driver/accelgyro_icm426xx.h" -#include "gpio.h" -#include "hooks.h" -#include "i2c.h" -#include "keyboard_scan.h" -#include "lid_switch.h" -#include "motion_sense.h" -#include "power.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "regulator.h" -#include "spi.h" -#include "switch.h" -#include "tablet_mode.h" -#include "task.h" -#include "timer.h" -#include "uart.h" - -/* Initialize board. */ -static void board_init(void) -{ - /* Enable motion sensor interrupt */ - gpio_enable_interrupt(GPIO_BASE_IMU_INT_L); - gpio_enable_interrupt(GPIO_LID_ACCEL_INT_L); -} -DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); - -/* Sensor */ -static struct mutex g_base_mutex; -static struct mutex g_lid_mutex; - -static struct stprivate_data g_lis2dwl_data; -static struct icm_drv_data_t g_icm426xx_data; - -struct motion_sensor_t motion_sensors[] = { - /* - * Note: icm426xx: supports accelerometer and gyro sensor - * Requirement: accelerometer sensor must init before gyro sensor - * DO NOT change the order of the following table. - */ - [BASE_ACCEL] = { - .name = "Base Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, - .mutex = &g_base_mutex, - .drv_data = &g_icm426xx_data, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, - .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs. */ - .rot_standard_ref = NULL, - .min_frequency = ICM426XX_ACCEL_MIN_FREQ, - .max_frequency = ICM426XX_ACCEL_MAX_FREQ, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 100 * MSEC, - }, - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, - [BASE_GYRO] = { - .name = "Base Gyro", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_ICM426XX, - .type = MOTIONSENSE_TYPE_GYRO, - .location = MOTIONSENSE_LOC_BASE, - .drv = &icm426xx_drv, - .mutex = &g_base_mutex, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, - .default_range = 1000, /* dps */ - .rot_standard_ref = NULL, - .min_frequency = ICM426XX_GYRO_MIN_FREQ, - .max_frequency = ICM426XX_GYRO_MAX_FREQ, - }, - [LID_ACCEL] = { - .name = "Lid Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_LIS2DWL, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_LID, - .drv = &lis2dw12_drv, - .mutex = &g_lid_mutex, - .drv_data = &g_lis2dwl_data, - .int_signal = GPIO_LID_ACCEL_INT_L, - .port = I2C_PORT_ACCEL, - .i2c_spi_addr_flags = LIS2DWL_ADDR1_FLAGS, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .rot_standard_ref = NULL, /* identity matrix */ - .default_range = 2, /* g */ - .min_frequency = LIS2DW12_ODR_MIN_VAL, - .max_frequency = LIS2DW12_ODR_MAX_VAL, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 12500 | ROUND_UP_FLAG, - }, - /* Sensor on for lid angle detection */ - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, -}; -const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); - -void motion_interrupt(enum gpio_signal signal) -{ - icm426xx_interrupt(signal); -} - -/* ADC channels. Must be in the exactly same order as in enum adc_channel. */ -const struct adc_t adc_channels[] = { - /* Convert to mV (3000mV/1024). */ - {"VBUS_C0", ADC_MAX_MVOLT * 10, ADC_READ_MAX + 1, 0, CHIP_ADC_CH0}, - {"BOARD_ID_0", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH1}, - {"BOARD_ID_1", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH2}, - /* AMON/BMON gain = 17.97 */ - {"CHARGER_AMON_R", ADC_MAX_MVOLT * 1000 / 17.97, ADC_READ_MAX + 1, 0, - CHIP_ADC_CH3}, - {"VBUS_C1", ADC_MAX_MVOLT * 10, ADC_READ_MAX + 1, 0, CHIP_ADC_CH5}, - {"CHARGER_PMON", ADC_MAX_MVOLT, ADC_READ_MAX + 1, 0, CHIP_ADC_CH6}, -}; -BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); - -/* PWM */ - -/* - * PWM channels. Must be in the exactly same order as in enum pwm_channel. - * There total three 16 bits clock prescaler registers for all pwm channels, - * so use the same frequency and prescaler register setting is required if - * number of pwm channel greater than three. - */ -const struct pwm_t pwm_channels[] = { - [PWM_CH_LED1] = { - .channel = 0, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, - [PWM_CH_LED2] = { - .channel = 1, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, - [PWM_CH_LED3] = { - .channel = 2, - .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW, - .freq_hz = 324, /* maximum supported frequency */ - .pcfsr_sel = PWM_PRESCALER_C4 - }, -}; -BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/krabby/gpio.inc b/board/krabby/gpio.inc deleted file mode 100644 index be37d43fb8..0000000000 --- a/board/krabby/gpio.inc +++ /dev/null @@ -1,157 +0,0 @@ -/* -*- mode:c -*- - * - * Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Declare symbolic names for all the GPIOs that we care about. - * Note: Those with interrupt handlers must be declared first. */ - -/* Wake Source interrupts */ -GPIO_INT(POWER_BUTTON_L, PIN(E, 4), - GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, - power_button_interrupt) /* GSC_EC_PWR_BTN_ODL */ -GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, - lid_interrupt) /* LID_OPEN_3V3 */ -GPIO_INT(TABLET_MODE_L, PIN(J, 7), GPIO_INT_BOTH, - gmr_tablet_switch_isr) - -/* Chipset interrupts */ -GPIO_INT(AP_EC_WARM_RST_REQ, PIN(D, 3), GPIO_INT_RISING | GPIO_SEL_1P8V, - chipset_reset_request_interrupt) - -/* Power sequencing interrupts */ -GPIO_INT(AP_IN_SLEEP_L, PIN(B, 6), - GPIO_INT_BOTH | GPIO_SEL_1P8V, power_signal_interrupt) - -/* Sensor Interrupts */ -GPIO_INT(BASE_IMU_INT_L, PIN(M, 3), GPIO_INT_FALLING | GPIO_SEL_1P8V, - motion_interrupt) -GPIO_INT(LID_ACCEL_INT_L, PIN(M, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, - lis2dw12_interrupt) - -/* Volume button interrupts */ -GPIO_INT(VOLUME_DOWN_L, PIN(D, 5), GPIO_INT_BOTH, - button_interrupt) /* EC_VOLDN_BTN_ODL */ -GPIO_INT(VOLUME_UP_L, PIN(D, 6), GPIO_INT_BOTH, - button_interrupt) /* EC_VOLUP_BTN_ODL */ - -/* Other interrupts */ -GPIO_INT(AP_XHCI_INIT_DONE, PIN(J, 5), - GPIO_INT_BOTH | GPIO_SEL_1P8V, - usb_a0_interrupt) -GPIO_INT(AC_PRESENT, PIN(E, 5), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, - extpower_interrupt) /* GSC_ACOK_OD */ -GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING, - uart_deepsleep_interrupt) /* UART_DEBUG_TX_EC_RX */ -GPIO_INT(WP, PIN(I, 4), GPIO_INT_BOTH | GPIO_SEL_1P8V, - switch_interrupt) /* EC_FLASH_WP_OD */ -GPIO_INT(SPI0_CS, PIN(M, 5), GPIO_INT_FALLING | GPIO_SEL_1P8V, - spi_event) /* SPI slave Chip Select -- AP_EC_SPI_CS_L */ -GPIO_INT(X_EC_GPIO2, PIN(B, 2), GPIO_INT_BOTH | GPIO_ODR_HIGH, - x_ec_interrupt) - -/* USB-C interrupts */ -/* TODO: interrupt function not ready */ -GPIO(USB_C0_PPC_BC12_INT_ODL, PIN(D, 1), GPIO_INT_FALLING) -GPIO(USB_C1_BC12_CHARGER_INT_ODL, PIN(J, 4), GPIO_INT_FALLING) - -/* Power Sequencing Signals */ -GPIO(EC_PMIC_EN_ODL, PIN(D, 0), GPIO_ODR_HIGH | GPIO_SEL_1P8V) -GPIO(EN_PP5000_Z2, PIN(C, 6), GPIO_OUT_HIGH) -GPIO(EN_ULP, PIN(E, 3), GPIO_OUT_LOW) -GPIO(SYS_RST_ODL, PIN(G, 1), GPIO_ODR_LOW) -GPIO(EC_BL_EN_OD, PIN(B, 5), GPIO_ODR_LOW | GPIO_SEL_1P8V) -GPIO(AP_EC_SYSRST_ODL, PIN(J, 2), GPIO_INPUT | GPIO_SEL_1P8V) -GPIO(AP_EC_WDTRST_L, PIN(C, 7), GPIO_INPUT | GPIO_SEL_1P8V) - -/* MKBP event synchronization */ -GPIO(EC_INT_L, PIN(E, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_AP_INT_ODL */ - -/* USB and USBC Signals */ -GPIO(DP_AUX_PATH_SEL, PIN(G, 0), GPIO_OUT_HIGH) -GPIO(EC_AP_DP_HPD_ODL, PIN(J, 0), GPIO_ODR_HIGH) -GPIO(EN_PP5000_USB_A0_VBUS, PIN(B, 7), GPIO_OUT_LOW) -GPIO(USB_C0_PPC_FRSINFO, PIN(F, 0), GPIO_INPUT) - -/* Misc Signals */ -GPIO(EC_BATT_PRES_ODL, PIN(C, 0), GPIO_INPUT) -GPIO(EN_EC_ID_ODL, PIN(H, 5), GPIO_ODR_LOW) -GPIO(ENTERING_RW, PIN(C, 5), GPIO_OUT_LOW) /* EC_ENTERING_RW */ -GPIO(EN_5V_USM, PIN(G, 3), GPIO_OUT_LOW) -GPIO(USB_A0_FAULT_ODL, PIN(J, 6), GPIO_INPUT) - -/* I2C pins - Alternate function below configures I2C module on these pins */ -GPIO(I2C_A_SCL, PIN(B, 3), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_PWR_CBI_SCL */ -GPIO(I2C_A_SDA, PIN(B, 4), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_PWR_CBI_SDA */ -GPIO(I2C_B_SCL, PIN(C, 1), GPIO_INPUT) /* I2C_BATT_SCL_3V3 */ -GPIO(I2C_B_SDA, PIN(C, 2), GPIO_INPUT) /* I2C_BATT_SDA_3V3 */ -GPIO(I2C_C_SCL, PIN(F, 6), GPIO_INPUT) /* I2C_USB_C0_SCL */ -GPIO(I2C_C_SDA, PIN(F, 7), GPIO_INPUT) /* I2C_USB_C0_SDA */ -GPIO(I2C_D_SCL, PIN(F, 2), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_SENSOR_SCL */ -GPIO(I2C_D_SDA, PIN(F, 3), GPIO_INPUT | GPIO_SEL_1P8V) /* I2C_SENSOR_SDA */ -GPIO(I2C_E_SCL, PIN(E, 0), GPIO_INPUT) /* I2C_USB_C1_SCL */ -GPIO(I2C_E_SDA, PIN(E, 7), GPIO_INPUT) /* I2C_USB_C1_SDA */ -GPIO(I2C_F_SCL, PIN(A, 4), GPIO_INPUT) /* I2C_PROG_SCL */ -GPIO(I2C_F_SDA, PIN(A, 5), GPIO_INPUT) /* I2C_PROG_SDA */ - -/* SPI pins - Alternate function below configures SPI module on these pins */ - -/* Keyboard pins */ - -/* Subboards HDMI/TYPEC */ -GPIO(EC_X_GPIO1, PIN(H, 4), GPIO_OUT_LOW) -GPIO(EC_X_GPIO3, PIN(J, 1), GPIO_INPUT) -GPIO(HDMI_PRSNT_ODL, PIN(J, 3), GPIO_INPUT) /* low -> hdmi, other -> usb */ - -/* Alternate functions GPIO definitions */ -ALTERNATE(PIN_MASK(B, 0x18), 1, MODULE_I2C, 0) /* I2C A */ -ALTERNATE(PIN_MASK(C, 0x06), 1, MODULE_I2C, GPIO_SEL_1P8V) /* I2C B */ -ALTERNATE(PIN_MASK(F, 0xCC), 1, MODULE_I2C, 0) /* I2C C, D */ -ALTERNATE(PIN_MASK(E, 0x81), 1, MODULE_I2C, 0) /* I2C E */ - -/* UART */ -ALTERNATE(PIN_MASK(B, 0x03), 1, MODULE_UART, 0) /* EC to Servo */ - -/* PWM */ -ALTERNATE(PIN_MASK(A, 0x07), 1, MODULE_PWM, 0) /* PWM 0~2 */ - -/* ADC */ -ALTERNATE(PIN_MASK(I, 0b10010111), 0, MODULE_ADC, 0) /* ADC 0,1,2,4,7 */ - -/* SPI */ -ALTERNATE(PIN_MASK(M, 0x33), 0, MODULE_SPI, GPIO_SEL_1P8V) /* SPI */ - -/* Unimplemented Pins */ -GPIO(PACKET_MODE_EN, PIN(D, 4), GPIO_OUT_LOW) -GPIO(PG_PP5000_Z2_OD, PIN(D, 2), GPIO_INPUT) -GPIO(PG_MT6315_PROC_B_ODL, PIN(E, 1), GPIO_INPUT) -GPIO(EC_PEN_CHG_DIS_ODL, PIN(H, 3), GPIO_ODR_HIGH) /* 5V output */ -/* reserved for future use */ -GPIO(CCD_MODE_ODL, PIN(C, 4), GPIO_INPUT) - -/* NC pins, enable internal pull-up/down to avoid floating state. */ -GPIO(NC_GPA3, PIN(A, 3), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPA6, PIN(A, 6), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPA7, PIN(A, 7), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPC3, PIN(C, 3), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPD7, PIN(D, 7), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPF1, PIN(F, 1), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(SPI_CLK_GPG6, PIN(G, 6), GPIO_INPUT | GPIO_PULL_UP) -GPIO(NC_GPH0, PIN(H, 0), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPH6, PIN(H, 6), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPI7, PIN(I, 7), GPIO_INPUT | GPIO_PULL_DOWN) -GPIO(NC_GPM6, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN) -/* - * These pins don't have internal pull-down capability, - * so we set them as output low. - */ -GPIO(SPI_MOSI_GPG4, PIN(G, 4), GPIO_OUT_LOW) -GPIO(SPI_MISO_GPG5, PIN(G, 5), GPIO_OUT_LOW) -GPIO(SPI_CS_GPG7, PIN(G, 7), GPIO_OUT_LOW) - -/* pins used in power/mt8192, will be removed after mt8186 code ready */ -UNIMPLEMENTED(AP_EC_WATCHDOG_L) -UNIMPLEMENTED(EC_PMIC_WATCHDOG_L) -UNIMPLEMENTED(PMIC_EC_PWRGD) diff --git a/board/krabby/usbc_config.c b/board/krabby/usbc_config.c deleted file mode 100644 index ee5d9483eb..0000000000 --- a/board/krabby/usbc_config.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Krabby board-specific USB-C configuration */ - -#include "driver/tcpm/it83xx_pd.h" -#include "driver/usb_mux/ps8743.h" -#include "hooks.h" - -void board_usb_mux_init(void) -{ - if (board_get_sub_board() == SUB_BOARD_TYPEC) { - ps8743_tune_usb_eq(&usb_muxes[1], - PS8743_USB_EQ_TX_12_8_DB, - PS8743_USB_EQ_RX_12_8_DB); - ps8743_write(&usb_muxes[1], - PS8743_REG_HS_DET_THRESHOLD, - PS8743_USB_HS_THRESH_NEG_10); - } -} -DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); - -const struct cc_para_t *board_get_cc_tuning_parameter(enum usbpd_port port) -{ - const static struct cc_para_t - cc_parameter[CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT] = { - { - .rising_time = IT83XX_TX_PRE_DRIVING_TIME_1_UNIT, - .falling_time = IT83XX_TX_PRE_DRIVING_TIME_2_UNIT, - }, - { - .rising_time = IT83XX_TX_PRE_DRIVING_TIME_1_UNIT, - .falling_time = IT83XX_TX_PRE_DRIVING_TIME_2_UNIT, - }, - }; - - return &cc_parameter[port]; -} diff --git a/board/kracko/board.c b/board/kracko/board.c index 99dcd56810..566ecdf3b4 100644 --- a/board/kracko/board.c +++ b/board/kracko/board.c @@ -364,8 +364,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -393,8 +391,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/kukui/board.c b/board/kukui/board.c index 8d386815c6..a3468b62ca 100644 --- a/board/kukui/board.c +++ b/board/kukui/board.c @@ -75,8 +75,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -123,8 +135,12 @@ void board_set_dp_mux_control(int output_enable, int polarity) } static void board_hpd_update(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/lantis/board.c b/board/lantis/board.c index a64d8fa17a..6ddc1c3f89 100644 --- a/board/lantis/board.c +++ b/board/lantis/board.c @@ -328,8 +328,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -357,8 +355,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/lazor/board.c b/board/lazor/board.c index 1118f3a845..03192e1bbc 100644 --- a/board/lazor/board.c +++ b/board/lazor/board.c @@ -77,16 +77,41 @@ const int keyboard_factory_scan_pins_used = /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/lazor/usbc_config.c b/board/lazor/usbc_config.c index f8c9662136..b489c2b8ed 100644 --- a/board/lazor/usbc_config.c +++ b/board/lazor/usbc_config.c @@ -7,6 +7,8 @@ #include "battery_fuel_gauge.h" #include "bc12/pi3usb9201_public.h" +#include "charger.h" +#include "charger/isl923x_public.h" #include "charge_manager.h" #include "charge_state.h" #include "common.h" @@ -28,6 +30,52 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} + void usb0_evt(enum gpio_signal signal) { task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); diff --git a/board/liara/board.c b/board/liara/board.c index 4f8b552d1f..c8fdeff2cd 100644 --- a/board/liara/board.c +++ b/board/liara/board.c @@ -29,12 +29,48 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"kblight", I2C_PORT_KBLIGHT, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "kblight", + .port = I2C_PORT_KBLIGHT, + .kbps = 100, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/lick/board.c b/board/lick/board.c index 4b5608b7b0..678634f785 100644 --- a/board/lick/board.c +++ b/board/lick/board.c @@ -144,8 +144,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &standard_rot_ref, @@ -176,8 +174,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/lindar/board.c b/board/lindar/board.c index e1975260df..3b18845b36 100644 --- a/board/lindar/board.c +++ b/board/lindar/board.c @@ -180,8 +180,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -212,8 +210,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/lindar/ec.tasklist b/board/lindar/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/lindar/ec.tasklist +++ b/board/lindar/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/madoo/board.c b/board/madoo/board.c index 1c989b859e..31b0c5309e 100644 --- a/board/madoo/board.c +++ b/board/madoo/board.c @@ -394,8 +394,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -423,8 +421,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/magolor/board.c b/board/magolor/board.c index 3d3765dbe0..ca656fcf0d 100644 --- a/board/magolor/board.c +++ b/board/magolor/board.c @@ -805,6 +805,37 @@ struct motion_sensor_t motion_sensors[] = { unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); +/** + * Handle debounced pen input changing state. + */ +static void pendetect_deferred(void) +{ + int pen_charge_enable = !gpio_get_level(GPIO_PEN_DET_ODL) && + !chipset_in_state(CHIPSET_STATE_ANY_OFF); + + if (pen_charge_enable) + gpio_set_level(GPIO_EN_PP5000_PEN, 1); + else + gpio_set_level(GPIO_EN_PP5000_PEN, 0); + + CPRINTS("Pen charge %sable", pen_charge_enable ? "en" : "dis"); +} +DECLARE_DEFERRED(pendetect_deferred); + +void pen_detect_interrupt(enum gpio_signal signal) +{ + /* pen input debounce time */ + hook_call_deferred(&pendetect_deferred_data, (100 * MSEC)); +} + +static void pen_charge_check(void) +{ + if (get_cbi_fw_config_stylus() == STYLUS_PRESENT) + hook_call_deferred(&pendetect_deferred_data, (100 * MSEC)); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pen_charge_check, HOOK_PRIO_LAST); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pen_charge_check, HOOK_PRIO_LAST); + void board_init(void) { int on; @@ -874,6 +905,16 @@ void board_init(void) GPIO_INPUT | GPIO_PULL_DOWN); } + if (get_cbi_fw_config_stylus() == STYLUS_PRESENT) { + gpio_enable_interrupt(GPIO_PEN_DET_ODL); + /* Make sure pen detection is triggered or not at sysjump */ + pen_charge_check(); + } else { + gpio_disable_interrupt(GPIO_PEN_DET_ODL); + gpio_set_flags(GPIO_PEN_DET_ODL, + GPIO_INPUT | GPIO_PULL_DOWN); + } + /* Turn on 5V if the system is on, otherwise turn it off. */ on = chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_SOFT_OFF); diff --git a/board/magolor/board.h b/board/magolor/board.h index c1ef73cc64..9b7117fa0c 100644 --- a/board/magolor/board.h +++ b/board/magolor/board.h @@ -208,5 +208,6 @@ enum battery_type { }; void motion_interrupt(enum gpio_signal signal); +void pen_detect_interrupt(enum gpio_signal s); #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/magolor/gpio.inc b/board/magolor/gpio.inc index b7b692ca56..00a6b4effc 100644 --- a/board/magolor/gpio.inc +++ b/board/magolor/gpio.inc @@ -37,6 +37,7 @@ GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH, lid_interrupt) GPIO_INT(EC_WP_OD, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(BASE_SIXAXIS_INT_L, PIN(5, 6), GPIO_INT_FALLING | GPIO_SEL_1P8V, motion_interrupt) GPIO_INT(LID_360_L, PIN(9, 5), GPIO_INT_BOTH, gmr_tablet_switch_isr) +GPIO_INT(PEN_DET_ODL, PIN(5, 0), GPIO_INT_BOTH, pen_detect_interrupt) /* I2C Ports */ GPIO(EC_I2C_EEPROM_SCL, PIN(B, 3), GPIO_INPUT) @@ -57,7 +58,7 @@ GPIO(EC_SUB_IO_2, PIN(3, 4), GPIO_OUT_LOW) GPIO(EN_VCCIO_EXT, PIN(6, 1), GPIO_OUT_LOW) /* TODO(b:149775160) - Modify if needed if we ever use this signal. */ GPIO(EN_VCCST, PIN(A, 7), GPIO_INPUT) -GPIO(EN_PP3300_PEN, PIN(6, 3), GPIO_OUT_LOW) +GPIO(EN_PP5000_PEN, PIN(6, 3), GPIO_OUT_LOW) GPIO(EN_PP3300_A, PIN(0, 3), GPIO_OUT_LOW) GPIO(EN_PP5000_U, PIN(A, 4), GPIO_OUT_LOW) GPIO(EN_SLP_Z, PIN(8, 3), GPIO_OUT_LOW) diff --git a/board/makomo/board.c b/board/makomo/board.c index 1bb6b134a7..616b50003d 100644 --- a/board/makomo/board.c +++ b/board/makomo/board.c @@ -66,13 +66,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -138,8 +157,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/makomo/board.h b/board/makomo/board.h index 844fd95292..3c620cd823 100644 --- a/board/makomo/board.h +++ b/board/makomo/board.h @@ -90,7 +90,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/marzipan/board.c b/board/marzipan/board.c index 915f96743d..753d7a2e2a 100644 --- a/board/marzipan/board.c +++ b/board/marzipan/board.c @@ -105,16 +105,41 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/marzipan/usbc_config.c b/board/marzipan/usbc_config.c index 3704a94197..e8fc9e76a3 100644 --- a/board/marzipan/usbc_config.c +++ b/board/marzipan/usbc_config.c @@ -5,9 +5,61 @@ /* Marzipan board-specific USB-C configuration */ +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" #include "usb_pd.h" #include "usbc_config.h" +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} + /* GPIO Interrupt Handlers */ void tcpc_alert_event(enum gpio_signal signal) { diff --git a/board/mchpevb1/board.c b/board/mchpevb1/board.c index aa74d07a0d..99e3ac9328 100644 --- a/board/mchpevb1/board.c +++ b/board/mchpevb1/board.c @@ -230,8 +230,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); * MCHP EVB connected to KBL RVP3 */ const struct i2c_port_t i2c_ports[] = { - {"sensors", MCHP_I2C_PORT4, 100, GPIO_SMB04_SCL, GPIO_SMB04_SDA}, - {"batt", MCHP_I2C_PORT5, 100, GPIO_SMB05_SCL, GPIO_SMB05_SDA}, + { + .name = "sensors", + .port = MCHP_I2C_PORT4, + .kbps = 100, + .scl = GPIO_SMB04_SCL, + .sda = GPIO_SMB04_SDA + }, + { + .name = "batt", + .port = MCHP_I2C_PORT5, + .kbps = 100, + .scl = GPIO_SMB05_SCL, + .sda = GPIO_SMB05_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/mchpevb1/board.h b/board/mchpevb1/board.h index de1e7a75e9..e16d0bb10f 100644 --- a/board/mchpevb1/board.h +++ b/board/mchpevb1/board.h @@ -163,7 +163,7 @@ #define CONFIG_CHIPSET_SKYLAKE #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/mchpevb1/gpio.inc b/board/mchpevb1/gpio.inc index 8be1099fbd..3949e31843 100644 --- a/board/mchpevb1/gpio.inc +++ b/board/mchpevb1/gpio.inc @@ -27,8 +27,8 @@ #define GPIO_BOTH_EDGES_PU (GPIO_INT_BOTH | GPIO_PULL_UP) -/* Only needed if CONFIG_HOSTCMD_ESPI is not set, using LPC interface to PCH */ -#ifndef CONFIG_HOSTCMD_ESPI +/* Only needed if CONFIG_HOST_INTERFACE_ESPI is not set, using LPC interface to PCH */ +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(PCH_PLTRST_L, PIN(064), GPIO_BOTH_EDGES_PU, lpcrst_interrupt) #endif diff --git a/board/meep/board.c b/board/meep/board.c index daac19a89a..3771c72072 100644 --- a/board/meep/board.c +++ b/board/meep/board.c @@ -176,8 +176,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -208,8 +206,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/metaknight/board.c b/board/metaknight/board.c index 253ce31571..fc138bbbe2 100644 --- a/board/metaknight/board.c +++ b/board/metaknight/board.c @@ -567,8 +567,6 @@ struct motion_sensor_t lsm6dsm_base_accel = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_lsm6dsm_ref, @@ -597,8 +595,6 @@ struct motion_sensor_t lsm6dsm_base_gyro = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -878,28 +874,43 @@ void motion_interrupt(enum gpio_signal signal) const struct i2c_port_t i2c_ports[] = { { - "eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA }, { - "battery", I2C_PORT_BATTERY, 100, GPIO_EC_I2C_BATTERY_SCL, - GPIO_EC_I2C_BATTERY_SDA + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BATTERY_SCL, + .sda = GPIO_EC_I2C_BATTERY_SDA }, { - "sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA }, { - "usbc0", I2C_PORT_USB_C0, 1000, GPIO_EC_I2C_USB_C0_SCL, - GPIO_EC_I2C_USB_C0_SDA + .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_SCL, + .sda = GPIO_EC_I2C_USB_C0_SDA }, #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 { - "sub_usbc1", I2C_PORT_SUB_USB_C1, 1000, - GPIO_EC_I2C_SUB_USB_C1_SCL, GPIO_EC_I2C_SUB_USB_C1_SDA + .name = "sub_usbc1", + .port = I2C_PORT_SUB_USB_C1, + .kbps = 1000, + .scl = GPIO_EC_I2C_SUB_USB_C1_SCL, + .sda = GPIO_EC_I2C_SUB_USB_C1_SDA }, #endif }; diff --git a/board/moonbuggy/board.c b/board/moonbuggy/board.c index 0ebf1380cb..889f4de898 100644 --- a/board/moonbuggy/board.c +++ b/board/moonbuggy/board.c @@ -135,12 +135,48 @@ const struct pwm_t pwm_channels[] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"pse", I2C_PORT_PSE, 400, GPIO_I2C4_SCL, GPIO_I2C4_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "pse", + .port = I2C_PORT_PSE, + .kbps = 400, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/moonbuggy/board.h b/board/moonbuggy/board.h index 4ec5233f6f..64db35874e 100644 --- a/board/moonbuggy/board.h +++ b/board/moonbuggy/board.h @@ -38,7 +38,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -104,7 +104,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -218,6 +218,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/moonbuggy/gpio.inc b/board/moonbuggy/gpio.inc index 6a905fdf04..d8f2989b8e 100644 --- a/board/moonbuggy/gpio.inc +++ b/board/moonbuggy/gpio.inc @@ -58,7 +58,7 @@ GPIO_INT(USB_A3_OC_ODL, PIN(0, 3), GPIO_INT_BOTH, port_ocp_interrupt) GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) diff --git a/board/morphius/board.h b/board/morphius/board.h index a38fd93fc1..343f1055e5 100644 --- a/board/morphius/board.h +++ b/board/morphius/board.h @@ -42,7 +42,7 @@ #define CONFIG_TABLET_MODE #define CONFIG_TEMP_SENSOR #define CONFIG_TEMP_SENSOR_TMP432 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_PWR_A +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_LID_ANGLE #define CONFIG_LID_ANGLE_UPDATE #define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL @@ -71,6 +71,7 @@ #define GPIO_S0_PGOOD GPIO_S0_PWROK_OD #define GPIO_S5_PGOOD GPIO_EC_PWROK_OD #define GPIO_SYS_RESET_L GPIO_EC_SYS_RST_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_PWR_A #define GPIO_VOLUME_DOWN_L GPIO_VOLDN_BTN_ODL #define GPIO_VOLUME_UP_L GPIO_VOLUP_BTN_ODL #define GPIO_WP_L GPIO_EC_WP_L diff --git a/board/morphius/thermal.c b/board/morphius/thermal.c index 449fd92d5d..329157b6ec 100644 --- a/board/morphius/thermal.c +++ b/board/morphius/thermal.c @@ -495,16 +495,16 @@ void board_override_fan_control(int fan, int *tmp) void thermal_protect(void) { - if ((!lid_is_open()) && (!extpower_is_present())) { - int rv1, rv2; - int thermal_sensor1, thermal_sensor2; + int rv1, rv2; + int thermal_sensor1, thermal_sensor2; - rv1 = temp_sensor_read(TEMP_SENSOR_5V_REGULATOR, - &thermal_sensor1); - rv2 = temp_sensor_read(TEMP_SENSOR_CPU, - &thermal_sensor2); + rv1 = temp_sensor_read(TEMP_SENSOR_5V_REGULATOR, + &thermal_sensor1); + rv2 = temp_sensor_read(TEMP_SENSOR_CPU, + &thermal_sensor2); - if (rv2 == EC_SUCCESS) { + if (rv2 == EC_SUCCESS) { + if ((!lid_is_open()) && (!extpower_is_present())) { if (thermal_sensor2 > C_TO_K(70)) { chipset_throttle_cpu(1); throttle_on = 1; @@ -513,9 +513,17 @@ void thermal_protect(void) chipset_throttle_cpu(0); throttle_on = 0; } + } else { + if (throttle_on == 1) { + chipset_throttle_cpu(0); + throttle_on = 0; + } } - if (rv1 == EC_SUCCESS && - thermal_sensor1 > C_TO_K(51)) + } + + if (rv1 == EC_SUCCESS) { + if ((!lid_is_open()) && (!extpower_is_present()) + && thermal_sensor1 > C_TO_K(51)) chipset_force_shutdown(CHIPSET_SHUTDOWN_THERMAL); } } diff --git a/board/mrbland/board.c b/board/mrbland/board.c index d367b82521..b94717b5a4 100644 --- a/board/mrbland/board.c +++ b/board/mrbland/board.c @@ -107,14 +107,34 @@ static void switchcap_interrupt(enum gpio_signal signal) /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/mrbland/build.mk b/board/mrbland/build.mk index 74b6b95e4d..452abeb591 100644 --- a/board/mrbland/build.mk +++ b/board/mrbland/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o base_detect.o +board-y=battery.o board.o led.o base_detect.o usbc_config.o diff --git a/board/mrbland/usbc_config.c b/board/mrbland/usbc_config.c new file mode 100644 index 0000000000..8f3fb02c30 --- /dev/null +++ b/board/mrbland/usbc_config.c @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "usb_pd.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/munna/board.c b/board/munna/board.c index f31c7a7e39..6cba87ada2 100644 --- a/board/munna/board.c +++ b/board/munna/board.c @@ -67,13 +67,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 2, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 2, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 3, 100, GPIO_I2C4_SCL, GPIO_I2C4_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 3, + .kbps = 100, + .scl = GPIO_I2C4_SCL, + .sda = GPIO_I2C4_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -139,8 +158,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. @@ -267,7 +290,7 @@ static void board_spi_enable(void) #ifdef CHIP_FAMILY_STM32L4 /* Set I/O speed before AF configured */ /* EMMC SPI SLAVE: PB13/14/15 */ - /* SENSORS SPI MASTER: PB10, PB12, PC2, PC3 */ + /* SENSORS SPI controller: PB10, PB12, PC2, PC3 */ STM32_GPIO_OSPEEDR(GPIO_B) |= 0xFF300000; STM32_GPIO_OSPEEDR(GPIO_C) |= 0x000000F0; diff --git a/board/munna/board.h b/board/munna/board.h index baf68470e4..96a76b11b5 100644 --- a/board/munna/board.h +++ b/board/munna/board.h @@ -113,7 +113,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/mushu/board.h b/board/mushu/board.h index 493ef442df..a91040962c 100644 --- a/board/mushu/board.h +++ b/board/mushu/board.h @@ -23,7 +23,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_CMD_MFALLOW @@ -121,7 +121,7 @@ #define CONFIG_CUSTOM_FAN_CONTROL #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -148,6 +148,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/nami/board.c b/board/nami/board.c index 70e85fd83b..d5b585b526 100644 --- a/board/nami/board.c +++ b/board/nami/board.c @@ -218,12 +218,48 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"tcpc0", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"tcpc1", NPCX_I2C_PORT0_1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"battery", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"charger", NPCX_I2C_PORT2, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"pmic", NPCX_I2C_PORT2, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"accelgyro", NPCX_I2C_PORT3, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc0", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "tcpc1", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "battery", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "charger", + .port = NPCX_I2C_PORT2, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "pmic", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "accelgyro", + .port = NPCX_I2C_PORT3, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/nami/board.h b/board/nami/board.h index 1753ec538f..5952b1a754 100644 --- a/board/nami/board.h +++ b/board/nami/board.h @@ -73,7 +73,7 @@ #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_HAS_PRE_INIT_CALLBACK #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define CONFIG_HOSTCMD_FLASH_SPI_INFO diff --git a/board/nautilus/board.c b/board/nautilus/board.c index bcdaf568e7..f08dc20097 100644 --- a/board/nautilus/board.c +++ b/board/nautilus/board.c @@ -137,11 +137,41 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"tcpc0", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"tcpc1", NPCX_I2C_PORT0_1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"charger", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"pmic", NPCX_I2C_PORT2, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"accelgyro", NPCX_I2C_PORT3, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc0", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "tcpc1", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "charger", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "pmic", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "accelgyro", + .port = NPCX_I2C_PORT3, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/nautilus/board.h b/board/nautilus/board.h index 6be7167538..b4a05e46d1 100644 --- a/board/nautilus/board.h +++ b/board/nautilus/board.h @@ -62,7 +62,7 @@ #define CONFIG_CHIPSET_SKYLAKE #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/nightfury/board.h b/board/nightfury/board.h index 86191e104d..0b50ed75b9 100644 --- a/board/nightfury/board.h +++ b/board/nightfury/board.h @@ -20,7 +20,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -117,7 +117,7 @@ #define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL /* Thermal features */ -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -141,6 +141,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/nipperkin/board.c b/board/nipperkin/board.c index a065dad5c0..3fe31fdfd8 100644 --- a/board/nipperkin/board.c +++ b/board/nipperkin/board.c @@ -16,7 +16,7 @@ #include "driver/retimer/ps8811.h" #include "driver/retimer/ps8818.h" #include "driver/temp_sensor/sb_tsi.h" -#include "driver/temp_sensor/tmp112.h" +#include "driver/temp_sensor/pct2075.h" #include "extpower.h" #include "gpio.h" #include "hooks.h" @@ -28,7 +28,6 @@ #include "tablet_mode.h" #include "temp_sensor.h" #include "temp_sensor/thermistor.h" -#include "temp_sensor/tmp112.h" #include "thermal.h" #include "timer.h" #include "usb_mux.h" @@ -127,10 +126,10 @@ __override int board_c1_ps8818_mux_set(const struct usb_mux *me, return rv; /* Enable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 1); + ioex_set_level(IOEX_USB_C1_IN_HPD, 1); } else { /* Disable HPD on the DB */ - gpio_set_level(GPIO_USB_C1_HPD, 0); + ioex_set_level(IOEX_USB_C1_IN_HPD, 0); } return rv; @@ -146,7 +145,7 @@ DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); static void board_chipset_startup(void) { if (get_board_version() > 1) - tmp112_init(); + pct2075_init(); } DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); @@ -156,7 +155,7 @@ int board_get_soc_temp_k(int idx, int *temp_k) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_k(idx, temp_k); + return pct2075_get_val_k(idx, temp_k); } int board_get_soc_temp_mk(int *temp_mk) @@ -164,7 +163,7 @@ int board_get_soc_temp_mk(int *temp_mk) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_mk(TMP112_SOC, temp_mk); + return pct2075_get_val_mk(PCT2075_SOC, temp_mk); } int board_get_ambient_temp_mk(int *temp_mk) @@ -172,7 +171,7 @@ int board_get_ambient_temp_mk(int *temp_mk) if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) return EC_ERROR_NOT_POWERED; - return tmp112_get_val_mk(TMP112_AMB, temp_mk); + return pct2075_get_val_mk(PCT2075_AMB, temp_mk); } /* ADC Channels */ @@ -218,18 +217,18 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* Temp Sensors */ static int board_get_temp(int, int *); -const struct tmp112_sensor_t tmp112_sensors[] = { - { I2C_PORT_SENSOR, TMP112_I2C_ADDR_FLAGS0 }, - { I2C_PORT_SENSOR, TMP112_I2C_ADDR_FLAGS1 }, +const struct pct2075_sensor_t pct2075_sensors[] = { + { I2C_PORT_SENSOR, PCT2075_I2C_ADDR_FLAGS0 }, + { I2C_PORT_SENSOR, PCT2075_I2C_ADDR_FLAGS7 }, }; -BUILD_ASSERT(ARRAY_SIZE(tmp112_sensors) == TMP112_COUNT); +BUILD_ASSERT(ARRAY_SIZE(pct2075_sensors) == PCT2075_COUNT); const struct temp_sensor_t temp_sensors[] = { [TEMP_SENSOR_SOC] = { .name = "SOC", .type = TEMP_SENSOR_TYPE_BOARD, .read = board_get_soc_temp_k, - .idx = TMP112_SOC, + .idx = PCT2075_SOC, }, [TEMP_SENSOR_CHARGER] = { .name = "Charger", @@ -258,8 +257,8 @@ const struct temp_sensor_t temp_sensors[] = { [TEMP_SENSOR_AMBIENT] = { .name = "Ambient", .type = TEMP_SENSOR_TYPE_BOARD, - .read = tmp112_get_val_k, - .idx = TMP112_AMB, + .read = pct2075_get_val_k, + .idx = PCT2075_AMB, }, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); diff --git a/board/nipperkin/board.h b/board/nipperkin/board.h index f9495857d5..6521188c20 100644 --- a/board/nipperkin/board.h +++ b/board/nipperkin/board.h @@ -40,6 +40,9 @@ #define CONFIG_LED_COMMON #define CONFIG_LED_ONOFF_STATES +/* Thermal Config */ +#define CONFIG_TEMP_SENSOR_PCT2075 + #ifndef __ASSEMBLER__ #include "gpio_signal.h" @@ -73,6 +76,13 @@ enum temp_sensor_id { TEMP_SENSOR_COUNT }; +/* PCT2075 sensors */ +enum pct2075_sensor { + PCT2075_SOC, + PCT2075_AMB, + PCT2075_COUNT, +}; + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/nipperkin/led.c b/board/nipperkin/led.c index 59d03dbe83..93131400d2 100644 --- a/board/nipperkin/led.c +++ b/board/nipperkin/led.c @@ -167,18 +167,32 @@ static void led_set_battery(void) if (charge_get_percent() < 10) led_set_color_battery(LED_RIGHT_PORT, (battery_ticks % LED_TICKS_PER_CYCLE - < LED_ON_TICKS) ? LED_WHITE : LED_OFF); + < LED_ON_TICKS) ? LED_AMBER : LED_OFF); else led_set_color_battery(LED_RIGHT_PORT, LED_OFF); } - if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) - led_set_color_battery(LED_LEFT_PORT, LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + if (charge_get_percent() < 10) + led_set_color_battery(LED_LEFT_PORT, + (battery_ticks % LED_TICKS_PER_CYCLE + < LED_ON_TICKS) ? LED_AMBER : LED_OFF); + else + led_set_color_battery(LED_LEFT_PORT, LED_OFF); + } break; case PWR_STATE_ERROR: - set_active_port_color((battery_ticks & 0x2) ? - LED_WHITE : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { + led_set_color_battery(LED_RIGHT_PORT, + (battery_ticks & 0x1) ? LED_AMBER : LED_OFF); + } + + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + led_set_color_battery(LED_LEFT_PORT, + (battery_ticks & 0x1) ? LED_AMBER : LED_OFF); + } break; + case PWR_STATE_CHARGE_NEAR_FULL: set_active_port_color(LED_WHITE); break; diff --git a/board/nipperkin/thermal.c b/board/nipperkin/thermal.c index 7266e80b14..3ead6da3e5 100644 --- a/board/nipperkin/thermal.c +++ b/board/nipperkin/thermal.c @@ -18,6 +18,25 @@ #define CPUTS(outstr) cputs(CC_THERMAL, outstr) #define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) +const struct fan_conf fan_conf_0 = { + .flags = FAN_USE_RPM_MODE, + .ch = MFT_CH_0, /* Use MFT id to control fan */ + .pgood_gpio = GPIO_S0_PGOOD, + .enable_gpio = -1, +}; +const struct fan_rpm fan_rpm_0 = { + .rpm_min = 1000, + .rpm_start = 1000, + .rpm_max = 6500, +}; +const struct fan_t fans[] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(fans) == FAN_CH_COUNT); + struct fan_step { /* * Sensor 1~4 trigger point, set -1 if we're not using this diff --git a/board/nocturne/board.c b/board/nocturne/board.c index 5987bae025..7cdebfe18b 100644 --- a/board/nocturne/board.c +++ b/board/nocturne/board.c @@ -133,26 +133,43 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { { - "battery", I2C_PORT_BATTERY, 100, GPIO_EC_I2C4_BATTERY_SCL, - GPIO_EC_I2C4_BATTERY_SDA + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C4_BATTERY_SCL, + .sda = GPIO_EC_I2C4_BATTERY_SDA }, { - "power", I2C_PORT_POWER, 100, GPIO_EC_I2C0_POWER_SCL, - GPIO_EC_I2C0_POWER_SDA + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C0_POWER_SCL, + .sda = GPIO_EC_I2C0_POWER_SDA }, { - "als_gyro", I2C_PORT_ALS_GYRO, 400, GPIO_EC_I2C5_ALS_GYRO_SCL, - GPIO_EC_I2C5_ALS_GYRO_SDA + .name = "als_gyro", + .port = I2C_PORT_ALS_GYRO, + .kbps = 400, + .scl = GPIO_EC_I2C5_ALS_GYRO_SCL, + .sda = GPIO_EC_I2C5_ALS_GYRO_SDA }, { - "usbc0", I2C_PORT_USB_C0, 100, GPIO_USB_C0_SCL, GPIO_USB_C0_SDA + .name = "usbc0", + .port = I2C_PORT_USB_C0, + .kbps = 100, + .scl = GPIO_USB_C0_SCL, + .sda = GPIO_USB_C0_SDA }, { - "usbc1", I2C_PORT_USB_C1, 100, GPIO_USB_C1_SCL, GPIO_USB_C1_SDA + .name = "usbc1", + .port = I2C_PORT_USB_C1, + .kbps = 100, + .scl = GPIO_USB_C1_SCL, + .sda = GPIO_USB_C1_SDA }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/nocturne/board.h b/board/nocturne/board.h index 70da6ac3ae..7f44e0d48e 100644 --- a/board/nocturne/board.h +++ b/board/nocturne/board.h @@ -30,7 +30,7 @@ /* EC modules */ #define CONFIG_ADC #define CONFIG_BACKLIGHT_LID -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_I2C #define CONFIG_I2C_BUS_MAY_BE_UNPOWERED #define CONFIG_I2C_CONTROLLER diff --git a/board/nocturne_fp/board_rw.c b/board/nocturne_fp/board_rw.c index 0a7b38b97d..abc6bf88d8 100644 --- a/board/nocturne_fp/board_rw.c +++ b/board/nocturne_fp/board_rw.c @@ -86,7 +86,9 @@ static void spi_configure(enum fp_sensor_spi_select spi_select) gpio_config_module(MODULE_SPI_CONTROLLER, 1); } - /* Set all SPI master signal pins to very high speed: pins E2/4/5/6 */ + /* Set all SPI controller signal pins to very high speed: + * pins E2/4/5/6 + */ STM32_GPIO_OSPEEDR(GPIO_E) |= 0x00003f30; /* Enable clocks to SPI4 module (master) */ STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI4; @@ -125,7 +127,7 @@ void board_init(void) gpio_enable_interrupt(GPIO_SLP_L); /* - * Enable the SPI slave interface if the PCH is up. + * Enable the SPI peripheral interface if the PCH is up. * Do not use hook_call_deferred(), because ap_deferred() will be * called after tasks with priority higher than HOOK task (very late). */ diff --git a/board/npcx7_evb/board.c b/board/npcx7_evb/board.c index 9ddaf9bd51..7909668d2c 100644 --- a/board/npcx7_evb/board.c +++ b/board/npcx7_evb/board.c @@ -82,11 +82,41 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master0-0", NPCX_I2C_PORT0_0, 100, GPIO_I2C0_SCL0, GPIO_I2C0_SDA0}, - {"master1-0", NPCX_I2C_PORT1_0, 100, GPIO_I2C1_SCL0, GPIO_I2C1_SDA0}, - {"master2-0", NPCX_I2C_PORT2_0, 100, GPIO_I2C2_SCL0, GPIO_I2C2_SDA0}, - {"master3-0", NPCX_I2C_PORT3_0, 100, GPIO_I2C3_SCL0, GPIO_I2C3_SDA0}, - {"master7-0", NPCX_I2C_PORT7_0, 100, GPIO_I2C7_SCL0, GPIO_I2C7_SDA0}, + { + .name = "master0-0", + .port = NPCX_I2C_PORT0_0, + .kbps = 100, + .scl = GPIO_I2C0_SCL0, + .sda = GPIO_I2C0_SDA0 + }, + { + .name = "master1-0", + .port = NPCX_I2C_PORT1_0, + .kbps = 100, + .scl = GPIO_I2C1_SCL0, + .sda = GPIO_I2C1_SDA0 + }, + { + .name = "master2-0", + .port = NPCX_I2C_PORT2_0, + .kbps = 100, + .scl = GPIO_I2C2_SCL0, + .sda = GPIO_I2C2_SDA0 + }, + { + .name = "master3-0", + .port = NPCX_I2C_PORT3_0, + .kbps = 100, + .scl = GPIO_I2C3_SCL0, + .sda = GPIO_I2C3_SDA0 + }, + { + .name = "master7-0", + .port = NPCX_I2C_PORT7_0, + .kbps = 100, + .scl = GPIO_I2C7_SCL0, + .sda = GPIO_I2C7_SDA0 + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/npcx7_evb/board.h b/board/npcx7_evb/board.h index 4bad61b152..ab8b850d94 100644 --- a/board/npcx7_evb/board.h +++ b/board/npcx7_evb/board.h @@ -28,7 +28,7 @@ #define CONFIG_SPI #define CONFIG_I2C /* Features of eSPI */ -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 diff --git a/board/npcx9_evb/board.c b/board/npcx9_evb/board.c index 8bfc053fa5..b412fe8b30 100644 --- a/board/npcx9_evb/board.c +++ b/board/npcx9_evb/board.c @@ -103,11 +103,41 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master0-0", NPCX_I2C_PORT0_0, 100, GPIO_I2C0_SCL0, GPIO_I2C0_SDA0}, - {"master1-0", NPCX_I2C_PORT1_0, 100, GPIO_I2C1_SCL0, GPIO_I2C1_SDA0}, - {"master2-0", NPCX_I2C_PORT2_0, 100, GPIO_I2C2_SCL0, GPIO_I2C2_SDA0}, - {"master3-0", NPCX_I2C_PORT3_0, 100, GPIO_I2C3_SCL0, GPIO_I2C3_SDA0}, - {"master7-0", NPCX_I2C_PORT7_0, 100, GPIO_I2C7_SCL0, GPIO_I2C7_SDA0}, + { + .name = "master0-0", + .port = NPCX_I2C_PORT0_0, + .kbps = 100, + .scl = GPIO_I2C0_SCL0, + .sda = GPIO_I2C0_SDA0 + }, + { + .name = "master1-0", + .port = NPCX_I2C_PORT1_0, + .kbps = 100, + .scl = GPIO_I2C1_SCL0, + .sda = GPIO_I2C1_SDA0 + }, + { + .name = "master2-0", + .port = NPCX_I2C_PORT2_0, + .kbps = 100, + .scl = GPIO_I2C2_SCL0, + .sda = GPIO_I2C2_SDA0 + }, + { + .name = "master3-0", + .port = NPCX_I2C_PORT3_0, + .kbps = 100, + .scl = GPIO_I2C3_SCL0, + .sda = GPIO_I2C3_SDA0 + }, + { + .name = "master7-0", + .port = NPCX_I2C_PORT7_0, + .kbps = 100, + .scl = GPIO_I2C7_SCL0, + .sda = GPIO_I2C7_SDA0 + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/npcx9_evb/board.h b/board/npcx9_evb/board.h index e7e1190480..a0d209c938 100644 --- a/board/npcx9_evb/board.h +++ b/board/npcx9_evb/board.h @@ -13,7 +13,7 @@ #define CONFIG_PWM #define CONFIG_I2C /* Features of eSPI */ -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 diff --git a/board/npcx_evb/board.c b/board/npcx_evb/board.c index 61e0665b7f..ee448bbbd2 100644 --- a/board/npcx_evb/board.c +++ b/board/npcx_evb/board.c @@ -101,11 +101,41 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master0-0", NPCX_I2C_PORT0_0, 100, GPIO_I2C0_SCL0, GPIO_I2C0_SDA0}, - {"master0-1", NPCX_I2C_PORT0_1, 100, GPIO_I2C0_SCL1, GPIO_I2C0_SDA1}, - {"master1", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"master2", NPCX_I2C_PORT2, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"master3", NPCX_I2C_PORT3, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "master0-0", + .port = NPCX_I2C_PORT0_0, + .kbps = 100, + .scl = GPIO_I2C0_SCL0, + .sda = GPIO_I2C0_SDA0 + }, + { + .name = "master0-1", + .port = NPCX_I2C_PORT0_1, + .kbps = 100, + .scl = GPIO_I2C0_SCL1, + .sda = GPIO_I2C0_SDA1 + }, + { + .name = "master1", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "master2", + .port = NPCX_I2C_PORT2, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "master3", + .port = NPCX_I2C_PORT3, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/npcx_evb/board.h b/board/npcx_evb/board.h index fc12b6d80a..5a22435396 100644 --- a/board/npcx_evb/board.h +++ b/board/npcx_evb/board.h @@ -12,7 +12,7 @@ #define CONFIG_ADC #define CONFIG_PWM #define CONFIG_SPI -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_PECI /* Optional features */ diff --git a/board/npcx_evb_arm/board.c b/board/npcx_evb_arm/board.c index 4ee03e7a00..abb6e2279b 100644 --- a/board/npcx_evb_arm/board.c +++ b/board/npcx_evb_arm/board.c @@ -79,11 +79,41 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master0-0", NPCX_I2C_PORT0_0, 100, GPIO_I2C0_SCL0, GPIO_I2C0_SDA0}, - {"master0-1", NPCX_I2C_PORT0_1, 100, GPIO_I2C0_SCL1, GPIO_I2C0_SDA1}, - {"master1", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"master2", NPCX_I2C_PORT2, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"master3", NPCX_I2C_PORT3, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "master0-0", + .port = NPCX_I2C_PORT0_0, + .kbps = 100, + .scl = GPIO_I2C0_SCL0, + .sda = GPIO_I2C0_SDA0 + }, + { + .name = "master0-1", + .port = NPCX_I2C_PORT0_1, + .kbps = 100, + .scl = GPIO_I2C0_SCL1, + .sda = GPIO_I2C0_SDA1 + }, + { + .name = "master1", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "master2", + .port = NPCX_I2C_PORT2, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "master3", + .port = NPCX_I2C_PORT3, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/npcx_evb_arm/board.h b/board/npcx_evb_arm/board.h index c3fd341365..a56cec9783 100644 --- a/board/npcx_evb_arm/board.h +++ b/board/npcx_evb_arm/board.h @@ -11,7 +11,7 @@ /* Optional modules */ #define CONFIG_ADC #define CONFIG_PWM -#define CONFIG_HOSTCMD_SHI /* Used in ARM-based platform for host interface */ +#define CONFIG_HOST_INTERFACE_SHI /* ARM-based platform for host interface */ /* Optional features */ #define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands for testing */ diff --git a/board/nucleo-dartmonkey/board.c b/board/nucleo-dartmonkey/board.c index a7851ec00b..ea0d11eaf5 100644 --- a/board/nucleo-dartmonkey/board.c +++ b/board/nucleo-dartmonkey/board.c @@ -76,7 +76,9 @@ static void spi_configure(void) { /* Configure SPI GPIOs */ gpio_config_module(MODULE_SPI_CONTROLLER, 1); - /* Set all SPI master signal pins to very high speed: pins E2/4/5/6 */ + /* Set all SPI controller signal pins to very high speed: + * pins E2/4/5/6 + */ STM32_GPIO_OSPEEDR(GPIO_E) |= 0x00003f30; /* Enable clocks to SPI4 module (master) */ STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI4; @@ -97,7 +99,7 @@ static void board_init(void) gpio_enable_interrupt(GPIO_SLP_L); /* - * Enable the SPI slave interface if the PCH is up. + * Enable the SPI peripheral interface if the PCH is up. * Do not use hook_call_deferred(), because ap_deferred() will be * called after tasks with priority higher than HOOK task (very late). */ diff --git a/board/nucleo-f072rb/board.c b/board/nucleo-f072rb/board.c index 66e8960ce7..078af171cb 100644 --- a/board/nucleo-f072rb/board.c +++ b/board/nucleo-f072rb/board.c @@ -39,7 +39,13 @@ DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT); #ifdef CTS_MODULE_I2C const struct i2c_port_t i2c_ports[] = { - {"test", STM32_I2C1_PORT, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + { + .name = "test", + .port = STM32_I2C1_PORT, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/nucleo-f411re/board.c b/board/nucleo-f411re/board.c index 074507e039..96e7fefb69 100644 --- a/board/nucleo-f411re/board.c +++ b/board/nucleo-f411re/board.c @@ -52,8 +52,13 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/nucleo-f412zg/board.c b/board/nucleo-f412zg/board.c index 4324101da9..da3b4a3d4d 100644 --- a/board/nucleo-f412zg/board.c +++ b/board/nucleo-f412zg/board.c @@ -60,7 +60,7 @@ static void board_init(void) gpio_enable_interrupt(GPIO_PCH_SLP_S0_L); /* - * Enable the SPI slave interface if the PCH is up. + * Enable the SPI peripheral interface if the PCH is up. * Do not use hook_call_deferred(), because ap_deferred() will be * called after tasks with priority higher than HOOK task (very late). */ diff --git a/board/nucleo-h743zi/board.c b/board/nucleo-h743zi/board.c index f1493658aa..c69a456425 100644 --- a/board/nucleo-h743zi/board.c +++ b/board/nucleo-h743zi/board.c @@ -60,7 +60,7 @@ static void board_init(void) gpio_enable_interrupt(GPIO_PCH_SLP_S0_L); /* - * Enable the SPI slave interface if the PCH is up. + * Enable the SPI peripheral interface if the PCH is up. * Do not use hook_call_deferred(), because ap_deferred() will be * called after tasks with priority higher than HOOK task (very late). */ diff --git a/board/nuwani/board.c b/board/nuwani/board.c index 8004e25b37..a2d659af27 100644 --- a/board/nuwani/board.c +++ b/board/nuwani/board.c @@ -32,11 +32,41 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -100,8 +130,6 @@ struct motion_sensor_t base_accel_1 = { .mutex = &g_base_mutex_1, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &lsm6dsm_base_standard_ref, @@ -132,8 +160,6 @@ struct motion_sensor_t base_gyro_1 = { .mutex = &g_base_mutex_1, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/oak/board.c b/board/oak/board.c index e8eba6d45b..0275981446 100644 --- a/board/oak/board.c +++ b/board/oak/board.c @@ -97,8 +97,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"battery", I2C_PORT_BATTERY, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"pd", I2C_PORT_PD_MCU, 1000, GPIO_I2C1_SCL, GPIO_I2C1_SDA} + { + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "pd", + .port = I2C_PORT_PD_MCU, + .kbps = 1000, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + } }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/oak/board.h b/board/oak/board.h index e82907a508..2c30e6185e 100644 --- a/board/oak/board.h +++ b/board/oak/board.h @@ -163,7 +163,7 @@ #define I2C_PORT_TCPC 1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* First SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* First SPI controller port (SPI2) */ /* Ambient Light Sensor address */ #define OPT3001_I2C_ADDR_FLAGS OPT3001_I2C_ADDR1_FLAGS diff --git a/board/palkia/board.h b/board/palkia/board.h index 010bfb908b..783f01c444 100644 --- a/board/palkia/board.h +++ b/board/palkia/board.h @@ -16,7 +16,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -56,7 +56,7 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -78,6 +78,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/pazquel/board.c b/board/pazquel/board.c index 8d7e679190..8cab9ee887 100644 --- a/board/pazquel/board.c +++ b/board/pazquel/board.c @@ -141,16 +141,41 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -193,9 +218,8 @@ const struct adc_t adc_channels[] = { BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); const struct pwm_t pwm_channels[] = { - [PWM_CH_KBLIGHT] = { .channel = 3, .flags = 0, .freq = 10000 }, - /* TODO(waihong): Assign a proper frequency. */ - [PWM_CH_DISPLIGHT] = { .channel = 5, .flags = 0, .freq = 4800 }, + [PWM_CH_KBLIGHT] = { .channel = 3, .flags = 0, .freq = 10000 }, + [PWM_CH_DISPLIGHT] = { .channel = 5, .flags = 0, .freq = 20000 }, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/pazquel/board.h b/board/pazquel/board.h index a143a3fe7f..fa1ab621f8 100644 --- a/board/pazquel/board.h +++ b/board/pazquel/board.h @@ -37,6 +37,7 @@ /* USB */ #define CONFIG_USB_PD_TCPM_PS8805 +#define CONFIG_USB_PD_TCPM_PS8805_FORCE_DID #define CONFIG_USBC_PPC_SN5S330 #define CONFIG_USB_PD_PORT_MAX_COUNT 2 diff --git a/board/pazquel/build.mk b/board/pazquel/build.mk index f03287a2ee..f130540bd4 100644 --- a/board/pazquel/build.mk +++ b/board/pazquel/build.mk @@ -14,3 +14,4 @@ BASEBOARD:=trogdor board-y+=battery.o board-y+=board.o board-y+=led.o +board-y+=usbc_config.o diff --git a/board/pazquel/usbc_config.c b/board/pazquel/usbc_config.c new file mode 100644 index 0000000000..8f3fb02c30 --- /dev/null +++ b/board/pazquel/usbc_config.c @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "usb_pd.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/pdeval-stm32f072/board.c b/board/pdeval-stm32f072/board.c index 8c62c10b79..525f14a4af 100644 --- a/board/pdeval-stm32f072/board.c +++ b/board/pdeval-stm32f072/board.c @@ -53,7 +53,13 @@ void board_reset_pd_mcu(void) /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"tcpc", I2C_PORT_TCPC, 400 /* kHz */, GPIO_I2C0_SCL, GPIO_I2C0_SDA} + { + .name = "tcpc", + .port = I2C_PORT_TCPC, + .kbps = 400 /* kHz */, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + } }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/pdeval-stm32f072/usb_pd_policy.c b/board/pdeval-stm32f072/usb_pd_policy.c index 6fdb894eed..b7425ce66c 100644 --- a/board/pdeval-stm32f072/usb_pd_policy.c +++ b/board/pdeval-stm32f072/usb_pd_policy.c @@ -243,6 +243,7 @@ __override int svdm_dp_config(int port, uint32_t *payload) __override void svdm_dp_post_config(int port) { + bool unused; const struct usb_mux *mux = &usb_muxes[port]; dp_flags[port] |= DP_FLAGS_DP_ON; @@ -252,7 +253,8 @@ __override void svdm_dp_post_config(int port) /* Note: Usage is deprecated, use usb_mux_hpd_update instead */ if (IS_ENABLED(CONFIG_USB_PD_TCPM_ANX7447)) anx7447_tcpc_update_hpd_status(mux, USB_PD_MUX_HPD_LVL | - USB_PD_MUX_HPD_IRQ_DEASSERTED); + USB_PD_MUX_HPD_IRQ_DEASSERTED, + &unused); } __override int svdm_dp_attention(int port, uint32_t *payload) @@ -261,6 +263,8 @@ __override int svdm_dp_attention(int port, uint32_t *payload) int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); const struct usb_mux *mux = &usb_muxes[port]; + bool unused; + mux_state_t mux_state = (lvl ? USB_PD_MUX_HPD_LVL : USB_PD_MUX_HPD_LVL_DEASSERTED) | (irq ? USB_PD_MUX_HPD_IRQ : @@ -268,7 +272,7 @@ __override int svdm_dp_attention(int port, uint32_t *payload) /* Note: Usage is deprecated, use usb_mux_hpd_update instead */ CPRINTS("Attention: 0x%x", payload[1]); - anx7447_tcpc_update_hpd_status(mux, mux_state); + anx7447_tcpc_update_hpd_status(mux, mux_state, &unused); #endif dp_status[port] = payload[1]; diff --git a/board/phaser/board.c b/board/phaser/board.c index 488880c1fc..3db1dc2345 100644 --- a/board/phaser/board.c +++ b/board/phaser/board.c @@ -167,8 +167,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &standard_rot_ref, @@ -199,8 +197,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -247,6 +243,11 @@ static void cbi_init(void) } DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_INIT_I2C + 1); +void board_hibernate_late(void) +{ + NPCX_KBSINPU = 0x0A; +} + /* This callback disables keyboard when convertibles are fully open */ __override void lid_angle_peripheral_enable(int enable) { diff --git a/board/phaser/board.h b/board/phaser/board.h index 443dbf37c1..a03782b245 100644 --- a/board/phaser/board.h +++ b/board/phaser/board.h @@ -13,6 +13,20 @@ #define VARIANT_OCTOPUS_CHARGER_ISL9238 #include "baseboard.h" +/* b/203442963 + * It's workaround to reduce keyboard's "Silver Migration". + * From keyboard vendor's feedback, there are two factors to cause + * "Silver Migration". + * 1. A voltage potential between trace. + * 2. The presence of an electrolyte , such as moisture. + * The reason cause voltage potential between KSIxx trace is EC enter ec + * hibernate PSL and turn EC's VCC1 power off. Besides KSI2, the other + * KSIxx will be turn off. KSI2 is powered by H1. + * To avoid voltage potential is keep KSIxx on. That means not to enter + * ec hibernate PSL. + */ +#undef CONFIG_HIBERNATE_PSL + #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD #define CONFIG_VOLUME_BUTTONS diff --git a/board/pico/board.c b/board/pico/board.c index e930c7c998..eaecf77f31 100644 --- a/board/pico/board.c +++ b/board/pico/board.c @@ -207,9 +207,27 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", IT83XX_I2C_CH_C, 400, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"sensor", IT83XX_I2C_CH_B, 400, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, - {"battery", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, + { + .name = "typec", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_I2C_C_SCL, + .sda = GPIO_I2C_C_SDA + }, + { + .name = "sensor", + .port = IT83XX_I2C_CH_B, + .kbps = 400, + .scl = GPIO_I2C_B_SCL, + .sda = GPIO_I2C_B_SDA + }, + { + .name = "battery", + .port = IT83XX_I2C_CH_A, + .kbps = 100, + .scl = GPIO_I2C_A_SCL, + .sda = GPIO_I2C_A_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -242,8 +260,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/pirika/board.c b/board/pirika/board.c index 098e6baa9b..7da53b686c 100644 --- a/board/pirika/board.c +++ b/board/pirika/board.c @@ -631,8 +631,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = NULL, @@ -660,8 +658,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/plankton/board.c b/board/plankton/board.c index a361f5fff3..5a62f63c86 100644 --- a/board/plankton/board.c +++ b/board/plankton/board.c @@ -460,8 +460,13 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/pompom/board.c b/board/pompom/board.c index 855a8c305d..f961a12921 100644 --- a/board/pompom/board.c +++ b/board/pompom/board.c @@ -129,14 +129,34 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/pompom/build.mk b/board/pompom/build.mk index a044fa58cb..04c90da3fe 100644 --- a/board/pompom/build.mk +++ b/board/pompom/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o +board-y=battery.o board.o led.o usbc_config.o diff --git a/board/pompom/usbc_config.c b/board/pompom/usbc_config.c new file mode 100644 index 0000000000..8f3fb02c30 --- /dev/null +++ b/board/pompom/usbc_config.c @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "usb_pd.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/poppy/board.c b/board/poppy/board.c index 2124faa421..9dc0250e80 100644 --- a/board/poppy/board.c +++ b/board/poppy/board.c @@ -179,11 +179,41 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"tcpc", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"als", NPCX_I2C_PORT0_1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"charger", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"pmic", NPCX_I2C_PORT2, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"accelgyro", NPCX_I2C_PORT3, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "tcpc", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "als", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "charger", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "pmic", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "accelgyro", + .port = NPCX_I2C_PORT3, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/poppy/board.h b/board/poppy/board.h index 98fcfdbfa9..ca287c7c6e 100644 --- a/board/poppy/board.h +++ b/board/poppy/board.h @@ -63,7 +63,7 @@ #define CONFIG_CHIPSET_SKYLAKE #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define GPIO_PG_EC_RSMRST_ODL GPIO_RSMRST_L_PGOOD diff --git a/board/primus/board.c b/board/primus/board.c index 0881ab1c86..d0fa9f6cae 100644 --- a/board/primus/board.c +++ b/board/primus/board.c @@ -8,6 +8,7 @@ #include "charge_ramp.h" #include "charger.h" #include "common.h" +#include "charge_manager.h" #include "charge_state_v2.h" #include "compile_time_macros.h" #include "console.h" @@ -35,6 +36,8 @@ #define KBLIGHT_LED_ON_LVL 100 #define KBLIGHT_LED_OFF_LVL 0 +#define PD_MAX_SUSPEND_CURRENT_MA 3000 + /******************************************************************************/ /* USB-A charging control */ @@ -123,12 +126,45 @@ __override void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, int charge_mv) { /* - * Follow OEM request to limit the input current to - * 97% negotiated limit. + * Need to set different input current limit depend on system state. + * Guard adapter plug/ un-plug here. */ - charge_ma = charge_ma * 97 / 100; + + if (((max_ma == PD_MAX_CURRENT_MA) && + chipset_in_state(CHIPSET_STATE_ANY_OFF)) || + (max_ma != PD_MAX_CURRENT_MA)) + charge_ma = charge_ma * 97 / 100; + else + charge_ma = charge_ma * 93 / 100; charge_set_input_current_limit(MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); } + +static void configure_input_current_limit(void) +{ + /* + * If adapter == 3250mA, we need system be charged at 3150mA in S5. + * And system be charged at 3000mA in S0. + */ + int adapter_current_ma; + int adapter_current_mv; + /* Get adapter voltage/ current */ + adapter_current_mv = charge_manager_get_charger_voltage(); + adapter_current_ma = charge_manager_get_charger_current(); + + if ((adapter_current_ma == PD_MAX_CURRENT_MA) && + chipset_in_or_transitioning_to_state(CHIPSET_STATE_SUSPEND)) + adapter_current_ma = PD_MAX_SUSPEND_CURRENT_MA; + else + adapter_current_ma = adapter_current_ma * 97 / 100; + + charge_set_input_current_limit(MAX(adapter_current_ma, + CONFIG_CHARGER_INPUT_CURRENT), + adapter_current_mv); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, configure_input_current_limit, + HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN_COMPLETE, configure_input_current_limit, + HOOK_PRIO_DEFAULT); diff --git a/board/primus/board.h b/board/primus/board.h index 5b87eb6477..830ad20529 100644 --- a/board/primus/board.h +++ b/board/primus/board.h @@ -49,8 +49,8 @@ * Passive USB-C cables only support up to 60W. */ #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 /* @@ -71,6 +71,7 @@ #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 @@ -124,12 +125,14 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* LED */ #define CONFIG_BATTERY_LEVEL_NEAR_FULL 91 +/* Fan features */ +#define CONFIG_CUSTOM_FAN_CONTROL #define CONFIG_FANS FAN_CH_COUNT #define RPM_DEVIATION 1 diff --git a/board/primus/build.mk b/board/primus/build.mk index d6fe9b4808..217f95da10 100644 --- a/board/primus/build.mk +++ b/board/primus/build.mk @@ -23,4 +23,5 @@ board-y+=led.o board-y+=pwm.o board-y+=ps2.o board-y+=sensors.o +board-y+=thermal.o board-y+=usbc_config.o diff --git a/board/primus/ec.tasklist b/board/primus/ec.tasklist index 2a9c288ee6..bf2ec04c62 100644 --- a/board/primus/ec.tasklist +++ b/board/primus/ec.tasklist @@ -18,6 +18,7 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, BASEBOARD_CHARGER_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/primus/fans.c b/board/primus/fans.c index d966056331..001c6fde5c 100644 --- a/board/primus/fans.c +++ b/board/primus/fans.c @@ -31,15 +31,12 @@ static const struct fan_conf fan_conf_0 = { }; /* - * TOOD(b/180681346): need to update for real fan - * - * Prototype fan spins at about 7200 RPM at 100% PWM. - * Set minimum at around 30% PWM. + * Set maximum rpm at 4800/ minimum rpm at 1800. */ static const struct fan_rpm fan_rpm_0 = { - .rpm_min = 2200, - .rpm_start = 2200, - .rpm_max = 7200, + .rpm_min = 1800, + .rpm_start = 1800, + .rpm_max = 4800, }; const struct fan_t fans[FAN_CH_COUNT] = { diff --git a/board/primus/fw_config.c b/board/primus/fw_config.c index 9506e778b5..0384d05b9d 100644 --- a/board/primus/fw_config.c +++ b/board/primus/fw_config.c @@ -54,6 +54,11 @@ union primus_cbi_fw_config get_fw_config(void) return fw_config; } +enum ec_cfg_mlb_usb ec_cfg_mlb_usb(void) +{ + return fw_config.mlb_usb; +} + enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void) { return fw_config.usb_db; diff --git a/board/primus/fw_config.h b/board/primus/fw_config.h index cbccbd07a9..f8792f1443 100644 --- a/board/primus/fw_config.h +++ b/board/primus/fw_config.h @@ -25,14 +25,21 @@ enum ec_cfg_keyboard_backlight_type { KEYBOARD_BACKLIGHT_ENABLED = 1 }; +enum ec_cfg_mlb_usb { + MLB_USB_TBT = 0, + MLB_USB_USB4 = 1 +}; + union primus_cbi_fw_config { struct { enum ec_cfg_usb_db_type usb_db : 4; uint32_t sd_db : 2; - uint32_t lte_db : 1; + uint32_t reserved_0 : 1; enum ec_cfg_keyboard_backlight_type kb_bl : 1; uint32_t audio : 3; - uint32_t reserved_1 : 21; + uint32_t cellular_db : 2; + enum ec_cfg_mlb_usb mlb_usb : 1; + uint32_t reserved_1 : 18; }; uint32_t raw_value; }; @@ -45,6 +52,13 @@ union primus_cbi_fw_config { union primus_cbi_fw_config get_fw_config(void); /** + * Get MLB USB type from FW_CONFIG. + * + * @return the MLB USB type. + */ +enum ec_cfg_mlb_usb ec_cfg_mlb_usb(void); + +/** * Get the USB daughter board type from FW_CONFIG. * * @return the USB daughter board type. diff --git a/board/primus/i2c.c b/board/primus/i2c.c index 3a4fe69b0c..019862f441 100644 --- a/board/primus/i2c.c +++ b/board/primus/i2c.c @@ -17,7 +17,7 @@ const struct i2c_port_t i2c_ports[] = { */ .name = "tcpc0", .port = I2C_PORT_USB_C0_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C0_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C0_TCPC_SDA, }, @@ -44,7 +44,7 @@ const struct i2c_port_t i2c_ports[] = { */ .name = "tcpc1", .port = I2C_PORT_USB_C1_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, }, diff --git a/board/primus/thermal.c b/board/primus/thermal.c new file mode 100644 index 0000000000..f5e200b14c --- /dev/null +++ b/board/primus/thermal.c @@ -0,0 +1,157 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "chipset.h" +#include "common.h" +#include "console.h" +#include "fan.h" +#include "hooks.h" +#include "host_command.h" +#include "temp_sensor.h" +#include "thermal.h" +#include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_THERMAL, outstr) +#define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) + + + +struct fan_step { + /* + * Sensor 1~4 trigger point, set -1 if we're not using this + * sensor to determine fan speed. + */ + int8_t on[TEMP_SENSOR_COUNT]; + /* + * Sensor 1~4 trigger point, set -1 if we're not using this + * sensor to determine fan speed. + */ + int8_t off[TEMP_SENSOR_COUNT]; + /* Fan rpm */ + uint16_t rpm[FAN_CH_COUNT]; +}; + +static const struct fan_step fan_table[] = { + { + /* level 0 */ + .on = {40, -1, -1, -1, -1}, + .off = {0, -1, -1, -1, -1}, + .rpm = {0}, + }, + { + /* level 1 */ + .on = {42, -1, -1, -1, -1}, + .off = {40, -1, -1, -1, -1}, + .rpm = {1800}, + }, + { + /* level 2 */ + .on = {43, -1, -1, -1, -1}, + .off = {42, -1, -1, -1, -1}, + .rpm = {2000}, + }, + { + /* level 3 */ + .on = {44, -1, -1, -1, -1}, + .off = {43, -1, -1, -1, -1}, + .rpm = {2200}, + }, + { + /* level 4 */ + .on = {45, -1, -1, -1, -1}, + .off = {44, -1, -1, -1, -1}, + .rpm = {2500}, + }, + { + /* level 5 */ + .on = {46, -1, -1, -1, -1}, + .off = {45, -1, -1, -1, -1}, + .rpm = {2800}, + }, + { + /* level 6 */ + .on = {47, -1, -1, -1, -1}, + .off = {46, -1, -1, -1, -1}, + .rpm = {3000}, + }, + { + /* level 7 */ + .on = {75, -1, -1, -1, -1}, + .off = {72, -1, -1, -1, -1}, + .rpm = {3200}, + }, +}; +const int num_fan_levels = ARRAY_SIZE(fan_table); + +int fan_table_to_rpm(int fan, int *temp, enum temp_sensor_id temp_sensor) +{ + /* current fan level */ + static int current_level; + /* previous fan level */ + static int prev_current_level; + + /* previous sensor temperature */ + static int prev_temp[TEMP_SENSOR_COUNT]; + int i; + int new_rpm = 0; + + /* + * Compare the current and previous temperature, we have + * the three paths : + * 1. decreasing path. (check the release point) + * 2. increasing path. (check the trigger point) + * 3. invariant path. (return the current RPM) + */ + if (temp[temp_sensor] < prev_temp[temp_sensor]) { + for (i = current_level; i > 0; i--) { + if (temp[temp_sensor] < + fan_table[i].off[temp_sensor]) + current_level = i - 1; + else + break; + } + } else if (temp[temp_sensor] > + prev_temp[temp_sensor]) { + for (i = current_level; i < num_fan_levels; i++) { + if (temp[temp_sensor] > + fan_table[i].on[temp_sensor]) + current_level = i + 1; + else + break; + } + } + if (current_level < 0) + current_level = 0; + + if (current_level != prev_current_level) { + CPRINTS("temp: %d, prev_temp: %d", temp[temp_sensor], + prev_temp[temp_sensor]); + CPRINTS("current_level: %d", current_level); + } + + prev_temp[temp_sensor] = temp[temp_sensor]; + prev_current_level = current_level; + + switch (fan) { + case FAN_CH_0: + new_rpm = fan_table[current_level].rpm[FAN_CH_0]; + break; + default: + break; + } + return new_rpm; +} +void board_override_fan_control(int fan, int *temp) +{ + if (chipset_in_state(CHIPSET_STATE_ON)) { + fan_set_rpm_mode(FAN_CH(fan), 1); + fan_set_rpm_target(FAN_CH(fan), + fan_table_to_rpm(FAN_CH(fan), temp, TEMP_SENSOR_1_DDR_SOC)); + } else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) { + /* Stop fan when enter S0ix */ + fan_set_rpm_mode(FAN_CH(fan), 1); + fan_set_rpm_target(FAN_CH(fan), 0); + } +} diff --git a/board/primus/usbc_config.c b/board/primus/usbc_config.c index 2207b1b085..44f58c184e 100644 --- a/board/primus/usbc_config.c +++ b/board/primus/usbc_config.c @@ -274,3 +274,11 @@ __override bool board_is_dts_port(int port) { return port == USBC_PORT_C0; } + +__override enum tbt_compat_cable_speed board_get_max_tbt_speed(int port) +{ + if (ec_cfg_mlb_usb()) + return TBT_SS_U32_GEN1_GEN2; + + return TBT_SS_TBT_GEN3; +} diff --git a/board/puff/board.c b/board/puff/board.c index b30ca74221..bf22657bf4 100644 --- a/board/puff/board.c +++ b/board/puff/board.c @@ -288,11 +288,41 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/puff/board.h b/board/puff/board.h index 9330d128ef..185c3d0076 100644 --- a/board/puff/board.h +++ b/board/puff/board.h @@ -38,7 +38,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -119,7 +119,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -278,6 +278,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/puff/gpio.inc b/board/puff/gpio.inc index 7e62488cee..b51f595e81 100644 --- a/board/puff/gpio.inc +++ b/board/puff/gpio.inc @@ -64,7 +64,7 @@ GPIO_INT(USB_A4_OC_ODL, PIN(B, 0), GPIO_OUT_LOW | GPIO_INT_BOTH, port_ocp GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) diff --git a/board/quackingstick/board.c b/board/quackingstick/board.c index 11fbb6cb12..749bcdc4fd 100644 --- a/board/quackingstick/board.c +++ b/board/quackingstick/board.c @@ -102,14 +102,34 @@ static void board_connect_c0_sbu(enum gpio_signal s) /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -243,8 +263,8 @@ static enum lid_accelgyro_type lid_accelgyro_config; /* Matrix to rotate accelerometer into standard reference frame */ const mat33_fp_t lid_standard_ref = { - { 0, FLOAT_TO_FP(-1), 0}, - { FLOAT_TO_FP(1), 0, 0}, + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, { 0, 0, FLOAT_TO_FP(1)} }; @@ -373,13 +393,15 @@ void motion_interrupt(enum gpio_signal signal) static void board_init(void) { /* - * The rev-1 hardware doesn't have the external pull-up fix for the bug - * b/177611071. It requires rework to stuff the resistor. For people who - * has difficulty to do the rework, this is a workaround, which makes - * the GPIO push-pull, instead of open-drain. + * The rev-1 hardware use PP1800_SENSORS as the power of the hall IC, + * it cause the LID_OPEN_EC wake EC immediately when EC enter hibernate. */ - if (system_get_board_version() == 1) - gpio_set_flags(GPIO_HIBERNATE_L, GPIO_OUTPUT); + if (system_get_board_version() <= 1) { + hibernate_wake_pins[0] = GPIO_AC_PRESENT; + hibernate_wake_pins[1] = GPIO_POWER_BUTTON_L; + hibernate_wake_pins[2] = GPIO_EC_RST_ODL; + hibernate_wake_pins_used = 3; + } /* Enable BC1.2 interrupts */ gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_L); @@ -392,6 +414,10 @@ static void board_init(void) */ gpio_enable_interrupt(GPIO_CCD_MODE_ODL); + /* Enable pen input detect interrupt */ + if (system_get_board_version() >= 2) + gpio_enable_interrupt(GPIO_EC_PEN_PDCT_L); + /* Set the backlight duty cycle to 0. AP will override it later. */ pwm_set_duty(PWM_CH_DISPLIGHT, 0); } @@ -445,7 +471,7 @@ void board_hibernate(void) * Board rev 1+ has the hardware fix. Don't need the following * workaround. */ - if (system_get_board_version() >= 1) + if (system_get_board_version() > 1) return; /* @@ -606,6 +632,33 @@ void board_set_charge_limit(int port, int supplier, int charge_ma, charge_mv); } +/** + * Handle debounced pen input changing state. + */ +static void pen_input_deferred(void) +{ + bool pen_charge_enable = !gpio_get_level(GPIO_EC_PEN_PDCT_L) && + !chipset_in_state(CHIPSET_STATE_ANY_OFF); + + gpio_set_level(GPIO_PEN_PWR_EN, pen_charge_enable); + + CPRINTS("Pen charge %sable", pen_charge_enable ? "en" : "dis"); +} +DECLARE_DEFERRED(pen_input_deferred); + +void pen_input_interrupt(enum gpio_signal signal) +{ + /* pen input debounce time */ + hook_call_deferred(&pen_input_deferred_data, (100 * MSEC)); +} + +static void pen_charge_check(void) +{ + hook_call_deferred(&pen_input_deferred_data, (100 * MSEC)); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pen_charge_check, HOOK_PRIO_LAST); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pen_charge_check, HOOK_PRIO_LAST); + uint16_t tcpc_get_alert_status(void) { uint16_t status = 0; diff --git a/board/quackingstick/board.h b/board/quackingstick/board.h index 7ad8cd227c..0d412246ec 100644 --- a/board/quackingstick/board.h +++ b/board/quackingstick/board.h @@ -116,6 +116,7 @@ void board_set_tcpc_power_mode(int port, int mode); void base_detect_interrupt(enum gpio_signal signal); /* motion sensor interrupt */ void motion_interrupt(enum gpio_signal signal); +void pen_input_interrupt(enum gpio_signal signal); #endif /* !defined(__ASSEMBLER__) */ diff --git a/board/quackingstick/build.mk b/board/quackingstick/build.mk index 74b6b95e4d..452abeb591 100644 --- a/board/quackingstick/build.mk +++ b/board/quackingstick/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o base_detect.o +board-y=battery.o board.o led.o base_detect.o usbc_config.o diff --git a/board/quackingstick/gpio.inc b/board/quackingstick/gpio.inc index 09983989d2..c126b59977 100644 --- a/board/quackingstick/gpio.inc +++ b/board/quackingstick/gpio.inc @@ -39,6 +39,7 @@ GPIO_INT(BASE_DET_L, PIN(3, 7), GPIO_INT_BOTH, base_detect_interrupt) /* /* Sensor interrupts */ GPIO_INT(ACCEL_GYRO_INT_L, PIN(A, 0), GPIO_INT_FALLING, motion_interrupt) /* Accelerometer/gyro interrupt */ +GPIO_INT(EC_PEN_PDCT_L, PIN(5, 0), GPIO_INT_BOTH, pen_input_interrupt) /* Pen input detect */ /* * EC_RST_ODL acts as a wake source from hibernate mode. However, it does not @@ -62,6 +63,7 @@ GPIO(EC_BL_DISABLE_L, PIN(B, 6), GPIO_OUT_LOW) /* Backlight disable sign /* Base detection */ GPIO(EN_BASE, PIN(0, 4), GPIO_OUT_LOW) /* Enable power to detachable base */ +GPIO(PEN_PWR_EN, PIN(8, 2), GPIO_OUT_LOW) /* Pen input charge */ /* USB-C */ GPIO(USB_C0_PD_RST_L, PIN(F, 1), GPIO_ODR_HIGH) /* Port-0 TCPC chip reset, actaully Open-Drain */ @@ -122,12 +124,10 @@ GPIO(ARM_X86, PIN(6, 6), GPIO_OUT_LOW) /* NC, low for power savin /* Unused GPIOs, NC. Apply PU for power saving */ UNUSED(PIN(F, 5)) UNUSED(PIN(4, 0)) -UNUSED(PIN(8, 2)) UNUSED(PIN(7, 4)) UNUSED(PIN(7, 3)) UNUSED(PIN(D, 7)) UNUSED(PIN(6, 0)) -UNUSED(PIN(5, 0)) UNUSED(PIN(C, 5)) UNUSED(PIN(3, 0)) UNUSED(PIN(E, 4)) diff --git a/board/quackingstick/usbc_config.c b/board/quackingstick/usbc_config.c new file mode 100644 index 0000000000..b41eb2ecf1 --- /dev/null +++ b/board/quackingstick/usbc_config.c @@ -0,0 +1,98 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "temp_sensor.h" +#include "usb_pd.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +struct temp_chg_step { + int low; /* temp thershold ('C) to lower level*/ + int high; /* temp thershold ('C) to higher level */ + int current; /* charging limitation (mA) */ +}; + +static const struct temp_chg_step temp_chg_table[] = { + {.low = 0, .high = 50, .current = 3000}, /* Lv0: normal charge */ + {.low = 48, .high = 53, .current = 1500}, + {.low = 51, .high = 56, .current = 1000}, + {.low = 54, .high = 100, .current = 800}, +}; +#define NUM_TEMP_CHG_LEVELS ARRAY_SIZE(temp_chg_table) + +int charger_profile_override(struct charge_state_data *curr) +{ + static int current_level; + int charger_temp, charger_temp_c; + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* charge current control depends on temp if the system is on */ + if (chipset_in_state(CHIPSET_STATE_ON)) { + temp_sensor_read(TEMP_SENSOR_SYS2, &charger_temp); + charger_temp_c = K_TO_C(charger_temp); + + if (charger_temp_c <= temp_chg_table[current_level].low) + current_level--; + else if (charger_temp_c >= temp_chg_table[current_level].high) + current_level++; + + if (current_level < 0) + current_level = 0; + + if (current_level >= NUM_TEMP_CHG_LEVELS) + current_level = NUM_TEMP_CHG_LEVELS - 1; + + curr->requested_current = MIN(curr->requested_current, + temp_chg_table[current_level].current); + } + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/quiche/board.c b/board/quiche/board.c index e49b2e1b1a..76004ee37e 100644 --- a/board/quiche/board.c +++ b/board/quiche/board.c @@ -345,6 +345,30 @@ int dock_get_mf_preference(void) return mf; } +static void board_usb_tc_connect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* + * The EC needs to indicate to the MST hub when the host port is + * attached. GPIO_UFP_PLUG_DET is used for this purpose. + */ + if (port == USB_PD_PORT_HOST) + gpio_set_level(GPIO_UFP_PLUG_DET, 0); +} +DECLARE_HOOK(HOOK_USB_PD_CONNECT, board_usb_tc_connect, HOOK_PRIO_DEFAULT); + +static void board_usb_tc_disconnect(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + + /* Only the host port disconnect is relevant */ + if (port == USB_PD_PORT_HOST) + gpio_set_level(GPIO_UFP_PLUG_DET, 1); +} +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, board_usb_tc_disconnect, \ + HOOK_PRIO_DEFAULT); + #endif /* SECTION_IS_RW */ static void board_init(void) diff --git a/board/rainier/board.c b/board/rainier/board.c index 0f9c388399..15fbfeb8ef 100644 --- a/board/rainier/board.c +++ b/board/rainier/board.c @@ -72,7 +72,13 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/rainier/board.h b/board/rainier/board.h index a323a90889..a980afba50 100644 --- a/board/rainier/board.h +++ b/board/rainier/board.h @@ -128,7 +128,7 @@ #define I2C_PORT_TCPC0 1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_MKBP_INPUT_DEVICES #define CONFIG_MKBP_EVENT diff --git a/board/rammus/board.c b/board/rammus/board.c index c4e32a9791..2f45cf6d41 100644 --- a/board/rammus/board.c +++ b/board/rammus/board.c @@ -142,11 +142,41 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"i2c_0_0", NPCX_I2C_PORT0_0, 400, GPIO_I2C0_0_SCL, GPIO_I2C0_0_SDA}, - {"i2c_0_1", NPCX_I2C_PORT0_1, 400, GPIO_I2C0_1_SCL, GPIO_I2C0_1_SDA}, - {"i2c_1", NPCX_I2C_PORT1, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"i2c_2", NPCX_I2C_PORT2, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"i2c_3", NPCX_I2C_PORT3, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + { + .name = "i2c_0_0", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_I2C0_0_SCL, + .sda = GPIO_I2C0_0_SDA + }, + { + .name = "i2c_0_1", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_I2C0_1_SCL, + .sda = GPIO_I2C0_1_SDA + }, + { + .name = "i2c_1", + .port = NPCX_I2C_PORT1, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "i2c_2", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "i2c_3", + .port = NPCX_I2C_PORT3, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/rammus/board.h b/board/rammus/board.h index c084d98fb0..24df8218ca 100644 --- a/board/rammus/board.h +++ b/board/rammus/board.h @@ -58,7 +58,7 @@ #define CONFIG_CHIPSET_SKYLAKE #define CONFIG_CHIPSET_HAS_PLATFORM_PMIC_RESET #define CONFIG_CHIPSET_RESET_HOOK -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #define CONFIG_HOSTCMD_FLASH_SPI_INFO diff --git a/board/redrix/board.h b/board/redrix/board.h index fa6a5b7dd5..8037a14d41 100644 --- a/board/redrix/board.h +++ b/board/redrix/board.h @@ -19,6 +19,9 @@ */ #define CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP +/* Chipset */ +#define CONFIG_CHIPSET_RESUME_INIT_HOOK + /* Sensors */ #define CONFIG_ACCEL_BMA255 /* Lid accel */ #define CONFIG_ACCELGYRO_LSM6DSM /* Base accel */ @@ -107,6 +110,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -169,7 +173,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* Fan features */ diff --git a/board/redrix/ec.tasklist b/board/redrix/ec.tasklist index 769b73d365..cfc1fea6ea 100644 --- a/board/redrix/ec.tasklist +++ b/board/redrix/ec.tasklist @@ -20,6 +20,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/redrix/fw_config.h b/board/redrix/fw_config.h index 6480f07b35..9a73890f7d 100644 --- a/board/redrix/fw_config.h +++ b/board/redrix/fw_config.h @@ -3,8 +3,8 @@ * found in the LICENSE file. */ -#ifndef __BOARD_BRYA_FW_CONFIG_H_ -#define __BOARD_BRYA_FW_CONFIG_H_ +#ifndef __BOARD_REDRIX_FW_CONFIG_H_ +#define __BOARD_REDRIX_FW_CONFIG_H_ #include <stdint.h> @@ -52,4 +52,4 @@ union redrix_cbi_fw_config get_fw_config(void); */ bool ec_cfg_has_eps(void); -#endif /* __BOARD_BRYA_FW_CONFIG_H_ */ +#endif /* __BOARD_REDRIX_FW_CONFIG_H_ */ diff --git a/board/redrix/gpio.inc b/board/redrix/gpio.inc index 21f8b51ee1..a658ec5927 100644 --- a/board/redrix/gpio.inc +++ b/board/redrix/gpio.inc @@ -82,6 +82,7 @@ GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW) GPIO(USB_C1_TCPC_RST_ODL, PIN(A, 0), GPIO_ODR_LOW) GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) GPIO(PEN_RST_L, PIN(0, 2), GPIO_ODR_HIGH) +GPIO(LRA_DIS_ODL, PIN(0, 4), GPIO_ODR_HIGH) /* Reserved for disable haptic pad LRA */ /* LED */ GPIO(C0_CHARGE_LED_AMBER_L, PIN(C, 4), GPIO_OUT_HIGH) /* Amber C0 port */ @@ -116,12 +117,11 @@ ALTERNATE(PIN_MASK(4, 0x34), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */ /* KB alternate functions */ -ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */ +ALTERNATE(PIN_MASK(0, 0xe0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05 */ ALTERNATE(PIN_MASK(1, 0x7f), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO06/GPO13/GP_SEL_L, KSO07/GPO12/JEN_L, KSO03/GPIO16/JTAG_TDO0_SWO, KSO04/GPIO15/XNOR, KSO05/GPIO14, KSO08/GPIO11/CR_SOUT1, KSO09/GPIO10/CR_SIN1 */ ALTERNATE(PIN_MASK(2, 0xfc), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI2/GPIO27/TRACEDATA1, KSI3/GPIO26/TRACEDATA0, KSI4/GPIO25/TRACECLK/GP_SCLK, KSI5/GPIO24/GP_MISO, KSI6/GPIO23/S_SBUB, KSI7/GPIO22/S_SBUA */ ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO00/GPIO21/JTAG_TCK_SWCLK, KSO01/GPIO20/JTAG_TMS_SWIO */ ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI0/GPIO31/TRACEDATA3/GP_MOSI, KSI1/GPIO30/TRACEDATA2/GP_CS_L */ -ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO14/GPIO82 */ /* PMU alternate functions */ ALTERNATE(PIN_MASK(0, 0x01), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN2_L&GPI00/GPIO00 */ @@ -133,6 +133,7 @@ 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)) /* GPO66/ARM_L_x86 */ +UNUSED(PIN(8, 2)) /* KSO14/GPIO82 */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/redrix/i2c.c b/board/redrix/i2c.c index b993a7978e..5b71c4eb71 100644 --- a/board/redrix/i2c.c +++ b/board/redrix/i2c.c @@ -46,7 +46,7 @@ const struct i2c_port_t i2c_ports[] = { /* I2C4 C1 TCPC */ .name = "tcpc1", .port = I2C_PORT_USB_C1_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, }, @@ -62,7 +62,7 @@ const struct i2c_port_t i2c_ports[] = { /* I2C6 */ .name = "ppc1,retimer1", .port = I2C_PORT_USB_C1_PPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_MIX_SCL, .sda = GPIO_EC_I2C_USB_C1_MIX_SDA, }, diff --git a/board/redrix/led.c b/board/redrix/led.c index c794bc8b5f..96ccae2689 100644 --- a/board/redrix/led.c +++ b/board/redrix/led.c @@ -174,17 +174,30 @@ static void led_set_battery(void) if (charge_get_percent() < 10) led_set_color_battery(RIGHT_PORT, (battery_ticks % LED_TICKS_PER_CYCLE - < LED_ON_TICKS) ? LED_WHITE : LED_OFF); + < LED_ON_TICKS) ? LED_AMBER : LED_OFF); else led_set_color_battery(RIGHT_PORT, LED_OFF); } - if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) - led_set_color_battery(LEFT_PORT, LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + if (charge_get_percent() < 10) + led_set_color_battery(LEFT_PORT, + (battery_ticks % LED_TICKS_PER_CYCLE + < LED_ON_TICKS) ? LED_AMBER : LED_OFF); + else + led_set_color_battery(LEFT_PORT, LED_OFF); + } break; case PWR_STATE_ERROR: - set_active_port_color((battery_ticks & 0x1) ? - LED_WHITE : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { + led_set_color_battery(RIGHT_PORT, (battery_ticks & 0x1) + ? LED_AMBER : LED_OFF); + } + + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) { + led_set_color_battery(LEFT_PORT, (battery_ticks & 0x1) + ? LED_AMBER : LED_OFF); + } break; case PWR_STATE_CHARGE_NEAR_FULL: set_active_port_color(LED_WHITE); diff --git a/board/redrix/sensors.c b/board/redrix/sensors.c index 8a92b8825f..df152b8d1c 100644 --- a/board/redrix/sensors.c +++ b/board/redrix/sensors.c @@ -72,7 +72,7 @@ static struct als_drv_data_t g_tcs3400_data = { .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 */ + .cover_scale = ALS_CHANNEL_SCALE(0.98), /* CT */ }, }; @@ -82,39 +82,39 @@ static struct als_drv_data_t g_tcs3400_data = { */ 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(0), + .offset = 66, /* 66.47729532 */ + .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(0.00222243), + .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0.51877192), + .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(-0.28664117), + .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.0586877), .scale = { .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kr */ - .cover_scale = ALS_CHANNEL_SCALE(1.0) + .cover_scale = ALS_CHANNEL_SCALE(0.61) } }, .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(0), + .offset = 41, /* 40.95355984 */ + .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(-0.15384715), + .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0.40454969), + .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(-0.237452), + .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.13102168), .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(0), + .offset = 5, /* 5.08596128 */ + .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(-0.79005309), + .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(-0.35553576), + .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(0.13997097), + .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.40223911), .scale = { .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kb */ - .cover_scale = ALS_CHANNEL_SCALE(1.0) + .cover_scale = ALS_CHANNEL_SCALE(1.6) } }, - .calibration.irt = INT_TO_FP(1), + .calibration.irt = INT_TO_FP(0.41), .saturation.again = TCS_DEFAULT_AGAIN, .saturation.atime = TCS_DEFAULT_ATIME, }; @@ -157,8 +157,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -187,8 +185,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/redrix/thermal.c b/board/redrix/thermal.c index d35d81b02d..8e1b39a521 100644 --- a/board/redrix/thermal.c +++ b/board/redrix/thermal.c @@ -40,44 +40,44 @@ static const struct fan_step *fan_step_table; static const struct fan_step fan_table_clamshell[] = { { /* level 0 */ - .on = {44, 46, 0, -1}, + .on = {48, 51, 0, -1}, .off = {99, 99, 99, -1}, .rpm = {0, 0}, }, { /* level 1 */ - .on = {45, 47, 0, -1}, - .off = {44, 46, 99, -1}, + .on = {49, 52, 0, -1}, + .off = {48, 51, 99, -1}, .rpm = {4000, 4400}, }, { /* level 2 */ - .on = {46, 48, 0, -1}, - .off = {45, 47, 99, -1}, + .on = {50, 53, 0, -1}, + .off = {49, 52, 99, -1}, .rpm = {4700, 5000}, }, { /* level 3 */ - .on = {47, 49, 0, -1}, - .off = {46, 48, 99, -1}, - .rpm = {5000, 5400}, + .on = {51, 54, 0, -1}, + .off = {50, 53, 99, -1}, + .rpm = {5100, 5400}, }, { /* level 4 */ - .on = {48, 50, 50, -1}, - .off = {47, 49, 48, -1}, + .on = {52, 55, 53, -1}, + .off = {51, 54, 51, -1}, .rpm = {5300, 5600}, }, { /* level 5 */ - .on = {49, 51, 52, -1}, - .off = {48, 50, 50, -1}, + .on = {53, 56, 55, -1}, + .off = {52, 55, 53, -1}, .rpm = {5700, 6000}, }, { /* level 6 */ .on = {100, 100, 100, -1}, - .off = {49, 51, 52, -1}, + .off = {53, 56, 55, -1}, .rpm = {6200, 6400}, }, }; @@ -85,44 +85,44 @@ static const struct fan_step fan_table_clamshell[] = { static const struct fan_step fan_table_tablet[] = { { /* level 0 */ - .on = {44, 46, 0, -1}, + .on = {50, 53, 0, -1}, .off = {99, 99, 99, -1}, .rpm = {0, 0}, }, { /* level 1 */ - .on = {45, 47, 0, -1}, - .off = {44, 46, 99, -1}, - .rpm = {4200, 4400}, + .on = {51, 54, 0, -1}, + .off = {50, 53, 99, -1}, + .rpm = {4200, 4300}, }, { /* level 2 */ - .on = {46, 48, 0, -1}, - .off = {45, 47, 99, -1}, + .on = {52, 55, 0, -1}, + .off = {51, 54, 99, -1}, .rpm = {4700, 4900}, }, { /* level 3 */ - .on = {47, 49, 0, -1}, - .off = {46, 48, 99, -1}, + .on = {53, 56, 0, -1}, + .off = {52, 55, 99, -1}, .rpm = {5000, 5300}, }, { /* level 4 */ - .on = {48, 50, 50, -1}, - .off = {47, 49, 48, -1}, + .on = {54, 57, 55, -1}, + .off = {53, 56, 53, -1}, .rpm = {5200, 5500}, }, { /* level 5 */ - .on = {49, 51, 52, -1}, - .off = {48, 50, 50, -1}, + .on = {55, 58, 57, -1}, + .off = {54, 57, 55, -1}, .rpm = {5700, 5900}, }, { /* level 6 */ .on = {100, 100, 100, -1}, - .off = {49, 51, 52, -1}, + .off = {55, 58, 57, -1}, .rpm = {6100, 6300}, }, }; diff --git a/board/redrix/usbc_config.c b/board/redrix/usbc_config.c index 00b6589a46..aae3a4493b 100644 --- a/board/redrix/usbc_config.c +++ b/board/redrix/usbc_config.c @@ -208,12 +208,16 @@ static void board_tcpc_init(void) int i; /* Don't reset TCPCs after initial reset */ - if (!system_jumped_late()) { + if (!system_jumped_late()) board_reset_pd_mcu(); - for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i) - ioex_init(i); - } + /* + * These IO expander pins are implemented using the + * C0/C1 TCPCs, so they must be set up after the TCPCs has + * been taken out of reset. + */ + for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i) + ioex_init(i); /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); diff --git a/board/reef/board.c b/board/reef/board.c index ed8e83d0a8..92ff6a7764 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -147,16 +147,41 @@ const struct pwm_t pwm_channels[] = { BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); const struct i2c_port_t i2c_ports[] = { - {"tcpc0", NPCX_I2C_PORT0_0, 400, - GPIO_EC_I2C_USB_C0_PD_SCL, GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", NPCX_I2C_PORT0_1, 400, - GPIO_EC_I2C_USB_C1_PD_SCL, GPIO_EC_I2C_USB_C1_PD_SDA}, - {"accelgyro", I2C_PORT_GYRO, 400, - GPIO_EC_I2C_GYRO_SCL, GPIO_EC_I2C_GYRO_SDA}, - {"sensors", NPCX_I2C_PORT2, 400, - GPIO_EC_I2C_SENSOR_SCL, GPIO_EC_I2C_SENSOR_SDA}, - {"batt", NPCX_I2C_PORT3, 100, - GPIO_EC_I2C_POWER_SCL, GPIO_EC_I2C_POWER_SDA}, + { + .name = "tcpc0", + .port = NPCX_I2C_PORT0_0, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = NPCX_I2C_PORT0_1, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "accelgyro", + .port = I2C_PORT_GYRO, + .kbps = 400, + .scl = GPIO_EC_I2C_GYRO_SCL, + .sda = GPIO_EC_I2C_GYRO_SDA + }, + { + .name = "sensors", + .port = NPCX_I2C_PORT2, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, + { + .name = "batt", + .port = NPCX_I2C_PORT3, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/reef/board.h b/board/reef/board.h index 6b05bbc1ed..00544f7bf9 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -102,7 +102,7 @@ #define CONFIG_USBC_VCONN_SWAP /* SoC / PCH */ -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_CHIPSET_APOLLOLAKE #define CONFIG_CHIPSET_RESET_HOOK #define CONFIG_POWER_BUTTON diff --git a/board/reef/gpio.inc b/board/reef/gpio.inc index 5bf83f88bc..f508d7a84e 100644 --- a/board/reef/gpio.inc +++ b/board/reef/gpio.inc @@ -67,7 +67,8 @@ GPIO(EC_I2C_POWER_SCL, PIN(D, 1), GPIO_INPUT) * Pin 57 (SER_IRQ) defaults to LPC mode, but we also have EC_PCH_KB_INT_ODL * (Pin B0) in case it doesn't work (Set CONFIG_KEYBOARD_IRQ_GPIO in this case). * - * See also the NO_LPC_ESPI bit in DEVALT1 and the CONFIG_HOSTCMD_SHI option. + * See also the NO_LPC_ESPI bit in DEVALT1 and the + * CONFIG_HOST_INTERFACE_SHI option. */ GPIO(PCH_SMI_L, PIN(A, 6), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_SMI_ODL */ diff --git a/board/reef_it8320/board.c b/board/reef_it8320/board.c index 92fdc66806..db5bf728fd 100644 --- a/board/reef_it8320/board.c +++ b/board/reef_it8320/board.c @@ -66,10 +66,20 @@ const struct adc_t adc_channels[] = { BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); const struct i2c_port_t i2c_ports[] = { - {"mux", IT83XX_I2C_CH_C, 400, - GPIO_EC_I2C_C_SCL, GPIO_EC_I2C_C_SDA}, - {"batt", IT83XX_I2C_CH_E, 100, - GPIO_EC_I2C_E_SCL, GPIO_EC_I2C_E_SDA}, + { + .name = "mux", + .port = IT83XX_I2C_CH_C, + .kbps = 400, + .scl = GPIO_EC_I2C_C_SCL, + .sda = GPIO_EC_I2C_C_SDA + }, + { + .name = "batt", + .port = IT83XX_I2C_CH_E, + .kbps = 100, + .scl = GPIO_EC_I2C_E_SCL, + .sda = GPIO_EC_I2C_E_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -111,7 +121,8 @@ const enum gpio_signal hibernate_wake_pins[] = { const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); static void it83xx_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; @@ -119,6 +130,9 @@ static void it83xx_tcpc_update_hpd_status(const struct usb_mux *me, me->usb_port ? GPIO_USB_C1_HPD_1P8_ODL : GPIO_USB_C0_HPD_1P8_ODL; + /* This driver does not use host command ACKs */ + *ack_required = false; + hpd_lvl = !hpd_lvl; gpio_set_level(gpio, hpd_lvl); diff --git a/board/reef_it8320/board.h b/board/reef_it8320/board.h index 3598aee233..cf29faa8f8 100644 --- a/board/reef_it8320/board.h +++ b/board/reef_it8320/board.h @@ -99,7 +99,7 @@ #define CONFIG_USBC_VCONN_SWAP /* SoC / PCH */ -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_CHIPSET_APOLLOLAKE #define CONFIG_CHIPSET_RESET_HOOK #define CONFIG_POWER_BUTTON diff --git a/board/reef_it8320/gpio.inc b/board/reef_it8320/gpio.inc index 9882065d50..ac2fbf486e 100644 --- a/board/reef_it8320/gpio.inc +++ b/board/reef_it8320/gpio.inc @@ -20,7 +20,7 @@ GPIO_INT(PCH_SLP_S0_L, PIN(B, 7), GPIO_INT_BOTH, power_signal_interrupt) /* #endif GPIO_INT(SUSPWRDNACK, PIN(E, 1), GPIO_INT_BOTH, power_signal_interrupt) /* SUSPWRNACK */ GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH, lid_interrupt) /* LID_OPEN */ -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(PCH_PLTRST_L, PIN(E, 3), GPIO_INT_BOTH | GPIO_PULL_UP, lpcrst_interrupt) /* PLT_RST_L */ #endif GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH, power_button_interrupt) /* MECH_PWR_BTN_ODL */ diff --git a/board/reef_mchp/board.c b/board/reef_mchp/board.c index b934264510..be24f34aa8 100644 --- a/board/reef_mchp/board.c +++ b/board/reef_mchp/board.c @@ -205,16 +205,41 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); * 400 to 100 kHz. */ const struct i2c_port_t i2c_ports[] = { - {"tcpc0", MCHP_I2C_PORT0, 400, - GPIO_EC_I2C_USB_C0_PD_SCL, GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", MCHP_I2C_PORT2, 400, - GPIO_EC_I2C_USB_C1_PD_SCL, GPIO_EC_I2C_USB_C1_PD_SDA}, - {"accelgyro", I2C_PORT_GYRO, 400, - GPIO_EC_I2C_GYRO_SCL, GPIO_EC_I2C_GYRO_SDA}, - {"sensors", MCHP_I2C_PORT7, 400, - GPIO_EC_I2C_SENSOR_SCL, GPIO_EC_I2C_SENSOR_SDA}, - {"batt", MCHP_I2C_PORT3, 100, - GPIO_EC_I2C_POWER_SCL, GPIO_EC_I2C_POWER_SDA}, + { + .name = "tcpc0", + .port = MCHP_I2C_PORT0, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = MCHP_I2C_PORT2, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "accelgyro", + .port = I2C_PORT_GYRO, + .kbps = 400, + .scl = GPIO_EC_I2C_GYRO_SCL, + .sda = GPIO_EC_I2C_GYRO_SDA + }, + { + .name = "sensors", + .port = MCHP_I2C_PORT7, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, + { + .name = "batt", + .port = MCHP_I2C_PORT3, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/reef_mchp/board.h b/board/reef_mchp/board.h index 5e31c5de98..5ae0cdf214 100644 --- a/board/reef_mchp/board.h +++ b/board/reef_mchp/board.h @@ -104,7 +104,7 @@ #define CONFIG_USBC_VCONN_SWAP /* SoC / PCH */ -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_CHIPSET_APOLLOLAKE #define CONFIG_CHIPSET_RESET_HOOK #define CONFIG_POWER_BUTTON diff --git a/board/reef_mchp/gpio.inc b/board/reef_mchp/gpio.inc index 0385d82102..3274af3bff 100644 --- a/board/reef_mchp/gpio.inc +++ b/board/reef_mchp/gpio.inc @@ -84,7 +84,8 @@ GPIO(EC_I2C_POWER_SCL, PIN(010), GPIO_INPUT) * Pin 57 (SER_IRQ) defaults to LPC mode, but we also have EC_PCH_KB_INT_ODL * (Pin B0) in case it doesn't work (Set CONFIG_KEYBOARD_IRQ_GPIO in this case). * - * See also the NO_LPC_ESPI bit in DEVALT1 and the CONFIG_HOSTCMD_SHI option. + * See also the NO_LPC_ESPI bit in DEVALT1 and the + * CONFIG_HOST_INTERFACE_SHI option. */ GPIO(PCH_SMI_L, PIN(0227), GPIO_ODR_HIGH | GPIO_SEL_1P8V) /* EC_SMI_ODL */ diff --git a/board/scarlet/board.c b/board/scarlet/board.c index f109d0ada3..3120ef1efb 100644 --- a/board/scarlet/board.c +++ b/board/scarlet/board.c @@ -75,8 +75,20 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"charger", I2C_PORT_CHARGER, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + { + .name = "charger", + .port = I2C_PORT_CHARGER, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/scarlet/board.h b/board/scarlet/board.h index f8d1ba7011..8d810d3217 100644 --- a/board/scarlet/board.h +++ b/board/scarlet/board.h @@ -10,6 +10,7 @@ /* Free up flash space */ #define CONFIG_DEBUG_ASSERT_BRIEF +#define CONFIG_LTO #define CONFIG_USB_PD_DEBUG_LEVEL 0 /* Optional modules */ @@ -61,7 +62,6 @@ #undef CONFIG_HOSTCMD_DEBUG_MODE #define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_OFF #undef CONFIG_LID_SWITCH -#undef CONFIG_LTO #define CONFIG_POWER_BUTTON #define CONFIG_POWER_BUTTON_IGNORE_LID #define CONFIG_POWER_TRACK_HOST_SLEEP_STATE @@ -186,7 +186,7 @@ #define VIRTUAL_BATTERY_ADDR_FLAGS 0x0B /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_MKBP_INPUT_DEVICES #define CONFIG_MKBP_EVENT diff --git a/board/scout/board.c b/board/scout/board.c index d45b627ce1..8c9de5da64 100644 --- a/board/scout/board.c +++ b/board/scout/board.c @@ -233,12 +233,48 @@ const struct pwm_t pwm_channels[] = { /******************************************************************************/ /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { - {"ina", I2C_PORT_INA, 400, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"ppc0", I2C_PORT_PPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"scaler", I2C_PORT_SCALER, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"power", I2C_PORT_POWER, 400, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "ina", + .port = I2C_PORT_INA, + .kbps = 400, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "ppc0", + .port = I2C_PORT_PPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "scaler", + .port = I2C_PORT_SCALER, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 400, + .scl = GPIO_I2C5_SCL, + .sda = GPIO_I2C5_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -320,8 +356,8 @@ const struct fan_conf fan_conf_0 = { }; const struct fan_rpm fan_rpm_0 = { - .rpm_min = 2500, - .rpm_start = 2500, + .rpm_min = 2400, + .rpm_start = 2400, .rpm_max = 5300, }; @@ -519,6 +555,8 @@ void board_enable_s0_rails(int enable) gpio_set_level(GPIO_EC_CAM_V3P3_EN, enable); gpio_set_level(GPIO_PP3300_TPU_A_EN, enable); + + gpio_set_level(GPIO_EN_LOAD_SWITCH, enable); } int ec_config_get_usb4_present(void) diff --git a/board/scout/board.h b/board/scout/board.h index 5a09624b15..67b9c3bdeb 100644 --- a/board/scout/board.h +++ b/board/scout/board.h @@ -38,7 +38,7 @@ #define CONFIG_MKBP_USE_HOST_EVENT #undef CONFIG_KEYBOARD_RUNTIME_KEYS #undef CONFIG_HIBERNATE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #define CONFIG_LED_COMMON #undef CONFIG_LID_SWITCH #define CONFIG_LTO @@ -123,7 +123,7 @@ #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 0 #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_ROA_RAILS +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_THROTTLE_AP @@ -256,6 +256,7 @@ unsigned int ec_config_get_thermal_solution(void); #define GPIO_PCH_SLP_S0_L GPIO_SLP_S0_L #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_ROA_RAILS #define GPIO_AC_PRESENT GPIO_BJ_ADP_PRESENT_L /* diff --git a/board/scout/gpio.inc b/board/scout/gpio.inc index 583e4159bd..fa3530a401 100644 --- a/board/scout/gpio.inc +++ b/board/scout/gpio.inc @@ -60,7 +60,7 @@ GPIO_INT(USB_A3_OC_ODL, PIN(0, 3), GPIO_INT_BOTH, port_ocp_interrupt) GPIO(EC_PCH_PWROK, PIN(0, 5), GPIO_OUT_LOW) GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) -GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_ODR_HIGH) +GPIO(EC_PCH_RTCRST, PIN(7, 6), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_ODL, PIN(7, 4), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_IN_OD, PIN(3, 4), GPIO_INPUT) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) @@ -87,6 +87,7 @@ GPIO(EC_MX8M_ONOFF, PIN(9, 3), GPIO_OUT_LOW) GPIO(EC_SCALER_EN, PIN(E, 0), GPIO_OUT_LOW) GPIO(PP3300_TPU_A_EN, PIN(B, 0), GPIO_OUT_LOW) GPIO(PWR_CTRL, PIN(6, 2), GPIO_OUT_LOW) +GPIO(EN_LOAD_SWITCH, PIN(4, 2), GPIO_OUT_LOW) /* Barreljack */ GPIO(EN_PPVAR_BJ_ADP_L, PIN(0, 4), GPIO_OUT_LOW) @@ -143,7 +144,7 @@ ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* PWM5 - Fan 1 ALTERNATE(PIN_MASK(7, 0x08), 0, MODULE_PWM, 0) /* TA2 - Fan Tachometer */ /* ADC */ -ALTERNATE(PIN_MASK(4, 0x3E), 0, MODULE_ADC, 0) /* ADC0, ADC1, ADC2, ADC4 */ +ALTERNATE(PIN_MASK(4, 0x3A), 0, MODULE_ADC, 0) /* ADC0, ADC1, ADC2, ADC4 */ ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* ADC7 */ ALTERNATE(PIN_MASK(F, 0x01), 0, MODULE_ADC, 0) /* ADC9 */ @@ -154,7 +155,6 @@ ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* UART from EC UNUSED(PIN(1, 3)) /* EC_GP_SEL1_ODL */ UNUSED(PIN(C, 0)) /* FAN_PWM_2 */ UNUSED(PIN(8, 0)) /* LED_BLUE_L */ -UNUSED(PIN(4, 2)) /* ADC3/TEMP_SENSOR_3 */ UNUSED(PIN(C, 2)) /* A12 NC */ UNUSED(PIN(1, 2)) /* C6 NC */ UNUSED(PIN(6, 6)) /* H4 NC */ diff --git a/board/scout/led.c b/board/scout/led.c index a9f70d2d40..3066c182d1 100644 --- a/board/scout/led.c +++ b/board/scout/led.c @@ -199,6 +199,16 @@ static void led_init(void) } DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_INIT_PWM + 1); +void board_led_auto_control(void) +{ + 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 led_alert(int enable) { if (enable) { diff --git a/board/servo_micro/board.c b/board/servo_micro/board.c index 8074ba38ab..f82376a15a 100644 --- a/board/servo_micro/board.c +++ b/board/servo_micro/board.c @@ -314,6 +314,7 @@ const void *const usb_strings[] = { [USB_STR_PRODUCT] = USB_STRING_DESC("Servo Micro"), [USB_STR_SERIALNO] = 0, [USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32), + [USB_STR_SPI_NAME] = USB_STRING_DESC("SPI"), [USB_STR_I2C_NAME] = USB_STRING_DESC("I2C"), [USB_STR_USART4_STREAM_NAME] = USB_STRING_DESC("UART3"), [USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Servo Shell"), @@ -372,8 +373,13 @@ USB_SPI_CONFIG(usb_spi, USB_IFACE_SPI, USB_EP_SPI, 0); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/servo_micro/board.h b/board/servo_micro/board.h index 306bc0e5d7..1983ee13e3 100644 --- a/board/servo_micro/board.h +++ b/board/servo_micro/board.h @@ -76,7 +76,7 @@ /* Enable control of SPI over USB */ #define CONFIG_USB_SPI #define CONFIG_SPI_CONTROLLER -#define CONFIG_SPI_FLASH_PORT 0 /* First SPI master port */ +#define CONFIG_SPI_FLASH_PORT 0 /* First SPI controller port */ /* This is not actually an EC so disable some features. */ #undef CONFIG_WATCHDOG_HELP @@ -120,6 +120,7 @@ enum usb_strings { USB_STR_PRODUCT, USB_STR_SERIALNO, USB_STR_VERSION, + USB_STR_SPI_NAME, USB_STR_I2C_NAME, USB_STR_USART4_STREAM_NAME, USB_STR_CONSOLE_NAME, diff --git a/board/servo_v4/board.c b/board/servo_v4/board.c index 8540de710f..b304408f74 100644 --- a/board/servo_v4/board.c +++ b/board/servo_v4/board.c @@ -298,8 +298,13 @@ BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c index d9d48a42ce..3284b4ef58 100644 --- a/board/servo_v4p1/board.c +++ b/board/servo_v4p1/board.c @@ -65,6 +65,26 @@ static void tca_evt(enum gpio_signal signal) irq_ioexpanders(); } +/* + * TUSB1064 set mux board tuning. + * Adds in board specific gain and DP lane count configuration + */ +static int board_tusb1064_dp_rx_eq_set(const struct usb_mux *me, + mux_state_t mux_state) +{ + int rv = EC_SUCCESS; + + /* + * Apply 10dB gain. Note, this value is selected to match the gain that + * would be set by default if the 2 GPIO gain set pins are left + * floating. + */ + if (mux_state & USB_PD_MUX_DP_ENABLED) + rv = tusb1064_set_dp_rx_eq(me, TUSB1064_DP_EQ_RX_10_0_DB); + + return rv; +} + const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { [CHG] = { /* CHG port connected directly to USB 3.0 hub, no mux */ }, [DUT] = { /* DUT port with UFP mux */ @@ -72,6 +92,7 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_port = I2C_PORT_MASTER, .i2c_addr_flags = TUSB1064_I2C_ADDR10_FLAGS, .driver = &tusb1064_usb_mux_driver, + .board_set = &board_tusb1064_dp_rx_eq_set, } }; @@ -380,8 +401,13 @@ BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/shuboz/board.c b/board/shuboz/board.c index 3008434ea4..615193b8f4 100644 --- a/board/shuboz/board.c +++ b/board/shuboz/board.c @@ -153,7 +153,6 @@ struct motion_sensor_t motion_sensors[] = { .drv = &bmi160_drv, .mutex = &g_base_mutex, .drv_data = &g_bmi160_data, - .int_signal = GPIO_6AXIS_INT_L, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ diff --git a/board/spherion/board.c b/board/spherion/board.c index 1119b1f077..95fa0a06de 100644 --- a/board/spherion/board.c +++ b/board/spherion/board.c @@ -105,10 +105,15 @@ DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, kb_backlight_disable, HOOK_PRIO_DEFAULT); void board_usb_mux_init(void) { - if (board_get_sub_board() == SUB_BOARD_TYPEC) + if (board_get_sub_board() == SUB_BOARD_TYPEC) { ps8743_tune_usb_eq(&usb_muxes[1], PS8743_USB_EQ_TX_12_8_DB, PS8743_USB_EQ_RX_12_8_DB); + ps8743_field_update(&usb_muxes[1], + PS8743_REG_DCI_CONFIG_2, + PS8743_AUTO_DCI_MODE_MASK, + PS8743_AUTO_DCI_MODE_FORCE_USB); + } } DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/board/stern/board.c b/board/stern/board.c index 609dfdf7e5..53690e8c94 100644 --- a/board/stern/board.c +++ b/board/stern/board.c @@ -67,13 +67,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -139,8 +158,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/stern/board.h b/board/stern/board.h index 5bf23a6733..f682f2bb2b 100644 --- a/board/stern/board.h +++ b/board/stern/board.h @@ -85,7 +85,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/stm32f446e-eval/board.c b/board/stm32f446e-eval/board.c index f4cf28898c..fd6ff8bbe2 100644 --- a/board/stm32f446e-eval/board.c +++ b/board/stm32f446e-eval/board.c @@ -43,10 +43,20 @@ struct dwc_usb usb_ctl = { /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"i2c1", I2C_PORT_0, 100, - GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"fmpi2c4", FMPI2C_PORT_3, 100, - GPIO_FMPI2C_SCL, GPIO_FMPI2C_SDA}, + { + .name = "i2c1", + .port = I2C_PORT_0, + .kbps = 100, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "fmpi2c4", + .port = FMPI2C_PORT_3, + .kbps = 100, + .scl = GPIO_FMPI2C_SCL, + .sda = GPIO_FMPI2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/stm32l476g-eval/board.c b/board/stm32l476g-eval/board.c index c7ebc2c6b8..70375abe95 100644 --- a/board/stm32l476g-eval/board.c +++ b/board/stm32l476g-eval/board.c @@ -33,7 +33,13 @@ DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT); #ifdef CTS_MODULE_I2C const struct i2c_port_t i2c_ports[] = { - {"test", STM32_I2C2_PORT, 100, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "test", + .port = STM32_I2C2_PORT, + .kbps = 100, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); #endif diff --git a/board/storo/battery.c b/board/storo/battery.c index d273b391e7..b28e5bbf37 100644 --- a/board/storo/battery.c +++ b/board/storo/battery.c @@ -32,8 +32,8 @@ * address, mask, and disconnect value need to be provided. */ const struct board_batt_params board_battery_info[] = { - /* C21N2018 Battery Information */ - [BATTERY_C21N2018] = { + /* C21N2018_AS3GXXD3KA Battery Information */ + [BATTERY_AS3GXXD3KA] = { .fuel_gauge = { .manuf_name = "AS3GXXD3KA", .device_name = "C110160", @@ -61,8 +61,39 @@ const struct board_batt_params board_battery_info[] = { .discharging_min_c = -20, .discharging_max_c = 60, }, + }, + + /* C21N2018_AS3FXXD3KA Battery Information */ + [BATTERY_AS3FXXD3KA] = { + .fuel_gauge = { + .manuf_name = "AS3FXXD3KA", + .device_name = "C110160", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x99, + .reg_mask = 0x000C, + .disconnect_val = 0x000C, + .cfet_mask = 0x0004, + .cfet_off_val = 0x0004 + } + }, + .batt_info = { + .voltage_max = 8800, + .voltage_normal = 7890, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, } }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_C21N2018; +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_AS3GXXD3KA; diff --git a/board/storo/board.c b/board/storo/board.c index f864d230c2..280a85fd99 100644 --- a/board/storo/board.c +++ b/board/storo/board.c @@ -462,10 +462,6 @@ int board_set_active_charge_port(int port) old_port = charge_manager_get_active_charge_port(); - /* If the port is not changing, we should do nothing */ - if (old_port == port) - return EC_SUCCESS; - CPRINTS("New chg p%d", port); /* Disable all ports. */ @@ -503,7 +499,7 @@ int board_set_active_charge_port(int port) * Stop the charger IC from switching while changing ports. Otherwise, * we can overcurrent the adapter we're switching to. (crbug.com/926056) */ - if (old_port != CHARGE_PORT_NONE) + if ((old_port != CHARGE_PORT_NONE) && (old_port != port)) charger_discharge_on_ac(1); /* Enable requested charge port. */ diff --git a/board/storo/board.h b/board/storo/board.h index cb738e8245..3ee8791e80 100644 --- a/board/storo/board.h +++ b/board/storo/board.h @@ -141,7 +141,8 @@ enum temp_sensor_id { /* List of possible batteries */ enum battery_type { - BATTERY_C21N2018, + BATTERY_AS3GXXD3KA, + BATTERY_AS3FXXD3KA, BATTERY_TYPE_COUNT, }; diff --git a/board/stryke/board.h b/board/stryke/board.h index d84a09fe36..3ad04aad96 100644 --- a/board/stryke/board.h +++ b/board/stryke/board.h @@ -16,7 +16,7 @@ #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE -#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOST_INTERFACE_ESPI #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -81,7 +81,8 @@ #define CONFIG_FANS 1 #undef CONFIG_FAN_INIT_SPEED #define CONFIG_FAN_INIT_SPEED 50 -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_EN_A_RAILS +#define CONFIG_TEMP_SENSOR +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_THERMISTOR #define CONFIG_THROTTLE_AP #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B @@ -108,6 +109,7 @@ #define GPIO_PCH_SYS_PWROK GPIO_EC_PCH_SYS_PWROK #define GPIO_PCH_SLP_S3_L GPIO_SLP_S3_L #define GPIO_PCH_SLP_S4_L GPIO_SLP_S4_L +#define GPIO_TEMP_SENSOR_POWER GPIO_EN_A_RAILS #define GPIO_EN_PP5000 GPIO_EN_PP5000_A #ifndef __ASSEMBLER__ diff --git a/board/sweetberry/board.c b/board/sweetberry/board.c index 66b21a81b9..bee8f91a22 100644 --- a/board/sweetberry/board.c +++ b/board/sweetberry/board.c @@ -59,14 +59,34 @@ struct dwc_usb usb_ctl = { /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"i2c1", I2C_PORT_0, 400, - GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"i2c2", I2C_PORT_1, 400, - GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"i2c3", I2C_PORT_2, 400, - GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"fmpi2c4", FMPI2C_PORT_3, 900, - GPIO_FMPI2C_SCL, GPIO_FMPI2C_SDA}, + { + .name = "i2c1", + .port = I2C_PORT_0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "i2c2", + .port = I2C_PORT_1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "i2c3", + .port = I2C_PORT_2, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "fmpi2c4", + .port = FMPI2C_PORT_3, + .kbps = 900, + .scl = GPIO_FMPI2C_SCL, + .sda = GPIO_FMPI2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/taeko/board.c b/board/taeko/board.c index c3b496d9ce..6fb96f7d21 100644 --- a/board/taeko/board.c +++ b/board/taeko/board.c @@ -5,7 +5,9 @@ #include "battery.h" #include "button.h" +#include "charge_manager.h" #include "charge_ramp.h" +#include "charge_state_v2.h" #include "charger.h" #include "common.h" #include "compile_time_macros.h" @@ -109,3 +111,17 @@ enum battery_present battery_hw_present(void) /* The GPIO is low when the battery is physically present */ return gpio_get_level(GPIO_EC_BATT_PRES_ODL) ? BP_NO : BP_YES; } + +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* + * Follow OEM request to limit the input current to + * 95% negotiated limit. + */ + charge_ma = charge_ma * 95 / 100; + + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} diff --git a/board/taeko/board.h b/board/taeko/board.h index 66905bb82d..5ba767bdb9 100644 --- a/board/taeko/board.h +++ b/board/taeko/board.h @@ -19,6 +19,7 @@ #include "baseboard.h" #define CONFIG_SYSTEM_UNLOCKED +#define CONFIG_BYPASS_CBI_EEPROM_WP_CHECK /* * This will happen automatically on NPCX9 ES2 and later. Do not remove @@ -91,6 +92,12 @@ #define CONFIG_USBC_PPC_SYV682X #define CONFIG_USBC_PPC_NX20P3483 +/* I2C speed console command */ +#define CONFIG_CMD_I2C_SPEED + +/* I2C control host command */ +#define CONFIG_HOSTCMD_I2C_CONTROL + /* 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 */ @@ -104,6 +111,9 @@ #define PD_MAX_CURRENT_MA 3000 #define PD_MAX_VOLTAGE_MV 20000 +/* The lower the input voltage, the higher the power efficiency. */ +#define PD_PREFER_LOW_VOLTAGE + /* * 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 @@ -122,6 +132,7 @@ #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 #define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L /* @@ -162,7 +173,7 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B /* Fan */ @@ -171,10 +182,30 @@ /* Charger defines */ #define CONFIG_CHARGER_BQ25720 #define CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM -#define CONFIG_CHARGER_BQ25720_VSYS_TH2_DV 70 +/* 37h BIT7:2 VSYS_TH2 6.0V */ +#define CONFIG_CHARGER_BQ25720_VSYS_TH2_DV 60 #define CONFIG_CHARGE_RAMP_SW #define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR 10 #define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR_AC 10 +/* 30h BIT13:12 Enable PSYS 00b */ +#define CONFIG_CHARGER_BQ25710_PSYS_SENSING +/* 31h BIT3 = 1 Enable ACOC */ +#define CONFIG_CHARGER_BQ25710_EN_ACOC +/* 33h BIT15:11 ILIM2 TH 140% */ +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH \ + BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P40 +/* 34h BIT0 CONFIG_CHARGER_BQ25710_PP_ACOK */ +#define CONFIG_CHARGER_BQ25710_PP_ACOK +/* 34h BIT3 and BIT15:10 IDCHG 9728mA, step is 512mA */ +#define CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA 9728 +/* 36h UVP 5600mV */ +#define CONFIG_CHARGER_BQ25720_VSYS_UVP_CUSTOM +#define CONFIG_CHARGER_BQ25720_VSYS_UVP \ + BQ25720_CHARGE_OPTION_4_VSYS_UVP__5P6 +/* 3Eh BIT15:8 VSYS_MIN 6.1V */ +#define CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_CUSTOM +#define CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_MV 6100 #ifndef __ASSEMBLER__ diff --git a/board/taeko/ec.tasklist b/board/taeko/ec.tasklist index 41d86da3d6..6d995d6b44 100644 --- a/board/taeko/ec.tasklist +++ b/board/taeko/ec.tasklist @@ -19,6 +19,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ diff --git a/board/taeko/gpio.inc b/board/taeko/gpio.inc index 7e97007af6..583efc308c 100644 --- a/board/taeko/gpio.inc +++ b/board/taeko/gpio.inc @@ -73,7 +73,7 @@ GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW) GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW) GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT) -GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_LOW) +GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_HIGH) GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) /* UART alternate functions */ @@ -120,6 +120,7 @@ UNUSED(PIN(3, 2)) /* GPO32/TRIS_L */ UNUSED(PIN(3, 5)) /* GPO35/CR_SOUT4/TEST_L */ UNUSED(PIN(4, 1)) /* GPIO41/ADC4 */ UNUSED(PIN(6, 6)) /* GPIO66 */ +UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ /* Pre-configured PSL balls: J8 K6 */ diff --git a/board/taeko/i2c.c b/board/taeko/i2c.c index 0a32a502ab..2c990254fa 100644 --- a/board/taeko/i2c.c +++ b/board/taeko/i2c.c @@ -38,9 +38,10 @@ const struct i2c_port_t i2c_ports[] = { /* I2C4 C1 TCPC */ .name = "tcpc1", .port = I2C_PORT_USB_C1_TCPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, }, { /* I2C5 */ @@ -54,7 +55,7 @@ const struct i2c_port_t i2c_ports[] = { /* I2C6 */ .name = "ppc1", .port = I2C_PORT_USB_C1_PPC, - .kbps = 400, + .kbps = 1000, .scl = GPIO_EC_I2C_USB_C1_MIX_SCL, .sda = GPIO_EC_I2C_USB_C1_MIX_SDA, }, diff --git a/board/taeko/sensors.c b/board/taeko/sensors.c index b5d75460fe..f12e2a9f94 100644 --- a/board/taeko/sensors.c +++ b/board/taeko/sensors.c @@ -67,21 +67,24 @@ static struct accelgyro_saved_data_t g_bma422_data; static struct lsm6dso_data lsm6dso_data; static struct lsm6dsm_data lsm6dsm_data = LSM6DSM_DATA; -/* TODO(b/201504044): calibrate the orientation matrix on later board stage */ -#if 0 -static const mat33_fp_t lid_standard_ref = { +/* The matrix for new DB */ +static const mat33_fp_t lid_ref_for_new_DB = { + { FLOAT_TO_FP(-1), 0, 0}, { 0, FLOAT_TO_FP(1), 0}, - { FLOAT_TO_FP(1), 0, 0}, { 0, 0, FLOAT_TO_FP(-1)} }; +/* Matrix to rotate lid and base sensor into standard reference frame */ +static const mat33_fp_t lid_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; static const mat33_fp_t base_standard_ref = { - { FLOAT_TO_FP(1), 0, 0}, - { 0, FLOAT_TO_FP(-1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, FLOAT_TO_FP(1), 0}, { 0, 0, FLOAT_TO_FP(-1)} }; -#endif - struct motion_sensor_t bma422_lid_accel = { .name = "Lid Accel - BMA", @@ -94,7 +97,7 @@ struct motion_sensor_t bma422_lid_accel = { .drv_data = &g_bma422_data, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = BMA4_I2C_ADDR_PRIMARY, /* 0x18 */ - .rot_standard_ref = NULL, /* identity matrix */ + .rot_standard_ref = &lid_standard_ref, /* identity matrix */ .default_range = 2, /* g, enough for laptop. */ .min_frequency = BMA4_ACCEL_MIN_FREQ, .max_frequency = BMA4_ACCEL_MAX_FREQ, @@ -122,11 +125,9 @@ struct motion_sensor_t lsm6dsm_base_accel = { .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, - .rot_standard_ref = NULL, + .rot_standard_ref = &base_standard_ref, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ .min_frequency = LSM6DSM_ODR_MIN_VAL, .max_frequency = LSM6DSM_ODR_MAX_VAL, @@ -153,12 +154,10 @@ struct motion_sensor_t lsm6dsm_base_gyro = { .drv = &lsm6dsm_drv, .mutex = &g_base_accel_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ - .rot_standard_ref = NULL, + .rot_standard_ref = &base_standard_ref, .min_frequency = LSM6DSM_ODR_MIN_VAL, .max_frequency = LSM6DSM_ODR_MAX_VAL, }; @@ -173,11 +172,9 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lis2dw12_drv, .mutex = &g_lid_accel_mutex, .drv_data = &g_lis2dw12_data, - .int_signal = GPIO_EC_ACCEL_INT_R_L, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LIS2DW12_ADDR1, /* 0x19 */ - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .rot_standard_ref = NULL, /* identity matrix */ + .rot_standard_ref = &lid_standard_ref, /* identity matrix */ .default_range = 2, /* g */ .min_frequency = LIS2DW12_ODR_MIN_VAL, .max_frequency = LIS2DW12_ODR_MAX_VAL, @@ -202,11 +199,9 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lsm6dso_drv, .mutex = &g_base_accel_mutex, .drv_data = &lsm6dso_data, - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, - .rot_standard_ref = NULL, + .rot_standard_ref = &base_standard_ref, .default_range = 4, /* g */ .min_frequency = LSM6DSO_ODR_MIN_VAL, .max_frequency = LSM6DSO_ODR_MAX_VAL, @@ -231,12 +226,10 @@ struct motion_sensor_t motion_sensors[] = { .drv = &lsm6dso_drv, .mutex = &g_base_accel_mutex, .drv_data = &lsm6dso_data, - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ - .rot_standard_ref = NULL, + .rot_standard_ref = &base_standard_ref, .min_frequency = LSM6DSO_ODR_MIN_VAL, .max_frequency = LSM6DSO_ODR_MAX_VAL, }, @@ -287,6 +280,11 @@ static void board_detect_motionsensor(void) * we don't use INT1. Keep this pin as input w/o enable * interrupt. */ + if (get_board_id() >= 2) { + /* Need to change matrix when board ID >= 2 */ + bma422_lid_accel.rot_standard_ref = + &lid_ref_for_new_DB; + } return; } @@ -322,6 +320,12 @@ static void baseboard_sensors_init(void) motion_sensors[BASE_GYRO] = lsm6dsm_base_gyro; } + if (get_board_id() >= 2) { + /* Need to change matrix when board ID >= 2 */ + motion_sensors[LID_ACCEL].rot_standard_ref = + &lid_ref_for_new_DB; + } + /* Enable gpio interrupt for base accelgyro sensor */ gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L); } else { diff --git a/board/taeko/usbc_config.c b/board/taeko/usbc_config.c index c8e02581be..4cdb29b779 100644 --- a/board/taeko/usbc_config.c +++ b/board/taeko/usbc_config.c @@ -6,6 +6,7 @@ #include <stdint.h> #include <stdbool.h> +#include "battery.h" #include "common.h" #include "compile_time_macros.h" #include "console.h" @@ -64,7 +65,8 @@ const struct tcpc_config_t tcpc_config[] = { }, .drv = &ps8xxx_tcpm_drv, .flags = TCPC_FLAGS_TCPCI_REV2_0 | - TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V, + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, }, }; BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); @@ -168,6 +170,11 @@ static void ps8815_reset(void) if (i2c_read8(I2C_PORT_USB_C1_TCPC, PS8751_I2C_ADDR1_FLAGS, 0x0f, &val) == EC_SUCCESS) CPRINTS("ps8815: reg 0x0f was %02x", val); + else { + CPRINTS("delay 10ms to make sure PS8815 is waken from idle"); + msleep(10); + } + if (i2c_write8(I2C_PORT_USB_C1_TCPC, PS8751_I2C_ADDR1_FLAGS, 0x0f, 0x31) == EC_SUCCESS) @@ -235,7 +242,15 @@ void board_reset_pd_mcu(void) */ gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 0); - gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0); + + /* + * (b/202489681): Nx20p3483 cannot sink power after reset ec + * To avoid nx20p3483 cannot sink power after reset ec w/ AC + * only in TCPC1 port, EC shouldn't assert GPIO_USB_C1_RT_RST_R_ODL + * if no battery. + */ + if (battery_hw_present()) + gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0); /* * delay for power-on to reset-off and min. assertion time diff --git a/board/taniks/battery.c b/board/taniks/battery.c new file mode 100644 index 0000000000..61de7bcf80 --- /dev/null +++ b/board/taniks/battery.c @@ -0,0 +1,103 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery.h" +#include "battery_fuel_gauge.h" +#include "battery_smart.h" +#include "common.h" +#include "util.h" +/* + * Battery info for all Taniks battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + [BATTERY_SMP] = { + .fuel_gauge = { + .manuf_name = "SMP", + .device_name = "L21M4PG4", + .ship_mode = { + .reg_addr = 0x34, + .reg_data = { 0x0000, 0x1000 }, + }, + .fet = { + .reg_addr = 0x34, + .reg_mask = 0x0100, + .disconnect_val = 0x0100, + } + }, + .batt_info = { + .voltage_max = 8900, /* mV */ + .voltage_normal = 7720, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 330, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, + [BATTERY_SUNWODA] = { + .fuel_gauge = { + .manuf_name = "Sunwoda", + .device_name = "L21D4PG4", + .ship_mode = { + .reg_addr = 0x34, + .reg_data = { 0x0000, 0x1000 }, + }, + .fet = { + .reg_addr = 0x34, + .reg_mask = 0x0100, + .disconnect_val = 0x0100, + } + }, + .batt_info = { + .voltage_max = 8900, /* mV */ + .voltage_normal = 7720, /* mV */ + .voltage_min = 6000, /* mV */ + .precharge_current = 330, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_SMP; + +__override bool board_battery_is_initialized(void) +{ + bool batt_initialization_state; + int batt_status; + + batt_initialization_state = (battery_status(&batt_status) ? false : + !!(batt_status & STATUS_INITIALIZED)); + return batt_initialization_state; +} diff --git a/board/taniks/board.c b/board/taniks/board.c new file mode 100644 index 0000000000..80be70ca27 --- /dev/null +++ b/board/taniks/board.c @@ -0,0 +1,127 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery.h" +#include "button.h" +#include "charge_manager.h" +#include "charge_ramp.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "gpio.h" +#include "gpio_signal.h" +#include "hooks.h" +#include "driver/accel_lis2dw12.h" +#include "driver/accelgyro_lsm6dso.h" +#include "driver/als_tcs3400.h" +#include "fw_config.h" +#include "hooks.h" +#include "lid_switch.h" +#include "power_button.h" +#include "power.h" +#include "registers.h" +#include "switch.h" +#include "tablet_mode.h" +#include "throttle_ap.h" +#include "usbc_config.h" + +#include "gpio_list.h" /* Must come after other header files. */ + +/* Console output macros */ +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) + +/******************************************************************************/ +/* USB-A charging control */ + +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_PP5000_USBA_R, +}; +BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT); + +/******************************************************************************/ + +__override void board_cbi_init(void) +{ + config_usb_db_type(); +} + +/* Called on AP S3 -> S0 transition */ +static void board_chipset_resume(void) +{ + /* Allow keyboard backlight to be enabled */ + if (ec_cfg_has_keyboard_backlight() == 1) { + /* GPIO_EC_KB_BL_EN_L is low active pin */ + gpio_set_level(GPIO_EC_KB_BL_EN_L, 0); + } +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); + +/* Called on AP S0 -> S3 transition */ +static void board_chipset_suspend(void) +{ + /* Turn off the keyboard backlight if it's on. */ + if (ec_cfg_has_keyboard_backlight() == 1) { + /* GPIO_EC_KB_BL_EN_L is low active pin */ + gpio_set_level(GPIO_EC_KB_BL_EN_L, 1); + } +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); + +#ifdef CONFIG_CHARGE_RAMP_SW + +/* + * TODO: 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 */ + +enum battery_present battery_hw_present(void) +{ + /* The GPIO is low when the battery is physically present */ + return gpio_get_level(GPIO_EC_BATT_PRES_ODL) ? BP_NO : BP_YES; +} + +__override void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* + * Follow OEM request to limit the input current to + * 95% negotiated limit. + */ + charge_ma = charge_ma * 95 / 100; + + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +}
\ No newline at end of file diff --git a/board/taniks/board.h b/board/taniks/board.h new file mode 100644 index 0000000000..919a156801 --- /dev/null +++ b/board/taniks/board.h @@ -0,0 +1,262 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taniks board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#include "compile_time_macros.h" + +/* + * Taniks boards are set up for vivaldi + */ +#define CONFIG_KEYBOARD_VIVALDI + +/* Baseboard features */ +#include "baseboard.h" + +#define CONFIG_SYSTEM_UNLOCKED + +/* + * This will happen automatically on NPCX9 ES2 and later. Do not remove + * until we can confirm all earlier chips are out of service. + */ +#define CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP + +/* LED */ +#define CONFIG_LED_ONOFF_STATES + +/* Sensors */ +#define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT + + +/* Change Request (b/211078551) + * GYRO sensor change from ST LSM6DSOETR3TR to ST LSM6DS3TR-C + * LSM6DSOETR3TR base accel/gyro if board id = 0 + * LSM6DS3TR-C Base accel/gyro if board id > 0 + */ +#define CONFIG_ACCELGYRO_LSM6DSO /* Base accel */ +#define CONFIG_ACCEL_LSM6DSO_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#define CONFIG_ACCELGYRO_LSM6DSM +#define CONFIG_ACCEL_LSM6DSM_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) + +/* Enable sensor fifo, must also define the _SIZE and _THRES */ +#define CONFIG_ACCEL_FIFO +/* FIFO size is in power of 2. */ +#define CONFIG_ACCEL_FIFO_SIZE 256 +/* Depends on how fast the AP boots and typical ODRs */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) + +/* Sensors without hardware FIFO are in forced mode */ +#define CONFIG_ACCEL_FORCE_MODE_MASK \ + (BIT(LID_ACCEL)) + +/* Lid accel */ +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL +#define CONFIG_ACCEL_BMA4XX +#define CONFIG_ACCEL_LIS2DWL +#define CONFIG_ACCEL_LIS2DW_AS_BASE +#define CONFIG_ACCEL_LIS2DW12_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL) + +#define CONFIG_ACCEL_INTERRUPTS + +/* Sensor console commands */ +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO + +/* USB Type A Features */ +#define USB_PORT_COUNT 1 +#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 1 + +#define CONFIG_USB_PD_TCPM_PS8815 +#define CONFIG_USB_PD_TCPM_PS8815_FORCE_DID +#define CONFIG_USBC_PPC_SYV682X +#define CONFIG_USBC_PPC_NX20P3483 + +/* 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 */ + +/* + * Passive USB-C cables only support up to 60W. + */ +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW 45000 +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_VOLTAGE_MV 20000 + +/* The lower the input voltage, the higher the power efficiency. */ +#define PD_PREFER_LOW_VOLTAGE + +/* + * 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_ENABLE_BACKLIGHT GPIO_EC_EN_EDP_BL +#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW +#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV +#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 GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L + +/* + * 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_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL +#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL +#define GPIO_WP_L GPIO_EC_WP_ODL + +/* System has back-lit keyboard */ +#define CONFIG_PWM_KBLIGHT + +/* I2C Bus Configuration */ +#define I2C_PORT_SENSOR NPCX_I2C_PORT0_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_PPC NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C1_PPC NPCX_I2C_PORT6_1 +#define I2C_PORT_USB_C0_BC12 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C1_BC12 NPCX_I2C_PORT6_1 +#define I2C_PORT_USB_C1_MUX NPCX_I2C_PORT6_1 +#define I2C_PORT_BATTERY NPCX_I2C_PORT5_0 +#define I2C_PORT_CHARGER NPCX_I2C_PORT7_0 +#define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 +#define I2C_PORT_MP2964 NPCX_I2C_PORT7_0 +#define I2C_PORT_KBMCU NPCX_I2C_PORT3_0 + +#define I2C_ADDR_EEPROM_FLAGS 0x50 + +#define I2C_ADDR_MP2964_FLAGS 0x20 + +/* Thermal features */ +#define CONFIG_THERMISTOR +#define CONFIG_TEMP_SENSOR +#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B + +/* Fan */ +#define CONFIG_FANS FAN_CH_COUNT + +/* Charger defines */ +#define CONFIG_CHARGER_BQ25720 +#define CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM +/* 37h BIT7:2 VSYS_TH2 6.0V */ +#define CONFIG_CHARGER_BQ25720_VSYS_TH2_DV 60 +#define CONFIG_CHARGE_RAMP_SW +#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR_AC 10 +/* 30h BIT13:12 Enable PSYS 00b */ +#define CONFIG_CHARGER_BQ25710_PSYS_SENSING +/* 31h BIT3 = 1 Enable ACOC */ +#define CONFIG_CHARGER_BQ25710_EN_ACOC +/* 33h BIT15:11 ILIM2 TH 140% */ +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH \ + BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P40 +/* 34h BIT0 CONFIG_CHARGER_BQ25710_PP_ACOK */ +#define CONFIG_CHARGER_BQ25710_PP_ACOK +/* 34h BIT3 and BIT15:10 IDCHG 9728mA, step is 512mA */ +#define CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA 9728 +/* 36h UVP 5600mV */ +#define CONFIG_CHARGER_BQ25720_VSYS_UVP_CUSTOM +#define CONFIG_CHARGER_BQ25720_VSYS_UVP \ + BQ25720_CHARGE_OPTION_4_VSYS_UVP__5P6 +/* 3Eh BIT15:8 VSYS_MIN 6.1V */ +#define CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_CUSTOM +#define CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_MV 6100 + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" /* needed by registers.h */ +#include "registers.h" +#include "usbc_config.h" + +enum adc_channel { + ADC_TEMP_SENSOR_1_DDR_SOC, + ADC_TEMP_SENSOR_2_FAN, + ADC_TEMP_SENSOR_3_CHARGER, + ADC_TEMP_SENSOR_4_CPUCHOKE, + ADC_CH_COUNT +}; + +enum temp_sensor_id { + TEMP_SENSOR_1_DDR_SOC, + TEMP_SENSOR_2_FAN, + TEMP_SENSOR_3_CHARGER, + TEMP_SENSOR_4_CPUCHOKE, + TEMP_SENSOR_COUNT +}; + +enum sensor_id { + LID_ACCEL = 0, + BASE_ACCEL, + BASE_GYRO, + SENSOR_COUNT +}; + +enum ioex_port { + IOEX_C0_NCT38XX = 0, + IOEX_PORT_COUNT +}; + +enum battery_type { + BATTERY_SMP, + BATTERY_LGC, + BATTERY_SUNWODA, + BATTERY_TYPE_COUNT, +}; + +enum pwm_channel { + PWM_CH_KBLIGHT = 0, /* PWM3 */ + PWM_CH_FAN, /* PWM5 */ + PWM_CH_COUNT +}; + +enum fan_channel { + FAN_CH_0 = 0, + FAN_CH_COUNT +}; + +enum mft_channel { + MFT_CH_0 = 0, + MFT_CH_COUNT +}; + +void motion_interrupt(enum gpio_signal signal); + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/taniks/build.mk b/board/taniks/build.mk new file mode 100644 index 0000000000..2afcd5a0f8 --- /dev/null +++ b/board/taniks/build.mk @@ -0,0 +1,25 @@ +# -*- makefile -*- +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Taniks board specific files build +# + +CHIP:=npcx +CHIP_FAMILY:=npcx9 +CHIP_VARIANT:=npcx9m3f +BASEBOARD:=brya + +board-y= +board-y+=battery.o +board-y+=board.o +board-y+=charger.o +board-y+=fans.o +board-y+=fw_config.o +board-y+=i2c.o +board-y+=keyboard.o +board-y+=led.o +board-y+=pwm.o +board-y+=sensors.o +board-y+=usbc_config.o diff --git a/board/taniks/charger.c b/board/taniks/charger.c new file mode 120000 index 0000000000..476ce97df2 --- /dev/null +++ b/board/taniks/charger.c @@ -0,0 +1 @@ +../../baseboard/brya/charger_bq25720.c
\ No newline at end of file diff --git a/board/taniks/ec.tasklist b/board/taniks/ec.tasklist new file mode 100644 index 0000000000..6d995d6b44 --- /dev/null +++ b/board/taniks/ec.tasklist @@ -0,0 +1,30 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * 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, 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(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) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ + 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_INT_C0, pd_interrupt_handler_task, 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/taniks/fans.c b/board/taniks/fans.c new file mode 100644 index 0000000000..d50d3e5506 --- /dev/null +++ b/board/taniks/fans.c @@ -0,0 +1,88 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Physical fans. These are logically separate from pwm_channels. */ + +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "fan_chip.h" +#include "fan.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_1, + .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, +}; + +/* + * TODO(b/211076077): 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, + }, +}; + +#ifndef CONFIG_FANS + +/* + * TODO(b/211076077): use static fan speeds until fan and sensors are + * tuned. for now, use: + * + * AP off: 33% + * AP on: 100% + */ + +static void fan_slow(void) +{ + const int duty_pct = 33; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +static void fan_max(void) +{ + const int duty_pct = 100; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +DECLARE_HOOK(HOOK_INIT, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESET, fan_max, HOOK_PRIO_FIRST); +DECLARE_HOOK(HOOK_CHIPSET_RESUME, fan_max, HOOK_PRIO_DEFAULT); + +#endif /* CONFIG_FANS */ diff --git a/board/taniks/fw_config.c b/board/taniks/fw_config.c new file mode 100644 index 0000000000..578fcdfeb0 --- /dev/null +++ b/board/taniks/fw_config.c @@ -0,0 +1,65 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "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_CHIPSET, format, ## args) + +static union taniks_cbi_fw_config fw_config; +BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t)); + +/* + * FW_CONFIG defaults for Taniks if the CBI.FW_CONFIG data is not + * initialized. + */ +static const union taniks_cbi_fw_config fw_config_defaults = { + .usb_db = DB_USB3_PS8815, + .kb_bl = KEYBOARD_BACKLIGHT_ENABLED, +}; + +/**************************************************************************** + * Taniks 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; + } + + if (get_board_id() == 0) { + /* TODO(b/211076082): Update CBI fw config structure + * Update correct FW_CONFIG. + */ + CPRINTS("CBI: Using board defaults for early board"); + if (ec_cfg_has_tabletmode()) { + fw_config = fw_config_defaults; + } + } +} + +union taniks_cbi_fw_config get_fw_config(void) +{ + return fw_config; +} + +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void) +{ + return fw_config.usb_db; +} + +bool ec_cfg_has_keyboard_backlight(void) +{ + return (fw_config.kb_bl == KEYBOARD_BACKLIGHT_ENABLED); +} + +bool ec_cfg_has_tabletmode(void) +{ + return (fw_config.tabletmode == TABLETMODE_ENABLED); +} diff --git a/board/taniks/fw_config.h b/board/taniks/fw_config.h new file mode 100644 index 0000000000..35bf7b9cc2 --- /dev/null +++ b/board/taniks/fw_config.h @@ -0,0 +1,82 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __BOARD_TANIKS_FW_CONFIG_H_ +#define __BOARD_TANIKS_FW_CONFIG_H_ + +#include <stdint.h> + +/**************************************************************************** + * CBI FW_CONFIG layout for Taniks board. + * + * Source of truth is the project/taniks/taniks/config.star configuration file. + */ + +enum ec_cfg_usb_db_type { + DB_USB_ABSENT = 0, + DB_USB3_PS8815 = 1 +}; + +enum ec_cfg_keyboard_backlight_type { + KEYBOARD_BACKLIGHT_DISABLED = 0, + KEYBOARD_BACKLIGHT_ENABLED = 1 +}; + +enum ec_cfg_tabletmode_type { + TABLETMODE_DISABLED = 0, + TABLETMODE_ENABLED = 1 +}; + +union taniks_cbi_fw_config { + struct { + enum ec_cfg_usb_db_type usb_db : 2; + uint32_t sd_db : 2; + enum ec_cfg_keyboard_backlight_type kb_bl : 1; + uint32_t audio : 3; + uint32_t reserved_1 : 6; + /* b/211079131 - Fw config structure + * b/211076082 - Move tablet mode to bit14 + * bit8-9: kb_layout + * bit10-11: wifi_sar_id, + * bit12: nvme + * bit13: emmc + */ + enum ec_cfg_tabletmode_type tabletmode : 1; + uint32_t reserved_2 : 17; + }; + uint32_t raw_value; +}; + +/** + * Read the cached FW_CONFIG. Guaranteed to have valid values. + * + * @return the FW_CONFIG for the board. + */ +union taniks_cbi_fw_config get_fw_config(void); + +/** + * Get the USB daughter board type from FW_CONFIG. + * + * @return the USB daughter board type. + */ +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void); + +/** + * Check if the FW_CONFIG has enabled keyboard backlight. + * + * @return true if board supports keyboard backlight, false if the board + * doesn't support it. + */ +bool ec_cfg_has_keyboard_backlight(void); + +/** + * Check if the FW_CONFIG has enabled tablet mode. + * + * @return true if board supports tablet mode, false if the board + * doesn't support it. + */ +bool ec_cfg_has_tabletmode(void); + +#endif /* __BOARD_TANIKS_FW_CONFIG_H_ */ diff --git a/board/taniks/gpio.inc b/board/taniks/gpio.inc new file mode 100644 index 0000000000..9984ebc55e --- /dev/null +++ b/board/taniks/gpio.inc @@ -0,0 +1,146 @@ +/* -*- mode:c -*- + * + * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define MODULE_KB MODULE_KEYBOARD_SCAN + +/* 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, motion_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(2, 4), 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) +GPIO_INT(EC_VOLUP_BTN_ODL, PIN(9, 7), GPIO_INT_BOTH | GPIO_PULL_UP, button_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 | GPIO_HIB_WAKE_LOW, power_button_interrupt) +GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) +GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SEQ_EC_DSW_PWROK, PIN(2, 2), 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(2, 5), 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_TCPC_INT_ODL, PIN(2, 3), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C1_BC12_INT_ODL, PIN(5, 0), GPIO_INT_FALLING, bc12_interrupt) +GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(USB_C1_PPC_INT_ODL, PIN(F, 5), GPIO_INT_FALLING, ppc_interrupt) + +/* USED GPIOs: */ +GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) +GPIO(CHARGER_VAP_OTG_EN, PIN(7, 3), GPIO_OUT_LOW) +GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) +GPIO(EC_BATT_PRES_ODL, PIN(A, 3), GPIO_INPUT) +GPIO(EC_ENTERING_RW, PIN(0, 3), GPIO_OUT_LOW) +GPIO(EC_EN_EDP_BL, PIN(D, 3), GPIO_OUT_HIGH) +GPIO(EC_GSC_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW) +GPIO(EC_I2C_BAT_SCL, PIN(3, 3), GPIO_INPUT) +GPIO(EC_I2C_BAT_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_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_PPC_BC_SCL, PIN(9, 2), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_PPC_BC_SDA, PIN(9, 1), GPIO_INPUT) +GPIO(EC_I2C_KBMCU_SCL, PIN(D, 1), GPIO_INPUT) +GPIO(EC_I2C_KBMCU_SDA, PIN(D, 0), 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) +GPIO(EC_I2C_USB_C1_TCPC_SDA, PIN(F, 2), GPIO_INPUT) +GPIO(EC_KB_BL_EN_L, PIN(8, 6), GPIO_OUT_HIGH) +GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT) +GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) +GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), 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(2, 6), GPIO_OUT_LOW) +GPIO(EC_PCH_WAKE_R_ODL, PIN(C, 0), GPIO_ODR_HIGH) +GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) +GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_LOW) +GPIO(EN_PP5000_USBA_R, PIN(D, 7), GPIO_OUT_LOW) +GPIO(EN_S5_RAILS, PIN(B, 6), GPIO_OUT_LOW) +GPIO(IMVP9_VRRDY_OD, PIN(3, 0), GPIO_INPUT) +GPIO(PCH_PWROK, PIN(7, 2), GPIO_OUT_LOW) +GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH) +GPIO(USB_C0_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW) +GPIO(USB_C1_FRS_EN, PIN(9, 4), GPIO_OUT_LOW) +GPIO(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INPUT) +GPIO(USB_C1_RT_RST_R_ODL, PIN(0, 2), GPIO_ODR_HIGH) +GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) +GPIO(KBMCU_INT_ODL, PIN(7, 0), GPIO_INPUT) + +/* 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, GPIO_SEL_1P8V) /* 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(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ +ALTERNATE(PIN_MASK(8, 0x01), 0, MODULE_PWM, 0) /* GPIO80/PWM3 */ +ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */ + +/* ADC alternate functions */ +ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ +ALTERNATE(PIN_MASK(4, 0x24), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0 */ +ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */ + +/* KB alternate functions */ +ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */ +ALTERNATE(PIN_MASK(1, 0x7f), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO06/GPO13/GP_SEL_L, KSO07/GPO12/JEN_L, KSO03/GPIO16/JTAG_TDO0_SWO, KSO04/GPIO15/XNOR, KSO05/GPIO14, KSO08/GPIO11/CR_SOUT1, KSO09/GPIO10/CR_SIN1 */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO00/GPIO21/JTAG_TCK_SWCLK, KSO01/GPIO20/JTAG_TMS_SWIO */ +ALTERNATE(PIN_MASK(3, 0x80), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* GPIO37/PS2_CLK2/ADC5 */ +ALTERNATE(PIN_MASK(4, 0x1a), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* GPIO44/ADC1, GPIO43/ADC2, GPIO41/ADC4 */ +ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO14/GPIO82 */ +ALTERNATE(PIN_MASK(C, 0x80), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* GPIOC7/DTR_L_BOUT/ADC11 */ +ALTERNATE(PIN_MASK(E, 0x01), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* GPIOE0/ADC10 */ +ALTERNATE(PIN_MASK(F, 0x03), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* GPIOF1/ADC8, GPIOF0/ADC9 */ + +/* PMU alternate functions */ +ALTERNATE(PIN_MASK(0, 0x01), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN2_L&GPI00/GPIO00 */ +ALTERNATE(PIN_MASK(0, 0x02), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW) /* GPIO01/PSL_IN3_L&GPI01 */ +ALTERNATE(PIN_MASK(D, 0x04), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN1_L&GPID2/GPIOD2 */ + +/* Unused Pins */ +UNUSED(PIN(B, 1)) /* KSO17/GPIOB1/CR_SIN4 */ +UNUSED(PIN(D, 4)) /* GPIOD4/CR_SIN3 */ +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(4, 1)) /* GPIO41/ADC4 */ +UNUSED(PIN(6, 6)) /* GPIO66 */ +UNUSED(PIN(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ + +/* Pre-configured PSL balls: J8 K6 */ + +/* + * The NPCX keyboard driver does not use named GPIOs to access + * keyboard scan pins, so we do not list them in *gpio.inc. However, when + * KEYBOARD_COL2_INVERTED is defined, this name is required. + */ +GPIO(EC_KSO_02_INV, PIN(1, 7), 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) + +/* LED */ +GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_HIGH) /* Battery - Red LED */ +GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_HIGH) /* Battery - Green LED */ +GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_HIGH) /* Power - White LED */ diff --git a/board/taniks/i2c.c b/board/taniks/i2c.c new file mode 100644 index 0000000000..afbf101431 --- /dev/null +++ b/board/taniks/i2c.c @@ -0,0 +1,79 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "compile_time_macros.h" + +#include "i2c.h" + +/* I2C port map configuration */ +const struct i2c_port_t i2c_ports[] = { + { + /* I2C0 */ + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA, + }, + { + /* I2C1 */ + .name = "tcpc0", + .port = I2C_PORT_USB_C0_TCPC, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_TCPC_SCL, + .sda = GPIO_EC_I2C_USB_C0_TCPC_SDA, + }, + { + /* I2C2 */ + .name = "ppc0", + .port = I2C_PORT_USB_C0_PPC, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PPC_BC_SCL, + .sda = GPIO_EC_I2C_USB_C0_PPC_BC_SDA, + }, + { + /* I2C3 */ + .name = "kbmcu", + .port = I2C_PORT_KBMCU, + .kbps = 400, + .scl = GPIO_EC_I2C_KBMCU_SCL, + .sda = GPIO_EC_I2C_KBMCU_SDA, + }, + { + /* I2C4 C1 TCPC */ + /* TODO(b/211080526): Change TCPC1's (PS8815) I2C frequency from 400Khz to 1000Khz */ + .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 = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BAT_SCL, + .sda = GPIO_EC_I2C_BAT_SDA, + }, + { + /* I2C6 */ + .name = "ppc1", + .port = I2C_PORT_USB_C1_PPC, + .kbps = 400, + .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/taniks/keyboard.c b/board/taniks/keyboard.c new file mode 100644 index 0000000000..38a0799f9c --- /dev/null +++ b/board/taniks/keyboard.c @@ -0,0 +1,48 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#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 = { + 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ + }, +}; + +static const struct ec_response_keybd_config taniks_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 &taniks_kb; +} diff --git a/board/taniks/led.c b/board/taniks/led.c new file mode 100644 index 0000000000..1631bce51f --- /dev/null +++ b/board/taniks/led.c @@ -0,0 +1,119 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taniks specific PWM LED settings: there are 2 LEDs on each side of the board, + * each one can be controlled separately. The LED colors are white or amber, + * and the default behavior is tied to the charging process: both sides are + * amber while charging the battery and white when the battery is charged. + */ + +#include "common.h" +#include "led_onoff_states.h" +#include "led_common.h" +#include "gpio.h" + +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) + +#define LED_OFF_LVL 1 +#define LED_ON_LVL 0 + +__override const int led_charge_lvl_1 = 5; + +__override const int led_charge_lvl_2 = 97; + +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_RED, LED_INDEFINITE} }, + [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_GREEN, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_RED, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_RED, 2 * LED_ONE_SEC}, + {EC_LED_COLOR_GREEN, 2 * LED_ONE_SEC} }, +}; + +__override const struct led_descriptor + led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { + [PWR_LED_STATE_ON] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [PWR_LED_STATE_SUSPEND_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_SUSPEND_NO_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} }, +}; + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, + EC_LED_ID_POWER_LED +}; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_power(enum ec_led_colors color) +{ + if (color == EC_LED_COLOR_WHITE) + gpio_set_level(GPIO_LED_3_L, LED_ON_LVL); + else + /* LED_OFF and unsupported colors */ + gpio_set_level(GPIO_LED_3_L, LED_OFF_LVL); +} + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + gpio_set_level(GPIO_LED_1_L, LED_ON_LVL); + gpio_set_level(GPIO_LED_2_L, LED_ON_LVL); + break; + case EC_LED_COLOR_RED: + gpio_set_level(GPIO_LED_1_L, LED_ON_LVL); + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + break; + case EC_LED_COLOR_GREEN: + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_2_L, LED_ON_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + break; + } +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + brightness_range[EC_LED_COLOR_RED] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + brightness_range[EC_LED_COLOR_GREEN] = 1; + } else if (led_id == EC_LED_ID_POWER_LED) { + brightness_range[EC_LED_COLOR_WHITE] = 1; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + if (brightness[EC_LED_COLOR_RED] != 0) + led_set_color_battery(EC_LED_COLOR_RED); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else if (brightness[EC_LED_COLOR_GREEN] != 0) + led_set_color_battery(EC_LED_COLOR_GREEN); + else + led_set_color_battery(LED_OFF); + } else if (led_id == EC_LED_ID_POWER_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(EC_LED_COLOR_WHITE); + else + led_set_color_power(LED_OFF); + } + + return EC_SUCCESS; +} diff --git a/board/taniks/pwm.c b/board/taniks/pwm.c new file mode 100644 index 0000000000..b5fef384f9 --- /dev/null +++ b/board/taniks/pwm.c @@ -0,0 +1,39 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "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_KBLIGHT] = { + .channel = 3, + .flags = 0, + /* + * Set PWM frequency to multiple of 50 Hz and 60 Hz to prevent + * flicker. Higher frequencies consume similar average power to + * lower PWM frequencies, but higher frequencies record a much + * lower maximum power. + */ + .freq = 2400, + }, + [PWM_CH_FAN] = { + .channel = 5, + .flags = PWM_CONFIG_OPEN_DRAIN, + .freq = 25000 + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +static void board_pwm_init(void) +{ + + pwm_enable(PWM_CH_KBLIGHT, 1); + pwm_set_duty(PWM_CH_KBLIGHT, 50); +} +DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT); diff --git a/board/taniks/sensors.c b/board/taniks/sensors.c new file mode 100644 index 0000000000..ca8afa7f8d --- /dev/null +++ b/board/taniks/sensors.c @@ -0,0 +1,436 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "accelgyro.h" +#include "adc_chip.h" +#include "driver/accel_bma422.h" +#include "driver/accel_bma4xx.h" +#include "driver/accel_lis2dw12.h" +#include "driver/accelgyro_lsm6dsm.h" +#include "driver/accelgyro_lsm6dso.h" +#include "fw_config.h" +#include "hooks.h" +#include "i2c.h" +#include "motion_sense.h" +#include "temp_sensor.h" +#include "thermal.h" +#include "temp_sensor/thermistor.h" + +#if 0 +#define CPRINTS(format, args...) ccprints(format, ## args) +#define CPRINTF(format, args...) ccprintf(format, ## args) +#else +#define CPRINTS(format, args...) +#define CPRINTF(format, args...) +#endif + +/* ADC configuration */ +const struct adc_t adc_channels[] = { + [ADC_TEMP_SENSOR_1_DDR_SOC] = { + .name = "TEMP_DDR_SOC", + .input_ch = NPCX_ADC_CH0, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_2_FAN] = { + .name = "TEMP_FAN", + .input_ch = NPCX_ADC_CH1, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_3_CHARGER] = { + .name = "TEMP_CHARGER", + .input_ch = NPCX_ADC_CH6, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_4_CPUCHOKE] = { + .name = "CPU_CHOKE", + .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); + +K_MUTEX_DEFINE(g_lid_accel_mutex); +K_MUTEX_DEFINE(g_base_accel_mutex); +static struct stprivate_data g_lis2dw12_data; +static struct accelgyro_saved_data_t g_bma422_data; +static struct lsm6dso_data lsm6dso_data; +static struct lsm6dsm_data lsm6dsm_data = LSM6DSM_DATA; + +/* Matrix to rotate lid and base sensor into standard reference frame */ +static const mat33_fp_t lid_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(-1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +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)} +}; + +struct motion_sensor_t bma422_lid_accel = { + .name = "Lid Accel - BMA", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMA422, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &bma4_accel_drv, + .mutex = &g_lid_accel_mutex, + .drv_data = &g_bma422_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMA4_I2C_ADDR_PRIMARY, /* 0x18 */ + .rot_standard_ref = &lid_standard_ref, /* identity matrix */ + .default_range = 2, /* g, enough for laptop. */ + .min_frequency = BMA4_ACCEL_MIN_FREQ, + .max_frequency = BMA4_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 0, + }, + }, +}; + +struct motion_sensor_t lsm6dsm_base_accel = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSM, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dsm_drv, + .mutex = &g_base_accel_mutex, + .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, + MOTIONSENSE_TYPE_ACCEL), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ + .min_frequency = LSM6DSM_ODR_MIN_VAL, + .max_frequency = LSM6DSM_ODR_MAX_VAL, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, +}; + +struct motion_sensor_t lsm6dsm_base_gyro = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSM, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dsm_drv, + .mutex = &g_base_accel_mutex, + .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, + .default_range = 1000 | ROUND_UP_FLAG, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = LSM6DSM_ODR_MIN_VAL, + .max_frequency = LSM6DSM_ODR_MAX_VAL, +}; + +struct motion_sensor_t motion_sensors[] = { + [LID_ACCEL] = { + .name = "Lid Accel - ST", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LIS2DW12, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &lis2dw12_drv, + .mutex = &g_lid_accel_mutex, + .drv_data = &g_lis2dw12_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LIS2DW12_ADDR1, /* 0x19 */ + .rot_standard_ref = &lid_standard_ref, /* identity matrix */ + .default_range = 2, /* g */ + .min_frequency = LIS2DW12_ODR_MIN_VAL, + .max_frequency = LIS2DW12_ODR_MAX_VAL, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 12500 | ROUND_UP_FLAG, + }, + /* Sensor on for lid angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSO, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dso_drv, + .mutex = &g_base_accel_mutex, + .drv_data = &lsm6dso_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .default_range = 4, /* g */ + .min_frequency = LSM6DSO_ODR_MIN_VAL, + .max_frequency = LSM6DSO_ODR_MAX_VAL, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSO, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dso_drv, + .mutex = &g_base_accel_mutex, + .drv_data = &lsm6dso_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, + .default_range = 1000 | ROUND_UP_FLAG, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = LSM6DSO_ODR_MIN_VAL, + .max_frequency = LSM6DSO_ODR_MAX_VAL, + }, + +}; + +#ifdef CONFIG_DYNAMIC_MOTION_SENSOR_COUNT +unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); +#else +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); +#endif + + +static void board_detect_motionsensor(void) +{ + int ret; + int val; + + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return; + + /* + * b/194765820 - Dynamic motion sensor count + * All board supports tablet mode if board id > 0 + */ + if (get_board_id() == 0 && !ec_cfg_has_tabletmode()) + return; + + /* Check lid accel chip */ + ret = i2c_read8(I2C_PORT_SENSOR, LIS2DW12_ADDR1, + LIS2DW12_WHO_AM_I_REG, &val); + if (ret == 0 && val == LIS2DW12_WHO_AM_I) { + CPRINTS("LID_ACCEL is IS2DW12"); + /* Enable gpio interrupt for lid accel sensor */ + gpio_enable_interrupt(GPIO_EC_ACCEL_INT_R_L); + return; + } + + ret = i2c_read8(I2C_PORT_SENSOR, BMA4_I2C_ADDR_PRIMARY, + BMA4_CHIP_ID_ADDR, &val); + if (ret == 0 && val == BMA422_CHIP_ID) { + CPRINTS("LID_ACCEL is BMA422"); + motion_sensors[LID_ACCEL] = bma422_lid_accel; + /* + * The driver for BMA422 doesn't have code to support + * INT1. So, it doesn't need to enable interrupt. + * Vendor recommend to configure EC gpio as high-z if + * we don't use INT1. Keep this pin as input w/o enable + * interrupt. + */ + return; + } + + /* Lid accel is not stuffed, don't allow line to float */ + gpio_disable_interrupt(GPIO_EC_ACCEL_INT_R_L); + gpio_set_flags(GPIO_EC_ACCEL_INT_R_L, GPIO_INPUT | GPIO_PULL_DOWN); + CPRINTS("No LID_ACCEL are detected"); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_detect_motionsensor, + HOOK_PRIO_DEFAULT); + +static void baseboard_sensors_init(void) +{ + CPRINTS("baseboard_sensors_init"); + /* b/194765820 + * Dynamic motion sensor count + * All board supports tablet mode if board id > 0 + */ + if (ec_cfg_has_tabletmode()) { + /* + * GPIO_EC_ACCEL_INT_R_L + * The interrupt of lid accel is disabled by default. + * We'll enable it later if lid accel is LIS2DW12. + */ + + /* Change Request (b/199529373) + * GYRO sensor change from ST LSM6DSOETR3TR to ST LSM6DS3TR-C + * LSM6DSOETR3TR base accel/gyro if board id = 0 + * LSM6DS3TR-C Base accel/gyro if board id > 0 + */ + if (get_board_id() > 0) { + motion_sensors[BASE_ACCEL] = lsm6dsm_base_accel; + motion_sensors[BASE_GYRO] = lsm6dsm_base_gyro; + } + + /* Enable gpio interrupt for base accelgyro sensor */ + gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L); + } else { + CPRINTS("Clamshell"); + motion_sensor_count = 0; + /* Gyro is not present, don't allow line to float */ + gpio_set_flags(GPIO_EC_IMU_INT_R_L, GPIO_INPUT | + GPIO_PULL_DOWN); + } +} +DECLARE_HOOK(HOOK_INIT, baseboard_sensors_init, HOOK_PRIO_INIT_I2C + 1); + +void motion_interrupt(enum gpio_signal signal) +{ + if (motion_sensors[LID_ACCEL].chip == MOTIONSENSE_CHIP_LIS2DW12) { + lis2dw12_interrupt(signal); + CPRINTS("IS2DW12 interrupt"); + return; + } + + /* + * From other project, ex. guybrush, it seem BMA422 doesn't have + * interrupt handler when EC_ACCEL_INT_R_L is asserted. + * However, I don't see BMA422 assert EC_ACCEL_INT_R_L when it has + * power. That could be the reason EC code doesn't register any + * interrupt handler. + */ + CPRINTS("BMA422 interrupt"); + +} + +/* Temperature sensor configuration */ +const struct temp_sensor_t temp_sensors[] = { + [TEMP_SENSOR_1_DDR_SOC] = { + .name = "DDR and SOC", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_1_DDR_SOC + }, + [TEMP_SENSOR_2_FAN] = { + .name = "FAN", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_2_FAN + }, + [TEMP_SENSOR_3_CHARGER] = { + .name = "CHARGER", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_3_CHARGER + }, + [TEMP_SENSOR_4_CPUCHOKE] = { + .name = "CPU CHOKE", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_4_CPUCHOKE + }, +}; + + +BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +/* + * TODO(b/201021109): 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 (100 C) + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_CPU \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(100), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; + +/* + * TODO(b/201021109): update for Alder Lake/brya + * + * Inductor limits - used for both charger and PP3300 regulator + * + * Need to use the lower of the charger IC, PP3300 regulator, and the inductors + * + * Charger max recommended temperature 100C, max absolute temperature 125C + * PP3300 regulator: operating range -40 C to 145 C + * + * Inductors: limit of 125c + * PCB: limit is 100c + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_FAN \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(100), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_fan = THERMAL_FAN; + +/* this should really be "const" */ +struct ec_thermal_config thermal_params[] = { + [TEMP_SENSOR_1_DDR_SOC] = THERMAL_CPU, + [TEMP_SENSOR_2_FAN] = THERMAL_FAN, + [TEMP_SENSOR_3_CHARGER] = THERMAL_FAN, + [TEMP_SENSOR_4_CPUCHOKE] = THERMAL_FAN, +}; + +BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); diff --git a/board/taniks/usbc_config.c b/board/taniks/usbc_config.c new file mode 100644 index 0000000000..4cdb29b779 --- /dev/null +++ b/board/taniks/usbc_config.c @@ -0,0 +1,392 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdint.h> +#include <stdbool.h> + +#include "battery.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" +#include "ioexpander.h" +#include "system.h" +#include "task.h" +#include "task_id.h" +#include "timer.h" +#include "usbc_config.h" +#include "usbc_ppc.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +#if 0 +/* Debug only! */ +#define CPRINTSUSB(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTFUSB(format, args...) cprintf(CC_USBPD, format, ## args) +#else +#define CPRINTSUSB(format, args...) +#define CPRINTFUSB(format, args...) +#endif + +/* 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_TCPC, + .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, + }, + .drv = &nct38xx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, + [USBC_PORT_C1] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = PS8751_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, + }, +}; +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_PPC, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .drv = &syv682x_drv, + }, + [USBC_PORT_C1] = { + /* Compatible with Silicon Mitus SM536A0 */ + .i2c_port = I2C_PORT_USB_C1_PPC, + .i2c_addr_flags = NX20P3483_ADDR2_FLAGS, + .drv = &nx20p348x_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 */ + +/* + * 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 + * and updates the TCSS configuration on state changes. + */ +static const struct usb_mux usbc1_usb3_db_retimer = { + .usb_port = USBC_PORT_C1, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, +}; + +const struct usb_mux usb_muxes[] = { + [USBC_PORT_C0] = { + .usb_port = USBC_PORT_C0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + }, + [USBC_PORT_C1] = { + /* PS8815 DB */ + .usb_port = USBC_PORT_C1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + .next_mux = &usbc1_usb3_db_retimer, + }, +}; +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_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, + }, +}; +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_TCPC, + .i2c_addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, + .drv = &nct38xx_ioexpander_drv, + .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(ioex_config) == CONFIG_IO_EXPANDER_PORT_COUNT); + +void config_usb_db_type(void) +{ + enum ec_cfg_usb_db_type db_type = ec_cfg_usb_db_type(); + + /* + * TODO(b/194515356): implement multiple DB types + */ + CPRINTS("Configured USB DB type number is %d", db_type); +} + +static void ps8815_reset(void) +{ + int val; + + CPRINTS("%s: patching ps8815 registers", __func__); + + if (i2c_read8(I2C_PORT_USB_C1_TCPC, + PS8751_I2C_ADDR1_FLAGS, 0x0f, &val) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f was %02x", val); + else { + CPRINTS("delay 10ms to make sure PS8815 is waken from idle"); + msleep(10); + } + + + if (i2c_write8(I2C_PORT_USB_C1_TCPC, + PS8751_I2C_ADDR1_FLAGS, 0x0f, 0x31) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f set to 0x31"); + + if (i2c_read8(I2C_PORT_USB_C1_TCPC, + PS8751_I2C_ADDR1_FLAGS, 0x0f, &val) == EC_SUCCESS) + CPRINTS("ps8815: reg 0x0f now %02x", val); +} + +/** + * b/197585292 + * It's used for early board to check if usb_db is plugged or not. + * That's used to avoid TCPC1 initialization abnormal if db isn't + * plugged into system. + */ +enum usb_db_present { + DB_USB_NOT_PRESENT = 0, + DB_USB_PRESENT = 1, +}; +static enum usb_db_present db_usb_hw_pres; + +/** + * Init hw ps8815 detection and keep it in db_usb_hw_press. + * Then, we don't need to keep query ps8815 mcu. + */ +static void board_init_ps8815_detection(void) +{ + int rv, val; + + CPRINTSUSB("%s", __func__); + + rv = i2c_read8(I2C_PORT_USB_C1_TCPC, + PS8751_I2C_ADDR1_FLAGS, 0x00, &val); + + db_usb_hw_pres = (rv == EC_SUCCESS)?DB_USB_PRESENT:DB_USB_NOT_PRESENT; + + if (db_usb_hw_pres == DB_USB_NOT_PRESENT) + CPRINTS("DB isn't plugged or something went wrong!"); +} + +/** + * @return true if ps8815_db is plugged, false if it isn't plugged. + */ +static bool board_detect_ps8815_db(void) +{ + CPRINTSUSB("%s", __func__); + + /* All dut should plug ps8815 db if board id > 0 */ + if (get_board_id() > 0) + return true; + + if (ec_cfg_usb_db_type() == DB_USB3_PS8815 && + db_usb_hw_pres == DB_USB_PRESENT) + return true; + + CPRINTSUSB("No PS8815 DB"); + return false; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b/194618663): figure out correct timing + */ + + gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 0); + + /* + * (b/202489681): Nx20p3483 cannot sink power after reset ec + * To avoid nx20p3483 cannot sink power after reset ec w/ AC + * only in TCPC1 port, EC shouldn't assert GPIO_USB_C1_RT_RST_R_ODL + * if no battery. + */ + if (battery_hw_present()) + gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 0); + + /* + * delay for power-on to reset-off and min. assertion time + */ + msleep(GENERIC_MAX(PS8XXX_RESET_DELAY_MS, + PS8815_PWR_H_RST_H_DELAY_MS)); + + gpio_set_level(GPIO_USB_C0_TCPC_RST_ODL, 1); + gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1); + + /* wait for chips to come up */ + msleep(PS8815_FW_INIT_DELAY_MS); + ps8815_reset(); + + /* + * board_init_ps8815_detection should be called before + * board_get_usb_pd_port_count(). usb_mux_hpd_update can check + * pd port count. + */ + board_init_ps8815_detection(); + usb_mux_hpd_update(USBC_PORT_C1, USB_PD_MUX_HPD_LVL_DEASSERTED | + USB_PD_MUX_HPD_IRQ_DEASSERTED); +} + +static void board_tcpc_init(void) +{ + CPRINTSUSB("%s: board id = %d", __func__, get_board_id()); + + /* 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. + */ + ioex_init(0); + } + + CPRINTSUSB("Enable GPIO INT"); + + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); + if (board_detect_ps8815_db()) + gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); + + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL); + if (board_detect_ps8815_db()) + gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL); + + /* Enable BC1.2 interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); + if (board_detect_ps8815_db()) + gpio_enable_interrupt(GPIO_USB_C1_BC12_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_TCPC_INT_ODL) == 0) + status |= PD_STATUS_TCPC_ALERT_0; + + 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; + + if (port == USBC_PORT_C1) + return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0; + + return 0; +} + +void tcpc_alert_event(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_USB_C0_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: + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); + break; + case GPIO_USB_C1_BC12_INT_ODL: + task_set_event(TASK_ID_USB_CHG_P1, 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: + nx20p348x_interrupt(USBC_PORT_C1); + break; + default: + break; + } +} + +__override bool board_is_dts_port(int port) +{ + return port == USBC_PORT_C0; +} + +__override uint8_t board_get_usb_pd_port_count(void) +{ + CPRINTSUSB("%s is called by task_id:%d", __func__, task_get_current()); + + if (board_detect_ps8815_db()) + return CONFIG_USB_PD_PORT_MAX_COUNT; + + return CONFIG_USB_PD_PORT_MAX_COUNT - 1; +} diff --git a/board/taniks/usbc_config.h b/board/taniks/usbc_config.h new file mode 100644 index 0000000000..8bcf365e8d --- /dev/null +++ b/board/taniks/usbc_config.h @@ -0,0 +1,21 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Taniks board-specific USB-C configuration */ + +#ifndef __CROS_EC_USBC_CONFIG_H +#define __CROS_EC_USBC_CONFIG_H + +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 + +enum usbc_port { + USBC_PORT_C0 = 0, + USBC_PORT_C1, + USBC_PORT_COUNT +}; + +void config_usb_db_type(void); + +#endif /* __CROS_EC_USBC_CONFIG_H */ diff --git a/board/taniks/vif_override.xml b/board/taniks/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/taniks/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/terrador/ec.tasklist b/board/terrador/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/terrador/ec.tasklist +++ b/board/terrador/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/tglrvp_ish/board.h b/board/tglrvp_ish/board.h index 03044a5bb8..12f4b5992a 100644 --- a/board/tglrvp_ish/board.h +++ b/board/tglrvp_ish/board.h @@ -35,7 +35,7 @@ #define CONFIG_ACCEL_FORCE_MODE_MASK BIT(BASE_ACCEL) /* Host command over HECI */ -#define CONFIG_HOSTCMD_HECI +#define CONFIG_HOST_INTERFACE_HECI /* I2C ports */ #define I2C_PORT_SENSOR ISH_I2C1 diff --git a/board/tglrvpu_ite/gpio.inc b/board/tglrvpu_ite/gpio.inc index e0bce1ddd8..b84c92aac6 100644 --- a/board/tglrvpu_ite/gpio.inc +++ b/board/tglrvpu_ite/gpio.inc @@ -37,7 +37,7 @@ GPIO_INT(UART1_RX, PIN(B, 0), GPIO_INT_FALLING, uart_deepsleep_interrupt) /* UAR GPIO_INT(WP_L, PIN(I, 4), GPIO_INT_BOTH, switch_interrupt) /* EC_WP_ODL */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* enable 1.8v input of EC's espi_reset pin, and then this pin takes effect. */ GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INT_FALLING | GPIO_SEL_1P8V, espi_reset_pin_asserted_interrupt) /* eSPI_reset# */ #endif @@ -75,7 +75,7 @@ GPIO(EC_PCH_DSW_PWROK, PIN(L, 6), GPIO_OUT_LOW) /* Host communication GPIOs */ GPIO(PCH_WAKE_L, PIN(J, 0), GPIO_ODR_HIGH) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO(PCH_PLTRST_L, PIN(E, 3), GPIO_INPUT | GPIO_PULL_UP) #endif @@ -165,7 +165,7 @@ GPIO(NC_USB_C1_RETIMER_ALRT, PIN(G, 0), GPIO_INPUT) /* Used if Base EC is present */ GPIO(NC_EC_BASE_DET, PIN(I, 3), GPIO_INPUT) -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI GPIO_INT(ESPI_RESET_L, PIN(D, 2), GPIO_INPUT) #endif diff --git a/board/tigertail/board.c b/board/tigertail/board.c index f4d0382b9c..e7679a125d 100644 --- a/board/tigertail/board.c +++ b/board/tigertail/board.c @@ -103,8 +103,13 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, - GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_MASTER_I2C_SCL, + .sda = GPIO_MASTER_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/treeya/board.c b/board/treeya/board.c index 4583d89d7c..b0e4f459da 100644 --- a/board/treeya/board.c +++ b/board/treeya/board.c @@ -32,11 +32,41 @@ const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, - {"thermal", I2C_PORT_THERMAL_AP, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_I2C0_SCL, + .sda = GPIO_I2C0_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, + { + .name = "thermal", + .port = I2C_PORT_THERMAL_AP, + .kbps = 400, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_I2C7_SCL, + .sda = GPIO_I2C7_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); @@ -100,8 +130,6 @@ struct motion_sensor_t base_accel_1 = { .mutex = &g_base_mutex_1, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &lsm6dsm_base_standard_ref, @@ -132,8 +160,6 @@ struct motion_sensor_t base_gyro_1 = { .mutex = &g_base_mutex_1, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_ACCEL, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ @@ -144,10 +170,14 @@ struct motion_sensor_t base_gyro_1 = { static int board_use_st_sensor(void) { - /* sku_id 0xa8-0xa9 use ST sensors */ + /* sku_id 0xa8-0xa9, 0xbe, 0xbf use ST sensors */ uint32_t sku_id = system_get_sku_id(); - return sku_id == 0xa8 || sku_id == 0xa9; + if (sku_id == 0xa8 || sku_id == 0xa9 || + sku_id == 0xbe || sku_id == 0xbf) + return 1; + else + return 0; } /* treeya board will use two sets of lid/base sensor, we need update diff --git a/board/trogdor/board.c b/board/trogdor/board.c index 0261ada9ff..7036e57c4a 100644 --- a/board/trogdor/board.c +++ b/board/trogdor/board.c @@ -53,16 +53,41 @@ __override struct keyboard_scan_config keyscan_config = { /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/trogdor/usbc_config.c b/board/trogdor/usbc_config.c index dddc1d87a6..283001e3ed 100644 --- a/board/trogdor/usbc_config.c +++ b/board/trogdor/usbc_config.c @@ -6,6 +6,8 @@ /* Trogdor board-specific USB-C configuration */ #include "bc12/pi3usb9201_public.h" +#include "charger.h" +#include "charger/isl923x_public.h" #include "charge_manager.h" #include "charge_state.h" #include "common.h" @@ -26,6 +28,52 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} + /* GPIO Interrupt Handlers */ void tcpc_alert_event(enum gpio_signal signal) { diff --git a/board/twinkie/board.c b/board/twinkie/board.c index 6572f27281..f3f8460c8d 100644 --- a/board/twinkie/board.c +++ b/board/twinkie/board.c @@ -66,7 +66,13 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"master", I2C_PORT_MASTER, 100, GPIO_I2C_SCL, GPIO_I2C_SDA}, + { + .name = "master", + .port = I2C_PORT_MASTER, + .kbps = 100, + .scl = GPIO_I2C_SCL, + .sda = GPIO_I2C_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/twinkie/sniffer.c b/board/twinkie/sniffer.c index a567b5d725..7d2d8d439f 100644 --- a/board/twinkie/sniffer.c +++ b/board/twinkie/sniffer.c @@ -316,9 +316,9 @@ void sniffer_task(void) + (EP_PACKET_HEADER_SIZE>>1))), samples[d >> 4]+off, EP_PAYLOAD_SIZE); - atomic_clear_bits((uint32_t *)&free_usb, 1 << u); + atomic_clear_bits((atomic_t *)&free_usb, 1 << u); u = !u; - atomic_clear_bits((uint32_t *)&filled_dma, 1 << d); + atomic_clear_bits((atomic_t *)&filled_dma, 1 << d); } led_reset_record(); diff --git a/board/vell/battery.c b/board/vell/battery.c index 1f0239a013..f45cc53c13 100644 --- a/board/vell/battery.c +++ b/board/vell/battery.c @@ -33,70 +33,37 @@ * address, mask, and disconnect value need to be provided. */ const struct board_batt_params board_battery_info[] = { - /* POW-TECH GQA05 Battery Information */ - [BATTERY_POWER_TECH] = { - /* BQ40Z50 Fuel Gauge */ + /* Simplo Coslight Battery Information */ + [BATTERY_SIMPLO_COS] = { .fuel_gauge = { - .manuf_name = "POW-TECH", - .device_name = "BATGQA05L22", + .manuf_name = "333-1C-DA-A", .ship_mode = { .reg_addr = 0x00, .reg_data = { 0x0010, 0x0010 }, }, .fet = { .mfgacc_support = 1, - .reg_addr = 0x00, - .reg_mask = 0x2000, /* XDSG */ - .disconnect_val = 0x2000, - } - }, - .batt_info = { - .voltage_max = TARGET_WITH_MARGIN(13050, 5), - .voltage_normal = 11400, /* mV */ - .voltage_min = 9000, /* mV */ - .precharge_current = 280, /* mA */ - .start_charging_min_c = 0, - .start_charging_max_c = 45, - .charging_min_c = 0, - .charging_max_c = 45, - .discharging_min_c = -10, - .discharging_max_c = 60, - }, - }, - /* LGC L17L3PB0 Battery Information */ - /* - * Battery info provided by ODM on b/143477210, comment #11 - */ - [BATTERY_LGC011] = { - .fuel_gauge = { - .manuf_name = "LGC", - .ship_mode = { - .reg_addr = 0x00, - .reg_data = { 0x0010, 0x0010 }, - }, - .fet = { .reg_addr = 0x0, - .reg_mask = 0x6000, - .disconnect_val = 0x6000, - } + .reg_mask = 0x0006, + }, }, .batt_info = { - .voltage_max = TARGET_WITH_MARGIN(13200, 5), - .voltage_normal = 11550, /* mV */ - .voltage_min = 9000, /* mV */ - .precharge_current = 256, /* mA */ - .start_charging_min_c = 0, - .start_charging_max_c = 45, - .charging_min_c = 0, - .charging_max_c = 60, - .discharging_min_c = 0, - .discharging_max_c = 75, + .voltage_max = 8800, /* mV */ + .voltage_normal = 7600, + .voltage_min = 6000, + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 45, + .discharging_min_c = 0, + .discharging_max_c = 60, }, }, }; BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); -const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_POWER_TECH; +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_SIMPLO_COS; enum battery_present battery_hw_present(void) { diff --git a/board/vell/board.c b/board/vell/board.c index cb060442a2..47774afec5 100644 --- a/board/vell/board.c +++ b/board/vell/board.c @@ -13,8 +13,6 @@ #include "gpio.h" #include "gpio_signal.h" #include "hooks.h" -#include "driver/accel_lis2dw12.h" -#include "driver/accelgyro_lsm6dso.h" #include "driver/als_tcs3400.h" #include "fw_config.h" #include "hooks.h" @@ -23,7 +21,6 @@ #include "power.h" #include "registers.h" #include "switch.h" -#include "tablet_mode.h" #include "throttle_ap.h" #include "usbc_config.h" @@ -33,20 +30,18 @@ #define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) #define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) -/* Called on AP S3 -> S0 transition */ -static void board_chipset_resume(void) +static void board_chipset_startup(void) { /* Allow keyboard backlight to be enabled */ - gpio_set_level(GPIO_EC_KB_BL_EN_L, 0); + gpio_set_level(GPIO_EC_KB_BL_EN, 1); } -DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); -/* Called on AP S0 -> S3 transition */ -static void board_chipset_suspend(void) +static void board_chipset_shutdown(void) { /* Turn off the keyboard backlight if it's on. */ - gpio_set_level(GPIO_EC_KB_BL_EN_L, 1); + gpio_set_level(GPIO_EC_KB_BL_EN, 0); } -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); diff --git a/board/vell/board.h b/board/vell/board.h index 6b99df2569..30ec2a210f 100644 --- a/board/vell/board.h +++ b/board/vell/board.h @@ -10,11 +10,6 @@ #include "compile_time_macros.h" -/* - * Early brya boards are not set up for vivaldi - */ -#undef CONFIG_KEYBOARD_VIVALDI - /* Baseboard features */ #include "baseboard.h" @@ -24,22 +19,13 @@ */ #define CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP -/* LED */ -#define CONFIG_LED_PWM -#define CONFIG_LED_PWM_COUNT 2 -#undef CONFIG_LED_PWM_NEAR_FULL_COLOR -#undef CONFIG_LED_PWM_SOC_ON_COLOR -#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR -#undef CONFIG_LED_PWM_LOW_BATT_COLOR -#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE -#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER +/* Buttons */ +#undef CONFIG_VOLUME_BUTTONS /* Sensors */ -#define CONFIG_ACCELGYRO_LSM6DSO /* Base accel */ -#define CONFIG_ACCEL_LSM6DSO_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#undef CONFIG_TABLET_MODE +#undef CONFIG_TABLET_MODE_SWITCH +#undef CONFIG_GMR_TABLET_MODE /* TCS3400 ALS */ #define CONFIG_ALS @@ -56,29 +42,10 @@ #define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) /* Sensors without hardware FIFO are in forced mode */ -#define CONFIG_ACCEL_FORCE_MODE_MASK \ - (BIT(LID_ACCEL) | BIT(CLEAR_ALS)) - -/* Lid accel */ -#define CONFIG_LID_ANGLE -#define CONFIG_LID_ANGLE_UPDATE -#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL -#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL -#define CONFIG_ACCEL_LIS2DWL -#define CONFIG_ACCEL_LIS2DW_AS_BASE -#define CONFIG_ACCEL_LIS2DW12_INT_EVENT \ - TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL) +#define CONFIG_ACCEL_FORCE_MODE_MASK BIT(CLEAR_ALS) #define CONFIG_ACCEL_INTERRUPTS -/* Sensor console commands */ -#define CONFIG_CMD_ACCELS -#define CONFIG_CMD_ACCEL_INFO - -/* USB Type A Features */ -#define USB_PORT_COUNT 1 -#define CONFIG_USB_PORT_POWER_DUMB - /* USB Type C and USB PD defines */ #define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY @@ -86,31 +53,25 @@ #define CONFIG_IO_EXPANDER_NCT38XX #define CONFIG_IO_EXPANDER_PORT_COUNT 4 -#define CONFIG_USB_PD_TCPM_PS8815 -#define CONFIG_USB_PD_TCPM_PS8815_FORCE_DID #define CONFIG_USBC_RETIMER_INTEL_BB -/* I2C speed console command */ -#define CONFIG_CMD_I2C_SPEED - -/* I2C control host command */ -#define CONFIG_HOSTCMD_I2C_CONTROL - #define CONFIG_USBC_PPC_SYV682X +/* TODO: b/211791444 - Remove it after compile error fixed */ #define CONFIG_USBC_PPC_NX20P3483 +#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 */ -/* - * Passive USB-C cables only support up to 60W. - */ +/* USB Type C and USB PD defines */ #define PD_OPERATING_POWER_MW 15000 -#define PD_MAX_POWER_MW 60000 -#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_CURRENT_MA 5000 #define PD_MAX_VOLTAGE_MV 20000 +/* Max Power = 100 W */ +#define PD_MAX_POWER_MW ((PD_MAX_VOLTAGE_MV * PD_MAX_CURRENT_MA) / 1000) /* * Macros for GPIO signals used in common code that don't match the @@ -130,7 +91,7 @@ #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 GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_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 @@ -142,9 +103,11 @@ #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_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL -#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL #define GPIO_WP_L GPIO_EC_WP_ODL +#define GPIO_RIGHT_LED_AMBER_L GPIO_LED_1_L +#define GPIO_RIGHT_LED_WHITE_L GPIO_LED_2_L +#define GPIO_LEFT_LED_AMBER_L GPIO_LED_3_L +#define GPIO_LEFT_LED_WHITE_L GPIO_LED_4_L /* System has back-lit keyboard */ #define CONFIG_PWM_KBLIGHT @@ -153,17 +116,17 @@ #define I2C_PORT_SENSOR 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_C1_TCPC NPCX_I2C_PORT1_0 +#define I2C_PORT_USB_C2_C3_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_C1_PPC NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C2_C3_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_C1_BC12 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_C2_C3_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_USB_C0_C1_MUX NPCX_I2C_PORT3_0 +#define I2C_PORT_USB_C2_C3_MUX NPCX_I2C_PORT3_0 #define I2C_PORT_BATTERY NPCX_I2C_PORT5_0 #define I2C_PORT_CHARGER NPCX_I2C_PORT7_0 @@ -175,7 +138,9 @@ * see b/174768555#comment22 */ #define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x56 -#define USBC_PORT_C2_BB_RETIMER_I2C_ADDR 0x57 +#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x57 +#define USBC_PORT_C2_BB_RETIMER_I2C_ADDR 0x58 +#define USBC_PORT_C3_BB_RETIMER_I2C_ADDR 0x59 /* Enabling Thunderbolt-compatible mode */ #define CONFIG_USB_PD_TBT_COMPAT_MODE @@ -189,19 +154,19 @@ /* Thermal features */ #define CONFIG_THERMISTOR #define CONFIG_TEMP_SENSOR -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_TEMP_SENSOR_POWER #define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B #define CONFIG_FANS FAN_CH_COUNT /* Charger defines */ -#define CONFIG_CHARGER_BQ25720 -#define CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM -#define CONFIG_CHARGER_BQ25720_VSYS_TH2_DV 70 +#define CONFIG_CHARGER_ISL9241 #define CONFIG_CHARGE_RAMP_SW -#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR 10 -#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR_AC 10 -#define CONFIG_CHARGER_BQ25710_PSYS_SENSING +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 + +/* Keyboard features */ +#define CONFIG_KEYBOARD_REFRESH_ROW3 /* * Older boards have a different ADC assignment. @@ -216,51 +181,45 @@ #include "usbc_config.h" 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_TEMP_SENSOR_1_SOC, + ADC_TEMP_SENSOR_2_CHARGER, + ADC_TEMP_SENSOR_3_WWAN, + ADC_TEMP_SENSOR_4_DDR, + ADC_TEMP_SENSOR_5_REGULATOR, ADC_CH_COUNT }; enum temp_sensor_id { - TEMP_SENSOR_1_DDR_SOC, - TEMP_SENSOR_2_AMBIENT, - TEMP_SENSOR_3_CHARGER, - TEMP_SENSOR_4_WWAN, + TEMP_SENSOR_1_SOC, + TEMP_SENSOR_2_CHARGER, + TEMP_SENSOR_3_WWAN, + TEMP_SENSOR_4_DDR, + TEMP_SENSOR_5_REGULATOR, TEMP_SENSOR_COUNT }; enum sensor_id { - LID_ACCEL = 0, - BASE_ACCEL, - BASE_GYRO, - CLEAR_ALS, + CLEAR_ALS = 0, RGB_ALS, SENSOR_COUNT }; enum ioex_port { IOEX_C0_NCT38XX = 0, + IOEX_C1_NCT38XX, IOEX_C2_NCT38XX, - IOEX_ID_1_C0_NCT38XX, - IOEX_ID_1_C2_NCT38XX, + IOEX_C3_NCT38XX, IOEX_PORT_COUNT }; enum battery_type { - BATTERY_POWER_TECH, - BATTERY_LGC011, + BATTERY_SIMPLO_COS, 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_KBLIGHT = 0, /* PWM3 */ PWM_CH_FAN, /* PWM5 */ - PWM_CH_LED4, /* PWM7 (white on DB) */ PWM_CH_COUNT }; diff --git a/board/vell/charger.c b/board/vell/charger.c index 04be67147d..06933f04f1 100644 --- a/board/vell/charger.c +++ b/board/vell/charger.c @@ -10,7 +10,8 @@ #include "charger.h" #include "compile_time_macros.h" #include "console.h" -#include "driver/charger/bq25710.h" +#include "driver/charger/isl9241.h" +#include "hooks.h" #include "usbc_ppc.h" #include "usb_pd.h" #include "util.h" @@ -23,8 +24,8 @@ const struct charger_config_t chg_chips[] = { { .i2c_port = I2C_PORT_CHARGER, - .i2c_addr_flags = BQ25710_SMBUS_ADDR1_FLAGS, - .drv = &bq25710_drv, + .i2c_addr_flags = ISL9241_ADDR_FLAGS, + .drv = &isl9241_drv, }, }; BUILD_ASSERT(ARRAY_SIZE(chg_chips) == CHARGER_NUM); @@ -88,3 +89,9 @@ __overridable void board_set_charge_limit(int port, int supplier, int charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); } + +static void set_ac_prochot(void) +{ + isl9241_set_ac_prochot(CHARGER_SOLO, PD_MAX_CURRENT_MA); +} +DECLARE_HOOK(HOOK_INIT, set_ac_prochot, HOOK_PRIO_DEFAULT); diff --git a/board/vell/ec.tasklist b/board/vell/ec.tasklist index 5efc5a8d23..924d708a6b 100644 --- a/board/vell/ec.tasklist +++ b/board/vell/ec.tasklist @@ -12,14 +12,17 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, HOOKS_TASK_STACK_SIZE) \ + TASK_ALWAYS(LED, led_task, NULL, 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(USB_CHG_P3, 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) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ @@ -27,5 +30,6 @@ 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) + TASK_ALWAYS(PD_C3, pd_task, NULL, BASEBOARD_PD_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C0, pd_shared_alert_task, (BIT(1) | BIT(0)), BASEBOARD_PD_INT_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_shared_alert_task, (BIT(3) | BIT(2)), BASEBOARD_PD_INT_TASK_STACK_SIZE) diff --git a/board/vell/gpio.inc b/board/vell/gpio.inc index 27f57f392a..3753ad8eb5 100644 --- a/board/vell/gpio.inc +++ b/board/vell/gpio.inc @@ -9,32 +9,31 @@ /* 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) -GPIO_INT(EC_VOLUP_BTN_ODL, PIN(9, 7), GPIO_INT_BOTH | GPIO_PULL_UP, button_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 | GPIO_HIB_WAKE_LOW, power_button_interrupt) GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) -GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(SEQ_EC_ALL_SYS_PG, PIN(D, 7), 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(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_C1_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_C1_PPC_INT_ODL, PIN(9, 5), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C1_RT_INT_ODL, PIN(A, 0), GPIO_INT_FALLING, retimer_interrupt) GPIO_INT(USB_C2_BC12_INT_ODL, PIN(8, 3), GPIO_INT_FALLING, bc12_interrupt) +GPIO_INT(USB_C2_C3_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_FALLING, tcpc_alert_event) 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(USB_C2_RT_INT_ODL, PIN(9, 4), GPIO_INT_FALLING, retimer_interrupt) +GPIO_INT(USB_C3_BC12_INT_ODL, PIN(5, 6), GPIO_INT_FALLING, bc12_interrupt) +GPIO_INT(USB_C3_PPC_INT_ODL, PIN(8, 1), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C3_RT_INT_ODL, PIN(9, 3), GPIO_INT_FALLING, retimer_interrupt) /* USED GPIOs: */ GPIO(CCD_MODE_ODL, PIN(E, 5), GPIO_INPUT) @@ -50,17 +49,17 @@ 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_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) -GPIO(EC_KB_BL_EN_L, PIN(8, 6), GPIO_OUT_HIGH) +GPIO(EC_I2C_USB_C0_C1_PPC_BC_SCL, PIN(9, 2), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_C1_PPC_BC_SDA, PIN(9, 1), GPIO_INPUT) +GPIO(EC_I2C_USB_RT_SCL, PIN(D, 1), GPIO_INPUT) +GPIO(EC_I2C_USB_RT_SDA, PIN(D, 0), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_C1_TCPC_SCL, PIN(9, 0), GPIO_INPUT) +GPIO(EC_I2C_USB_C0_C1_TCPC_SDA, PIN(8, 7), GPIO_INPUT) +GPIO(EC_I2C_USB_C2_C3_PPC_BC_RT_SCL, PIN(E, 4), GPIO_INPUT) +GPIO(EC_I2C_USB_C2_C3_PPC_BC_RT_SDA, PIN(E, 3), GPIO_INPUT) +GPIO(EC_I2C_USB_C2_C3_TCPC_SCL, PIN(F, 3), GPIO_INPUT) +GPIO(EC_I2C_USB_C2_C3_TCPC_SDA, PIN(F, 2), GPIO_INPUT) +GPIO(EC_KB_BL_EN, PIN(8, 0), GPIO_OUT_LOW) GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT) GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), GPIO_ODR_HIGH) @@ -70,18 +69,20 @@ GPIO(EC_PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) GPIO(EC_PCH_WAKE_R_ODL, PIN(C, 0), GPIO_ODR_HIGH) GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH) -GPIO(EN_PP5000_USBA_R, PIN(D, 7), GPIO_OUT_LOW) 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_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(USB_C0_C1_TCPC_RST_ODL, PIN(A, 7), GPIO_ODR_LOW) +GPIO(USB_C2_C3_TCPC_RST_ODL, PIN(9, 6), GPIO_ODR_LOW) GPIO(VCCST_PWRGD_OD, PIN(A, 4), GPIO_ODR_LOW) +/* LED */ +GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_HIGH) +GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_HIGH) +GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_HIGH) +GPIO(LED_4_L, PIN(6, 0), GPIO_OUT_HIGH) + /* UART alternate functions */ ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* GPIO64/CR_SIN1, GPO65/CR_SOUT1/FLPRG1_L */ @@ -97,14 +98,11 @@ ALTERNATE(PIN_MASK(F, 0x0c), 0, MODULE_I2C, 0) /* GPIOF3/I2C4_SCL1 /* PWM alternate functions */ ALTERNATE(PIN_MASK(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ -ALTERNATE(PIN_MASK(6, 0x01), 0, MODULE_PWM, 0) /* GPIO60/PWM7 */ -ALTERNATE(PIN_MASK(8, 0x01), 0, MODULE_PWM, 0) /* GPIO80/PWM3 */ ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */ -ALTERNATE(PIN_MASK(C, 0x1c), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0, GPIOC2/PWM1/I2C6_SCL0 */ /* ADC alternate functions */ ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ -ALTERNATE(PIN_MASK(4, 0x34), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1 */ +ALTERNATE(PIN_MASK(4, 0x36), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1, GPIO41/ADC4*/ ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */ /* KB alternate functions */ @@ -125,6 +123,11 @@ 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(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ +UNUSED(PIN(F, 4)) /* GPIOF4/I2C5_SDA1 */ +UNUSED(PIN(F, 5)) /* GPIOF5/I2C5_SCL1 */ +UNUSED(PIN(8, 6)) /* GPO86/TXD/CR_SOUT2 */ +UNUSED(PIN(9, 7)) /* GPIO97 */ /* Pre-configured PSL balls: J8 K6 */ @@ -136,14 +139,26 @@ UNUSED(PIN(6, 6)) /* GPIO66 */ GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) /* IO expander configuration */ -/* GPIO02_P2 to PU */ -/* GPIO03_P2 to PU */ +/* GPIO02_P1 to PU */ +/* GPIO03_P1 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_C1_RT_RST_ODL, EXPIN(IOEX_C1_NCT38XX, 0, 2), GPIO_ODR_LOW) +/* GPIO03_P2 to PU */ +IOEX(USB_C1_OC_ODL, EXPIN(IOEX_C1_NCT38XX, 0, 4), GPIO_ODR_HIGH) +IOEX(USB_C1_FRS_EN, EXPIN(IOEX_C1_NCT38XX, 0, 6), GPIO_LOW) +/* GPIO07_P2 to PU */ + +/* GPIO02_P1 to PU */ +/* GPIO03_P1 to PU */ 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) +IOEX(USB_C2_RT_RST_ODL, EXPIN(IOEX_C2_NCT38XX, 0, 7), GPIO_ODR_LOW) + +IOEX(USB_C3_RT_RST_ODL, EXPIN(IOEX_C3_NCT38XX, 0, 2), GPIO_ODR_LOW) +/* GPIO03_P2 to PU */ +IOEX(USB_C3_OC_ODL, EXPIN(IOEX_C3_NCT38XX, 0, 4), GPIO_ODR_HIGH) +IOEX(USB_C3_FRS_EN, EXPIN(IOEX_C3_NCT38XX, 0, 6), GPIO_LOW) /* GPIO07_P2 to PU */ diff --git a/board/vell/i2c.c b/board/vell/i2c.c index 3db2e0c17b..def6bff688 100644 --- a/board/vell/i2c.c +++ b/board/vell/i2c.c @@ -8,8 +8,6 @@ #include "hooks.h" #include "i2c.h" -#define BOARD_ID_FAST_PLUS_CAPABLE 2 - /* I2C port map configuration */ const struct i2c_port_t i2c_ports[] = { { @@ -22,36 +20,35 @@ const struct i2c_port_t i2c_ports[] = { }, { /* 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, + .name = "tcpc0,1", + .port = I2C_PORT_USB_C0_C1_TCPC, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C0_C1_TCPC_SCL, + .sda = GPIO_EC_I2C_USB_C0_C1_TCPC_SDA, }, { /* I2C2 */ - .name = "ppc0,2", - .port = I2C_PORT_USB_C0_C2_PPC, - .kbps = 1000, - .scl = GPIO_EC_I2C_USB_C0_C2_PPC_BC_SCL, - .sda = GPIO_EC_I2C_USB_C0_C2_PPC_BC_SDA, + .name = "ppc0,1", + .port = I2C_PORT_USB_C0_C1_PPC, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C0_C1_PPC_BC_SCL, + .sda = GPIO_EC_I2C_USB_C0_C1_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, + .name = "retimer0,1,2,3", + .port = I2C_PORT_USB_C0_C1_MUX, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_RT_SCL, + .sda = GPIO_EC_I2C_USB_RT_SDA, }, { - /* I2C4 C1 TCPC */ - .name = "tcpc1", - .port = I2C_PORT_USB_C1_TCPC, - .kbps = 1000, - .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, - .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, - .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + /* I2C4 */ + .name = "tcpc2,3", + .port = I2C_PORT_USB_C2_C3_TCPC, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C2_C3_TCPC_SCL, + .sda = GPIO_EC_I2C_USB_C2_C3_TCPC_SDA, }, { /* I2C5 */ @@ -63,12 +60,11 @@ const struct i2c_port_t i2c_ports[] = { }, { /* 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, - .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + .name = "ppc2,3", + .port = I2C_PORT_USB_C2_C3_PPC, + .kbps = 400, + .scl = GPIO_EC_I2C_USB_C2_C3_PPC_BC_RT_SCL, + .sda = GPIO_EC_I2C_USB_C2_C3_PPC_BC_RT_SDA, }, { /* I2C7 */ @@ -80,19 +76,3 @@ const struct i2c_port_t i2c_ports[] = { }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); - -/* - * I2C controllers are initialized in main.c. This sets the speed much - * later, but before I2C peripherals are initialized. - */ -static void set_board_legacy_i2c_speeds(void) -{ - if (get_board_id() >= BOARD_ID_FAST_PLUS_CAPABLE) - return; - - ccprints("setting USB DB I2C buses to 400 kHz\n"); - - i2c_set_freq(I2C_PORT_USB_C1_TCPC, I2C_FREQ_400KHZ); - i2c_set_freq(I2C_PORT_USB_C1_PPC, I2C_FREQ_400KHZ); -} -DECLARE_HOOK(HOOK_INIT, set_board_legacy_i2c_speeds, HOOK_PRIO_INIT_I2C - 1); diff --git a/board/vell/keyboard.c b/board/vell/keyboard.c index a9f033130d..2ab0ef9fc3 100644 --- a/board/vell/keyboard.c +++ b/board/vell/keyboard.c @@ -4,7 +4,7 @@ */ #include "common.h" - +#include "ec_commands.h" #include "keyboard_scan.h" #include "timer.h" @@ -23,3 +23,30 @@ __override struct keyboard_scan_config keyscan_config = { 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ }, }; + +static const struct ec_response_keybd_config keybd1 = { + .num_top_row_keys = 13, + .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_KBD_BKLIGHT_TOGGLE, /* T8 */ + TK_PLAY_PAUSE, /* T9 */ + TK_MICMUTE, /* T10 */ + TK_VOL_MUTE, /* T11 */ + TK_VOL_DOWN, /* T12 */ + TK_VOL_UP, /* T13 */ + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + +__override const struct ec_response_keybd_config * +board_vivaldi_keybd_config(void) +{ + return &keybd1; + +} diff --git a/board/vell/led.c b/board/vell/led.c index 68945ec79e..48555f8de7 100644 --- a/board/vell/led.c +++ b/board/vell/led.c @@ -1,93 +1,206 @@ /* Copyright 2021 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. - */ - -/* Brya specific PWM LED settings: there are 2 LEDs on each side of the board, - * each one can be controlled separately. The LED colors are white or amber, - * and the default behavior is tied to the charging process: both sides are - * amber while charging the battery and white when the battery is charged. + * + * Power and battery LED control for Vell */ #include <stdint.h> -#include "common.h" -#include "compile_time_macros.h" +#include "battery.h" +#include "charge_manager.h" +#include "charge_state.h" #include "ec_commands.h" -#include "led_pwm.h" -#include "pwm.h" +#include "gpio.h" +#include "host_command.h" +#include "led_common.h" +#include "task.h" #include "util.h" +#define BAT_LED_ON 0 +#define BAT_LED_OFF 1 + +#define LED_TICK_INTERVAL_MS (500 * MSEC) +#define LED_CYCLE_TIME_MS (2000 * MSEC) +#define LED_TICKS_PER_CYCLE (LED_CYCLE_TIME_MS / LED_TICK_INTERVAL_MS) +#define LED_ON_TIME_MS (1000 * MSEC) +#define LED_ON_TICKS (LED_ON_TIME_MS / LED_TICK_INTERVAL_MS) + const enum ec_led_id supported_led_ids[] = { EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED, + EC_LED_ID_RIGHT_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -/* - * We only have a white and an amber LED, so setting any other color results in - * both LEDs being off. - */ -struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { - /* Amber, White */ - [EC_LED_COLOR_RED] = { 0, 0 }, - [EC_LED_COLOR_GREEN] = { 0, 0 }, - [EC_LED_COLOR_BLUE] = { 0, 0 }, - [EC_LED_COLOR_YELLOW] = { 0, 0 }, - [EC_LED_COLOR_WHITE] = { 0, 100 }, - [EC_LED_COLOR_AMBER] = { 100, 0 }, +enum led_color { + LED_OFF = 0, + LED_AMBER, + LED_WHITE, + LED_COLOR_COUNT /* Number of colors, not a color itself */ }; -/* Two logical LEDs with amber and white channels. */ -struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { - { - .ch0 = PWM_CH_LED1, - .ch1 = PWM_CH_LED2, - .ch2 = PWM_LED_NO_CHANNEL, - .enable = &pwm_enable, - .set_duty = &pwm_set_duty, - }, - { - .ch0 = PWM_CH_LED3, - .ch1 = PWM_CH_LED4, - .ch2 = PWM_LED_NO_CHANNEL, - .enable = &pwm_enable, - .set_duty = &pwm_set_duty, - }, +enum led_port { + RIGHT_PORT = 0, + LEFT_PORT }; +static void led_set_color_battery(int port, enum led_color color) +{ + enum gpio_signal amber_led, white_led; + + amber_led = (port == RIGHT_PORT ? GPIO_RIGHT_LED_AMBER_L : + GPIO_LEFT_LED_AMBER_L); + white_led = (port == RIGHT_PORT ? GPIO_RIGHT_LED_WHITE_L : + GPIO_LEFT_LED_WHITE_L); + + switch (color) { + case LED_WHITE: + gpio_set_level(white_led, BAT_LED_ON); + gpio_set_level(amber_led, BAT_LED_OFF); + break; + case LED_AMBER: + gpio_set_level(white_led, BAT_LED_OFF); + gpio_set_level(amber_led, BAT_LED_ON); + break; + case LED_OFF: + gpio_set_level(white_led, BAT_LED_OFF); + gpio_set_level(amber_led, BAT_LED_OFF); + break; + default: + break; + } +} + void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { memset(brightness_range, '\0', sizeof(*brightness_range) * EC_LED_COLOR_COUNT); - brightness_range[EC_LED_COLOR_AMBER] = 100; - brightness_range[EC_LED_COLOR_WHITE] = 100; + switch (led_id) { + case EC_LED_ID_LEFT_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + break; + case EC_LED_ID_RIGHT_LED: + brightness_range[EC_LED_COLOR_WHITE] = 1; + brightness_range[EC_LED_COLOR_AMBER] = 1; + break; + default: + break; + } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { - enum pwm_led_id pwm_id; - - /* Convert ec_led_id to pwm_led_id. */ switch (led_id) { case EC_LED_ID_LEFT_LED: - pwm_id = PWM_LED0; + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(LEFT_PORT, LED_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(LEFT_PORT, LED_AMBER); + else + led_set_color_battery(LEFT_PORT, LED_OFF); break; case EC_LED_ID_RIGHT_LED: - pwm_id = PWM_LED1; + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(RIGHT_PORT, LED_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(RIGHT_PORT, LED_AMBER); + else + led_set_color_battery(RIGHT_PORT, LED_OFF); break; default: - return EC_ERROR_UNKNOWN; + return EC_ERROR_PARAM1; } - if (brightness[EC_LED_COLOR_WHITE]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); - else if (brightness[EC_LED_COLOR_AMBER]) - set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); - else - /* Otherwise, the "color" is "off". */ - set_pwm_led_color(pwm_id, -1); - return EC_SUCCESS; } + +/* + * Set active charge port color to the parameter, turn off all others. + * If no port is active (-1), turn off all LEDs. + */ +static void set_active_port_color(enum led_color color) +{ + int usbc_port = charge_manager_get_active_charge_port(); + int port = 0; + + if ((usbc_port == USBC_PORT_C0) || (usbc_port == USBC_PORT_C1)) + port = RIGHT_PORT; + else if ((usbc_port == USBC_PORT_C2) || (usbc_port == USBC_PORT_C3)) + port = LEFT_PORT; + + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) + led_set_color_battery(RIGHT_PORT, + (port == RIGHT_PORT) ? color : LED_OFF); + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + led_set_color_battery(LEFT_PORT, + (port == LEFT_PORT) ? color : LED_OFF); +} + +static void led_set_battery(void) +{ + static unsigned int battery_ticks; + uint32_t chflags = charge_get_flags(); + + battery_ticks++; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + /* Always indicate when charging, even in suspend. */ + set_active_port_color(LED_AMBER); + break; + case PWR_STATE_DISCHARGE: + if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) { + if (charge_get_percent() < 10) + led_set_color_battery(RIGHT_PORT, + (battery_ticks % LED_TICKS_PER_CYCLE + < LED_ON_TICKS) ? LED_WHITE : LED_OFF); + else + led_set_color_battery(RIGHT_PORT, LED_OFF); + } + + if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) + led_set_color_battery(LEFT_PORT, LED_OFF); + break; + case PWR_STATE_ERROR: + set_active_port_color((battery_ticks & 0x1) ? + LED_WHITE : LED_OFF); + break; + case PWR_STATE_CHARGE_NEAR_FULL: + set_active_port_color(LED_WHITE); + break; + case PWR_STATE_IDLE: /* External power connected in IDLE */ + if (chflags & CHARGE_FLAG_FORCE_IDLE) + set_active_port_color((battery_ticks % + LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? + LED_AMBER : LED_OFF); + else + set_active_port_color(LED_WHITE); + break; + default: + /* Other states don't alter LED behavior */ + break; + } +} + +void led_task(void *u) +{ + uint32_t start_time; + uint32_t task_duration; + + while (1) { + start_time = get_time().le.lo; + + led_set_battery(); + + /* Compute time for this iteration */ + task_duration = get_time().le.lo - start_time; + /* + * Compute wait time required to for next desired LED tick. If + * the duration exceeds the tick time, then don't sleep. + */ + if (task_duration < LED_TICK_INTERVAL_MS) + usleep(LED_TICK_INTERVAL_MS - task_duration); + } +} diff --git a/board/vell/pwm.c b/board/vell/pwm.c index 6e662f8e7d..8535de88e1 100644 --- a/board/vell/pwm.c +++ b/board/vell/pwm.c @@ -11,21 +11,6 @@ #include "pwm_chip.h" const struct pwm_t pwm_channels[] = { - [PWM_CH_LED2] = { - .channel = 0, - .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, - .freq = 4800, - }, [PWM_CH_KBLIGHT] = { .channel = 3, .flags = 0, @@ -42,11 +27,6 @@ const struct pwm_t pwm_channels[] = { .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP, .freq = 1000 }, - [PWM_CH_LED4] = { - .channel = 7, - .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, - .freq = 4800, - }, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); @@ -54,17 +34,7 @@ static void board_pwm_init(void) { /* * Turn on all the LED at 50%. - * Turn on the fan at 100%. */ - pwm_enable(PWM_CH_LED1, 1); - pwm_set_duty(PWM_CH_LED1, 50); - pwm_enable(PWM_CH_LED2, 1); - pwm_set_duty(PWM_CH_LED2, 50); - pwm_enable(PWM_CH_LED3, 1); - pwm_set_duty(PWM_CH_LED3, 50); - pwm_enable(PWM_CH_LED4, 1); - pwm_set_duty(PWM_CH_LED4, 50); - pwm_enable(PWM_CH_KBLIGHT, 1); pwm_set_duty(PWM_CH_KBLIGHT, 50); } diff --git a/board/vell/sensors.c b/board/vell/sensors.c index 0a4b0198bd..46bc33e492 100644 --- a/board/vell/sensors.c +++ b/board/vell/sensors.c @@ -6,8 +6,6 @@ #include "common.h" #include "accelgyro.h" #include "adc.h" -#include "driver/accel_lis2dw12.h" -#include "driver/accelgyro_lsm6dso.h" #include "driver/als_tcs3400_public.h" #include "hooks.h" #include "motion_sense.h" @@ -17,56 +15,44 @@ /* ADC configuration */ struct adc_t adc_channels[] = { - [ADC_TEMP_SENSOR_1_DDR_SOC] = { - .name = "TEMP_DDR_SOC", + [ADC_TEMP_SENSOR_1_SOC] = { + .name = "TEMP_SOC", .input_ch = NPCX_ADC_CH0, .factor_mul = ADC_MAX_VOLT, .factor_div = ADC_READ_MAX + 1, .shift = 0, }, - [ADC_TEMP_SENSOR_2_AMBIENT] = { - .name = "TEMP_AMBIENT", + [ADC_TEMP_SENSOR_2_CHARGER] = { + .name = "TEMP_CHARGER", .input_ch = NPCX_ADC_CH1, .factor_mul = ADC_MAX_VOLT, .factor_div = ADC_READ_MAX + 1, .shift = 0, }, - [ADC_TEMP_SENSOR_3_CHARGER] = { - .name = "TEMP_CHARGER", + [ADC_TEMP_SENSOR_3_WWAN] = { + .name = "TEMP_WWAN", .input_ch = NPCX_ADC_CH6, .factor_mul = ADC_MAX_VOLT, .factor_div = ADC_READ_MAX + 1, .shift = 0, }, - [ADC_TEMP_SENSOR_4_WWAN] = { - .name = "TEMP_WWAN", + [ADC_TEMP_SENSOR_4_DDR] = { + .name = "TEMP_DDR", .input_ch = NPCX_ADC_CH7, .factor_mul = ADC_MAX_VOLT, .factor_div = ADC_READ_MAX + 1, .shift = 0, }, + [ADC_TEMP_SENSOR_5_REGULATOR] = { + .name = "TEMP_REGULATOR", + .input_ch = NPCX_ADC_CH4, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, }; BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); -K_MUTEX_DEFINE(g_lid_accel_mutex); -K_MUTEX_DEFINE(g_base_accel_mutex); -static struct stprivate_data g_lis2dw12_data; -static struct lsm6dso_data lsm6dso_data; - -/* TODO(b/184779333): calibrate the orientation matrix on later board stage */ -static const mat33_fp_t lid_standard_ref = { - { 0, FLOAT_TO_FP(1), 0}, - { FLOAT_TO_FP(1), 0, 0}, - { 0, 0, FLOAT_TO_FP(-1)} -}; - -/* TODO(b/184779743): verify orientation matrix */ -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, @@ -122,85 +108,6 @@ static struct tcs3400_rgb_drv_data_t g_tcs3400_rgb_data = { }; struct motion_sensor_t motion_sensors[] = { - [LID_ACCEL] = { - .name = "Lid Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_LIS2DW12, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_LID, - .drv = &lis2dw12_drv, - .mutex = &g_lid_accel_mutex, - .drv_data = &g_lis2dw12_data, - .int_signal = GPIO_EC_ACCEL_INT_R_L, - .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = LIS2DW12_ADDR0, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .rot_standard_ref = &lid_standard_ref, /* identity matrix */ - .default_range = 2, /* g */ - .min_frequency = LIS2DW12_ODR_MIN_VAL, - .max_frequency = LIS2DW12_ODR_MAX_VAL, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - /* Sensor on for lid angle detection */ - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, - - [BASE_ACCEL] = { - .name = "Base Accel", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_LSM6DSO, - .type = MOTIONSENSE_TYPE_ACCEL, - .location = MOTIONSENSE_LOC_BASE, - .drv = &lsm6dso_drv, - .mutex = &g_base_accel_mutex, - .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, - MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, - .rot_standard_ref = &base_standard_ref, - .default_range = 4, /* g */ - .min_frequency = LSM6DSO_ODR_MIN_VAL, - .max_frequency = LSM6DSO_ODR_MAX_VAL, - .config = { - [SENSOR_CONFIG_EC_S0] = { - .odr = 13000 | ROUND_UP_FLAG, - .ec_rate = 100 * MSEC, - }, - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 100 * MSEC, - }, - }, - }, - - [BASE_GYRO] = { - .name = "Base Gyro", - .active_mask = SENSOR_ACTIVE_S0_S3, - .chip = MOTIONSENSE_CHIP_LSM6DSO, - .type = MOTIONSENSE_TYPE_GYRO, - .location = MOTIONSENSE_LOC_BASE, - .drv = &lsm6dso_drv, - .mutex = &g_base_accel_mutex, - .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, - MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_EC_IMU_INT_R_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, - .port = I2C_PORT_SENSOR, - .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, - .default_range = 1000 | ROUND_UP_FLAG, /* dps */ - .rot_standard_ref = &base_standard_ref, - .min_frequency = LSM6DSO_ODR_MIN_VAL, - .max_frequency = LSM6DSO_ODR_MAX_VAL, - }, - [CLEAR_ALS] = { .name = "Clear Light", .active_mask = SENSOR_ACTIVE_S0_S3, @@ -249,46 +156,48 @@ 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); } DECLARE_HOOK(HOOK_INIT, baseboard_sensors_init, HOOK_PRIO_INIT_I2C + 1); /* Temperature sensor configuration */ const struct temp_sensor_t temp_sensors[] = { - [TEMP_SENSOR_1_DDR_SOC] = { - .name = "DDR and SOC", + [TEMP_SENSOR_1_SOC] = { + .name = "SOC", .type = TEMP_SENSOR_TYPE_BOARD, .read = get_temp_3v3_30k9_47k_4050b, - .idx = ADC_TEMP_SENSOR_1_DDR_SOC, + .idx = ADC_TEMP_SENSOR_1_SOC, }, - [TEMP_SENSOR_2_AMBIENT] = { - .name = "Ambient", + [TEMP_SENSOR_2_CHARGER] = { + .name = "Charger", .type = TEMP_SENSOR_TYPE_BOARD, .read = get_temp_3v3_30k9_47k_4050b, - .idx = ADC_TEMP_SENSOR_2_AMBIENT, + .idx = ADC_TEMP_SENSOR_2_CHARGER, }, - [TEMP_SENSOR_3_CHARGER] = { - .name = "Charger", + [TEMP_SENSOR_3_WWAN] = { + .name = "WWAN", .type = TEMP_SENSOR_TYPE_BOARD, .read = get_temp_3v3_30k9_47k_4050b, - .idx = ADC_TEMP_SENSOR_3_CHARGER, + .idx = ADC_TEMP_SENSOR_3_WWAN, }, - [TEMP_SENSOR_4_WWAN] = { - .name = "WWAN", + [TEMP_SENSOR_4_DDR] = { + .name = "DDR", .type = TEMP_SENSOR_TYPE_BOARD, .read = get_temp_3v3_30k9_47k_4050b, - .idx = ADC_TEMP_SENSOR_4_WWAN, + .idx = ADC_TEMP_SENSOR_4_DDR, + }, + [TEMP_SENSOR_5_REGULATOR] = { + .name = "Regulator", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_5_REGULATOR, }, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); /* - * TODO(b/180681346): update for Alder Lake/brya + * TODO(b/203839956): update for Alder Lake/vell * * Alder 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 @@ -312,17 +221,7 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); __maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; /* - * TODO(b/180681346): update for Alder Lake/brya - * - * Inductor limits - used for both charger and PP3300 regulator - * - * Need to use the lower of the charger IC, PP3300 regulator, and the inductors - * - * Charger max recommended temperature 100C, max absolute temperature 125C - * PP3300 regulator: operating range -40 C to 145 C - * - * Inductors: limit of 125c - * PCB: limit is 80c + * TODO(b/203839956): update for Alder Lake/vell */ /* * TODO(b/202062363): Remove when clang is fixed. @@ -343,15 +242,7 @@ __maybe_unused static const struct ec_thermal_config thermal_ambient = THERMAL_AMBIENT; /* - * Inductor limits - used for both charger and PP3300 regulator - * - * Need to use the lower of the charger IC, PP3300 regulator, and the inductors - * - * Charger max recommended temperature 125C, max absolute temperature 150C - * PP3300 regulator: operating range -40 C to 125 C - * - * Inductors: limit of 125c - * PCB: limit is 80c + * TODO(b/203839956): update for Alder Lake/vell */ /* * TODO(b/202062363): Remove when clang is fixed. @@ -372,7 +263,7 @@ __maybe_unused static const struct ec_thermal_config thermal_charger = THERMAL_CHARGER; /* - * TODO(b/180681346): update for brya WWAN module + * TODO(b/203839956): update for vell WWAN module */ /* * TODO(b/202062363): Remove when clang is fixed. @@ -392,27 +283,54 @@ __maybe_unused static const struct ec_thermal_config thermal_charger = __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); +/* + * TODO(b/203839956): update for Alder Lake/vell + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ -static void board_thermals_init(void) -{ - if (get_board_id() == 1) { - /* - * Board ID 1 only has 3 sensors and the AMBIENT sensor - * ADC pins have been reassigned, so we're down to 2 - * sensors that can easily be configured. So, alias the - * AMBIENT sensor ADC channel to the unimplemented ADC - * slots. - */ - adc_channels[ADC_TEMP_SENSOR_3_CHARGER].input_ch = NPCX_ADC_CH1; - adc_channels[ADC_TEMP_SENSOR_4_WWAN].input_ch = NPCX_ADC_CH1; +#define THERMAL_DDR \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(90), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ } -} +__maybe_unused static const struct ec_thermal_config thermal_ddr = + THERMAL_DDR; + +/* + * TODO(b/203839956): update for Alder Lake/vell + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ + +#define THERMAL_REGULATOR \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(105), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(120), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(65), \ + } +__maybe_unused static const struct ec_thermal_config thermal_regulator = + THERMAL_REGULATOR; -DECLARE_HOOK(HOOK_INIT, board_thermals_init, HOOK_PRIO_INIT_CHIPSET); +struct ec_thermal_config thermal_params[] = { + [TEMP_SENSOR_1_SOC] = thermal_cpu, + [TEMP_SENSOR_2_CHARGER] = thermal_charger, + [TEMP_SENSOR_3_WWAN] = thermal_wwan, + [TEMP_SENSOR_4_DDR] = thermal_ddr, + [TEMP_SENSOR_5_REGULATOR] = thermal_regulator, +}; diff --git a/board/vell/usbc_config.c b/board/vell/usbc_config.c index ba50928dd2..eca6782ba4 100644 --- a/board/vell/usbc_config.c +++ b/board/vell/usbc_config.c @@ -17,7 +17,6 @@ #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" @@ -44,29 +43,35 @@ 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_C1_TCPC, .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, }, .drv = &nct38xx_tcpm_drv, - .flags = TCPC_FLAGS_TCPCI_REV2_0 | - TCPC_FLAGS_NO_DEBUG_ACC_CONTROL, + .flags = TCPC_FLAGS_TCPCI_REV2_0, }, [USBC_PORT_C1] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { - .port = I2C_PORT_USB_C1_TCPC, - .addr_flags = PS8751_I2C_ADDR1_FLAGS, + .port = I2C_PORT_USB_C0_C1_TCPC, + .addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS, }, - .drv = &ps8xxx_tcpm_drv, - .flags = TCPC_FLAGS_TCPCI_REV2_0 | - TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | - TCPC_FLAGS_CONTROL_VCONN, + .drv = &nct38xx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0, }, [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, + .port = I2C_PORT_USB_C2_C3_TCPC, + .addr_flags = NCT38XX_I2C_ADDR1_4_FLAGS, + }, + .drv = &nct38xx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, + [USBC_PORT_C3] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C2_C3_TCPC, + .addr_flags = NCT38XX_I2C_ADDR2_4_FLAGS, }, .drv = &nct38xx_tcpm_drv, .flags = TCPC_FLAGS_TCPCI_REV2_0, @@ -75,38 +80,28 @@ const struct tcpc_config_t tcpc_config[] = { BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT); BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT); -/******************************************************************************/ -/* USB-A charging control */ - -const int usb_port_enable[USB_PORT_COUNT] = { - GPIO_EN_PP5000_USBA_R, -}; -BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT); - -/******************************************************************************/ - /* 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_C1_PPC, .i2c_addr_flags = SYV682X_ADDR0_FLAGS, .drv = &syv682x_drv, }, [USBC_PORT_C1] = { - /* Compatible with Silicon Mitus SM536A0 */ - .i2c_port = I2C_PORT_USB_C1_PPC, - .i2c_addr_flags = NX20P3483_ADDR2_FLAGS, - .drv = &nx20p348x_drv, + .i2c_port = I2C_PORT_USB_C0_C1_PPC, + .i2c_addr_flags = SYV682X_ADDR1_FLAGS, + .drv = &syv682x_drv, }, [USBC_PORT_C2] = { - .i2c_port = I2C_PORT_USB_C0_C2_PPC, - /* - * b/179987870 - * schematics I2C map says ADDR3 - */ + .i2c_port = I2C_PORT_USB_C2_C3_PPC, .i2c_addr_flags = SYV682X_ADDR2_FLAGS, .drv = &syv682x_drv, }, + [USBC_PORT_C3] = { + .i2c_port = I2C_PORT_USB_C2_C3_PPC, + .i2c_addr_flags = SYV682X_ADDR3_FLAGS, + .drv = &syv682x_drv, + }, }; BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT); @@ -118,21 +113,20 @@ static const struct usb_mux usbc0_tcss_usb_mux = { .driver = &virtual_usb_mux_driver, .hpd_update = &virtual_hpd_update, }; +static const struct usb_mux usbc1_tcss_usb_mux = { + .usb_port = USBC_PORT_C1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; static const struct usb_mux usbc2_tcss_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 - * and updates the TCSS configuration on state changes. - */ -static const struct usb_mux usbc1_usb3_db_retimer = { - .usb_port = USBC_PORT_C1, - .driver = &tcpci_tcpm_usb_mux_driver, - .hpd_update = &ps8xxx_tcpc_update_hpd_status, +static const struct usb_mux usbc3_tcss_usb_mux = { + .usb_port = USBC_PORT_C3, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, }; const struct usb_mux usb_muxes[] = { @@ -140,42 +134,55 @@ const struct usb_mux usb_muxes[] = { .usb_port = USBC_PORT_C0, .driver = &bb_usb_retimer, .hpd_update = bb_retimer_hpd_update, - .i2c_port = I2C_PORT_USB_C0_C2_MUX, + .i2c_port = I2C_PORT_USB_C0_C1_MUX, .i2c_addr_flags = USBC_PORT_C0_BB_RETIMER_I2C_ADDR, .next_mux = &usbc0_tcss_usb_mux, }, [USBC_PORT_C1] = { - /* PS8815 DB */ .usb_port = USBC_PORT_C1, - .driver = &virtual_usb_mux_driver, - .hpd_update = &virtual_hpd_update, - .next_mux = &usbc1_usb3_db_retimer, + .driver = &bb_usb_retimer, + .hpd_update = bb_retimer_hpd_update, + .i2c_port = I2C_PORT_USB_C0_C1_MUX, + .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR, + .next_mux = &usbc1_tcss_usb_mux, }, [USBC_PORT_C2] = { .usb_port = USBC_PORT_C2, .driver = &bb_usb_retimer, .hpd_update = bb_retimer_hpd_update, - .i2c_port = I2C_PORT_USB_C0_C2_MUX, + .i2c_port = I2C_PORT_USB_C2_C3_MUX, .i2c_addr_flags = USBC_PORT_C2_BB_RETIMER_I2C_ADDR, .next_mux = &usbc2_tcss_usb_mux, }, + [USBC_PORT_C3] = { + .usb_port = USBC_PORT_C3, + .driver = &bb_usb_retimer, + .hpd_update = bb_retimer_hpd_update, + .i2c_port = I2C_PORT_USB_C2_C3_MUX, + .i2c_addr_flags = USBC_PORT_C3_BB_RETIMER_I2C_ADDR, + .next_mux = &usbc3_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_port = I2C_PORT_USB_C0_C1_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, + .i2c_port = I2C_PORT_USB_C0_C1_BC12, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_2_FLAGS, }, [USBC_PORT_C2] = { - .i2c_port = I2C_PORT_USB_C0_C2_BC12, + .i2c_port = I2C_PORT_USB_C2_C3_BC12, .i2c_addr_flags = PI3USB9201_I2C_ADDR_1_FLAGS, }, + [USBC_PORT_C3] = { + .i2c_port = I2C_PORT_USB_C2_C3_BC12, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_0_FLAGS, + }, }; BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT); @@ -190,26 +197,26 @@ 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_C1_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, + [IOEX_C1_NCT38XX] = { + .i2c_host_port = I2C_PORT_USB_C0_C1_TCPC, .i2c_addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS, .drv = &nct38xx_ioexpander_drv, .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED, }, - [IOEX_ID_1_C0_NCT38XX] = { - .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC, - .i2c_addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, + [IOEX_C2_NCT38XX] = { + .i2c_host_port = I2C_PORT_USB_C2_C3_TCPC, + .i2c_addr_flags = NCT38XX_I2C_ADDR1_4_FLAGS, .drv = &nct38xx_ioexpander_drv, .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED, }, - [IOEX_ID_1_C2_NCT38XX] = { - .i2c_host_port = I2C_PORT_USB_C0_C2_TCPC, - .i2c_addr_flags = NCT38XX_I2C_ADDR2_1_FLAGS, + [IOEX_C3_NCT38XX] = { + .i2c_host_port = I2C_PORT_USB_C2_C3_TCPC, + .i2c_addr_flags = NCT38XX_I2C_ADDR2_4_FLAGS, .drv = &nct38xx_ioexpander_drv, .flags = IOEX_FLAGS_DEFAULT_INIT_DISABLED, }, @@ -256,8 +263,12 @@ __override int bb_retimer_power_enable(const struct usb_mux *me, bool enable) if (me->usb_port == USBC_PORT_C0) rst_signal = IOEX_USB_C0_RT_RST_ODL; + else if (me->usb_port == USBC_PORT_C1) + rst_signal = IOEX_USB_C1_RT_RST_ODL; else if (me->usb_port == USBC_PORT_C2) rst_signal = IOEX_USB_C2_RT_RST_ODL; + else if (me->usb_port == USBC_PORT_C3) + rst_signal = IOEX_USB_C3_RT_RST_ODL; else return EC_ERROR_INVAL; @@ -288,63 +299,58 @@ __override int bb_retimer_power_enable(const struct usb_mux *me, bool enable) void board_reset_pd_mcu(void) { - /* - * TODO(b/203371200): figure out correct timing - */ - - gpio_set_level(GPIO_USB_C0_C2_TCPC_RST_ODL, 0); - 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_C1_TCPC_RST_ODL, 0); + gpio_set_level(GPIO_USB_C2_C3_TCPC_RST_ODL, 0); /* * delay for power-on to reset-off and min. assertion time */ + msleep(NCT38XX_RESET_HOLD_DELAY_MS); - msleep(20); + gpio_set_level(GPIO_USB_C0_C1_TCPC_RST_ODL, 1); + gpio_set_level(GPIO_USB_C2_C3_TCPC_RST_ODL, 1); - gpio_set_level(GPIO_USB_C0_C2_TCPC_RST_ODL, 1); - gpio_set_level(GPIO_USB_C1_RST_ODL, 1); - gpio_set_level(GPIO_USB_C1_RT_RST_R_ODL, 1); + nct38xx_reset_notify(USBC_PORT_C0); + nct38xx_reset_notify(USBC_PORT_C1); + nct38xx_reset_notify(USBC_PORT_C2); + nct38xx_reset_notify(USBC_PORT_C3); /* wait for chips to come up */ - - msleep(50); -} - -static void enable_ioex(int ioex) -{ - ioex_init(ioex); + if (NCT3808_RESET_POST_DELAY_MS != 0) + msleep(NCT3808_RESET_POST_DELAY_MS); } static void board_tcpc_init(void) { + int i; + /* Don't reset TCPCs after initial reset */ - if (!system_jumped_late()) { + 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); - } + /* + * These IO expander pins are implemented using the + * C0/C1/C2/C3 TCPCs, so they must be set up after the TCPC + * has been taken out of reset. + */ + for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; ++i) + ioex_init(i); /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); gpio_enable_interrupt(GPIO_USB_C2_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C3_PPC_INT_ODL); /* Enable TCPC interrupts. */ - gpio_enable_interrupt(GPIO_USB_C0_C2_TCPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C0_C1_TCPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C2_C3_TCPC_INT_ODL); /* Enable BC1.2 interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); - gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL); - - gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); - gpio_enable_interrupt(GPIO_USB_C1_TCPC_INT_ODL); gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C3_BC12_INT_ODL); } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_CHIPSET); @@ -352,11 +358,11 @@ 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_C0_C1_TCPC_INT_ODL) == 0) + status = PD_STATUS_TCPC_ALERT_0 | PD_STATUS_TCPC_ALERT_1; - if (gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL) == 0) - status |= PD_STATUS_TCPC_ALERT_1; + if (gpio_get_level(GPIO_USB_C2_C3_TCPC_INT_ODL) == 0) + status = PD_STATUS_TCPC_ALERT_2 | PD_STATUS_TCPC_ALERT_3; return status; } @@ -369,17 +375,19 @@ int ppc_get_alert_status(int port) 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; + else if (port == USBC_PORT_C3) + return gpio_get_level(GPIO_USB_C3_PPC_INT_ODL) == 0; return 0; } void tcpc_alert_event(enum gpio_signal signal) { switch (signal) { - case GPIO_USB_C0_C2_TCPC_INT_ODL: + case GPIO_USB_C0_C1_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); + case GPIO_USB_C2_C3_TCPC_INT_ODL: + schedule_deferred_pd_interrupt(USBC_PORT_C2); break; default: break; @@ -398,6 +406,9 @@ void bc12_interrupt(enum gpio_signal signal) case GPIO_USB_C2_BC12_INT_ODL: task_set_event(TASK_ID_USB_CHG_P2, USB_CHG_EVENT_BC12); break; + case GPIO_USB_C3_BC12_INT_ODL: + task_set_event(TASK_ID_USB_CHG_P3, USB_CHG_EVENT_BC12); + break; default: break; } @@ -410,11 +421,14 @@ void ppc_interrupt(enum gpio_signal signal) syv682x_interrupt(USBC_PORT_C0); break; case GPIO_USB_C1_PPC_INT_ODL: - nx20p348x_interrupt(USBC_PORT_C1); + syv682x_interrupt(USBC_PORT_C1); break; case GPIO_USB_C2_PPC_INT_ODL: syv682x_interrupt(USBC_PORT_C2); break; + case GPIO_USB_C3_PPC_INT_ODL: + syv682x_interrupt(USBC_PORT_C3); + break; default: break; } @@ -431,19 +445,3 @@ __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/vell/usbc_config.h b/board/vell/usbc_config.h index f21e2c17dc..447c03efb3 100644 --- a/board/vell/usbc_config.h +++ b/board/vell/usbc_config.h @@ -8,12 +8,13 @@ #ifndef __CROS_EC_USBC_CONFIG_H #define __CROS_EC_USBC_CONFIG_H -#define CONFIG_USB_PD_PORT_MAX_COUNT 3 +#define CONFIG_USB_PD_PORT_MAX_COUNT 4 enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_C2, + USBC_PORT_C3, USBC_PORT_COUNT }; diff --git a/board/vilboz/board.c b/board/vilboz/board.c index a39d46cbcd..006ee57645 100644 --- a/board/vilboz/board.c +++ b/board/vilboz/board.c @@ -106,8 +106,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs.*/ @@ -138,8 +136,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(g_lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_6AXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/voema/ec.tasklist b/board/voema/ec.tasklist index 292de51cdb..3e20d8ae39 100644 --- a/board/voema/ec.tasklist +++ b/board/voema/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/volet/ec.tasklist b/board/volet/ec.tasklist index e76bd368eb..ca6d9fbf14 100644 --- a/board/volet/ec.tasklist +++ b/board/volet/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/volmar/battery.c b/board/volmar/battery.c new file mode 100644 index 0000000000..172365195e --- /dev/null +++ b/board/volmar/battery.c @@ -0,0 +1,112 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_fuel_gauge.h" +#include "cbi.h" +#include "common.h" +#include "compile_time_macros.h" +#include "gpio.h" +/* + * Battery info for all Brya battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* POW-TECH GQA05 Battery Information */ + [BATTERY_POWER_TECH] = { + /* BQ40Z50 Fuel Gauge */ + .fuel_gauge = { + .manuf_name = "POW-TECH", + .device_name = "BATGQA05L22", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .mfgacc_support = 1, + .reg_addr = 0x00, + .reg_mask = 0x2000, /* XDSG */ + .disconnect_val = 0x2000, + } + }, + .batt_info = { + .voltage_max = TARGET_WITH_MARGIN(13050, 5), + .voltage_normal = 11400, /* mV */ + .voltage_min = 9000, /* mV */ + .precharge_current = 280, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 45, + .discharging_min_c = -10, + .discharging_max_c = 60, + }, + }, + /* LGC L17L3PB0 Battery Information */ + /* + * Battery info provided by ODM on b/143477210, comment #11 + */ + [BATTERY_LGC011] = { + .fuel_gauge = { + .manuf_name = "LGC", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x6000, + .disconnect_val = 0x6000, + } + }, + .batt_info = { + .voltage_max = TARGET_WITH_MARGIN(13200, 5), + .voltage_normal = 11550, /* mV */ + .voltage_min = 9000, /* mV */ + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = 0, + .discharging_max_c = 75, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_POWER_TECH; + +enum battery_present battery_hw_present(void) +{ + enum gpio_signal batt_pres; + + if (get_board_id() == 1) + batt_pres = GPIO_ID_1_EC_BATT_PRES_ODL; + else + batt_pres = GPIO_EC_BATT_PRES_ODL; + + /* The GPIO is low when the battery is physically present */ + return gpio_get_level(batt_pres) ? BP_NO : BP_YES; +} diff --git a/board/volmar/board.c b/board/volmar/board.c new file mode 100644 index 0000000000..4ca53ffa48 --- /dev/null +++ b/board/volmar/board.c @@ -0,0 +1,108 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery.h" +#include "button.h" +#include "charge_ramp.h" +#include "charger.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "gpio.h" +#include "gpio_signal.h" +#include "hooks.h" +#include "driver/accel_lis2dw12.h" +#include "driver/accelgyro_lsm6dso.h" +#include "driver/als_tcs3400.h" +#include "fw_config.h" +#include "hooks.h" +#include "lid_switch.h" +#include "power_button.h" +#include "power.h" +#include "registers.h" +#include "switch.h" +#include "tablet_mode.h" +#include "throttle_ap.h" +#include "usbc_config.h" + +#include "gpio_list.h" /* Must come after other header files. */ + +/* Console output macros */ +#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) +{ + /* Allow keyboard backlight to be enabled */ + + if (get_board_id() == 1) + gpio_set_level(GPIO_ID_1_EC_KB_BL_EN, 1); + else + gpio_set_level(GPIO_EC_KB_BL_EN_L, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); + +/* Called on AP S0 -> S3 transition */ +static void board_chipset_suspend(void) +{ + /* Turn off the keyboard backlight if it's on. */ + + if (get_board_id() == 1) + gpio_set_level(GPIO_ID_1_EC_KB_BL_EN, 0); + else + gpio_set_level(GPIO_EC_KB_BL_EN_L, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); + +/* + * Explicitly apply the board ID 1 *gpio.inc settings to pins that + * were reassigned on current boards. + */ + +static void set_board_id_1_gpios(void) +{ + if (get_board_id() != 1) + return; + + gpio_set_flags(GPIO_ID_1_EC_KB_BL_EN, GPIO_OUT_LOW); +} +DECLARE_HOOK(HOOK_INIT, set_board_id_1_gpios, HOOK_PRIO_FIRST); + +/* + * Reclaim GPIO pins on board ID 1 that are used as ADC inputs on + * current boards. ALT function group MODULE_ADC pins are set in + * HOOK_PRIO_INIT_ADC and can be reclaimed right after the hook runs. + */ + +static void board_id_1_reclaim_adc(void) +{ + if (get_board_id() != 1) + return; + + /* + * GPIO_ID_1_USB_C0_C2_TCPC_RST_ODL is on GPIO34 + * + * The TCPC has already been reset by board_tcpc_init() executed + * from HOOK_PRIO_INIT_CHIPSET. Later, the pin gets set to ADC6 + * in HOOK_PRIO_INIT_ADC, so we simply need to set the pin back + * to GPIO34. + */ + gpio_set_flags(GPIO_ID_1_USB_C0_C2_TCPC_RST_ODL, GPIO_ODR_HIGH); + gpio_set_alternate_function(GPIO_PORT_3, BIT(4), GPIO_ALT_FUNC_NONE); + + /* + * The pin gets set to ADC7 in HOOK_PRIO_INIT_ADC, so we simply + * need to set it back to GPIOE1. + */ + gpio_set_flags(GPIO_ID_1_EC_BATT_PRES_ODL, GPIO_INPUT); + gpio_set_alternate_function(GPIO_PORT_E, BIT(1), GPIO_ALT_FUNC_NONE); +} +DECLARE_HOOK(HOOK_INIT, board_id_1_reclaim_adc, HOOK_PRIO_INIT_ADC + 1); diff --git a/board/volmar/board.h b/board/volmar/board.h new file mode 100644 index 0000000000..b9217e32d9 --- /dev/null +++ b/board/volmar/board.h @@ -0,0 +1,286 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Brya board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#include "compile_time_macros.h" + +/* + * Early brya boards are not set up for vivaldi + */ +#undef CONFIG_KEYBOARD_VIVALDI + +/* Baseboard features */ +#include "baseboard.h" + +/* + * This will happen automatically on NPCX9 ES2 and later. Do not remove + * until we can confirm all earlier chips are out of service. + */ +#define CONFIG_HIBERNATE_PSL_VCC1_RST_WAKEUP + +#define CONFIG_MP2964 + +/* LED */ +#define CONFIG_LED_PWM +#define CONFIG_LED_PWM_COUNT 2 +#undef CONFIG_LED_PWM_NEAR_FULL_COLOR +#undef CONFIG_LED_PWM_SOC_ON_COLOR +#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR +#undef CONFIG_LED_PWM_LOW_BATT_COLOR +#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_WHITE +#define CONFIG_LED_PWM_LOW_BATT_COLOR EC_LED_COLOR_AMBER + +/* Sensors */ +#define CONFIG_ACCELGYRO_LSM6DSO /* Base accel */ +#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. */ +#define CONFIG_ACCEL_FIFO_SIZE 256 +/* Depends on how fast the AP boots and typical ODRs */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) + +/* Sensors without hardware FIFO are in forced mode */ +#define CONFIG_ACCEL_FORCE_MODE_MASK \ + (BIT(LID_ACCEL) | BIT(CLEAR_ALS)) + +/* Lid accel */ +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL +#define CONFIG_ACCEL_LIS2DWL +#define CONFIG_ACCEL_LIS2DW_AS_BASE +#define CONFIG_ACCEL_LIS2DW12_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(LID_ACCEL) + +#define CONFIG_ACCEL_INTERRUPTS + +/* Sensor console commands */ +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO + +/* USB Type A Features */ +#define USB_PORT_COUNT 1 +#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 4 + +#define CONFIG_USB_PD_TCPM_PS8815 +#define CONFIG_USB_PD_TCPM_PS8815_FORCE_DID +#define CONFIG_USBC_RETIMER_INTEL_BB + +/* I2C speed console command */ +#define CONFIG_CMD_I2C_SPEED + +/* I2C control host command */ +#define CONFIG_HOSTCMD_I2C_CONTROL + +#define CONFIG_USBC_PPC_SYV682X +#define CONFIG_USBC_PPC_NX20P3483 + +/* 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 */ + +/* + * Passive USB-C cables only support up to 60W. + */ +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW 60000 +#define PD_MAX_CURRENT_MA 3000 +#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_ENABLE_BACKLIGHT GPIO_EC_EN_EDP_BL +#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW +#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV +#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 GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L + +/* + * 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_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL +#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL +#define GPIO_WP_L GPIO_EC_WP_ODL + +#define GPIO_ID_1_EC_KB_BL_EN GPIO_EC_BATT_PRES_ODL + +/* System has back-lit keyboard */ +#define CONFIG_PWM_KBLIGHT + +/* I2C Bus Configuration */ + +#define I2C_PORT_SENSOR 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_BATTERY NPCX_I2C_PORT5_0 +#define I2C_PORT_CHARGER NPCX_I2C_PORT7_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 + +/* + * see b/174768555#comment22 + */ +#define USBC_PORT_C0_BB_RETIMER_I2C_ADDR 0x56 +#define USBC_PORT_C2_BB_RETIMER_I2C_ADDR 0x57 + +/* Enabling Thunderbolt-compatible mode */ +#define CONFIG_USB_PD_TBT_COMPAT_MODE + +/* Enabling USB4 mode */ +#define CONFIG_USB_PD_USB4 + +/* Retimer */ +#define CONFIG_USBC_RETIMER_FW_UPDATE + +/* Thermal features */ +#define CONFIG_THERMISTOR +#define CONFIG_TEMP_SENSOR +#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_SEQ_EC_DSW_PWROK +#define CONFIG_STEINHART_HART_3V3_30K9_47K_4050B + +#define CONFIG_FANS FAN_CH_COUNT + +/* Charger defines */ +#define CONFIG_CHARGER_BQ25720 +#define CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM +#define CONFIG_CHARGER_BQ25720_VSYS_TH2_DV 70 +#define CONFIG_CHARGE_RAMP_SW +#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_BQ25710_SENSE_RESISTOR_AC 10 +#define CONFIG_CHARGER_BQ25710_PSYS_SENSING + +/* + * Older boards have a different ADC assignment. + */ + +#define CONFIG_ADC_CHANNELS_RUNTIME_CONFIG + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" /* needed by registers.h */ +#include "registers.h" +#include "usbc_config.h" + +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 +}; + +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 ioex_port { + IOEX_C0_NCT38XX = 0, + IOEX_C2_NCT38XX, + IOEX_ID_1_C0_NCT38XX, + IOEX_ID_1_C2_NCT38XX, + IOEX_PORT_COUNT +}; + +enum battery_type { + BATTERY_POWER_TECH, + BATTERY_LGC011, + 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 +}; + +enum fan_channel { + FAN_CH_0 = 0, + FAN_CH_COUNT +}; + +enum mft_channel { + MFT_CH_0 = 0, + MFT_CH_COUNT +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/volmar/build.mk b/board/volmar/build.mk new file mode 100644 index 0000000000..e69587a781 --- /dev/null +++ b/board/volmar/build.mk @@ -0,0 +1,26 @@ +# -*- makefile -*- +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Brya board specific files build +# + +CHIP:=npcx +CHIP_FAMILY:=npcx9 +CHIP_VARIANT:=npcx9m3f +BASEBOARD:=brya + +board-y= +board-y+=battery.o +board-y+=board.o +board-y+=charger.o +board-y+=fans.o +board-y+=fw_config.o +board-y+=i2c.o +board-y+=keyboard.o +board-y+=led.o +board-y+=pwm.o +board-y+=sensors.o +board-y+=tune_mp2964.o +board-y+=usbc_config.o diff --git a/board/volmar/charger.c b/board/volmar/charger.c new file mode 100644 index 0000000000..e6a5c446d7 --- /dev/null +++ b/board/volmar/charger.c @@ -0,0 +1,90 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" + +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "compile_time_macros.h" +#include "console.h" +#include "driver/charger/bq25710.h" +#include "usbc_ppc.h" +#include "usb_pd.h" +#include "util.h" + + +#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +/* Charger Chip Configuration */ +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = BQ25710_SMBUS_ADDR1_FLAGS, + .drv = &bq25710_drv, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(chg_chips) == CHARGER_NUM); + +int board_set_active_charge_port(int port) +{ + int is_valid_port = board_is_usb_pd_port_present(port); + int i; + + if (port == CHARGE_PORT_NONE) { + CPRINTSUSB("Disabling all charger ports"); + + /* Disable all ports. */ + for (i = 0; i < ppc_cnt; i++) { + /* + * Do not return early if one fails otherwise we can + * get into a boot loop assertion failure. + */ + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("Disabling C%d as sink failed.", i); + } + + return EC_SUCCESS; + } else if (!is_valid_port) { + return EC_ERROR_INVAL; + } + + /* Check if the port is sourcing VBUS. */ + if (ppc_is_sourcing_vbus(port)) { + CPRINTFUSB("Skip enable C%d", port); + return EC_ERROR_INVAL; + } + + CPRINTSUSB("New charge port: C%d", port); + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < ppc_cnt; i++) { + if (i == port) + continue; + + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("C%d: sink path disable failed.", i); + } + + /* Enable requested charge port. */ + if (ppc_vbus_sink_enable(port, 1)) { + CPRINTSUSB("C%d: sink path enable failed.", port); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +__overridable void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} diff --git a/board/volmar/ec.tasklist b/board/volmar/ec.tasklist new file mode 100644 index 0000000000..a049ba3bfa --- /dev/null +++ b/board/volmar/ec.tasklist @@ -0,0 +1,32 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * 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, 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) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, BASEBOARD_CHIPSET_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, CONSOLE_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, BASEBOARD_POWERBTN_TASK_STACK_SIZE) \ + 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/volmar/fans.c b/board/volmar/fans.c new file mode 100644 index 0000000000..27f5bca929 --- /dev/null +++ b/board/volmar/fans.c @@ -0,0 +1,89 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Physical fans. These are logically separate from pwm_channels. */ + +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "fan_chip.h" +#include "fan.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_1, + .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/181271666): thermistor placement and calibration + * + * Prototype fan spins at about 4200 RPM at 100% PWM, this + * is specific to board ID 2 and might also apears in later + * boards as well. + */ +static const struct fan_rpm fan_rpm_0 = { + .rpm_min = 2200, + .rpm_start = 2200, + .rpm_max = 4200, +}; + +const struct fan_t fans[FAN_CH_COUNT] = { + [FAN_CH_0] = { + .conf = &fan_conf_0, + .rpm = &fan_rpm_0, + }, +}; + +#ifndef CONFIG_FANS + +/* + * TODO(b/181271666): use static fan speeds until fan and sensors are + * tuned. for now, use: + * + * AP off: 33% + * AP on: 100% + */ + +static void fan_slow(void) +{ + const int duty_pct = 33; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +static void fan_max(void) +{ + const int duty_pct = 100; + + ccprints("%s: speed %d%%", __func__, duty_pct); + + pwm_enable(PWM_CH_FAN, 1); + pwm_set_duty(PWM_CH_FAN, duty_pct); +} + +DECLARE_HOOK(HOOK_INIT, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, fan_slow, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESET, fan_max, HOOK_PRIO_FIRST); +DECLARE_HOOK(HOOK_CHIPSET_RESUME, fan_max, HOOK_PRIO_DEFAULT); + +#endif /* CONFIG_FANS */ diff --git a/board/volmar/fw_config.c b/board/volmar/fw_config.c new file mode 100644 index 0000000000..544f276d25 --- /dev/null +++ b/board/volmar/fw_config.c @@ -0,0 +1,61 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "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_CHIPSET, format, ## args) + +static union brya_cbi_fw_config fw_config; +BUILD_ASSERT(sizeof(fw_config) == sizeof(uint32_t)); + +/* + * FW_CONFIG defaults for brya if the CBI.FW_CONFIG data is not + * initialized. + */ +static const union brya_cbi_fw_config fw_config_defaults = { + .usb_db = DB_USB3_PS8815, + .kb_bl = KEYBOARD_BACKLIGHT_ENABLED, +}; + +/**************************************************************************** + * Brya 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; + } + + if (get_board_id() == 0) { + /* + * Early boards have a zero'd out FW_CONFIG, so replace + * it with a sensible default value. If DB_USB_ABSENT2 + * was used as an alternate encoding of DB_USB_ABSENT to + * avoid the zero check, then fix it. + */ + if (fw_config.raw_value == 0) { + CPRINTS("CBI: FW_CONFIG is zero, using board defaults"); + fw_config = fw_config_defaults; + } else if (fw_config.usb_db == DB_USB_ABSENT2) { + fw_config.usb_db = DB_USB_ABSENT; + } + } +} + +union brya_cbi_fw_config get_fw_config(void) +{ + return fw_config; +} + +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void) +{ + return fw_config.usb_db; +} diff --git a/board/volmar/fw_config.h b/board/volmar/fw_config.h new file mode 100644 index 0000000000..ed4dbce7d9 --- /dev/null +++ b/board/volmar/fw_config.h @@ -0,0 +1,54 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __BOARD_BRYA_FW_CONFIG_H_ +#define __BOARD_BRYA_FW_CONFIG_H_ + +#include <stdint.h> + +/**************************************************************************** + * CBI FW_CONFIG layout for Brya board. + * + * Source of truth is the project/brya/brya/config.star configuration file. + */ + +enum ec_cfg_usb_db_type { + DB_USB_ABSENT = 0, + DB_USB3_PS8815 = 1, + DB_USB_ABSENT2 = 15 +}; + +enum ec_cfg_keyboard_backlight_type { + KEYBOARD_BACKLIGHT_DISABLED = 0, + KEYBOARD_BACKLIGHT_ENABLED = 1 +}; + +union brya_cbi_fw_config { + struct { + enum ec_cfg_usb_db_type usb_db : 4; + uint32_t sd_db : 2; + uint32_t lte_db : 1; + enum ec_cfg_keyboard_backlight_type kb_bl : 1; + uint32_t audio : 3; + uint32_t reserved_1 : 21; + }; + uint32_t raw_value; +}; + +/** + * Read the cached FW_CONFIG. Guaranteed to have valid values. + * + * @return the FW_CONFIG for the board. + */ +union brya_cbi_fw_config get_fw_config(void); + +/** + * Get the USB daughter board type from FW_CONFIG. + * + * @return the USB daughter board type. + */ +enum ec_cfg_usb_db_type ec_cfg_usb_db_type(void); + +#endif /* __BOARD_BRYA_FW_CONFIG_H_ */ diff --git a/board/volmar/generated-gpio.inc b/board/volmar/generated-gpio.inc new file mode 100644 index 0000000000..f4772188a5 --- /dev/null +++ b/board/volmar/generated-gpio.inc @@ -0,0 +1,125 @@ +/* + * This file was auto-generated. + */ + +/* 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) +GPIO_INT(EC_VOLUP_BTN_ODL, PIN(9, 7), GPIO_INT_BOTH | GPIO_PULL_UP, button_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 | GPIO_HIB_WAKE_LOW, power_button_interrupt) +GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_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(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_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) +GPIO(CHARGER_VAP_OTG_EN, PIN(7, 3), GPIO_OUT_LOW) +GPIO(CPU_C10_GATE_L, PIN(6, 7), GPIO_INPUT) +GPIO(EC_BATT_PRES_ODL, PIN(A, 3), GPIO_INPUT) +GPIO(EC_ENTERING_RW, PIN(0, 3), GPIO_OUT_LOW) +GPIO(EC_EN_EDP_BL, PIN(D, 3), GPIO_OUT_HIGH) +GPIO(EC_GSC_PACKET_MODE, PIN(7, 5), GPIO_OUT_LOW) +GPIO(EC_I2C_BAT_SCL, PIN(3, 3), GPIO_INPUT) +GPIO(EC_I2C_BAT_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_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_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) +GPIO(EC_KB_BL_EN_L, PIN(8, 6), GPIO_OUT_HIGH) +GPIO(EC_PCHHOT_ODL, PIN(7, 4), GPIO_INPUT) +GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH) +GPIO(EC_PCH_PWR_BTN_ODL, PIN(C, 1), 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_R_ODL, PIN(C, 0), GPIO_ODR_HIGH) +GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH) +GPIO(EN_PP5000_FAN, PIN(6, 1), GPIO_OUT_HIGH) +GPIO(EN_PP5000_USBA_R, PIN(D, 7), GPIO_OUT_LOW) +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_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) + +/* 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, GPIO_SEL_1P8V) /* 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(4, 0x01), 0, MODULE_PWM, 0) /* GPIO40/TA1 */ +ALTERNATE(PIN_MASK(6, 0x01), 0, MODULE_PWM, 0) /* GPIO60/PWM7 */ +ALTERNATE(PIN_MASK(8, 0x01), 0, MODULE_PWM, 0) /* GPIO80/PWM3 */ +ALTERNATE(PIN_MASK(B, 0x80), 0, MODULE_PWM, 0) /* GPIOB7/PWM5 */ +ALTERNATE(PIN_MASK(C, 0x1c), 0, MODULE_PWM, 0) /* GPIOC4/PWM2, GPIOC3/PWM0, GPIOC2/PWM1/I2C6_SCL0 */ + +/* ADC alternate functions */ +ALTERNATE(PIN_MASK(3, 0x10), 0, MODULE_ADC, 0) /* GPIO34/PS2_DAT2/ADC6 */ +ALTERNATE(PIN_MASK(4, 0x34), 0, MODULE_ADC, 0) /* GPIO42/ADC3/RI_L, GPIO45/ADC0, GPIO44/ADC1 */ +ALTERNATE(PIN_MASK(E, 0x02), 0, MODULE_ADC, 0) /* GPIOE1/ADC7 */ + +/* KB alternate functions */ +ALTERNATE(PIN_MASK(0, 0xf0), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO10&P80_CLK/GPIO07, KSO11&P80_DAT/GPIO06, KSO12/GPIO05, KSO13/GPIO04 */ +ALTERNATE(PIN_MASK(1, 0x7f), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO06/GPO13/GP_SEL_L, KSO07/GPO12/JEN_L, KSO03/GPIO16/JTAG_TDO0_SWO, KSO04/GPIO15/XNOR, KSO05/GPIO14, KSO08/GPIO11/CR_SOUT1, KSO09/GPIO10/CR_SIN1 */ +ALTERNATE(PIN_MASK(2, 0xfc), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI2/GPIO27/TRACEDATA1, KSI3/GPIO26/TRACEDATA0, KSI4/GPIO25/TRACECLK/GP_SCLK, KSI5/GPIO24/GP_MISO, KSI6/GPIO23/S_SBUB, KSI7/GPIO22/S_SBUA */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO00/GPIO21/JTAG_TCK_SWCLK, KSO01/GPIO20/JTAG_TMS_SWIO */ +ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KB, GPIO_INPUT | GPIO_PULL_UP) /* KSI0/GPIO31/TRACEDATA3/GP_MOSI, KSI1/GPIO30/TRACEDATA2/GP_CS_L */ +ALTERNATE(PIN_MASK(8, 0x04), 0, MODULE_KB, GPIO_ODR_HIGH) /* KSO14/GPIO82 */ + +/* PMU alternate functions */ +ALTERNATE(PIN_MASK(0, 0x01), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN2_L&GPI00/GPIO00 */ +ALTERNATE(PIN_MASK(0, 0x02), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_LOW) /* GPIO01/PSL_IN3_L&GPI01 */ +ALTERNATE(PIN_MASK(D, 0x04), 0, MODULE_PMU, GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH) /* PSL_IN1_L&GPID2/GPIOD2 */ + +/* 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(5, 7)) /* GPIO57/SER_IRQ/ESPI_ALERT_L */ + +/* Pre-configured PSL balls: J8 K6 */ diff --git a/board/volmar/gpio.inc b/board/volmar/gpio.inc new file mode 100644 index 0000000000..c338e6b5ec --- /dev/null +++ b/board/volmar/gpio.inc @@ -0,0 +1,74 @@ +/* -*- mode:c -*- + * + * Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define MODULE_KB MODULE_KEYBOARD_SCAN + +/* + * Generated-gpio.inc is produced using a Brya specific tool that + * parses the GPIO definitions derived from the board schematics and + * EC pinout descriptions derived form the chip datasheets to generate + * the Chrome EC GPIO pinout definitions. Due to the confidential + * nature of schematics and datasheets, they are not provided here. + * + * Variants that do not auto-generate their GPIO definitions should + * combine the Brya gpio.inc and generated-gpio.inc into their + * gpio.inc and customize as appropriate. + */ + +#include "generated-gpio.inc" + +/* + * The NPCX keyboard driver does not use named GPIOs to access + * keyboard scan pins, so we do not list them in *gpio.inc. However, when + * KEYBOARD_COL2_INVERTED is defined, this name is required. + */ +GPIO(EC_KSO_02_INV, PIN(1, 7), GPIO_OUT_LOW) + +/* + * GPIOE1 is an ALT function ADC INPUT on board ID 2 and a GPIO INPUT on + * board ID 1. This declaration gives us a signal name to use on board + * ID 1. + */ +GPIO(ID_1_EC_BATT_PRES_ODL, PIN(E, 1), GPIO_INPUT) + +/* + * GPIO34 is an INPUT on board ID 2 and ODR_LOW on board ID 1. + * + * Since this pin is pulled up to 3.3V through a 30.9K ohm resistor on + * board ID 2, we will leak about 0.3mW until the pin is put in ALT mode + * when MODULE_ADC configuration runs. Initializing the pin to ODR_LOW + * gives us full control on both boards. + */ +GPIO(ID_1_USB_C0_C2_TCPC_RST_ODL, PIN(3, 4), GPIO_ODR_LOW) + +/* Board ID 1 IO expander configuration */ + +IOEX(ID_1_USB_C0_RT_RST_ODL, EXPIN(IOEX_ID_1_C0_NCT38XX, 0, 2), GPIO_ODR_LOW) +/* GPIO03_P1 to PU */ +IOEX(ID_1_USB_C0_FRS_EN, EXPIN(IOEX_ID_1_C0_NCT38XX, 0, 4), GPIO_LOW) +IOEX(ID_1_USB_C0_OC_ODL, EXPIN(IOEX_ID_1_C0_NCT38XX, 0, 6), GPIO_ODR_HIGH) +/* GPIO07_P1 to PU */ + +IOEX(ID_1_USB_C2_RT_RST_ODL, EXPIN(IOEX_ID_1_C2_NCT38XX, 0, 2), GPIO_ODR_LOW) +/* GPIO03_P2 to PU */ +IOEX(ID_1_USB_C2_FRS_EN, EXPIN(IOEX_ID_1_C2_NCT38XX, 0, 4), GPIO_LOW) +IOEX(ID_1_USB_C1_OC_ODL, EXPIN(IOEX_ID_1_C2_NCT38XX, 0, 6), GPIO_ODR_HIGH) +IOEX(ID_1_USB_C2_OC_ODL, EXPIN(IOEX_ID_1_C2_NCT38XX, 0, 7), GPIO_ODR_HIGH) + +/* Board ID 2 IO expander configuration */ + +/* 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 */ diff --git a/board/volmar/i2c.c b/board/volmar/i2c.c new file mode 100644 index 0000000000..b63cfa645f --- /dev/null +++ b/board/volmar/i2c.c @@ -0,0 +1,98 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "compile_time_macros.h" +#include "hooks.h" +#include "i2c.h" + +#define BOARD_ID_FAST_PLUS_CAPABLE 2 + +/* I2C port map configuration */ +const struct i2c_port_t i2c_ports[] = { + { + /* I2C0 */ + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_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_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, + }, + { + /* I2C4 C1 TCPC */ + .name = "tcpc1", + .port = I2C_PORT_USB_C1_TCPC, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_TCPC_SCL, + .sda = GPIO_EC_I2C_USB_C1_TCPC_SDA, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + }, + { + /* I2C5 */ + .name = "battery", + .port = I2C_PORT_BATTERY, + .kbps = 100, + .scl = GPIO_EC_I2C_BAT_SCL, + .sda = GPIO_EC_I2C_BAT_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, + .flags = I2C_PORT_FLAG_DYNAMIC_SPEED, + }, + { + /* 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); + +/* + * I2C controllers are initialized in main.c. This sets the speed much + * later, but before I2C peripherals are initialized. + */ +static void set_board_legacy_i2c_speeds(void) +{ + if (get_board_id() >= BOARD_ID_FAST_PLUS_CAPABLE) + return; + + ccprints("setting USB DB I2C buses to 400 kHz\n"); + + i2c_set_freq(I2C_PORT_USB_C1_TCPC, I2C_FREQ_400KHZ); + i2c_set_freq(I2C_PORT_USB_C1_PPC, I2C_FREQ_400KHZ); +} +DECLARE_HOOK(HOOK_INIT, set_board_legacy_i2c_speeds, HOOK_PRIO_INIT_I2C - 1); diff --git a/board/volmar/keyboard.c b/board/volmar/keyboard.c new file mode 100644 index 0000000000..133d574dfa --- /dev/null +++ b/board/volmar/keyboard.c @@ -0,0 +1,25 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.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 = { + 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ + }, +}; diff --git a/board/volmar/led.c b/board/volmar/led.c new file mode 100644 index 0000000000..be2b832237 --- /dev/null +++ b/board/volmar/led.c @@ -0,0 +1,93 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Brya specific PWM LED settings: there are 2 LEDs on each side of the board, + * each one can be controlled separately. The LED colors are white or amber, + * and the default behavior is tied to the charging process: both sides are + * amber while charging the battery and white when the battery is charged. + */ + +#include <stdint.h> + +#include "common.h" +#include "compile_time_macros.h" +#include "ec_commands.h" +#include "led_pwm.h" +#include "pwm.h" +#include "util.h" + +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); + +/* + * We only have a white and an amber LED, so setting any other color results in + * both LEDs being off. Cap at 50% to save power. + */ +struct pwm_led_color_map led_color_map[EC_LED_COLOR_COUNT] = { + /* Amber, White */ + [EC_LED_COLOR_RED] = { 0, 0 }, + [EC_LED_COLOR_GREEN] = { 0, 0 }, + [EC_LED_COLOR_BLUE] = { 0, 0 }, + [EC_LED_COLOR_YELLOW] = { 0, 0 }, + [EC_LED_COLOR_WHITE] = { 0, 50 }, + [EC_LED_COLOR_AMBER] = { 50, 0 }, +}; + +/* Two logical LEDs with amber and white channels. */ +struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { + { + .ch0 = PWM_CH_LED1, + .ch1 = PWM_CH_LED2, + .ch2 = PWM_LED_NO_CHANNEL, + .enable = &pwm_enable, + .set_duty = &pwm_set_duty, + }, + { + .ch0 = PWM_CH_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) +{ + memset(brightness_range, '\0', + sizeof(*brightness_range) * EC_LED_COLOR_COUNT); + brightness_range[EC_LED_COLOR_AMBER] = 100; + brightness_range[EC_LED_COLOR_WHITE] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + enum pwm_led_id pwm_id; + + /* Convert ec_led_id to pwm_led_id. */ + switch (led_id) { + case EC_LED_ID_LEFT_LED: + pwm_id = PWM_LED0; + break; + case EC_LED_ID_RIGHT_LED: + pwm_id = PWM_LED1; + break; + default: + return EC_ERROR_UNKNOWN; + } + + if (brightness[EC_LED_COLOR_WHITE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); + else + /* Otherwise, the "color" is "off". */ + set_pwm_led_color(pwm_id, -1); + + return EC_SUCCESS; +} diff --git a/board/volmar/pwm.c b/board/volmar/pwm.c new file mode 100644 index 0000000000..de19f15cd5 --- /dev/null +++ b/board/volmar/pwm.c @@ -0,0 +1,71 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#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_LED2] = { + .channel = 0, + .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, + .freq = 4800, + }, + [PWM_CH_KBLIGHT] = { + .channel = 3, + .flags = 0, + /* + * Set PWM frequency to multiple of 50 Hz and 60 Hz to prevent + * flicker. Higher frequencies consume similar average power to + * lower PWM frequencies, but higher frequencies record a much + * lower maximum power. + */ + .freq = 2400, + }, + [PWM_CH_FAN] = { + .channel = 5, + .flags = PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_DSLEEP, + .freq = 1000 + }, + [PWM_CH_LED4] = { + .channel = 7, + .flags = PWM_CONFIG_ACTIVE_LOW | PWM_CONFIG_DSLEEP, + .freq = 4800, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +static void board_pwm_init(void) +{ + /* + * Turn off all the LEDs. + * Turn on the fan at 100%. + */ + pwm_enable(PWM_CH_LED1, 1); + 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); +} +DECLARE_HOOK(HOOK_INIT, board_pwm_init, HOOK_PRIO_DEFAULT); diff --git a/board/volmar/sensors.c b/board/volmar/sensors.c new file mode 100644 index 0000000000..b355c98123 --- /dev/null +++ b/board/volmar/sensors.c @@ -0,0 +1,412 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "accelgyro.h" +#include "adc.h" +#include "driver/accel_lis2dw12.h" +#include "driver/accelgyro_lsm6dso.h" +#include "driver/als_tcs3400_public.h" +#include "hooks.h" +#include "motion_sense.h" +#include "temp_sensor.h" +#include "thermal.h" +#include "temp_sensor/thermistor.h" + +/* ADC configuration */ +struct adc_t adc_channels[] = { + [ADC_TEMP_SENSOR_1_DDR_SOC] = { + .name = "TEMP_DDR_SOC", + .input_ch = NPCX_ADC_CH0, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_2_AMBIENT] = { + .name = "TEMP_AMBIENT", + .input_ch = NPCX_ADC_CH1, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [ADC_TEMP_SENSOR_3_CHARGER] = { + .name = "TEMP_CHARGER", + .input_ch = NPCX_ADC_CH6, + .factor_mul = ADC_MAX_VOLT, + .factor_div = ADC_READ_MAX + 1, + .shift = 0, + }, + [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); + +K_MUTEX_DEFINE(g_lid_accel_mutex); +K_MUTEX_DEFINE(g_base_accel_mutex); +static struct stprivate_data g_lis2dw12_data; +static struct lsm6dso_data lsm6dso_data; + +/* TODO(b/184779333): calibrate the orientation matrix on later board stage */ +static const mat33_fp_t lid_standard_ref = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; + +/* TODO(b/184779743): verify orientation matrix */ +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", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LIS2DW12, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &lis2dw12_drv, + .mutex = &g_lid_accel_mutex, + .drv_data = &g_lis2dw12_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LIS2DW12_ADDR0, + .rot_standard_ref = &lid_standard_ref, /* identity matrix */ + .default_range = 2, /* g */ + .min_frequency = LIS2DW12_ODR_MIN_VAL, + .max_frequency = LIS2DW12_ODR_MAX_VAL, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* Sensor on for lid angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSO, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dso_drv, + .mutex = &g_base_accel_mutex, + .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, + MOTIONSENSE_TYPE_ACCEL), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .default_range = 4, /* g */ + .min_frequency = LSM6DSO_ODR_MIN_VAL, + .max_frequency = LSM6DSO_ODR_MAX_VAL, + .config = { + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_LSM6DSO, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &lsm6dso_drv, + .mutex = &g_base_accel_mutex, + .drv_data = LSM6DSO_ST_DATA(lsm6dso_data, + MOTIONSENSE_TYPE_GYRO), + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = LSM6DSO_ADDR0_FLAGS, + .default_range = 1000 | ROUND_UP_FLAG, /* dps */ + .rot_standard_ref = &base_standard_ref, + .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); +} +DECLARE_HOOK(HOOK_INIT, baseboard_sensors_init, HOOK_PRIO_INIT_I2C + 1); + +/* Temperature sensor configuration */ +const struct temp_sensor_t temp_sensors[] = { + [TEMP_SENSOR_1_DDR_SOC] = { + .name = "DDR and SOC", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_1_DDR_SOC, + }, + [TEMP_SENSOR_2_AMBIENT] = { + .name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_30k9_47k_4050b, + .idx = ADC_TEMP_SENSOR_2_AMBIENT, + }, + [TEMP_SENSOR_3_CHARGER] = { + .name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .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); + +/* + * TODO(b/180681346): update for Alder Lake/brya + * + * Alder 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(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(90), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_cpu = THERMAL_CPU; + +/* + * TODO(b/180681346): update for Alder Lake/brya + * + * Inductor limits - used for both charger and PP3300 regulator + * + * Need to use the lower of the charger IC, PP3300 regulator, and the inductors + * + * Charger max recommended temperature 100C, max absolute temperature 125C + * PP3300 regulator: operating range -40 C to 145 C + * + * Inductors: limit of 125c + * PCB: limit is 80c + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_AMBIENT \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(85), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(90), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(80), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(60), \ + } +__maybe_unused static const struct ec_thermal_config thermal_ambient = + THERMAL_AMBIENT; + +/* + * Inductor limits - used for both charger and PP3300 regulator + * + * Need to use the lower of the charger IC, PP3300 regulator, and the inductors + * + * Charger max recommended temperature 125C, max absolute temperature 150C + * PP3300 regulator: operating range -40 C to 125 C + * + * Inductors: limit of 125c + * PCB: limit is 80c + */ +/* + * TODO(b/202062363): Remove when clang is fixed. + */ +#define THERMAL_CHARGER \ + { \ + .temp_host = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(105), \ + [EC_TEMP_THRESH_HALT] = C_TO_K(120), \ + }, \ + .temp_host_release = { \ + [EC_TEMP_THRESH_HIGH] = C_TO_K(90), \ + }, \ + .temp_fan_off = C_TO_K(35), \ + .temp_fan_max = C_TO_K(65), \ + } +__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); + +static void board_thermals_init(void) +{ + if (get_board_id() == 1) { + /* + * Board ID 1 only has 3 sensors and the AMBIENT sensor + * ADC pins have been reassigned, so we're down to 2 + * sensors that can easily be configured. So, alias the + * AMBIENT sensor ADC channel to the unimplemented ADC + * slots. + */ + adc_channels[ADC_TEMP_SENSOR_3_CHARGER].input_ch = NPCX_ADC_CH1; + adc_channels[ADC_TEMP_SENSOR_4_WWAN].input_ch = NPCX_ADC_CH1; + } +} + +DECLARE_HOOK(HOOK_INIT, board_thermals_init, HOOK_PRIO_INIT_CHIPSET); diff --git a/board/kano/tune_mp2964.c b/board/volmar/tune_mp2964.c index 198f06d8eb..f67caa587e 100644 --- a/board/kano/tune_mp2964.c +++ b/board/volmar/tune_mp2964.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2022 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/board/volmar/usbc_config.c b/board/volmar/usbc_config.c new file mode 100644 index 0000000000..e1d899f7fc --- /dev/null +++ b/board/volmar/usbc_config.c @@ -0,0 +1,506 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdint.h> +#include <stdbool.h> + +#include "cbi.h" +#include "charger.h" +#include "charge_ramp.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" +#include "ioexpander.h" +#include "system.h" +#include "task.h" +#include "task_id.h" +#include "timer.h" +#include "usbc_config.h" +#include "usbc_ppc.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.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 = PS8751_I2C_ADDR1_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_TCPCI_REV2_0_NO_VSAFE0V | + TCPC_FLAGS_CONTROL_VCONN, + }, + [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); + +/******************************************************************************/ +/* USB-A charging control */ + +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_PP5000_USBA_R, +}; +BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_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] = { + /* Compatible with Silicon Mitus SM536A0 */ + .i2c_port = I2C_PORT_USB_C1_PPC, + .i2c_addr_flags = NX20P3483_ADDR2_FLAGS, + .drv = &nx20p348x_drv, + }, + [USBC_PORT_C2] = { + .i2c_port = I2C_PORT_USB_C0_C2_PPC, + /* + * b/179987870 + * schematics I2C map says ADDR3 + */ + .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 usbc0_tcss_usb_mux = { + .usb_port = USBC_PORT_C0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; +static const struct usb_mux usbc2_tcss_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 + * and updates the TCSS configuration on state changes. + */ +static const struct usb_mux usbc1_usb3_db_retimer = { + .usb_port = USBC_PORT_C1, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, +}; + +const struct usb_mux usb_muxes[] = { + [USBC_PORT_C0] = { + .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_mux = &usbc0_tcss_usb_mux, + }, + [USBC_PORT_C1] = { + /* PS8815 DB */ + .usb_port = USBC_PORT_C1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + .next_mux = &usbc1_usb3_db_retimer, + }, + [USBC_PORT_C2] = { + .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_mux = &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, + }, + [IOEX_ID_1_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_ID_1_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); + +#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) { + if (get_board_id() == 1) + rst_signal = IOEX_ID_1_USB_C0_RT_RST_ODL; + else + rst_signal = IOEX_USB_C0_RT_RST_ODL; + } else if (me->usb_port == USBC_PORT_C2) { + if (get_board_id() == 1) + rst_signal = IOEX_ID_1_USB_C2_RT_RST_ODL; + else + 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); + if (get_board_id() == 1) { + int val; + + /* + * Check if we were able to deassert + * reset. Board ID 1 uses a GPIO that is + * uncontrollable when a debug accessory is + * connected. + */ + if (ioex_get_level(rst_signal, &val) != EC_SUCCESS) + return EC_ERROR_UNKNOWN; + if (val != 1) + return EC_ERROR_NOT_POWERED; + } + } else { + ioex_set_level(rst_signal, 0); + msleep(1); + } + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + enum gpio_signal tcpc_rst; + + if (get_board_id() == 1) + tcpc_rst = GPIO_ID_1_USB_C0_C2_TCPC_RST_ODL; + else + tcpc_rst = GPIO_USB_C0_C2_TCPC_RST_ODL; + + /* + * 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); + } + + /* + * delay for power-on to reset-off and min. assertion time + */ + + 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); + } + + /* wait for chips to come up */ + + msleep(50); +} + +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. + */ + if (get_board_id() == 1) { + ioex_init(IOEX_ID_1_C0_NCT38XX); + ioex_init(IOEX_ID_1_C2_NCT38XX); + } else { + ioex_init(IOEX_C0_NCT38XX); + ioex_init(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); + + /* Enable BC1.2 interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C2_BC12_INT_ODL); + + 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); + gpio_enable_interrupt(GPIO_USB_C1_BC12_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 ((ec_cfg_usb_db_type() != DB_USB_ABSENT) && + 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) && + (ec_cfg_usb_db_type() != DB_USB_ABSENT)) + 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: + if (ec_cfg_usb_db_type() == DB_USB_ABSENT) + break; + 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: + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12); + break; + case GPIO_USB_C1_BC12_INT_ODL: + if (ec_cfg_usb_db_type() == DB_USB_ABSENT) + break; + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12); + break; + case GPIO_USB_C2_BC12_INT_ODL: + task_set_event(TASK_ID_USB_CHG_P2, 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: + 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); + 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/volmar/usbc_config.h b/board/volmar/usbc_config.h new file mode 100644 index 0000000000..3a500af9d3 --- /dev/null +++ b/board/volmar/usbc_config.h @@ -0,0 +1,22 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* 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 +}; + +void config_usb_db_type(void); + +#endif /* __CROS_EC_USBC_CONFIG_H */ diff --git a/board/volmar/vif_override.xml b/board/volmar/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/volmar/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/volteer/ec.tasklist b/board/volteer/ec.tasklist index ec9e64e850..d94a4445b9 100644 --- a/board/volteer/ec.tasklist +++ b/board/volteer/ec.tasklist @@ -16,6 +16,7 @@ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, 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) \ diff --git a/board/volteer_ish/board.h b/board/volteer_ish/board.h index 097ee25750..527432285c 100644 --- a/board/volteer_ish/board.h +++ b/board/volteer_ish/board.h @@ -35,7 +35,7 @@ #define CONFIG_ACCEL_BMA255 /* Host command over HECI */ -#define CONFIG_HOSTCMD_HECI +#define CONFIG_HOST_INTERFACE_HECI #define CONFIG_MKBP_EVENT #define CONFIG_MKBP_USE_HECI diff --git a/board/voxel/ec.tasklist b/board/voxel/ec.tasklist index 292de51cdb..174a47eea3 100644 --- a/board/voxel/ec.tasklist +++ b/board/voxel/ec.tasklist @@ -15,7 +15,8 @@ TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ - TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_NOTEST(CHIPSET, chipset_task, NULL, ULTRA_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) \ diff --git a/board/waddledee/board.c b/board/waddledee/board.c index 1e4f8a387c..2e439de601 100644 --- a/board/waddledee/board.c +++ b/board/waddledee/board.c @@ -503,8 +503,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = NULL, @@ -532,8 +530,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/wheelie/board.c b/board/wheelie/board.c index 198dbda284..9740013ddd 100644 --- a/board/wheelie/board.c +++ b/board/wheelie/board.c @@ -394,8 +394,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = NULL, @@ -423,8 +421,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/willow/board.c b/board/willow/board.c index ba467fddc2..463550ddb2 100644 --- a/board/willow/board.c +++ b/board/willow/board.c @@ -64,13 +64,32 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); /******************************************************************************/ /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"typec", 0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, - {"other", 1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + { + .name = "typec", + .port = 0, + .kbps = 400, + .scl = GPIO_I2C1_SCL, + .sda = GPIO_I2C1_SDA + }, + { + .name = "other", + .port = 1, + .kbps = 400, + .scl = GPIO_I2C2_SCL, + .sda = GPIO_I2C2_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); const struct i2c_port_t i2c_bitbang_ports[] = { - {"battery", 2, 100, GPIO_I2C3_SCL, GPIO_I2C3_SDA, .drv = &bitbang_drv}, + { + .name = "battery", + .port = 2, + .kbps = 100, + .scl = GPIO_I2C3_SCL, + .sda = GPIO_I2C3_SDA, + .drv = &bitbang_drv + }, }; const unsigned int i2c_bitbang_ports_used = ARRAY_SIZE(i2c_bitbang_ports); @@ -136,8 +155,12 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; static void board_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * svdm_dp_attention() did most of the work, we only need to notify * host here. diff --git a/board/willow/board.h b/board/willow/board.h index a6907b9a9e..9ec0b9483b 100644 --- a/board/willow/board.h +++ b/board/willow/board.h @@ -81,7 +81,7 @@ #define IT8801_KEYBOARD_PWM_I2C_ADDR_FLAGS IT8801_I2C_ADDR1 /* Enable Accel over SPI */ -#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI master port (SPI2) */ +#define CONFIG_SPI_ACCEL_PORT 0 /* The first SPI controller port (SPI2) */ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #define CONFIG_MKBP_EVENT diff --git a/board/wormdingler/board.c b/board/wormdingler/board.c index d8bc04e4fd..e9ad3ab21c 100644 --- a/board/wormdingler/board.c +++ b/board/wormdingler/board.c @@ -119,16 +119,41 @@ static void switchcap_interrupt(enum gpio_signal signal) /* I2C port map */ const struct i2c_port_t i2c_ports[] = { - {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, - GPIO_EC_I2C_POWER_SDA}, - {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, - GPIO_EC_I2C_USB_C0_PD_SDA}, - {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, - GPIO_EC_I2C_USB_C1_PD_SDA}, - {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, - GPIO_EC_I2C_EEPROM_SDA}, - {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, - GPIO_EC_I2C_SENSOR_SDA}, + { + .name = "power", + .port = I2C_PORT_POWER, + .kbps = 100, + .scl = GPIO_EC_I2C_POWER_SCL, + .sda = GPIO_EC_I2C_POWER_SDA + }, + { + .name = "tcpc0", + .port = I2C_PORT_TCPC0, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C0_PD_SCL, + .sda = GPIO_EC_I2C_USB_C0_PD_SDA + }, + { + .name = "tcpc1", + .port = I2C_PORT_TCPC1, + .kbps = 1000, + .scl = GPIO_EC_I2C_USB_C1_PD_SCL, + .sda = GPIO_EC_I2C_USB_C1_PD_SDA + }, + { + .name = "eeprom", + .port = I2C_PORT_EEPROM, + .kbps = 400, + .scl = GPIO_EC_I2C_EEPROM_SCL, + .sda = GPIO_EC_I2C_EEPROM_SDA + }, + { + .name = "sensor", + .port = I2C_PORT_SENSOR, + .kbps = 400, + .scl = GPIO_EC_I2C_SENSOR_SCL, + .sda = GPIO_EC_I2C_SENSOR_SDA + }, }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); diff --git a/board/wormdingler/board.h b/board/wormdingler/board.h index 83f0e98365..4423a21aeb 100644 --- a/board/wormdingler/board.h +++ b/board/wormdingler/board.h @@ -10,14 +10,6 @@ #include "baseboard.h" -/* TODO(waihong): Remove the following bringup features */ -#define CONFIG_BRINGUP -#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands. */ -#define CONFIG_USB_PD_DEBUG_LEVEL 3 -#define CONFIG_CMD_GPIO_EXTENDED -#define CONFIG_CMD_POWERINDEBUG -#define CONFIG_I2C_DEBUG - #define CONFIG_BUTTON_TRIGGERED_RECOVERY /* Internal SPI flash on NPCX7 */ diff --git a/board/wormdingler/build.mk b/board/wormdingler/build.mk index 74b6b95e4d..452abeb591 100644 --- a/board/wormdingler/build.mk +++ b/board/wormdingler/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=trogdor -board-y=battery.o board.o led.o base_detect.o +board-y=battery.o board.o led.o base_detect.o usbc_config.o diff --git a/board/wormdingler/usbc_config.c b/board/wormdingler/usbc_config.c new file mode 100644 index 0000000000..8f3fb02c30 --- /dev/null +++ b/board/wormdingler/usbc_config.c @@ -0,0 +1,60 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor family-specific USB-C configuration */ + +#include "charger.h" +#include "charger/isl923x_public.h" +#include "charge_state.h" +#include "usb_pd.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +int charger_profile_override(struct charge_state_data *curr) +{ + int usb_mv; + int port; + + if (curr->state != ST_CHARGE) + return 0; + + /* Lower the max requested voltage to 5V when battery is full. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && + !(curr->batt.flags & BATT_FLAG_BAD_STATUS) && + !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) && + (curr->batt.status & STATUS_FULLY_CHARGED)) + usb_mv = 5000; + else + usb_mv = PD_MAX_VOLTAGE_MV; + + if (pd_get_max_voltage() != usb_mv) { + CPRINTS("VBUS limited to %dmV", usb_mv); + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) + pd_set_external_voltage_limit(port, usb_mv); + } + + return 0; +} + +enum ec_status charger_profile_override_get_param(uint32_t param, + uint32_t *value) +{ + return EC_RES_INVALID_PARAM; +} + +enum ec_status charger_profile_override_set_param(uint32_t param, + uint32_t value) +{ + return EC_RES_INVALID_PARAM; +} diff --git a/board/yorp/board.c b/board/yorp/board.c index 625db5d0b7..137100aec3 100644 --- a/board/yorp/board.c +++ b/board/yorp/board.c @@ -142,8 +142,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_ACCEL), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .rot_standard_ref = &base_standard_ref, @@ -174,8 +172,6 @@ struct motion_sensor_t motion_sensors[] = { .mutex = &g_base_mutex, .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data, MOTIONSENSE_TYPE_GYRO), - .int_signal = GPIO_BASE_SIXAXIS_INT_L, - .flags = MOTIONSENSE_FLAG_INT_SIGNAL, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS, .default_range = 1000 | ROUND_UP_FLAG, /* dps */ diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index 0b6f1995f5..9d27181032 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -4,6 +4,7 @@ */ /* tiny substitute of the runtime layer */ +#include "atomic.h" #include "chip/stm32/clock-f.h" #include "clock.h" #include "common.h" @@ -16,7 +17,7 @@ #include "util.h" volatile uint32_t last_event; -uint32_t sleep_mask; +atomic_t sleep_mask; /* High word of the 64-bit timestamp counter */ static volatile uint32_t clksrc_high; diff --git a/chip/ish/aontaskfw/ish_aontask.c b/chip/ish/aontaskfw/ish_aontask.c index ab3749477f..e2106abf0a 100644 --- a/chip/ish/aontaskfw/ish_aontask.c +++ b/chip/ish/aontaskfw/ish_aontask.c @@ -788,7 +788,7 @@ static void handle_reset(enum ish_pm_state pm_state) * ISH ipc host driver will set DMA_ENABLED_MASK bit when it * is loaded and starts, and clear this bit when it is removed. * - * see: https://github.com/torvalds/linux/blob/master/drivers/ + * see: https://github.com/torvalds/linux/blob/HEAD/drivers/ * hid/intel-ish-hid/ipc/ipc.c * * we have two kinds of reset situations need to handle here: diff --git a/chip/ish/build.mk b/chip/ish/build.mk index 9f220abd21..8072a20791 100644 --- a/chip/ish/build.mk +++ b/chip/ish/build.mk @@ -20,8 +20,8 @@ endif chip-y+=clock.o gpio.o system.o hwtimer.o uart.o flash.o ish_persistent_data.o chip-$(CONFIG_I2C)+=i2c.o chip-$(CONFIG_WATCHDOG)+=watchdog.o -chip-$(CONFIG_HOSTCMD_HECI)+=host_command_heci.o -chip-$(CONFIG_HOSTCMD_HECI)+=heci.o system_state_subsys.o ipc_heci.o +chip-$(CONFIG_HOST_INTERFACE_HECI)+=host_command_heci.o +chip-$(CONFIG_HOST_INTERFACE_HECI)+=heci.o system_state_subsys.o ipc_heci.o chip-$(CONFIG_HID_HECI)+=hid_subsys.o chip-$(CONFIG_HID_HECI)+=heci.o system_state_subsys.o ipc_heci.o chip-$(CONFIG_DMA_PAGING)+=dma.o diff --git a/chip/ish/uart_defs.h b/chip/ish/uart_defs.h index b573ef7710..5bfc7b9a6b 100644 --- a/chip/ish/uart_defs.h +++ b/chip/ish/uart_defs.h @@ -10,6 +10,7 @@ #include <stdint.h> #include <stddef.h> +#include "atomic.h" #define UART_ERROR -1 #define UART_BUSY -2 @@ -354,7 +355,7 @@ struct uart_ctx { uint32_t id; uint32_t base; uint32_t addr_interval; - uint32_t uart_state; + atomic_t uart_state; uint32_t is_open; uint32_t baud_rate; uint32_t input_freq; diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk index bbff9f009b..cffd7c68f8 100644 --- a/chip/it83xx/build.mk +++ b/chip/it83xx/build.mk @@ -29,7 +29,7 @@ chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_ADC)+=adc.o chip-$(CONFIG_DAC)+=dac.o chip-$(CONFIG_HOSTCMD_X86)+=lpc.o ec2i.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o +chip-$(CONFIG_HOST_INTERFACE_ESPI)+=espi.o chip-$(CONFIG_SPI_CONTROLLER)+=spi_master.o chip-$(CONFIG_SPI)+=spi.o chip-$(CONFIG_PECI)+=peci.o diff --git a/chip/it83xx/clock.c b/chip/it83xx/clock.c index 41f800721a..c1e9df4265 100644 --- a/chip/it83xx/clock.c +++ b/chip/it83xx/clock.c @@ -232,7 +232,7 @@ static void clock_set_pll(enum pll_freq_idx idx) ext_timer_ms(LOW_POWER_EXT_TIMER, EXT_PSR_32P768K_HZ, 1, 1, 5, 1, 0); task_clear_pending_irq(et_ctrl_regs[LOW_POWER_EXT_TIMER].irq); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* * Workaround for (b:70537592): * We have to set chip select pin as input mode in order to @@ -249,7 +249,7 @@ static void clock_set_pll(enum pll_freq_idx idx) #endif /* Update PLL settings. */ clock_pll_changed(); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI #ifdef IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED /* Enable eSPI pad after changing PLL sequence. */ espi_enable_pad(1); @@ -301,7 +301,8 @@ void clock_init(void) */ IT83XX_GCTRL_RSTS = (IT83XX_GCTRL_RSTS & 0x3F) + 0x40; -#if defined(IT83XX_ESPI_RESET_MODULE_BY_FW) && defined(CONFIG_HOSTCMD_ESPI) +#if defined(IT83XX_ESPI_RESET_MODULE_BY_FW) && \ + defined(CONFIG_HOST_INTERFACE_ESPI) /* * Because we don't support eSPI HW reset function (b/111480168) on DX * version, so we have to reset eSPI configurations during init to @@ -539,7 +540,7 @@ void __enter_hibernate(uint32_t seconds, uint32_t microseconds) /* EC sleep */ ec_sleep = 1; #if defined(IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED) && \ -defined(CONFIG_HOSTCMD_ESPI) +defined(CONFIG_HOST_INTERFACE_ESPI) /* Disable eSPI pad. */ espi_enable_pad(0); #endif @@ -565,7 +566,7 @@ void clock_sleep_mode_wakeup_isr(void) /* trigger a reboot if wake up EC from sleep mode (system hibernate) */ if (clock_ec_wake_from_sleep()) { #if defined(IT83XX_ESPI_INHIBIT_CS_BY_PAD_DISABLED) && \ -defined(CONFIG_HOSTCMD_ESPI) +defined(CONFIG_HOST_INTERFACE_ESPI) /* * Enable eSPI pad. * We will not need to enable eSPI pad here if Dx is able to @@ -636,6 +637,12 @@ void __ram_code __idle(void) while (1) { /* Disable interrupts */ interrupt_disable(); +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE + if (i2c_idle_not_allowed()) { + interrupt_enable(); + continue; + } +#endif /* Check if the EC can enter deep doze mode or not */ if (DEEP_SLEEP_ALLOWED && clock_allow_low_power_idle()) { /* reset low power mode hw timer */ diff --git a/chip/it83xx/ec2i.c b/chip/it83xx/ec2i.c index be02a8f813..5542d455a9 100644 --- a/chip/it83xx/ec2i.c +++ b/chip/it83xx/ec2i.c @@ -20,7 +20,7 @@ static const struct ec2i_t keyboard_settings[] = { /* Set IRQ=01h for logical device */ {HOST_INDEX_IRQNUMX, 0x01}, /* Configure IRQTP for KBC. */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* * Interrupt request type select (IRQTP) for KBC. * bit 1, 0: IRQ request is buffered and applied to SERIRQ diff --git a/chip/it83xx/i2c.c b/chip/it83xx/i2c.c index 5aa8f8a460..836ee7a82f 100644 --- a/chip/it83xx/i2c.c +++ b/chip/it83xx/i2c.c @@ -21,6 +21,48 @@ /* Default maximum time we allow for an I2C transfer */ #define I2C_TIMEOUT_DEFAULT_US (100 * MSEC) +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE + +#ifdef CHIP_CORE_NDS32 +#error "Remapping DLM base is required on it8320 series" +#endif + +/* It is allowed to configure the size up to 2K bytes. */ +#define I2C_CQ_MODE_MAX_PAYLOAD_SIZE 128 +/* reserved 5 bytes for ID and CMD_x */ +#define I2C_CQ_MODE_TX_MAX_PAYLOAD_SIZE (I2C_CQ_MODE_MAX_PAYLOAD_SIZE - 5) +uint8_t i2c_cq_mode_tx_dlm[I2C_ENHANCED_PORT_COUNT] + [I2C_CQ_MODE_MAX_PAYLOAD_SIZE] __aligned(4); +uint8_t i2c_cq_mode_rx_dlm[I2C_ENHANCED_PORT_COUNT] + [I2C_CQ_MODE_MAX_PAYLOAD_SIZE] __aligned(4); + +/* Repeat Start */ +#define I2C_CQ_CMD_L_RS BIT(7) +/* + * R/W (Read/ Write) decides the I2C read or write direction + * 1: read, 0: write + */ +#define I2C_CQ_CMD_L_RW BIT(6) +/* P (STOP) is the I2C STOP condition */ +#define I2C_CQ_CMD_L_P BIT(5) +/* E (End) is this device end flag */ +#define I2C_CQ_CMD_L_E BIT(4) +/* LA (Last ACK) is Last ACK in master receiver */ +#define I2C_CQ_CMD_L_LA BIT(3) +/* bit[2:0] are number of transfer out or receive data which depends on R/W. */ +#define I2C_CQ_CMD_L_NUM_BIT_2_0 GENMASK(2, 0) + +struct i2c_cq_packet { + uint8_t id; + uint8_t cmd_l; + uint8_t cmd_h; + uint8_t wdata[0]; +}; + +/* Preventing CPU going into idle mode during command queue I2C transaction. */ +static uint32_t i2c_idle_disabled; +#endif /* CONFIG_IT83XX_I2C_CMD_QUEUE */ + enum enhanced_i2c_transfer_direct { TX_DIRECT, RX_DIRECT, @@ -98,6 +140,8 @@ enum enhanced_i2c_ctl { E_START_ID = (E_INT_EN | E_MODE_SEL | E_ACK | E_START | E_HW_RST), /* Generate stop condition */ E_FINISH = (E_INT_EN | E_MODE_SEL | E_ACK | E_STOP | E_HW_RST), + /* start with command queue mode */ + E_START_CQ = (E_INT_EN | E_MODE_SEL | E_ACK | E_START), }; enum i2c_reset_cause { @@ -587,11 +631,199 @@ static int enhanced_i2c_error(int p) return pd->err; } -static int i2c_transaction(int p) +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE +static void enhanced_i2c_set_cmd_addr_regs(int p) +{ + int dlm_index = p - I2C_STANDARD_PORT_COUNT; + int p_ch = i2c_ch_reg_shift(p); + uint32_t dlm_base; + + /* set "Address Register" to store the I2C data */ + dlm_base = (uint32_t)&i2c_cq_mode_rx_dlm[dlm_index] & 0xffffff; + IT83XX_I2C_RAMH2A(p_ch) = (dlm_base >> 16) & 0xff; + IT83XX_I2C_RAMHA(p_ch) = (dlm_base >> 8) & 0xff; + IT83XX_I2C_RAMLA(p_ch) = dlm_base & 0xff; + + /* Set "Command Address Register" to get commands */ + dlm_base = (uint32_t)&i2c_cq_mode_tx_dlm[dlm_index] & 0xffffff; + IT83XX_I2C_CMD_ADDH2(p_ch) = (dlm_base >> 16) & 0xff; + IT83XX_I2C_CMD_ADDH(p_ch) = (dlm_base >> 8) & 0xff; + IT83XX_I2C_CMD_ADDL(p_ch) = dlm_base & 0xff; +} + +static void i2c_enable_idle(int port) +{ + i2c_idle_disabled &= ~BIT(port); +} + +static void i2c_disable_idle(int port) +{ + i2c_idle_disabled |= BIT(port); +} + +uint32_t i2c_idle_not_allowed(void) +{ + return i2c_idle_disabled; +} + +static int command_i2c_idle_mask(int argc, char **argv) +{ + ccprintf("i2c idle mask: %08x\n", i2c_idle_disabled); + + return EC_SUCCESS; +} +DECLARE_SAFE_CONSOLE_COMMAND(i2cidlemask, command_i2c_idle_mask, + NULL, "Display i2c idle mask"); + +static void enhanced_i2c_cq_write(int p) +{ + struct i2c_port_data *pd = pdata + p; + struct i2c_cq_packet *i2c_cq_pckt; + uint8_t num_bit_2_0 = (pd->out_size - 1) & I2C_CQ_CMD_L_NUM_BIT_2_0; + uint8_t num_bit_10_3 = ((pd->out_size - 1) >> 3) & 0xff; + int dlm_index = p - I2C_STANDARD_PORT_COUNT; + + i2c_cq_pckt = (struct i2c_cq_packet *)&i2c_cq_mode_tx_dlm[dlm_index]; + /* Set commands in RAM. */ + i2c_cq_pckt->id = pd->addr_8bit; + i2c_cq_pckt->cmd_l = I2C_CQ_CMD_L_P | I2C_CQ_CMD_L_E | num_bit_2_0; + i2c_cq_pckt->cmd_h = num_bit_10_3; + for (int i = 0; i < pd->out_size; i++) + i2c_cq_pckt->wdata[i] = pd->out[i]; +} + +static void enhanced_i2c_cq_read(int p) +{ + struct i2c_port_data *pd = pdata + p; + struct i2c_cq_packet *i2c_cq_pckt; + uint8_t num_bit_2_0 = (pd->in_size - 1) & I2C_CQ_CMD_L_NUM_BIT_2_0; + uint8_t num_bit_10_3 = ((pd->in_size - 1) >> 3) & 0xff; + int dlm_index = p - I2C_STANDARD_PORT_COUNT; + + i2c_cq_pckt = (struct i2c_cq_packet *)&i2c_cq_mode_tx_dlm[dlm_index]; + /* Set commands in RAM. */ + i2c_cq_pckt->id = pd->addr_8bit; + i2c_cq_pckt->cmd_l = I2C_CQ_CMD_L_RW | I2C_CQ_CMD_L_P | + I2C_CQ_CMD_L_E | num_bit_2_0; + i2c_cq_pckt->cmd_h = num_bit_10_3; +} + +static void enhanced_i2c_cq_write_to_read(int p) +{ + struct i2c_port_data *pd = pdata + p; + struct i2c_cq_packet *i2c_cq_pckt; + uint8_t num_bit_2_0 = (pd->out_size - 1) & I2C_CQ_CMD_L_NUM_BIT_2_0; + uint8_t num_bit_10_3 = ((pd->out_size - 1) >> 3) & 0xff; + int dlm_index = p - I2C_STANDARD_PORT_COUNT; + int i; + + i2c_cq_pckt = (struct i2c_cq_packet *)&i2c_cq_mode_tx_dlm[dlm_index]; + /* Set commands in RAM. (command byte for write) */ + i2c_cq_pckt->id = pd->addr_8bit; + i2c_cq_pckt->cmd_l = num_bit_2_0; + i2c_cq_pckt->cmd_h = num_bit_10_3; + for (i = 0; i < pd->out_size; i++) + i2c_cq_pckt->wdata[i] = pd->out[i]; + /* Set commands in RAM. (command byte for read) */ + num_bit_2_0 = (pd->in_size - 1) & I2C_CQ_CMD_L_NUM_BIT_2_0; + num_bit_10_3 = ((pd->in_size - 1) >> 3) & 0xff; + i2c_cq_pckt->wdata[i++] = I2C_CQ_CMD_L_RS | I2C_CQ_CMD_L_RW | + I2C_CQ_CMD_L_P | I2C_CQ_CMD_L_E | num_bit_2_0; + i2c_cq_pckt->wdata[i] = num_bit_10_3; +} + +static int enhanced_i2c_cmd_queue_trans(int p) +{ + struct i2c_port_data *pd = pdata + p; + int p_ch = i2c_ch_reg_shift(p); + int dlm_index = p - I2C_STANDARD_PORT_COUNT; + + /* ISR of command queue mode */ + if (in_interrupt_context()) { + /* device 1 finish IRQ */ + if (IT83XX_I2C_FST(p_ch) & IT83XX_I2C_FST_DEV1_IRQ) { + /* get data if this is a read transaction */ + for (int i = 0; i < pd->in_size; i++) + pd->in[i] = i2c_cq_mode_rx_dlm[dlm_index][i]; + } else { + /* device 1 error have occurred. eg. nack, timeout... */ + if (IT83XX_I2C_NST(p_ch) & IT83XX_I2C_NST_ID_NACK) + pd->err = E_HOSTA_ACK; + else + pd->err = IT83XX_I2C_STR(p_ch) & + E_HOSTA_ANY_ERROR; + } + /* reset bus */ + IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; + IT83XX_I2C_CTR1(p_ch) = 0; + + return 0; + } + + if ((pd->out_size > I2C_CQ_MODE_TX_MAX_PAYLOAD_SIZE) || + (pd->in_size > I2C_CQ_MODE_MAX_PAYLOAD_SIZE)) { + pd->err = EC_ERROR_INVAL; + return 0; + } + + /* State reset and hardware reset */ + IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; + /* Set "PSR" registers to decide the i2c speed. */ + IT83XX_I2C_PSR(p_ch) = pdata[p].freq; + IT83XX_I2C_HSPR(p_ch) = pdata[p].freq; + /* Set time out register. port D, E, or F clock/data low timeout. */ + IT83XX_I2C_TOR(p_ch) = I2C_CLK_LOW_TIMEOUT; + + /* i2c write to read */ + if (pd->out_size && pd->in_size) + enhanced_i2c_cq_write_to_read(p); + /* i2c write */ + else if (pd->out_size) + enhanced_i2c_cq_write(p); + /* i2c read */ + else if (pd->in_size) + enhanced_i2c_cq_read(p); + + /* enable i2c module with command queue mode */ + IT83XX_I2C_CTR1(p_ch) = IT83XX_I2C_MDL_EN | IT83XX_I2C_COMQ_EN; + /* one shot on device 1 */ + IT83XX_I2C_MODE_SEL(p_ch) = 0; + IT83XX_I2C_CTR2(p_ch) = 1; + /* start */ + i2c_disable_idle(p); + IT83XX_I2C_CTR(p_ch) = E_START_CQ; + + return 0; +} +#endif /* CONFIG_IT83XX_I2C_CMD_QUEUE */ + +static int enhanced_i2c_pio_trans(int p) { struct i2c_port_data *pd = pdata + p; int p_ch; + /* no error */ + if (!(enhanced_i2c_error(p))) { + /* i2c write */ + if (pd->out_size) + return enhanced_i2c_tran_write(p); + /* i2c read */ + else if (pd->in_size) + return enhanced_i2c_tran_read(p); + } + + p_ch = i2c_ch_reg_shift(p); + IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; + IT83XX_I2C_CTR1(p_ch) = 0; + + return 0; +} + +static int i2c_transaction(int p) +{ + struct i2c_port_data *pd = pdata + p; + int ret; + if (p < I2C_STANDARD_PORT_COUNT) { /* any error */ if (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR) { @@ -612,18 +844,13 @@ static int i2c_transaction(int p) /* disable the SMBus host interface */ IT83XX_SMB_HOCTL2(p) = 0x00; } else { - /* no error */ - if (!(enhanced_i2c_error(p))) { - /* i2c write */ - if (pd->out_size) - return enhanced_i2c_tran_write(p); - /* i2c read */ - else if (pd->in_size) - return enhanced_i2c_tran_read(p); - } - p_ch = i2c_ch_reg_shift(p); - IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; - IT83XX_I2C_CTR1(p_ch) = 0; +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE + if (pd->flags == I2C_XFER_SINGLE) + ret = enhanced_i2c_cmd_queue_trans(p); + else +#endif + ret = enhanced_i2c_pio_trans(p); + return ret; } /* done doing work */ return 0; @@ -713,6 +940,10 @@ int chip_i2c_xfer(int port, uint16_t addr_flags, if (pd->err) pd->i2ccs = I2C_CH_NORMAL; +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE + i2c_enable_idle(port); +#endif + return pd->err; } @@ -933,6 +1164,10 @@ void i2c_init(void) IT83XX_I2C_CTR(p_ch) = E_STS_AND_HW_RST; /* bit1, Module enable */ IT83XX_I2C_CTR1(p_ch) = 0; +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE + /* set command address registers */ + enhanced_i2c_set_cmd_addr_regs(p); +#endif } pdata[i].task_waiting = TASK_ID_INVALID; } diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c index 5e6fd734c4..45fff30c1e 100644 --- a/chip/it83xx/intc.c +++ b/chip/it83xx/intc.c @@ -84,7 +84,7 @@ static void intc_cpu_int_group_12(void) peci_interrupt(); break; #endif -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI case IT83XX_IRQ_ESPI: espi_interrupt(); break; diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h index 62ceb34576..50d31999f9 100644 --- a/chip/it83xx/intc.h +++ b/chip/it83xx/intc.h @@ -50,5 +50,8 @@ void spi_peripheral_int_handler(void); void lpc_kbc_ibf_interrupt(void); void lpc_kbc_obe_interrupt(void); #endif +#ifdef CONFIG_IT83XX_I2C_CMD_QUEUE +uint32_t i2c_idle_not_allowed(void); +#endif #endif /* __CROS_EC_INTC_H */ diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c index 867d9e024f..8a90bd426d 100644 --- a/chip/it83xx/lpc.c +++ b/chip/it83xx/lpc.c @@ -136,7 +136,7 @@ static void keyboard_irq_assert(void) */ static void lpc_generate_smi(void) { -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_vw_set_wire(VW_SMI_L, 0); udelay(65); espi_vw_set_wire(VW_SMI_L, 1); @@ -149,7 +149,7 @@ static void lpc_generate_smi(void) static void lpc_generate_sci(void) { -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_vw_set_wire(VW_SCI_L, 0); udelay(65); espi_vw_set_wire(VW_SCI_L, 1); @@ -377,7 +377,7 @@ void lpc_clear_acpi_status_mask(uint8_t mask) pm_set_status(LPC_ACPI_CMD, mask, 0); } -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI int lpc_get_pltrst_asserted(void) { return !gpio_get_level(GPIO_PCH_PLTRST_L); @@ -688,7 +688,7 @@ static void lpc_init(void) */ IT83XX_GCTRL_SPCTRL1 |= 0xC2; -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI gpio_enable_interrupt(GPIO_PCH_PLTRST_L); #endif @@ -711,7 +711,7 @@ static void lpc_init(void) task_clear_pending_irq(IT83XX_IRQ_PMC3_IN); task_enable_irq(IT83XX_IRQ_PMC3_IN); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_init(); #endif /* Sufficiently initialized */ @@ -726,7 +726,7 @@ static void lpc_init(void) */ DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC); -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI void lpcrst_interrupt(enum gpio_signal signal) { if (lpc_get_pltrst_asserted()) diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index 34a2ddd6ae..b752f012d8 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -1456,7 +1456,7 @@ enum bram_indices { BRAM_IDX_EC_LOG_STATUS = 0xc, /* offset 0x0d ~ 0x1f are reserved for future use. */ -#if defined(CONFIG_HOSTCMD_LPC) || defined(CONFIG_HOSTCMD_ESPI) +#if defined(CONFIG_HOST_INTERFACE_LPC) || defined(CONFIG_HOST_INTERFACE_ESPI) /* * offset 0x20 ~ 0x7b are reserved for future use. * (apply to x86 platform) @@ -1508,7 +1508,7 @@ enum bram_ec_logs_status { * And they will be used to save panic data if the GPG1 reset mechanism * is enabled. */ -#if defined(CONFIG_HOSTCMD_LPC) || defined(CONFIG_HOSTCMD_ESPI) +#if defined(CONFIG_HOST_INTERFACE_LPC) || defined(CONFIG_HOST_INTERFACE_ESPI) /* offset 0x80 ~ 0xbf */ #define IT83XX_BRAM_BANK1(i) REG8(IT83XX_BRAM_BASE + 0x80 + i) #else @@ -1552,7 +1552,20 @@ enum bram_ec_logs_status { #define IT83XX_I2C_IDR(ch) REG8(IT83XX_I2C_BASE+0x06+(ch << 7)) #define IT83XX_I2C_TOS(ch) REG8(IT83XX_I2C_BASE+0x07+(ch << 7)) #define IT83XX_I2C_CLK_STR (1 << 7) +#define IT83XX_I2C_STR2(ch) REG8(IT83XX_I2C_BASE+0x12+(ch << 7)) +#define IT83XX_I2C_NST(ch) REG8(IT83XX_I2C_BASE+0x13+(ch << 7)) +#define IT83XX_I2C_NST_CNS BIT(7) +#define IT83XX_I2C_NST_ID_NACK BIT(3) +#define IT83XX_I2C_TO_ARB_ST(ch) REG8(IT83XX_I2C_BASE+0x18+(ch << 7)) +#define IT83XX_I2C_ERR_ST(ch) REG8(IT83XX_I2C_BASE+0x19+(ch << 7)) +#define IT83XX_I2C_ERR_ST_DEV1_EIRQ BIT(0) +#define IT83XX_I2C_FST(ch) REG8(IT83XX_I2C_BASE+0x1b+(ch << 7)) +#define IT83XX_I2C_FST_DEV1_IRQ BIT(4) +#define IT83XX_I2C_EM(ch) REG8(IT83XX_I2C_BASE+0x1c+(ch << 7)) +#define IT83XX_I2C_EM_DEV1_IRQ BIT(4) +#define IT83XX_I2C_MODE_SEL(ch) REG8(IT83XX_I2C_BASE+0x1d+(ch << 7)) #define IT83XX_I2C_IDR2(ch) REG8(IT83XX_I2C_BASE+0x1F+(ch << 7)) +#define IT83XX_I2C_CTR2(ch) REG8(IT83XX_I2C_BASE+0x20+(ch << 7)) #define IT83XX_I2C_RAMHA(ch) REG8(IT83XX_I2C_BASE+0x23+(ch << 7)) #define IT83XX_I2C_RAMLA(ch) REG8(IT83XX_I2C_BASE+0x24+(ch << 7)) #define IT83XX_I2C_RAMHA2(ch) REG8(IT83XX_I2C_BASE+0x2B+(ch << 7)) diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c index 16871e5826..ae7fd627bf 100644 --- a/chip/it83xx/system.c +++ b/chip/it83xx/system.c @@ -50,7 +50,7 @@ static void clear_reset_flags(void) } DECLARE_HOOK(HOOK_INIT, clear_reset_flags, HOOK_PRIO_LAST); -#if !defined(CONFIG_HOSTCMD_LPC) && !defined(CONFIG_HOSTCMD_ESPI) +#if !defined(CONFIG_HOST_INTERFACE_LPC) && !defined(CONFIG_HOST_INTERFACE_ESPI) static void system_save_panic_data_to_bram(void) { uint8_t *ptr = (uint8_t *)PANIC_DATA_PTR; diff --git a/chip/lm4/build.mk b/chip/lm4/build.mk index 26419d3a04..c1d7787bf3 100644 --- a/chip/lm4/build.mk +++ b/chip/lm4/build.mk @@ -20,7 +20,7 @@ chip-$(CONFIG_EEPROM)+=eeprom.o chip-$(CONFIG_FANS)+=fan.o chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o chip-$(CONFIG_I2C)+=i2c.o -chip-$(CONFIG_HOSTCMD_LPC)+=lpc.o +chip-$(CONFIG_HOST_INTERFACE_LPC)+=lpc.o chip-$(CONFIG_PECI)+=peci.o # pwm functions are implemented with the fan functions chip-$(CONFIG_PWM)+=pwm.o fan.o diff --git a/chip/lm4/config_chip.h b/chip/lm4/config_chip.h index 4e442004c9..8e1ea51785 100644 --- a/chip/lm4/config_chip.h +++ b/chip/lm4/config_chip.h @@ -93,7 +93,7 @@ /* Optional features present on this chip */ #define CONFIG_ADC #define CONFIG_HOSTCMD_ALIGNED -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_PECI #define CONFIG_RTC #define CONFIG_SWITCH diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h index 0c59da19f6..1065cd7f5e 100644 --- a/chip/lm4/registers.h +++ b/chip/lm4/registers.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_REGISTERS_H #define __CROS_EC_REGISTERS_H +#include "atomic.h" #include "common.h" #define LM4_UART_CH0_BASE 0x4000c000 @@ -265,7 +266,7 @@ static inline int lm4_fan_addr(int ch, int offset) #define LM4_SYSTEM_SRI2C REG32(0x400fe520) #define LM4_SYSTEM_SREEPROM REG32(0x400fe558) -#define LM4_SYSTEM_SRI2C_ADDR ((uint32_t *)0x400fe520) +#define LM4_SYSTEM_SRI2C_ADDR ((atomic_t *)0x400fe520) #define LM4_SYSTEM_RCGC_BASE ((volatile uint32_t *)0x400fe600) #define LM4_SYSTEM_RCGCGPIO REG32(0x400fe608) diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c index 0b923f0692..83136d0b46 100644 --- a/chip/lm4/uart.c +++ b/chip/lm4/uart.c @@ -123,7 +123,7 @@ static void uart_host_interrupt(void) /* Clear transmit and receive interrupt status */ LM4_UART_ICR(CONFIG_UART_HOST) = 0x70; -#ifdef CONFIG_HOSTCMD_LPC +#ifdef CONFIG_HOST_INTERFACE_LPC /* * If we have space in our FIFO and a character is pending in LPC, * handle that character. diff --git a/chip/mchp/build.mk b/chip/mchp/build.mk index 155fbf385f..226fe23363 100644 --- a/chip/mchp/build.mk +++ b/chip/mchp/build.mk @@ -32,7 +32,7 @@ endif chip-y=clock.o gpio.o hwtimer.o system.o uart.o port80.o tfdp.o chip-$(CONFIG_ADC)+=adc.o chip-$(CONFIG_DMA)+=dma.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o +chip-$(CONFIG_HOST_INTERFACE_ESPI)+=espi.o chip-$(CONFIG_FANS)+=fan.o chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o chip-$(CONFIG_I2C)+=i2c.o diff --git a/chip/mchp/clock.c b/chip/mchp/clock.c index 362025ee1c..e646470ac6 100644 --- a/chip/mchp/clock.c +++ b/chip/mchp/clock.c @@ -395,7 +395,7 @@ static void prepare_for_deep_sleep(void) #endif -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; MCHP_INT_ENABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; #else @@ -475,7 +475,7 @@ static void resume_from_deep_sleep(void) */ MCHP_PCR_SLP_EN3 |= (MCHP_PCR_SLP_EN3_HTMR0); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI #ifdef CONFIG_POWER_S0IX MCHP_INT_DISABLE(22) = MCHP_INT22_WAKE_ONLY_ESPI; MCHP_INT_SOURCE(22) = MCHP_INT22_WAKE_ONLY_ESPI; @@ -763,7 +763,7 @@ static int command_dsleep(int argc, char **argv) } } - ccprintf("Sleep mask: %08x\n", sleep_mask); + ccprintf("Sleep mask: %08x\n", (int)sleep_mask); ccprintf("Console in use timeout: %d sec\n", console_in_use_timeout_sec); diff --git a/chip/mchp/espi.c b/chip/mchp/espi.c index a7db914f3b..778990b852 100644 --- a/chip/mchp/espi.c +++ b/chip/mchp/espi.c @@ -1386,7 +1386,7 @@ void espi_init(void) (CONFIG_HOSTCMD_ESPI_EC_MODE << MCHP_ESPI_CAP1_IO_BITPOS); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_ESPI_IO_PLTRST_SRC = MCHP_ESPI_PLTRST_SRC_VW; #else MCHP_ESPI_IO_PLTRST_SRC = MCHP_ESPI_PLTRST_SRC_PIN; diff --git a/chip/mchp/lpc.c b/chip/mchp/lpc.c index 9f6a731eb5..9e64281276 100644 --- a/chip/mchp/lpc.c +++ b/chip/mchp/lpc.c @@ -88,7 +88,7 @@ static void keyboard_irq_assert(void) static void lpc_generate_smi(void) { CPUTS("LPC Pulse SMI"); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* eSPI: pulse SMI# Virtual Wire low */ espi_vw_pulse_wire(VW_SMI_L, 0); #else @@ -106,7 +106,7 @@ static void lpc_generate_sci(void) udelay(65); gpio_set_level(CONFIG_SCI_GPIO, 1); #else -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_vw_pulse_wire(VW_SCI_L, 0); #else MCHP_ACPI_PM_STS |= 1; @@ -129,7 +129,7 @@ static void lpc_update_wake(host_event_t wake_events) */ wake_events &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_vw_set_wire(VW_WAKE_L, !wake_events); #else /* Signal is asserted low when wake events is non-zero */ @@ -304,7 +304,7 @@ const int acpi_ec_nvic_ibf[] = { }; BUILD_ASSERT(ARRAY_SIZE(acpi_ec_nvic_ibf) == MCHP_ACPI_EC_INSTANCES); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI const int acpi_ec_espi_bar_id[] = { MCHP_ESPI_IO_BAR_ID_ACPI_EC0, MCHP_ESPI_IO_BAR_ID_ACPI_EC1, @@ -326,7 +326,7 @@ void chip_acpi_ec_config(int instance, uint32_t io_base, uint8_t mask) MCHP_PCR_SLP_DIS_DEV(acpi_ec_pcr_slp[instance]); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_ESPI_IO_BAR_CTL_MASK(acpi_ec_espi_bar_id[instance]) = mask; MCHP_ESPI_IO_BAR(acpi_ec_espi_bar_id[instance]) = @@ -350,7 +350,7 @@ void chip_8042_config(uint32_t io_base) { MCHP_PCR_SLP_DIS_DEV(MCHP_PCR_8042); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_ID_8042) = 0x04; MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_ID_8042) = (io_base << 16) + 0x01ul; @@ -372,7 +372,7 @@ void chip_8042_config(uint32_t io_base) #ifndef CONFIG_KEYBOARD_IRQ_GPIO /* Set up SERIRQ for keyboard */ MCHP_8042_KB_CTRL |= BIT(5); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* Delivery 8042 keyboard interrupt as IRQ1 using eSPI SERIRQ */ MCHP_ESPI_IO_SERIRQ_REG(MCHP_ESPI_SIRQ_8042_KB) = 1; #else @@ -392,7 +392,7 @@ void chip_8042_config(uint32_t io_base) */ void chip_emi0_config(uint32_t io_base) { -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_ID_EMI0) = 0x0F; MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_ID_EMI0) = (io_base << 16) + 0x01ul; @@ -442,7 +442,7 @@ void chip_port80_config(uint32_t io_base) MCHP_P80_CFG(0) = MCHP_P80_FLUSH_FIFO_WO + MCHP_P80_RESET_TIMESTAMP_WO; -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI MCHP_ESPI_IO_BAR_CTL_MASK(MCHP_ESPI_IO_BAR_P80_0) = 0x00; MCHP_ESPI_IO_BAR(MCHP_ESPI_IO_BAR_P80_0) = (io_base << 16) + 0x01ul; @@ -484,7 +484,7 @@ static void chip_lpc_iobar_debug(void) * For eSPI PLATFORM_RESET# virtual wire is used as LRESET# * */ -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI static void setup_lpc(void) { MCHP_LPC_CFG_BAR |= (1ul << 15); @@ -545,7 +545,7 @@ static void lpc_init(void) MCHP_PCR_SLP_EN2_ACPI_EC0 + MCHP_PCR_SLP_EN2_MIF8042); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI espi_init(); @@ -621,7 +621,7 @@ void lpc_set_init_done(int val) */ void lpcrst_interrupt(enum gpio_signal signal) { -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI /* Initialize LPC module when LRESET# is de-asserted */ if (!lpc_get_pltrst_asserted()) { setup_lpc(); @@ -941,10 +941,10 @@ void lpc_clear_acpi_status_mask(uint8_t mask) */ int lpc_get_pltrst_asserted(void) { -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* * eSPI PLTRST# a VWire or side-band signal - * Controlled by CONFIG_HOSTCMD_ESPI + * Controlled by CONFIG_HOST_INTERFACE_ESPI */ return !espi_vw_get_wire(VW_PLTRST_L); #else diff --git a/chip/mchp/lpc_chip.h b/chip/mchp/lpc_chip.h index dcb5577fc1..434b307968 100644 --- a/chip/mchp/lpc_chip.h +++ b/chip/mchp/lpc_chip.h @@ -8,7 +8,7 @@ #ifndef __CROS_EC_LPC_CHIP_H #define __CROS_EC_LPC_CHIP_H -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI #include "espi.h" @@ -37,7 +37,7 @@ void lpc_set_init_done(int val); void lpc_mem_mapped_init(void); -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI void lpcrst_interrupt(enum gpio_signal signal); #endif diff --git a/chip/mchp/system.c b/chip/mchp/system.c index 5591c818c4..72c96bef8f 100644 --- a/chip/mchp/system.c +++ b/chip/mchp/system.c @@ -178,7 +178,7 @@ void system_pre_init(void) MCHP_EC_AHB_ERR_EN = 0; /* enable capture of address on error */ /* Manual voltage selection only required for MEC170x and MEC152x */ - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) vtr3_voltage_select(1); else vtr3_voltage_select(0); @@ -427,7 +427,7 @@ int system_get_scratchpad(uint32_t *value) * defined for MEC170x and the IS_ENABLED() macro causes the * compiler to evaluate both true and false code paths. */ -#if defined(CONFIG_HOSTCMD_ESPI) +#if defined(CONFIG_HOST_INTERFACE_ESPI) static void disable_host_ifc_clocks(void) { MCHP_ESPI_ACTIVATE &= ~0x01; diff --git a/chip/mec1322/build.mk b/chip/mec1322/build.mk index 2b0c9cc229..dd0ef8cd90 100644 --- a/chip/mec1322/build.mk +++ b/chip/mec1322/build.mk @@ -22,7 +22,7 @@ chip-$(CONFIG_ADC)+=adc.o chip-$(CONFIG_FANS)+=fan.o chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o chip-$(CONFIG_I2C)+=i2c.o -chip-$(CONFIG_HOSTCMD_LPC)+=lpc.o +chip-$(CONFIG_HOST_INTERFACE_LPC)+=lpc.o chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_WATCHDOG)+=watchdog.o ifndef CONFIG_KEYBOARD_NOT_RAW diff --git a/chip/mec1322/config_chip.h b/chip/mec1322/config_chip.h index 414fb492bf..951de3fb4f 100644 --- a/chip/mec1322/config_chip.h +++ b/chip/mec1322/config_chip.h @@ -103,7 +103,7 @@ #define CONFIG_MPU #endif #define CONFIG_DMA -#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOST_INTERFACE_LPC #define CONFIG_SPI #define CONFIG_SWITCH diff --git a/chip/mt_scp/mt8195/clock.c b/chip/mt_scp/mt8195/clock.c index 1ad1706e6a..eac6436a46 100644 --- a/chip/mt_scp/mt8195/clock.c +++ b/chip/mt_scp/mt8195/clock.c @@ -378,11 +378,11 @@ power_chipset_handle_host_sleep_event(enum host_sleep_event state, { if (state == HOST_SLEEP_EVENT_S3_SUSPEND) { CPRINTS("AP suspend"); - disable_watchdog(); + watchdog_disable(); clock_select_clock(SCP_CLK_SYSTEM); } else if (state == HOST_SLEEP_EVENT_S3_RESUME) { clock_select_clock(SCP_CLK_ULPOSC2_HIGH_SPEED); - enable_watchdog(); + watchdog_enable(); CPRINTS("AP resume"); } } diff --git a/chip/mt_scp/mt8195/intc.h b/chip/mt_scp/mt8195/intc.h index 87181c46ca..ba77f069f2 100644 --- a/chip/mt_scp/mt8195/intc.h +++ b/chip/mt_scp/mt8195/intc.h @@ -102,13 +102,13 @@ /* 68 */ #define SCP_IRQ_APU_MBOX 68 #define SCP_IRQ_DEVAPC_SECURE_VIO 69 -#define SCP_IRQ_CAMSYS_29 70 -#define SCP_IRQ_CAMSYS_28 71 +#define SCP_IRQ_APDMA0 70 +#define SCP_IRQ_APDMA1 71 /* 72 */ -#define SCP_IRQ_CAMSYS_5 72 -#define SCP_IRQ_CAMSYS_4 73 -#define SCP_IRQ_CAMSYS_3 74 -#define SCP_IRQ_CAMSYS_2 75 +#define SCP_IRQ_APDMA2 72 +#define SCP_IRQ_APDMA3 73 +#define SCP_IRQ_APDMA4 74 +#define SCP_IRQ_APDMA5 75 /* 76 */ #define SCP_IRQ_HDMIRX_PM_DVI_SQH 76 #define SCP_IRQ_HDMIRX_RESERVED 77 diff --git a/chip/mt_scp/rv32i_common/intc.c b/chip/mt_scp/rv32i_common/intc.c index 7e6b39e1f2..1e4fd1cef4 100644 --- a/chip/mt_scp/rv32i_common/intc.c +++ b/chip/mt_scp/rv32i_common/intc.c @@ -243,13 +243,13 @@ static struct { /* 68 */ [SCP_IRQ_APU_MBOX] = { INTC_GRP_0 }, [SCP_IRQ_DEVAPC_SECURE_VIO] = { INTC_GRP_0 }, - [SCP_IRQ_CAMSYS_29] = { INTC_GRP_0 }, - [SCP_IRQ_CAMSYS_28] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA0] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA1] = { INTC_GRP_0 }, /* 72 */ - [SCP_IRQ_CAMSYS_5] = { INTC_GRP_0 }, - [SCP_IRQ_CAMSYS_4] = { INTC_GRP_0 }, - [SCP_IRQ_CAMSYS_3] = { INTC_GRP_0 }, - [SCP_IRQ_CAMSYS_2] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA2] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA3] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA4] = { INTC_GRP_0 }, + [SCP_IRQ_APDMA5] = { INTC_GRP_0 }, /* 76 */ [SCP_IRQ_HDMIRX_PM_DVI_SQH] = { INTC_GRP_0 }, [SCP_IRQ_HDMIRX_RESERVED] = { INTC_GRP_0 }, @@ -272,9 +272,9 @@ static struct { [SCP_IRQ_HDMI2] = { INTC_GRP_0 }, /* 92 */ [SCP_IRQ_EARC] = { INTC_GRP_0 }, - [SCP_IRQ_HDMI2] = { INTC_GRP_0 }, - [SCP_IRQ_HDMI2] = { INTC_GRP_0 }, - [SCP_IRQ_HDMI2] = { INTC_GRP_0 }, + [SCP_IRQ_CEC] = { INTC_GRP_0 }, + [SCP_IRQ_HDMI_DEV_DET] = { INTC_GRP_0 }, + [SCP_IRQ_HDMIRX_OUT_ARM_PHY] = { INTC_GRP_0 }, /* 96 */ [SCP_IRQ_I2C2] = { INTC_GRP_0 }, [SCP_IRQ_I2C3] = { INTC_GRP_0 }, diff --git a/chip/mt_scp/rv32i_common/ipi.c b/chip/mt_scp/rv32i_common/ipi.c index cba5c65d0b..a7fc720d42 100644 --- a/chip/mt_scp/rv32i_common/ipi.c +++ b/chip/mt_scp/rv32i_common/ipi.c @@ -28,7 +28,7 @@ static struct ipc_shared_obj *const ipi_recv_buf = (struct ipc_shared_obj *)(CONFIG_IPC_SHARED_OBJ_ADDR + sizeof(struct ipc_shared_obj)); -static uint32_t disable_irq_count, saved_int_mask; +static atomic_t disable_irq_count, saved_int_mask; void ipi_disable_irq(void) { diff --git a/chip/mt_scp/rv32i_common/scp_watchdog.h b/chip/mt_scp/rv32i_common/scp_watchdog.h index 0277aeaec7..87309a2f82 100644 --- a/chip/mt_scp/rv32i_common/scp_watchdog.h +++ b/chip/mt_scp/rv32i_common/scp_watchdog.h @@ -9,7 +9,7 @@ #include "watchdog.h" -void disable_watchdog(void); -void enable_watchdog(void); +void watchdog_disable(void); +void watchdog_enable(void); #endif /* __SCP_WATCHDOG_H */ diff --git a/chip/mt_scp/rv32i_common/watchdog.c b/chip/mt_scp/rv32i_common/watchdog.c index 05acf6ea29..f77a948da3 100644 --- a/chip/mt_scp/rv32i_common/watchdog.c +++ b/chip/mt_scp/rv32i_common/watchdog.c @@ -17,7 +17,7 @@ void watchdog_reload(void) } DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); -void disable_watchdog(void) +void watchdog_disable(void) { /* disable watchdog */ SCP_CORE0_WDT_CFG &= ~WDT_EN; @@ -25,7 +25,7 @@ void disable_watchdog(void) SCP_CORE0_WDT_IRQ |= BIT(0); } -void enable_watchdog(void) +void watchdog_enable(void) { const uint32_t timeout = WDT_PERIOD(CONFIG_WATCHDOG_PERIOD_MS); @@ -41,7 +41,7 @@ void enable_watchdog(void) int watchdog_init(void) { - enable_watchdog(); + watchdog_enable(); return EC_SUCCESS; } diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk index 3a41cfbd53..246ab84f34 100644 --- a/chip/npcx/build.mk +++ b/chip/npcx/build.mk @@ -33,9 +33,9 @@ chip-$(CONFIG_FANS)+=fan.o chip-$(CONFIG_FLASH_PHYSICAL)+=flash.o chip-$(CONFIG_I2C)+=i2c.o i2c-$(CHIP_FAMILY).o chip-$(CONFIG_HOSTCMD_X86)+=lpc.o -chip-$(CONFIG_HOSTCMD_ESPI)+=espi.o +chip-$(CONFIG_HOST_INTERFACE_ESPI)+=espi.o chip-$(CONFIG_PECI)+=peci.o -chip-$(CONFIG_HOSTCMD_SHI)+=shi.o +chip-$(CONFIG_HOST_INTERFACE_SHI)+=shi.o chip-$(CONFIG_CEC)+=cec.o # pwm functions are implemented with the fan functions chip-$(CONFIG_PWM)+=pwm.o diff --git a/chip/npcx/cec.c b/chip/npcx/cec.c index e7cd0ae7b9..eb1cfefa0f 100644 --- a/chip/npcx/cec.c +++ b/chip/npcx/cec.c @@ -251,7 +251,7 @@ static int cap_charge; static uint8_t cec_addr = UINT8_MAX; /* Events to send to AP */ -static uint32_t cec_events; +static atomic_t cec_events; /* APB1 frequency. Store divided by 10k to avoid some runtime divisions */ static uint32_t apb1_freq_div_10k; diff --git a/chip/npcx/clock.c b/chip/npcx/clock.c index ad611973be..4656e83a52 100644 --- a/chip/npcx/clock.c +++ b/chip/npcx/clock.c @@ -422,7 +422,7 @@ void __idle(void) * CSAE bit is set. Please notice this symptom only * occurs at npcx5. */ -#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOSTCMD_ESPI) +#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOST_INTERFACE_ESPI) /* Enable Host access wakeup */ SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); #endif @@ -499,7 +499,7 @@ static int command_dsleep(int argc, char **argv) } } - ccprintf("Sleep mask: %08x\n", sleep_mask); + ccprintf("Sleep mask: %08x\n", (int)sleep_mask); ccprintf("Console in use timeout: %d sec\n", console_in_use_timeout_sec); ccprintf("PMCSR register: 0x%02x\n", NPCX_PMCSR); diff --git a/chip/npcx/gpio-npcx5.c b/chip/npcx/gpio-npcx5.c index c6fcf7351b..9412aa9d9f 100644 --- a/chip/npcx/gpio-npcx5.c +++ b/chip/npcx/gpio-npcx5.c @@ -67,7 +67,7 @@ static void __gpio_wk0efgh_interrupt(void) SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 6); return; } - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) { if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 5) && IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 5)) { @@ -179,7 +179,7 @@ DECLARE_IRQ(NPCX_IRQ_KSI_WKINTC_1, __gpio_wk1c_interrupt, 3); #endif DECLARE_IRQ(NPCX_IRQ_WKINTD_1, __gpio_wk1d_interrupt, 3); DECLARE_IRQ(NPCX_IRQ_WKINTE_1, __gpio_wk1e_interrupt, 3); -#ifdef CONFIG_HOSTCMD_SHI +#ifdef CONFIG_HOST_INTERFACE_SHI /* * HACK: Make CS GPIO P2 to improve SHI reliability. * TODO: Increase CS-assertion-to-transaction-start delay on host to diff --git a/chip/npcx/gpio-npcx9.c b/chip/npcx/gpio-npcx9.c index e9e8ad2ad9..31ed4e62ac 100644 --- a/chip/npcx/gpio-npcx9.c +++ b/chip/npcx/gpio-npcx9.c @@ -70,7 +70,7 @@ static void __gpio_host_interrupt(void) SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_5), 6); return; } - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) { if (IS_BIT_SET(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 5) && IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_5), 5)) { @@ -195,7 +195,7 @@ DECLARE_IRQ(NPCX_IRQ_KSI_WKINTC_1, __gpio_wk1c_interrupt, 3); #endif DECLARE_IRQ(NPCX_IRQ_WKINTD_1, __gpio_wk1d_interrupt, 3); DECLARE_IRQ(NPCX_IRQ_WKINTE_1, __gpio_wk1e_interrupt, 3); -#ifdef CONFIG_HOSTCMD_SHI +#ifdef CONFIG_HOST_INTERFACE_SHI /* * HACK: Make CS GPIO P2 to improve SHI reliability. * TODO: Increase CS-assertion-to-transaction-start delay on host to diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c index e740f0aa9f..5f1e3c78b6 100644 --- a/chip/npcx/gpio.c +++ b/chip/npcx/gpio.c @@ -560,7 +560,7 @@ void gpio_pre_init(void) #endif /* Pin_Mux for LPC & SHI */ -#ifdef CONFIG_HOSTCMD_SHI +#ifdef CONFIG_HOST_INTERFACE_SHI /* Switching to eSPI mode for SHI interface */ NPCX_DEVCNT |= 0x08; /* Alternate Intel bus interface LPC/eSPI to GPIOs first */ diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c index 9bb2de8936..d52b9c968a 100644 --- a/chip/npcx/lpc.c +++ b/chip/npcx/lpc.c @@ -86,7 +86,7 @@ static void lpc_task_enable_irq(void) #endif task_enable_irq(NPCX_IRQ_PM_CHAN_IBF); task_enable_irq(NPCX_IRQ_PORT80); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI task_enable_irq(NPCX_IRQ_ESPI); /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ task_enable_irq(NPCX_IRQ_WKINTA_2); @@ -105,7 +105,7 @@ static void lpc_task_disable_irq(void) #endif task_disable_irq(NPCX_IRQ_PM_CHAN_IBF); task_disable_irq(NPCX_IRQ_PORT80); -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI task_disable_irq(NPCX_IRQ_ESPI); /* Virtual Wire: SLP_S3/4/5, SUS_STAT, PLTRST, OOB_RST_WARN */ task_disable_irq(NPCX_IRQ_WKINTA_2); @@ -137,7 +137,7 @@ static void lpc_generate_smi(void) udelay(65); /* Set signal high, now that we've generated the edge */ gpio_set_level(GPIO_PCH_SMI_L, 1); -#elif defined(CONFIG_HOSTCMD_ESPI) +#elif defined(CONFIG_HOST_INTERFACE_ESPI) /* * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. @@ -183,7 +183,7 @@ static void lpc_generate_sci(void) udelay(65); /* Set signal high, now that we've generated the edge */ gpio_set_level(CONFIG_SCI_GPIO, 1); -#elif defined(CONFIG_HOSTCMD_ESPI) +#elif defined(CONFIG_HOST_INTERFACE_ESPI) /* * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. @@ -584,7 +584,8 @@ static void lpc_port80_interrupt(void) uint32_t code = 0; /* buffer Port80 data to the local buffer if FIFO is not empty */ - while (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FNE)) + while (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FNE) && + (count < ARRAY_SIZE(port80_buf))) port80_buf[count++] = NPCX_DP80BUF; for (i = 0; i < count; i++) { @@ -698,7 +699,7 @@ void host_register_init(void) * EC hardware will put those 4 bytes of Port80 code to DP80BUF FIFO. * This is only supported when CHIP_FAMILY >= NPCX9. */ - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) sib_write_reg(SIO_OFFSET, 0xFD, 0x0F); /* enable SHM */ sib_write_reg(SIO_OFFSET, 0x30, 0x01); @@ -721,7 +722,7 @@ int lpc_get_pltrst_asserted(void) return IS_BIT_SET(NPCX_MSWCTL1, NPCX_MSWCTL1_PLTRST_ACT); } -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI /* Initialize host settings by interrupt */ void lpc_lreset_pltrst_handler(void) { @@ -771,7 +772,7 @@ static void lpc_init(void) * In npcx9, the booter will not do this anymore. The HIF_TYP_SEL * field should be set by firmware. */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI /* Initialize eSPI module */ NPCX_DEVCNT |= 0x08; espi_init(); @@ -787,7 +788,7 @@ static void lpc_init(void) /* Clear Host Access Hold state */ NPCX_SMC_CTL = 0xC0; -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI /* * Set alternative pin from GPIO to CLKRUN no matter SERIRQ is under * continuous or quiet mode. @@ -800,7 +801,7 @@ static void lpc_init(void) * valid if CONFIG_SCI_GPIO isn't defined. eSPI sends SMI/SCI through VW * automatically by toggling them, too. It's unnecessary to set pin mux. */ -#if !defined(CONFIG_SCI_GPIO) && !defined(CONFIG_HOSTCMD_ESPI) +#if !defined(CONFIG_SCI_GPIO) && !defined(CONFIG_HOST_INTERFACE_ESPI) SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_EC_SCI_SL); SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_SMI_SL); #endif @@ -876,7 +877,7 @@ static void lpc_init(void) * Init PORT80 * Enable Port80, Enable Port80 function & Interrupt & Read auto */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI NPCX_DP80CTL = 0x2b; #else NPCX_DP80CTL = 0x29; @@ -926,7 +927,7 @@ static void lpc_init(void) /* initial IO port address via SIB-write modules */ host_register_init(); #else -#ifndef CONFIG_HOSTCMD_ESPI +#ifndef CONFIG_HOST_INTERFACE_ESPI /* * Initialize LRESET# interrupt only in case of LPC. For eSPI, there is * no dedicated GPIO pin for LRESET/PLTRST. PLTRST is indicated as a VW diff --git a/chip/npcx/shi_chip.h b/chip/npcx/shi_chip.h index c14aec196e..3fd73e8119 100644 --- a/chip/npcx/shi_chip.h +++ b/chip/npcx/shi_chip.h @@ -5,10 +5,9 @@ /* NPCX-specific SHI module for Chrome EC */ -#ifndef SHI_CHIP_H_ -#define SHI_CHIP_H_ +#ifndef __CROS_EC_SHI_CHIP_H_ +#define __CROS_EC_SHI_CHIP_H_ -#ifdef CONFIG_HOSTCMD_SHI /** * Called when the NSS level changes, signalling the start of a SHI * transaction. @@ -19,6 +18,5 @@ void shi_cs_event(enum gpio_signal signal); #ifdef NPCX_SHI_V2 void shi_cs_gpio_int(enum gpio_signal signal); #endif -#endif -#endif /* SHI_CHIP_H_ */ +#endif /* __CROS_EC_SHI_CHIP_H_ */ diff --git a/chip/npcx/sib.c b/chip/npcx/sib.c index b62946fc96..424048518e 100644 --- a/chip/npcx/sib.c +++ b/chip/npcx/sib.c @@ -19,7 +19,7 @@ * For eSPI - it is 200 us. * For LPC - it is 5 us. */ -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI #define HOST_TRANSACTION_TIMEOUT_US 200 #else #define HOST_TRANSACTION_TIMEOUT_US 5 diff --git a/chip/npcx/system.c b/chip/npcx/system.c index ac7056330f..97fcd01c41 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -872,7 +872,7 @@ void system_pre_init(void) BIT(NPCX_PWDWN_CTL6_ITIM6_PD) | #endif BIT(NPCX_PWDWN_CTL6_ITIM4_PD); /* Skip ITIM5_PD */ -#if !defined(CONFIG_HOSTCMD_ESPI) +#if !defined(CONFIG_HOST_INTERFACE_ESPI) pwdwn6 |= 1 << NPCX_PWDWN_CTL6_ESPI_PD; #endif NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_6) = pwdwn6; diff --git a/chip/stm32/pwm.c b/chip/stm32/pwm.c index 0b339399c9..aadbde08c2 100644 --- a/chip/stm32/pwm.c +++ b/chip/stm32/pwm.c @@ -17,7 +17,7 @@ #include "util.h" /* Bitmap of currently active PWM channels. 1 bit per channel. */ -static uint32_t using_pwm; +static atomic_t using_pwm; void pwm_set_duty(enum pwm_channel ch, int percent) { diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c index bafca58c46..6be0790c63 100644 --- a/chip/stm32/uart.c +++ b/chip/stm32/uart.c @@ -176,7 +176,14 @@ static void uart_interrupt(void) #if defined(CHIP_FAMILY_STM32F4) STM32_USART_SR(UARTN_BASE) &= ~STM32_USART_SR_TC; #else - STM32_USART_ICR(UARTN_BASE) |= STM32_USART_SR_TC; + /* + * ST reference code does blind write to this register, as is + * usual with the "write 1 to clear" convention, despite the + * datasheet listing the bits as "keep at reset value", (which + * we assume is due to copying from the description of + * reserved bits in read/write registers.) + */ + STM32_USART_ICR(UARTN_BASE) = STM32_USART_SR_TC; #endif if (!(STM32_USART_SR(UARTN_BASE) & ~STM32_USART_SR_TC)) return; diff --git a/chip/stm32/usart-stm32f0.c b/chip/stm32/usart-stm32f0.c index b4e7c924a8..740d3929bc 100644 --- a/chip/stm32/usart-stm32f0.c +++ b/chip/stm32/usart-stm32f0.c @@ -82,7 +82,14 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, freq_change, HOOK_PRIO_DEFAULT); void usart_clear_tc(struct usart_config const *config) { - STM32_USART_ICR(config->hw->base) |= STM32_USART_ICR_TCCF; + /* + * ST reference code does blind write to this register, as is usual + * with the "write 1 to clear" convention, despite the datasheet + * listing the bits as "keep at reset value", (which we assume is due + * to copying from the description of reserved bits in read/write + * registers.) + */ + STM32_USART_ICR(config->hw->base) = STM32_USART_ICR_TCCF; } /* diff --git a/chip/stm32/usart-stm32f3.c b/chip/stm32/usart-stm32f3.c index 18452cb3fb..887d79d21f 100644 --- a/chip/stm32/usart-stm32f3.c +++ b/chip/stm32/usart-stm32f3.c @@ -56,7 +56,14 @@ static struct usart_hw_ops const usart_variant_hw_ops = { void usart_clear_tc(struct usart_config const *config) { - STM32_USART_ICR(config->hw->base) |= STM32_USART_ICR_TCCF; + /* + * ST reference code does blind write to this register, as is usual + * with the "write 1 to clear" convention, despite the datasheet + * listing the bits as "keep at reset value", (which we assume is due + * to copying from the description of reserved bits in read/write + * registers.) + */ + STM32_USART_ICR(config->hw->base) = STM32_USART_ICR_TCCF; } /* diff --git a/chip/stm32/usart_info_command.c b/chip/stm32/usart_info_command.c index 2649a97351..7b7dc1362a 100644 --- a/chip/stm32/usart_info_command.c +++ b/chip/stm32/usart_info_command.c @@ -20,13 +20,14 @@ static int command_usart_info(int argc, char **argv) if (config == NULL) continue; - ccprintf( - "USART%d\n" - " dropped %d bytes\n" - " overran %d times\n", - config->hw->index + 1, - atomic_clear((uint32_t *)&(config->state->rx_dropped)), - atomic_clear((uint32_t *)&(config->state->rx_overrun))); + ccprintf("USART%d\n" + " dropped %d bytes\n" + " overran %d times\n", + config->hw->index + 1, + (int)atomic_clear( + (atomic_t *)&(config->state->rx_dropped)), + (int)atomic_clear( + (atomic_t *)&(config->state->rx_overrun))); if (config->rx->info) config->rx->info(config); diff --git a/chip/stm32/usart_rx_dma.c b/chip/stm32/usart_rx_dma.c index a185878261..c75ebdde41 100644 --- a/chip/stm32/usart_rx_dma.c +++ b/chip/stm32/usart_rx_dma.c @@ -81,7 +81,7 @@ static void usart_rx_dma_interrupt_common( /* (new_index == old_index): nothing to add to the queue. */ } - atomic_add((uint32_t *)&(config->state->rx_dropped), new_bytes - added); + atomic_add((atomic_t *)&(config->state->rx_dropped), new_bytes - added); if (dma_config->state->max_bytes < new_bytes) dma_config->state->max_bytes = new_bytes; @@ -115,5 +115,5 @@ void usart_rx_dma_info(struct usart_config const *config) DOWNCAST(config->rx, struct usart_rx_dma const, usart_rx); ccprintf(" DMA RX max_bytes %d\n", - atomic_clear((uint32_t *)&dma_config->state->max_bytes)); + (int)atomic_clear((atomic_t *)&dma_config->state->max_bytes)); } diff --git a/chip/stm32/usart_rx_interrupt-stm32f4.c b/chip/stm32/usart_rx_interrupt-stm32f4.c index 198c6dd180..b796ae1175 100644 --- a/chip/stm32/usart_rx_interrupt-stm32f4.c +++ b/chip/stm32/usart_rx_interrupt-stm32f4.c @@ -33,7 +33,7 @@ static void usart_rx_interrupt_handler(struct usart_config const *config) uint8_t byte = STM32_USART_RDR(base); if (!queue_add_unit(config->producer.queue, &byte)) - atomic_add((uint32_t *)&(config->state->rx_dropped), 1); + atomic_add((atomic_t *)&(config->state->rx_dropped), 1); } } diff --git a/chip/stm32/usart_rx_interrupt-stm32l.c b/chip/stm32/usart_rx_interrupt-stm32l.c index 24ca7a0487..a89d474d05 100644 --- a/chip/stm32/usart_rx_interrupt-stm32l.c +++ b/chip/stm32/usart_rx_interrupt-stm32l.c @@ -30,7 +30,24 @@ static void usart_rx_interrupt_handler(struct usart_config const *config) * we can't disable it. */ if (status & STM32_USART_SR_ORE) { +#ifdef STM32_USART_ICR_ORECF /* + * Newer series (STM32L4xx and STM32L5xx) have an explicit + * "interrupt clear" register. + * + * ST reference code does blind write to this register, as is + * usual with the "write 1 to clear" convention, despite the + * datasheet listing the bits as "keep at reset value", (which + * we assume is due to copying from the description of + * reserved bits in read/write registers.) + */ + STM32_USART_ICR(config->hw->base) = STM32_USART_ICR_ORECF; +#else + /* + * On the older series STM32L1xx, the overrun bit is cleared + * by a read of the status register, followed by a read of the + * data register. + * * In the unlikely event that the overrun error bit was set but * the RXNE bit was not (possibly because a read was done from * RDR without first reading the status register) we do a read @@ -38,15 +55,16 @@ static void usart_rx_interrupt_handler(struct usart_config const *config) */ if (!(status & STM32_USART_SR_RXNE)) (void)STM32_USART_RDR(config->hw->base); +#endif - atomic_add((uint32_t *)&(config->state->rx_overrun), 1); + atomic_add((atomic_t *)&(config->state->rx_overrun), 1); } if (status & STM32_USART_SR_RXNE) { uint8_t byte = STM32_USART_RDR(base); if (!queue_add_unit(config->producer.queue, &byte)) - atomic_add((uint32_t *)&(config->state->rx_dropped), 1); + atomic_add((atomic_t *)&(config->state->rx_dropped), 1); } } diff --git a/chip/stm32/usart_rx_interrupt.c b/chip/stm32/usart_rx_interrupt.c index 3bc30d4aaf..49d4e83894 100644 --- a/chip/stm32/usart_rx_interrupt.c +++ b/chip/stm32/usart_rx_interrupt.c @@ -30,7 +30,7 @@ static void usart_rx_interrupt_handler(struct usart_config const *config) uint8_t byte = STM32_USART_RDR(base); if (!queue_add_unit(config->producer.queue, &byte)) - atomic_add((uint32_t *)&(config->state->rx_dropped), 1); + atomic_add((atomic_t *)&(config->state->rx_dropped), 1); } } diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c index dde84efaea..a1f60e8906 100644 --- a/chip/stm32/usb.c +++ b/chip/stm32/usb.c @@ -578,7 +578,7 @@ void usb_wake(void) } /* Only allow one caller at a time. */ - if (!atomic_clear((int *)&usb_wake_done)) + if (!atomic_clear((atomic_t *)&usb_wake_done)) return; CPRINTF("WAKE\n"); diff --git a/chip/stm32/usb_hid_keyboard.c b/chip/stm32/usb_hid_keyboard.c index ac4a9f5a1f..b4561d591f 100644 --- a/chip/stm32/usb_hid_keyboard.c +++ b/chip/stm32/usb_hid_keyboard.c @@ -397,7 +397,7 @@ static void write_keyboard_report(void) return; } - if (atomic_clear((int *)&hid_ep_data_ready)) { + if (atomic_clear((atomic_t *)&hid_ep_data_ready)) { /* * Endpoint is not busy, and interrupt handler did not just * send the buffer: enable TX. diff --git a/chip/stm32/usb_spi.h b/chip/stm32/usb_spi.h index 591975234d..a1be2c11fb 100644 --- a/chip/stm32/usb_spi.h +++ b/chip/stm32/usb_spi.h @@ -366,11 +366,18 @@ enum usb_spi_request { * If a platform has a small maximum SPI transfer size, it can be optimized * by setting these limits to the maximum transfer size. */ +#ifdef CONFIG_USB_SPI_BUFFER_SIZE +#define USB_SPI_BUFFER_SIZE CONFIG_USB_SPI_BUFFER_SIZE +#else #define USB_SPI_BUFFER_SIZE (USB_SPI_PAYLOAD_SIZE_V2_START + \ (4 * USB_SPI_PAYLOAD_SIZE_V2_CONTINUE)) +#endif #define USB_SPI_MAX_WRITE_COUNT USB_SPI_BUFFER_SIZE #define USB_SPI_MAX_READ_COUNT USB_SPI_BUFFER_SIZE +/* Protocol uses two-byte length fields. Larger buffer makes no sense. */ +BUILD_ASSERT(USB_SPI_BUFFER_SIZE <= 65536); + struct usb_spi_transfer_ctx { /* Address of transfer buffer. */ uint8_t *buffer; @@ -520,7 +527,7 @@ struct usb_spi_config { .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ .bInterfaceSubClass = USB_SUBCLASS_GOOGLE_SPI, \ .bInterfaceProtocol = USB_PROTOCOL_GOOGLE_SPI, \ - .iInterface = 0, \ + .iInterface = USB_STR_SPI_NAME, \ }; \ const struct usb_endpoint_descriptor \ USB_EP_DESC(INTERFACE, 0) = { \ diff --git a/common/battery_fuel_gauge.c b/common/battery_fuel_gauge.c index 528713d68f..5555255188 100644 --- a/common/battery_fuel_gauge.c +++ b/common/battery_fuel_gauge.c @@ -14,11 +14,83 @@ #define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) +/* + * Authenticate the battery connected. + * + * Compare the manufacturer name read from the fuel gauge to the + * manufacturer names defined in the board_battery_info table. If + * a device name has been specified in the board_battery_info table, + * then both the manufacturer and device name must match. + */ +static bool authenticate_battery_type(int index, char *manuf_name) +{ + char device_name[32]; + + const struct fuel_gauge_info * const fuel_gauge = + &board_battery_info[index].fuel_gauge; + int len = 0; + + /* check for valid index */ + if (index >= BATTERY_TYPE_COUNT) + return false; + + /* manufacturer name mismatch */ + if (strcasecmp(manuf_name, fuel_gauge->manuf_name)) + return false; + + /* device name is specified in table */ + if (fuel_gauge->device_name != NULL) { + + /* Get the device name */ + if (battery_device_name(device_name, + sizeof(device_name))) + return false; + + len = strlen(fuel_gauge->device_name); + + /* device name mismatch */ + if (strncasecmp(device_name, fuel_gauge->device_name, + len)) + return false; + } + + CPRINTS("found batt:%s", fuel_gauge->manuf_name); + return true; +} + +#ifdef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT + +/* Variable to decide the battery type */ +static int fixed_battery_type = BATTERY_TYPE_UNINITIALIZED; + +/* + * Function to get the fixed battery type. + */ +static int battery_get_fixed_battery_type(void) +{ + if (fixed_battery_type == BATTERY_TYPE_UNINITIALIZED) { + CPRINTS("Warning: Battery type is not Initialized! " + "Setting to default battery type.\n"); + fixed_battery_type = DEFAULT_BATTERY_TYPE; + } + + return fixed_battery_type; +} + +/* + * Function to set the battery type, when auto-detection cannot be used. + */ +void battery_set_fixed_battery_type(int type) +{ + if (type < BATTERY_TYPE_COUNT) + fixed_battery_type = type; +} +#endif /* CONFIG_BATTERY_TYPE_NO_AUTO_DETECT */ /* Get type of the battery connected on the board */ static int get_battery_type(void) { - char manuf_name[32], device_name[32]; + char manuf_name[32]; int i; static enum battery_type battery_type = BATTERY_TYPE_COUNT; @@ -33,36 +105,18 @@ static int get_battery_type(void) if (battery_manufacturer_name(manuf_name, sizeof(manuf_name))) return battery_type; - /* - * Compare the manufacturer name read from the fuel gauge to the - * manufacturer names defined in the board_battery_info table. If - * a device name has been specified in the board_battery_info table, - * then both the manufacturer and device name must match. - */ +#if defined(CONFIG_BATTERY_TYPE_NO_AUTO_DETECT) + i = battery_get_fixed_battery_type(); + if (authenticate_battery_type(i, manuf_name)) + battery_type = i; +#else for (i = 0; i < BATTERY_TYPE_COUNT; i++) { - const struct fuel_gauge_info * const fuel_gauge = - &board_battery_info[i].fuel_gauge; - int len = 0; - - if (strcasecmp(manuf_name, fuel_gauge->manuf_name)) - continue; - - if (fuel_gauge->device_name != NULL) { - - if (battery_device_name(device_name, - sizeof(device_name))) - continue; - - len = strlen(fuel_gauge->device_name); - if (strncasecmp(device_name, fuel_gauge->device_name, - len)) - continue; + if (authenticate_battery_type(i, manuf_name)) { + battery_type = i; + break; } - - CPRINTS("found batt:%s", fuel_gauge->manuf_name); - battery_type = i; - break; } +#endif return battery_type; } diff --git a/common/build.mk b/common/build.mk index 901d0d3c9d..d00a7f8bb1 100644 --- a/common/build.mk +++ b/common/build.mk @@ -30,6 +30,7 @@ common-$(CONFIG_ACCEL_LIS2DS)+=math_util.o common-$(CONFIG_ACCEL_KXCJ9)+=math_util.o common-$(CONFIG_ACCEL_KX022)+=math_util.o common-$(CONFIG_TEMP_SENSOR_TMP112)+=math_util.o +common-$(CONFIG_TEMP_SENSOR_PCT2075)+=math_util.o ifneq ($(CORE),cortex-m) common-$(CONFIG_AES)+=aes.o endif @@ -83,7 +84,7 @@ common-$(CONFIG_DEVICE_STATE)+=device_state.o common-$(CONFIG_DPTF)+=dptf.o common-$(CONFIG_EC_EC_COMM_CLIENT)+=ec_ec_comm_client.o common-$(CONFIG_EC_EC_COMM_SERVER)+=ec_ec_comm_server.o -common-$(CONFIG_HOSTCMD_ESPI)+=espi.o +common-$(CONFIG_HOST_INTERFACE_ESPI)+=espi.o common-$(CONFIG_EXTPOWER_GPIO)+=extpower_gpio.o common-$(CONFIG_EXTPOWER)+=extpower_common.o common-$(CONFIG_FANS)+=fan.o pwm.o diff --git a/common/button.c b/common/button.c index d30115066d..145cd9db74 100644 --- a/common/button.c +++ b/common/button.c @@ -43,7 +43,7 @@ static uint64_t next_deferred_time; /* Bitmask to keep track of simulated state of each button. * Bit numbers are aligned to enum button. */ -static int sim_button_state; +static atomic_t sim_button_state; /* * Flip state of associated button type in sim_button_state bitmask. @@ -62,7 +62,7 @@ static int sim_button_state; */ static int simulated_button_pressed(const struct button_config *button) { - return !!(sim_button_state & BIT(button->type)); + return !!((uint32_t)sim_button_state & BIT(button->type)); } #endif @@ -389,7 +389,8 @@ static void simulate_button_release_deferred(void) /* Release the button */ for (button_idx = 0; button_idx < BUTTON_COUNT; button_idx++) { /* Check state for button pressed */ - if (sim_button_state & BIT(buttons[button_idx].type)) { + if ((uint32_t)sim_button_state & + BIT(buttons[button_idx].type)) { /* Set state of the button as released */ atomic_clear_bits(&sim_button_state, BIT(buttons[button_idx].type)); diff --git a/common/charge_manager.c b/common/charge_manager.c index 3d41c3a08d..041f41f1bc 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -1388,9 +1388,9 @@ void charge_manager_source_port(int port, int enable) int p, rp; if (enable) - atomic_or((uint32_t *)&source_port_bitmap, 1 << port); + atomic_or((atomic_t *)&source_port_bitmap, 1 << port); else - atomic_clear_bits((uint32_t *)&source_port_bitmap, 1 << port); + atomic_clear_bits((atomic_t *)&source_port_bitmap, 1 << port); /* No change, exit early. */ if (prev_bitmap == source_port_bitmap) diff --git a/common/charge_ramp.c b/common/charge_ramp.c index a408771f40..32e0d21ddb 100644 --- a/common/charge_ramp.c +++ b/common/charge_ramp.c @@ -18,16 +18,29 @@ test_mockable int chg_ramp_allowed(int port, int supplier) return 0; switch (supplier) { - /* Use ramping for USB-C DTS suppliers (debug accessory eg suzy-q). */ + /* + * Use ramping for USB-C DTS suppliers (debug accessory eg suzy-q). + * The suzy-q simply passes through the VBUS. The power supplier behind + * may be a SDP/CDP which requires ramping. + */ case CHARGE_SUPPLIER_TYPEC_DTS: return 1; /* - * Use HW ramping for USB-C chargers. Don't use SW ramping since the - * slow ramp causes issues with auto power on (b/169634979). + * Don't regulate the input voltage for USB-C chargers. It is + * unnecessary as the USB-C compliant adapters should never trigger it + * active. + * + * The USB-C spec defines their load curves should not be below + * 4.75V @0A and 4V @3A. We can't define the voltage regulation value + * higher than 4V since it limits the current reaching its max 3A. If + * we define the voltage regulation value lower than 4V, their load + * curves will never be below the voltage regulation line. + * + * Check go/charge_ramp_typec for detail. */ case CHARGE_SUPPLIER_PD: case CHARGE_SUPPLIER_TYPEC: - return IS_ENABLED(CONFIG_CHARGE_RAMP_HW); + return 0; /* default: fall through */ } diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index abb271cad4..75ffad576b 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -1200,7 +1200,12 @@ static int shutdown_on_critical_battery(void) switch (board_critical_shutdown_check(&curr)) { case CRITICAL_SHUTDOWN_HIBERNATE: if (IS_ENABLED(CONFIG_HIBERNATE)) { - if (power_get_state() == POWER_S3S5) + /* + * If the chipset is on its way down but not + * quite there yet, give it a little time to + * get there. + */ + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) sleep(1); CPRINTS("Hibernate due to critical battery"); cflush(); @@ -1208,7 +1213,11 @@ static int shutdown_on_critical_battery(void) } break; case CRITICAL_SHUTDOWN_CUTOFF: - if (power_get_state() == POWER_S3S5) + /* + * Give the chipset just a sec to get to off if + * it's trying. + */ + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) sleep(1); CPRINTS("Cutoff due to critical battery"); cflush(); diff --git a/common/device_event.c b/common/device_event.c index f7944ae930..748a98ae8f 100644 --- a/common/device_event.c +++ b/common/device_event.c @@ -17,8 +17,8 @@ #define CPUTS(outstr) cputs(CC_EVENTS, outstr) #define CPRINTS(format, args...) cprints(CC_EVENTS, format, ## args) -static uint32_t device_current_events; -static uint32_t device_enabled_events; +static atomic_t device_current_events; +static atomic_t device_enabled_events; uint32_t device_get_current_events(void) { @@ -40,7 +40,7 @@ void device_set_events(uint32_t mask) /* Ignore events that are not enabled */ mask &= device_enabled_events; - if ((device_current_events & mask) != mask) { + if (((uint32_t)device_current_events & mask) != mask) { CPRINTS("device event set 0x%08x", mask); } else { /* @@ -64,7 +64,7 @@ void device_set_events(uint32_t mask) void device_clear_events(uint32_t mask) { /* Only print if something's about to change */ - if (device_current_events & mask) + if ((uint32_t)device_current_events & mask) CPRINTS("device event clear 0x%08x", mask); atomic_clear_bits(&device_current_events, mask); diff --git a/common/dptf.c b/common/dptf.c index 33a42ba5af..28ccff34f2 100644 --- a/common/dptf.c +++ b/common/dptf.c @@ -28,6 +28,8 @@ static struct { int temp; /* degrees K, negative for disabled */ cond_t over; /* watch for crossings */ } dptf_threshold[TEMP_SENSOR_COUNT][DPTF_THRESHOLDS_PER_SENSOR]; +_STATIC_ASSERT(TEMP_SENSOR_COUNT > 0, + "CONFIG_PLATFORM_EC_DPTF enabled, but no temp sensors"); static void dptf_init(void) { @@ -43,14 +45,14 @@ static void dptf_init(void) DECLARE_HOOK(HOOK_INIT, dptf_init, HOOK_PRIO_DEFAULT); /* Keep track of which triggered sensor thresholds the AP has seen */ -static uint32_t dptf_seen; +static atomic_t dptf_seen; int dptf_query_next_sensor_event(void) { int id; for (id = 0; id < TEMP_SENSOR_COUNT; id++) - if (dptf_seen & BIT(id)) { /* atomic? */ + if ((uint32_t)dptf_seen & BIT(id)) { atomic_clear_bits(&dptf_seen, BIT(id)); return id; } @@ -196,7 +198,7 @@ static int command_dptftemp(int argc, char **argv) ccprintf(" %s\n", temp_sensors[id].name); } - ccprintf("AP seen mask: 0x%08x\n", dptf_seen); + ccprintf("AP seen mask: 0x%08x\n", (int)dptf_seen); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(dptftemp, command_dptftemp, diff --git a/common/ec_features.c b/common/ec_features.c index a7e097e733..2147c1b48a 100644 --- a/common/ec_features.c +++ b/common/ec_features.c @@ -147,6 +147,9 @@ uint32_t get_feature_flags1(void) #ifdef CONFIG_USB_MUX_AP_ACK_REQUEST | EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK) #endif +#ifdef CONFIG_POWER_S4_RESIDENCY + | EC_FEATURE_MASK_1(EC_FEATURE_S4_RESIDENCY) +#endif ; return board_override_feature_flags1(result); } diff --git a/common/fmap.c b/common/fmap.c index 47fa75f0e9..6bae9c7f85 100644 --- a/common/fmap.c +++ b/common/fmap.c @@ -13,7 +13,7 @@ /* * FMAP structs. - * See https://chromium.googlesource.com/chromiumos/third_party/flashmap/+/master/lib/fmap.h + * See https://chromium.googlesource.com/chromiumos/third_party/flashmap/+/HEAD/lib/fmap.h */ #define FMAP_NAMELEN 32 #define FMAP_SIGNATURE "__FMAP__" diff --git a/common/fpsensor/fpsensor.c b/common/fpsensor/fpsensor.c index 8d4f88c8eb..58b1bd71cf 100644 --- a/common/fpsensor/fpsensor.c +++ b/common/fpsensor/fpsensor.c @@ -754,7 +754,7 @@ static enum ec_error_list fp_console_action(uint32_t mode) while (tries--) { if (!(sensor_mode & FP_MODE_ANY_CAPTURE)) { - CPRINTS("done (events:%x)", fp_events); + CPRINTS("done (events:%x)", (int)fp_events); return 0; } usleep(100 * MSEC); diff --git a/common/fpsensor/fpsensor_state.c b/common/fpsensor/fpsensor_state.c index db64110b56..bd907e2c00 100644 --- a/common/fpsensor/fpsensor_state.c +++ b/common/fpsensor/fpsensor_state.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "atomic.h" #include "common.h" #include "cryptoc/util.h" #include "ec_commands.h" @@ -51,7 +52,7 @@ uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES]; /* Status of the FP encryption engine. */ static uint32_t fp_encryption_status; -uint32_t fp_events; +atomic_t fp_events; uint32_t sensor_mode; diff --git a/common/host_event_commands.c b/common/host_event_commands.c index 1856c88c37..532cfe3be3 100644 --- a/common/host_event_commands.c +++ b/common/host_event_commands.c @@ -264,7 +264,7 @@ static struct lazy_wake_masks { static void host_events_atomic_or(host_event_t *e, host_event_t m) { - uint32_t *ptr = (uint32_t *)e; + atomic_t *ptr = (atomic_t *)e; atomic_or(ptr, (uint32_t)m); #ifdef CONFIG_HOST_EVENT64 @@ -274,7 +274,7 @@ static void host_events_atomic_or(host_event_t *e, host_event_t m) static void host_events_atomic_clear(host_event_t *e, host_event_t m) { - uint32_t *ptr = (uint32_t *)e; + atomic_t *ptr = (atomic_t *)e; atomic_clear_bits(ptr, (uint32_t)m); #ifdef CONFIG_HOST_EVENT64 diff --git a/common/i2c_controller.c b/common/i2c_controller.c index 90d8a8da80..a99952943e 100644 --- a/common/i2c_controller.c +++ b/common/i2c_controller.c @@ -272,8 +272,8 @@ int i2c_xfer_unlocked(const int port, num_msgs++; } - - if (no_pec_af & ~I2C_ADDR_MASK) + /* Big endian flag is used in wrappers for this call */ + if (no_pec_af & ~(I2C_ADDR_MASK | I2C_FLAG_BIG_ENDIAN)) ccprintf("Ignoring flags from i2c addr_flags: %04x", no_pec_af); diff --git a/common/i2c_trace.c b/common/i2c_trace.c index 67b8864b22..e853a834bd 100644 --- a/common/i2c_trace.c +++ b/common/i2c_trace.c @@ -67,7 +67,11 @@ static int command_i2ctrace_list(void) ccprintf("%-2zd %d %-8s 0x%X", i, trace_entries[i].port, +#ifndef CONFIG_ZEPHYR i2c_port->name, +#else + "", +#endif /* CONFIG_ZEPHYR */ trace_entries[i].addr_lo); if (trace_entries[i].addr_hi != trace_entries[i].addr_lo) diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c index 071b441cfa..8d59fb0a33 100644 --- a/common/keyboard_scan.c +++ b/common/keyboard_scan.c @@ -140,9 +140,9 @@ void keyboard_scan_enable(int enable, enum kb_scan_disable_masks mask) { /* Access atomically */ if (enable) { - atomic_clear_bits((uint32_t *)&disable_scanning_mask, mask); + atomic_clear_bits((atomic_t *)&disable_scanning_mask, mask); } else { - atomic_or((uint32_t *)&disable_scanning_mask, mask); + atomic_or((atomic_t *)&disable_scanning_mask, mask); clear_typematic_key(); } @@ -954,9 +954,9 @@ int keyboard_factory_test_scan(void) gpio_set_flags_by_mask(port, 1 << id, GPIO_OUT_LOW); - for (j = 0; j < i; j++) { + for (j = 0; j < keyboard_factory_scan_pins_used; j++) { - if (keyboard_factory_scan_pins[j][0] < 0) + if (keyboard_factory_scan_pins[j][0] < 0 || i == j) continue; if (keyboard_raw_is_input_low( diff --git a/common/led_common.c b/common/led_common.c index 85879b148f..6c0e2ac426 100644 --- a/common/led_common.c +++ b/common/led_common.c @@ -47,6 +47,16 @@ int led_auto_control_is_enabled(enum ec_led_id led_id) return (led_auto_control_flags & LED_AUTO_CONTROL_FLAG(led_id)) != 0; } +__attribute__((weak)) void board_led_auto_control(void) +{ + /* + * The projects have only power led won't change the led + * state immediately as the auto command is called for + * they only check the led state while the power state + * is changed. + */ +} + static enum ec_status led_command_control(struct host_cmd_handler_args *args) { const struct ec_params_led_control *p = args->params; @@ -69,6 +79,8 @@ static enum ec_status led_command_control(struct host_cmd_handler_args *args) if (p->flags & EC_LED_FLAGS_AUTO) { led_auto_control(p->led_id, 1); + if (!IS_ENABLED(CONFIG_LED_ONOFF_STATES)) + board_led_auto_control(); } else { if (led_set_brightness(p->led_id, p->brightness) != EC_SUCCESS) return EC_RES_INVALID_PARAM; diff --git a/common/mkbp_fifo.c b/common/mkbp_fifo.c index 428d6412fc..c394d9fc77 100644 --- a/common/mkbp_fifo.c +++ b/common/mkbp_fifo.c @@ -28,7 +28,7 @@ static uint32_t fifo_start; /* first entry */ static uint32_t fifo_end; /* last entry */ -static uint32_t fifo_entries; /* number of existing entries */ +static atomic_t fifo_entries; /* number of existing entries */ static uint8_t fifo_max_depth = FIFO_DEPTH; static struct ec_response_get_next_event fifo[FIFO_DEPTH]; diff --git a/common/mock/usb_pd_dpm_mock.c b/common/mock/usb_pd_dpm_mock.c index 8b6fbaa30e..766cdcecf4 100644 --- a/common/mock/usb_pd_dpm_mock.c +++ b/common/mock/usb_pd_dpm_mock.c @@ -31,6 +31,10 @@ void dpm_init(int port) dpm[port].mode_exit_request = false; } +void dpm_mode_exit_complete(int port) +{ +} + void dpm_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, uint32_t *vdm) { diff --git a/common/motion_sense.c b/common/motion_sense.c index a9b15fd071..afffb02e78 100644 --- a/common/motion_sense.c +++ b/common/motion_sense.c @@ -73,7 +73,7 @@ STATIC_IF(CONFIG_MOTION_FILL_LPC_SENSE_DATA) void update_sense_data( uint8_t *lpc_status, int *psample_id); /* Flags to control whether to send an ODR change event for a sensor */ -static uint32_t odr_event_required; +static atomic_t odr_event_required; /* Whether or not the FIFO interrupt should be enabled (set from the AP). */ __maybe_unused static int fifo_int_enabled; diff --git a/common/ocpc.c b/common/ocpc.c index 3bc2a265d3..d63e6f8793 100644 --- a/common/ocpc.c +++ b/common/ocpc.c @@ -379,6 +379,7 @@ int ocpc_config_secondary_charger(int *desired_input_current, if (batt.desired_voltage) { if (((batt.voltage < batt_info->voltage_min) || ((batt.voltage < batt_info->voltage_normal) && + (current_ma >= 0) && (current_ma <= batt_info->precharge_current))) && (ph != PHASE_PRECHARGE)) { /* diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c index 0a597ad6bd..9ed8d8394d 100644 --- a/common/peripheral_charger.c +++ b/common/peripheral_charger.c @@ -22,7 +22,7 @@ #define CPRINTS(fmt, args...) cprints(CC_PCHG, "PCHG: " fmt, ##args) /* Currently only used for FW update. */ -static uint32_t pchg_host_events; +static atomic_t pchg_host_events; static void pchg_queue_event(struct pchg *ctx, enum pchg_event event) { diff --git a/common/system.c b/common/system.c index 5e18170b59..8f85e85e3c 100644 --- a/common/system.c +++ b/common/system.c @@ -72,11 +72,11 @@ STATIC_IF(CONFIG_HIBERNATE) uint32_t hibernate_seconds; STATIC_IF(CONFIG_HIBERNATE) uint32_t hibernate_microseconds; /* On-going actions preventing going into deep-sleep mode */ -uint32_t sleep_mask; +atomic_t sleep_mask; #ifdef CONFIG_LOW_POWER_IDLE_LIMITED /* Set it to prevent going into idle mode */ -uint32_t idle_disabled; +atomic_t idle_disabled; #endif /* SKU ID sourced from AP */ @@ -1491,7 +1491,7 @@ static int command_sleepmask(int argc, char **argv) } } #endif - ccprintf("sleep mask: %08x\n", sleep_mask); + ccprintf("sleep mask: %08x\n", (int)sleep_mask); return EC_SUCCESS; } diff --git a/common/thermal.c b/common/thermal.c index dba7334b74..50bf3e27f1 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -54,7 +54,7 @@ BUILD_ASSERT(EC_TEMP_THRESH_COUNT == 3); static cond_t cond_hot[EC_TEMP_THRESH_COUNT]; /* thermal sensor read delay */ -#if defined(CONFIG_TEMP_SENSOR_POWER_GPIO) && \ +#if defined(CONFIG_TEMP_SENSOR_POWER) && \ defined(CONFIG_TEMP_SENSOR_FIRST_READ_DELAY_MS) static int first_read_delay = CONFIG_TEMP_SENSOR_FIRST_READ_DELAY_MS; #endif @@ -77,7 +77,7 @@ static void thermal_control(void) #endif /* add delay to ensure thermal sensor is ready when EC boot */ -#if defined(CONFIG_TEMP_SENSOR_POWER_GPIO) && \ +#if defined(CONFIG_TEMP_SENSOR_POWER) && \ defined(CONFIG_TEMP_SENSOR_FIRST_READ_DELAY_MS) if (first_read_delay != 0) { msleep(first_read_delay); diff --git a/common/timer.c b/common/timer.c index 0490741c4c..0cb0d97289 100644 --- a/common/timer.c +++ b/common/timer.c @@ -49,7 +49,7 @@ static int timer_irq; static void expire_timer(task_id_t tskid) { /* we are done with this timer */ - atomic_clear_bits(&timer_running, 1 << tskid); + atomic_clear_bits((atomic_t *)&timer_running, 1 << tskid); /* wake up the taks waiting for this timer */ task_set_event(tskid, TASK_EVENT_TIMER); } @@ -142,7 +142,7 @@ int timer_arm(timestamp_t event, task_id_t tskid) return EC_ERROR_BUSY; timer_deadline[tskid] = event; - atomic_or(&timer_running, BIT(tskid)); + atomic_or((atomic_t *)&timer_running, BIT(tskid)); /* Modify the next event if needed */ if ((event.le.hi < now.le.hi) || @@ -156,7 +156,7 @@ void timer_cancel(task_id_t tskid) { ASSERT(tskid < TASK_ID_COUNT); - atomic_clear_bits(&timer_running, BIT(tskid)); + atomic_clear_bits((atomic_t *)&timer_running, BIT(tskid)); /* * Don't need to cancel the hardware timer interrupt, instead do * timer-related housekeeping when the next timer interrupt fires. diff --git a/common/usb_common.c b/common/usb_common.c index d5f42edca2..be54c62eff 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -132,7 +132,7 @@ int remote_flashing(int argc, char **argv) struct ec_params_usb_pd_rw_hash_entry rw_hash_table[RW_HASH_ENTRIES]; #endif /* CONFIG_COMMON_RUNTIME */ -static __maybe_unused uint32_t pd_host_event_status __aligned(4); +static __maybe_unused atomic_t pd_host_event_status __aligned(4); bool pd_firmware_upgrade_check_power_readiness(int port) { @@ -578,7 +578,7 @@ static void pd_send_hard_reset(int port) #ifdef CONFIG_USBC_OCP -static uint32_t port_oc_reset_req; +static atomic_t port_oc_reset_req; static void re_enable_ports(void) { @@ -838,7 +838,7 @@ void pd_set_vbus_discharge(int port, int enable) if (get_usb_pd_discharge() == USB_PD_DISCHARGE_GPIO) { gpio_discharge_vbus(port, enable); } else if (get_usb_pd_discharge() == USB_PD_DISCHARGE_TCPC) { -#ifdef CONFIG_USB_PD_DISCHARGE_PPC +#ifdef CONFIG_USB_PD_DISCHARGE_TCPC tcpc_discharge_vbus(port, enable); #endif } else if (get_usb_pd_discharge() == USB_PD_DISCHARGE_PPC) { @@ -852,7 +852,7 @@ void pd_set_vbus_discharge(int port, int enable) #endif /* CONFIG_USB_PD_DISCHARGE */ #ifdef CONFIG_USB_PD_TCPM_TCPCI -static uint32_t pd_ports_to_resume; +static atomic_t pd_ports_to_resume; static void resume_pd_port(void) { uint32_t port; diff --git a/common/usb_pd_host_cmd.c b/common/usb_pd_host_cmd.c index 47ec36ad5f..3cc3584e92 100644 --- a/common/usb_pd_host_cmd.c +++ b/common/usb_pd_host_cmd.c @@ -548,7 +548,7 @@ DECLARE_HOST_COMMAND(EC_CMD_PD_CONTROL, pd_control, EC_VER_MASK(0)); * Note: this variable must be aligned on 4-byte boundary because we pass the * address to atomic_ functions which use assembly to access them. */ -static uint32_t pd_host_event_status __aligned(4); +static atomic_t pd_host_event_status __aligned(4); static enum ec_status hc_pd_host_event_status(struct host_cmd_handler_args *args) diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index abf75e8004..94eb1a3aa7 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -243,9 +243,9 @@ static struct pd_protocol { /* Time to debounce exit low power mode */ uint64_t low_power_exit_time; /* Tasks to notify after TCPC has been reset */ - int tasks_waiting_on_reset; + atomic_t tasks_waiting_on_reset; /* Tasks preventing TCPC from entering low power mode */ - int tasks_preventing_lpm; + atomic_t tasks_preventing_lpm; #endif #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE diff --git a/common/usbc/dp_alt_mode.c b/common/usbc/dp_alt_mode.c index 2a532466ac..1ebc5d3d04 100644 --- a/common/usbc/dp_alt_mode.c +++ b/common/usbc/dp_alt_mode.c @@ -58,10 +58,12 @@ static const uint8_t state_vdm_cmd[DP_STATE_COUNT] = { */ #define DP_FLAG_RETRY BIT(0) -static uint32_t dpm_dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; +static atomic_t dpm_dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -#define DP_SET_FLAG(port, flag) atomic_or(&dpm_dp_flags[port], (flag)) -#define DP_CLR_FLAG(port, flag) atomic_clear_bits(&dpm_dp_flags[port], (flag)) +#define DP_SET_FLAG(port, flag) \ + atomic_or(&dpm_dp_flags[port], (flag)) +#define DP_CLR_FLAG(port, flag) \ + atomic_clear_bits(&dpm_dp_flags[port], (flag)) #define DP_CHK_FLAG(port, flag) (dpm_dp_flags[port] & (flag)) bool dp_is_active(int port) diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 36cfdf0f75..5deea53d5d 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -37,7 +37,7 @@ #define DPM_ATTENION_MAX_VDO 2 static struct { - uint32_t flags; + atomic_t flags; uint32_t vdm_attention[DPM_ATTENION_MAX_VDO]; int vdm_cnt; mutex_t vdm_attention_mutex; @@ -48,12 +48,16 @@ static struct { #define DPM_CHK_FLAG(port, flag) (dpm[(port)].flags & (flag)) /* Flags for internal DPM state */ -#define DPM_FLAG_MODE_ENTRY_DONE BIT(0) -#define DPM_FLAG_EXIT_REQUEST BIT(1) -#define DPM_FLAG_ENTER_DP BIT(2) -#define DPM_FLAG_ENTER_TBT BIT(3) -#define DPM_FLAG_ENTER_USB4 BIT(4) -#define DPM_FLAG_SEND_ATTENTION BIT(5) +#define DPM_FLAG_MODE_ENTRY_DONE BIT(0) +#define DPM_FLAG_EXIT_REQUEST BIT(1) +#define DPM_FLAG_ENTER_DP BIT(2) +#define DPM_FLAG_ENTER_TBT BIT(3) +#define DPM_FLAG_ENTER_USB4 BIT(4) +#define DPM_FLAG_ENTER_ANY (DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT \ + | DPM_FLAG_ENTER_USB4) +#define DPM_FLAG_SEND_ATTENTION BIT(5) +#define DPM_FLAG_DATA_RESET_REQUESTED BIT(6) +#define DPM_FLAG_DATA_RESET_DONE BIT(7) #ifdef CONFIG_ZEPHYR static int init_vdm_attention_mutex(const struct device *dev) @@ -134,6 +138,7 @@ enum ec_status pd_request_enter_mode(int port, enum typec_mode mode) DPM_CLR_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE); DPM_CLR_FLAG(port, DPM_FLAG_EXIT_REQUEST); + DPM_CLR_FLAG(port, DPM_FLAG_DATA_RESET_DONE); return EC_RES_SUCCESS; } @@ -143,6 +148,12 @@ void dpm_init(int port) dpm[port].flags = 0; } +void dpm_mode_exit_complete(int port) +{ + DPM_CLR_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE | DPM_FLAG_EXIT_REQUEST | + DPM_FLAG_SEND_ATTENTION); +} + static void dpm_set_mode_entry_done(int port) { DPM_SET_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE); @@ -155,6 +166,13 @@ void dpm_set_mode_exit_request(int port) DPM_SET_FLAG(port, DPM_FLAG_EXIT_REQUEST); } +void dpm_data_reset_complete(int port) +{ + DPM_CLR_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED); + DPM_SET_FLAG(port, DPM_FLAG_DATA_RESET_DONE); + DPM_CLR_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE); +} + static void dpm_clear_mode_exit_request(int port) { DPM_CLR_FLAG(port, DPM_FLAG_EXIT_REQUEST); @@ -287,6 +305,22 @@ static void dpm_attempt_mode_entry(int port) if (IS_ENABLED(CONFIG_USBC_SS_MUX) && !usb_mux_set_completed(port)) return; + if (IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) && + IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && + DPM_CHK_FLAG(port, DPM_FLAG_ENTER_ANY) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { + pd_dpm_request(port, DPM_REQUEST_DATA_RESET); + DPM_SET_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED); + return; + } + + if (IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) && + IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { + return; + } + /* Check if port, port partner and cable support USB4. */ if (IS_ENABLED(CONFIG_USB_PD_USB4) && board_is_tbt_usb4_port(port) && @@ -469,11 +503,11 @@ static uint32_t max_current_claimed; K_MUTEX_DEFINE(max_current_claimed_lock); /* Ports with PD sink needing > 1.5 A */ -static uint32_t sink_max_pdo_requested; +static atomic_t sink_max_pdo_requested; /* Ports with FRS source needing > 1.5 A */ -static uint32_t source_frs_max_requested; +static atomic_t source_frs_max_requested; /* Ports with non-PD sinks, so current requirements are unknown */ -static uint32_t non_pd_sink_max_requested; +static atomic_t non_pd_sink_max_requested; #define LOWEST_PORT(p) __builtin_ctz(p) /* Undefined behavior if p == 0 */ @@ -674,8 +708,8 @@ void dpm_remove_sink(int port) if (CONFIG_USB_PD_3A_PORTS == 0) return; - if (!(BIT(port) & sink_max_pdo_requested) && - !(BIT(port) & non_pd_sink_max_requested)) + if (!(BIT(port) & (uint32_t)sink_max_pdo_requested) && + !(BIT(port) & (uint32_t)non_pd_sink_max_requested)) return; atomic_clear_bits(&sink_max_pdo_requested, BIT(port)); @@ -696,7 +730,7 @@ void dpm_remove_source(int port) if (!IS_ENABLED(CONFIG_USB_PD_FRS)) return; - if (!(BIT(port) & source_frs_max_requested)) + if (!(BIT(port) & (uint32_t)source_frs_max_requested)) return; atomic_clear_bits(&source_frs_max_requested, BIT(port)); diff --git a/common/usbc/usb_pd_timer.c b/common/usbc/usb_pd_timer.c index 97aa699737..4d284024be 100644 --- a/common/usbc/usb_pd_timer.c +++ b/common/usbc/usb_pd_timer.c @@ -21,30 +21,35 @@ #define NO_TIMEOUT (-1) #define EXPIRE_NOW (0) -#define PD_SET_ACTIVE(p, m) pd_timer_atomic_op( \ - atomic_or, \ - timer_active[p], \ +#define PD_SET_ACTIVE(p, m) pd_timer_atomic_op( \ + atomic_or, \ + (atomic_t *)timer_active[p], \ (m)) -#define PD_CLR_ACTIVE(p, m) pd_timer_atomic_op( \ - atomic_clear_bits, \ - timer_active[p], \ +#define PD_CLR_ACTIVE(p, m) pd_timer_atomic_op( \ + atomic_clear_bits, \ + (atomic_t *)timer_active[p], \ (m)) -#define PD_CHK_ACTIVE(p, m) ((timer_active[p][0] & ((m) >> 32)) | \ +#define PD_CHK_ACTIVE(p, m) ((timer_active[p][0] & ((m) >> 32)) | \ (timer_active[p][1] & (m))) -#define PD_SET_DISABLED(p, m) pd_timer_atomic_op( \ - atomic_or, \ - timer_disabled[p], \ +#define PD_SET_DISABLED(p, m) pd_timer_atomic_op( \ + atomic_or, \ + (atomic_t *)timer_disabled[p], \ (m)) -#define PD_CLR_DISABLED(p, m) pd_timer_atomic_op( \ - atomic_clear_bits, \ - timer_disabled[p], \ +#define PD_CLR_DISABLED(p, m) pd_timer_atomic_op( \ + atomic_clear_bits, \ + (atomic_t *)timer_disabled[p], \ (m)) #define PD_CHK_DISABLED(p, m) ((timer_disabled[p][0] & ((m) >> 32)) | \ (timer_disabled[p][1] & (m))) #define TIMER_FIELD_NUM_UINT32S 2 +/* + * Use uint32_t for timer_active and timer_disabled instead of atomic_t, + * because mixing types signed and unsigned around shifting may lead to + * undefined behavior. + */ test_mockable_static uint32_t timer_active[MAX_PD_PORTS][TIMER_FIELD_NUM_UINT32S]; test_mockable_static @@ -77,6 +82,9 @@ __maybe_unused static __const_data const char * const pd_timer_names[] = { [PE_TIMER_VCONN_ON] = "PE-VCONN_ON", [PE_TIMER_VDM_RESPONSE] = "PE-VDM_RESPONSE", [PE_TIMER_WAIT_AND_ADD_JITTER] = "PE-WAIT_AND_ADD_JITTER", + [PE_TIMER_VCONN_DISCHARGE] = "PE-VCONN_DISCHARGE", + [PE_TIMER_VCONN_REAPPLIED] = "PE-VCONN_REAPPLIED", + [PE_TIMER_DATA_RESET_FAIL] = "PE-DATA_RESET_FAIL", [PR_TIMER_CHUNK_SENDER_REQUEST] = "PR-CHUNK_SENDER_REQUEST", [PR_TIMER_CHUNK_SENDER_RESPONSE] = "PR-CHUNK_SENDER_RESPONSE", @@ -116,9 +124,9 @@ __maybe_unused static __const_data const char * const pd_timer_names[] = { */ test_mockable_static void pd_timer_atomic_op( atomic_val_t (*op)(atomic_t*, atomic_val_t), - uint32_t *const timer_field, const uint64_t mask_val) + atomic_t *const timer_field, const uint64_t mask_val) { - uint32_t *atomic_timer_field; + atomic_t *atomic_timer_field; union mask64_t { struct { #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 431dcdc9af..60a2255215 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -20,9 +20,11 @@ #include "task.h" #include "tcpm/tcpm.h" #include "util.h" +#include "usb_charge.h" #include "usb_common.h" #include "usb_dp_alt_mode.h" #include "usb_mode.h" +#include "usb_mux.h" #include "usb_pd_dpm.h" #include "usb_pd_policy.h" #include "usb_pd.h" @@ -153,6 +155,8 @@ #define PE_FLAGS_MSG_DISCARDED BIT(29) /* FLAG to note that hard reset can't be performed due to battery low */ #define PE_FLAGS_SNK_WAITING_BATT BIT(30) +/* FLAG to note that a data reset is complete */ +#define PE_FLAGS_DATA_RESET_COMPLETE BIT(31) /* Message flags which should not persist on returning to ready state */ #define PE_FLAGS_READY_CLR (PE_FLAGS_LOCALLY_INITIATED_AMS \ @@ -171,7 +175,6 @@ */ #define PE_CHK_REPLY(port) (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED) && \ !PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) - /* 6.7.3 Hard Reset Counter */ #define N_HARD_RESET_COUNT 2 @@ -319,6 +322,13 @@ enum usb_pe_state { PE_DR_SRC_GET_SOURCE_CAP, /* PD3.0 only states below here*/ +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + /* DFP Data Reset States */ + PE_DDR_SEND_DATA_RESET, + PE_DDR_WAIT_FOR_VCONN_OFF, + PE_DDR_PERFORM_DATA_RESET, +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ + PE_FRS_SNK_SRC_START_AMS, PE_GIVE_BATTERY_CAP, PE_GIVE_BATTERY_STATUS, @@ -452,6 +462,11 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { #ifdef CONFIG_USBC_VCONN [PE_VCS_FORCE_VCONN] = "PE_VCS_Force_Vconn", #endif +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + [PE_DDR_SEND_DATA_RESET] = "PE_DDR_Send_Data_Reset", + [PE_DDR_WAIT_FOR_VCONN_OFF] = "PE_DDR_Wait_For_VCONN_Off", + [PE_DDR_PERFORM_DATA_RESET] = "PE_DDR_Perform_Data_Reset", +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ #endif /* CONFIG_USB_PD_REV30 */ }; @@ -562,9 +577,9 @@ static struct policy_engine { /* current port data role (DFP or UFP) */ enum pd_data_role data_role; /* state machine flags */ - uint32_t flags; + atomic_t flags; /* Device Policy Manager Request */ - uint32_t dpm_request; + atomic_t dpm_request; uint32_t dpm_curr_request; /* last requested voltage PDO index */ int requested_idx; @@ -573,7 +588,7 @@ static struct policy_engine { * Port events - PD_STATUS_EVENT_* values * Set from PD task but may be cleared by host command */ - uint32_t events; + atomic_t events; /* port address where soft resets are sent */ enum tcpci_msg_type soft_reset_sop; @@ -1172,6 +1187,11 @@ void pe_report_error(int port, enum pe_error e, enum tcpci_msg_type type) get_state_pe(port) == PE_SRC_DISCOVERY || get_state_pe(port) == PE_VCS_CBL_SEND_SOFT_RESET || get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) || +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + get_state_pe(port) == PE_DDR_SEND_DATA_RESET || + get_state_pe(port) == PE_DDR_WAIT_FOR_VCONN_OFF || + get_state_pe(port) == PE_DDR_PERFORM_DATA_RESET || +#endif (pe_in_frs_mode(port) && get_state_pe(port) == PE_PRS_SNK_SRC_SEND_SWAP) ) { @@ -1529,7 +1549,21 @@ static bool common_src_snk_dpm_requests(int port) set_state_pe(port, PE_VCS_CBL_SEND_SOFT_RESET); return true; } +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_DATA_RESET)) { + if (prl_get_rev(port, TCPCI_MSG_SOP) < PD_REV30) { + dpm_data_reset_complete(port); + return false; + } + pe_set_dpm_curr_request(port, DPM_REQUEST_DATA_RESET); + if (pe[port].data_role == PD_ROLE_DFP) + set_state_pe(port, PE_DDR_SEND_DATA_RESET); + else + return false; + return true; + } +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ return false; } @@ -2167,6 +2201,7 @@ static void pe_src_startup_entry(int port) /* Clear port discovery/mode flags */ pd_dfp_discovery_init(port); pd_dfp_mode_init(port); + dpm_init(port); pe[port].ama_vdo = PD_VDO_INVALID; pe[port].vpd_vdo = PD_VDO_INVALID; pe[port].discover_identity_counter = 0; @@ -3021,6 +3056,7 @@ static void pe_snk_startup_entry(int port) /* Clear port discovery/mode flags */ pd_dfp_discovery_init(port); pd_dfp_mode_init(port); + dpm_init(port); pe[port].discover_identity_counter = 0; /* Reset dr swap attempt counter */ @@ -6974,6 +7010,255 @@ static void pe_dr_src_get_source_cap_exit(int port) pe_sender_response_msg_exit(port); } +#ifdef CONFIG_USB_PD_DATA_RESET_MSG +/* + * PE_DDR_Send_Data_Reset + * See PD rev 3.1, v. 1.2, Figure 8-88. + */ +static void pe_ddr_send_data_reset_entry(int port) +{ + print_current_state(port); + /* Send Data Reset message */ + send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_DATA_RESET); + pe_sender_response_msg_entry(port); +} + +static void pe_ddr_send_data_reset_run(int port) +{ + enum pe_msg_check msg_check = pe_sender_response_msg_run(port); + + /* Handle Discarded message, return to PE_SNK/SRC_READY */ + if (msg_check & PE_MSG_DISCARDED) { + pe_set_ready_state(port); + return; + } else if (msg_check == PE_MSG_SEND_PENDING) { + /* Wait until message is sent */ + return; + } + + /* + * Transition to the next Data Reset state after receiving Accept. + * Return to the ready state after receiving Not Supported. After + * receiving Reject or any other message type (Protocol Error), + * transition to Error Recovery. + */ + if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + const uint32_t hdr = rx_emsg[port].header; + + PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); + + if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && + PD_HEADER_CNT(hdr) == 0 && + !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_ACCEPT) { + /* + * Start DataResetFailTimer NOTE: This timer continues + * to run in every state until it is stopped or it times + * out. + */ + pd_timer_enable(port, PE_TIMER_DATA_RESET_FAIL, + PD_T_DATA_RESET_FAIL); + set_state_pe(port, tc_is_vconn_src(port) ? + PE_DDR_PERFORM_DATA_RESET : + PE_DDR_WAIT_FOR_VCONN_OFF); + return; + } else if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && + PD_HEADER_CNT(hdr) == 0 && + !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_NOT_SUPPORTED) { + /* Just pretend it worked. */ + dpm_data_reset_complete(port); + pe_set_ready_state(port); + return; + } + + /* Otherwise, it's a protocol error. */ + PE_SET_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + } + + if (pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE) || + PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + return; + } +} + +static void pe_ddr_send_data_reset_exit(int port) +{ + pe_sender_response_msg_exit(port); +} + +/* + * PE_DDR_Wait_For_VCONN_Off + */ +static void pe_ddr_wait_for_vconn_off_entry(int port) +{ + print_current_state(port); + /* Initialize and start VCONNDischargeTimer */ + pd_timer_enable(port, PE_TIMER_VCONN_DISCHARGE, PD_T_VCONN_DISCHARGE); +} + +static void pe_ddr_wait_for_vconn_off_run(int port) +{ + if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + const uint32_t hdr = rx_emsg[port].header; + + PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); + + if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && + PD_HEADER_CNT(hdr) == 0 && + !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_PS_RDY) { + /* PS_RDY message received */ + pd_timer_enable(port, PE_TIMER_VCONN_REAPPLIED, + PD_T_VCONN_REAPPLIED); + set_state_pe(port, PE_DDR_PERFORM_DATA_RESET); + return; + } + + /* Otherwise, it's a protocol error. */ + PE_SET_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + } + + if (pd_timer_is_expired(port, PE_TIMER_VCONN_DISCHARGE) || + PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + return; + } +} + +static void pe_ddr_wait_for_vconn_off_exit(int port) +{ + pd_timer_disable(port, PE_TIMER_VCONN_DISCHARGE); +} + +/* + * PE_DDR_Perform_Data_Reset + * See PD rev 3.1, v. 1.2, section 6.3.14. + */ +static void pe_ddr_perform_data_reset_entry(int port) +{ + print_current_state(port); + + /* + * 1) The DFP shall: + * a) Disconnect the Port’s USB 2.0 D+/D- signals. + * b) If operating in USB 3.2 remove the port’s Rx Terminations. + * c) If operating in [USB4] drive the port’s SBTX to a logic low. + */ + usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, + polarity_rm_dts(pd_get_polarity(port))); + + /* 2) Both the DFP and UFP Shall exit all Alternate Modes if any. */ + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPCI_MSG_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPCI_MSG_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPCI_MSG_SOP_PRIME_PRIME, 0, 0); + } + + /* 3) Reset the cable */ + /* + * TODO(b/141363146): The PD spec is ambiguous about which state the PE + * should be in during the cable reset (step 3 in section 6.3.14). If + * the DFP is not the initial VCONN Source, the cable reset presumably + * starts in PE_DDR_Wait_for_VCONN_Off and finishes in + * PE_DDR_Perform_Data_Reset. To be consistent with the steps in 6.3.14, + * that would imply that steps 1 and 2 take place in + * PE_DDR_Send_Data_Reset. However, this would be inconsistent with the, + * "Tell the Policy Manager to Perform Data Reset," action in + * PE_DDR_Perform_Data_Reset in figure 8-88, DFP Data_Reset Message + * State Diagram, since the Data Reset process would have had to start + * before then. Resolve this ambiguity and update this implementation. + */ + if (IS_ENABLED(CONFIG_USBC_VCONN) && tc_is_vconn_src(port)) + pd_request_vconn_swap_off(port); + else + PE_SET_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE); +} + +static void pe_ddr_perform_data_reset_run(int port) +{ + /* + * PE_FLAGS_VCONN_SWAP_COMPLETE may be set in 2 cases: + * a) If the PE requested to turn VCONN off while entering this state, + * i.e. if the TCPM was VCONN Source at that time. If the TCPM did not + * start out as VCONN Source, then PE_DDR_Wait_For_VCONN_Off will have + * already started the VCONN reapplied timer. + * b) When this state requests to turn VCONN on after tVCONNReapplied + * expires. At this point, the Data Reset process is complete. + */ + if (IS_ENABLED(CONFIG_USBC_VCONN) && !tc_is_vconn_src(port) && + PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE)) { + PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE); + pd_timer_enable(port, PE_TIMER_VCONN_REAPPLIED, + PD_T_VCONN_REAPPLIED); + } else if (IS_ENABLED(CONFIG_USBC_VCONN) && + pd_timer_is_expired(port, PE_TIMER_VCONN_REAPPLIED)) { + pd_request_vconn_swap_on(port); + pd_timer_disable(port, PE_TIMER_VCONN_REAPPLIED); + + /* + * 4) After tDataReset the DFP shall: + * a) Reconnect the [USB 2.0] D+/D- signals + * b) If the Port was operating in [USB 3.2] or [USB4] + * reapply the port’s Rx Terminations + * TODO: Section 6.3.14 implies that tDataReset is a minimum + * time for the DFP to leave the lines disconnected during Data + * Reset, possibly starting after the cable reset. Section + * 6.6.10.2 implies that tDataReset is the maximum time for the + * DFP to send Data_Reset_Complete after receiving Accept. These + * interpretations are mutually exclusive. Resolve that + * ambiguity and update this implementation. + */ + usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, + polarity_rm_dts(pd_get_polarity(port))); + } else if (IS_ENABLED(CONFIG_USBC_VCONN) && + PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE) && + tc_is_vconn_src(port)) { + PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE); + PE_SET_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE); + } else if (PE_CHK_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE) && + !pd_timer_is_disabled(port, PE_TIMER_DATA_RESET_FAIL)) { + pd_timer_disable(port, PE_TIMER_DATA_RESET_FAIL); + send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_DATA_RESET_COMPLETE); + } else if (PE_CHK_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE)) { + /* + * There is no specified response to Data_Reset_Complete, but + * make sure the port partner receives it before returning to a + * ready state. + */ + if (PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + else if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) + pe_set_ready_state(port); + return; + } else if (pd_timer_is_expired(port, PE_TIMER_DATA_RESET_FAIL) || + PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + return; + } + + /* + * No messages are expected, so any received would be a protocol error. + */ + if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + } +} + +static void pe_ddr_perform_data_reset_exit(int port) +{ + pd_timer_disable(port, PE_TIMER_VCONN_REAPPLIED); + pd_timer_disable(port, PE_TIMER_DATA_RESET_FAIL); + PE_CLR_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE); + dpm_data_reset_complete(port); +} +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ + const uint32_t * const pd_get_src_caps(int port) { return pe[port].src_caps; @@ -6998,7 +7283,7 @@ uint8_t pd_get_src_cap_cnt(int port) } /* Track access to the PD discovery structures during HC execution */ -uint32_t task_access[CONFIG_USB_PD_PORT_MAX_COUNT][DISCOVERY_TYPE_COUNT]; +atomic_t task_access[CONFIG_USB_PD_PORT_MAX_COUNT][DISCOVERY_TYPE_COUNT]; void pd_dfp_discovery_init(int port) { @@ -7022,7 +7307,7 @@ void pd_dfp_mode_init(int port) memset(pe[port].partner_amodes, 0, sizeof(pe[port].partner_amodes)); /* Reset the DPM and DP modules to enable alternate mode entry. */ - dpm_init(port); + dpm_mode_exit_complete(port); dp_init(port); if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)) @@ -7446,6 +7731,23 @@ static __const_data const struct usb_state pe_states[] = { .exit = pe_vcs_force_vconn_exit, }, #endif /* CONFIG_USBC_VCONN */ +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + [PE_DDR_SEND_DATA_RESET] = { + .entry = pe_ddr_send_data_reset_entry, + .run = pe_ddr_send_data_reset_run, + .exit = pe_ddr_send_data_reset_exit, + }, + [PE_DDR_WAIT_FOR_VCONN_OFF] = { + .entry = pe_ddr_wait_for_vconn_off_entry, + .run = pe_ddr_wait_for_vconn_off_run, + .exit = pe_ddr_wait_for_vconn_off_exit, + }, + [PE_DDR_PERFORM_DATA_RESET] = { + .entry = pe_ddr_perform_data_reset_entry, + .run = pe_ddr_perform_data_reset_run, + .exit = pe_ddr_perform_data_reset_exit, + }, +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ #endif /* CONFIG_USB_PD_REV30 */ }; diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index b85a7ee553..d9c3849f58 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -294,7 +294,7 @@ static struct rx_chunked { /* state machine context */ struct sm_ctx ctx; /* PRL_FLAGS */ - uint32_t flags; + atomic_t flags; /* error to report when moving to rch_report_error state */ enum pe_error error; } rch[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -304,7 +304,7 @@ static struct tx_chunked { /* state machine context */ struct sm_ctx ctx; /* state machine flags */ - uint32_t flags; + atomic_t flags; /* error to report when moving to tch_report_error state */ enum pe_error error; } tch[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -322,7 +322,7 @@ static struct protocol_layer_tx { /* state machine context */ struct sm_ctx ctx; /* state machine flags */ - uint32_t flags; + atomic_t flags; /* last message type we transmitted */ enum tcpci_msg_type last_xmit_type; /* message id counters for all 6 port partners */ @@ -336,13 +336,13 @@ static struct protocol_hard_reset { /* state machine context */ struct sm_ctx ctx; /* state machine flags */ - uint32_t flags; + atomic_t flags; } prl_hr[CONFIG_USB_PD_PORT_MAX_COUNT]; /* Chunking Message Object */ static struct pd_message { /* message status flags */ - uint32_t flags; + atomic_t flags; /* SOP* */ enum tcpci_msg_type xmit_type; /* type of message */ diff --git a/common/usbc/usb_retimer_fw_update.c b/common/usbc/usb_retimer_fw_update.c index 1ff198c78f..87a8f786c5 100644 --- a/common/usbc/usb_retimer_fw_update.c +++ b/common/usbc/usb_retimer_fw_update.c @@ -96,8 +96,29 @@ static inline mux_state_t retimer_fw_update_usb_mux_get(int port) return usb_mux_get(port) & USB_RETIMER_FW_UPDATE_MUX_MASK; } +/* Allow mux results to be filled in during HOOKS if needed */ +static void last_result_mux_get(void); +DECLARE_DEFERRED(last_result_mux_get); + +static void last_result_mux_get(void) +{ + if (!usb_mux_set_completed(cur_port)) { + hook_call_deferred(&last_result_mux_get_data, 20 * MSEC); + return; + } + + last_result = retimer_fw_update_usb_mux_get(cur_port); +} + void usb_retimer_fw_update_process_op_cb(int port) { + bool result_mux_get = false; + + if (port != cur_port) { + CPRINTS("Unexpected FW op: port %d, cur %d", port, cur_port); + return; + } + switch (last_op) { case USB_RETIMER_FW_UPDATE_SUSPEND_PD: last_result = 0; @@ -123,30 +144,37 @@ void usb_retimer_fw_update_process_op_cb(int port) pd_set_suspend(port, RESUME); break; case USB_RETIMER_FW_UPDATE_GET_MUX: - last_result = retimer_fw_update_usb_mux_get(port); + result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_SET_USB: usb_mux_set(port, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT, pd_get_polarity(port)); - last_result = retimer_fw_update_usb_mux_get(port); + result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_SET_SAFE: usb_mux_set_safe_mode(port); - last_result = retimer_fw_update_usb_mux_get(port); + result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_SET_TBT: usb_mux_set(port, USB_PD_MUX_TBT_COMPAT_ENABLED, USB_SWITCH_CONNECT, pd_get_polarity(port)); - last_result = retimer_fw_update_usb_mux_get(port); + result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_DISCONNECT: usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, pd_get_polarity(port)); - last_result = retimer_fw_update_usb_mux_get(port); + result_mux_get = true; break; default: break; } + + /* + * Fill in our mux result if available, or set up a deferred retrieval + * if the set is still pending. + */ + if (result_mux_get) + last_result_mux_get(); } void usb_retimer_fw_update_process_op(int port, int op) @@ -158,6 +186,7 @@ void usb_retimer_fw_update_process_op(int port, int op) * not change cur_port if retimer scan is in progress */ last_op = op; + cur_port = port; switch (op) { case USB_RETIMER_FW_UPDATE_QUERY_PORT: @@ -169,7 +198,6 @@ void usb_retimer_fw_update_process_op(int port, int op) break; case USB_RETIMER_FW_UPDATE_SUSPEND_PD: case USB_RETIMER_FW_UPDATE_RESUME_PD: - cur_port = port; tc_usb_firmware_fw_update_run(port); break; case USB_RETIMER_FW_UPDATE_SET_USB: diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 3fa9528699..726958ba03 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -401,7 +401,7 @@ static struct type_c { * else they're disabled if bits PD_DISABLED_NO_CONNECTION or * PD_DISABLED_BY_POLICY are set. */ - uint32_t pd_disabled_mask; + atomic_t pd_disabled_mask; /* * Timer for handling TOGGLE_OFF/FORCE_SINK mode when auto-toggle * enabled. See drp_auto_toggle_next_state() for details. @@ -414,13 +414,13 @@ static struct type_c { /* Port polarity */ enum tcpc_cc_polarity polarity; /* port flags, see TC_FLAGS_* */ - uint32_t flags; + atomic_t flags; /* The cc state */ enum pd_cc_states cc_state; /* Tasks to notify after TCPC has been reset */ - int tasks_waiting_on_reset; + atomic_t tasks_waiting_on_reset; /* Tasks preventing TCPC from entering low power mode */ - int tasks_preventing_lpm; + atomic_t tasks_preventing_lpm; /* Voltage on CC pin */ enum tcpc_cc_voltage_status cc_voltage; /* Type-C current */ @@ -457,7 +457,7 @@ static void set_state_tc(const int port, const enum usb_tc_state new_state); test_export_static enum usb_tc_state get_state_tc(const int port); /* Enable variable for Try.SRC states */ -static uint32_t pd_try_src; +static atomic_t pd_try_src; static volatile enum try_src_override_t pd_try_src_override; static void pd_update_try_source(void); @@ -825,6 +825,10 @@ int tc_is_attached_snk(int port) return IS_ATTACHED_SNK(port); } +__overridable void tc_update_pd_sleep_mask(int port) +{ +} + void tc_pd_connection(int port, int en) { if (en) { @@ -836,9 +840,10 @@ void tc_pd_connection(int port, int en) TC_SET_FLAG(port, TC_FLAGS_PARTNER_PD_CAPABLE); /* If a PD device is attached then disable deep sleep */ if (IS_ENABLED(CONFIG_LOW_POWER_IDLE) && - !IS_ENABLED(CONFIG_USB_PD_TCPC_ON_CHIP)) { + IS_ENABLED(CONFIG_USB_PD_TCPC_ON_CHIP)) + tc_update_pd_sleep_mask(port); + else if (IS_ENABLED(CONFIG_LOW_POWER_IDLE)) disable_sleep(SLEEP_MASK_USB_PD); - } /* * Update the mux state, only when the PD capable flag @@ -852,7 +857,9 @@ void tc_pd_connection(int port, int en) TC_CLR_FLAG(port, TC_FLAGS_PARTNER_PD_CAPABLE); /* If a PD device isn't attached then enable deep sleep */ if (IS_ENABLED(CONFIG_LOW_POWER_IDLE) && - !IS_ENABLED(CONFIG_USB_PD_TCPC_ON_CHIP)) { + IS_ENABLED(CONFIG_USB_PD_TCPC_ON_CHIP)) + tc_update_pd_sleep_mask(port); + else if (IS_ENABLED(CONFIG_LOW_POWER_IDLE)) { int i; /* If all ports are not connected, allow the sleep */ diff --git a/common/usbc_ocp.c b/common/usbc_ocp.c index e20cf9f1f8..c7c977bf12 100644 --- a/common/usbc_ocp.c +++ b/common/usbc_ocp.c @@ -42,7 +42,7 @@ static uint8_t oc_event_cnt_tbl[CONFIG_USB_PD_PORT_MAX_COUNT]; /* A flag for ports with sink device connected. */ -static uint32_t snk_connected_ports; +static atomic_t snk_connected_ports; static void clear_oc_tbl(void) { @@ -53,7 +53,7 @@ static void clear_oc_tbl(void) * Only clear the table if the port partner is no longer * attached after debouncing. */ - if ((!(BIT(port) & snk_connected_ports)) && + if ((!(BIT(port) & (uint32_t)snk_connected_ports)) && oc_event_cnt_tbl[port]) { oc_event_cnt_tbl[port] = 0; CPRINTS("C%d: OC events cleared", port); diff --git a/core/cortex-m/atomic.h b/core/cortex-m/atomic.h index e9b96f6fd5..ce183465e8 100644 --- a/core/cortex-m/atomic.h +++ b/core/cortex-m/atomic.h @@ -8,11 +8,9 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits) { return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST); diff --git a/core/cortex-m/cpu.h b/core/cortex-m/cpu.h index 0b03302bfc..dbad99650c 100644 --- a/core/cortex-m/cpu.h +++ b/core/cortex-m/cpu.h @@ -70,6 +70,26 @@ enum { #define CPU_SCB_DCISW CPUREG(0xe000ef60) #define CPU_SCB_DCCISW CPUREG(0xe000ef74) +/* Bitfield values for EXC_RETURN. */ +#define EXC_RETURN_ES_MASK BIT(0) +#define EXC_RETURN_ES_NON_SECURE 0 +#define EXC_RETURN_ES_SECURE BIT(0) +#define EXC_RETURN_SPSEL_MASK BIT(2) +#define EXC_RETURN_SPSEL_MSP 0 +#define EXC_RETURN_SPSEL_PSP BIT(2) +#define EXC_RETURN_MODE_MASK BIT(3) +#define EXC_RETURN_MODE_HANDLER 0 +#define EXC_RETURN_MODE_THREAD BIT(3) +#define EXC_RETURN_FTYPE_MASK BIT(4) +#define EXC_RETURN_FTYPE_ON 0 +#define EXC_RETURN_FTYPE_OFF BIT(4) +#define EXC_RETURN_DCRS_MASK BIT(5) +#define EXC_RETURN_DCRS_OFF 0 +#define EXC_RETURN_DCRS_ON BIT(5) +#define EXC_RETURN_S_MASK BIT(6) +#define EXC_RETURN_S_NON_SECURE 0 +#define EXC_RETURN_S_SECURE BIT(6) + /* Set up the cpu to detect faults */ void cpu_init(void); /* Enable the CPU I-cache and D-cache if they are not already enabled */ diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c index d8e82a4e5d..2f71080392 100644 --- a/core/cortex-m/panic.c +++ b/core/cortex-m/panic.c @@ -182,13 +182,13 @@ static uint32_t get_exception_frame_size(const struct panic_data *pdata) /* CPU uses xPSR[9] to indicate whether it padded the stack for * alignment or not. */ - if (pdata->cm.frame[7] & BIT(9)) + if (pdata->cm.frame[CORTEX_PANIC_FRAME_REGISTER_PSR] & BIT(9)) frame_size += sizeof(uint32_t); #ifdef CONFIG_FPU /* CPU uses EXC_RETURN[4] to indicate whether it stored extended * frame for FPU or not. */ - if (!(pdata->cm.regs[11] & BIT(4))) + if (!(pdata->cm.regs[CORTEX_PANIC_REGISTER_LR] & BIT(4))) frame_size += 18 * sizeof(uint32_t); #endif @@ -202,9 +202,10 @@ static uint32_t get_exception_frame_size(const struct panic_data *pdata) */ static uint32_t get_process_stack_position(const struct panic_data *pdata) { - uint32_t psp = pdata->cm.regs[0]; + uint32_t psp = pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP]; - if (!is_frame_in_handler_stack(pdata->cm.regs[11])) + if (!is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR])) psp += get_exception_frame_size(pdata); return psp; @@ -260,8 +261,8 @@ void panic_data_print(const struct panic_data *pdata) { const uint32_t *lregs = pdata->cm.regs; const uint32_t *sregs = NULL; - const int32_t in_handler = - is_frame_in_handler_stack(pdata->cm.regs[11]); + const int32_t in_handler = is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR]); int i; if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) @@ -269,17 +270,20 @@ void panic_data_print(const struct panic_data *pdata) panic_printf("\n=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n", in_handler ? "HANDLER" : "PROCESS", - lregs[1] & 0xff, sregs ? sregs[7] : -1); + lregs[CORTEX_PANIC_REGISTER_IPSR] & 0xff, + sregs ? sregs[CORTEX_PANIC_FRAME_REGISTER_PSR] : -1); for (i = 0; i < 4; i++) print_reg(i, sregs, i); for (i = 4; i < 10; i++) print_reg(i, lregs, i - 1); - print_reg(10, lregs, 9); - print_reg(11, lregs, 10); - print_reg(12, sregs, 4); - print_reg(13, lregs, in_handler ? 2 : 0); - print_reg(14, sregs, 5); - print_reg(15, sregs, 6); + print_reg(10, lregs, CORTEX_PANIC_REGISTER_R10); + print_reg(11, lregs, CORTEX_PANIC_REGISTER_R11); + print_reg(12, sregs, CORTEX_PANIC_FRAME_REGISTER_R12); + print_reg(13, lregs, + in_handler ? CORTEX_PANIC_REGISTER_MSP : + CORTEX_PANIC_REGISTER_PSP); + print_reg(14, sregs, CORTEX_PANIC_FRAME_REGISTER_LR); + print_reg(15, sregs, CORTEX_PANIC_FRAME_REGISTER_PC); #ifdef CONFIG_DEBUG_EXCEPTIONS panic_show_extra(pdata); @@ -303,8 +307,10 @@ void __keep report_panic(void) pdata->reserved = 0; /* Choose the right sp (psp or msp) based on EXC_RETURN value */ - sp = is_frame_in_handler_stack(pdata->cm.regs[11]) - ? pdata->cm.regs[2] : pdata->cm.regs[0]; + sp = is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR]) ? + pdata->cm.regs[CORTEX_PANIC_REGISTER_MSP] : + pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP]; /* If stack is valid, copy exception frame to pdata */ if ((sp & 3) == 0 && sp >= CONFIG_RAM_BASE && @@ -439,9 +445,9 @@ void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception) pdata->arch = PANIC_ARCH_CORTEX_M; /* Log panic cause */ - lregs[1] = exception; - lregs[3] = reason; - lregs[4] = info; + lregs[CORTEX_PANIC_REGISTER_IPSR] = exception; + lregs[CORTEX_PANIC_REGISTER_R4] = reason; + lregs[CORTEX_PANIC_REGISTER_R5] = info; } void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) @@ -451,9 +457,9 @@ void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) if (pdata && pdata->struct_version == 2) { lregs = pdata->cm.regs; - *exception = lregs[1]; - *reason = lregs[3]; - *info = lregs[4]; + *exception = lregs[CORTEX_PANIC_REGISTER_IPSR]; + *reason = lregs[CORTEX_PANIC_REGISTER_R4]; + *info = lregs[CORTEX_PANIC_REGISTER_R5]; } else { *exception = *reason = *info = 0; } diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index fa5642cca6..934de2b70c 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -22,7 +22,7 @@ typedef union { * for __switchto() to work. */ uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ + atomic_t events; /* Bitmaps of received events */ uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ }; @@ -79,7 +79,7 @@ void __idle(void) * CSAE bit is set. Please notice this symptom only * occurs at npcx5. */ -#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOSTCMD_ESPI) +#if defined(CHIP_FAMILY_NPCX5) && defined(CONFIG_HOST_INTERFACE_ESPI) /* Enable Host access wakeup */ SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 6); #endif @@ -202,13 +202,13 @@ static int need_resched_or_profiling; * can do their init within a task switching context. The hooks task will then * make a call to enable all tasks. */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); +static atomic_t tasks_ready = BIT(TASK_ID_HOOKS); /* * Initially allow only the HOOKS and IDLE task to run, regardless of ready * status, in order for HOOK_INIT to complete before other tasks. * task_enable_all_tasks() will open the flood gates. */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); +static atomic_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); static int start_called; /* Has task swapping started */ @@ -263,7 +263,7 @@ task_id_t task_get_current(void) return current_task - tasks; } -uint32_t *task_get_event_bitmap(task_id_t tskid) +atomic_t *task_get_event_bitmap(task_id_t tskid) { task_ *tsk = __task_id_to_ptr(tskid); return &tsk->events; @@ -389,7 +389,9 @@ void __keep task_start_irq_handler(void *excep_return) * and we are not called from another exception (this must match the * logic for when we chain to svc_handler() below). */ - if (!need_resched_or_profiling || (((uint32_t)excep_return & 0xf) == 1)) + if (!need_resched_or_profiling + || (((uint32_t)excep_return & EXC_RETURN_MODE_MASK) + == EXC_RETURN_MODE_HANDLER)) return; exc_start_time = t; @@ -402,7 +404,9 @@ void __keep task_resched_if_needed(void *excep_return) * Continue iff a rescheduling event happened or profiling is active, * and we are not called from another exception. */ - if (!need_resched_or_profiling || (((uint32_t)excep_return & 0xf) == 1)) + if (!need_resched_or_profiling + || (((uint32_t)excep_return & EXC_RETURN_MODE_MASK) + == EXC_RETURN_MODE_HANDLER)) return; svc_handler(0, 0); @@ -948,7 +952,7 @@ void task_print_list(void) ccputs("Task Ready Name Events Time (s) StkUsed\n"); for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; + char is_ready = ((uint32_t)tasks_ready & BIT(i)) ? 'R' : ' '; uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -959,7 +963,7 @@ void task_print_list(void) stackused -= sizeof(uint32_t); ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", i, is_ready, - task_names[i], tasks[i].events, tasks[i].runtime, + task_names[i], (int)tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); cflush(); } @@ -1002,10 +1006,10 @@ DECLARE_SAFE_CONSOLE_COMMAND(taskinfo, command_task_info, static int command_task_ready(int argc, char **argv) { if (argc < 2) { - ccprintf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", (int)tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", (int)tasks_ready); __schedule(0, 0); } diff --git a/core/cortex-m0/atomic.h b/core/cortex-m0/atomic.h index 1774d90332..aef4d2a0a6 100644 --- a/core/cortex-m0/atomic.h +++ b/core/cortex-m0/atomic.h @@ -8,11 +8,9 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - /** * Implements atomic arithmetic operations on 32-bit integers. * diff --git a/core/cortex-m0/cpu.h b/core/cortex-m0/cpu.h index ac184090f9..c30095fd65 100644 --- a/core/cortex-m0/cpu.h +++ b/core/cortex-m0/cpu.h @@ -38,6 +38,14 @@ #define CPU_NVIC_CCR_UNALIGN_TRAP BIT(3) +/* Bitfield values for EXC_RETURN. */ +#define EXC_RETURN_SPSEL_MASK BIT(2) +#define EXC_RETURN_SPSEL_MSP 0 +#define EXC_RETURN_SPSEL_PSP BIT(2) +#define EXC_RETURN_MODE_MASK BIT(3) +#define EXC_RETURN_MODE_HANDLER 0 +#define EXC_RETURN_MODE_THREAD BIT(3) + /* Set up the cpu to detect faults */ void cpu_init(void); diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c index 34519c73d4..f1ee816c60 100644 --- a/core/cortex-m0/panic.c +++ b/core/cortex-m0/panic.c @@ -81,8 +81,8 @@ void panic_data_print(const struct panic_data *pdata) { const uint32_t *lregs = pdata->cm.regs; const uint32_t *sregs = NULL; - const int32_t in_handler = - is_frame_in_handler_stack(pdata->cm.regs[11]); + const int32_t in_handler = is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR]); int i; if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) @@ -90,17 +90,20 @@ void panic_data_print(const struct panic_data *pdata) panic_printf("\n=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n", in_handler ? "HANDLER" : "PROCESS", - lregs[1] & 0xff, sregs ? sregs[7] : -1); + lregs[CORTEX_PANIC_REGISTER_IPSR] & 0xff, + sregs ? sregs[CORTEX_PANIC_FRAME_REGISTER_PSR] : -1); for (i = 0; i < 4; i++) print_reg(i, sregs, i); for (i = 4; i < 10; i++) print_reg(i, lregs, i - 1); - print_reg(10, lregs, 9); - print_reg(11, lregs, 10); - print_reg(12, sregs, 4); - print_reg(13, lregs, in_handler ? 2 : 0); - print_reg(14, sregs, 5); - print_reg(15, sregs, 6); + print_reg(10, lregs, CORTEX_PANIC_REGISTER_R10); + print_reg(11, lregs, CORTEX_PANIC_REGISTER_R11); + print_reg(12, sregs, CORTEX_PANIC_FRAME_REGISTER_R12); + print_reg(13, lregs, + in_handler ? CORTEX_PANIC_REGISTER_MSP : + CORTEX_PANIC_REGISTER_PSP); + print_reg(14, sregs, CORTEX_PANIC_FRAME_REGISTER_LR); + print_reg(15, sregs, CORTEX_PANIC_FRAME_REGISTER_PC); } void __keep report_panic(void) @@ -120,8 +123,10 @@ void __keep report_panic(void) pdata->reserved = 0; /* Choose the right sp (psp or msp) based on EXC_RETURN value */ - sp = is_frame_in_handler_stack(pdata->cm.regs[11]) - ? pdata->cm.regs[2] : pdata->cm.regs[0]; + sp = is_frame_in_handler_stack( + pdata->cm.regs[CORTEX_PANIC_REGISTER_LR]) ? + pdata->cm.regs[CORTEX_PANIC_REGISTER_MSP] : + pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP]; /* If stack is valid, copy exception frame to pdata */ if ((sp & 3) == 0 && sp >= CONFIG_RAM_BASE && @@ -201,9 +206,9 @@ void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception) pdata->arch = PANIC_ARCH_CORTEX_M; /* Log panic cause */ - lregs[1] = exception; - lregs[3] = reason; - lregs[4] = info; + lregs[CORTEX_PANIC_REGISTER_IPSR] = exception; + lregs[CORTEX_PANIC_REGISTER_R4] = reason; + lregs[CORTEX_PANIC_REGISTER_R5] = info; } void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) @@ -213,9 +218,9 @@ void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception) if (pdata && pdata->struct_version == 2) { lregs = pdata->cm.regs; - *exception = lregs[1]; - *reason = lregs[3]; - *info = lregs[4]; + *exception = lregs[CORTEX_PANIC_REGISTER_IPSR]; + *reason = lregs[CORTEX_PANIC_REGISTER_R4]; + *info = lregs[CORTEX_PANIC_REGISTER_R5]; } else { *exception = *reason = *info = 0; } diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c index 274b6a263d..e8aec0926e 100644 --- a/core/cortex-m0/task.c +++ b/core/cortex-m0/task.c @@ -22,7 +22,7 @@ typedef union { * for __switchto() to work. */ uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ + atomic_t events; /* Bitmaps of received events */ uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ }; @@ -136,13 +136,13 @@ task_ *current_task = (task_ *)scratchpad; * can do their init within a task switching context. The hooks task will then * make a call to enable all tasks. */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); +static atomic_t tasks_ready = BIT(TASK_ID_HOOKS); /* * Initially allow only the HOOKS and IDLE task to run, regardless of ready * status, in order for HOOK_INIT to complete before other tasks. * task_enable_all_tasks() will open the flood gates. */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); +static atomic_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); static int start_called; /* Has task swapping started */ @@ -197,7 +197,7 @@ task_id_t task_get_current(void) return current_task - tasks; } -uint32_t *task_get_event_bitmap(task_id_t tskid) +atomic_t *task_get_event_bitmap(task_id_t tskid) { task_ *tsk = __task_id_to_ptr(tskid); return &tsk->events; @@ -304,7 +304,9 @@ void task_start_irq_handler(void *excep_return) * Continue iff the tasks are ready and we are not called from another * exception (as the time accouting is done in the outer irq). */ - if (!start_called || ((uint32_t)excep_return & 0xf) == 1) + if (!start_called + || (((uint32_t)excep_return & EXC_RETURN_MODE_MASK) + == EXC_RETURN_MODE_HANDLER)) return; exc_start_time = t; @@ -322,7 +324,9 @@ void task_end_irq_handler(void *excep_return) * Continue iff the tasks are ready and we are not called from another * exception (as the time accouting is done in the outer irq). */ - if (!start_called || ((uint32_t)excep_return & 0xf) == 1) + if (!start_called + || (((uint32_t)excep_return & EXC_RETURN_MODE_MASK) + == EXC_RETURN_MODE_HANDLER)) return; /* Track time in interrupts */ @@ -565,7 +569,7 @@ void task_print_list(void) ccputs("Task Ready Name Events Time (s) StkUsed\n"); for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; + char is_ready = ((uint32_t)tasks_ready & BIT(i)) ? 'R' : ' '; uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -576,7 +580,7 @@ void task_print_list(void) stackused -= sizeof(uint32_t); ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", i, is_ready, - task_names[i], tasks[i].events, tasks[i].runtime, + task_names[i], (int)tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); cflush(); } @@ -619,10 +623,10 @@ DECLARE_CONSOLE_COMMAND(taskinfo, command_task_info, static int command_task_ready(int argc, char **argv) { if (argc < 2) { - ccprintf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", (int)tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", (int)tasks_ready); __schedule(0, 0); } diff --git a/core/host/atomic.h b/core/host/atomic.h index 83786de904..175b743d05 100644 --- a/core/host/atomic.h +++ b/core/host/atomic.h @@ -8,11 +8,9 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits) { return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST); diff --git a/core/host/task.c b/core/host/task.c index 44d8082d82..83e51fb83b 100644 --- a/core/host/task.c +++ b/core/host/task.c @@ -28,7 +28,7 @@ struct emu_task_t { pthread_t thread; pthread_cond_t resume; - uint32_t event; + atomic_t event; timestamp_t wake_time; uint8_t started; }; @@ -209,7 +209,7 @@ uint32_t task_set_event(task_id_t tskid, uint32_t event) return 0; } -uint32_t *task_get_event_bitmap(task_id_t tskid) +atomic_t *task_get_event_bitmap(task_id_t tskid) { return &tasks[tskid].event; } diff --git a/core/minute-ia/atomic.h b/core/minute-ia/atomic.h index 37a4454902..dbcd04b7de 100644 --- a/core/minute-ia/atomic.h +++ b/core/minute-ia/atomic.h @@ -8,12 +8,10 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" #include "util.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - static inline int bool_compare_and_swap_u32(uint32_t *var, uint32_t old_value, uint32_t new_value) { diff --git a/core/minute-ia/task.c b/core/minute-ia/task.c index cde3d80e12..3526b93dd0 100644 --- a/core/minute-ia/task.c +++ b/core/minute-ia/task.c @@ -60,7 +60,7 @@ static uint64_t task_start_time; /* Time task scheduling started */ static uint32_t exc_start_time; /* Time of task->exception transition */ static uint32_t exc_end_time; /* Time of exception->task transition */ static uint64_t exc_total_time; /* Total time in exceptions */ -static uint32_t svc_calls; /* Number of service calls */ +static atomic_t svc_calls; /* Number of service calls */ static uint32_t task_switches; /* Number of times active task changed */ static uint32_t irq_dist[CONFIG_IRQ_COUNT]; /* Distribution of IRQ calls */ #endif @@ -143,13 +143,13 @@ task_ *current_task, *next_task; * can do their init within a task switching context. The hooks task will then * make a call to enable all tasks. */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); +static atomic_t tasks_ready = BIT(TASK_ID_HOOKS); /* * Initially allow only the HOOKS and IDLE task to run, regardless of ready * status, in order for HOOK_INIT to complete before other tasks. * task_enable_all_tasks() will open the flood gates. */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); +static atomic_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); static int start_called; /* Has task swapping started */ @@ -207,7 +207,7 @@ const char *task_get_name(task_id_t tskid) return "<< unknown >>"; } -uint32_t *task_get_event_bitmap(task_id_t tskid) +atomic_t *task_get_event_bitmap(task_id_t tskid) { task_ *tsk = __task_id_to_ptr(tskid); @@ -521,7 +521,7 @@ void task_print_list(void) "StkUsed\n"); for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; + char is_ready = ((uint32_t)tasks_ready & BIT(i)) ? 'R' : ' '; uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -535,14 +535,14 @@ void task_print_list(void) char use_fpu = tasks[i].use_fpu ? 'Y' : 'N'; ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d %c\n", - i, is_ready, task_get_name(i), tasks[i].events, - tasks[i].runtime, stackused, - tasks_init[i].stack_size, use_fpu); + i, is_ready, task_get_name(i), + (int)tasks[i].events, tasks[i].runtime, + stackused, tasks_init[i].stack_size, use_fpu); } else { ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", - i, is_ready, task_get_name(i), tasks[i].events, - tasks[i].runtime, stackused, - tasks_init[i].stack_size); + i, is_ready, task_get_name(i), + (int)tasks[i].events, tasks[i].runtime, + stackused, tasks_init[i].stack_size); } cflush(); @@ -565,8 +565,9 @@ static int command_task_info(int argc, char **argv) total += irq_dist[i]; } } - ccprintf("Service calls: %11d\n", svc_calls); - ccprintf("Total exceptions: %11d\n", total + svc_calls); + ccprintf("Service calls: %11d\n", (int)svc_calls); + ccprintf("Total exceptions: %11d\n", + total + (int)svc_calls); ccprintf("Task switches: %11d\n", task_switches); ccprintf("Task switching started: %11.6lld s\n", task_start_time); @@ -586,10 +587,10 @@ __maybe_unused static int command_task_ready(int argc, char **argv) { if (argc < 2) { - ccprintf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", (int)tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", (int)tasks_ready); __schedule(0, 0); } diff --git a/core/minute-ia/task_defs.h b/core/minute-ia/task_defs.h index 01632392cb..18458b1533 100644 --- a/core/minute-ia/task_defs.h +++ b/core/minute-ia/task_defs.h @@ -15,6 +15,7 @@ * defines for inline asm */ #ifndef __ASSEMBLER__ +#include "atomic.h" #include "common.h" #define USE_FPU_OFFSET_STR STRINGIFY(USE_FPU_OFFSET) /* "20" */ @@ -34,7 +35,7 @@ typedef union { * for __switchto() to work. */ uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ + atomic_t events; /* Bitmaps of received events */ uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ #ifdef CONFIG_FPU diff --git a/core/nds32/atomic.h b/core/nds32/atomic.h index b634c3a551..f50deaaba3 100644 --- a/core/nds32/atomic.h +++ b/core/nds32/atomic.h @@ -8,13 +8,11 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" #include "cpu.h" #include "task.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits) { atomic_val_t ret; diff --git a/core/nds32/init.S b/core/nds32/init.S index b8e109c434..159f3709d3 100644 --- a/core/nds32/init.S +++ b/core/nds32/init.S @@ -87,7 +87,7 @@ vector irq_15, 15 /* HW 15 */ .global eflash_sig eflash_sig: .byte 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5 -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI .byte 0xA4 /* eSPI */ #else .byte 0xA5 /* LPC */ diff --git a/core/nds32/task.c b/core/nds32/task.c index 3457af2bb5..aa88193d91 100644 --- a/core/nds32/task.c +++ b/core/nds32/task.c @@ -25,7 +25,7 @@ typedef union { * for __switchto() to work. */ uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ + atomic_t events; /* Bitmaps of received events */ uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ }; @@ -159,13 +159,13 @@ int need_resched; * can do their init within a task switching context. The hooks task will then * make a call to enable all tasks. */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); +static atomic_t tasks_ready = BIT(TASK_ID_HOOKS); /* * Initially allow only the HOOKS and IDLE task to run, regardless of ready * status, in order for HOOK_INIT to complete before other tasks. * task_enable_all_tasks() will open the flood gates. */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); +static atomic_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); int start_called; /* Has task swapping started */ @@ -250,7 +250,7 @@ task_id_t task_get_current(void) return start_called ? (current_task - tasks) : TASK_ID_INVALID; } -uint32_t *task_get_event_bitmap(task_id_t tskid) +atomic_t *task_get_event_bitmap(task_id_t tskid) { task_ *tsk = __task_id_to_ptr(tskid); return &tsk->events; @@ -670,7 +670,7 @@ void task_print_list(void) ccputs("Task Ready Name Events Time (s) StkUsed\n"); for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; + char is_ready = ((uint32_t)tasks_ready & BIT(i)) ? 'R' : ' '; uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -681,7 +681,7 @@ void task_print_list(void) stackused -= sizeof(uint32_t); ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", i, is_ready, - task_names[i], tasks[i].events, tasks[i].runtime, + task_names[i], (int)tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); cflush(); } @@ -724,10 +724,10 @@ DECLARE_CONSOLE_COMMAND(taskinfo, command_task_info, static int command_task_ready(int argc, char **argv) { if (argc < 2) { - ccprintf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", (int)tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", (int)tasks_ready); __schedule(0, 0, 0); } diff --git a/core/riscv-rv32i/atomic.h b/core/riscv-rv32i/atomic.h index e92beb2ca0..91658e8065 100644 --- a/core/riscv-rv32i/atomic.h +++ b/core/riscv-rv32i/atomic.h @@ -8,13 +8,11 @@ #ifndef __CROS_EC_ATOMIC_H #define __CROS_EC_ATOMIC_H +#include "atomic_t.h" #include "common.h" #include "cpu.h" #include "task.h" -typedef int atomic_t; -typedef atomic_t atomic_val_t; - static inline atomic_val_t atomic_clear_bits(atomic_t *addr, atomic_val_t bits) { return __atomic_fetch_and(addr, ~bits, __ATOMIC_SEQ_CST); diff --git a/core/riscv-rv32i/init.S b/core/riscv-rv32i/init.S index 5715478356..8ee5479e0e 100644 --- a/core/riscv-rv32i/init.S +++ b/core/riscv-rv32i/init.S @@ -75,7 +75,7 @@ __ec_intc: .global eflash_sig eflash_sig: .byte 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5 -#ifdef CONFIG_HOSTCMD_ESPI +#ifdef CONFIG_HOST_INTERFACE_ESPI .byte 0xA4 /* eSPI */ #else .byte 0xA5 /* LPC */ diff --git a/core/riscv-rv32i/task.c b/core/riscv-rv32i/task.c index 89d7671fe1..204e58432d 100644 --- a/core/riscv-rv32i/task.c +++ b/core/riscv-rv32i/task.c @@ -20,7 +20,7 @@ typedef struct { * for __switchto() to work. */ uint32_t sp; /* Saved stack pointer for context switch */ - uint32_t events; /* Bitmaps of received events */ + atomic_t events; /* Bitmaps of received events */ uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ } task_; @@ -154,13 +154,13 @@ int need_resched; * can do their init within a task switching context. The hooks task will then * make a call to enable all tasks. */ -static uint32_t tasks_ready = BIT(TASK_ID_HOOKS); +static atomic_t tasks_ready = BIT(TASK_ID_HOOKS); /* * Initially allow only the HOOKS and IDLE task to run, regardless of ready * status, in order for HOOK_INIT to complete before other tasks. * task_enable_all_tasks() will open the flood gates. */ -static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); +static atomic_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE); int start_called; /* Has task swapping started */ @@ -229,7 +229,7 @@ task_id_t __ram_code task_get_current(void) return current_task - tasks; } -uint32_t * __ram_code task_get_event_bitmap(task_id_t tskid) +atomic_t * __ram_code task_get_event_bitmap(task_id_t tskid) { task_ *tsk = __task_id_to_ptr(tskid); @@ -603,7 +603,7 @@ void task_print_list(void) ccputs("Task Ready Name Events Time (s) StkUsed\n"); for (i = 0; i < TASK_ID_COUNT; i++) { - char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; + char is_ready = ((uint32_t)tasks_ready & BIT(i)) ? 'R' : ' '; uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -614,7 +614,7 @@ void task_print_list(void) stackused -= sizeof(uint32_t); ccprintf("%4d %c %-16s %08x %11.6lld %3d/%3d\n", i, is_ready, - task_names[i], tasks[i].events, tasks[i].runtime, + task_names[i], (int)tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); cflush(); } @@ -657,10 +657,10 @@ DECLARE_CONSOLE_COMMAND(taskinfo, command_task_info, static int command_task_ready(int argc, char **argv) { if (argc < 2) { - ccprintf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", (int)tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", (int)tasks_ready); __schedule(0, 0, 0); } diff --git a/cts/interrupt/dut.c b/cts/interrupt/dut.c index 3c83e5701f..a479918c5f 100644 --- a/cts/interrupt/dut.c +++ b/cts/interrupt/dut.c @@ -66,7 +66,7 @@ void cts_irq2(enum gpio_signal signal) void clean_state(void) { - uint32_t *event; + atomic_t *event; interrupt_enable(); got_interrupt = 0; diff --git a/docs/configuration/config_ap_to_ec_comm.md b/docs/configuration/config_ap_to_ec_comm.md index 24b309feb7..0a517401be 100644 --- a/docs/configuration/config_ap_to_ec_comm.md +++ b/docs/configuration/config_ap_to_ec_comm.md @@ -9,10 +9,10 @@ details a system level of the operation of this feature. Configure the AP to EC communication channel, picking exactly one of the following options. -- `CONFIG_HOSTCMD_SHI` - [SPI Host Interface](../ec_terms.md#shi) (SHI) -- `CONFIG_HOSTCMD_HECI` - HECI interface -- `CONFIG_HOSTCMD_LPC` - [LPC](../ec_terms.md#lpc) bus -- `CONFIG_HOSTCMD_ESPI` - [eSPI](../ec_terms.md#espi) bus +- `CONFIG_HOST_INTERFACE_SHI` - [SPI Host Interface](../ec_terms.md#shi) (SHI) +- `CONFIG_HOST_INTERFACE_HECI` - HECI interface +- `CONFIG_HOST_INTERFACE_LPC` - [LPC](../ec_terms.md#lpc) bus +- `CONFIG_HOST_INTERFACE_ESPI` - [eSPI](../ec_terms.md#espi) bus In [config.h], search for options that start with the same name as your selected communication interface. Override defaults as needed. diff --git a/docs/ec_terms.md b/docs/ec_terms.md index 3b9f88416e..d5f3690615 100644 --- a/docs/ec_terms.md +++ b/docs/ec_terms.md @@ -239,7 +239,7 @@ [BC 1.2 Specification]: <https://www.usb.org/document-library/battery-charging-v12-spec-and-adopters-agreement> [CrOS Board Info]: <https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md> [CEC Wikipedia page]: <https://en.wikipedia.org/wiki/Consumer_Electronics_Control> -[DPTF Readme]: <https://github.com/intel/dptf/blob/master/README.txt> +[DPTF Readme]: <https://github.com/intel/dptf/blob/HEAD/README.txt> [eSPI Specification]: <https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0.pdf> [FAFT design doc]: <https://chromium.googlesource.com/chromiumos/third_party/autotest/+/HEAD/docs/faft-design-doc.md> [I2C Specification]: <https://www.nxp.com/docs/en/user-guide/UM10204.pdf> diff --git a/docs/fingerprint/fingerprint-dev-for-partners.md b/docs/fingerprint/fingerprint-dev-for-partners.md index 2d9332db5b..4fd6673861 100644 --- a/docs/fingerprint/fingerprint-dev-for-partners.md +++ b/docs/fingerprint/fingerprint-dev-for-partners.md @@ -650,7 +650,7 @@ Make sure that this interface is disabled: <!-- https://docs.google.com/drawings/d/1YhOUD-Qf69NUdugT6n0cX7o7CWvb5begcdmJwv7ch6I --> -[Dragonclaw Rev 0.2 1.8V Rework]: https://github.com/coreboot/chrome-ec/blob/master/docs/images/dragonclaw_rev_0.2_1.8v_load_switch_rework.pdf +[Dragonclaw Rev 0.2 1.8V Rework]: https://github.com/coreboot/chrome-ec/blob/HEAD/docs/images/dragonclaw_rev_0.2_1.8v_load_switch_rework.pdf <!-- https://docs.google.com/drawings/d/1w2qbb4AsSxY-KTK2vXZ6TKeWHveWvS3Dkgh61ocu0wc --> diff --git a/docs/fingerprint/fingerprint.md b/docs/fingerprint/fingerprint.md index 51c6192670..7b55ef7827 100644 --- a/docs/fingerprint/fingerprint.md +++ b/docs/fingerprint/fingerprint.md @@ -582,7 +582,7 @@ a given device can be found by viewing `chrome://system/#platform_identity_sku`. [CBI Info]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md [Chrome OS Config SKU]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#identity [Chrome OS Project Configuration]: https://chromium.googlesource.com/chromiumos/config/+/HEAD/README.md -[Starlark]: https://docs.bazel.build/versions/master/skylark/language.html +[Starlark]: https://docs.bazel.build/versions/main/skylark/language.html [`create_fingerprint`]: https://chromium.googlesource.com/chromiumos/config/+/e1fa0d7f56eb3dd6e9378e4326de086ada46b7d3/util/hw_topology.star#444 [Morphius `config.star`]: https://chrome-internal.googlesource.com/chromeos/project/zork/morphius/+/593b657a776ed6b320c826916adc9cd845faf709/config.star#85 [regenerate the config]: https://chromium.googlesource.com/chromiumos/config/+/HEAD/README.md#making-configuration-changes-for-your-project diff --git a/docs/i2c-debugging.md b/docs/i2c-debugging.md index 125e72b777..4b6afc9a54 100644 --- a/docs/i2c-debugging.md +++ b/docs/i2c-debugging.md @@ -4,6 +4,9 @@ The EC codebase has functionality to help you debug I²C errors without pulling out the scope. Some of the debug functionality is disabled by default to save space, but can be enabled with the `CONFIG_I2C_DEBUG` option. +For Zephyr EC builds, enable I²C by adding `CONFIG_PLATFORM_EC_I2C_DEBUG=y` to +one of your project's Kconfig files. + ## Tracing You can use the `i2ctrace` command to monitor (ranges of) addresses: diff --git a/docs/reducing_ec_image_size.md b/docs/reducing_ec_image_size.md index dd7d9bbcab..4b5c5bbf31 100644 --- a/docs/reducing_ec_image_size.md +++ b/docs/reducing_ec_image_size.md @@ -452,7 +452,7 @@ Note that there are some [FAFT tests][5] that rely on the GPIO name. If you enable this option, you may also need to change firmware testing configuration [file][6]. -[1]:./zephyr_build.md#Working-outside-the-chroot +[1]:./zephyr/zephyr_build.md#Working-outside-the-chroot [2]:https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/shell/Kconfig [3]:https://docs.zephyrproject.org/latest/guides/optimizations/tools.html [4]:https://github.com/zephyrproject-rtos/zephyr/issues/2112 diff --git a/docs/schematics/dragonclaw/README.md b/docs/schematics/dragonclaw/README.md index 66fde41df8..82a2fa2681 100644 --- a/docs/schematics/dragonclaw/README.md +++ b/docs/schematics/dragonclaw/README.md @@ -6,5 +6,5 @@ Note that you'll need to download and save the HTML file from The layout file is in the [`.brd`] file. -[`.brd`]: https://raw.githubusercontent.com/coreboot/chrome-ec/master/docs/schematics/dragonclaw/dragonclaw_v0.2.brd -[schematic]: https://raw.githubusercontent.com/coreboot/chrome-ec/master/docs/schematics/dragonclaw/dragonclaw_v0.2.html +[`.brd`]: https://raw.githubusercontent.com/coreboot/chrome-ec/HEAD/docs/schematics/dragonclaw/dragonclaw_v0.2.brd +[schematic]: https://raw.githubusercontent.com/coreboot/chrome-ec/HEAD/docs/schematics/dragonclaw/dragonclaw_v0.2.html diff --git a/docs/sitemap.md b/docs/sitemap.md index 2b9f4aaaf8..7258aacd17 100644 --- a/docs/sitemap.md +++ b/docs/sitemap.md @@ -35,7 +35,7 @@ ## Testing * [Unit Tests](./unit_tests.md) - * [Porting EC unit tests to Ztest](./ztest.md) + * [Porting EC unit tests to Ztest](./zephyr/ztest.md) * [Code Coverage](./code_coverage.md) ## Updaters @@ -59,10 +59,11 @@ ## Zephyr -* [Initialization Order](./zephyr_init.md) -* [Proof-of-Concept-Device Bringup](./zephyr_poc_device_bringup.md) -* [Shimming](./zephyr_shim.md) -* [Porting EC unit tests to Ztest](./ztest.md) +* [Building Zephyr OS](./zephyr/zephyr_build.md) +* [Initialization Order](./zephyr/zephyr_init.md) +* [Proof-of-Concept-Device Bringup](./zephyr/zephyr_poc_device_bringup.md) +* [Shimming](./zephyr/zephyr_shim.md) +* [Porting EC unit tests to Ztest](./zephyr/ztest.md) ## Miscellaneous diff --git a/docs/unit_tests.md b/docs/unit_tests.md index f26a8519c8..1d9da40f9d 100644 --- a/docs/unit_tests.md +++ b/docs/unit_tests.md @@ -196,7 +196,7 @@ Build and run the test as an EC unit test: ``` For building the test as a Zephyr Ztest unit test, follow the instructions in -[Porting EC unit tests to Ztest](./ztest.md) to build the unit test for Zephyr's +[Porting EC unit tests to Ztest](./zephyr/ztest.md) to build the unit test for Zephyr's "native_posix" host-based target. <!-- mdformat off(b/139308852) --> diff --git a/docs/zephyr/project_config.md b/docs/zephyr/project_config.md new file mode 100644 index 0000000000..285e90dbdd --- /dev/null +++ b/docs/zephyr/project_config.md @@ -0,0 +1,174 @@ +Project Configuration +===================== + +[TOC] + +## Setting up a new program ("reference board" or "baseboard") + +Unlike the legacy EC codebase, Zephyr projects all live together in +one big happy directory. The intent of this design is to encourage +code-sharing between projects, and reduce the amount of copy/paste +that is required to bring up a new project. This directory can, but +does not have to, correlate to the unified build Chrome OS board, +however firmware authors can always choose a different structure if it +makes sense for the specific scenario. As a hypothetical example, +similar Chromeboxes and Chromebooks may wish to share the Zephyr EC +project directory instead of use separate directories, even if they +are using a different unified build board. + +To set up a new EC program, create a new directory under +[`zephyr/projects`](../../zephyr/projects) with the following files: + +- `BUILD.py` - specifies which builds can be made from this directory, + and what the device-tree overlays and Kconfig files are for each + build. +- `CMakeLists.txt` - Baseboard-specific C files can be listed here. +- `prj.conf` (optional) - Default Kconfig settings for all projects. +- `Kconfig` (optional) - Set options for your reference design here, + which variants can use to install optional C sources. + +An in-depth example of each file is given below: + +### BUILD.py + +`BUILD.py` is a Python-based config file for setting up your reference +board and the associated variants. The name `BUILD.py` is important +and case-sensitive: `zmake` searches for files by this +name. + +When `BUILD.py` is sourced, the following two globals are defined: + +- `here`: A `pathlib.Path` object containing the path to the directory + `BUILD.py` is located in. +- `register_project`: A function which informs `zmake` of a new + project to be built. Your `BUILD.py` file needs to call this + function one or more times. + +`register_project` takes the following keyword arguments: + +- `project_name` (required): The name of the project (typically the + Google codename). This name must be unique amongst all projects + known to `zmake`, and `zmake` will error if you choose a conflicting + name. +- `zephyr_board` (required): The name of the Zephyr board to use for + the project. The Zephyr build system expects a Zephyr board + directory under `boards/${ARCH}/${ZEPHYR_BOARD_NAME}`. **Note:** + the concept of a Zephyr board does not align with the Chrome OS + concept of a board: for most projects this will typically be the + name of the EC chip used, not the name of the model or overlay. +- `supported_toolchains` (required): A list of the toolchain names + supported by the build. Valid values are `coreboot-sdk`, `host`, + `llvm`, and `zephyr`. Note that only `coreboot-sdk` and `llvm` are + supported in the chroot, and all projects must be able to build in + the chroot, so your project must at least list one of `coreboot-sdk` + or `llvm`. +- `output_packer` (required): An output packer type which defines + which builds get generated, and how they get assembled together into + a binary. +- `modules` (optional): A list of module names required by the + project. The default, if left unspecified, is to use all modules + known by `zmake`. Generally speaking, there is no harm to including + unnecessary modules as modules are typically guarded by Kconfig + options, so the only reason to set this is if your project needs to + build in a limited environment where not all modules are available. +- `is_test` (optional): `True` if the code should be executed as a + test after compilation, `False` otherwise. Defaults to `False`. +- `dts_overlays` (optional): A list of files which should be + concatenated together and applied as a Zephyr device-tree overlay. + Defaults to no overlays (empty list). +- `project_dir` (optional): The path to where `CMakeLists.txt` and + `Kconfig` can be found for the project, defaulting to `here`. + +Note that most projects will not want to call `register_project` +directly, but instead one of the helper functions, which sets even +more defaults for you: + +- `register_host_project`: Define a project which runs in the chroot + (not on hardware). +- `register_host_test`: Just like `register_host_project`, but + `is_test` gets set to `True`. +- `register_raw_project`: Register a project which builds a single + `.bin` file, no RO+RW packing, no FMAP. +- `register_binman_project`: Register a project which builds RO and RW + sections, packed together, and including FMAP. +- `register_npcx_project`: Just like `register_binman_project`, but + expects a file generated named `zephyr.npcx.bin` for the RO section + with Nuvoton's header. + +You can find the implementation of these functions in +[`zephyr/zmake/zmake/configlib.py`](../../zephyr/zmake/zmake/configlib.py). + +`BUILD.py` files are auto-formatted with `black`. After editing a +`BUILD.py` file, please run `black BUILD.py` on it. + +### CMakeLists.txt + +This file, should at minimum contain the following: + +``` cmake +cmake_minimum_required(VERSION 3.20.1) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ec) +``` + +You may additionally want to specify any C files or include +directories your project needs using `zephyr_library_sources` or +`zephyr_library_include_directories`. + +### prj.conf and prj_${project_name}.conf + +`prj.conf` has default Kconfig settings for all projects, and +`prj_${project_name}.conf` can contain overrides for certain projects. +The format is `KEY=VALUE`, as typical for Kconfig. + +### Kconfig + +If certain projects need project-specific C files or ifdefs, the only +way to do so is to create a `Kconfig` file with the options schema you +want, and use it to toggle the inclusion of certain files. + +The file must end with a single line that reads +`source "Kconfig.zephyr"`. Note that this file is optional, so it's +recommended to only include it if you really need it. + +## Setting up a new variant of an EC program + +**Unlike our legacy EC, there are no files or directories to copy and +paste to setup a new variant in Zephyr code.** + +Simply add a `register_project`-based call to the existing `BUILD.py` +for your reference board. + +Below is an example of how programs may wish to structure this in +`BUILD.py`: + +``` python +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +def register_variant(project_name, chip="it8xx2", extra_dts_overlays=()): + register_binman_project( + project_name=project_name, + zephyr_board=chip, + dts_overlays=[ + here / "base_power_sequence.dts", + here / "i2c.dts", + **extra_dts_overlays, + ], + ) + + +# Reference board +register_variant( + project_name="asurada", + extra_dts_overlays=[here / "reference_gpios.dts"], +) + +# Variants +register_variant( + project_name="hayato", + extra_dts_overlays=[here / "hayato_gpios.dts"], +) +``` diff --git a/docs/zephyr_build.md b/docs/zephyr/zephyr_build.md index 60a9e1d97e..60a9e1d97e 100644 --- a/docs/zephyr_build.md +++ b/docs/zephyr/zephyr_build.md diff --git a/docs/zephyr/zephyr_i2c.md b/docs/zephyr/zephyr_i2c.md new file mode 100644 index 0000000000..625efa98a5 --- /dev/null +++ b/docs/zephyr/zephyr_i2c.md @@ -0,0 +1,370 @@ +# Zephyr I2C Bus Configuration + +[TOC] + +## Overview + +The [I2C] buses provide access and control to on-board peripherals, including +USB-C chips, battery, charging IC, and sensors. + +## Kconfig Options + +Kconfig Option | Default state | Documentation +:--------------------------------- | :-----------: | :------------ +`CONFIG_PLATFORM_EC_I2C` | y | [EC I2C] + +The following options are available only when `CONFIG_PLATFORM_EC_I2C=y`. + +Kconfig sub-option | Default | Documentation +:-------------------------------------------- | :-----: | :------------ +`CONFIG_I2C_SHELL` | y | [CONFIG_I2C_SHELL] +`CONFIG_PLATFORM_EC_I2C_DEBUG` | n | [I2C Debug] +`CONFIG_PLATFORM_EC_I2C_DEBUG_PASSTHRU` | n | [I2C Debug Passthru] +`CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP` | n | [I2C Portmap] +`CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_SPEED` | n | [I2C Speed] +`CONFIG_PLATFORM_EC_HOSTCMD_I2C_CONTROL` | n | [I2C Control] +`CONFIG_PLATFORM_EC_I2C_PASSTHRU_RESTRICTED` | n | [I2C Passthru Restricted] + +## Devicetree Nodes + +The EC chip disables all I2C buses by default. Enable the I2C buses used on +your design by changing the chip-specific I2C bus `status` property to `"okay"`. + +I2C bus properties: + +Property | Description | Settings +:------- | :---------- | :------- +`status` | Enables or disables the I2C controller | `"okay"` <br> `"disabled"` +`label` | Override the EC chip specific label. We recommend changing the label to match the net name of the I2C bus. The label must begin with `"I2C_"`. |`"I2C_<net_name>"` +`clock-frequency` | Sets the initial I2C bus frequency in Hz. | `I2C_BITRATE_STANDARD` - 100 KHz <br> `I2C_BITRATE_FAST` - 400 KHz <br> `I2C_BITRATE_FAST_PLUS` - 1 MHz + +Example enabling I2C0 and I2C3 at 100 KHz and 1 MHz, respectively. +``` +&i2c0 { + status = "okay"; + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; +&i2c3 { + status = "okay"; + label = "I2C_USB_C0_PD"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; +``` + +### Nuvoton NPCX ECs + +Nuvoton ECs use two devicetree nodes to describe the I2C buses used, an I2C +controller and an I2C port. + +Nuvoton I2C node labels use the following pattern: +- I2C controller: `&i2c_ctrl<controller>` +- I2C port: `&i2c<controller>_<port>` + +Where `<controller>` specifies the I2C controller number (0-7), and `<port>` +specifies the port number (0-1). You can only enable one I2C port per +controller, and not all I2C controllers support both ports. + +The Nuvoton I2C port contains the standard Zephyr I2C bus properties. The +Nuvoton I2C controller contains only the `status` property. + +To enable a Nuvoton I2C bus, set both the I2C controller and I2C port `status` +property to `"okay"`.Set the `clock-frequency` and `label` properties in the I2C +port as shown below: + +``` +&i2c_ctrl4 { + status = "okay"; +}; +&i2c4_1 { + status = "okay"; + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; +}; +``` + +### ITE IT8xxx2 ECs + +ITE ECs use a single devicetree node, `&i2c<channel>` to enable an I2C bus. +`<channel>` specifies the I2C/SMBus channel number (0-5). + +``` +&i2c3 { + status = "okay"; + label = "I2C_USB_C0_PD"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; +``` + +### Mapping legacy I2C port numbers to Zephyr devicetree nodes + +The legacy I2C API for the Chromium EC application uses an enumeration (e.g. +`I2C_PORT_ACCEL`, `I2C_PORT_EEPROM`) to specify the I2C bus during transfer +operations. + +The `named-i2c-ports` node creates the mapping between the legacy I2C bus +enumeration and the Zephyr I2C bus device instance. + +``` +named-i2c-ports { + compatible = "named-i2c-ports"; + battery { + i2c-port = <&i2c0_0>; + remote-port = <0>; + enum-name = "I2C_PORT_BATTERY"; + } +}; +``` + +You can map multiple enumeration values to the same Zephyr I2C bus device +instance. + +``` +named-i2c-ports { + compatible = "named-i2c-ports"; + battery { + i2c-port = <&i2c0_0>; + remote-port = <0>; + enum-name = "I2C_PORT_BATTERY"; + } + charger { + i2c-port = <&i2c0_0>; + remote-port = <0>; + enum-name = "I2C_PORT_CHARGER"; + }; +}; +``` + +Refer to the [cros-ec-i2c-port-base.yaml] child-binding file for details about +each property. + +## Board Specific Code + +None required. + +## Threads + +I2C support does not enable any threads. + +## Testing and Debugging + +### Shell Command: i2c +The EC application enables the the Zephyr shell command, `i2c`, when +`CONFIG_I2C_SHELL=y`. The `i2c` command includes the following [subcommands]: + +Subcommand | Description | Usage +:--------- | :---------- | :---- +`scan` | Scan I2C devices | `i2c scan <i2c_bus_label>` +`recover` | Recover I2C bus | `i2c recover <i2c_bus_label>` +`read` | Read bytes from an I2C device | `i2c read <i2c_bus_label> <dev_addr> <reg_addr> [<num_bytes>]` +`read_byte` | Read a byte from an I2C device | `i2c read_byte <i2c_bus_label> <dev_addr> <reg_addr>` +`write` | Write bytes to an I2C device | `i2c write <i2c_bus_label> <dev_addr> <reg_addr> <out_byte0> .. <out_byteN>` +`write_byte` | Write a byte to an I2C device | `i2c write_byte <i2c_bus_label> <dev_addr> <reg_addr> <out_byte>` + +I2C parameter summary: + +Parameter | Description +:-------- | :---------- +`<i2c_bus_label>` | The I2C bus label property. By default this is specified by the EC vendor in the respective devicetree include file unless you override the label in your devicetree. +`<dev_addr>` | The I2C device address, specified using 7-bit notation. Valid device addresses are 0 - 0x7F. +`<reg_addr>` | The register address with the I2C device to read or write. +`<num_bytes>` | For the `read` subcommand, specifies the number of bytes to read from the I2C device. Default is 16 bytes if not specified. +`<out_byte>` | For the `write_byte` subcommand, specifies the single data byte to write to the I2C device. +`<out_byte0>..<out_byteN>` | For the `write` subcommand, specifies the data bytes to write to the I2C device. + +### Shell Command: i2c_portmap +The shell command `i2c_portmap` displays the mapping of I2C bus enumeration to +the physical bus and to the remote port index. + +Example `i2c_portmap` output from a Volteer board: +``` +uart:~$ i2c_portmap +Zephyr physical I2C ports (9): + 0 : 0 + 1 : 0 + 2 : 1 + 3 : 2 + 4 : 3 + 5 : 4 + 6 : 4 + 7 : 5 + 8 : 5 +Zephyr remote I2C ports (9): + 0 : -1 + 1 : -1 + 2 : -1 + 3 : -1 + 4 : -1 + 5 : -1 + 6 : -1 + 7 : 7 + 8 : -1 +``` + +### I2C Tracing + +For runtime troubleshooting of an I2C device, enable the [I2C +tracing](../i2c-debugging.md) module to log all I2C transactions initiated by +the EC code. + +## Example + +The image below shows the I2C bus assignment for the Volteer reference board. + +![I2C Example] + +The Volteer reference design uses the Nuvoton NPCX EC, and needs the following +I2C buses enabled: + +Net Name | NPCX I2C Designator | Bus speed +:----------------- | :------------------ | :-------- +EC_I2C7_EEPROM_PWR | I2C7_PORT0 | 400 kHz +EC_I2C5_BATTERY | I2C5_PORT0 | 100 kHz +EC_I2C0_SENSOR | I2C0_PORT0 | 400 kHz +EC_I2C1_USB_C0 | I2C1_PORT0 | 1000 kHz +EC_I2C2_USB_C1 | I2C2_PORT0 | 1000 kHz +EC_I2C3_USB_1_MIX | I2C3_PORT0 | 100 kHz + + +### Enable Nuvoton I2C buses +The Volteer project enables the Nuvoton I2C buses in [volteer.dts]. + +```c +&i2c0_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; + label = "I2C_SENSOR"; +}; +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c1_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + label = "I2C_USB_C0"; +}; +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c2_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + label = "I2C_USB_C1"; +}; +&i2c_ctrl2 { + status = "okay"; +}; + +&i2c3_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_STANDARD>; + label = "I2C_USB_1_MIX"; +}; +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c5_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_STANDARD>; + label = "I2C_BATTERY"; +}; +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c7_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; + label = "I2C_EEPROM_PWR"; + + isl9241: isl9241@9 { + compatible = "intersil,isl9241"; + reg = <0x09>; + label = "ISL9241_CHARGER"; + switching-frequency = <SWITCHING_FREQ_724KHZ>; + }; +}; +&i2c_ctrl7 { + status = "okay"; +}; +``` + +### Map I2C Enumerations +The legacy cros-ec drivers require the board to define the following enumeration +values: + +I2C Enumeration Name | Volteer I2C Bus Mapping +:------------------- | :---------------------- +`I2C_PORT_SENSOR` | EC_I2C0_SENSOR +`I2C_PORT_ACCEL` | EC_I2C0_SENSOR +`I2C_PORT_USB_C0` | EC_I2C1_USB_C0 +`I2C_PORT_USB_C1` | EC_I2C2_USB_C1 +`I2C_PORT_USB_1_MIX` | EC_I2C3_USB_1_MIX +`I2C_PORT_POWER` | EC_I2C5_BATTERY +`I2C_PORT_BATTERY` | EC_I2C5_BATTERY +`I2C_PORT_EEPROM` | EC_I2C7_EEPROM_PWR +`I2C_PORT_CHARGER` | EC_I2C7_EEPROM_PWR + +The Volteer project establishes this map using the `named-i2c-ports` as shown +below: + +```c + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_sensor: sensor { + i2c-port = <&i2c0_0>; + enum-name = "I2C_PORT_SENSOR"; + }; + i2c-accel { + i2c-port = <&i2c0_0>; + enum-name = "I2C_PORT_ACCEL"; + }; + i2c_usb_c0: usb-c0 { + i2c-port = <&i2c1_0>; + enum-name = "I2C_PORT_USB_C0"; + }; + i2c_usb_c1: usb-c1 { + i2c-port = <&i2c2_0>; + enum-name = "I2C_PORT_USB_C1"; + }; + usb1-mix { + i2c-port = <&i2c3_0>; + enum-name = "I2C_PORT_USB_1_MIX"; + }; + power { + i2c-port = <&i2c5_0>; + enum-name = "I2C_PORT_POWER"; + }; + battery { + i2c-port = <&i2c5_0>; + enum-name = "I2C_PORT_BATTERY"; + }; + eeprom { + i2c-port = <&i2c7_0>; + remote-port = <7>; + enum-name = "I2C_PORT_EEPROM"; + }; + charger { + i2c-port = <&i2c7_0>; + enum-name = "I2C_PORT_CHARGER"; + }; + }; +``` + +[I2C]: ../ec_terms.md#i2c +[subcommands]: https://github.com/zephyrproject-rtos/zephyr/blob/f4a0ea7b43eee4d2ee735ab6beccc68c9d40a7d0/drivers/i2c/i2c_shell.c#L245 +[I2C Example]: ../images/i2c_example.png +[EC I2C]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q="config%20PLATFORM_EC_I2C"&ss=chromiumos +[CONFIG_I2C_SHELL]: https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_I2C_SHELL.html +[I2C Debug]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q=PLATFORM_EC_I2C_DEBUG&sq=&ss=chromiumos +[I2C Debug Passthru]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig;?q=PLATFORM_EC_I2C_DEBUG_PASSTHRU&ss=chromiumos +[I2C Portmap]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP&ss=chromiumos%2Fchromiumos%2Fcodesearch +[I2C Speed]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_CONSOLE_CMD_I2C_SPEED&ss=chromiumos +[I2C Control]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_HOSTCMD_I2C_CONTROL&ss=chromiumos +[I2C Passthru Restricted]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=PLATFORM_EC_I2C_PASSTHRU_RESTRICTED&ss=chromiumos +[cros-ec-i2c-port-base.yaml]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml +[volteer.dts]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/boards/arm/volteer/volteer.dts; diff --git a/docs/zephyr_init.md b/docs/zephyr/zephyr_init.md index 8822736efb..8822736efb 100644 --- a/docs/zephyr_init.md +++ b/docs/zephyr/zephyr_init.md diff --git a/docs/zephyr/zephyr_new_board_checklist.md b/docs/zephyr/zephyr_new_board_checklist.md new file mode 100644 index 0000000000..c90bd4e2f2 --- /dev/null +++ b/docs/zephyr/zephyr_new_board_checklist.md @@ -0,0 +1,65 @@ +# Creating a New Zephyr EC Project + +[TOC] + +## Overview + +This document describes the high-level steps needed to create a new Zephyr EC +project for a Chromebook design. + +## Intended Audience + +This document is for use by software engineers working in the EC codebase. This +document and the linked documents provide a guide for creating new Zephyr EC +projects and for modifying/maintaining existing Zephyr EC projects. + +## How to use this document + +The following sections detail a single feature set that needs modification for +your board design. Each feature set can be implemented with a reasonably sized +change list, and can be worked on independently. + +Each feature includes the following sub-tasks: + +- **Kconfig Options** - This section details the `Kconfig` options relevant to + the feature. `Kconfig` options are enabled in one of the [project + configuration files]. +- **Devicetree Nodes** - This section details the devicetree nodes and + properties required by the feature. +- **Board Specific Code** - When present, this section details any C code that + your project must implement. +- **Threads** - This section details the threads created by the feature and + provides an overview of each thread. +- **Testing and Debugging** - This section details strategies for testing the EC + feature set and for debugging issues. This section also documents EC console + commands related to the feature set. +- **Example** - This section walks through a complete example for configuring an + EC feature based on existing board implementation. + +## Adding a new board to zmake + +Refer the [zmake](TODO) documentation to add a new board project to zmake. + +## Configure EC Features + +The checklist below provides an overview of EC features that you must configure +for correct operation of a Chromebook. The “Needed for Power On” column +indicates the critical features needed during board bringup. Use the +documentation link for details about the code changes required to implement each +feature. + +EC Feature | Needed for Power On +:-------------------------------------------------------------------------- | :-----------------: +[Configure EC Chipset (TODO)](./zephyr_template.md) | yes +[Configure AP to EC Communication (TOD0)](./zephyr_template.md) | yes +[Configure AP Power Sequencing (TODO)](./zephyr_template.md) | yes +[Configure USB-C (TODO)](./zephyr_template.md) | yes +[Configure Charger (TODO)](./zephyr_template.md) | yes +[Configure I2C Buses (TODO)](./zephyr_template.md) | yes +[Configure Batteries (TODO)](./zephyr_template.md) | no +[Configure CrOS Board Information (CBI) (TODO)](./zephyr_template.md) | no +[Configure Keyboard (TODO)](./zephyr_template.md) | no +[Configure LEDs (TODO)](./zephyr_template.md) | no +[Configure Motion Sensors (TODO)](./zephyr_template.md) | no +[Configure BC1.2 Charger Detector (TODO)](./zephyr_template.md) | no +[Configure Battery (TODO)](./zephyr_template.md) | no diff --git a/docs/zephyr_poc_device_bringup.md b/docs/zephyr/zephyr_poc_device_bringup.md index 394aa4a05b..394aa4a05b 100644 --- a/docs/zephyr_poc_device_bringup.md +++ b/docs/zephyr/zephyr_poc_device_bringup.md diff --git a/docs/zephyr_shim.md b/docs/zephyr/zephyr_shim.md index fac0383aff..fac0383aff 100644 --- a/docs/zephyr_shim.md +++ b/docs/zephyr/zephyr_shim.md diff --git a/docs/zephyr/zephyr_template.md b/docs/zephyr/zephyr_template.md new file mode 100644 index 0000000000..f75883eec9 --- /dev/null +++ b/docs/zephyr/zephyr_template.md @@ -0,0 +1,56 @@ +# Zephyr EC Feature Configuration Template + +[TOC] + +## Overview + +*Description of the Zephyr EC feature and the capabilities provided* + +## Kconfig Options + +*List the Kconfig options that enable the feature and list any sub-configuration +options that control the behavior of the feature.* + +Kconfig Option | Default | Documentation +:------------------------------------- | :-----: | :------------ +`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig) + +Kconfig sub-option | Default | Documentation +:------------------------------------- | :-----: | :------------ +`CONFIG_PLATFORM_EC_<option>` | y/n | [zephyr/Kconfig](../zephyr/Kconfig) + + +*Note - Avoid documenting `CONFIG_` options in the markdown as the relevant +`Kconfig*` contains the authoritative definition. Link directly to the Kconfig +option in source like this: [I2C Passthru Restricted].* + +## Devicetree Nodes + +*Detail the devicetree nodes that configure the feature.* + +*Note - avoid documenting node properties here. Point to the relevant `.yaml` +file instead, which contains the authoritative definition.* + +## Board Specific Code + +*Document any board specific routines that a user must create to successfully +compile and run. For many features, this can section can be empty.* + +## Threads + +*Document any threads enabled by this feature.* + +## Testing and Debugging + +*Provide any tips for testing and debugging the EC feature.* + +## Example + +*Provide code snippets from a working board to walk the user through +all code that must be created to enable this feature.* + +<!-- +The following demonstrates linking to a code search result for a Kconfig option. +Reference this link in your text by matching the text in brackets exactly. +--> +[I2C Passthru Restricted]:https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/Kconfig?q=%22config%20PLATFORM_EC_I2C_PASSTHRU_RESTRICTED%22&ss=chromiumos diff --git a/docs/ztest.md b/docs/zephyr/ztest.md index 021b3391bd..021b3391bd 100644 --- a/docs/ztest.md +++ b/docs/zephyr/ztest.md diff --git a/driver/accel_lis2ds.c b/driver/accel_lis2ds.c index 93272262ad..ad1a7e0e36 100644 --- a/driver/accel_lis2ds.c +++ b/driver/accel_lis2ds.c @@ -89,12 +89,8 @@ __maybe_unused static int lis2ds_config_interrupt(const struct motion_sensor_t * int ret = EC_SUCCESS; /* Interrupt trigger level of power-on-reset is HIGH */ - if (!(s->flags & MOTIONSENSE_FLAG_INT_ACTIVE_HIGH)) { - ret = st_write_data_with_mask(s, LIS2DS_H_ACTIVE_ADDR, - LIS2DS_H_ACTIVE_MASK, LIS2DS_EN_BIT); - if (ret != EC_SUCCESS) - return ret; - } + RETURN_ERROR(st_write_data_with_mask(s, LIS2DS_H_ACTIVE_ADDR, + LIS2DS_H_ACTIVE_MASK, LIS2DS_EN_BIT)); if (IS_ENABLED(CONFIG_ACCEL_FIFO)) { /* diff --git a/driver/accel_lis2dw12.c b/driver/accel_lis2dw12.c index 1872e572f2..f8e9c305cb 100644 --- a/driver/accel_lis2dw12.c +++ b/driver/accel_lis2dw12.c @@ -64,7 +64,7 @@ static __maybe_unused int lis2dw12_enable_fifo(const struct motion_sensor_t *s, * @s: Motion sensor pointer */ static __maybe_unused int lis2dw12_load_fifo(struct motion_sensor_t *s, - int nsamples, uint32_t *last_fifo_read_ts) + int nsamples) { int ret, left, length, i; struct ec_response_motion_sensor_data vect; @@ -87,7 +87,6 @@ static __maybe_unused int lis2dw12_load_fifo(struct motion_sensor_t *s, ret = st_raw_read_n(s->port, s->i2c_spi_addr_flags, LIS2DW12_OUT_X_L_ADDR, fifo, length); - *last_fifo_read_ts = __hw_clock_source_read(); if (ret != EC_SUCCESS) return ret; @@ -107,8 +106,6 @@ static __maybe_unused int lis2dw12_load_fifo(struct motion_sensor_t *s, left -= length; } while (left > 0); - motion_sense_fifo_commit_data(); - return EC_SUCCESS; } @@ -130,21 +127,6 @@ static __maybe_unused int lis2dw12_get_fifo_samples(struct motion_sensor_t *s, return EC_SUCCESS; } -static __maybe_unused int fifo_data_avail(struct motion_sensor_t *s) -{ - int ret, nsamples; - - if (s->flags & MOTIONSENSE_FLAG_INT_SIGNAL) - return gpio_get_level(s->int_signal) == - !!(MOTIONSENSE_FLAG_INT_ACTIVE_HIGH & s->flags); - - ret = lis2dw12_get_fifo_samples(s, &nsamples); - /* If we failed to read the FIFO size assume empty. */ - if (ret != EC_SUCCESS) - return 0; - return nsamples; -} - /** * lis2dw12_config_interrupt- Configure interrupt for supported features. * @s: Motion sensor pointer @@ -211,22 +193,16 @@ static __maybe_unused int lis2dw12_config_interrupt( } #ifdef LIS2DW12_ENABLE_FIFO -static void lis2dw12_handle_interrupt_for_fifo(uint32_t ts) -{ - if (IS_ENABLED(CONFIG_ACCEL_FIFO) && - time_after(ts, last_interrupt_timestamp)) - last_interrupt_timestamp = ts; - - task_set_event(TASK_ID_MOTIONSENSE, CONFIG_ACCEL_LIS2DW12_INT_EVENT); -} - /** * lis2dw12_interrupt - interrupt from int pin of sensor * Schedule Motion Sense Task to manage Interrupts. */ void lis2dw12_interrupt(enum gpio_signal signal) { - lis2dw12_handle_interrupt_for_fifo(__hw_clock_source_read()); + if (IS_ENABLED(LIS2DW12_ENABLE_FIFO)) + last_interrupt_timestamp = __hw_clock_source_read(); + + task_set_event(TASK_ID_MOTIONSENSE, CONFIG_ACCEL_LIS2DW12_INT_EVENT); } /** @@ -235,8 +211,6 @@ void lis2dw12_interrupt(enum gpio_signal signal) static int lis2dw12_irq_handler(struct motion_sensor_t *s, uint32_t *event) { - int ret = EC_SUCCESS; - if ((s->type != MOTIONSENSE_TYPE_ACCEL) || (!(*event & CONFIG_ACCEL_LIS2DW12_INT_EVENT))) { return EC_ERROR_NOT_HANDLED; @@ -254,39 +228,28 @@ static int lis2dw12_irq_handler(struct motion_sensor_t *s, } if (IS_ENABLED(CONFIG_ACCEL_FIFO)) { + bool commit_needed = false; int nsamples; - uint32_t last_fifo_read_ts; - uint32_t triggering_interrupt_timestamp = - last_interrupt_timestamp; - - ret = lis2dw12_get_fifo_samples(s, &nsamples); - if (ret != EC_SUCCESS) - return ret; - last_fifo_read_ts = __hw_clock_source_read(); - if (nsamples == 0) - return EC_SUCCESS; + do { + RETURN_ERROR(lis2dw12_get_fifo_samples(s, &nsamples)); - ret = lis2dw12_load_fifo(s, nsamples, &last_fifo_read_ts); + if (nsamples != 0) { + commit_needed = true; + RETURN_ERROR(lis2dw12_load_fifo(s, nsamples)); + } + } while (nsamples != 0); - /* - * Check if FIFO isn't empty and we never got an interrupt. - * This can happen if new entries were added to the FIFO after - * the count was read, but before the FIFO was cleared out. - * In the long term it might be better to use the last - * spread timestamp instead. - */ - if (fifo_data_avail(s) && - triggering_interrupt_timestamp == last_interrupt_timestamp) - lis2dw12_handle_interrupt_for_fifo(last_fifo_read_ts); + if (commit_needed) + motion_sense_fifo_commit_data(); } - return ret; + return EC_SUCCESS; } #endif /** - * set_power_mode - set sensor power mode + * lis2dw12_set_power_mode - set sensor power mode * @s: Motion sensor pointer * @mode: LIS2DW12_LOW_POWER, LIS2DW12_HIGH_PERF * @lpmode: LIS2DW12_LOW_POWER_MODE_2, @@ -296,9 +259,10 @@ static int lis2dw12_irq_handler(struct motion_sensor_t *s, * TODO: LIS2DW12_LOW_POWER_MODE_1 not implemented because output differ * in resolution */ -static int set_power_mode(const struct motion_sensor_t *s, - enum lis2sw12_mode mode, - enum lis2sw12_lpmode lpmode) +STATIC_IF_NOT(CONFIG_ZTEST) +int lis2dw12_set_power_mode(const struct motion_sensor_t *s, + enum lis2sw12_mode mode, + enum lis2sw12_lpmode lpmode) { int ret = EC_SUCCESS; @@ -425,9 +389,6 @@ static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd) if (reg_val > LIS2DW12_ODR_1_6kHZ_VAL) { reg_val = LIS2DW12_ODR_1_6kHZ_VAL; normalized_rate = LIS2DW12_ODR_MAX_VAL; - } else if (reg_val < LIS2DW12_ODR_12HZ_VAL) { - reg_val = LIS2DW12_ODR_12HZ_VAL; - normalized_rate = LIS2DW12_ODR_MIN_VAL; } /* lis2dwl supports 14 bit resolution only at high performance mode, @@ -436,9 +397,9 @@ static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd) */ if (!IS_ENABLED(CONFIG_ACCEL_LIS2DWL)) { if (reg_val > LIS2DW12_ODR_200HZ_VAL) - ret = set_power_mode(s, LIS2DW12_HIGH_PERF, 0); + ret = lis2dw12_set_power_mode(s, LIS2DW12_HIGH_PERF, 0); else - ret = set_power_mode(s, LIS2DW12_LOW_POWER, + ret = lis2dw12_set_power_mode(s, LIS2DW12_LOW_POWER, LIS2DW12_LOW_POWER_MODE_2); } @@ -555,8 +516,7 @@ static int init(struct motion_sensor_t *s) goto err_unlock; /* Interrupt trigger level of power-on-reset is HIGH */ - if (IS_ENABLED(LIS2DW12_ENABLE_FIFO) && - !(MOTIONSENSE_FLAG_INT_ACTIVE_HIGH & s->flags)) { + if (IS_ENABLED(LIS2DW12_ENABLE_FIFO)) { ret = st_write_data_with_mask(s, LIS2DW12_H_ACTIVE_ADDR, LIS2DW12_H_ACTIVE_MASK, LIS2DW12_EN_BIT); @@ -569,10 +529,10 @@ static int init(struct motion_sensor_t *s) * lis2dwl supports 14 bit resolution only * at high performance mode */ - ret = set_power_mode(s, LIS2DW12_HIGH_PERF, 0); + ret = lis2dw12_set_power_mode(s, LIS2DW12_HIGH_PERF, 0); else /* Set default Mode and Low Power Mode. */ - ret = set_power_mode(s, LIS2DW12_LOW_POWER, + ret = lis2dw12_set_power_mode(s, LIS2DW12_LOW_POWER, LIS2DW12_LOW_POWER_MODE_2); if (ret != EC_SUCCESS) goto err_unlock; diff --git a/driver/accel_lis2dw12.h b/driver/accel_lis2dw12.h index 8e1c97464c..9d0be0ac0a 100644 --- a/driver/accel_lis2dw12.h +++ b/driver/accel_lis2dw12.h @@ -45,6 +45,11 @@ #define LIS2DW12_FIFO_THS_UP 0x80 #define LIS2DW12_OUT_X_L_ADDR 0x28 +#define LIS2DW12_OUT_X_H_ADDR 0x29 +#define LIS2DW12_OUT_Y_L_ADDR 0x2a +#define LIS2DW12_OUT_Y_H_ADDR 0x2b +#define LIS2DW12_OUT_Z_L_ADDR 0x2c +#define LIS2DW12_OUT_Z_H_ADDR 0x2d #define LIS2DW12_FIFO_CTRL_ADDR 0x2e @@ -206,4 +211,16 @@ enum lis2dw12_fs { */ #define LIS2DW12_RESOLUTION 14 +/** Maximum possible sample */ +#define LIS2DW12_SAMPLE_MAX ((1<<(LIS2DW12_RESOLUTION-1))-1) + +/** Smallest possible sample */ +#define LIS2DW12_SAMPLE_MIN (-(1<<(LIS2DW12_RESOLUTION-1))) + +#ifdef CONFIG_ZTEST +int lis2dw12_set_power_mode(const struct motion_sensor_t *s, + enum lis2sw12_mode mode, + enum lis2sw12_lpmode lpmode); +#endif + #endif /* __CROS_EC_ACCEL_LIS2DW12_H */ diff --git a/driver/accelgyro_bmi3xx.c b/driver/accelgyro_bmi3xx.c index febe97a7aa..4b525c94df 100644 --- a/driver/accelgyro_bmi3xx.c +++ b/driver/accelgyro_bmi3xx.c @@ -370,6 +370,43 @@ static int read_temp(const struct motion_sensor_t *s, int *temp_ptr) return EC_ERROR_UNIMPLEMENTED; } +static int reset_offset(const struct motion_sensor_t *s, uint8_t offset_en) +{ + uint8_t offset_sel[2] = { BMI3_REG_UGAIN_OFF_SEL, 0 }; + uint8_t reg_data[4] = { 0 }; + + /* Reset the existing offset values by setting the bits in DMA*/ + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, + offset_sel, 2)); + + reg_data[0] = offset_en; + reg_data[1] = 0; + + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, + reg_data, 2)); + + /* Update the offset change to the sensor engine */ + reg_data[0] = (uint8_t)(BMI3_CMD_USR_GAIN_OFFS_UPDATE & + BMI3_SET_LOW_BYTE); + reg_data[1] = (uint8_t)((BMI3_CMD_USR_GAIN_OFFS_UPDATE & + BMI3_SET_HIGH_BYTE) >> 8); + RETURN_ERROR(bmi3_write_n(s, BMI3_REG_CMD, reg_data, 2)); + + /* Delay time for offset update */ + msleep(OFFSET_UPDATE_DELAY); + + /* Read the configuration from the feature engine register */ + RETURN_ERROR(bmi3_read_n(s, BMI3_FEATURE_IO_1, reg_data, 4)); + + if ((reg_data[3] & BMI3_UGAIN_OFFS_UPD_COMPLETE) + && ((reg_data[2] & BMI3_FEATURE_IO_1_ERROR_MASK) + == BMI3_FEATURE_IO_1_NO_ERROR)) { + return EC_SUCCESS; + } + + return EC_ERROR_NOT_CALIBRATED; +} + int get_gyro_offset(const struct motion_sensor_t *s, intv3_t v) { int i; @@ -393,28 +430,25 @@ int get_gyro_offset(const struct motion_sensor_t *s, intv3_t v) return EC_SUCCESS; } -int set_gyro_offset(const struct motion_sensor_t *s, intv3_t v) +static int write_gyro_offset(const struct motion_sensor_t *s, int *val) { uint8_t reg_data[6] = { 0 }; uint8_t base_addr[2] = { BMI3_GYRO_OFFSET_ADDR, 0 }; - int i, val[3]; - - for (i = X; i <= Z; ++i) { - val[i] = round_divide((int64_t)v[i] * BMI_OFFSET_GYRO_DIV_MDS, - BMI_OFFSET_GYRO_MULTI_MDS); - if (val[i] > 511) - val[i] = 511; - if (val[i] < -512) - val[i] = -512; - if (val[i] < 0) - val[i] = 1024 + val[i]; - } + uint8_t offset_sel[2] = { BMI3_REG_UGAIN_OFF_SEL, 0 }; + /* Enable user gain/offset update*/ + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, + offset_sel, 2)); + reg_data[0] = 0; + reg_data[1] = 0; + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, + reg_data, 2)); /* - * Set the user accel offset base address to feature engine + * Set the user gyro offset base address to feature engine * transmission address to start DMA transaction */ - RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, base_addr, 2)); + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, + base_addr, 2)); reg_data[0] = (uint8_t)(val[0] & BMI3_SET_LOW_BYTE); reg_data[1] = (uint8_t)((val[0] & 0x0300) >> 8); @@ -424,16 +458,66 @@ int set_gyro_offset(const struct motion_sensor_t *s, intv3_t v) reg_data[5] = (uint8_t)((val[2] & 0x0300) >> 8); /* Set the configuration to the feature engine register */ - RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, reg_data, - 6)); + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, + reg_data, 6)); /* Update the offset to the sensor engine */ reg_data[0] = (uint8_t)(BMI3_CMD_USR_GAIN_OFFS_UPDATE & BMI3_SET_LOW_BYTE); reg_data[1] = (uint8_t)((BMI3_CMD_USR_GAIN_OFFS_UPDATE & - BMI3_SET_HIGH_BYTE) >> 8); + BMI3_SET_HIGH_BYTE) >> 8); RETURN_ERROR(bmi3_write_n(s, BMI3_REG_CMD, reg_data, 2)); + msleep(OFFSET_UPDATE_DELAY); + + /* Read the configuration from the feature engine register */ + RETURN_ERROR(bmi3_read_n(s, BMI3_FEATURE_IO_1, reg_data, 4)); + + if ((reg_data[3] & BMI3_UGAIN_OFFS_UPD_COMPLETE) + && ((reg_data[2] & BMI3_FEATURE_IO_1_ERROR_MASK) + == BMI3_FEATURE_IO_1_NO_ERROR)) { + return EC_SUCCESS; + } + + return EC_ERROR_NOT_CALIBRATED; +} + +int set_gyro_offset(const struct motion_sensor_t *s, intv3_t v) +{ + uint8_t reg_data[4] = { 0 }; + uint8_t saved_conf[6] = { 0 }; + int i, val[3]; + + for (i = X; i <= Z; ++i) { + val[i] = round_divide((int64_t)v[i] * BMI_OFFSET_GYRO_DIV_MDS, + BMI_OFFSET_GYRO_MULTI_MDS); + if (val[i] > 511) + val[i] = 511; + if (val[i] < -512) + val[i] = -512; + if (val[i] < 0) + val[i] = 1024 + val[i]; + } + + /* Set the power mode as suspend */ + RETURN_ERROR(bmi3_read_n(s, BMI3_REG_ACC_CONF, saved_conf, 6)); + + /* Disable accelerometer and gyroscope */ + reg_data[0] = saved_conf[2]; + reg_data[1] = 0x00; + reg_data[2] = saved_conf[4]; + reg_data[3] = 0x00; + RETURN_ERROR(bmi3_write_n(s, BMI3_REG_ACC_CONF, reg_data, 4)); + + /* Reset the existing offset values */ + RETURN_ERROR(reset_offset(s, 2)); + + /* Set the gyro offset in the sensor registers */ + RETURN_ERROR(write_gyro_offset(s, val)); + + /* Restore ACC_CONF by storing saved_conf data */ + RETURN_ERROR(bmi3_write_n(s, BMI3_REG_ACC_CONF, &saved_conf[2], 4)); + return EC_SUCCESS; } @@ -460,10 +544,64 @@ int get_accel_offset(const struct motion_sensor_t *s, intv3_t v) return EC_SUCCESS; } -int set_accel_offset(const struct motion_sensor_t *s, intv3_t v) +static int write_accel_offsets(const struct motion_sensor_t *s, int *val) { - uint8_t reg_data[6] = { 0 }; uint8_t base_addr[2] = { BMI3_ACC_OFFSET_ADDR, 0 }; + uint8_t offset_sel[2] = { BMI3_REG_UGAIN_OFF_SEL, 0 }; + uint8_t reg_data[6] = {0}; + + /* Enable user gain/offset update*/ + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, + offset_sel, 2)); + reg_data[0] = 0; + reg_data[1] = 0; + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, + reg_data, 2)); + /* + * Set the user accel offset base address to feature engine + * transmission address to start DMA transaction + */ + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, + base_addr, 2)); + + reg_data[0] = (uint8_t)(val[0] & BMI3_SET_LOW_BYTE); + reg_data[1] = (uint8_t)((val[0] & 0x1F00) >> 8); + reg_data[2] = (uint8_t)(val[1] & BMI3_SET_LOW_BYTE); + reg_data[3] = (uint8_t)((val[1] & 0x1F00) >> 8); + reg_data[4] = (uint8_t)(val[2] & BMI3_SET_LOW_BYTE); + reg_data[5] = (uint8_t)((val[2] & 0x1F00) >> 8); + + /* Set the configuration to the feature engine register */ + RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, + reg_data, 6)); + + /* Update the offset to the sensor engine */ + reg_data[0] = (uint8_t)(BMI3_CMD_USR_GAIN_OFFS_UPDATE & + BMI3_SET_LOW_BYTE); + + reg_data[1] = (uint8_t)((BMI3_CMD_USR_GAIN_OFFS_UPDATE & + BMI3_SET_HIGH_BYTE) >> 8); + + RETURN_ERROR(bmi3_write_n(s, BMI3_REG_CMD, reg_data, 2)); + + msleep(OFFSET_UPDATE_DELAY); + + /* Read the configuration from the feature engine register */ + RETURN_ERROR(bmi3_read_n(s, BMI3_FEATURE_IO_1, reg_data, 4)); + + if ((reg_data[3] & BMI3_UGAIN_OFFS_UPD_COMPLETE) + && ((reg_data[2] & BMI3_FEATURE_IO_1_ERROR_MASK) + == BMI3_FEATURE_IO_1_NO_ERROR)) { + return EC_SUCCESS; + } + + return EC_ERROR_NOT_CALIBRATED; +} + +int set_accel_offset(const struct motion_sensor_t *s, intv3_t v, + uint8_t reset_en) +{ + uint8_t reg_data[4] = { 0 }; uint8_t saved_conf[6] = { 0 }; int i, val[3]; @@ -488,31 +626,14 @@ int set_accel_offset(const struct motion_sensor_t *s, intv3_t v) reg_data[3] = 0x00; RETURN_ERROR(bmi3_write_n(s, BMI3_REG_ACC_CONF, reg_data, 4)); - /* - * Set the user accel offset base address to feature engine - * transmission address to start DMA transaction - */ - RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, base_addr, 2)); - - reg_data[0] = (uint8_t)(val[0] & BMI3_SET_LOW_BYTE); - reg_data[1] = (uint8_t)((val[0] & 0x1F00) >> 8); - reg_data[2] = (uint8_t)(val[1] & BMI3_SET_LOW_BYTE); - reg_data[3] = (uint8_t)((val[1] & 0x1F00) >> 8); - reg_data[4] = (uint8_t)(val[2] & BMI3_SET_LOW_BYTE); - reg_data[5] = (uint8_t)((val[2] & 0x1F00) >> 8); - - /* Set the configuration to the feature engine register */ - RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX_DATA, reg_data, - 6)); - - /* Update the offset to the sensor engine */ - reg_data[0] = (uint8_t)(BMI3_CMD_USR_GAIN_OFFS_UPDATE & - BMI3_SET_LOW_BYTE); - - reg_data[1] = (uint8_t)((BMI3_CMD_USR_GAIN_OFFS_UPDATE & - BMI3_SET_HIGH_BYTE) >> 8); + /* Reset the existing offset values */ + if (reset_en) { + /* Reset is only done for writing offset and not for FOC */ + RETURN_ERROR(reset_offset(s, 1)); + } - RETURN_ERROR(bmi3_write_n(s, BMI3_REG_CMD, reg_data, 2)); + /* Set the accel offset in the sensor registers */ + RETURN_ERROR(write_accel_offsets(s, val)); /* Restore ACC_CONF by storing saved_conf data */ RETURN_ERROR(bmi3_write_n(s, BMI3_REG_ACC_CONF, &saved_conf[2], 4)); @@ -585,7 +706,10 @@ static int8_t perform_accel_foc(struct motion_sensor_t *s, int *target, rotate_inv(offset, *s->rot_standard_ref, offset); - RETURN_ERROR(set_accel_offset(s, offset)); + /* Set accel offset without resetting the existing offsets + * since we calculated the bias with the existing offsets + */ + RETURN_ERROR(set_accel_offset(s, offset, BMI3_DISABLE)); return EC_SUCCESS; } @@ -596,7 +720,7 @@ static int set_gyro_foc_config(struct motion_sensor_t *s) uint8_t base_addr[2] = { BMI3_BASE_ADDR_SC, 0 }; /* - * Set the user accel offset base address to feature engine + * Set the FOC base address to feature engine * transmission address to start DMA transaction */ RETURN_ERROR(bmi3_write_n(s, BMI3_FEATURE_ENGINE_DMA_TX, base_addr, 2)); @@ -629,7 +753,7 @@ static int get_calib_result(struct motion_sensor_t *s) for (i = 0; i < 25; i++) { /* A delay of 120ms is required to read this status register */ - msleep(120); + msleep(OFFSET_UPDATE_DELAY); /* Read the configuration from the feature engine register */ RETURN_ERROR(bmi3_read_n(s, BMI3_FEATURE_IO_1, reg_data, 4)); @@ -768,7 +892,7 @@ static int set_offset(const struct motion_sensor_t *s, switch (s->type) { case MOTIONSENSE_TYPE_ACCEL: /* Offset should be in units of mg */ - RETURN_ERROR(set_accel_offset(s, v)); + RETURN_ERROR(set_accel_offset(s, v, BMI3_ENABLE)); break; case MOTIONSENSE_TYPE_GYRO: /* Offset should be in units of mdps */ diff --git a/driver/accelgyro_bmi3xx.h b/driver/accelgyro_bmi3xx.h index b52d503f92..afd6855bc0 100644 --- a/driver/accelgyro_bmi3xx.h +++ b/driver/accelgyro_bmi3xx.h @@ -50,7 +50,7 @@ #define BMI3_REG_GYR_CONF 0x21 #define BMI3_REG_INT_MAP1 0x3A #define BMI3_REG_FIFO_WATERMARK 0x35 - +#define BMI3_REG_UGAIN_OFF_SEL 0x3F #define BMI3_REG_FIFO_CONF 0x36 #define BMI3_FIFO_STOP_ON_FULL 0x01 #define BMI3_FIFO_TIME_EN 0x01 @@ -106,9 +106,10 @@ #define BMI3_ACC_FOC_16G_REF 2048 #define BMI3_FOC_SAMPLE_LIMIT 32 -/* 20ms delay for 50Hz ODR */ #define FOC_TRY_COUNT 5 +/* 20ms delay for 50Hz ODR */ #define FOC_DELAY 20 +#define OFFSET_UPDATE_DELAY 120 #define BMI3_INT_STATUS_FWM 0x4000 #define BMI3_INT_STATUS_FFULL 0x8000 #define BMI3_INT_STATUS_ORIENTATION 0x0008 diff --git a/driver/accelgyro_icm42607.c b/driver/accelgyro_icm42607.c index ae831c5918..2a2c68bc17 100644 --- a/driver/accelgyro_icm42607.c +++ b/driver/accelgyro_icm42607.c @@ -26,6 +26,27 @@ #define CPRINTF(format, args...) cprintf(CC_ACCEL, format, ## args) #define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args) +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_ACCEL_INTERRUPTS) + +/* Get the motion sensor ID of the ICM42607 sensor that generates the interrupt. + * The interrupt is converted to the event and transferred to motion sense task + * that actually handles the interrupt. + * + * Here we use an alias (icm42607_int) to get the motion sensor ID. This alias + * MUST be defined for this driver to work. + * aliases { + * icm42607-int = &base_accel; + * }; + */ +#if DT_NODE_EXISTS(DT_ALIAS(icm42607_int)) +#define CONFIG_ACCELGYRO_ICM42607_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(SENSOR_ID(DT_ALIAS(icm42607_int))) +#else +#error Missing aliases/icm42607-int in device tree +#endif + +#endif /* defined(CONFIG_ZEPHYR) && defined(CONFIG_ACCEL_INTERRUPTS) */ + STATIC_IF(CONFIG_ACCEL_FIFO) volatile uint32_t last_interrupt_timestamp; static int icm_switch_on_mclk(const struct motion_sensor_t *s) diff --git a/driver/accelgyro_icm426xx.c b/driver/accelgyro_icm426xx.c index 68d45c4a6a..6f916b5559 100644 --- a/driver/accelgyro_icm426xx.c +++ b/driver/accelgyro_icm426xx.c @@ -326,13 +326,8 @@ static int icm426xx_config_interrupt(const struct motion_sensor_t *s) int val, ret; /* configure INT1 pin */ - val = ICM426XX_INT1_PUSH_PULL; - if (s->flags & MOTIONSENSE_FLAG_INT_ACTIVE_HIGH) - val |= ICM426XX_INT1_ACTIVE_HIGH; - - ret = icm_write8(s, ICM426XX_REG_INT_CONFIG, val); - if (ret != EC_SUCCESS) - return ret; + RETURN_ERROR(icm_write8(s, ICM426XX_REG_INT_CONFIG, + ICM426XX_INT1_PUSH_PULL)); /* deassert async reset for proper INT pin operation */ ret = icm_field_update8(s, ICM426XX_REG_INT_CONFIG1, diff --git a/driver/accelgyro_lsm6dsm.c b/driver/accelgyro_lsm6dsm.c index cffb721aa7..3b743aaa3f 100644 --- a/driver/accelgyro_lsm6dsm.c +++ b/driver/accelgyro_lsm6dsm.c @@ -24,8 +24,6 @@ #define CPRINTF(format, args...) cprintf(CC_ACCEL, format, ## args) #define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args) -#define IS_FSTS_EMPTY(s) ((s).len & LSM6DSM_FIFO_EMPTY) - #ifndef FIFO_READ_LEN #define FIFO_READ_LEN 0 #endif @@ -34,7 +32,7 @@ #define CONFIG_ACCEL_LSM6DSM_INT_EVENT 0 #endif -static volatile uint32_t last_interrupt_timestamp; +STATIC_IF(CONFIG_ACCEL_FIFO) volatile uint32_t last_interrupt_timestamp; /** * Gets the sensor type associated with the dev_fifo enum. This type can be used @@ -337,8 +335,7 @@ static void push_fifo_data(struct motion_sensor_t *accel, uint8_t *fifo, } } -static int load_fifo(struct motion_sensor_t *s, const struct fstatus *fsts, - uint32_t *last_fifo_read_ts) +static int load_fifo(struct motion_sensor_t *s, const struct fstatus *fsts) { uint32_t interrupt_timestamp = last_interrupt_timestamp; int err, left, length; @@ -352,12 +349,6 @@ static int load_fifo(struct motion_sensor_t *s, const struct fstatus *fsts, left *= sizeof(uint16_t); left = (left / OUT_XYZ_SIZE) * OUT_XYZ_SIZE; - /* - * TODO(b/122912601): phaser360: Investigate Standard Deviation error - * during CtsSensorTests - * - check "pattern" register versus where code thinks it is parsing - */ - /* Push all data on upper side. */ do { /* Fit len to pre-allocated static buffer. */ @@ -370,7 +361,6 @@ static int load_fifo(struct motion_sensor_t *s, const struct fstatus *fsts, err = st_raw_read_n_noinc(s->port, s->i2c_spi_addr_flags, LSM6DSM_FIFO_DATA_ADDR, fifo, length); - *last_fifo_read_ts = __hw_clock_source_read(); if (err != EC_SUCCESS) return err; @@ -381,46 +371,22 @@ static int load_fifo(struct motion_sensor_t *s, const struct fstatus *fsts, * where we empty the FIFO, and a new IRQ comes in between * reading the last sample and pushing it into the FIFO. */ - push_fifo_data(s, fifo, length, interrupt_timestamp); left -= length; } while (left > 0); - motion_sense_fifo_commit_data(); - return EC_SUCCESS; } -static int is_fifo_empty(struct motion_sensor_t *s, struct fstatus *fsts) -{ - int res; - - if (s->flags & MOTIONSENSE_FLAG_INT_SIGNAL) - return gpio_get_level(s->int_signal); - CPRINTS("Interrupt signal not set for %s", s->name); - res = st_raw_read_n_noinc(s->port, s->i2c_spi_addr_flags, - LSM6DSM_FIFO_STS1_ADDR, - (int8_t *)fsts, sizeof(*fsts)); - /* If we failed to read the FIFO size assume empty. */ - if (res != EC_SUCCESS) - return 1; - return IS_FSTS_EMPTY(*fsts); -} - -static void handle_interrupt_for_fifo(uint32_t ts) -{ - if (IS_ENABLED(CONFIG_ACCEL_FIFO) && - time_after(ts, last_interrupt_timestamp)) - last_interrupt_timestamp = ts; - task_set_event(TASK_ID_MOTIONSENSE, CONFIG_ACCEL_LSM6DSM_INT_EVENT); -} - /** * lsm6dsm_interrupt - interrupt from int1/2 pin of sensor */ void lsm6dsm_interrupt(enum gpio_signal signal) { - handle_interrupt_for_fifo(__hw_clock_source_read()); + if (IS_ENABLED(CONFIG_ACCEL_FIFO)) + last_interrupt_timestamp = __hw_clock_source_read(); + + task_set_event(TASK_ID_MOTIONSENSE, CONFIG_ACCEL_LSM6DSM_INT_EVENT); } /** @@ -429,43 +395,36 @@ void lsm6dsm_interrupt(enum gpio_signal signal) __maybe_unused static int irq_handler( struct motion_sensor_t *s, uint32_t *event) { - int ret = EC_SUCCESS; - if ((s->type != MOTIONSENSE_TYPE_ACCEL) || (!(*event & CONFIG_ACCEL_LSM6DSM_INT_EVENT))) return EC_ERROR_NOT_HANDLED; if (IS_ENABLED(CONFIG_ACCEL_FIFO)) { struct fstatus fsts; - uint32_t last_fifo_read_ts; - uint32_t triggering_interrupt_timestamp = - last_interrupt_timestamp; - - /* Read how many data pattern on FIFO to read and pattern. */ - ret = st_raw_read_n_noinc(s->port, s->i2c_spi_addr_flags, - LSM6DSM_FIFO_STS1_ADDR, - (uint8_t *)&fsts, sizeof(fsts)); - if (ret != EC_SUCCESS) - return ret; - last_fifo_read_ts = __hw_clock_source_read(); - if (fsts.len & (LSM6DSM_FIFO_DATA_OVR | LSM6DSM_FIFO_FULL)) - CPRINTS("%s FIFO Overrun: %04x", s->name, fsts.len); - if (!IS_FSTS_EMPTY(fsts)) - ret = load_fifo(s, &fsts, &last_fifo_read_ts); - - /* - * Check if FIFO isn't empty and we never got an interrupt. - * This can happen if new entries were added to the FIFO after - * the count was read, but before the FIFO was cleared out. - * In the long term it might be better to use the last - * spread timestamp instead. - */ - if (!is_fifo_empty(s, &fsts) && - triggering_interrupt_timestamp == last_interrupt_timestamp) - handle_interrupt_for_fifo(last_fifo_read_ts); + int fifo_empty = false; + bool commit_needed = false; + + while (!fifo_empty) { + /* Read how many data pattern on FIFO to read. */ + RETURN_ERROR(st_raw_read_n_noinc(s->port, + s->i2c_spi_addr_flags, + LSM6DSM_FIFO_STS1_ADDR, + (uint8_t *)&fsts, sizeof(fsts))); + if (fsts.len & (LSM6DSM_FIFO_DATA_OVR | + LSM6DSM_FIFO_FULL)) + CPRINTS("%s FIFO Overrun: %04x", + s->name, fsts.len); + fifo_empty = fsts.len & LSM6DSM_FIFO_EMPTY; + if (!fifo_empty) { + commit_needed = true; + RETURN_ERROR(load_fifo(s, &fsts)); + } + } + if (commit_needed) + motion_sense_fifo_commit_data(); } - return ret; + return EC_SUCCESS; } /** diff --git a/driver/accelgyro_lsm6dso.c b/driver/accelgyro_lsm6dso.c index fbce687f2c..ca5850ac8f 100644 --- a/driver/accelgyro_lsm6dso.c +++ b/driver/accelgyro_lsm6dso.c @@ -25,6 +25,23 @@ STATIC_IF(CONFIG_ACCEL_FIFO) volatile uint32_t last_interrupt_timestamp; STATIC_IF(CONFIG_ACCEL_INTERRUPTS) int config_interrupt( const struct motion_sensor_t *s); +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_ACCEL_INTERRUPTS) +/* Get the motion sensor ID of the LSM6DSO sensor that generates the + * interrupt. The interrupt is converted to the event and transferred to + * motion sense task that actually handles the interrupt. + * + * Here we use an alias (lsm6dso_int) to get the motion sensor ID. This alias + * MUST be defined for this driver to work. + * aliases { + * lsm6dso-int = &lid_accel; + * }; + */ +#if DT_NODE_EXISTS(DT_ALIAS(lsm6dso_int)) +#define CONFIG_ACCEL_LSM6DSO_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(SENSOR_ID(DT_ALIAS(lsm6dso_int))) +#endif +#endif + /* * When ODR change, the sensor filters need settling time; * Add a counter to discard a well known number of data with @@ -160,8 +177,7 @@ static void push_fifo_data(struct motion_sensor_t *main_s, uint8_t *fifo, } static inline int load_fifo(struct motion_sensor_t *main_s, - const uint16_t fifo_len, - uint32_t saved_ts) + const uint16_t fifo_len) { uint8_t fifo[LSM6DSO_FIFO_SAMPLE_SIZE]; int i, err; @@ -174,7 +190,7 @@ static inline int load_fifo(struct motion_sensor_t *main_s, if (err != EC_SUCCESS) return err; - push_fifo_data(main_s, fifo, saved_ts); + push_fifo_data(main_s, fifo, last_interrupt_timestamp); } return EC_SUCCESS; @@ -227,7 +243,7 @@ void lsm6dso_interrupt(enum gpio_signal signal) */ static int irq_handler(struct motion_sensor_t *s, uint32_t *event) { - int ret = EC_SUCCESS, fifo_len = 0; + int fifo_len = 0; struct lsm6dso_fstatus fsts; bool has_read_fifo = false; @@ -240,26 +256,23 @@ static int irq_handler(struct motion_sensor_t *s, uint32_t *event) do { /* Read how many data patterns on FIFO to read. */ - ret = st_raw_read_n_noinc(s->port, s->i2c_spi_addr_flags, - LSM6DSO_FIFO_STS1_ADDR, - (uint8_t *)&fsts, sizeof(fsts)); - if (ret != EC_SUCCESS) - break; - + RETURN_ERROR(st_raw_read_n_noinc(s->port, s->i2c_spi_addr_flags, + LSM6DSO_FIFO_STS1_ADDR, + (uint8_t *)&fsts, sizeof(fsts))); if (fsts.len & (LSM6DSO_FIFO_DATA_OVR | LSM6DSO_FIFO_FULL)) CPRINTS("%s FIFO Overrun: %04x", s->name, fsts.len); fifo_len = fsts.len & LSM6DSO_FIFO_DIFF_MASK; if (fifo_len) { - ret = load_fifo(s, fifo_len, last_interrupt_timestamp); + RETURN_ERROR(load_fifo(s, fifo_len)); has_read_fifo = true; } - } while (fifo_len != 0 && ret == EC_SUCCESS); + } while (fifo_len != 0); - if (ret == EC_SUCCESS && has_read_fifo) + if (has_read_fifo) motion_sense_fifo_commit_data(); - return ret; + return EC_SUCCESS; } #endif /* CONFIG_ACCEL_INTERRUPTS */ diff --git a/driver/accelgyro_lsm6dso.h b/driver/accelgyro_lsm6dso.h index 9a58fe7d36..15c17f167a 100644 --- a/driver/accelgyro_lsm6dso.h +++ b/driver/accelgyro_lsm6dso.h @@ -8,15 +8,9 @@ #ifndef __CROS_EC_ACCELGYRO_LSM6DSO_H #define __CROS_EC_ACCELGYRO_LSM6DSO_H +#include "driver/accelgyro_lsm6dso_public.h" #include "stm_mems_common.h" -/* - * 7-bit address is 110101xb. Where 'x' is determined - * by the voltage on the ADDR pin - */ -#define LSM6DSO_ADDR0_FLAGS 0x6a -#define LSM6DSO_ADDR1_FLAGS 0x6b - /* Access to embedded sensor hub register bank */ #define LSM6DSO_FUNC_CFG_ACC_ADDR 0x01 #define LSM6DSO_FUNC_CFG_EN 0x80 @@ -113,11 +107,6 @@ struct lsm6dso_fstatus { uint16_t pattern; }; -/* Absolute maximum rate for Acc and Gyro sensors */ -#define LSM6DSO_ODR_MIN_VAL 13000 -#define LSM6DSO_ODR_MAX_VAL \ - MOTION_MAX_SENSOR_FREQUENCY(416000, 13000) - /* ODR reg value from selected data rate in mHz */ #define LSM6DSO_ODR_TO_REG(_odr) (__fls(_odr / LSM6DSO_ODR_MIN_VAL) + 1) diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c index 50aa4d0e45..78d955fc9e 100644 --- a/driver/bc12/mt6360.c +++ b/driver/bc12/mt6360.c @@ -166,7 +166,19 @@ static void mt6360_usb_charger_task(const int port) /* vbus change, start bc12 detection */ if (evt & USB_CHG_EVENT_VBUS) { - if (pd_snk_is_vbus_provided(port)) + bool is_sink = pd_get_power_role(port) == PD_ROLE_SINK; + bool is_non_pd_sink = !pd_capable(port) && + is_sink && + pd_snk_is_vbus_provided(port); + + if (is_sink) + mt6360_clr_bit(MT6360_REG_CHG_CTRL1, + MT6360_MASK_HZ); + else + mt6360_set_bit(MT6360_REG_CHG_CTRL1, + MT6360_MASK_HZ); + + if (is_non_pd_sink) mt6360_enable_bc12_detection(1); else mt6360_update_charge_manager( diff --git a/driver/bc12/mt6360.h b/driver/bc12/mt6360.h index e23a2623ed..781bed2f57 100644 --- a/driver/bc12/mt6360.h +++ b/driver/bc12/mt6360.h @@ -9,6 +9,9 @@ #define MT6360_IRQ_MASK 0x0C +#define MT6360_REG_CHG_CTRL1 0x11 +#define MT6360_MASK_HZ BIT(2) + #define MT6360_REG_DEVICE_TYPE 0x22 #define MT6360_MASK_USBCHGEN BIT(7) diff --git a/driver/build.mk b/driver/build.mk index cb7262e778..2757eb3ceb 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -104,6 +104,7 @@ driver-$(CONFIG_LED_DRIVER_DS2413)+=led/ds2413.o driver-$(CONFIG_LED_DRIVER_LM3509)+=led/lm3509.o driver-$(CONFIG_LED_DRIVER_LM3630A)+=led/lm3630a.o driver-$(CONFIG_LED_DRIVER_LP5562)+=led/lp5562.o +driver-$(CONFIG_LED_DRIVER_MP3385)+=led/mp3385.o driver-$(CONFIG_LED_DRIVER_OZ554)+=led/oz554.o # 7-segment display @@ -121,6 +122,7 @@ driver-$(CONFIG_TEMP_SENSOR_G753)+=temp_sensor/g753.o driver-$(CONFIG_TEMP_SENSOR_G781)+=temp_sensor/g78x.o driver-$(CONFIG_TEMP_SENSOR_G782)+=temp_sensor/g78x.o driver-$(CONFIG_TEMP_SENSOR_OTI502)+=temp_sensor/oti502.o +driver-$(CONFIG_TEMP_SENSOR_PCT2075)+=temp_sensor/pct2075.o driver-$(CONFIG_TEMP_SENSOR_SB_TSI)+=temp_sensor/sb_tsi.o driver-$(CONFIG_TEMP_SENSOR_TMP006)+=temp_sensor/tmp006.o driver-$(CONFIG_TEMP_SENSOR_TMP112)+=temp_sensor/tmp112.o @@ -207,6 +209,7 @@ driver-y += ppc/nx20p348x.o endif driver-$(CONFIG_USBC_PPC_SYV682X)+=ppc/syv682x.o driver-$(CONFIG_USBC_PPC_NX20P3483)+=ppc/nx20p348x.o +driver-$(CONFIG_USBC_PPC_KTU1125)+=ppc/ktu1125.o # Switchcap driver-$(CONFIG_LN9310)+=ln9310.o diff --git a/driver/charger/bq25710.c b/driver/charger/bq25710.c index d3aeb354af..2f5ac93e91 100644 --- a/driver/charger/bq25710.c +++ b/driver/charger/bq25710.c @@ -54,6 +54,16 @@ #define CONFIG_CHARGER_BQ25720_IDCHG_TH2 1 #endif +#ifndef CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM +#define CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG 0 +#endif + +#ifndef CONFIG_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +/* Reduce ILIM from default of 150% to 110% */ +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH \ + BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P10 +#endif + /* * Helper macros */ @@ -62,6 +72,10 @@ CHARGE_OPTION_1, \ _field, _c, (_x)) +#define SET_CO2(_field, _v, _x) SET_BQ_FIELD(BQ257X0, \ + CHARGE_OPTION_2, \ + _field, _v, (_x)) + #define SET_CO2_BY_NAME(_field, _c, _x) SET_BQ_FIELD_BY_NAME(BQ257X0, \ CHARGE_OPTION_2, \ _field, _c, (_x)) @@ -78,6 +92,18 @@ CHARGE_OPTION_4, \ _field, _v, (_x)) +#define SET_CO4_BY_NAME(_field, _c, _x) SET_BQ_FIELD_BY_NAME(BQ25720, \ + CHARGE_OPTION_4, \ + _field, _c, (_x)) + +#define SET_PO0(_field, _v, _x) SET_BQ_FIELD(BQ257X0, \ + PROCHOT_OPTION_0, \ + _field, _v, (_x)) + +#define SET_PO0_BY_NAME(_field, _c, _x) SET_BQ_FIELD_BY_NAME(BQ257X0, \ + PROCHOT_OPTION_0, \ + _field, _c, (_x)) + #define SET_PO1(_field, _v, _x) SET_BQ_FIELD(BQ257X0, \ PROCHOT_OPTION_1, \ _field, _v, (_x)) @@ -322,6 +348,20 @@ static int bq257x0_init_charge_option_1(int chgnum) return raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_1, reg); } +static int bq257x0_init_prochot_option_0(int chgnum) +{ + int rv; + int reg; + + rv = raw_read16(chgnum, BQ25710_REG_PROCHOT_OPTION_0, ®); + if (rv) + return rv; + + reg = SET_PO0(ILIM2_VTH, CONFIG_CHARGER_BQ257X0_ILIM2_VTH, reg); + + return raw_write16(chgnum, BQ25710_REG_PROCHOT_OPTION_0, reg); +} + static int bq257x0_init_prochot_option_1(int chgnum) { int rv; @@ -387,6 +427,12 @@ static int bq257x0_init_charge_option_2(int chgnum) */ reg = SET_BQ_FIELD(BQ257X0, CHARGE_OPTION_2, PKPWR_TMAX, 0, reg); + if (IS_ENABLED(CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM)) { + /* Set input overload time in peak power mode. */ + reg = SET_CO2(PKPWR_TOVLD_DEG, + CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG, reg); + } + if (IS_ENABLED(CONFIG_CHARGER_BQ25710_EN_ACOC)) { /* Enable AC input over-current protection. */ reg = SET_CO2_BY_NAME(EN_ACOC, ENABLE, reg); @@ -399,12 +445,7 @@ static int bq257x0_init_charge_option_2(int chgnum) if (IS_ENABLED(CONFIG_CHARGER_BQ25710_BATOC_VTH_MINIMUM)) { /* Set battery over-current threshold to minimum. */ - if (IS_ENABLED(CONFIG_CHARGER_BQ25720)) - reg = SET_BQ_FIELD_BY_NAME(BQ25720, CHARGE_OPTION_2, - BATOC_VTH, 1P33, reg); - else - reg = SET_BQ_FIELD_BY_NAME(BQ25710, CHARGE_OPTION_2, - BATOC_VTH, 1P50, reg); + reg = SET_CO2_BY_NAME(BATOC_VTH, 1P33, reg); } return raw_write16(chgnum, BQ25710_REG_CHARGE_OPTION_2, reg); @@ -454,6 +495,9 @@ static int bq257x0_init_charge_option_4(int chgnum) if (IS_ENABLED(CONFIG_CHARGER_BQ25720_IDCHG_TH2_CUSTOM)) reg = SET_CO4(IDCHG_TH2, CONFIG_CHARGER_BQ25720_IDCHG_TH2, reg); + if (IS_ENABLED(CONFIG_CHARGER_BQ25720_PP_IDCHG2)) + reg = SET_CO4_BY_NAME(PP_IDCHG2, ENABLE, reg); + return raw_write16(chgnum, BQ25720_REG_CHARGE_OPTION_4, reg); } @@ -532,14 +576,9 @@ static void bq25710_init(int chgnum) bq257x0_init_charge_option_1(chgnum); - bq257x0_init_prochot_option_1(chgnum); + bq257x0_init_prochot_option_0(chgnum); - /* Reduce ILIM from default of 150% to 105% */ - if (!raw_read16(chgnum, BQ25710_REG_PROCHOT_OPTION_0, ®)) { - reg = SET_BQ_FIELD(BQ257X0, PROCHOT_OPTION_0, ILIM2_VTH, 0, - reg); - raw_write16(chgnum, BQ25710_REG_PROCHOT_OPTION_0, reg); - } + bq257x0_init_prochot_option_1(chgnum); bq257x0_init_charge_option_2(chgnum); diff --git a/driver/charger/bq25710.h b/driver/charger/bq25710.h index 603f3bf140..bb1ee1ba99 100644 --- a/driver/charger/bq25710.h +++ b/driver/charger/bq25710.h @@ -60,8 +60,8 @@ #endif /* Min System Voltage Register */ -#define BQ25710_MIN_SYSTEM_VOLTAGE_STEP_MV 100 -#define BQ25720_VSYS_MIN_VOLTAGE_STEP_MV 256 +#define BQ25710_MIN_SYSTEM_VOLTAGE_STEP_MV 256 +#define BQ25720_VSYS_MIN_VOLTAGE_STEP_MV 100 extern const struct charger_drv bq25710_drv; diff --git a/driver/charger/bq257x0_regs.h b/driver/charger/bq257x0_regs.h index 0df033f535..58d203b55e 100644 --- a/driver/charger/bq257x0_regs.h +++ b/driver/charger/bq257x0_regs.h @@ -57,6 +57,10 @@ /* * ChargeOption2 Register (0x31) */ +#define BQ257X0_CHARGE_OPTION_2_PKPWR_TOVLD_DEG_SHIFT 14 +#define BQ257X0_CHARGE_OPTION_2_PKPWR_TOVLD_DEG_BITS 2 +#define BQ25720_CHARGE_OPTION_2_PKPWR_TOVLD_DEG__10MS 3 + #define BQ257X0_CHARGE_OPTION_2_PKPWR_TMAX_SHIFT 8 #define BQ257X0_CHARGE_OPTION_2_PKPWR_TMAX_BITS 2 @@ -73,20 +77,10 @@ #define BQ257X0_CHARGE_OPTION_2_ACOC_VTH__1P33 0 #define BQ257X0_CHARGE_OPTION_2_ACOC_VTH__2P00 1 -#define BQ257X0_CHARGE_OPTION_2_ACOC_VTH_SHIFT 2 -#define BQ257X0_CHARGE_OPTION_2_ACOC_VTH_BITS 1 -#define BQ257X0_CHARGE_OPTION_2_ACOC_VTH__1P33 0 -#define BQ257X0_CHARGE_OPTION_2_ACOC_VTH__2P00 1 - -#define BQ25710_CHARGE_OPTION_2_BATOC_VTH_SHIFT 0 -#define BQ25710_CHARGE_OPTION_2_BATOC_VTH_BITS 1 -#define BQ25710_CHARGE_OPTION_2_BATOC_VTH__1P50 0 -#define BQ25710_CHARGE_OPTION_2_BATOC_VTH__2P00 1 - -#define BQ25720_CHARGE_OPTION_2_BATOC_VTH_SHIFT 0 -#define BQ25720_CHARGE_OPTION_2_BATOC_VTH_BITS 1 -#define BQ25720_CHARGE_OPTION_2_BATOC_VTH__1P33 0 -#define BQ25720_CHARGE_OPTION_2_BATOC_VTH__2P00 1 +#define BQ257X0_CHARGE_OPTION_2_BATOC_VTH_SHIFT 0 +#define BQ257X0_CHARGE_OPTION_2_BATOC_VTH_BITS 1 +#define BQ257X0_CHARGE_OPTION_2_BATOC_VTH__1P33 0 +#define BQ257X0_CHARGE_OPTION_2_BATOC_VTH__2P00 1 /* * ChargeOption3 Register (0x32) @@ -107,7 +101,13 @@ #define BQ25720_CHARGE_OPTION_4_VSYS_UVP_SHIFT 13 #define BQ25720_CHARGE_OPTION_4_VSYS_UVP_BITS 3 #define BQ25720_CHARGE_OPTION_4_VSYS_UVP__2P4 0 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__3P2 1 #define BQ25720_CHARGE_OPTION_4_VSYS_UVP__4P0 2 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__4P8 3 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__5P6 4 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__6P4 5 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__7P2 6 +#define BQ25720_CHARGE_OPTION_4_VSYS_UVP__8P0 7 #define BQ25720_CHARGE_OPTION_4_IDCHG_DEG2_SHIFT 6 #define BQ25720_CHARGE_OPTION_4_IDCHG_DEG2_BITS 2 @@ -119,6 +119,11 @@ #define BQ25720_CHARGE_OPTION_4_IDCHG_TH2__1P25 0 #define BQ25720_CHARGE_OPTION_4_IDCHG_TH2__1P5 1 +#define BQ25720_CHARGE_OPTION_4_PP_IDCHG2_SHIFT 2 +#define BQ25720_CHARGE_OPTION_4_PP_IDCHG2_BITS 1 +#define BQ25720_CHARGE_OPTION_4_PP_IDCHG2__DISABLE 0 +#define BQ25720_CHARGE_OPTION_4_PP_IDCHG2__ENABLE 1 + /* * Vmin Active Protection Register (0x37) */ @@ -130,6 +135,13 @@ */ #define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH_SHIFT 11 #define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH_BITS 5 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P10 1 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P40 7 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__1P50 9 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__2P30 25 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__2P50 26 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__4P50 30 +#define BQ257X0_PROCHOT_OPTION_0_ILIM2_VTH__NA 31 /* * ProchotOption1 Register (0x34) diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h index 558c17f971..0de2a32ae5 100644 --- a/driver/charger/isl923x.h +++ b/driver/charger/isl923x.h @@ -42,7 +42,7 @@ /* Maximum charging current register value */ #define ISL923X_CURRENT_REG_MAX 0x17c0 /* bit<12:2> 10111110000 */ -#define RAA489000_CURRENT_REG_MAX 0x1ffc +#define RAA489000_CURRENT_REG_MAX 0x17fc /* 2-level adpater current limit duration T1 & T2 in micro seconds */ #define ISL923X_T1_10000 0x00 diff --git a/driver/charger/rt946x.h b/driver/charger/rt946x.h index 5e6f9e0223..8c8cdf03ff 100644 --- a/driver/charger/rt946x.h +++ b/driver/charger/rt946x.h @@ -281,11 +281,12 @@ #define RT946X_MASK_STAT_EN BIT(RT946X_SHIFT_STAT_EN) /* ========== CHGCTRL2 0x02 ============ */ -#define RT946X_SHIFT_SHIP_MODE 7 -#define RT946X_SHIFT_TE 4 -#define RT946X_SHIFT_ILMTSEL 2 -#define RT946X_SHIFT_CFO_EN 1 -#define RT946X_SHIFT_CHG_EN 0 +#define RT946X_SHIFT_SHIP_MODE 7 +#define RT946X_SHIFT_BATDET_DIS_DLY 6 +#define RT946X_SHIFT_TE 4 +#define RT946X_SHIFT_ILMTSEL 2 +#define RT946X_SHIFT_CFO_EN 1 +#define RT946X_SHIFT_CHG_EN 0 #define RT946X_MASK_SHIP_MODE BIT(RT946X_SHIFT_SHIP_MODE) #define RT946X_MASK_TE BIT(RT946X_SHIFT_TE) diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index 43a54d798b..36c4e705c2 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -48,7 +48,7 @@ static const struct charger_info sm5803_charger_info = { .input_current_step = INPUT_I_STEP, }; -static uint32_t irq_pending; /* Bitmask of chips with interrupts pending */ +static atomic_t irq_pending; /* Bitmask of chips with interrupts pending */ static struct mutex flow1_access_lock[CHARGER_NUM]; static struct mutex flow2_access_lock[CHARGER_NUM]; diff --git a/driver/led/max695x.c b/driver/led/max695x.c index 6f0e1b8e84..c6155f1499 100644 --- a/driver/led/max695x.c +++ b/driver/led/max695x.c @@ -93,6 +93,7 @@ static void max695x_init(void) max695x_i2c_write(MAX695X_REG_DECODE_MODE, buf, ARRAY_SIZE(buf)); } DECLARE_HOOK(HOOK_INIT, max695x_init, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, max695x_init, HOOK_PRIO_DEFAULT); static void max695x_shutdown(void) { diff --git a/driver/led/mp3385.c b/driver/led/mp3385.c new file mode 100644 index 0000000000..278e333ae1 --- /dev/null +++ b/driver/led/mp3385.c @@ -0,0 +1,132 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * MPS MP3385 LED driver. + */ + +#include "console.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "mp3385.h" +#include "task.h" +#include "timer.h" + +#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_I2C, format, ## args) + +#define I2C_ADDR_MP3385_FLAGS 0x31 + +struct mp3385_value { + uint8_t offset; + uint8_t data; +}; + +/* + * MP3385 asserts the interrupt when it's ready for writing settings, which + * are cleared when it's turned off. We enable the interrupt on HOOK_INIT and + * keep it enabled in S0/S3/S5. + * + * It's assumed the device doesn't have a lid and MP3385 is powered only in + * S0. For clamshell devices, different interrupt & power control scheme may be + * needed. + */ + +/* This ordering is suggested by vendor. */ +static struct mp3385_value mp3385_conf[] = { + /* + * Register 0x01: Operation frequency control + * Frequency selection: 300(KHz) + * Short circuit protection: 8(V) + */ + {.offset = 1, .data = 0x43}, + /* + * Register 0x02: LED current Full-Scale Register + * ISET Resistor: 127(Kohm) + * Maximum LED current: 20196/127 = 159(mA) + * Setting LED current: 62(mA) + */ + {.offset = 2, .data = 0x65}, + + /* Register 0x03: RO - ignored */ + + /* + * Register 0x04: Internal LED Dimming Brightness Register + * SMBus PWM function: None Use + */ + {.offset = 4, .data = 0x00}, + /* + * Register 0x05: OVP, OCP Threshold Register + * Over Current Protection: 0.5(V) + * Panel LED Voltage(Max): 47.8(V) + * OVP setting: 54(V) + */ + {.offset = 5, .data = 0x97}, + /* + * Register 0x00: Dimming mode Register + * String Selection: 4(Number) + * Interface Selection: 1 + * Brightness mode: 3 + */ + {.offset = 0, .data = 0xF2}, +}; +static const int mp3385_conf_size = ARRAY_SIZE(mp3385_conf); + +static void set_mp3385_reg(void) +{ + int i; + + for (i = 0; i < mp3385_conf_size; ++i) { + int rv = i2c_write8(I2C_PORT_BACKLIGHT, + I2C_ADDR_MP3385_FLAGS, + mp3385_conf[i].offset, mp3385_conf[i].data); + if (rv) { + CPRINTS("Write MP3385 register %d " + "failed rv=%d", i, rv); + return; + } + } + CPRINTS("Wrote MP3385 settings"); +} + +static void mp3385_backlight_enable_deferred(void) +{ + if (gpio_get_level(GPIO_PANEL_BACKLIGHT_EN)) + set_mp3385_reg(); +} +DECLARE_DEFERRED(mp3385_backlight_enable_deferred); + +void mp3385_interrupt(enum gpio_signal signal) +{ + /* + * 1. Spec says backlight should be turned on after 500ms + * after eDP signals are ready. + * + * 2. There's no way to get exact eDP ready time, therefore, + * give one second delay. + * + * power up __/---------------- + * eDP ______/------------ + * backlight _____________/----- + * |- t1 -| : >=500 ms + * |- t2 -| : 1 second is enough + */ + hook_call_deferred(&mp3385_backlight_enable_deferred_data, + MP3385_POWER_BACKLIGHT_DELAY); +} + +int mp3385_set_config(int offset, int data) +{ + int i; + + for (i = 0; i < mp3385_conf_size; i++) { + if (mp3385_conf[i].offset == offset) { + mp3385_conf[i].data = data; + return EC_SUCCESS; + } + } + + CPRINTS("mp3385: offset %d not found", i); + return EC_ERROR_INVAL; +} diff --git a/driver/led/mp3385.h b/driver/led/mp3385.h new file mode 100644 index 0000000000..9463b06aa5 --- /dev/null +++ b/driver/led/mp3385.h @@ -0,0 +1,35 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * MPS MP3385 LED driver. + */ + +#ifndef __CROS_EC_MP3385_H +#define __CROS_EC_MP3385_H + +#include "gpio.h" +#include "common.h" + +/* + * Overridable board initialization. Should be overridden by a board + * specific function if the default is not appropriate + */ +void mp3385_board_init(void); + +/** + * Update mp3385 configuration array (mp3385_conf). + * + * @param offset: Offset of the register to be set. + * @param data: Value to be set. + * @return EC_SUCCESS or EC_ERROR_* for errors. + */ +int mp3385_set_config(int offset, int data); + +#ifndef MP3385_POWER_BACKLIGHT_DELAY +#define MP3385_POWER_BACKLIGHT_DELAY SECOND +#endif + +void mp3385_interrupt(enum gpio_signal signal); + +#endif diff --git a/driver/led/oz554.c b/driver/led/oz554.c index 504ac55e90..4b661a592c 100644 --- a/driver/led/oz554.c +++ b/driver/led/oz554.c @@ -98,7 +98,7 @@ static void backlight_enable_deferred(void) } DECLARE_DEFERRED(backlight_enable_deferred); -void backlight_enable_interrupt(enum gpio_signal signal) +void oz554_interrupt(enum gpio_signal signal) { /* * 1. Spec says backlight should be turned on after 500ms @@ -132,16 +132,3 @@ int oz554_set_config(int offset, int data) oz554_conf[i].data = data; return EC_SUCCESS; } - -static void init_oz554(void) -{ - oz554_board_init(); - - gpio_enable_interrupt(GPIO_PANEL_BACKLIGHT_EN); -} -DECLARE_HOOK(HOOK_INIT, init_oz554, HOOK_PRIO_DEFAULT); - - -__overridable void oz554_board_init(void) -{ -} diff --git a/driver/led/oz554.h b/driver/led/oz554.h index d1d9d9656e..1893900b22 100644 --- a/driver/led/oz554.h +++ b/driver/led/oz554.h @@ -15,7 +15,7 @@ * Overridable board initialization. Should be overridden by a board * specific function if the default is not appropriate */ -__override_proto void oz554_board_init(void); +void oz554_board_init(void); /** * Update oz554 configuration array (oz554_conf). @@ -30,6 +30,6 @@ int oz554_set_config(int offset, int data); #define OZ554_POWER_BACKLIGHT_DELAY SECOND #endif -void backlight_enable_interrupt(enum gpio_signal signal); +void oz554_interrupt(enum gpio_signal signal); #endif diff --git a/driver/mp2964.h b/driver/mp2964.h index 8c0339c06e..f424887567 100644 --- a/driver/mp2964.h +++ b/driver/mp2964.h @@ -9,7 +9,30 @@ #define MP2964_PAGE 0x00 #define MP2964_STORE_USER_ALL 0x15 #define MP2964_RESTORE_USER_ALL 0x16 +#define MP2964_MFR_VOUT_TRIM 0x22 +#define MP2964_MFR_PHASE_NUM 0x29 +#define MP2964_MFR_IMON_SNS_OFFS 0x2c +#define MP2964_IOUT_CAL_GAIN_SET 0x38 +#define MP2964_MFR_TRANS_FAST 0x3d #define MP2964_MFR_ALT_SET 0x3f +#define MP2964_MFR_CONFIG2 0x48 +#define MP2964_MFR_SLOPE_SR_DCM 0x4e +#define MP2964_MFR_ICC_MAX_SET 0x53 +#define MP2964_MFR_OCP_OVP_DAC_LIMIT 0x60 +#define MP2964_MFR_OCP_SET 0x62 +#define MP2964_PRODUCT_DATA_CODE 0x93 +#define MP2964_LOT_CODE_VR 0x94 +#define MP2964_MFR_PSI_TRIM4 0xb0 +#define MP2964_MFR_PSI_TRIM1 0xb1 +#define MP2964_MFR_PSI_TRIM3 0xb3 +#define MP2964_MFR_SLOPE_CNT_2P 0xd4 +#define MP2964_MFR_SLOPE_CNT_5P 0xe0 +#define MP2964_MFR_IMON_SVID1 0xe8 +#define MP2964_MFR_IMON_SVID2 0xe9 +#define MP2964_MFR_IMON_SVID3 0xea +#define MP2964_MFR_IMON_SVID4 0xeb +#define MP2964_MFR_IMON_SVID5 0xef +#define MP2964_MFR_IMON_SVID6 0xf0 struct mp2964_reg_val { uint8_t reg; diff --git a/driver/ppc/aoz1380.c b/driver/ppc/aoz1380.c index 935503b593..726f626caf 100644 --- a/driver/ppc/aoz1380.c +++ b/driver/ppc/aoz1380.c @@ -25,12 +25,12 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */ +static atomic_t irq_pending; /* Bitmask of ports signaling an interrupt. */ #define AOZ1380_FLAGS_SOURCE_ENABLED BIT(0) #define AOZ1380_FLAGS_SINK_ENABLED BIT(1) #define AOZ1380_FLAGS_INT_ON_DISCONNECT BIT(2) -static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; +static atomic_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; #define AOZ1380_SET_FLAG(port, flag) atomic_or(&flags[port], (flag)) #define AOZ1380_CLR_FLAG(port, flag) atomic_clear_bits(&flags[port], (flag)) diff --git a/driver/ppc/ktu1125.c b/driver/ppc/ktu1125.c new file mode 100644 index 0000000000..72caa068da --- /dev/null +++ b/driver/ppc/ktu1125.c @@ -0,0 +1,538 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Kinetic KTU1125 USB-C Power Path Controller */ + +#include "common.h" +#include "console.h" +#include "ktu1125.h" +#include "hooks.h" +#include "i2c.h" +#include "system.h" +#include "timer.h" +#include "usb_charge.h" +#include "usb_pd_tcpm.h" +#include "usb_pd.h" +#include "usbc_ppc.h" +#include "util.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */ + +static int read_reg(uint8_t port, int reg, int *regval) +{ + return i2c_read8(ppc_chips[port].i2c_port, + ppc_chips[port].i2c_addr_flags, + reg, + regval); +} + +static int write_reg(uint8_t port, int reg, int regval) +{ + return i2c_write8(ppc_chips[port].i2c_port, + ppc_chips[port].i2c_addr_flags, + reg, + regval); +} + +static int set_flags(const int port, const int addr, const int flags_to_set) +{ + int val, rv; + + rv = read_reg(port, addr, &val); + if (rv) + return rv; + + val |= flags_to_set; + + return write_reg(port, addr, val); +} + +static int clr_flags(const int port, const int addr, const int flags_to_clear) +{ + int val, rv; + + rv = read_reg(port, addr, &val); + if (rv) + return rv; + + val &= ~flags_to_clear; + + return write_reg(port, addr, val); +} + +static int set_field(const int port, const int addr, const int shift, + const int field_length, const int field_to_set) +{ + int val, rv, mask; + + mask = ((1 << field_length) - 1) << shift; + val = (field_to_set << shift) & mask; + + rv = clr_flags(port, addr, mask); + if (rv) + return rv; + + return set_flags(port, addr, val); +} + + +#ifdef CONFIG_CMD_PPC_DUMP +static int ktu1125_dump(int port) +{ + int i; + int data; + + for (i = KTU1125_ID; i <= KTU1125_INT_DATA; i++) { + read_reg(port, i, &data); + CPRINTF("REG %02Xh = 0x%02x\n", i, data); + } + + cflush(); + return EC_SUCCESS; +} +#endif /* defined(CONFIG_CMD_PPC_DUMP) */ + +/* helper */ +static int ktu1125_power_path_control(int port, int enable) +{ + int status = enable ? clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SW_AB_EN) + : set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SW_AB_EN); + + if (status) { + CPRINTS("ppc p%d: Failed to %s power path", + port, enable ? "enable" : "disable"); + } + + return status; +} + +static int ktu1125_init(int port) +{ + int regval; + int ctrl_sw_cfg = 0; + int set_sw_cfg = 0; + int set_sw2_cfg = 0; + int sysb_clp; + int status; + + CPRINTF("KTU1125 init\n"); + + /* Read and verify KTU1125 Vendor and Chip ID */ + status = read_reg(port, KTU1125_ID, ®val); + + if (status) { + ppc_prints("Failed to read device ID!", port); + return status; + } + + if (regval != KTU1125_VENDOR_DIE_IDS) { + ppc_err_prints("KTU1125 ID mismatch!", port, regval); + return regval; + } + + + /* + * Setting control register CTRL_SW_CFG + */ + + /* Check if VBUS is present and set SW_AB_EN accordingly */ + status = read_reg(port, KTU1125_MONITOR_SNK, ®val); + if (status) { + ppc_err_prints("VBUS present error", port, status); + return 0; + } + + if (regval & KTU1125_SYSA_OK) + ctrl_sw_cfg = KTU1125_SW_AB_EN; + + status = write_reg(port, KTU1125_CTRL_SW_CFG, ctrl_sw_cfg); + if (status) { + ppc_err_prints("Failed to write CTRL_SW_CFG!", port, status); + return status; + } + + /* + * Setting control register SET_SW_CFG + */ + +#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT + /* Set the sourcing current limit value */ + switch (CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) { + case TYPEC_RP_3A0: + /* Set current limit to ~3A */ + sysb_clp = KTU1125_SYSB_ILIM_3_30; + break; + + case TYPEC_RP_1A5: + default: + /* Set current limit to ~1.5A */ + sysb_clp = KTU1125_SYSB_ILIM_1_70; + break; + } +#else /* !defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + /* Default SRC current limit to ~1.5A */ + sysb_clp = KTU1125_SYSB_ILIM_1_70; +#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + + /* Set SYSB Current Limit Protection */ + set_sw_cfg |= sysb_clp << KTU1125_SYSB_CLP_SHIFT; + /* Set VCONN Current Limit Protection. + * Note: might be changed to 600mA in future + */ + set_sw_cfg |= KTU1125_VCONN_ILIM_0_40 << KTU1125_VCONN_CLP_SHIFT; + /* Disable Dead Battery resistance, because CC FETs are ON */ + set_sw_cfg |= KTU1125_RDB_DIS; + + status = write_reg(port, KTU1125_SET_SW_CFG, set_sw_cfg); + if (status) { + ppc_err_prints("Failed to write SET_SW_CFG!", port, status); + return status; + } + + /* + * Setting control register SET_SW2_CFG + */ + + /* Set T_HIC */ + set_sw2_cfg |= (KTU_T_HIC_MS_17 << KTU1125_T_HIC_SHIFT); + /* Set vbus discharge resistance */ + set_sw2_cfg |= (KTU1125_DIS_RES_1400 << KTU1125_DIS_RES_SHIFT); + /* Set Vbus OVP threshold to ~5V */ + set_sw2_cfg |= (KTU1125_SYSB_VLIM_6_00 << KTU1125_OVP_BUS_SHIFT); + + status = write_reg(port, KTU1125_SET_SW2_CFG, set_sw2_cfg); + if (status) { + ppc_err_prints("Failed to write SET_SW2_CFG!", port, status); + return status; + } + + /* + * Don't proceed with the rest of initialization if we're sysjumping. + * We would have already done this before + */ + if (system_jumped_late()) + return EC_SUCCESS; + + /* + * Enable interrupts + */ + + /* Leave SYSA_OK and FRS masked for SNK group of interrupts */ + regval = KTU1125_SNK_MASK_ALL & ~(KTU1125_SYSA_OK | KTU1125_FR_SWAP); + status = write_reg(port, KTU1125_INTMASK_SNK, regval); + if (status) { + ppc_err_prints("Failed to write INTMASK_SNK!", port, status); + return status; + } + + /* Only leave VBUS_OK masked for SRC group of interrupts */ + regval = KTU1125_SRC_MASK_ALL & ~KTU1125_VBUS_OK; + status = write_reg(port, KTU1125_INTMASK_SRC, regval); + if (status) { + ppc_err_prints("Failed to write INTMASK_SRC!", port, status); + return status; + } + + /* Unmask the entire DATA group of interrupts */ + status = write_reg(port, KTU1125_INTMASK_DATA, KTU1125_DATA_MASK_ALL); + if (status) { + ppc_err_prints("Failed to write INTMASK_DATA!", port, status); + return status; + } + + return EC_SUCCESS; +} + +#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC +static int ktu1125_is_vbus_present(int port) +{ + int regval; + int rv; + + rv = read_reg(port, KTU1125_MONITOR_SNK, ®val); + if (rv) { + ppc_err_prints("VBUS present error", port, rv); + return 0; + } + + return regval & KTU1125_SYSA_OK; +} +#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */ + +static int ktu1125_is_sourcing_vbus(int port) +{ + int regval; + int rv; + + rv = read_reg(port, KTU1125_MONITOR_SRC, ®val); + if (rv) { + ppc_err_prints("Sourcing VBUS error", port, rv); + return 0; + } + + return regval & KTU1125_VBUS_OK; +} + +#ifdef CONFIG_USBC_PPC_POLARITY +static int ktu1125_set_polarity(int port, int polarity) +{ + if (polarity) { + /* CC2 active. */ + clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC2S_VCONN); + return set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_CC1S_VCONN); + } + + /* else CC1 active. */ + clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC1S_VCONN); + return set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_CC2S_VCONN); +} +#endif + +static int ktu1125_set_vbus_src_current_limit(int port, enum tcpc_rp_value rp) +{ + int regval; + int status; + + /* + * Note that we chose the lowest current limit setting that is just + * above indicated Rp value. This is because these are minimum values + * and we must be able to provide the current that we advertise + */ + switch (rp) { + case TYPEC_RP_3A0: + regval = KTU1125_SYSB_ILIM_3_30; + break; + + case TYPEC_RP_1A5: + regval = KTU1125_SYSB_ILIM_1_70; + break; + + case TYPEC_RP_USB: + default: + regval = KTU1125_SYSB_ILIM_0_6; + break; + }; + + + status = set_field(port, KTU1125_SET_SW_CFG, KTU1125_SYSB_CLP_SHIFT, + KTU1125_SYSB_CLP_LEN, regval); + if (status) + ppc_prints("Failed to set KTU1125_SET_SW_CFG!", port); + + return status; +} + +static int ktu1125_discharge_vbus(int port, int enable) +{ + int status = enable ? set_flags(port, KTU1125_SET_SW2_CFG, + KTU1125_VBUS_DIS_EN) + : clr_flags(port, KTU1125_SET_SW2_CFG, + KTU1125_VBUS_DIS_EN); + + if (status) { + CPRINTS("ppc p%d: Failed to %s vbus discharge", + port, enable ? "enable" : "disable"); + return status; + } + + return EC_SUCCESS; +} + +#ifdef CONFIG_USBC_PPC_VCONN +static int ktu1125_set_vconn(int port, int enable) +{ + int status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_VCONN_EN) + : clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_VCONN_EN); + + return status; +} +#endif + +#ifdef CONFIG_USB_PD_FRS_PPC +static int ktu1125_set_frs_enable(int port, int enable) +{ + /* Enable/Disable FR_SWAP Interrupt */ + int status = enable ? clr_flags(port, KTU1125_INTMASK_SNK, + KTU1125_FR_SWAP) + : set_flags(port, KTU1125_INTMASK_SNK, + KTU1125_FR_SWAP); + + if (status) { + ppc_prints("Failed to write KTU1125_INTMASK_SNK!", port); + return status; + } + + /* Set the FRS_EN bit */ + status = enable ? set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_FRS_EN) + : clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_FRS_EN); + + return status; +} +#endif + +static int ktu1125_vbus_sink_enable(int port, int enable) +{ + /* Select active sink */ + int rv = clr_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); + + if (rv) { + ppc_err_prints("Could not select SNK path", port, rv); + return rv; + } + + return ktu1125_power_path_control(port, enable); +} + +static int ktu1125_vbus_source_enable(int port, int enable) +{ + /* Select active source */ + int rv = set_flags(port, KTU1125_CTRL_SW_CFG, KTU1125_POW_MODE); + + if (rv) { + ppc_err_prints("Could not select SRC path", port, rv); + return rv; + } + + return ktu1125_power_path_control(port, enable); +} + +#ifdef CONFIG_USBC_PPC_SBU +static int ktu1125_set_sbu(int port, int enable) +{ + int status = enable ? clr_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SBU_SHUT) + : set_flags(port, KTU1125_CTRL_SW_CFG, + KTU1125_SBU_SHUT); + + if (status) { + CPRINTS("ppc p%d: Failed to %s sbu", + port, enable ? "enable" : "disable"); + } + + return status; +} +#endif /* CONFIG_USBC_PPC_SBU */ + +static void ktu1125_handle_interrupt(int port) +{ + int attempt = 0; + + /* + * KTU1135's /INT pin is level, so process interrupts until it + * deasserts if the chip has a dedicated interrupt pin. + */ +#ifdef CONFIG_USBC_PPC_DEDICATED_INT + while (ppc_get_alert_status(port)) +#endif + { + int ovp_int_count = 0; + int snk = 0; + int src = 0; + int data = 0; + + attempt++; + if (attempt > 1) + ppc_prints("Could not clear interrupts on first " + "try, retrying", port); + + /* Clear the interrupt by reading all 3 registers */ + read_reg(port, KTU1125_INT_SNK, &snk); + read_reg(port, KTU1125_INT_SRC, &src); + read_reg(port, KTU1125_INT_DATA, &data); + + CPRINTS("ppc p%d: INTERRUPT snk=%02X src=%02X data=%02X", + port, snk, src, data); + + if (snk & KTU1125_FR_SWAP) + pd_got_frs_signal(port); + + if (snk & (KTU1125_SYSA_SCP | + KTU1125_SYSA_OCP | + KTU1125_VBUS_OVP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (src & (KTU1125_SYSB_CLP | + KTU1125_SYSB_OCP | + KTU1125_SYSB_SCP | + KTU1125_VCONN_CLP | + KTU1125_VCONN_SCP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (data & (KTU1125_SBU2_OVP | KTU1125_SBU1_OVP)) { + /* Log and PD reset */ + pd_handle_overcurrent(port); + } + + if (data & (KTU1125_CC1_OVP | KTU1125_CC2_OVP)) { + ppc_prints("CC Over Voltage!", port); + /* + * Bug on ktu1125 Rev A: + * OVP interrupts are falsely triggered + * after IC reset (RST_L 0-> 1) + */ + if (ovp_int_count++) + pd_handle_cc_overvoltage(port); + } + } +} + +static void ktu1125_irq_deferred(void) +{ + int i; + uint32_t pending = atomic_clear(&irq_pending); + + for (i = 0; i < board_get_usb_pd_port_count(); i++) + if (BIT(i) & pending) + ktu1125_handle_interrupt(i); +} +DECLARE_DEFERRED(ktu1125_irq_deferred); + +void ktu1125_interrupt(int port) +{ + atomic_or(&irq_pending, BIT(port)); + hook_call_deferred(&ktu1125_irq_deferred_data, 0); +} + +const struct ppc_drv ktu1125_drv = { + .init = &ktu1125_init, + .is_sourcing_vbus = &ktu1125_is_sourcing_vbus, + .vbus_sink_enable = &ktu1125_vbus_sink_enable, + .vbus_source_enable = &ktu1125_vbus_source_enable, +#ifdef CONFIG_USBC_PPC_POLARITY + .set_polarity = &ktu1125_set_polarity, +#endif + .set_vbus_source_current_limit = &ktu1125_set_vbus_src_current_limit, + .discharge_vbus = &ktu1125_discharge_vbus, +#ifdef CONFIG_USBC_PPC_SBU + .set_sbu = &ktu1125_set_sbu, +#endif +#ifdef CONFIG_USBC_PPC_VCONN + .set_vconn = &ktu1125_set_vconn, +#endif +#ifdef CONFIG_USB_PD_FRS_PPC + .set_frs_enable = &ktu1125_set_frs_enable, +#endif +#ifdef CONFIG_CMD_PPC_DUMP + .reg_dump = &ktu1125_dump, +#endif +#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC + .is_vbus_present = &ktu1125_is_vbus_present, +#endif + .interrupt = &ktu1125_interrupt, +}; diff --git a/driver/ppc/ktu1125.h b/driver/ppc/ktu1125.h new file mode 100644 index 0000000000..826c6a925e --- /dev/null +++ b/driver/ppc/ktu1125.h @@ -0,0 +1,125 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Kinetic KTU1125 Type-C Power Path Controller */ + +#ifndef __CROS_EC_KTU1125_H +#define __CROS_EC_KTU1125_H + +#include "common.h" + +#include "driver/ppc/ktu1125_public.h" + +#define KTU1125_ID 0x0 +#define KTU1125_CTRL_SW_CFG 0x1 +#define KTU1125_SET_SW_CFG 0x2 +#define KTU1125_SET_SW2_CFG 0x3 +#define KTU1125_MONITOR_SNK 0x4 +#define KTU1125_MONITOR_SRC 0x5 +#define KTU1125_MONITOR_DATA 0x6 +#define KTU1125_INTMASK_SNK 0x7 +#define KTU1125_INTMASK_SRC 0x8 +#define KTU1125_INTMASK_DATA 0x9 +#define KTU1125_INT_SNK 0xA +#define KTU1125_INT_SRC 0xB +#define KTU1125_INT_DATA 0xC + +/* KTU1125_ID default value */ +#define KTU1125_VENDOR_DIE_IDS 0xA5 + +/* KTU1125_CTRL_SW_CFG bits */ +#define KTU1125_SBU_SHUT BIT(0) +#define KTU1125_VCONN_EN BIT(1) +#define KTU1125_CC2S_VCONN BIT(2) +#define KTU1125_CC1S_VCONN BIT(3) +#define KTU1125_POW_MODE BIT(4) +#define KTU1125_SW_AB_EN BIT(5) +#define KTU1125_FRS_EN BIT(6) +#define KTU1125_EN_L BIT(7) + +/* KTU1125_SET_SW_CFG bits and fields */ +#define KTU1125_RDB_DIS BIT(0) +#define KTU1125_SS_CLP_SNK BIT(1) +#define KTU1125_TDON BIT(2) +#define KTU1125_VCONN_CLP_SHIFT 3 +#define KTU1125_VCONN_CLP_LEN 2 +#define KTU1125_SYSB_CLP_SHIFT 5 +#define KTU1125_SYSB_CLP_LEN 3 + +/* VBUS Switch Current Limit Settings - SYSB_CLP */ +#define KTU1125_SYSB_ILIM_0_6 0 +#define KTU1125_SYSB_ILIM_1_05 1 +#define KTU1125_SYSB_ILIM_1_70 2 +#define KTU1125_SYSB_ILIM_3_30 3 +#define KTU1125_SYSB_ILIM_3_60 4 + +/* VCONN Current Limit Settings - VCONN_CLP */ +#define KTU1125_VCONN_ILIM_0_40 0 +#define KTU1125_VCONN_ILIM_0_60 1 +#define KTU1125_VCONN_ILIM_1_00 2 +#define KTU1125_VCONN_ILIM_1_40 3 + +/* KTU1125_SET_SW2_CFG bits and fields */ +#define KTU1125_OVP_BUS_SHIFT 0 +#define KTU1125_OVP_BUS_LEN 3 +#define KTU1125_DIS_RES_SHIFT 3 +#define KTU1125_DIS_RES_LEN 2 +#define KTU1125_VBUS_DIS_EN BIT(5) +#define KTU1125_T_HIC_SHIFT 6 +#define KTU1125_T_HIC_LEN 2 + +/* VBUS Over Voltage Protection */ +#define KTU1125_SYSB_VLIM_25_00 0 +#define KTU1125_SYSB_VLIM_17_00 4 +#define KTU1125_SYSB_VLIM_13_75 5 +#define KTU1125_SYSB_VLIM_10_60 6 +#define KTU1125_SYSB_VLIM_6_00 7 + +/* Discharge resistor [ohms] */ +#define KTU1125_DIS_RES_1400 0 +#define KTU1125_DIS_RES_730 1 +#define KTU1125_DIS_RES_570 2 +#define KTU1125_DIS_RES_205 3 + +/* T _HIC values [ms] */ +#define KTU_T_HIC_MS_17 0 +#define KTU_T_HIC_MS_34 1 +#define KTU_T_HIC_MS_51 2 +#define KTU_T_HIC_MS_68 3 + +/* Bits for MONITOR/INTMASK/INT SNK */ +#define KTU1125_SS_FAIL BIT(0) +#define KTU1125_OTP BIT(1) +#define KTU1125_FR_SWAP BIT(2) +#define KTU1125_SYSA_SCP BIT(3) +#define KTU1125_SYSA_OCP BIT(4) +#define KTU1125_VBUS_OVP BIT(5) +#define KTU1125_VBUS_UVLO BIT(6) +#define KTU1125_SYSA_OK BIT(7) +#define KTU1125_SNK_MASK_ALL 0xFF + +/* Bits for MONITOR/INTMASK/INT SRC */ +#define KTU1125_VCONN_SCP BIT(0) +#define KTU1125_VCONN_CLP BIT(1) +#define KTU1125_VCONN_UVLO BIT(2) +#define KTU1125_SYSB_SCP BIT(3) +#define KTU1125_SYSB_OCP BIT(4) +#define KTU1125_SYSB_CLP BIT(5) +#define KTU1125_SYSB_UVLO BIT(6) +#define KTU1125_VBUS_OK BIT(7) +#define KTU1125_SRC_MASK_ALL 0xFF + +/* Bits for MONITOR/INTMASK/INT DATA */ +#define KTU1125_SBUB BIT(0) +#define KTU1125_SBUA BIT(1) +#define KTU1125_SBU2_OVP BIT(2) +#define KTU1125_SBU1_OVP BIT(3) +#define KTU1125_CC2_OVP BIT(4) +#define KTU1125_CC1_OVP BIT(5) +#define KTU1125_CC2S_CLAMP BIT(6) +#define KTU1125_CC1S_CLAMP BIT(7) +#define KTU1125_DATA_MASK_ALL 0xFC + +#endif /* defined(__CROS_EC_KTU1125_H) */ diff --git a/driver/ppc/nx20p348x.c b/driver/ppc/nx20p348x.c index b582259e04..130678d512 100644 --- a/driver/ppc/nx20p348x.c +++ b/driver/ppc/nx20p348x.c @@ -22,7 +22,7 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */ +static atomic_t irq_pending; /* Bitmask of ports signaling an interrupt. */ #define NX20P348X_DB_EXIT_FAIL_THRESHOLD 10 static int db_exit_fail_count[CONFIG_USB_PD_PORT_MAX_COUNT]; diff --git a/driver/ppc/rt1718s.c b/driver/ppc/rt1718s.c index 96cb789cd0..68bd1aad16 100644 --- a/driver/ppc/rt1718s.c +++ b/driver/ppc/rt1718s.c @@ -169,15 +169,20 @@ static int rt1718s_is_vbus_present(int port) } #endif +int rt1718s_frs_init(int port) +{ + /* Set Rx frs unmasked */ + RETURN_ERROR(update_bits(port, RT1718S_RT_MASK1, + RT1718S_RT_MASK1_M_RX_FRS, 0xFF)); + return EC_SUCCESS; +} + static int rt1718s_init(int port) { atomic_clear(&flags[port]); if (IS_ENABLED(CONFIG_USB_PD_FRS_PPC)) - /* Set Rx frs unmasked */ - RETURN_ERROR(update_bits(port, RT1718S_RT_MASK1, - RT1718S_RT_MASK1_M_RX_FRS, - 0xFF)); + RETURN_ERROR(rt1718s_frs_init(port)); return EC_SUCCESS; } @@ -189,8 +194,7 @@ static int rt1718s_set_polarity(int port, int polarity) } #endif -#ifdef CONFIG_USB_PD_FRS_PPC -static int rt1718s_set_frs_enable(int port, int enable) +int rt1718s_set_frs_enable(int port, int enable) { /* * Use write instead of update to save 2 i2c read. @@ -210,7 +214,6 @@ static int rt1718s_set_frs_enable(int port, int enable) RETURN_ERROR(write_reg(port, RT1718S_VBUS_CTRL_EN, vbus_ctrl_en)); return EC_SUCCESS; } -#endif const struct ppc_drv rt1718s_ppc_drv = { .init = &rt1718s_init, diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index 1aac04af02..0e5934533e 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -26,7 +26,7 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */ +static atomic_t irq_pending; /* Bitmask of ports signaling an interrupt. */ static int source_enabled[CONFIG_USB_PD_PORT_MAX_COUNT]; static int read_reg(uint8_t port, int reg, int *regval) @@ -464,7 +464,14 @@ static int sn5s330_init(int port) i2c_write8(i2c_port, i2c_addr_flags, SN5S330_INT_STATUS_REG4, regval); - /* Turn on PP2 FET. */ + /* + * Turn on PP2 FET. + * Although PP2 FET is already enabled during dead batter boot + * by the spec, we force that state here. + * + * TODO(207034759): Verify need or remove redundant PP2 set. + */ + status = sn5s330_pp_fet_enable(port, SN5S330_PP2, 1); if (status) { ppc_prints("Failed to turn on PP2 FET!", port); @@ -533,8 +540,10 @@ static int sn5s330_set_vbus_source_current_limit(int port, regval |= SN5S330_ILIM_1_62; break; + /* USB minimum source current is 0.5A */ case TYPEC_RP_USB: default: + /* SN5S330 Defaults to USB associated limits */ regval |= SN5S330_ILIM_0_63; break; }; diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index fbf1159165..9768906182 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -111,6 +111,7 @@ enum sn5s330_pp_idx { /* FUNC_SET_9 */ #define SN5S330_FORCE_OVP_EN_SBU BIT(1) #define SN5S330_PP2_CONFIG BIT(2) +#define SN5S330_PWR_OVR_VBUS BIT(3) #define SN5S330_OVP_EN_CC BIT(4) #define SN5S330_CONFIG_UVP BIT(5) #define SN5S330_FORCE_ON_VBUS_OVP BIT(6) diff --git a/driver/ppc/syv682x.c b/driver/ppc/syv682x.c index 722824c53d..5e0ad344cd 100644 --- a/driver/ppc/syv682x.c +++ b/driver/ppc/syv682x.c @@ -30,10 +30,10 @@ #define SYV682X_FLAGS_FRS BIT(7) #define SYV682X_FLAGS_VCONN_OCP BIT(8) -static uint32_t irq_pending; /* Bitmask of ports signaling an interrupt. */ -static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; +static atomic_t irq_pending; /* Bitmask of ports signaling an interrupt. */ +static atomic_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; /* Running count of sink ocp events */ -static uint32_t sink_ocp_count[CONFIG_USB_PD_PORT_MAX_COUNT]; +static atomic_t sink_ocp_count[CONFIG_USB_PD_PORT_MAX_COUNT]; static timestamp_t vbus_oc_timer[CONFIG_USB_PD_PORT_MAX_COUNT]; static timestamp_t vconn_oc_timer[CONFIG_USB_PD_PORT_MAX_COUNT]; diff --git a/driver/retimer/bb_retimer.c b/driver/retimer/bb_retimer.c index bf3da60b32..627f61b3e6 100644 --- a/driver/retimer/bb_retimer.c +++ b/driver/retimer/bb_retimer.c @@ -472,10 +472,14 @@ static int retimer_set_state(const struct usb_mux *me, mux_state_t mux_state, set_retimer_con); } -void bb_retimer_hpd_update(const struct usb_mux *me, mux_state_t mux_state) +void bb_retimer_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { uint32_t retimer_con_reg = 0; + /* This driver does not use host command ACKs */ + *ack_required = false; + if (bb_retimer_read(me, BB_RETIMER_REG_CONNECTION_STATE, &retimer_con_reg) != EC_SUCCESS) return; diff --git a/driver/retimer/ps8802.h b/driver/retimer/ps8802.h index 858b83bfc7..5f4b9e4e9c 100644 --- a/driver/retimer/ps8802.h +++ b/driver/retimer/ps8802.h @@ -2,7 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * PS8802 retimer. + * PS8802/PS8762 retimer. */ #include "usb_mux.h" @@ -47,6 +47,10 @@ #define PS8802_EXTRA_SWING_LEVEL_P0_UP_3 0X07 #define PS8802_EXTRA_SWING_LEVEL_P0_MASK 0X07 +#define PS8802_REG_DCIRX 0x4B +#define PS8802_AUTO_DCI_MODE_DISABLE BIT(7) +#define PS8802_FORCE_DCI_MODE BIT(6) + /* * PAGE 2 Register Definitions */ diff --git a/driver/sb_rmi.c b/driver/sb_rmi.c index fbcbd990ff..a7ceeeead4 100644 --- a/driver/sb_rmi.c +++ b/driver/sb_rmi.c @@ -17,8 +17,8 @@ #define CPUTS(outstr) cputs(CC_SYSTEM, outstr) #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) -#define SB_RMI_MAILBOX_TIMEOUT_MS 10 -#define SB_RMI_MAILBOX_RETRY_DELAY_US 200 +#define SB_RMI_MAILBOX_TIMEOUT_MS 200 +#define SB_RMI_MAILBOX_RETRY_DELAY_MS 5 /** * Write an SB-RMI register @@ -83,8 +83,7 @@ int sb_rmi_mailbox_xfer(int cmd, uint32_t msg_in, uint32_t *msg_out_ptr) * 8. For a read operation, the initiator (BMC) reads the firmware * response Command Data Out[31:0] from SBRMI::OutBndMsg_inst[4:1] * {SBRMI_x34(MSB):SBRMI_x31(LSB)}. - * 9. Firmware clears the interrupt on SBRMI::SoftwareInterrupt. - * 10. BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear the + * 9. BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear the * ALERT to initiator (BMC). It is recommended to clear the ALERT * upon completion of the current mailbox command. */ @@ -136,20 +135,17 @@ int sb_rmi_mailbox_xfer(int cmd, uint32_t msg_in, uint32_t *msg_out_ptr) alerted = true; break; } - msleep(1); + msleep(SB_RMI_MAILBOX_RETRY_DELAY_MS); } while (time_since32(start) < SB_RMI_MAILBOX_TIMEOUT_MS * MSEC); if (!alerted) { CPRINTS("SB-SMI: Mailbox transfer timeout"); - /* Clear interrupt */ - sb_rmi_assert_interrupt(0); return EC_ERROR_TIMEOUT; } RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG0_REG, &val)); if (val != cmd) { CPRINTS("RMI: Unexpected command value in out bound message"); - sb_rmi_assert_interrupt(0); return EC_ERROR_UNKNOWN; } @@ -164,17 +160,14 @@ int sb_rmi_mailbox_xfer(int cmd, uint32_t msg_in, uint32_t *msg_out_ptr) RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG4_REG, &val)); *msg_out_ptr |= val << 24; - /* Step 9: clear SBRMIx40[Software Interrupt] */ - RETURN_ERROR(sb_rmi_assert_interrupt(0)); - /** - * Step 10: BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear + * Step 9: BMC must write 1'b1 to SBRMI::Status[SwAlertSts] to clear * the ALERT to initiator (BMC). It is recommended to clear the * ALERT upon completion of the current mailbox command. */ RETURN_ERROR(sb_rmi_write(SB_RMI_STATUS_REG, 0x2)); - /* Step 11: read the return code from OutBndMsg_inst7 (SBRMI_x37) */ + /* Step 10: read the return code from OutBndMsg_inst7 (SBRMI_x37) */ RETURN_ERROR(sb_rmi_read(SB_RMI_OUT_BND_MSG7_REG, &val)); switch (val) { diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c index dde7b7e306..9ef281bc99 100644 --- a/driver/tcpm/anx7447.c +++ b/driver/tcpm/anx7447.c @@ -455,13 +455,17 @@ static void anx7447_tcpc_alert(int port) static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; void anx7447_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { int reg = 0; int port = me->usb_port; int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; + /* This driver does not use host command ACKs */ + *ack_required = false; + /* * All calls within this method need to update to a mux_read/write calls * that use the secondary address. This is a non-trival change and no diff --git a/driver/tcpm/anx7447.h b/driver/tcpm/anx7447.h index 75982e6b91..3b27a19e2d 100644 --- a/driver/tcpm/anx7447.h +++ b/driver/tcpm/anx7447.h @@ -143,7 +143,8 @@ extern const struct tcpm_drv anx7447_tcpm_drv; extern const struct usb_mux_driver anx7447_usb_mux_driver; void anx7447_tcpc_clear_hpd_status(int port); void anx7447_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state); + mux_state_t mux_state, + bool *ack_required); /** * Erase OCM flash if it's not empty diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c index 567005920e..1fc813c448 100644 --- a/driver/tcpm/anx74xx.c +++ b/driver/tcpm/anx74xx.c @@ -233,13 +233,17 @@ static void anx74xx_tcpc_discharge_vbus(int port, int enable) static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; void anx74xx_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { int reg; int port = me->usb_port; int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; + /* This driver does not use host command ACKs */ + *ack_required = false; + mux_read(me, ANX74XX_REG_HPD_CTRL_0, ®); if (hpd_lvl) reg |= ANX74XX_REG_HPD_OUT_DATA; diff --git a/driver/tcpm/anx74xx.h b/driver/tcpm/anx74xx.h index 8d700d4d86..19ac3e304f 100644 --- a/driver/tcpm/anx74xx.h +++ b/driver/tcpm/anx74xx.h @@ -220,7 +220,8 @@ extern const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver; void anx74xx_tcpc_set_vbus(int port, int enable); void anx74xx_tcpc_clear_hpd_status(int port); void anx74xx_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state); + mux_state_t mux_state, + bool *ack_required); #ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC extern struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev; diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c index 7bd2913bd7..c809cce153 100644 --- a/driver/tcpm/it83xx.c +++ b/driver/tcpm/it83xx.c @@ -737,8 +737,8 @@ static int it83xx_tcpm_enter_low_power_mode(int port) { /* * ITE embedded TCPC SLEEP_MASK_USB_PD flag is only controlled by - * it83xx driver in set_pd_sleep_mask(), and do low power mode in - * idle_task(). + * it83xx driver in tc_update_pd_sleep_mask(), and do low power + * mode in idle_task(). * In deep sleep mode, ITE TCPC clock is turned off, and the * timer every 5ms to exit the mode and wakeup PD task to run * (ex. change the CC lines termination). @@ -786,17 +786,17 @@ void switch_plug_out_type(enum usbpd_port port) it83xx_tcpm_switch_plug_out_type(port); } -void set_pd_sleep_mask(int port) +__override void tc_update_pd_sleep_mask(int port) { int i; bool prevent_deep_sleep = false; /* - * Set SLEEP_MASK_USB_PD for deep sleep mode: - * 1.Enable deep sleep mode, when all ITE ports are in Unattach.SRC/SNK - * state (HOOK_DISCONNECT called) and other ports aren't pd_capable(). - * 2.Disable deep sleep mode, when one of ITE port is in Attach.SRC/SNK - * state (HOOK_CONNECT called) or one of other ports is pd_capable(). + * Check ITE embedded pd ports to set SLEEP_MASK_USB_PD: + * In tc_attached_[src, snk]_entry states, calling HOOK_CONNECT + * to enable BMC PHY, and if one of ITE pd ports BMC PHY is enable, + * then EC deep doze mode will be disabled. + * Otherwise, EC deep doze mode will be enabled. */ for (i = 0; i < CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT; ++i) { if (IT83XX_USBPD_GCR(i) & USBPD_REG_MASK_BMC_PHY) { @@ -806,9 +806,11 @@ void set_pd_sleep_mask(int port) } /* - * Check if any other ports have a PD port partner connected. Deep - * sleep is forbidden if any PD port partner is connected. Above, we - * only checked for the ITE ports. + * Check Other stand alone pd ports to set SLEEP_MASK_USB_PD: + * In [pe_src_send_capabilities_run, pe_snk_select_capability_entry] + * states receive [GoodCRC, SRC_CAP] from port partner, then EC deep + * doze mode will be disabled. + * Otherwise, EC deep doze mode will be enabled. */ if (!prevent_deep_sleep) { for (; i < board_get_usb_pd_port_count(); i++) @@ -826,6 +828,16 @@ static void it83xx_tcpm_hook_connect(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* + * If it isn't ITE active port, then return. + * + * NOTE: If we don't use all the ITE pd ports on a board, then we + * need to start from port0 to use the ITE pd port. If we + * start from port1, then port1 HOOK function never works. + */ + if (port > (CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT - 1)) + return; + #ifdef CONFIG_USB_PD_TCPMV2 /* * There are five cases that hook_connect() be called by TCPMv2: @@ -848,7 +860,14 @@ static void it83xx_tcpm_hook_connect(void) #endif /* Enable PD PHY Tx and Rx module since type-c has connected. */ USBPD_ENABLE_BMC_PHY(port); - set_pd_sleep_mask(port); + /* + * After we're in attached.[SRC, SNK] states and before we receive + * [GoodCRC of SRC_CAP, SRC_CAP] this period time, if EC goes to + * deep doze mode, the pd clock will be gated, then pd can't + * transmit and receive any messages, so we disable deep doze mode + * to make sure that pd won't miss any messages. + */ + tc_update_pd_sleep_mask(port); } DECLARE_HOOK(HOOK_USB_PD_CONNECT, it83xx_tcpm_hook_connect, HOOK_PRIO_DEFAULT); @@ -857,6 +876,16 @@ static void it83xx_tcpm_hook_disconnect(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* + * If it isn't ITE active port, then return. + * + * NOTE: If we don't use all the ITE pd ports on a board, then we + * need to start from port0 to use the ITE pd port. If we + * start from port1, then port1 HOOK function never works. + */ + if (port > (CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT - 1)) + return; + if (IS_ENABLED(IT83XX_INTC_PLUG_IN_OUT_SUPPORT)) /* * Switch to detect plug in and enable detect plug in interrupt, @@ -876,7 +905,11 @@ static void it83xx_tcpm_hook_disconnect(void) if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) sop_prime_en[port] = 0; USBPD_DISABLE_BMC_PHY(port); - set_pd_sleep_mask(port); + /* + * Since PD BMC PHY is off, then EC can go to deep doze mode and + * turn off pd clock. + */ + tc_update_pd_sleep_mask(port); } DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, it83xx_tcpm_hook_disconnect, diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c index dd5d1231fc..7bed654132 100644 --- a/driver/tcpm/it8xxx2.c +++ b/driver/tcpm/it8xxx2.c @@ -657,7 +657,7 @@ static int it8xxx2_tcpm_enter_low_power_mode(int port) { /* * ITE embedded TCPC SLEEP_MASK_USB_PD flag is only controlled by - * it8xxx2 driver in it8xxx2_set_pd_sleep_mask(), and do low power + * it8xxx2 driver in tc_update_pd_sleep_mask(), and do low power * mode in idle_task(). * In deep sleep mode, ITE TCPC clock is turned off, and the * timer every 5ms to exit the mode and wakeup PD task to run @@ -844,17 +844,17 @@ static int it8xxx2_tcpm_init(int port) return EC_SUCCESS; } -static void it8xxx2_set_pd_sleep_mask(int port) +__override void tc_update_pd_sleep_mask(int port) { int i; bool prevent_deep_sleep = false; /* - * Set SLEEP_MASK_USB_PD for deep sleep mode: - * 1.Enable deep sleep mode, when all ITE ports are in Unattach.SRC/SNK - * state (HOOK_DISCONNECT called) and other ports aren't pd_capable(). - * 2.Disable deep sleep mode, when one of ITE port is in Attach.SRC/SNK - * state (HOOK_CONNECT called) or one of other ports is pd_capable(). + * Check ITE embedded pd ports to set SLEEP_MASK_USB_PD: + * In tc_attached_[src, snk]_entry states, calling HOOK_CONNECT + * to enable BMC PHY, and if one of ITE pd ports BMC PHY is enable, + * then EC deep doze mode will be disabled. + * Otherwise, EC deep doze mode will be enabled. */ for (i = 0; i < CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT; ++i) { if (IT83XX_USBPD_PDGCR(i) & USBPD_REG_MASK_BMC_PHY) { @@ -864,9 +864,11 @@ static void it8xxx2_set_pd_sleep_mask(int port) } /* - * Check if any other ports have a PD port partner connected. Deep - * sleep is forbidden if any PD port partner is connected. Above, we - * only checked for the ITE ports. + * Check Other stand alone pd ports to set SLEEP_MASK_USB_PD: + * In [pe_src_send_capabilities_run, pe_snk_select_capability_entry] + * states receive [GoodCRC, SRC_CAP] from port partner, then EC deep + * doze mode will be disabled. + * Otherwise, EC deep doze mode will be enabled. */ if (!prevent_deep_sleep) { for (; i < board_get_usb_pd_port_count(); i++) @@ -884,6 +886,16 @@ static void it8xxx2_tcpm_hook_connect(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* + * If it isn't ITE active port, then return. + * + * NOTE: If we don't use all the ITE pd ports on a board, then we + * need to start from port0 to use the ITE pd port. If we + * start from port1, then port1 HOOK function never works. + */ + if (port > (CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT - 1)) + return; + #ifdef CONFIG_USB_PD_TCPMV2 /* * There are five cases that hook_connect() be called by TCPMv2: @@ -906,7 +918,14 @@ static void it8xxx2_tcpm_hook_connect(void) #endif /* Enable PD PHY Tx and Rx module since type-c has connected. */ USBPD_ENABLE_BMC_PHY(port); - it8xxx2_set_pd_sleep_mask(port); + /* + * After we're in attached.[SRC, SNK] states and before we receive + * [GoodCRC of SRC_CAP, SRC_CAP] this period time, if EC goes to + * deep doze mode, the pd clock will be gated, then pd can't + * transmit and receive any messages, so we disable deep doze mode + * to make sure that pd won't miss any messages. + */ + tc_update_pd_sleep_mask(port); } DECLARE_HOOK(HOOK_USB_PD_CONNECT, it8xxx2_tcpm_hook_connect, HOOK_PRIO_DEFAULT); @@ -915,6 +934,16 @@ static void it8xxx2_tcpm_hook_disconnect(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* + * If it isn't ITE active port, then return. + * + * NOTE: If we don't use all the ITE pd ports on a board, then we + * need to start from port0 to use the ITE pd port. If we + * start from port1, then port1 HOOK function never works. + */ + if (port > (CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT - 1)) + return; + if (IS_ENABLED(IT83XX_INTC_PLUG_IN_OUT_SUPPORT)) /* * Switch to detect plug in and enable detect plug in interrupt, @@ -934,7 +963,11 @@ static void it8xxx2_tcpm_hook_disconnect(void) if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) sop_prime_en[port] = 0; USBPD_DISABLE_BMC_PHY(port); - it8xxx2_set_pd_sleep_mask(port); + /* + * Since PD BMC PHY is off, then EC can go to deep doze mode and + * turn off pd clock. + */ + tc_update_pd_sleep_mask(port); } DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, it8xxx2_tcpm_hook_disconnect, diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c index 00240516e5..0d45c8aa9f 100644 --- a/driver/tcpm/nct38xx.c +++ b/driver/tcpm/nct38xx.c @@ -14,6 +14,17 @@ #include "tcpm/tcpci.h" #include "usb_common.h" +#ifdef CONFIG_ZEPHYR +#include <device.h> +#include <drivers/gpio/gpio_nct38xx.h> +#include "usbc/tcpc_nct38xx.h" +#endif + +#if defined(CONFIG_ZEPHYR) && defined(CONFIG_IO_EXPANDER_NCT38XX) +#error CONFIG_IO_EXPANDER_NCT38XX cannot be used with Zephyr. +#error Enable the Zephyr driver CONFIG_GPIO_NCT38XX instead. +#endif + #if !defined(CONFIG_USB_PD_TCPM_TCPCI) #error "NCT38XX is using part of standard TCPCI control" #error "Please upgrade your board configuration" @@ -134,8 +145,19 @@ static int nct38xx_init(int port) * Enable the Vendor Define alert event only when the IO expander * feature is defined */ - if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX)) + if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX) || + IS_ENABLED(CONFIG_GPIO_NCT38XX)) { +#ifdef CONFIG_ZEPHYR + const struct device *dev = + nct38xx_get_gpio_device_from_port(port); + + if (!device_is_ready(dev)) { + CPRINTS("C%d: device is not ready", port); + return EC_ERROR_BUSY; + } +#endif /* CONFIG_ZEPHYR */ reg |= TCPC_REG_ALERT_VENDOR_DEF; + } rv = tcpc_update16(port, TCPC_REG_ALERT_MASK, @@ -244,6 +266,20 @@ __overridable int board_map_nct38xx_tcpc_port_to_ioex(int port) return port; } +static inline void nct38xx_tcpc_vendor_defined_alert(int port) +{ +#ifdef CONFIG_ZEPHYR + const struct device *dev = nct38xx_get_gpio_device_from_port(port); + + nct38xx_gpio_alert_handler(dev); +#else + int ioexport; + + ioexport = board_map_nct38xx_tcpc_port_to_ioex(port); + nct38xx_ioex_event_handler(ioexport); +#endif /* CONFIG_ZEPHYR */ +} + static void nct38xx_tcpc_alert(int port) { int alert, rv; @@ -274,12 +310,10 @@ static void nct38xx_tcpc_alert(int port) * tcpci_tcpc_alert(). Check the Vendor Defined Alert bit to * handle the IOEX IO's interrupt event. */ - if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX) && - rv == EC_SUCCESS && (alert & TCPC_REG_ALERT_VENDOR_DEF)) { - int ioexport; - - ioexport = board_map_nct38xx_tcpc_port_to_ioex(port); - nct38xx_ioex_event_handler(ioexport); + if ((IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX) || + IS_ENABLED(CONFIG_GPIO_NCT38XX)) && + rv == EC_SUCCESS && (alert & TCPC_REG_ALERT_VENDOR_DEF)) { + nct38xx_tcpc_vendor_defined_alert(port); } } diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index 426219f1fa..572616efb4 100644 --- a/driver/tcpm/ps8xxx.c +++ b/driver/tcpm/ps8xxx.c @@ -383,12 +383,16 @@ bool check_ps8755_chip(int port) } void ps8xxx_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state) + mux_state_t mux_state, + bool *ack_required) { int port = me->usb_port; int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; + /* This driver does not use host command ACKs */ + *ack_required = false; + if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8751_CUSTOM_MUX_DRIVER) && product_id[me->usb_port] == PS8751_PRODUCT_ID && me->flags & USB_MUX_FLAG_NOT_TCPC) @@ -710,11 +714,12 @@ static int ps8xxx_get_chip_info(int port, int live, static int ps8xxx_enter_low_power_mode(int port) { /* - * PS8751 has the auto sleep function that enters low power mode on - * its own in ~2 seconds. Other chips don't have it. Stub it out for - * PS8751. + * PS8751/PS8815 has the auto sleep function that enters + * low power mode on its own in ~2 seconds. Other chips + * don't have it. Stub it out for PS8751/PS8815. */ - if (product_id[port] == PS8751_PRODUCT_ID) + if (product_id[port] == PS8751_PRODUCT_ID || + product_id[port] == PS8815_PRODUCT_ID) return EC_SUCCESS; return tcpci_enter_low_power_mode(port); diff --git a/driver/tcpm/rt1718s.c b/driver/tcpm/rt1718s.c index 9d5a8895ad..81356c946c 100644 --- a/driver/tcpm/rt1718s.c +++ b/driver/tcpm/rt1718s.c @@ -88,7 +88,7 @@ int rt1718s_read16(int port, int reg, int *val) } -static int rt1718s_sw_reset(int port) +int rt1718s_sw_reset(int port) { int rv; @@ -252,6 +252,9 @@ static int rt1718s_init(int port) TCPC_REG_ALERT_MASK_VENDOR_DEF, MASK_SET)); + if (IS_ENABLED(CONFIG_USB_PD_FRS_TCPC)) + rt1718s_frs_init(port); + RETURN_ERROR(board_rt1718s_init(port)); return EC_SUCCESS; @@ -326,7 +329,11 @@ static void rt1718s_bc12_usb_charger_task(const int port) uint32_t evt = task_wait_event(-1); if (evt & USB_CHG_EVENT_VBUS) { - if (pd_snk_is_vbus_provided(port)) + bool is_non_pd_sink = !pd_capable(port) && + pd_get_power_role(port) == PD_ROLE_SINK && + pd_snk_is_vbus_provided(port); + + if (is_non_pd_sink) rt1718s_enable_bc12_sink(port, true); else rt1718s_update_charge_manager( @@ -428,7 +435,7 @@ static int rt1718s_enter_low_power_mode(int port) int rt1718s_get_adc(int port, enum rt1718s_adc_channel channel, int *adc_val) { - static struct mutex adc_lock; + static mutex_t adc_lock; int rv; const int max_wait_times = 30; @@ -520,6 +527,35 @@ int rt1718s_gpio_get_level(int port, enum rt1718s_gpio signal) return !!(val & RT1718S_GPIO_CTRL_I); } +static int command_rt1718s_gpio(int argc, char **argv) +{ + int i, j; + uint32_t flags; + + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + + if (tcpc_config[i].drv != &rt1718s_tcpm_drv) + continue; + + for (j = 0; j < RT1718S_GPIO_COUNT; j++) { + int rv; + + rv = rt1718s_read8(i, RT1718S_GPIO_CTRL(j), &flags); + if (rv) + return EC_ERROR_UNKNOWN; + + ccprintf("C%d GPIO%d OD=%d PU=%d PD=%d OE=%d HL=%d\n", + i, j, !(flags & RT1718S_GPIO_CTRL_OD_N), + !!(flags & RT1718S_GPIO_CTRL_PU), + !!(flags & RT1718S_GPIO_CTRL_PD), + !!(flags & RT1718S_GPIO_CTRL_OE), + !!(flags & RT1718S_GPIO_CTRL_O)); + } + } + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(rt1718s_gpio, command_rt1718s_gpio, "", "RT1718S GPIO"); + /* RT1718S is a TCPCI compatible port controller */ const struct tcpm_drv rt1718s_tcpm_drv = { .init = &rt1718s_init, @@ -554,6 +590,9 @@ const struct tcpm_drv rt1718s_tcpm_drv = { #ifdef CONFIG_USB_PD_TCPC_LOW_POWER .enter_low_power_mode = &rt1718s_enter_low_power_mode, #endif +#ifdef CONFIG_USB_PD_FRS_TCPC + .set_frs_enable = &rt1718s_set_frs_enable, +#endif }; const struct bc12_drv rt1718s_bc12_drv = { diff --git a/driver/tcpm/rt1718s.h b/driver/tcpm/rt1718s.h index 07c3ed3f82..2e74132847 100644 --- a/driver/tcpm/rt1718s.h +++ b/driver/tcpm/rt1718s.h @@ -10,7 +10,8 @@ #include "usb_pd_tcpm.h" /* RT1718S Private RegMap */ -#define RT1718S_I2C_ADDR_FLAGS 0x43 +#define RT1718S_I2C_ADDR1_FLAGS 0x43 +#define RT1718S_I2C_ADDR2_FLAGS 0x40 #define RT1718S_VID 0x29CF #define RT1718S_PID 0x1718 @@ -213,6 +214,7 @@ enum rt1718s_gpio { RT1718S_GPIO1 = 0, RT1718S_GPIO2, RT1718S_GPIO3, + RT1718S_GPIO_COUNT, }; /** @@ -242,4 +244,29 @@ void rt1718s_gpio_set_level(int port, enum rt1718s_gpio signal, int value); */ int rt1718s_gpio_get_level(int port, enum rt1718s_gpio signal); +/** + * Set fast role swap. + * + * @param port USB-C port + * @param enable enable/disable FRS + * @return EC_SUCCESS if success, EC_ERROR_UNKNOWN otherwise. + */ +int rt1718s_set_frs_enable(int port, int enable); + +/** + * Initialize RT1718S FRS function + * + * @param port USB-C port + * @return EC_SUCCESS if success, EC_ERROR_UNKNOWN otherwise. + */ +int rt1718s_frs_init(int port); + + +/** + * Software reset RT1718S + * + * @param port USB-C port + * @return EC_SUCCESS if success, EC_ERROR_UNKNOWN otherwise. + */ +int rt1718s_sw_reset(int port); #endif /* __CROS_EC_USB_PD_TCPM_MT6370_H */ diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 359cb04d30..b04d7be1af 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -877,12 +877,12 @@ struct queue { * Head points to the index of the first empty slot to put a new RX * message. Must be masked before used in lookup. */ - uint32_t head; + atomic_t head; /* * Tail points to the index of the first message for the PD task to * consume. Must be masked before used in lookup. */ - uint32_t tail; + atomic_t tail; struct cached_tcpm_message buffer[CACHE_DEPTH]; }; static struct queue cached_messages[CONFIG_USB_PD_PORT_MAX_COUNT]; diff --git a/driver/temp_sensor/adt7481.c b/driver/temp_sensor/adt7481.c index b10404733c..738fdb776a 100644 --- a/driver/temp_sensor/adt7481.c +++ b/driver/temp_sensor/adt7481.c @@ -25,8 +25,8 @@ static uint8_t is_sensor_shutdown; */ static int has_power(void) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return !is_sensor_shutdown; #endif @@ -340,12 +340,12 @@ DECLARE_CONSOLE_COMMAND(adt7481, command_adt7481, int adt7481_set_power(enum adt7481_power_state power_on) { -#ifndef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifndef CONFIG_TEMP_SENSOR_POWER uint8_t shutdown = (power_on == ADT7481_POWER_OFF) ? 1 : 0; return adt7481_shutdown(shutdown); #else - gpio_set_level(CONFIG_TEMP_SENSOR_POWER_GPIO, power_on); + gpio_set_level(GPIO_TEMP_SENSOR_POWER, power_on); return EC_SUCCESS; #endif } diff --git a/driver/temp_sensor/g753.c b/driver/temp_sensor/g753.c index 857263c161..e3946e4f43 100644 --- a/driver/temp_sensor/g753.c +++ b/driver/temp_sensor/g753.c @@ -22,8 +22,8 @@ static int temp_val_local; */ static int has_power(void) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return 1; #endif diff --git a/driver/temp_sensor/g78x.c b/driver/temp_sensor/g78x.c index aef13d3d68..c4fd0ff243 100644 --- a/driver/temp_sensor/g78x.c +++ b/driver/temp_sensor/g78x.c @@ -26,8 +26,8 @@ static int temp_val_remote2; */ static int has_power(void) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return 1; #endif diff --git a/driver/temp_sensor/pct2075.c b/driver/temp_sensor/pct2075.c new file mode 100644 index 0000000000..bde1521edc --- /dev/null +++ b/driver/temp_sensor/pct2075.c @@ -0,0 +1,91 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* PCT2075 temperature sensor module for Chrome EC */ + +#include "common.h" +#include "console.h" +#include "pct2075.h" +#include "i2c.h" +#include "hooks.h" +#include "math_util.h" +#include "util.h" + +#define PCT2075_RESOLUTION 11 +#define PCT2075_SHIFT1 (16 - PCT2075_RESOLUTION) +#define PCT2075_SHIFT2 (PCT2075_RESOLUTION - 8) + +#define CPRINTS(format, args...) cprints(CC_THERMAL, format, ## args) + +static int temp_mk_local[PCT2075_COUNT]; + +static int raw_read16(int sensor, const int offset, int *data_ptr) +{ +#ifdef CONFIG_I2C_BUS_MAY_BE_UNPOWERED + /* + * Don't try to read if the port is unpowered + */ + if (!board_is_i2c_port_powered(pct2075_sensors[sensor].i2c_port)) + return EC_ERROR_NOT_POWERED; +#endif + return i2c_read16(pct2075_sensors[sensor].i2c_port, + pct2075_sensors[sensor].i2c_addr_flags, + offset, data_ptr); +} + +static int get_reg_temp(int sensor, int *temp_ptr) +{ + int temp_raw = 0; + + RETURN_ERROR(raw_read16(sensor, PCT2075_REG_TEMP, &temp_raw)); + + *temp_ptr = (int)(int16_t)temp_raw; + return EC_SUCCESS; +} + +static inline int pct2075_reg_to_mk(int16_t reg) +{ + int temp_mc; + + temp_mc = (((reg >> PCT2075_SHIFT1) * 1000) >> PCT2075_SHIFT2); + + return MILLI_CELSIUS_TO_MILLI_KELVIN(temp_mc); +} + +int pct2075_get_val_k(int idx, int *temp_k_ptr) +{ + if (idx >= PCT2075_COUNT) + return EC_ERROR_INVAL; + + *temp_k_ptr = MILLI_KELVIN_TO_KELVIN(temp_mk_local[idx]); + return EC_SUCCESS; +} + +int pct2075_get_val_mk(int idx, int *temp_mk_ptr) +{ + if (idx >= PCT2075_COUNT) + return EC_ERROR_INVAL; + + *temp_mk_ptr = temp_mk_local[idx]; + return EC_SUCCESS; +} + +static void pct2075_poll(void) +{ + int s; + int temp_reg = 0; + + for (s = 0; s < PCT2075_COUNT; s++) { + if (get_reg_temp(s, &temp_reg) == EC_SUCCESS) + temp_mk_local[s] = pct2075_reg_to_mk(temp_reg); + } +} +DECLARE_HOOK(HOOK_SECOND, pct2075_poll, HOOK_PRIO_TEMP_SENSOR); + +void pct2075_init(void) +{ +/* Incase we need to initialize somthing */ +} +DECLARE_HOOK(HOOK_INIT, pct2075_init, HOOK_PRIO_DEFAULT); diff --git a/driver/temp_sensor/pct2075.h b/driver/temp_sensor/pct2075.h new file mode 100644 index 0000000000..c09d0e383c --- /dev/null +++ b/driver/temp_sensor/pct2075.h @@ -0,0 +1,70 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_PCT2075_H +#define __CROS_EC_PCT2075_H + +#include "i2c.h" + +#define PCT2075_I2C_ADDR_FLAGS0 (0x48 | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS1 (0x49 | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS2 (0x4A | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS3 (0x4B | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS4 (0x4C | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS5 (0x4D | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS6 (0x4E | I2C_FLAG_BIG_ENDIAN) +#define PCT2075_I2C_ADDR_FLAGS7 (0x4F | I2C_FLAG_BIG_ENDIAN) + +#define PCT2075_REG_TEMP 0x00 +#define PCT2075_REG_CONF 0x01 +#define PCT2075_REG_THYST 0x02 +#define PCT2075_REG_TOS 0x03 + +/* + * I2C port and address information for all the board PCT2075 sensors should be + * defined in an array of the following structures, with an enum PCT2075_sensor + * indexing the array. The enum PCT2075_sensor shall end with a PCT2075_COUNT + * defining the maximum number of sensors for the board. + */ + +struct pct2075_sensor_t { + int i2c_port; + int i2c_addr_flags; +}; + +extern const struct pct2075_sensor_t pct2075_sensors[]; + +/** + * Get the last polled value of a sensor. + * + * @param idx Index to read, from board's enum PCT2075_sensor + * definition + * + * @param temp_k_ptr Destination for temperature in K. + * + * @return EC_SUCCESS if successful, non-zero if error. + */ +int pct2075_get_val_k(int idx, int *temp_k_ptr); + +/** + * Get the last polled value of a sensor. + * + * @param idx Index to read, from board's enum PCT2075_sensor + * definition + * + * @param temp_mk_ptr Destination for temperature in mK. + * + * @return EC_SUCCESS if successful, non-zero if error. + */ +int pct2075_get_val_mk(int idx, int *temp_mk_ptr); + +/** + * Init the sensors. Note, this will run automatically on HOOK_INIT, but is + * made available for boards which may not always power the sensor in all + * states. + */ +void pct2075_init(void); + +#endif /* __CROS_EC_PCT2075_H */ diff --git a/driver/temp_sensor/thermistor.c b/driver/temp_sensor/thermistor.c index ffa780cb07..bef10416b6 100644 --- a/driver/temp_sensor/thermistor.c +++ b/driver/temp_sensor/thermistor.c @@ -77,14 +77,14 @@ int thermistor_get_temperature(int idx_adc, int *temp_ptr, { int mv; -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifdef CONFIG_TEMP_SENSOR_POWER /* * If the power rail for the thermistor circuit is not enabled, then * need to ignore any ADC measurments. */ - if (!gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO)) + if (!gpio_get_level(GPIO_TEMP_SENSOR_POWER)) return EC_ERROR_NOT_POWERED; -#endif /* CONFIG_TEMP_SENSOR_POWER_GPIO */ +#endif /* CONFIG_TEMP_SENSOR_POWER */ mv = adc_read_channel(idx_adc); if (mv < 0) return EC_ERROR_UNKNOWN; diff --git a/driver/temp_sensor/tmp006.c b/driver/temp_sensor/tmp006.c index 22f4402747..96922c857c 100644 --- a/driver/temp_sensor/tmp006.c +++ b/driver/temp_sensor/tmp006.c @@ -75,8 +75,8 @@ static const struct tmp006_data_t tmp006_data_default = { static int tmp006_has_power(int idx) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return 1; #endif diff --git a/driver/temp_sensor/tmp112.c b/driver/temp_sensor/tmp112.c index 4da5c4e0e8..6e726a27b9 100644 --- a/driver/temp_sensor/tmp112.c +++ b/driver/temp_sensor/tmp112.c @@ -7,12 +7,16 @@ #include "common.h" #include "console.h" -#include "tmp112.h" #include "i2c.h" #include "hooks.h" #include "math_util.h" +#include "temp_sensor/tmp112.h" #include "util.h" +#ifdef CONFIG_ZEPHYR +#include "temp_sensor/temp_sensor.h" +#endif + #define TMP112_RESOLUTION 12 #define TMP112_SHIFT1 (16 - TMP112_RESOLUTION) #define TMP112_SHIFT2 (TMP112_RESOLUTION - 8) diff --git a/driver/temp_sensor/tmp411.c b/driver/temp_sensor/tmp411.c index ee50d0a894..8db3f9a8d8 100644 --- a/driver/temp_sensor/tmp411.c +++ b/driver/temp_sensor/tmp411.c @@ -24,8 +24,8 @@ static uint8_t is_sensor_shutdown; */ static int has_power(void) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return !is_sensor_shutdown; #endif @@ -318,12 +318,12 @@ DECLARE_CONSOLE_COMMAND(tmp411, command_tmp411, int tmp411_set_power(enum tmp411_power_state power_on) { -#ifndef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifndef CONFIG_TEMP_SENSOR_POWER uint8_t shutdown = (power_on == TMP411_POWER_OFF) ? 1 : 0; return tmp411_shutdown(shutdown); #else - gpio_set_level(CONFIG_TEMP_SENSOR_POWER_GPIO, power_on); + gpio_set_level(GPIO_TEMP_SENSOR_POWER, power_on); return EC_SUCCESS; #endif } diff --git a/driver/temp_sensor/tmp432.c b/driver/temp_sensor/tmp432.c index 4226f51bfd..8db6a99e19 100644 --- a/driver/temp_sensor/tmp432.c +++ b/driver/temp_sensor/tmp432.c @@ -16,7 +16,7 @@ static int temp_val_local; static int temp_val_remote1; static int temp_val_remote2; -#ifndef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifndef CONFIG_TEMP_SENSOR_POWER static uint8_t is_sensor_shutdown; #endif static int fake_temp[TMP432_IDX_COUNT] = {-1, -1, -1}; @@ -28,8 +28,8 @@ static int fake_temp[TMP432_IDX_COUNT] = {-1, -1, -1}; */ static int has_power(void) { -#ifdef CONFIG_TEMP_SENSOR_POWER_GPIO - return gpio_get_level(CONFIG_TEMP_SENSOR_POWER_GPIO); +#ifdef CONFIG_TEMP_SENSOR_POWER + return gpio_get_level(GPIO_TEMP_SENSOR_POWER); #else return !is_sensor_shutdown; #endif @@ -92,7 +92,7 @@ int tmp432_get_val(int idx, int *temp_ptr) return EC_SUCCESS; } -#ifndef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifndef CONFIG_TEMP_SENSOR_POWER static int tmp432_shutdown(uint8_t want_shutdown) { int ret, value; @@ -388,11 +388,11 @@ DECLARE_CONSOLE_COMMAND(tmp432, command_tmp432, int tmp432_set_power(enum tmp432_power_state power_on) { -#ifndef CONFIG_TEMP_SENSOR_POWER_GPIO +#ifndef CONFIG_TEMP_SENSOR_POWER uint8_t shutdown = (power_on == TMP432_POWER_OFF) ? 1 : 0; return tmp432_shutdown(shutdown); #else - gpio_set_level(CONFIG_TEMP_SENSOR_POWER_GPIO, power_on); + gpio_set_level(GPIO_TEMP_SENSOR_POWER, power_on); return EC_SUCCESS; #endif } diff --git a/driver/usb_mux/ps8743.c b/driver/usb_mux/ps8743.c index f618bb009f..f126d36378 100644 --- a/driver/usb_mux/ps8743.c +++ b/driver/usb_mux/ps8743.c @@ -23,6 +23,14 @@ int ps8743_write(const struct usb_mux *me, uint8_t reg, uint8_t val) reg, val); } +int ps8743_field_update(const struct usb_mux *me, uint8_t reg, uint8_t mask, + uint8_t val) +{ + return i2c_field_update8(me->i2c_port, me->i2c_addr_flags, + reg, mask, val); +} + + int ps8743_check_chip_id(const struct usb_mux *me, int *val) { int id1; diff --git a/driver/usb_mux/tusb1064.c b/driver/usb_mux/tusb1064.c index c236e3d1ab..d0e8678039 100644 --- a/driver/usb_mux/tusb1064.c +++ b/driver/usb_mux/tusb1064.c @@ -14,12 +14,6 @@ #error "Must choose CONFIG_USB_MUX_TUSB1044 or CONFIG_USB_MUX_TUSB1064" #endif -/* - * configuration bits which never change in the General Register - * e.g. REG_GENERAL_DP_EN_CTRL or REG_GENERAL_EQ_OVERRIDE - */ -#define REG_GENERAL_STATIC_BITS REG_GENERAL_EQ_OVERRIDE - static int tusb1064_read(const struct usb_mux *me, uint8_t reg, uint8_t *val) { int buffer = 0xee; @@ -36,11 +30,15 @@ static int tusb1064_write(const struct usb_mux *me, uint8_t reg, uint8_t val) } #if defined(CONFIG_USB_MUX_TUSB1044) -void tusb1044_hpd_update(const struct usb_mux *me, mux_state_t mux_state) +void tusb1044_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { int res; uint8_t reg; + /* This driver does not use host command ACKs */ + *ack_required = false; + res = tusb1064_read(me, TUSB1064_REG_GENERAL, ®); if (res) return; @@ -60,11 +58,54 @@ void tusb1044_hpd_update(const struct usb_mux *me, mux_state_t mux_state) } #endif +int tusb1064_set_dp_rx_eq(const struct usb_mux *me, int db) +{ + uint8_t reg; + int rv; + + if (db < TUSB1064_DP_EQ_RX_NEG_0_3_DB || db > TUSB1064_DP_EQ_RX_12_1_DB) + return EC_ERROR_INVAL; + + /* Set the requested gain values */ + reg = TUSB1064_DP1EQ(db) | TUSB1064_DP3EQ(db); + rv = tusb1064_write(me, TUSB1064_REG_DP1DP3EQ_SEL, reg); + if (rv) + return rv; + + reg = TUSB1064_DP0EQ(db) | TUSB1064_DP2EQ(db); + rv = tusb1064_write(me, TUSB1064_REG_DP0DP2EQ_SEL, reg); + if (rv) + return rv; + + /* Enable EQ_OVERRIDE so the gain registers are used */ + rv = tusb1064_read(me, TUSB1064_REG_GENERAL, ®); + if (rv) + return rv; + + reg |= REG_GENERAL_EQ_OVERRIDE; + + return tusb1064_write(me, TUSB1064_REG_GENERAL, reg); +} + /* Writes control register to set switch mode */ static int tusb1064_set_mux(const struct usb_mux *me, mux_state_t mux_state, bool *ack_required) { - int reg = REG_GENERAL_STATIC_BITS; + uint8_t reg; + int rv; + int mask; + + rv = tusb1064_read(me, TUSB1064_REG_GENERAL, ®); + if (rv) + return rv; + + /* Mask bits that may be set in this function */ + mask = REG_GENERAL_CTLSEL_USB3 | REG_GENERAL_CTLSEL_ANYDP | + REG_GENERAL_FLIPSEL; +#ifdef CONFIG_USB_MUX_TUSB1044 + mask |= REG_GENERAL_HPDIN_OVERRIDE; +#endif + reg &= ~mask; /* This driver does not use host command ACKs */ *ack_required = false; @@ -112,22 +153,8 @@ static int tusb1064_get_mux(const struct usb_mux *me, mux_state_t *mux_state) static int tusb1064_init(const struct usb_mux *me) { int res; - uint8_t reg; bool unused; - /* Default to "Floating Pin" DP Equalization */ - reg = TUSB1064_DP1EQ(TUSB1064_DP_EQ_RX_10_0_DB) | - TUSB1064_DP3EQ(TUSB1064_DP_EQ_RX_10_0_DB); - res = tusb1064_write(me, TUSB1064_REG_DP1DP3EQ_SEL, reg); - if (res) - return res; - - reg = TUSB1064_DP0EQ(TUSB1064_DP_EQ_RX_10_0_DB) | - TUSB1064_DP2EQ(TUSB1064_DP_EQ_RX_10_0_DB); - res = tusb1064_write(me, TUSB1064_REG_DP0DP2EQ_SEL, reg); - if (res) - return res; - /* * Note that bypassing the usb_mux API is okay for internal driver calls * since the task calling init already holds this port's mux lock. diff --git a/driver/usb_mux/tusb1064.h b/driver/usb_mux/tusb1064.h index f6aa8e612e..5ab8b60e16 100644 --- a/driver/usb_mux/tusb1064.h +++ b/driver/usb_mux/tusb1064.h @@ -137,7 +137,17 @@ * or when no HPD physical pin is connected. * Writes HPD infomration to the General_1 Registor. */ -void tusb1044_hpd_update(const struct usb_mux *me, mux_state_t mux_state); +void tusb1044_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required); #endif +/** + * Set DP Rx Equalization value + * + * @param *me pointer to usb_mux descriptor + * @param db requested gain setting for DP Rx path + * @return EC_SUCCESS if db param is valid and I2C is successful + */ +int tusb1064_set_dp_rx_eq(const struct usb_mux *me, int db); + #endif /* __CROS_EC_TUSB1064_H */ diff --git a/driver/usb_mux/usb_mux.c b/driver/usb_mux/usb_mux.c index ee7f96b905..58cc91a396 100644 --- a/driver/usb_mux/usb_mux.c +++ b/driver/usb_mux/usb_mux.c @@ -32,7 +32,7 @@ static int enable_debug_prints; * Flags will reset to 0 after sysjump; This works for current flags as LPM will * get reset in the init method which is called during PD task startup. */ -static uint32_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; +static atomic_t flags[CONFIG_USB_PD_PORT_MAX_COUNT]; /* Device is in low power mode. */ #define USB_MUX_FLAG_IN_LPM BIT(0) @@ -317,9 +317,6 @@ static int configure_mux(int port, break; } - if (ack_required) - ack_task[port] = task_get_current(); - /* Apply board specific setting */ if (mux_ptr->board_set) rv = mux_ptr->board_set(mux_ptr, lcl_state); @@ -343,7 +340,8 @@ static int configure_mux(int port, case USB_MUX_HPD_UPDATE: if (mux_ptr->hpd_update) - mux_ptr->hpd_update(mux_ptr, *mux_state); + mux_ptr->hpd_update(mux_ptr, *mux_state, + &ack_required); } @@ -351,6 +349,8 @@ static int configure_mux(int port, mutex_unlock(&mux_lock[port]); if (ack_required) { + ack_task[port] = task_get_current(); + /* * This should only be called from the PD task or usb * mux task @@ -358,8 +358,15 @@ static int configure_mux(int port, if (IS_ENABLED(HAS_TASK_USB_MUX)) { assert(task_get_current() == TASK_ID_USB_MUX); } else { +#if defined(CONFIG_ZEPHYR) && defined(TEST_BUILD) + assert(port == + TASK_ID_TO_PD_PORT(task_get_current()) || + task_get_current() == + TASK_ID_TEST_RUNNER); +#else assert(port == TASK_ID_TO_PD_PORT(task_get_current())); +#endif /* defined(CONFIG_ZEPHYR) && defined(TEST_BUILD) */ } /* @@ -530,23 +537,29 @@ bool usb_mux_set_completed(int port) return !sets_pending; } -mux_state_t usb_mux_get(int port) +static enum ec_error_list try_usb_mux_get(int port, mux_state_t *mux_state) { - mux_state_t mux_state; - int rv; - - if (port >= board_get_usb_pd_port_count()) { - return USB_PD_MUX_NONE; - } + if (port >= board_get_usb_pd_port_count()) + return EC_ERROR_INVAL; /* Perform initialization if not initialized yet */ if (!(flags[port] & USB_MUX_FLAG_INIT)) usb_mux_init(port); - if (flags[port] & USB_MUX_FLAG_IN_LPM) - return USB_PD_MUX_NONE; + if (flags[port] & USB_MUX_FLAG_IN_LPM) { + *mux_state = USB_PD_MUX_NONE; + return EC_SUCCESS; + } - rv = configure_mux(port, USB_MUX_GET_MODE, &mux_state); + return configure_mux(port, USB_MUX_GET_MODE, mux_state); +} + +mux_state_t usb_mux_get(int port) +{ + mux_state_t mux_state; + enum ec_status rv; + + rv = try_usb_mux_get(port, &mux_state); return rv ? USB_PD_MUX_NONE : mux_state; } @@ -718,9 +731,8 @@ static enum ec_status hc_usb_pd_mux_info(struct host_cmd_handler_args *args) if (port >= board_get_usb_pd_port_count()) return EC_RES_INVALID_PARAM; - if (configure_mux(port, USB_MUX_GET_MODE, &mux_state)) + if (try_usb_mux_get(port, &mux_state)) return EC_RES_ERROR; - r->flags = mux_state; /* Clear HPD IRQ event since we're about to inform host of it. */ diff --git a/driver/usb_mux/virtual.c b/driver/usb_mux/virtual.c index 4388bb485a..23987fd676 100644 --- a/driver/usb_mux/virtual.c +++ b/driver/usb_mux/virtual.c @@ -55,16 +55,10 @@ static inline void virtual_mux_update_state(int port, mux_state_t mux_state, * TCSS Mux to allow better synchronization between them and thereby * remain in the same state for achieving proper safe state * terminations. + * + * Note the AP will only ACK if the mux state changed in some way. */ - - /* TODO(b/186777984): Wait for an ACK for all mux state change */ - - if ((!(previous_mux_state & USB_PD_MUX_SAFE_MODE) && - (mux_state & USB_PD_MUX_SAFE_MODE)) || - ((previous_mux_state & USB_PD_MUX_SAFE_MODE) && - !(mux_state & USB_PD_MUX_SAFE_MODE)) || - ((previous_mux_state != USB_PD_MUX_NONE) && - (mux_state == USB_PD_MUX_NONE))) + if (previous_mux_state != mux_state) *ack_required = true; } @@ -112,17 +106,16 @@ static int virtual_get_mux(const struct usb_mux *me, mux_state_t *mux_state) return EC_SUCCESS; } -void virtual_hpd_update(const struct usb_mux *me, mux_state_t mux_state) +void virtual_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { int port = me->usb_port; - bool unused; /* Current HPD related mux status + existing USB & DP mux status */ mux_state_t new_mux_state = mux_state | (virtual_mux_state[port] & USB_PD_MUX_USB_DP_STATE); - /* HPD ACK isn't required for the EC to continue with its tasks */ - virtual_mux_update_state(port, new_mux_state, &unused); + virtual_mux_update_state(port, new_mux_state, ack_required); } const struct usb_mux_driver virtual_usb_mux_driver = { diff --git a/include/atomic_t.h b/include/atomic_t.h new file mode 100644 index 0000000000..e35fc187bf --- /dev/null +++ b/include/atomic_t.h @@ -0,0 +1,22 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* This file is to provide atomic_t definition */ + +#ifndef __CROS_EC_ATOMIC_T_H +#define __CROS_EC_ATOMIC_T_H + +#ifndef CONFIG_ZEPHYR +#ifdef TEST_BUILD +typedef int atomic_t; +#else +typedef long atomic_t; +#endif +typedef atomic_t atomic_val_t; +#else +#include <sys/atomic.h> +#endif + +#endif /* __CROS_EC_ATOMIC_T_H */ diff --git a/include/battery_fuel_gauge.h b/include/battery_fuel_gauge.h index eb54b64c53..7589a68190 100644 --- a/include/battery_fuel_gauge.h +++ b/include/battery_fuel_gauge.h @@ -14,6 +14,9 @@ /* Number of writes needed to invoke battery cutoff command */ #define SHIP_MODE_WRITES 2 +/* When battery type is not initialized */ +#define BATTERY_TYPE_UNINITIALIZED -1 + struct ship_mode_info { /* * Write Block Support. If wb_support is true, then we use a i2c write @@ -78,6 +81,15 @@ int battery_bq4050_imbalance_mv(void); #endif +#ifdef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT +/* + * Set the battery type, when auto-detection cannot be used. + * + * @param type Battery type + */ +void battery_set_fixed_battery_type(int type); +#endif + /** * Return the board-specific default battery type. * diff --git a/include/chipset.h b/include/chipset.h index 333cef8ef4..8f242624a6 100644 --- a/include/chipset.h +++ b/include/chipset.h @@ -30,7 +30,7 @@ */ enum chipset_state_mask { CHIPSET_STATE_HARD_OFF = 0x01, /* Hard off (G3) */ - CHIPSET_STATE_SOFT_OFF = 0x02, /* Soft off (S5) */ + CHIPSET_STATE_SOFT_OFF = 0x02, /* Soft off (S5, S4) */ CHIPSET_STATE_SUSPEND = 0x04, /* Suspend (S3) */ CHIPSET_STATE_ON = 0x08, /* On (S0) */ CHIPSET_STATE_STANDBY = 0x10, /* Standby (S0ix) */ diff --git a/include/config.h b/include/config.h index 7fc59ac4a1..f2de323ca8 100644 --- a/include/config.h +++ b/include/config.h @@ -479,6 +479,11 @@ #undef CONFIG_BATTERY /* + * Config to indicate the battery type that cannot be auto detected. + */ +#undef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT + +/* * Compile battery-specific code. * * Note that some boards have their own unique battery constants / functions. @@ -1106,6 +1111,17 @@ */ #undef CONFIG_CHARGER_BQ25710_CMP_REF_1P2 +/* Enable if CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG should be applied */ +#undef CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM + +/* + * Input overload time when in peak power mode (PKPWR_TOVLD_DEG). This + * limits how long the charger can draw ILIM2 from the adapter. This is + * a 2 bit field. On the bq25710 1 ms to 20 ms can be encoded. On the + * bq25720 1 ms to 10 ms can be encoded. + */ +#undef CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG + /* * This config option is used to enable the charger's AC over-current * protection. The converter turns off when the OC threshold is @@ -1150,6 +1166,13 @@ */ #undef CONFIG_CHARGER_BQ25710_PP_ACOK +/* + * This config option sets the PP_IDCHG2 bit in the Charge Option 4 + * register. This causes PROCHOT to be pulsed when IDCHG_TH2 is reached. + */ + +#undef CONFIG_CHARGER_BQ25720_PP_IDCHG2 + /* Enable if CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_MV should be applied */ #undef CONFIG_CHARGER_BQ25710_VSYS_MIN_VOLTAGE_CUSTOM @@ -2395,7 +2418,7 @@ * Accept EC host commands over the SPI host interface. The AP is SPI * controller and the EC is the SPI peripheral for this configuration. */ -#undef CONFIG_HOSTCMD_SHI +#undef CONFIG_HOST_INTERFACE_SHI /* * Host command rate limiting assures EC will have time to process lower @@ -2776,6 +2799,12 @@ #undef CONFIG_IT83XX_HARD_RESET_BY_GPG1 /* + * Use i2c command queue mode for a single i2c transaction. + * (Applied to port D, E, and F) + */ +#undef CONFIG_IT83XX_I2C_CMD_QUEUE + +/* * Enable it if EC's VBAT won't go low when system's power isn't * presented (no battery and no AC) * If EC's VSTBY and VBAT(power source of BRAM) aren't connected to the same @@ -3060,6 +3089,7 @@ #undef CONFIG_LED_DRIVER_LM3509 /* LM3509, on I2C interface */ #undef CONFIG_LED_DRIVER_LM3630A /* LM3630A, on I2C interface */ #undef CONFIG_LED_DRIVER_LP5562 /* LP5562, on I2C interface */ +#undef CONFIG_LED_DRIVER_MP3385 /* MPS MP3385, on I2C */ #undef CONFIG_LED_DRIVER_OZ554 /* O2Micro OZ554, on I2C */ /* Offset in flash where little firmware will live. */ @@ -3141,26 +3171,27 @@ #undef CONFIG_HID_HECI /* Support host command interface over HECI */ -#undef CONFIG_HOSTCMD_HECI +#undef CONFIG_HOST_INTERFACE_HECI /* * EC supports x86 host communication with AP. This can either be through LPC * or eSPI. The CONFIG_HOSTCMD_X86 will get automatically defined if either - * CONFIG_HOSTCMD_LPC or CONFIG_HOSTCMD_ESPI are defined. LPC and eSPI are - * mutually exclusive. + * CONFIG_HOST_INTERFACE_LPC or CONFIG_HOST_INTERFACE_ESPI are defined. + * LPC and eSPI are mutually exclusive. */ #undef CONFIG_HOSTCMD_X86 /* Support host command interface over LPC bus. */ -#undef CONFIG_HOSTCMD_LPC +#undef CONFIG_HOST_INTERFACE_LPC /* Support host command interface over eSPI bus. */ -#undef CONFIG_HOSTCMD_ESPI +#undef CONFIG_HOST_INTERFACE_ESPI /* - * SLP signals (SLP_S3 and SLP_S4) use virtual wires intead of physical pins - * with eSPI interface. + * SLP signals (SLP_S3, SLP_S4, and SLP_S5) use virtual wires instead of + * physical pins with eSPI interface. */ #undef CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #undef CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +#undef CONFIG_HOSTCMD_ESPI_VW_SLP_S5 /* MCHP next two items are EC eSPI slave configuration */ /* Maximum clock frequence eSPI EC slave advertises @@ -3512,6 +3543,9 @@ /* Support S0ix */ #undef CONFIG_POWER_S0IX +/* Advertise S4 residency */ +#undef CONFIG_POWER_S4_RESIDENCY + /* Support detecting failure to enter a sleep state (S0ix/S3) */ #undef CONFIG_POWER_SLEEP_FAILURE_DETECTION @@ -4006,8 +4040,10 @@ #undef CONFIG_TEMP_SENSOR_G781 /* G781 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_G782 /* G782 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_OTI502 /* OTI502 sensor, on I2C bus */ +#undef CONFIG_TEMP_SENSOR_PCT2075 /* PCT2075 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_SB_TSI /* SB_TSI sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_TMP006 /* TI TMP006 sensor, on I2C bus */ +#undef CONFIG_TEMP_SENSOR_TMP112 /* TI TMP112 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_TMP411 /* TI TMP411 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_TMP432 /* TI TMP432 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_TMP468 /* TI TMP468 sensor, on I2C bus */ @@ -4033,10 +4069,11 @@ /* * If defined, active-high GPIO which indicates temperature sensor chips are - * powered. If not defined, temperature sensors are assumed to be always + * powered. The GPIO pin must be defined as GPIO_TEMP_SENSOR_POWER. + * If not defined, temperature sensors are assumed to be always * powered. */ -#undef CONFIG_TEMP_SENSOR_POWER_GPIO +#undef CONFIG_TEMP_SENSOR_POWER /* AMD STT (Skin Temperature Tracking) */ #undef CONFIG_AMD_STT @@ -4389,6 +4426,12 @@ #undef CONFIG_USB_PD_RUNTIME_FLAGS /* + * Define to enable the PD Data Reset Message. This is mandatory for + * USB4 and optional for USB 3.2 + */ +#undef CONFIG_USB_PD_DATA_RESET_MSG + +/* * Define if this board can enable VBUS discharge (eg. through a GPIO-controlled * discharge circuit, or through port controller registers) to discharge VBUS * rapidly on disconnect. Will be defined automatically when one of the below @@ -4857,6 +4900,7 @@ /* USB Type-C Power Path Controllers (PPC) */ #undef CONFIG_USBC_PPC_AOZ1380 +#undef CONFIG_USBC_PPC_KTU1125 #undef CONFIG_USBC_PPC_NX20P3481 #undef CONFIG_USBC_PPC_NX20P3483 #undef CONFIG_USBC_PPC_RT1718S @@ -5507,16 +5551,29 @@ * are configured as virtual wires. */ #if defined(CONFIG_HOSTCMD_ESPI_VW_SLP_S3) || \ - defined(CONFIG_HOSTCMD_ESPI_VW_SLP_S4) + defined(CONFIG_HOSTCMD_ESPI_VW_SLP_S4) || \ + defined(CONFIG_HOSTCMD_ESPI_VW_SLP_S5) #define CONFIG_HOST_ESPI_VW_POWER_SIGNAL #endif /* + * S4 residency works by observing SLP_S5 via virtual wire (as SLP_S5 has not + * traditionally been routed to the EC). If the board family wants S4 residency, + * they need to use ECs that support eSPI. Note that S4 residency is not + * strictly a requirement to support suspend-to-disk, except on Intel platforms + * with Key Locker support (TGL+). + */ +#if defined(CONFIG_POWER_S4_RESIDENCY) && \ + !defined(CONFIG_HOSTCMD_ESPI_VW_SLP_S5) +#error "S4_RESIDENCY needs eSPI support or SLP_S5 routed" +#endif + +/* * Note that in Zephyr OS, eSPI can be enabled for virtual wires * without using eSPI for host commands. */ #if (!defined(CONFIG_ZEPHYR) && defined(CONFIG_HOST_ESPI_VW_POWER_SIGNAL) && \ - !defined(CONFIG_HOSTCMD_ESPI)) + !defined(CONFIG_HOST_INTERFACE_ESPI)) #error Must enable eSPI to enable virtual wires. #endif @@ -5641,17 +5698,17 @@ * Automatically define CONFIG_HOSTCMD_X86 if either child option is defined. * Ensure LPC and eSPI are mutually exclusive */ -#if defined(CONFIG_HOSTCMD_LPC) || defined(CONFIG_HOSTCMD_ESPI) +#if defined(CONFIG_HOST_INTERFACE_LPC) || defined(CONFIG_HOST_INTERFACE_ESPI) #define CONFIG_HOSTCMD_X86 #endif -#if defined(CONFIG_HOSTCMD_LPC) && defined(CONFIG_HOSTCMD_ESPI) +#if defined(CONFIG_HOST_INTERFACE_LPC) && defined(CONFIG_HOST_INTERFACE_ESPI) #error Must select only one type of host communication bus. #endif #if defined(CONFIG_HOSTCMD_X86) && \ - !defined(CONFIG_HOSTCMD_LPC) && \ - !defined(CONFIG_HOSTCMD_ESPI) + !defined(CONFIG_HOST_INTERFACE_LPC) && \ + !defined(CONFIG_HOST_INTERFACE_ESPI) #error Must select one type of host communication bus. #endif @@ -5870,6 +5927,7 @@ /*****************************************************************************/ /* Define CONFIG_USBC_OCP if a component can detect overcurrent */ #if defined(CONFIG_USBC_PPC_AOZ1380) || \ + defined(CONFIG_USBC_PPC_KTU1125) || \ defined(CONFIG_USBC_PPC_NX20P3481) || \ defined(CONFIG_USBC_PPC_NX20P3483) || \ defined(CONFIG_USBC_PPC_SN5S330) || \ @@ -5911,6 +5969,10 @@ /* * Define CONFIG_USB_PD_TCPC_ON_CHIP if we use ITE series TCPM driver * on the board. + * + * NOTE: If we don't use all the ITE pd ports on a board, then we need to + * start from port0 to use the ITE pd port. If we start from port1, + * then port1 HOOK function never works. */ #ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP #define CONFIG_USB_PD_TCPC_ON_CHIP diff --git a/include/driver/accelgyro_lsm6dso_public.h b/include/driver/accelgyro_lsm6dso_public.h new file mode 100644 index 0000000000..65e98bccec --- /dev/null +++ b/include/driver/accelgyro_lsm6dso_public.h @@ -0,0 +1,25 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* LSM6DSO Accel and Gyro driver for Chrome EC */ + +#ifndef __CROS_EC_ACCELGYRO_LSM6DSO_PUBLIC_H +#define __CROS_EC_ACCELGYRO_LSM6DSO_PUBLIC_H + +#include "driver/accelgyro_lsm6dso_public.h" + +/* + * 7-bit address is 110101xb. Where 'x' is determined + * by the voltage on the ADDR pin + */ +#define LSM6DSO_ADDR0_FLAGS 0x6a +#define LSM6DSO_ADDR1_FLAGS 0x6b + +/* Absolute maximum rate for Acc and Gyro sensors */ +#define LSM6DSO_ODR_MIN_VAL 13000 +#define LSM6DSO_ODR_MAX_VAL \ + MOTION_MAX_SENSOR_FREQUENCY(416000, 13000) + +#endif /* __CROS_EC_ACCELGYRO_LSM6DSO_PUBLIC_H */ diff --git a/include/driver/ppc/ktu1125_public.h b/include/driver/ppc/ktu1125_public.h new file mode 100644 index 0000000000..276f8c9a99 --- /dev/null +++ b/include/driver/ppc/ktu1125_public.h @@ -0,0 +1,25 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Kinetic KTU1125 USB-C Power Path Controller */ + +#ifndef __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H +#define __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H + +#define KTU1125_ADDR0_FLAGS 0x78 +#define KTU1125_ADDR1_FLAGS 0x79 +#define KTU1125_ADDR2_FLAGS 0x7A +#define KTU1125_ADDR3_FLAGS 0x7B + +extern const struct ppc_drv ktu1125_drv; + +/** + * Interrupt Handler for the KTU1125. + * + * @param port: The Type-C port which triggered the interrupt. + */ +void ktu1125_interrupt(int port); + +#endif /* __CROS_EC_DRIVER_PPC_KTU1125_PUBLIC_H */ diff --git a/include/driver/ppc/syv682x_public.h b/include/driver/ppc/syv682x_public.h index f366da59b3..92c841f811 100644 --- a/include/driver/ppc/syv682x_public.h +++ b/include/driver/ppc/syv682x_public.h @@ -12,7 +12,7 @@ #define SYV682X_ADDR0_FLAGS 0x40 #define SYV682X_ADDR1_FLAGS 0x41 #define SYV682X_ADDR2_FLAGS 0x42 -#define SYV682x_ADDR3_FLAGS 0x43 +#define SYV682X_ADDR3_FLAGS 0x43 extern const struct ppc_drv syv682x_drv; diff --git a/include/driver/retimer/bb_retimer_public.h b/include/driver/retimer/bb_retimer_public.h index f1a924f67e..d79b051504 100644 --- a/include/driver/retimer/bb_retimer_public.h +++ b/include/driver/retimer/bb_retimer_public.h @@ -48,9 +48,12 @@ __override_proto int bb_retimer_power_enable(const struct usb_mux *me, * * Set the HPD related fields in the BB retimer * - * @param me Pointer to USB mux - * @param mux_state USB mux state containing HPD level and IRQ + * @param[in] me Pointer to USB mux + * @param[in] mux_state USB mux state containing HPD level and IRQ + * @param[out] ack_required Outputs whether the given change will require + * the AP to ACK before proceeding */ -void bb_retimer_hpd_update(const struct usb_mux *me, mux_state_t mux_state); +void bb_retimer_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required); #endif /* __CROS_EC_DRIVER_RETIMER_BB_RETIMER_PUBLIC_H */ diff --git a/include/driver/tcpm/ps8xxx_public.h b/include/driver/tcpm/ps8xxx_public.h index 0e200cb395..b186eacec7 100644 --- a/include/driver/tcpm/ps8xxx_public.h +++ b/include/driver/tcpm/ps8xxx_public.h @@ -79,7 +79,8 @@ __override_proto uint16_t board_get_ps8xxx_product_id(int port); void ps8xxx_tcpc_update_hpd_status(const struct usb_mux *me, - mux_state_t mux_state); + mux_state_t mux_state, + bool *ack_required); #ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC extern struct i2c_stress_test_dev ps8xxx_i2c_stress_test_dev; diff --git a/driver/temp_sensor/tmp112.h b/include/driver/temp_sensor/tmp112.h index d1b97b138c..d1b97b138c 100644 --- a/driver/temp_sensor/tmp112.h +++ b/include/driver/temp_sensor/tmp112.h diff --git a/include/driver/usb_mux/ps8743_public.h b/include/driver/usb_mux/ps8743_public.h index b0a7ae2eda..c20b948d07 100644 --- a/include/driver/usb_mux/ps8743_public.h +++ b/include/driver/usb_mux/ps8743_public.h @@ -95,9 +95,19 @@ #define PS8743_USB_HS_THRESH_NEG_45 0xc0 #define PS8743_USB_HS_THRESH_NEG_35 0xe0 +/* DCI config: 0x45~0x4D */ +#define PS8743_REG_DCI_CONFIG_2 0x47 +#define PS8743_AUTO_DCI_MODE_SHIFT 6 +#define PS8743_AUTO_DCI_MODE_MASK (3 << PS8743_AUTO_DCI_MODE_SHIFT) +#define PS8743_AUTO_DCI_MODE_ENABLE (0 << PS8743_AUTO_DCI_MODE_SHIFT) +#define PS8743_AUTO_DCI_MODE_FORCE_USB (2 << PS8743_AUTO_DCI_MODE_SHIFT) +#define PS8743_AUTO_DCI_MODE_FORCE_DCI (3 << PS8743_AUTO_DCI_MODE_SHIFT) + int ps8743_tune_usb_eq(const struct usb_mux *me, uint8_t tx, uint8_t rx); int ps8743_write(const struct usb_mux *me, uint8_t reg, uint8_t val); int ps8743_read(const struct usb_mux *me, uint8_t reg, int *val); +int ps8743_field_update(const struct usb_mux *me, uint8_t reg, uint8_t mask, + uint8_t val); int ps8743_check_chip_id(const struct usb_mux *me, int *val); #endif /* __CROS_EC_DRIVER_USB_MUX_PS8743_PUBLIC_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index b089cd08d4..652b491cd2 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -180,7 +180,7 @@ extern "C" { #define EC_MEMMAP_ACC_STATUS_PRESENCE_BIT BIT(7) /* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */ -#define EC_TEMP_SENSOR_ENTRIES 16 +#define EC_TEMP_SENSOR_ENTRIES 16 /* * Number of temp sensors at EC_MEMMAP_TEMP_SENSOR_B. * @@ -188,6 +188,10 @@ extern "C" { */ #define EC_TEMP_SENSOR_B_ENTRIES 8 +/* Max temp sensor entries for host commands */ +#define EC_MAX_TEMP_SENSOR_ENTRIES (EC_TEMP_SENSOR_ENTRIES + \ + EC_TEMP_SENSOR_B_ENTRIES) + /* Special values for mapped temperature sensors */ #define EC_TEMP_SENSOR_NOT_PRESENT 0xff #define EC_TEMP_SENSOR_ERROR 0xfe @@ -1502,6 +1506,10 @@ enum ec_feature_code { * mux. */ EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43, + /* + * The EC supports entering and residing in S4. + */ + EC_FEATURE_S4_RESIDENCY = 44, }; #define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32) diff --git a/include/fpsensor_state.h b/include/fpsensor_state.h index 6b752bc86d..98d5b63783 100644 --- a/include/fpsensor_state.h +++ b/include/fpsensor_state.h @@ -10,6 +10,8 @@ #include <stdbool.h> #include <stdint.h> + +#include "atomic.h" #include "common.h" #include "ec_commands.h" #include "link_defs.h" @@ -64,7 +66,7 @@ extern uint32_t user_id[FP_CONTEXT_USERID_WORDS]; /* Part of the IKM used to derive encryption keys received from the TPM. */ extern uint8_t tpm_seed[FP_CONTEXT_TPM_BYTES]; -extern uint32_t fp_events; +extern atomic_t fp_events; extern uint32_t sensor_mode; diff --git a/include/host_command.h b/include/host_command.h index 8a66776ce9..74f68f9891 100644 --- a/include/host_command.h +++ b/include/host_command.h @@ -358,13 +358,29 @@ stub_send_response_callback(struct host_cmd_handler_args *args) ARG_UNUSED(args); } -#define BUILD_HOST_COMMAND(CMD, VERSION, RESPONSE) \ - { \ - .command = (CMD), .version = (VERSION), \ - .send_response = stub_send_response_callback, \ - .response = &(RESPONSE), .response_max = sizeof(RESPONSE), \ - .response_size = sizeof(RESPONSE) \ +#define BUILD_HOST_COMMAND(CMD, VERSION, RESPONSE, PARAMS) \ + { \ + .command = (CMD), .version = (VERSION), \ + .send_response = stub_send_response_callback, \ + .response_size = 0, \ + COND_CODE_0(IS_EMPTY(RESPONSE), \ + (.response = &(RESPONSE), \ + .response_max = sizeof(RESPONSE)), \ + (.response = NULL, .response_max = 0)), \ + COND_CODE_0(IS_EMPTY(PARAMS), \ + (.params = &(PARAMS), \ + .params_size = sizeof(PARAMS)), \ + (.params = NULL, .params_size = 0)) \ } + +#define BUILD_HOST_COMMAND_RESPONSE(CMD, VERSION, RESPONSE) \ + BUILD_HOST_COMMAND(CMD, VERSION, RESPONSE, EMPTY) + +#define BUILD_HOST_COMMAND_PARAMS(CMD, VERSION, PARAMS) \ + BUILD_HOST_COMMAND(CMD, VERSION, EMPTY, PARAMS) + +#define BUILD_HOST_COMMAND_SIMPLE(CMD, VERSION) \ + BUILD_HOST_COMMAND(CMD, VERSION, EMPTY, EMPTY) #endif /* CONFIG_ZTEST */ #endif /* __CROS_EC_HOST_COMMAND_H */ diff --git a/include/i2c.h b/include/i2c.h index 57996289dd..7b66d67589 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -106,9 +106,9 @@ struct i2c_drv { /* Data structure to define I2C port configuration. */ struct i2c_port_t { - const char *name; /* Port name */ int port; /* Port */ #ifndef CONFIG_ZEPHYR + const char *name; /* Port name */ int kbps; /* Speed in kbps */ enum gpio_signal scl; /* Port SCL GPIO line */ enum gpio_signal sda; /* Port SDA GPIO line */ diff --git a/include/led_common.h b/include/led_common.h index a66455b008..1e4629a606 100644 --- a/include/led_common.h +++ b/include/led_common.h @@ -75,6 +75,12 @@ enum ec_led_state { }; /** + * Check the LED state while receive the auto control + * command. + */ +void board_led_auto_control(void); + +/** * Control state of LED. * * @param led_id ID of LED to control diff --git a/include/motion_sense.h b/include/motion_sense.h index e507a3c799..e642851845 100644 --- a/include/motion_sense.h +++ b/include/motion_sense.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_MOTION_SENSE_H #define __CROS_EC_MOTION_SENSE_H +#include "atomic.h" #include "chipset.h" #include "common.h" #include "ec_commands.h" @@ -127,8 +128,6 @@ struct motion_data_t { * the components. */ #define MOTIONSENSE_FLAG_IN_SPOOF_MODE BIT(1) -#define MOTIONSENSE_FLAG_INT_SIGNAL BIT(2) -#define MOTIONSENSE_FLAG_INT_ACTIVE_HIGH BIT(3) struct online_calib_data { /** @@ -163,8 +162,6 @@ struct motion_sensor_t { /* One mutex per physical chip. */ mutex_t *mutex; void *drv_data; - /* Only valid if flags & MOTIONSENSE_FLAG_INT_SIGNAL is true. */ - enum gpio_signal int_signal; /* Data used for online calibraiton, must match the sensor type. */ struct online_calib_data online_calib_data[__cfg_select(CONFIG_ONLINE_CALIB, 1, 0)]; @@ -215,7 +212,7 @@ struct motion_sensor_t { intv3_t spoof_xyz; /* How many flush events are pending */ - uint32_t flush_pending; + atomic_t flush_pending; /* * Allow EC to request an higher frequency for the sensors than the AP. diff --git a/include/peripheral_charger.h b/include/peripheral_charger.h index b1f82bb1f3..58fbf1482b 100644 --- a/include/peripheral_charger.h +++ b/include/peripheral_charger.h @@ -6,6 +6,7 @@ #ifndef __CROS_EC_PERIPHERAL_CHARGER_H #define __CROS_EC_PERIPHERAL_CHARGER_H +#include "atomic.h" #include "common.h" #include "ec_commands.h" #include "gpio.h" @@ -196,7 +197,7 @@ struct pchg { /* Event queue mutex */ struct mutex mtx; /* 1:Pending IRQ 0:No pending IRQ */ - uint32_t irq; + atomic_t irq; /* Event currently being handled */ enum pchg_event event; /* Error (enum pchg_error). Port is disabled until it's cleared. */ diff --git a/include/power.h b/include/power.h index 769a60fd53..e12f97cdb2 100644 --- a/include/power.h +++ b/include/power.h @@ -20,6 +20,7 @@ FORWARD_DECLARE_ENUM(power_state) { * which means totally unpowered...) */ POWER_S5, /* System is soft-off */ + POWER_S4, /* System is suspended to disk */ POWER_S3, /* Suspend; RAM on, processor is asleep */ POWER_S0, /* System is on */ #ifdef CONFIG_POWER_S0IX @@ -27,11 +28,15 @@ FORWARD_DECLARE_ENUM(power_state) { #endif /* Transitions */ POWER_G3S5, /* G3 -> S5 (at system init time) */ - POWER_S5S3, /* S5 -> S3 */ + POWER_S5S3, /* S5 -> S3 (skips S4 on non-Intel systems) */ POWER_S3S0, /* S3 -> S0 */ POWER_S0S3, /* S0 -> S3 */ - POWER_S3S5, /* S3 -> S5 */ + POWER_S3S5, /* S3 -> S5 (skips S4 on non-Intel systems) */ POWER_S5G3, /* S5 -> G3 */ + POWER_S3S4, /* S3 -> S4 */ + POWER_S4S3, /* S4 -> S3 */ + POWER_S4S5, /* S4 -> S5 */ + POWER_S5S4, /* S5 -> S4 */ #ifdef CONFIG_POWER_S0IX POWER_S0ixS0, /* S0ix -> S0 */ POWER_S0S0ix, /* S0 -> S0ix */ diff --git a/include/power/alderlake_slg4bd44540.h b/include/power/alderlake_slg4bd44540.h index 62c617bd98..387a583240 100644 --- a/include/power/alderlake_slg4bd44540.h +++ b/include/power/alderlake_slg4bd44540.h @@ -34,6 +34,7 @@ enum power_signal { X86_SLP_S0_DEASSERTED, X86_SLP_S3_DEASSERTED, X86_SLP_S4_DEASSERTED, + X86_SLP_S5_DEASSERTED, X86_SLP_SUS_DEASSERTED, X86_RSMRST_L_PGOOD, X86_DSW_DPWROK, diff --git a/include/power/icelake.h b/include/power/icelake.h index 08c14718ec..95460ae80d 100644 --- a/include/power/icelake.h +++ b/include/power/icelake.h @@ -33,6 +33,7 @@ enum power_signal { X86_SLP_S0_DEASSERTED, X86_SLP_S3_DEASSERTED, X86_SLP_S4_DEASSERTED, + X86_SLP_S5_DEASSERTED, X86_SLP_SUS_DEASSERTED, X86_RSMRST_L_PGOOD, X86_DSW_DPWROK, diff --git a/include/power/intel_x86.h b/include/power/intel_x86.h index 303db20de7..bc4e7ec8fb 100644 --- a/include/power/intel_x86.h +++ b/include/power/intel_x86.h @@ -41,6 +41,17 @@ #else #define SLP_S4_SIGNAL_L GPIO_PCH_SLP_S4_L #endif +/* + * The SLP_S5 signal has not traditionally been connected to the EC. If virtual + * wire support is enabled, then SLP_S5 will be available that way. Otherwise, + * use SLP_S4's GPIO as a proxy for SLP_S5. This matches old behavior and + * effectively prevents S4 residency. + */ +#ifdef CONFIG_HOSTCMD_ESPI_VW_SLP_S5 +#define SLP_S5_SIGNAL_L VW_SLP_S5_L +#else +#define SLP_S5_SIGNAL_L SLP_S4_SIGNAL_L +#endif /** * Handle RSMRST signal. diff --git a/include/power/mt8186.h b/include/power/mt8186.h new file mode 100644 index 0000000000..a2ad5648ed --- /dev/null +++ b/include/power/mt8186.h @@ -0,0 +1,17 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_POWER_MT8186_H_ +#define __CROS_EC_POWER_MT8186_H_ + +enum power_signal { + AP_IN_RST, + AP_IN_S3, + AP_WDT_ASSERTED, + AP_WARM_RST_REQ, + POWER_SIGNAL_COUNT, +}; + +#endif /* __CROS_EC_POWER_MT8186_H_ */ diff --git a/include/system.h b/include/system.h index 57592217ad..0fc0206bb3 100644 --- a/include/system.h +++ b/include/system.h @@ -570,7 +570,7 @@ enum { * Current sleep mask. You may read from this variable, but must NOT * modify it; use enable_sleep() or disable_sleep() to do that. */ -extern uint32_t sleep_mask; +extern atomic_t sleep_mask; /* * Macros to use to get whether deep sleep is allowed or whether @@ -613,7 +613,7 @@ static inline void disable_sleep(uint32_t mask) * Do NOT access it directly. Use idle_is_disabled() to read it and * enable_idle()/disable_idle() to write it. */ -extern uint32_t idle_disabled; +extern atomic_t idle_disabled; static inline uint32_t idle_is_disabled(void) { diff --git a/include/task.h b/include/task.h index fdfae9d5c6..2bcce8dc29 100644 --- a/include/task.h +++ b/include/task.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_TASK_H #define __CROS_EC_TASK_H +#include "atomic_t.h" #include "common.h" #include "compile_time_macros.h" #include <stdbool.h> @@ -187,7 +188,7 @@ static inline bool in_deferred_context(void) /** * Return a pointer to the bitmap of events of the task. */ -uint32_t *task_get_event_bitmap(task_id_t tskid); +atomic_t *task_get_event_bitmap(task_id_t tskid); /** * Wait for the next event. @@ -384,7 +385,7 @@ typedef struct k_mutex mutex_t; #else struct mutex { uint32_t lock; - uint32_t waiters; + atomic_t waiters; }; typedef struct mutex mutex_t; diff --git a/include/usb_mux.h b/include/usb_mux.h index 41e5881a81..e251d74f4c 100644 --- a/include/usb_mux.h +++ b/include/usb_mux.h @@ -139,12 +139,15 @@ struct usb_mux { * USB Type-C DP alt mode support. Notify Type-C controller * there is DP dongle hot-plug. * - * @param me usb_mux - * @param mux_state with HPD IRQ and HPD LVL flags set - * accordingly + * @param[in] me usb_mux + * @param[in] mux_state with HPD IRQ and HPD LVL flags set + * accordingly + * @param[out] ack_required: indication of whether this function + * requires a wait for an AP ACK after */ void (*hpd_update)(const struct usb_mux *me, - mux_state_t mux_state); + mux_state_t mux_state, + bool *ack_required); }; /* Supported USB mux drivers */ @@ -168,7 +171,8 @@ extern const struct usb_mux usb_muxes[]; #endif /* Supported hpd_update functions */ -void virtual_hpd_update(const struct usb_mux *me, mux_state_t mux_state); +void virtual_hpd_update(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required); /* * Helper methods that either use tcpc communication or direct i2c diff --git a/include/usb_pd.h b/include/usb_pd.h index ba6f3d99ff..5ff47eba94 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -95,6 +95,8 @@ enum pd_rx_errors { * Note: Some bits and decode macros are defined in ec_commands.h */ #define PDO_FIXED_SUSPEND BIT(28) /* USB Suspend supported */ +/* Higher capability in vSafe5V sink PDO */ +#define PDO_FIXED_SNK_HIGHER_CAP BIT(28) #define PDO_FIXED_FRS_CURR_NOT_SUPPORTED (0 << 23) #define PDO_FIXED_FRS_CURR_DFLT_USB_POWER (1 << 23) #define PDO_FIXED_FRS_CURR_1A5_AT_5V (2 << 23) @@ -243,6 +245,10 @@ enum pd_rx_errors { #define PD_T_DISCOVER_IDENTITY (45*MSEC) /* between 40ms and 50ms */ #define PD_T_SYSJUMP (1000*MSEC) /* 1s */ #define PD_T_PR_SWAP_WAIT (100*MSEC) /* tPRSwapWait 100ms */ +#define PD_T_DATA_RESET (225*MSEC) /* between 200ms and 250ms */ +#define PD_T_DATA_RESET_FAIL (300*MSEC) /* 300ms */ +#define PD_T_VCONN_REAPPLIED (15*MSEC) /* between 10ms and 20ms */ +#define PD_T_VCONN_DISCHARGE (240*MSEC) /* between 160ms and 240ms */ /* * Non-spec timer to prevent going Unattached if Vbus drops before a partner FRS @@ -1008,6 +1014,7 @@ enum pd_dpm_request { DPM_REQUEST_SOP_PRIME_SOFT_RESET_SEND = BIT(20), DPM_REQUEST_FRS_DET_ENABLE = BIT(21), DPM_REQUEST_FRS_DET_DISABLE = BIT(22), + DPM_REQUEST_DATA_RESET = BIT(23), }; /** @@ -1134,9 +1141,9 @@ enum pd_ctrl_msg_type { PD_CTRL_VCONN_SWAP = 11, PD_CTRL_WAIT = 12, PD_CTRL_SOFT_RESET = 13, - /* 14-15 Reserved */ - /* Used for REV 3.0 */ + PD_CTRL_DATA_RESET = 14, + PD_CTRL_DATA_RESET_COMPLETE = 15, PD_CTRL_NOT_SUPPORTED = 16, PD_CTRL_GET_SOURCE_CAP_EXT = 17, PD_CTRL_GET_STATUS = 18, diff --git a/include/usb_pd_dpm.h b/include/usb_pd_dpm.h index 18b73fca84..c7ae53340d 100644 --- a/include/usb_pd_dpm.h +++ b/include/usb_pd_dpm.h @@ -22,12 +22,26 @@ void dpm_init(int port); /* + * Informs the DPM that a mode exit is complete. + * + * @param port USB-C port number + */ +void dpm_mode_exit_complete(int port); + +/* * Informs the DPM that Exit Mode request is received * * @param port USB-C port number */ void dpm_set_mode_exit_request(int port); +/* Informs the DPM that the PE has performed a Data Reset (or at least + * determined that the port partner doesn't support one). + * + * @param port USB-C port number + */ +void dpm_data_reset_complete(int port); + /* * Informs the DPM that a VDM ACK was received. * diff --git a/include/usb_pd_timer.h b/include/usb_pd_timer.h index 5746e76430..1ed268f14d 100644 --- a/include/usb_pd_timer.h +++ b/include/usb_pd_timer.h @@ -10,6 +10,8 @@ #include <stdbool.h> +#include "atomic.h" + /* * List of all timers that will be managed by usb_pd_timer */ @@ -36,6 +38,15 @@ enum pd_task_timer { PE_TIMER_CHUNKING_NOT_SUPPORTED, /* + * PD 3.0, rev. 3.1, v. 1.2, section 6.6.10.3: The DataResetFailTimer + * Shall be used by the DFP’s Policy Engine to ensure the Data Reset + * process completes within tDataResetFail of the last bit of the + * GoodCRC acknowledging the Accept Message in response to the + * Data_Reset Message. + */ + PE_TIMER_DATA_RESET_FAIL, + + /* * This timer is used during an Explicit Contract when discovering * whether a Port Partner is PD Capable using SOP'. */ @@ -122,11 +133,25 @@ enum pd_task_timer { PE_TIMER_TIMEOUT, /* + * The amount of timer that the DFP shall wait for the UFP to discharge + * VCONN (and send PS_RDY) during Data Reset. See PD 3.0, rev. 3.1, v. + * 1.2, section 6.6.10.1 VCONNDischargeTimer. + */ + PE_TIMER_VCONN_DISCHARGE, + + /* * This timer is used during a VCONN Swap. */ PE_TIMER_VCONN_ON, /* + * The amount of time that VCONN shall remain off during the cable reset + * portion of a Data Reset. See PD 3.0, rev. 3.1, v. 1.2, section 7.1.15 + * VCONN Power Cycle. + */ + PE_TIMER_VCONN_REAPPLIED, + + /* * This timer is used by the Initiator’s Policy Engine to ensure that * a Structured VDM Command request needing a response (e.g. Discover * Identity Command request) is responded to within a bounded time of @@ -320,28 +345,28 @@ extern uint32_t timer_disabled[MAX_PD_PORTS][TIMER_FIELD_NUM_UINT32S]; /* exported: do not call directly, only for the defined macros */ extern void pd_timer_atomic_op( atomic_val_t (*op)(atomic_t*, atomic_val_t), - uint32_t *const timer_field, const uint64_t mask); + atomic_t *const timer_field, const uint64_t mask); /* exported: set/clear/check the current timer_active for a timer */ -#define PD_SET_ACTIVE(p, m) pd_timer_atomic_op( \ - atomic_or, \ - timer_active[p], \ +#define PD_SET_ACTIVE(p, m) pd_timer_atomic_op( \ + atomic_or, \ + (atomic_t *)timer_active[p], \ (m)) -#define PD_CLR_ACTIVE(p, m) pd_timer_atomic_op( \ - atomic_clear_bits, \ - timer_active[p], \ +#define PD_CLR_ACTIVE(p, m) pd_timer_atomic_op( \ + atomic_clear_bits, \ + (atomic_t *)timer_active[p], \ (m)) #define PD_CHK_ACTIVE(p, m) ((timer_active[p][0] & ((m) >> 32)) | \ (timer_active[p][1] & (m))) /* exported: set/clear/check the current timer_disabled for a timer */ -#define PD_SET_DISABLED(p, m) pd_timer_atomic_op( \ - atomic_or, \ - timer_disabled[p], \ +#define PD_SET_DISABLED(p, m) pd_timer_atomic_op( \ + atomic_or, \ + (atomic_t *)timer_disabled[p], \ (m)) -#define PD_CLR_DISABLED(p, m) pd_timer_atomic_op( \ - atomic_clear_bits, \ - timer_disabled[p], \ +#define PD_CLR_DISABLED(p, m) pd_timer_atomic_op( \ + atomic_clear_bits, \ + (atomic_t *)timer_disabled[p], \ (m)) #define PD_CHK_DISABLED(p, m) ((timer_disabled[p][0] & ((m) >> 32)) | \ (timer_disabled[p][1] & (m))) diff --git a/include/usb_tc_sm.h b/include/usb_tc_sm.h index 80a69279a2..4aaacd522b 100644 --- a/include/usb_tc_sm.h +++ b/include/usb_tc_sm.h @@ -181,6 +181,15 @@ void tc_request_power_swap(int port); void tc_pr_swap_complete(int port, bool success); /** + * The Type-C state machine updates the SLEEP_MASK_USB_PD mask for the + * case that TCPC wants to set/clear SLEEP_MASK_USB_PD mask only by + * itself, ex. TCPC embedded in EC. + * + * @param port USB_C port number + */ +__override_proto void tc_update_pd_sleep_mask(int port); + +/** * Instructs the Attached.SNK to stop drawing power. This function is called * from the Policy Engine and only has effect if the current Type-C state * Attached.SNK. @@ -6,6 +6,6 @@ * [Home][home] * [Documentation](/docs/sitemap.md) * [Getting Started Quickly](/docs/getting_started_quickly.md) -* [File a Bug](https://bugs.chromium.org/p/chromium/issues/entry?components=OS%3EFirmware%3EEC) +* [File a Bug](https://issuetracker.google.com/issues/new?component=960650) * [Report Security Issue](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/reporting_bugs.md#security) * [Chromium OS Docs](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/README.md) diff --git a/power/alderlake_slg4bd44540.c b/power/alderlake_slg4bd44540.c index 7c6e16b9c1..88bbefa654 100644 --- a/power/alderlake_slg4bd44540.c +++ b/power/alderlake_slg4bd44540.c @@ -67,6 +67,11 @@ const struct power_signal_info power_signal_list[] = { .flags = POWER_SIGNAL_ACTIVE_HIGH, .name = "SLP_S4_DEASSERTED", }, + [X86_SLP_S5_DEASSERTED] = { + .gpio = SLP_S5_SIGNAL_L, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "SLP_S5_DEASSERTED", + }, [X86_SLP_SUS_DEASSERTED] = { .gpio = GPIO_SLP_SUS_L, .flags = POWER_SIGNAL_ACTIVE_HIGH, diff --git a/power/build.mk b/power/build.mk index 3e47167f0a..b04526c45f 100644 --- a/power/build.mk +++ b/power/build.mk @@ -17,6 +17,7 @@ power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o power-$(CONFIG_CHIPSET_ICELAKE)+=icelake.o intel_x86.o power-$(CONFIG_CHIPSET_MT817X)+=mt817x.o power-$(CONFIG_CHIPSET_MT8183)+=mt8183.o +power-$(CONFIG_CHIPSET_MT8186)+=mt8186.o power-$(CONFIG_CHIPSET_MT8192)+=mt8192.o power-$(CONFIG_CHIPSET_CEZANNE)+=amd_x86.o power-$(CONFIG_CHIPSET_RK3288)+=rk3288.o diff --git a/power/common.c b/power/common.c index f3dbdb55f1..0285ca75a7 100644 --- a/power/common.c +++ b/power/common.c @@ -46,6 +46,7 @@ static const int s5_inactivity_timeout = 10; static const char * const state_names[] = { "G3", "S5", + "S4", "S3", "S0", #ifdef CONFIG_POWER_S0IX @@ -57,6 +58,10 @@ static const char * const state_names[] = { "S0->S3", "S3->S5", "S5->G3", + "S3->S4", + "S4->S3", + "S4->S5", + "S5->S4", #ifdef CONFIG_POWER_S0IX "S0ix->S0", "S0->S0ix", @@ -151,7 +156,7 @@ int power_signal_is_asserted(const struct power_signal_info *s) #ifdef CONFIG_BRINGUP static const char *power_signal_get_name(enum gpio_signal signal) { - if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) { + if (IS_ENABLED(CONFIG_HOST_INTERFACE_ESPI)) { /* Check signal is from GPIOs or VWs */ if (espi_signal_is_vw(signal)) return espi_vw_get_wire_name( @@ -246,11 +251,11 @@ void power_set_state(enum power_state new_state) /* * Reset want_g3_exit flag here to prevent the situation that if the - * error handler in POWER_S5S3 decides to force shutdown the system and + * error handler in POWER_S5S4 decides to force shutdown the system and * the flag is set, the system will go to G3 and then immediately exit * G3 again. */ - if (state == POWER_S5S3) + if ((state == POWER_S5S4) || (state == POWER_S5S3)) want_g3_exit = 0; } @@ -525,24 +530,20 @@ static enum power_state power_common_state(enum power_state state) } break; + case POWER_S4: + /* fallthrough */ case POWER_S3: - /* Wait for a message */ - power_wait_signals(0); - task_wait_event(-1); - break; - + /* fallthrough */ case POWER_S0: - /* Wait for a message */ - power_wait_signals(0); - task_wait_event(-1); - break; #ifdef CONFIG_POWER_S0IX + /* fallthrough */ case POWER_S0ix: +#endif /* Wait for a message */ power_wait_signals(0); task_wait_event(-1); break; -#endif + default: /* No common functionality for transition states */ break; @@ -576,10 +577,15 @@ int chipset_in_state(int state_mask) need_mask = CHIPSET_STATE_HARD_OFF | CHIPSET_STATE_SOFT_OFF; break; case POWER_S5: + case POWER_S5S4: + case POWER_S4S5: + case POWER_S4: need_mask = CHIPSET_STATE_SOFT_OFF; break; case POWER_S5S3: case POWER_S3S5: + case POWER_S4S3: + case POWER_S3S4: need_mask = CHIPSET_STATE_SOFT_OFF | CHIPSET_STATE_SUSPEND; break; case POWER_S3: @@ -614,11 +620,16 @@ int chipset_in_or_transitioning_to_state(int state_mask) case POWER_S5G3: return state_mask & CHIPSET_STATE_HARD_OFF; case POWER_S5: - case POWER_G3S5: + case POWER_S4: case POWER_S3S5: + case POWER_G3S5: + case POWER_S4S5: + case POWER_S5S4: + case POWER_S3S4: return state_mask & CHIPSET_STATE_SOFT_OFF; - case POWER_S3: case POWER_S5S3: + case POWER_S3: + case POWER_S4S3: case POWER_S0S3: return state_mask & CHIPSET_STATE_SUSPEND; #ifdef CONFIG_POWER_S0IX diff --git a/power/falconlite.c b/power/falconlite.c index d2f8e5952a..b418edfd84 100644 --- a/power/falconlite.c +++ b/power/falconlite.c @@ -462,6 +462,11 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: power_seq_run(s5g3_power_seq, ARRAY_SIZE(s5g3_power_seq)); return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/icelake.c b/power/icelake.c index 120df9f578..20fda53ef0 100644 --- a/power/icelake.c +++ b/power/icelake.c @@ -50,6 +50,11 @@ const struct power_signal_info power_signal_list[] = { .flags = POWER_SIGNAL_ACTIVE_HIGH, .name = "SLP_S4_DEASSERTED", }, + [X86_SLP_S5_DEASSERTED] = { + .gpio = SLP_S5_SIGNAL_L, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "SLP_S5_DEASSERTED", + }, [X86_SLP_SUS_DEASSERTED] = { .gpio = GPIO_SLP_SUS_L, .flags = POWER_SIGNAL_ACTIVE_HIGH, diff --git a/power/intel_x86.c b/power/intel_x86.c index 8c8ee908eb..e020874de6 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -29,6 +29,7 @@ enum sys_sleep_state { SYS_SLEEP_S3, SYS_SLEEP_S4, + SYS_SLEEP_S5, #ifdef CONFIG_POWER_S0IX SYS_SLEEP_S0IX, #endif @@ -37,6 +38,7 @@ enum sys_sleep_state { static const int sleep_sig[] = { [SYS_SLEEP_S3] = SLP_S3_SIGNAL_L, [SYS_SLEEP_S4] = SLP_S4_SIGNAL_L, + [SYS_SLEEP_S5] = SLP_S5_SIGNAL_L, #ifdef CONFIG_POWER_S0IX [SYS_SLEEP_S0IX] = GPIO_PCH_SLP_S0_L, #endif @@ -121,7 +123,7 @@ static enum power_state power_wait_s5_rtc_reset(void) } s5_exit_tries = 0; - return POWER_S5S3; /* Power up to next state */ + return POWER_S5S4; /* Power up to next state */ } #endif @@ -279,22 +281,34 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) return power_wait_s5_rtc_reset(); #endif - if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 1) - return POWER_S5S3; /* Power up to next state */ + if (chipset_get_sleep_signal(SYS_SLEEP_S5) == 1) + return POWER_S5S4; /* Power up to next state */ + break; + + case POWER_S4: + if (chipset_get_sleep_signal(SYS_SLEEP_S5) == 0) { + /* Power down to next state */ + return POWER_S4S5; + } else if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 1) { + /* Power up to the next level */ + return POWER_S4S3; + } + break; case POWER_S3: if (!power_has_signals(IN_PGOOD_ALL_CORE)) { - /* Required rail went away */ + /* Required rail went away, go straight to S5 */ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL); return POWER_S3S5; } else if (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1) { /* Power up to next state */ return POWER_S3S0; } else if (chipset_get_sleep_signal(SYS_SLEEP_S4) == 0) { - /* Power down to next state */ - return POWER_S3S5; + /* Power down to the next state */ + return POWER_S3S4; } + break; case POWER_S0: @@ -359,7 +373,15 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) power_s5_up = 1; return POWER_S5; + case POWER_S5S4: + return POWER_S4; /* Power up to next state */ + + case POWER_S3S4: + return POWER_S4; /* Power down to the next state */ + case POWER_S5S3: + /* fallthrough */ + case POWER_S4S3: if (!power_has_signals(IN_PGOOD_ALL_CORE)) { /* Required rail went away */ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL); @@ -380,7 +402,7 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) case POWER_S3S0: if (!power_has_signals(IN_PGOOD_ALL_CORE)) { - /* Required rail went away */ + /* Required rail went away, go straight back to S5 */ chipset_force_shutdown(CHIPSET_SHUTDOWN_POWERFAIL); return POWER_S3S5; } @@ -390,6 +412,10 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) lpc_s3_resume_clear_masks(); +#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK + /* Call hooks prior to chipset resume */ + hook_notify(HOOK_CHIPSET_RESUME_INIT); +#endif /* Call hooks now that rails are up */ hook_notify(HOOK_CHIPSET_RESUME); @@ -412,8 +438,13 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) return POWER_S0; case POWER_S0S3: + /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SUSPEND); +#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK + /* Call hooks after chipset suspend */ + hook_notify(HOOK_CHIPSET_SUSPEND_COMPLETE); +#endif /* Suspend wireless */ wireless_set_state(WIRELESS_SUSPEND); @@ -445,6 +476,11 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) * to go into deep sleep in S0ix. */ enable_sleep(SLEEP_MASK_AP_RUN); + +#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK + hook_notify(HOOK_CHIPSET_SUSPEND_COMPLETE); +#endif + return POWER_S0ix; case POWER_S0ixS0: @@ -454,11 +490,17 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) */ disable_sleep(SLEEP_MASK_AP_RUN); +#ifdef CONFIG_CHIPSET_RESUME_INIT_HOOK + hook_notify(HOOK_CHIPSET_RESUME_INIT); +#endif + sleep_resume_transition(); return POWER_S0; #endif case POWER_S3S5: + /* fallthrough */ + case POWER_S4S5: /* Call hooks before we remove power rails */ hook_notify(HOOK_CHIPSET_SHUTDOWN); diff --git a/power/mt817x.c b/power/mt817x.c index 8f11af2364..30d3ffed1e 100644 --- a/power/mt817x.c +++ b/power/mt817x.c @@ -748,6 +748,12 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: return POWER_G3; + + default: + /* Elm does not have space for such an extravagant print. */ + /* CPRINTS("Unexpected power state %d", state); */ + ASSERT(0); + break; } return state; diff --git a/power/mt8183.c b/power/mt8183.c index ddf49799e9..7c747541a6 100644 --- a/power/mt8183.c +++ b/power/mt8183.c @@ -570,6 +570,11 @@ enum power_state power_handle_state(enum power_state state) } return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/mt8186.c b/power/mt8186.c new file mode 100644 index 0000000000..75ab6fd170 --- /dev/null +++ b/power/mt8186.c @@ -0,0 +1,410 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * MT8186 SoC power sequencing module for Chrome EC + * + * This implements the following features: + * + * - Cold reset powers on the AP + * + * When powered off: + * - Press power button turns on the AP + * - Hold power button turns on the AP, and then 8s later turns it off and + * leaves it off until pwron is released and press again. + * - Lid open turns on the AP + * + * When powered on: + * - Holding power button for 8s powers off the AP + * - Pressing and releaseing power within that 8s is ignored + */ + +#include "assert.h" +#include "battery.h" +#include "chipset.h" +#include "common.h" +#include "gpio.h" +#include "hooks.h" +#include "lid_switch.h" +#include "power.h" +#include "power_button.h" +#include "system.h" +#include "task.h" +#include "timer.h" + +#ifdef CONFIG_BRINGUP +#define GPIO_SET_LEVEL(signal, value) \ + gpio_set_level_verbose(CC_CHIPSET, signal, value) +#else +#define GPIO_SET_LEVEL(signal, value) gpio_set_level(signal, value) +#endif + +/* Console output macros */ +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ##args) + +/* Input state flags */ +#define IN_SUSPEND_ASSERTED POWER_SIGNAL_MASK(AP_IN_S3) +#define IN_AP_RST POWER_SIGNAL_MASK(AP_IN_RST) + +/* Long power key press to force shutdown in S0. go/crosdebug */ +#define FORCED_SHUTDOWN_DELAY (8 * SECOND) + +/* Long power key press to boot from S5/G3 state. */ +#define POWERBTN_BOOT_DELAY (10 * MSEC) +#define PMIC_EN_PULSE_MS 50 + +/* Maximum time it should for PMIC to turn on after toggling PMIC_EN_ODL. */ +#define PMIC_EN_TIMEOUT (300 * MSEC) + +/* 30 ms for hard reset, we hold it longer to prevent TPM false alarm. */ +#define SYS_RST_PULSE_LENGTH (50 * MSEC) + +#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 */ + +static void reset_request_interrupt_deferred(void) +{ + chipset_reset(CHIPSET_RESET_AP_REQ); +} +DECLARE_DEFERRED(reset_request_interrupt_deferred); + +void chipset_reset_request_interrupt(enum gpio_signal signal) +{ + hook_call_deferred(&reset_request_interrupt_deferred_data, 0); +} + +static void release_power_button(void) +{ + CPRINTS("release power button after 8 seconds."); + GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1); +} +DECLARE_DEFERRED(release_power_button); + +void chipset_force_shutdown(enum chipset_shutdown_reason reason) +{ + CPRINTS("%s(%d)", __func__, reason); + report_ap_reset(reason); + + /* + * Force power off. This condition will reset once the state machine + * transitions to G3. + */ + GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0); + CPRINTS("Forcing pmic off with long press."); + GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 0); + hook_call_deferred(&release_power_button_data, + FORCED_SHUTDOWN_DELAY + SECOND); + + task_wake(TASK_ID_CHIPSET); +} + +void chipset_force_shutdown_button(void) +{ + chipset_force_shutdown(CHIPSET_SHUTDOWN_BUTTON); +} +DECLARE_DEFERRED(chipset_force_shutdown_button); + +void chipset_exit_hard_off_button(void) +{ + /* + * release power button in case we are in the 8 seconds long hold + * period + */ + hook_call_deferred(&release_power_button_data, -1); + release_power_button(); + /* Power up from off */ + chipset_exit_hard_off(); +} +DECLARE_DEFERRED(chipset_exit_hard_off_button); + +void chipset_reset(enum chipset_shutdown_reason reason) +{ + CPRINTS("%s: %d", __func__, reason); + report_ap_reset(reason); + + GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 0); + usleep(SYS_RST_PULSE_LENGTH); + GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1); +} + +#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE +static void power_reset_host_sleep_state(void) +{ + power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET); + sleep_reset_tracking(); + power_chipset_handle_host_sleep_event(HOST_SLEEP_EVENT_DEFAULT_RESET, + NULL); +} + +static void handle_chipset_reset(void) +{ + if (chipset_in_state(CHIPSET_STATE_SUSPEND)) { + CPRINTS("Chipset reset: exit s3"); + power_reset_host_sleep_state(); + task_wake(TASK_ID_CHIPSET); + } +} +DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST); +#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */ + +/* + * Power state is determined from the following table: + * + * | IN_AP_RST | IN_SUSPEND_ASSERTED | + * ---------------------------------------------- + * S0 | 0 | 0 | + * S3 | 0 | 1 | + * G3 | 1 | x | + * + * S5 is only used when exit from G3 in power_common_state(). + */ +static enum power_state power_get_signal_state(void) +{ + if (power_get_signals() & IN_AP_RST) + return POWER_G3; + if (power_get_signals() & IN_SUSPEND_ASSERTED) + return POWER_S3; + return POWER_S0; +} + +enum power_state power_chipset_init(void) +{ + int exit_hard_off = 1; + enum power_state init_state = power_get_signal_state(); + + /* Enable reboot / sleep control inputs from AP */ + gpio_enable_interrupt(GPIO_AP_EC_WARM_RST_REQ); + gpio_enable_interrupt(GPIO_AP_IN_SLEEP_L); + gpio_enable_interrupt(GPIO_AP_EC_SYSRST_ODL); + gpio_enable_interrupt(GPIO_AP_EC_WDTRST_L); + + if (system_jumped_late()) { + if (init_state == POWER_S0) { + disable_sleep(SLEEP_MASK_AP_RUN); + CPRINTS("already in S0"); + } + } else if (system_get_reset_flags() & EC_RESET_FLAG_AP_OFF) { + exit_hard_off = 0; + } else if ((system_get_reset_flags() & EC_RESET_FLAG_HIBERNATE) && + gpio_get_level(GPIO_AC_PRESENT)) { + /* + * If AC present, assume this is a wake-up by AC insert. + * Boot EC only. + * + * Note that extpower module is not initialized at this point, + * the only way is to ask GPIO_AC_PRESENT directly. + */ + exit_hard_off = 0; + } + + if (battery_is_present() == BP_YES) + /* + * (crosbug.com/p/28289): Wait battery stable. + * Some batteries use clock stretching feature, which requires + * more time to be stable. + */ + battery_wait_for_stable(); + + if (exit_hard_off) + /* Auto-power on */ + chipset_exit_hard_off(); + + if (init_state != POWER_G3 && !exit_hard_off) + /* Force shutdown from S5 if the PMIC is already up. */ + chipset_force_shutdown(CHIPSET_SHUTDOWN_INIT); + + return init_state; +} + +enum power_state power_handle_state(enum power_state state) +{ + enum power_state next_state = power_get_signal_state(); + + switch (state) { + case POWER_G3: + if (next_state != POWER_G3) + return POWER_G3S5; + break; + + case POWER_S5: + return POWER_S5S3; + + case POWER_S3: + if (next_state == POWER_G3) + return POWER_S3S5; + else if (next_state == POWER_S0) + return POWER_S3S0; + break; + + case POWER_S0: + if (next_state != POWER_S0) + return POWER_S0S3; + + break; + + case POWER_G3S5: + return POWER_S5; + + case POWER_S5S3: + hook_notify(HOOK_CHIPSET_PRE_INIT); + + GPIO_SET_LEVEL(GPIO_SYS_RST_ODL, 1); + msleep(PMIC_EN_PULSE_MS); + GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 0); + msleep(PMIC_EN_PULSE_MS); + GPIO_SET_LEVEL(GPIO_EC_PMIC_EN_ODL, 1); + + if (power_wait_mask_signals_timeout(0, IN_AP_RST, + PMIC_EN_TIMEOUT)) + /* Give up, go back to G3. */ + return POWER_S5G3; + + msleep(500); + /* Call hooks now that rails are up */ + hook_notify(HOOK_CHIPSET_STARTUP); + /* + * Clearing the sleep failure detection tracking on the path + * to S0 to handle any reset conditions. + */ +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + power_reset_host_sleep_state(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + /* Power up to next state */ + return POWER_S3; + + case POWER_S3S0: + if (power_wait_mask_signals_timeout(0, IN_AP_RST, SECOND)) { + chipset_force_shutdown(CHIPSET_SHUTDOWN_WAIT); + return POWER_S0S3; + } + + /* Call hooks now that rails are up */ + hook_notify(HOOK_CHIPSET_RESUME); + +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + sleep_resume_transition(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + + /* + * Disable idle task deep sleep. This means that the low + * power idle task will not go into deep sleep while in S0. + */ + disable_sleep(SLEEP_MASK_AP_RUN); + + /* Power up to next state */ + return POWER_S0; + + case POWER_S0S3: + /* Call hooks before we remove power rails */ + hook_notify(HOOK_CHIPSET_SUSPEND); + +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION + sleep_suspend_transition(); +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + + /* + * Enable idle task deep sleep. Allow the low power idle task + * to go into deep sleep in S3 or lower. + */ + enable_sleep(SLEEP_MASK_AP_RUN); + + /* + * In case the power button is held awaiting power-off timeout, + * power off immediately now that we're entering S3. + */ + if (power_button_is_pressed()) + hook_call_deferred(&chipset_force_shutdown_button_data, + -1); + + return POWER_S3; + + case POWER_S3S5: + /* Call hooks before we remove power rails */ + hook_notify(HOOK_CHIPSET_SHUTDOWN); + hook_notify(HOOK_CHIPSET_SHUTDOWN_COMPLETE); + + /* Skip S5 */ + return POWER_S5G3; + + case POWER_S5G3: + return POWER_G3; + default: + CPRINTS("Unexpected power state %d", state); + break; + } + + return state; +} + +static void power_button_changed(void) +{ + if (power_button_is_pressed()) { + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + hook_call_deferred(&chipset_exit_hard_off_button_data, + POWERBTN_BOOT_DELAY); + + /* Delayed power down from S0/S3, cancel on PB release */ + hook_call_deferred(&chipset_force_shutdown_button_data, + FORCED_SHUTDOWN_DELAY); + } else { + /* Power button released, cancel deferred shutdown/boot */ + hook_call_deferred(&chipset_exit_hard_off_button_data, -1); + hook_call_deferred(&chipset_force_shutdown_button_data, -1); + } +} +DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT); + +#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE +static void suspend_hang_detected(void) +{ + CPRINTS("Warning: Detected sleep hang! Waking host up!"); + host_set_single_event(EC_HOST_EVENT_HANG_DETECT); +} + +__override void power_chipset_handle_host_sleep_event( + enum host_sleep_event state, + struct host_sleep_event_context *ctx) +{ + CPRINTS("Handle sleep: %d", state); + + if (state == HOST_SLEEP_EVENT_S3_SUSPEND) { + /* + * Indicate to power state machine that a new host event for + * S3 suspend has been received and so chipset suspend + * notification needs to be sent to listeners. + */ + sleep_set_notify(SLEEP_NOTIFY_SUSPEND); + sleep_start_suspend(ctx, suspend_hang_detected); + + } else if (state == HOST_SLEEP_EVENT_S3_RESUME) { + /* + * Wake up chipset task and indicate to power state machine that + * listeners need to be notified of chipset resume. + */ + sleep_set_notify(SLEEP_NOTIFY_RESUME); + task_wake(TASK_ID_CHIPSET); + sleep_complete_resume(ctx); + + } +} +#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */ + +#ifdef CONFIG_LID_SWITCH +static void lid_changed(void) +{ + /* Power-up from off on lid open */ + if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF)) + chipset_exit_hard_off(); +} +DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT); +#endif diff --git a/power/mt8192.c b/power/mt8192.c index 5a4bafe600..3cb6e164d8 100644 --- a/power/mt8192.c +++ b/power/mt8192.c @@ -32,6 +32,7 @@ #include "system.h" #include "task.h" #include "timer.h" +#include "util.h" #ifdef CONFIG_BRINGUP #define GPIO_SET_LEVEL(signal, value) \ @@ -208,8 +209,7 @@ enum power_state power_chipset_init(void) gpio_enable_interrupt(GPIO_AP_EC_WARM_RST_REQ); gpio_enable_interrupt(GPIO_AP_IN_SLEEP_L); - if (system_get_reset_flags() & EC_RESET_FLAG_SYSJUMP && - !IS_ENABLED(CONFIG_VBOOT_EFS2)) { + if (system_jumped_late()) { if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { disable_sleep(SLEEP_MASK_AP_RUN); power_signal_enable_interrupt(GPIO_AP_EC_WATCHDOG_L); @@ -476,6 +476,11 @@ enum power_state power_handle_state(enum power_state state) return POWER_S5; return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/qcom.c b/power/qcom.c index a119ce23d6..2310dfedfa 100644 --- a/power/qcom.c +++ b/power/qcom.c @@ -1119,6 +1119,11 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/rk3288.c b/power/rk3288.c index 39f19ddeff..851a8b4e9d 100644 --- a/power/rk3288.c +++ b/power/rk3288.c @@ -506,6 +506,11 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/rk3399.c b/power/rk3399.c index c1693057b9..e0ea7ee483 100644 --- a/power/rk3399.c +++ b/power/rk3399.c @@ -529,6 +529,11 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/power/sdm845.c b/power/sdm845.c index 7157f98cc3..7463e00069 100644 --- a/power/sdm845.c +++ b/power/sdm845.c @@ -823,6 +823,11 @@ enum power_state power_handle_state(enum power_state state) case POWER_S5G3: return POWER_G3; + + default: + CPRINTS("Unexpected power state %d", state); + ASSERT(0); + break; } return state; diff --git a/test/fake_usbc.c b/test/fake_usbc.c index dc631997cf..f6207c4c4f 100644 --- a/test/fake_usbc.c +++ b/test/fake_usbc.c @@ -259,6 +259,10 @@ void dpm_init(int port) { } +void dpm_mode_exit_complete(int port) +{ +} + void dpm_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, uint32_t *vdm) { diff --git a/test/fpsensor.mocklist b/test/fpsensor.mocklist index 7e8240bb8d..3968a04e7e 100644 --- a/test/fpsensor.mocklist +++ b/test/fpsensor.mocklist @@ -14,7 +14,7 @@ #elif defined(TEST_BUILD) /* Mock the sensor detection on dragonclaw v0.2 dev boards since we can't * otherwise change the detected version in hardware without a rework. See - * https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/docs/schematics/dragonclaw + * https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/schematics/dragonclaw */ #define CONFIG_TEST_MOCK_LIST MOCK(FPSENSOR_DETECT) #endif /* BOARD_HOST */ diff --git a/test/i2c_bitbang.c b/test/i2c_bitbang.c index ab1136a922..dd84c0b83a 100644 --- a/test/i2c_bitbang.c +++ b/test/i2c_bitbang.c @@ -11,7 +11,13 @@ #include "util.h" const struct i2c_port_t i2c_bitbang_ports[] = { - {"", 0, 100, GPIO_I2C_SCL, GPIO_I2C_SDA} + { + .name = "", + .port = 0, + .kbps = 100, + .scl = GPIO_I2C_SCL, + .sda = GPIO_I2C_SDA + } }; const unsigned int i2c_bitbang_ports_used = 1; diff --git a/third_party/libaeabi-cortexm0/core/cortex-m0/div.S b/third_party/libaeabi-cortexm0/core/cortex-m0/div.S index 06dc7afacb..b3f61df632 100644 --- a/third_party/libaeabi-cortexm0/core/cortex-m0/div.S +++ b/third_party/libaeabi-cortexm0/core/cortex-m0/div.S @@ -49,7 +49,7 @@ __aeabi_idiv: L_num_pos: cmp r1, #0 - bge __aeabi_uidivmod + bge Luidivmod rsbs r1, r1, #0 @ den = -den @@ -94,7 +94,7 @@ L_neg_both: L_num_pos_bis: cmp r1, #0 - bge __aeabi_uidivmod + bge Luidivmod rsbs r1, r1, #0 @ den = -den push {lr} @@ -125,6 +125,7 @@ __aeabi_uidiv: __aeabi_uidivmod: +Luidivmod: cmp r1, #0 bne L_no_div0 b __aeabi_idiv0 diff --git a/util/config_allowed.txt b/util/config_allowed.txt index ba0d54fd5a..e7e751116c 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -488,22 +488,20 @@ CONFIG_HOSTCMD_ALIGNED CONFIG_HOSTCMD_AP_SET_SKUID CONFIG_HOSTCMD_BATTERY_V2 CONFIG_HOSTCMD_BUTTON -CONFIG_HOSTCMD_ESPI CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ CONFIG_HOSTCMD_ESPI_EC_MODE CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST CONFIG_HOSTCMD_ESPI_VW_SLP_S3 CONFIG_HOSTCMD_ESPI_VW_SLP_S4 +CONFIG_HOSTCMD_ESPI_VW_SLP_S5 CONFIG_HOSTCMD_EVENTS CONFIG_HOSTCMD_FLASHPD CONFIG_HOSTCMD_FLASH_SPI_INFO -CONFIG_HOSTCMD_HECI CONFIG_HOSTCMD_I2C_ADDR_FLAGS CONFIG_HOSTCMD_I2C_SLAVE_ADDR CONFIG_HOSTCMD_I2C_CONTROL CONFIG_HOSTCMD_LOCATE_CHIP -CONFIG_HOSTCMD_LPC CONFIG_HOSTCMD_PD CONFIG_HOSTCMD_PD_CHG_CTRL CONFIG_HOSTCMD_PD_PANIC @@ -512,7 +510,6 @@ CONFIG_HOSTCMD_RATE_LIMITING_PERIOD CONFIG_HOSTCMD_RATE_LIMITING_RECESS CONFIG_HOSTCMD_RWHASHPD CONFIG_HOSTCMD_SECTION_SORTED -CONFIG_HOSTCMD_SHI CONFIG_HOSTCMD_SKUID CONFIG_HOSTCMD_X86 CONFIG_HOST_COMMAND_STATUS @@ -520,6 +517,10 @@ CONFIG_HOST_ESPI_VW_POWER_SIGNAL CONFIG_HOST_EVENT64 CONFIG_HOST_EVENT64_REPORT_MASK CONFIG_HOST_EVENT_REPORT_MASK +CONFIG_HOST_INTERFACE_ESPI +CONFIG_HOST_INTERFACE_HECI +CONFIG_HOST_INTERFACE_LPC +CONFIG_HOST_INTERFACE_SHI CONFIG_HWTIMER_64BIT CONFIG_HW_CRC CONFIG_HW_SPECIFIC_UDELAY @@ -611,6 +612,7 @@ CONFIG_LED_DRIVER_DS2413 CONFIG_LED_DRIVER_LM3509 CONFIG_LED_DRIVER_LM3630A CONFIG_LED_DRIVER_LP5562 +CONFIG_LED_DRIVER_MP3385 CONFIG_LED_DRIVER_OZ554 CONFIG_LED_POLICY_STD CONFIG_LED_POWER_ACTIVE_LOW @@ -655,7 +657,6 @@ CONFIG_MAG_LSM6DSM_BMM150 CONFIG_MAG_LSM6DSM_LIS2MDL CONFIG_MALLOC CONFIG_MAPPED_STORAGE_BASE -CONFIG_MATH_UTIL CONFIG_MAX695X_SEVEN_SEGMENT_DISPLAY CONFIG_MCDP28X0 CONFIG_MCHP_48MHZ_OUT @@ -894,7 +895,8 @@ CONFIG_TEMP_SENSOR_G753 CONFIG_TEMP_SENSOR_G781 CONFIG_TEMP_SENSOR_G782 CONFIG_TEMP_SENSOR_OTI502 -CONFIG_TEMP_SENSOR_POWER_GPIO +CONFIG_TEMP_SENSOR_PCT2075 +CONFIG_TEMP_SENSOR_POWER CONFIG_TEMP_SENSOR_SB_TSI CONFIG_TEMP_SENSOR_TMP006 CONFIG_TEMP_SENSOR_TMP112 @@ -1052,9 +1054,6 @@ CONFIG_USB_PD_TCPMV2 CONFIG_USB_PD_TCPM_ANX3429 CONFIG_USB_PD_TCPM_ANX740X CONFIG_USB_PD_TCPM_ANX741X -CONFIG_USB_PD_TCPM_ANX7447 -CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD -CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND CONFIG_USB_PD_TCPM_ANX74XX CONFIG_USB_PD_TCPM_ANX7688 CONFIG_USB_PD_TCPM_CCGXXF diff --git a/util/config_option_check.py b/util/config_option_check.py index 29e8fb8611..8bd8ecb1f0 100755 --- a/util/config_option_check.py +++ b/util/config_option_check.py @@ -66,11 +66,11 @@ ALLOWLIST_CONFIGS = ['CONFIG_ZTEST'] def obtain_current_config_options(): """Obtains current config options from include/config.h. - Scans through the master config file defined in CONFIG_FILE for all CONFIG_* + Scans through the main config file defined in CONFIG_FILE for all CONFIG_* options. Returns: - config_options: A list of all the config options in the master CONFIG_FILE. + config_options: A list of all the config options in the main CONFIG_FILE. """ config_options = [] @@ -148,11 +148,11 @@ def print_missing_config_options(hunks, config_options): Args: hunks: A list of Hunk objects which represent the hunks from the git diff output. - config_options: A list of all the config options in the master CONFIG_FILE. + config_options: A list of all the config options in the main CONFIG_FILE. Returns: missing_config_option: A boolean indicating if any CONFIG_* options - are missing from the master CONFIG_FILE in this commit or if any CONFIG_* + are missing from the main CONFIG_FILE in this commit or if any CONFIG_* options removed are no longer being used in the repo. """ missing_config_option = False diff --git a/util/ec3po/console.py b/util/ec3po/console.py index 9f28c8b7bf..e71216e3f2 100755 --- a/util/ec3po/console.py +++ b/util/ec3po/console.py @@ -98,8 +98,8 @@ class Console(object): Attributes: logger: A logger for this module. - master_pty: File descriptor to the master side of the PTY. Used for driving - output to the user and receiving user input. + controller_pty: File descriptor to the controller side of the PTY. Used for + driving output to the user and receiving user input. user_pty: A string representing the PTY name of the served console. cmd_pipe: A socket.socket or multiprocessing.Connection object which represents the console side of the command pipe. This must be a @@ -139,13 +139,13 @@ class Console(object): output_line_log_buffer: buffer for lines coming from the EC to log to debug """ - def __init__(self, master_pty, user_pty, interface_pty, cmd_pipe, dbg_pipe, + def __init__(self, controller_pty, user_pty, interface_pty, cmd_pipe, dbg_pipe, name=None): """Initalises a Console object with the provided arguments. Args: - master_pty: File descriptor to the master side of the PTY. Used for driving - output to the user and receiving user input. + controller_pty: File descriptor to the controller side of the PTY. Used for + driving output to the user and receiving user input. user_pty: A string representing the PTY name of the served console. interface_pty: A string representing the PTY name of the served command interface. @@ -162,7 +162,7 @@ class Console(object): console_prefix = ('%s - ' % name) if name else '' logger = logging.getLogger('%sEC3PO.Console' % console_prefix) self.logger = interpreter.LoggerAdapter(logger, {'pty': user_pty}) - self.master_pty = master_pty + self.controller_pty = controller_pty self.user_pty = user_pty self.interface_pty = interface_pty self.cmd_pipe = cmd_pipe @@ -189,7 +189,7 @@ class Console(object): def __str__(self): """Show internal state of Console object as a string.""" string = [] - string.append('master_pty: %s' % self.master_pty) + string.append('controller_pty: %s' % self.controller_pty) string.append('user_pty: %s' % self.user_pty) string.append('interface_pty: %s' % self.interface_pty) string.append('cmd_pipe: %s' % self.cmd_pipe) @@ -208,7 +208,7 @@ class Console(object): return '\n'.join(string) def LogConsoleOutput(self, data): - """Log to debug user MCU output to master_pty when line is filled. + """Log to debug user MCU output to controller_pty when line is filled. The logging also suppresses the Cr50 spinner lines by removing characters when it sees backspaces. @@ -261,7 +261,7 @@ class Console(object): def PrintHistory(self): """Print the history of entered commands.""" - fd = self.master_pty + fd = self.controller_pty # Make it pretty by figuring out how wide to pad the numbers. wide = (len(self.history) // 10) + 1 for i in range(len(self.history)): @@ -298,7 +298,7 @@ class Console(object): # Print the last entry in the history buffer. self.logger.debug('printing previous entry %d - %s', self.history_pos, self.history[self.history_pos]) - fd = self.master_pty + fd = self.controller_pty prev_cmd = self.history[self.history_pos] os.write(fd, prev_cmd) # Update the input buffer. @@ -312,7 +312,7 @@ class Console(object): self.logger.debug('History buffer is empty.') return - fd = self.master_pty + fd = self.controller_pty self.logger.debug('current history position: %d', self.history_pos) # Increment the history position. @@ -357,7 +357,7 @@ class Console(object): def SliceOutChar(self): """Remove a char from the line and shift everything over 1 column.""" - fd = self.master_pty + fd = self.controller_pty # Remove the character at the input_buffer_pos by slicing it out. self.input_buffer = self.input_buffer[0:self.input_buffer_pos] + \ self.input_buffer[self.input_buffer_pos+1:] @@ -551,14 +551,14 @@ class Console(object): EOFError: Allowed to propagate through from self.CheckForEnhancedECImage() i.e. from self.dbg_pipe.recv(). """ - fd = self.master_pty + fd = self.controller_pty # Enter the OOBM prompt mode if the user presses '%'. if byte == ord('%'): self.logger.debug('Begin OOBM command.') self.receiving_oobm_cmd = True # Print a "prompt". - os.write(self.master_pty, b'\r\n% ') + os.write(self.controller_pty, b'\r\n% ') return # Add chars to the pending OOBM command if we're currently receiving one. @@ -566,7 +566,7 @@ class Console(object): tmp_bytes = six.int2byte(byte) self.pending_oobm_cmd += tmp_bytes self.logger.debug('%s', tmp_bytes) - os.write(self.master_pty, tmp_bytes) + os.write(self.controller_pty, tmp_bytes) return if byte == ControlKey.CARRIAGE_RETURN: @@ -579,7 +579,7 @@ class Console(object): self.pending_oobm_cmd) # Reset the state. - os.write(self.master_pty, b'\r\n' + self.prompt) + os.write(self.controller_pty, b'\r\n' + self.prompt) self.input_buffer = b'' self.input_buffer_pos = 0 self.receiving_oobm_cmd = False @@ -742,7 +742,7 @@ class Console(object): # If there's nothing to move, we're done. if not count: return - fd = self.master_pty + fd = self.controller_pty seq = b'\033[' + str(count).encode('ascii') if direction == 'left': # Bind the movement. @@ -790,7 +790,7 @@ class Console(object): def SendBackspace(self): """Backspace a character on the console.""" - os.write(self.master_pty, b'\033[1D \033[1D') + os.write(self.controller_pty, b'\033[1D \033[1D') def ProcessOOBMQueue(self): """Retrieve an item from the OOBM queue and process it.""" @@ -854,10 +854,10 @@ class Console(object): def PrintOOBMHelp(self): """Prints out the OOBM help.""" # Print help syntax. - os.write(self.master_pty, b'\r\n' + b'Known OOBM commands:\r\n') - os.write(self.master_pty, b' interrogate <never | always | auto> ' + os.write(self.controller_pty, b'\r\n' + b'Known OOBM commands:\r\n') + os.write(self.controller_pty, b' interrogate <never | always | auto> ' b'[enhanced]\r\n') - os.write(self.master_pty, b' loglevel <int>\r\n') + os.write(self.controller_pty, b' loglevel <int>\r\n') def CheckBufferForEnhancedImage(self, data): """Adds data to a look buffer and checks to see for enhanced EC image. @@ -933,14 +933,14 @@ def StartLoop(console, command_active, shutdown_pipe=None): """ try: console.logger.debug('Console is being served on %s.', console.user_pty) - console.logger.debug('Console master is on %s.', console.master_pty) + console.logger.debug('Console controller is on %s.', console.controller_pty) console.logger.debug('Command interface is being served on %s.', console.interface_pty) console.logger.debug(console) # This checks for HUP to indicate if the user has connected to the pty. ep = select.epoll() - ep.register(console.master_pty, select.EPOLLHUP) + ep.register(console.controller_pty, select.EPOLLHUP) # This is used instead of "break" to avoid exiting the loop in the middle of # an iteration. @@ -952,13 +952,13 @@ def StartLoop(console, command_active, shutdown_pipe=None): while continue_looping: # Check to see if pts is connected to anything events = ep.poll(0) - master_connected = not events + controller_connected = not events # Check to see if pipes or the console are ready for reading. read_list = [console.interface_pty, console.cmd_pipe, console.dbg_pipe] - if master_connected: - read_list.append(console.master_pty) + if controller_connected: + read_list.append(console.controller_pty) if shutdown_pipe is not None: read_list.append(shutdown_pipe) @@ -970,12 +970,12 @@ def StartLoop(console, command_active, shutdown_pipe=None): ready_for_reading = select_output[0] for obj in ready_for_reading: - if obj is console.master_pty: + if obj is console.controller_pty: if not command_active.value: # Convert to bytes so we can look for non-printable chars such as # Ctrl+A, Ctrl+E, etc. try: - line = bytearray(os.read(console.master_pty, CONSOLE_MAX_READ)) + line = bytearray(os.read(console.controller_pty, CONSOLE_MAX_READ)) console.logger.debug('Input from user: %s, locked:%s', str(line).strip(), command_active.value) for i in line: @@ -985,7 +985,7 @@ def StartLoop(console, command_active, shutdown_pipe=None): except EOFError: console.logger.debug( 'ec3po console received EOF from dbg_pipe in HandleChar()' - ' while reading console.master_pty') + ' while reading console.controller_pty') continue_looping = False break except OSError: @@ -1019,11 +1019,11 @@ def StartLoop(console, command_active, shutdown_pipe=None): # Write it to the user console. if console.raw_debug: console.logger.debug('|CMD|-%s->%r', - ('u' if master_connected else '') + + ('u' if controller_connected else '') + ('i' if command_active.value else ''), data.strip()) - if master_connected: - os.write(console.master_pty, data) + if controller_connected: + os.write(console.controller_pty, data) if command_active.value: os.write(console.interface_pty, data) @@ -1040,18 +1040,18 @@ def StartLoop(console, command_active, shutdown_pipe=None): # Write it to the user console. if len(data) > 1 and console.raw_debug: console.logger.debug('|DBG|-%s->%r', - ('u' if master_connected else '') + + ('u' if controller_connected else '') + ('i' if command_active.value else ''), data.strip()) console.LogConsoleOutput(data) - if master_connected: + if controller_connected: end = len(data) - 1 if console.timestamp_enabled: # A timestamp is required at the beginning of this line if tm_req is True: now = datetime.now() tm = CanonicalizeTimeString(now.strftime(HOST_STRFTIME)) - os.write(console.master_pty, tm) + os.write(console.controller_pty, tm) tm_req = False # Insert timestamps into the middle where appropriate @@ -1066,7 +1066,7 @@ def StartLoop(console, command_active, shutdown_pipe=None): # timestamp required on next input if data[end] == b'\n'[0]: tm_req = True - os.write(console.master_pty, data_tm) + os.write(console.controller_pty, data_tm) if command_active.value: os.write(console.interface_pty, data) @@ -1083,10 +1083,10 @@ def StartLoop(console, command_active, shutdown_pipe=None): pass finally: - ep.unregister(console.master_pty) + ep.unregister(console.controller_pty) console.dbg_pipe.close() console.cmd_pipe.close() - os.close(console.master_pty) + os.close(console.controller_pty) os.close(console.interface_pty) if shutdown_pipe is not None: shutdown_pipe.close() @@ -1155,12 +1155,12 @@ def main(argv): itpr_process.start() # Open a new pseudo-terminal pair - (master_pty, user_pty) = pty.openpty() + (controller_pty, user_pty) = pty.openpty() # Set the permissions to 660. os.chmod(os.ttyname(user_pty), (stat.S_IRGRP | stat.S_IWGRP | stat.S_IRUSR | stat.S_IWUSR)) # Create a console. - console = Console(master_pty, os.ttyname(user_pty), cmd_pipe_interactive, + console = Console(controller_pty, os.ttyname(user_pty), cmd_pipe_interactive, dbg_pipe_interactive) # Start serving the console. v = threadproc_shim.Value(ctypes.c_bool, False) diff --git a/util/ec3po/console_unittest.py b/util/ec3po/console_unittest.py index 3a44e0efce..7e341e7e8d 100755 --- a/util/ec3po/console_unittest.py +++ b/util/ec3po/console_unittest.py @@ -162,8 +162,8 @@ class TestConsoleEditingMethods(unittest.TestCase): format=('%(asctime)s - %(module)s -' ' %(levelname)s - %(message)s')) - # Create a temp file and set both the master and slave PTYs to the file to - # create a loopback. + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. self.tempfile = tempfile.TemporaryFile() # Create some mock pipes. These won't be used since we'll mock out sends @@ -1067,8 +1067,8 @@ class TestConsoleCompatibility(unittest.TestCase): logging.basicConfig(level=logging.DEBUG, format=('%(asctime)s - %(module)s -' ' %(levelname)s - %(message)s')) - # Create a temp file and set both the master and slave PTYs to the file to - # create a loopback. + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. self.tempfile = tempfile.TemporaryFile() # Mock out the pipes. @@ -1350,8 +1350,8 @@ class TestOOBMConsoleCommands(unittest.TestCase): logging.basicConfig(level=logging.DEBUG, format=('%(asctime)s - %(module)s -' ' %(levelname)s - %(message)s')) - # Create a temp file and set both the master and slave PTYs to the file to - # create a loopback. + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. self.tempfile = tempfile.TemporaryFile() # Mock out the pipes. diff --git a/util/ectool.c b/util/ectool.c index 0bc35ef3b4..c6cc36d97d 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -896,6 +896,7 @@ static const char * const ec_feature_names[] = { "Host-controlled Type-C mode entry", [EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK] = "AP ack for Type-C mux configuration", + [EC_FEATURE_S4_RESIDENCY] = "S4 residency", }; int cmd_inventory(int argc, char *argv[]) @@ -3022,12 +3023,13 @@ int read_mapped_temperature(int id) return rv; } -static int get_thermal_fan_percent(int temp) +static int get_thermal_fan_percent(int temp, int sensor_id) { struct ec_params_thermal_get_threshold_v1 p; struct ec_thermal_config r; int rv = 0; + p.sensor_num = sensor_id; rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, &p, sizeof(p), &r, sizeof(r)); @@ -3054,7 +3056,7 @@ static int cmd_temperature_print(int id, int mtemp) if (rc < 0) return rc; printf("%-20s %d K (= %d C) %11d%%\n", r.sensor_name, temp, - K_TO_C(temp), get_thermal_fan_percent(temp)); + K_TO_C(temp), get_thermal_fan_percent(temp, id)); return 0; } @@ -3074,9 +3076,7 @@ int cmd_temperature(int argc, char *argv[]) if (strcmp(argv[1], "all") == 0) { fprintf(stdout, header); - for (id = 0; - id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES; - id++) { + for (id = 0; id < EC_MAX_TEMP_SENSOR_ENTRIES; id++) { mtemp = read_mapped_temperature(id); switch (mtemp) { case EC_TEMP_SENSOR_NOT_PRESENT: @@ -3105,7 +3105,7 @@ int cmd_temperature(int argc, char *argv[]) } if (id < 0 || - id >= EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES) { + id >= EC_MAX_TEMP_SENSOR_ENTRIES) { printf("Sensor ID invalid.\n"); return -1; } @@ -3147,9 +3147,7 @@ int cmd_temp_sensor_info(int argc, char *argv[]) } if (strcmp(argv[1], "all") == 0) { - for (p.id = 0; - p.id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES; - p.id++) { + for (p.id = 0; p.id < EC_MAX_TEMP_SENSOR_ENTRIES; p.id++) { if (read_mapped_temperature(p.id) == EC_TEMP_SENSOR_NOT_PRESENT) continue; @@ -3271,7 +3269,7 @@ int cmd_thermal_get_threshold_v1(int argc, char *argv[]) int i; printf("sensor warn high halt fan_off fan_max name\n"); - for (i = 0; i < 99; i++) { /* number of sensors is unknown */ + for (i = 0; i < EC_MAX_TEMP_SENSOR_ENTRIES; i++) { /* ask for one */ p.sensor_num = i; @@ -5097,7 +5095,7 @@ static int ms_help(const char *cmd) cmd); printf(" %s active - print active flag\n", cmd); printf(" %s info NUM - print sensor info\n", cmd); - printf(" %s ec_rate [RATE_MS] - set/get sample rate\n", + printf(" %s ec_rate NUM [RATE_MS] - set/get sample rate\n", cmd); printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", cmd); @@ -5166,7 +5164,6 @@ static int cmd_motionsense(int argc, char **argv) { "Motion sensing inactive", "0"}, { "Motion sensing active", "1"}, }; - /* No motionsense command has more than 7 args. */ if (argc > 7) return ms_help(argv[0]); @@ -5388,14 +5385,18 @@ static int cmd_motionsense(int argc, char **argv) return 0; } - if (argc < 4 && !strcasecmp(argv[1], "ec_rate")) { + if (argc > 2 && !strcasecmp(argv[1], "ec_rate")) { param.cmd = MOTIONSENSE_CMD_EC_RATE; param.ec_rate.data = EC_MOTION_SENSE_NO_VALUE; - - if (argc == 3) { - param.ec_rate.data = strtol(argv[2], &e, 0); + param.sensor_odr.sensor_num = strtol(argv[2], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad %s arg.\n", argv[2]); + return -1; + } + if (argc == 4) { + param.ec_rate.data = strtol(argv[3], &e, 0); if (e && *e) { - fprintf(stderr, "Bad %s arg.\n", argv[2]); + fprintf(stderr, "Bad %s arg.\n", argv[3]); return -1; } } diff --git a/util/flash_ec b/util/flash_ec index d92a002d01..b0ef53e0c6 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -425,8 +425,7 @@ if [[ "${SERVO_TYPE}" =~ ^servo_v4(p1)?_with_.*_and_.*$ ]]; then fi servo_is_ccd() { - [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] || \ - [[ "${SERVO_TYPE}" =~ "ccd_ti50" ]] + [[ "${SERVO_TYPE}" =~ "ccd" ]] } servo_has_warm_reset() { diff --git a/util/flash_fp_mcu b/util/flash_fp_mcu index 57b2525141..d39feedeec 100644 --- a/util/flash_fp_mcu +++ b/util/flash_fp_mcu @@ -56,6 +56,24 @@ check_hardware_write_protect_disabled() { fi } +# Get the gpiochip base number from sysfs that matches +# a device path +get_sysfs_gpiochip_base() { + local match="${1}" + + for chip in /sys/class/gpio/gpiochip* + do + case "$(readlink ${chip})" in + ${match}) + echo "${chip#/sys/class/gpio/gpiochip}" + return 0 + ;; + esac + done + + return 1 +} + # Get the spiid for the fingerprint sensor based on the modalias # string: https://crbug.com/955117 get_spiid() { @@ -142,7 +160,7 @@ warn_gpio() { } # Taken verbatim from -# https://chromium.googlesource.com/chromiumos/docs/+/master/lsb-release.md#shell +# https://chromium.googlesource.com/chromiumos/docs/+/HEAD/lsb-release.md#shell # This should not be used by anything except get_platform_name. # See https://crbug.com/98462. lsbval() { @@ -410,8 +428,8 @@ flash_fp_mcu_stm32() { # outputs because they're not open-drain signals. # TODO(b/179839337): Make this the default and properly support # open-drain outputs on other platforms. - if [[ "${PLATFORM_NAME}" != "strongbad" ]] && - [[ "${PLATFORM_NAME}" != "herobrine" ]]; then + if [[ "${PLATFORM_BASE_NAME}" != "strongbad" ]] && + [[ "${PLATFORM_BASE_NAME}" != "herobrine" ]]; then gpio in "${gpio_boot0}" "${gpio_nrst}" fi gpio unexport "${gpio_boot0}" "${gpio_nrst}" @@ -491,7 +509,7 @@ config_herobrine() { config_nami() { readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev32765.0" + readonly DEVICE="/dev/spidev1.0" readonly GPIO_CHIP="gpiochip360" # FPMCU RST_ODL is on GPP_C9 = 360 + 57 = 417 @@ -547,11 +565,18 @@ config_strongbad() { # TODO(b/179533783): Fix modalias on strongbad and remove this bypass. readonly DEVICEID="spi10.0" - readonly GPIO_CHIP="gpiochip392" + local dev_path="*/platform/soc@0/3500000.pinctrl/gpio/*" + local gpiobase + if ! gpiobase=$(get_sysfs_gpiochip_base "${dev_path}"); then + echo "Unable to find gpio chip base" + return "${EXIT_PRECONDITION}" + fi + + readonly GPIO_CHIP="gpiochip${gpiobase}" # FPMCU RST_ODL is $(gpiofind FP_RST_L) is gpiochip0 22 - readonly GPIO_NRST=$((392 + $(gpiofind FP_RST_L|cut -f2 -d" "))) + readonly GPIO_NRST=$((${gpiobase} + $(gpiofind FP_RST_L|cut -f2 -d" "))) # FPMCU BOOT0 is $(gpiofind FPMCU_BOOT0) is gpiochip0 10 - readonly GPIO_BOOT0=$((392 + $(gpiofind FPMCU_BOOT0|cut -f2 -d" "))) + readonly GPIO_BOOT0=$((${gpiobase} + $(gpiofind FPMCU_BOOT0|cut -f2 -d" "))) # TODO(b/179839337): Hardware currently doesn't support PWREN, but the # next revision will. Add a comment here about the power enable gpio. readonly GPIO_PWREN=-1 diff --git a/util/make_linux_ec_commands_h.sh b/util/make_linux_ec_commands_h.sh index 4deeaeef32..3afb7c2f41 100755 --- a/util/make_linux_ec_commands_h.sh +++ b/util/make_linux_ec_commands_h.sh @@ -57,7 +57,7 @@ patch "${tmp}" << EOF + * Copyright (C) 2012 Google, Inc + * + * NOTE: This file is auto-generated from ChromeOS EC Open Source code from -+ * https://chromium.googlesource.com/chromiumos/platform/ec/+/master/include/ec_commands.h ++ * https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/include/ec_commands.h */ /* Host communication command constants for Chrome EC */ diff --git a/util/pinmap/README.md b/util/pinmap/README.md new file mode 100644 index 0000000000..a0b4823b2b --- /dev/null +++ b/util/pinmap/README.md @@ -0,0 +1,100 @@ +# pinmap + +## Overview + +This program reads a CSV (comma separated values) file and generates +Zephyr Device Tree entries for GPIOs and other configuration. + +A basic Device Tree configuration is generated for I2C buses, ADC pins, GPIO pins +and PWM pins, with labels and nodes generated for each of the signals in the +spreadsheet. + +A separate overlay Device Tree file can be used to modify the generated DTS +to allow specific properties and parameters to be set e.g bus speeds for I2C, conversion parameters +for ADCs, frequencies for PWM etc. + +## Building + +An ebuild file will eventually be created to integrate the building of the +utility to the standard host binary path. + +In the meantime, the utility can be built directly via: + +``` + +cd pinmap/pinmap +go build + +``` + +This builds the `pinmap` binary in the `pinmap/pinmap` directory. +This binary can be run directly or moved to an appropriate binary directory. + +## Executing + +Running `pinmap --help` prints a usage page. + +The `--reader` flag allows selecting different forms of input. +The default is `csv`, which is expected to be the downloaded CSV from a spreadsheet. + +The `--chip` flag selects the EC part to be used. + +## Spreadsheet format + +An [example spreadsheet](http://go/cros-nissa-ec-pinmap) shows the format expected. + +The first row should contain column titles that the CSV reader can match against to retrieve the +appropriate data. Currently the column names are fixed, but a TODO is to provide an external +map that allows the reader to be informed which columns are to be used. + +Multiple EC chips may be supported in the same spreadsheet. The EC part name is set +as one of the column headers, and this column can be selected using the `--chip` flag. + +An example of a working CSV file can also be viewed in the [file](readers/csv/testdata/data.csv) +used for the unit tests. + +The key columns that are expected (and must match exactly) by the reader are: + +| Column Title | Description | +| ----------- | ----------- | +| Signal Name | The net name as used in the circuit | +| Type | A drop down menu that indicates the type of pin (see the table below) | +| Enum | If set, this string will be added to the DTS node as the `enum-name` property | +| *chip* | This column contains the pin reference for this signal for this particular EC part number | + +The **Type** column indicates exactly what the type of signal is, and is used to +generate the GPIO or other configuration flags in the DTS. + +| Type Name | Description | +| ----------- | ----------- | +| `ADC` | An analogue to digital converter signal | +| `PWM` | A pulse width modulator signal | +| `PWM_INVERT` | A pulse width modulator signal with inverted output | +| `I2C_CLOCK` | The clock signal for an I2C bus | +| `I2C_DATA` | The data signal for an I2C bus (ignored) | +| `INPUT` | A GPIO input signal | +| `INPUT_PU` | A GPIO input signal with internal pull-up | +| `INPUT_PD` | A GPIO input signal with internal pull-down | +| `OUTPUT` | A GPIO output signal | +| `OUTPUT_ODR` | A GPIO output open drain signal | +| `OUTPUT_ODL` | A GPIO output open drain signal (default low) | +| `OTHER` | This signal is ignored, and no DTS configuration is generated for this pin | + +For the I2C signals, only the `I2C_CLOCK` signal is used to determine which I2C +bus is referenced - the `I2C_DATA` signal is effectively ignored. + +## Example use + +Assume that the spreadsheet is downloaded as CSV format to the file `signals.csv`, and +a NPCX993 EC chip is selected, the following command can be run: + +``` +pinmap --chip=NPCX993 --output=generated.dts signals.csv +``` + +The file `generated.dts` contains the DTS configuration as processed and generated by the utility. + +## TODO + +- Read signals from arbitrage (requires more data in arbitrage) +- Build chip map from vendor data diff --git a/util/pinmap/chips/it81302.go b/util/pinmap/chips/it81302.go new file mode 100644 index 0000000000..fef82df49b --- /dev/null +++ b/util/pinmap/chips/it81302.go @@ -0,0 +1,243 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package chips + +import ( + "fmt" + "strings" +) + +// As provided by ITE. +var it81302_pins map[string]string = map[string]string{ + "A1": "GPL5", + "A2": "GPL4", + "A3": "SMDAT1/GPC2", + "A4": "SMCLK1/GPC1", + "A5": "SMCLK0/GPB3", + "A6": "FSCK/GPG7", + "A7": "FMOSI/GPG4", + "A8": "GPH6/ID6", + "A9": "GPH4/ID4", + "A10": "SMINT11/PD1CC2/GPF5", + "A11": "RTS0#/SMINT9/GPF3", + "A12": "GPF1", + "A13": "ADC13/GPL0", + "A14": "ADC14/GPL1", + "A15": "ADC15/GPL2", + "B1": "GPL6", + "B2": "RING#/PWRFAIL#/CK32KOUT/LPCRST#/GPB7", + "B3": "SMDAT0/GPB4", + "B4": "SOUT0/GPB1", + "B5": "SIN0/GPB0", + "B6": "DTR1#/GPG1/ID7", + "B7": "FMISO/GPG5", + "B8": "FSCE#/GPG3", + "B9": "GPH5/ID5", + "B10": "GPH3/ID3", + "B11": "DTR0#/SMINT8/GPF2", + "B12": "CEC/GPF0", + "B13": "GPE2", + "B14": "GPE1", + "B15": "ADC16/GPL3", + "C1": "GPL7", + "C2": "SMCLK2/PECI/GPF6", + "C14": "DCD0#/GPJ4", + "C15": "GPE3", + "D1": "GPC4", + "D2": "SMDAT2/PECIRQT#/GPF7", + "D14": "TACH1B/SMINT7/GPJ3", + "D15": "RIG0#/GPJ5", + "E1": "GPB2", + "E2": "GPC0", + "E5": "VSTBY", + "E6": "VFSPI", + "E7": "DSR0#/GPG6", + "E8": "SOUT1/SMDAT3/PD2CC2/GPH2/ID2", + "E9": "CLKRUN#/GPH0/ID0", + "E10": "SMINT10/PD1CC1/GPF4", + "E11": "VSTBY", + "E14": "SMINT5/GPJ1", + "E15": "TACH0B/SMINT6/GPJ2", + "F1": "PWRSW/GPE4", + "F2": "GPC6", + "F5": "VSTBY", + "F6": "VSS", + "F7": "SSCE1#/GPG0", + "F8": "SSCE0#/GPG2", + "F9": "SIN1/SMCLK3/PD2CC1/GPH1/ID1", + "F10": "AVCC", + "F11": "AVSS", + "F14": "ADC7/CTS1#/GPI7", + "F15": "TACH2/SMINT4/GPJ0", + "G1": "CK32K/GPJ6", + "G2": "GA20/GPB5", + "G5": "VSS", + "G6": "VSS", + "G10": "ADC3/SMINT2/GPI3", + "G11": "ADC5/DCD1#/GPI5", + "G14": "ADC4/SMINT3/GPI4", + "G15": "ADC6/DSR1#/GPI6", + "H1": "ALERT#/SERIRQ/GPM6", + "H2": "GPJ7", + "H5": "VSS", + "H6": "VSS", + "H10": "KSI7", + "H11": "ADC0/GPI0", + "H14": "ADC1/SMINT0/GPI1", + "H15": "ADC2/SMINT1/GPI2", + "J1": "EIO3/LAD3/GPM3", + "J2": "ECS#/LFRAME#/GPM5", + "J5": "KBRST#/GPB6", + "J6": "VSS", + "J10": "KSI4", + "J11": "KSI5", + "J14": "KSI6", + "J15": "KSI3/SLIN#", + "K1": "EIO1/LAD1/GPM1", + "K2": "EIO2/LAD2/GPM2", + "K5": "VBAT", + "K6": "VCC", + "K7": "PWM5/SMDAT5/GPA5", + "K8": "KSO1/PD1", + "K9": "KSO5/PD5", + "K10": "KSI2/INIT#", + "K11": "KSO17/SMISO/GPC5", + "K14": "KSI1/AFD#", + "K15": "KSI0/STB#", + "L1": "ESCK/LPCCLK/GPM4", + "L2": "EIO0/LAD0/GPM0", + "L5": "VSTBY", + "L6": "VCORE", + "L7": "PWM4/SMCLK5/GPA4", + "L8": "PWM7/RIG1#/GPA7", + "L9": "KSO4/PD4", + "L10": "KSO9/BUSY", + "L11": "VSTBY", + "L14": "KSO16/SMOSI/GPC3", + "L15": "KSO15", + "M1": "ECSMI#/GPD4", + "M2": "WRST#", + "M14": "KSO14", + "M15": "KSO13", + "N1": "PWUREQ#/BBO/SMCLK2ALT/GPC7", + "N2": "LPCPD#/GPE6", + "N14": "KSO12/SLCT", + "N15": "WUI14/GPK6", + "P1": "WUI8/GPK0", + "P2": "RI1#/GPD0", + "P3": "L80HLAT/BAO/SMCLK4/GPE0", + "P4": "RI2#/GPD1", + "P5": "ECSCI#/GPD3", + "P6": "PWM1/GPA1", + "P7": "PWM3/GPA3", + "P8": "GINT/CTS0#/GPD5", + "P9": "RTS1#/GPE5", + "P10": "KSO2/PD2", + "P11": "KSO6/PD6", + "P12": "KSO8/ACK#", + "P13": "KSO10/PE", + "P14": "KSO11/ERR#", + "P15": "WUI15/GPK7", + "R1": "WUI9/GPK1", + "R2": "WUI10/GPK2", + "R3": "WUI11/GPK3", + "R4": "L80LLAT/SMDAT4/GPE7", + "R5": "ERST#/LPCRST#/GPD2", + "R6": "PWM0/GPA0", + "R7": "PWM2/GPA2", + "R8": "PWM6/SSCK/GPA6", + "R9": "KSO0/PD0", + "R10": "KSO3/PD3", + "R11": "KSO7/PD7", + "R12": "TACH0A/GPD6", + "R13": "TACH1A/GPD7", + "R14": "WUI13/GPK5", + "R15": "WUI12/GPK4", +} + +// it81302 represents an ITE81302 EC. +type It81302 struct { + okay []string // Nodes to enable. +} + +// Name returns the name of this EC. +func (c *It81302) Name() string { + return "IT81302" +} + +// EnabledNodes returns a list of the DTS nodes that require enabling. +func (c *It81302) EnabledNodes() []string { + return c.okay +} + +// Adc returns the configuration of this pin as an ADC. +func (c *It81302) Adc(p string) string { + s, ok := it81302_pins[p] + if ok { + // Found the pin, now find the ADC name. + for _, ss := range strings.Split(s, "/") { + if strings.HasPrefix(ss, "ADC") && len(ss) > 3 { + c.okay = append(c.okay, "adc0") + return fmt.Sprintf("%s", ss[3:]) + } + } + return "" + } else { + return "" + } +} + +// Gpio returns the configuration of this pin as a GPIO. +func (c *It81302) Gpio(p string) string { + s, ok := it81302_pins[p] + if ok { + // Found the pin, now find the GP name. + for _, ss := range strings.Split(s, "/") { + if strings.HasPrefix(ss, "GP") && len(ss) == 4 { + lc := strings.ToLower(ss) + return fmt.Sprintf("gpio%c %c", lc[2], lc[3]) + } + } + return "" + } else { + return "" + } +} + +// I2c returns the configuration of this pin as an I2C bus. +func (c *It81302) I2c(p string) string { + s, ok := it81302_pins[p] + if ok { + // Found the pin, now find the I2C name. + for _, ss := range strings.Split(s, "/") { + if strings.HasPrefix(ss, "SMCLK") && len(ss) > 5 { + i2c := fmt.Sprintf("i2c%s", ss[5:]) + c.okay = append(c.okay, i2c) + return i2c + } + } + return "" + } else { + return "" + } +} + +// Pwm returns the configuration of this pin as a PWM. +func (c *It81302) Pwm(p string) string { + s, ok := it81302_pins[p] + if ok { + // Found the pin, now find the PWM name. + for _, ss := range strings.Split(s, "/") { + if strings.HasPrefix(ss, "PWM") && len(ss) > 3 { + pwm := fmt.Sprintf("pwm%s", ss[3:]) + c.okay = append(c.okay, pwm) + return fmt.Sprintf("%s %s", pwm, ss[3:]) + } + } + return "" + } else { + return "" + } +} diff --git a/util/pinmap/chips/npcx993.go b/util/pinmap/chips/npcx993.go new file mode 100644 index 0000000000..88639232dc --- /dev/null +++ b/util/pinmap/chips/npcx993.go @@ -0,0 +1,239 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package chips + +import ( + "fmt" + "strings" +) + +// As provided by Nuvoton. +var npcx993_pins map[string]string = map[string]string{ + "E7": "PSL_IN2#&GPI00,GPIO00", + "E6": "GPIO01,PSL_IN3#&GPI01", + "F7": "GPIO02,PSL_IN4#&GPI02", + "D9": "KSO16,GPIO03", + "D11": "KSO13,GPIO04", + "C11": "KSO12,GPIO05", + "B10": "KSO11&P80_DAT,GPIO06", + "B11": "KSO10&P80_CLK,GPIO07", + "C10": "KSO09,GPIO10,CR_SIN1", + "C9": "KSO08,GPIO11,CR_SOUT1", + "B9": "KSO07,GPO12,JEN#", + "C8": "KSO06,GPO13,GP_SEL#", + "C6": "KSO05,GPIO14", + "C7": "KSO04,GPIO15,XNOR", + "B8": "KSO03,GPIO16,JTAG_TDO0_SWO0", + "B7": "KSO02,GPIO17,JTAG_TDI0", + "B6": "KSO01,GPIO20,JTAG_TMS0_SWIO0", + "B5": "KSO00,GPIO21,JTAG_TCK0_SWCLK0", + "C5": "KSI7,GPIO22,S_SBUA", + "C4": "KSI6,GPIO23,S_SBUB", + "C3": "KSI5,GPIO24,,GP_MISO", + "B4": "KSI4,GPIO25,TRACECLK,GP_SCLK", + "B3": "KSI3,GPIO26,TRACEDATA0", + "A4": "KSI2,GPIO27,TRACEDATA1", + "A3": "KSI1,GPIO30,TRACEDATA2,GP_CS#", + "A2": "KSI0,GPIO31,TRACEDATA3,GP_MOSI", + "E4": "GPO32,TRIS#", + "D5": "GPIO33,CTS#,I2C5_SCL0", + "B2": "GPIO34,PS2_DAT2,ADC6", + "K2": "GPO35,CR_SOUT4,TEST#", + "D4": "GPIO36,RTS#,I2C5_SDA0", + "C1": "GPIO37,PS2_CLK2,ADC5", + "E5": "GPIO40,TA1", + "F4": "GPIOE0,ADC10", + "C2": "GPIO41,ADC4", + "D2": "GPIOF0,ADC9", + "D1": "AVCC", + "D3": "GPIO42,ADC3,RI#", + "E2": "GPIO43,ADC2", + "E3": "GPIO44,ADC1", + "F2": "GPIO45,ADC0", + "E1": "AVSS", + "F3": "GPIOE1,ADC7", + "G3": "GPIOF1,ADC8", + "H1": "LAD0,GPIO46", + "J1": "LAD1,GPIO47", + "G10": "GPIO50", + "K1": "LAD2,GPIO51", + "L1": "LAD3,GPIO52", + "L2": "LFRAME#,GPIO53", + "K3": "LRESET#,GPIO54", + "M1": "PCI_CLK,GPIO55", + "M2": "GPIO56,CLKRUN#", + "L3": "SER_IRQ,GPIO57", + "F1": "VHIF", + "L7": "GPIOE3,I2C6_SDA1,I3C_SDA", + "L6": "GPIOE4,I2C6_SCL1,I3C_SCL", + "G6": "GPIO60,PWM7", + "K4": "GPIO61,PWROFF#", + "H2": "GPIO62,PS2_CLK1", + "J2": "GPIO63,PS2_DAT1", + "G4": "GPIO64,CR_SIN1", + "H4": "GPO65,CR_SOUT1,FLPRG1#", + "G2": "GPIO66", + "J3": "GPIO67,PS2_CLK0", + "J4": "GPIO70,PS2_DAT0", + "L4": "VBAT", + "M4": "PWRGD,GPIO72", + "M5": "32KXOUT", + "L5": "32KXIN&32KCLKIN", + "G5": "GPIO73,TA2", + "H5": "GPIO74", + "J6": "GPIO75,32KHZ_OUT,RXD,CR_SIN2", + "J5": "GPIO76,EC_SCI#", + "K6": "VCC1_RST#,GPO77", + "K5": "GPIO80,PWM3", + "M6": "VREF_PECI", + "M7": "PECI_DATA,GPIO81", + "M10": "VSBY", + "J8": "PSL_OUT&GPIO85,GPO85", + "H6": "PSL_GPO,GPOD7", + "D6": "KSO14,GPIO82", + "D7": "KSO15,GPIO83", + "J9": "GPO86,TXD,CR_SOUT2,FLPRG2#", + "K7": "GPIO87,I2C1_SDA0", + "K8": "GPIO90,I2C1_SCL0", + "K9": "GPIO91,I2C2_SDA0", + "L8": "GPIO92,I2C2_SCL0", + "E11": "GPIO93,TA1,F_DIO2", + "M11": "GPIO94", + "M12": ",SPIP_MISO,GPIO95", + "G12": "F_DIO1,GPIO96", + "L10": ",GPIO97", + "G11": "F_CS0#,GPIOA0", + "L12": ",SPIP_SCLK,GPIOA1", + "F12": "F_SCLK,GPIOA2", + "K12": ",SPIP_MOSI,GPIOA3", + "H11": "F_DIO0,GPIOA4,TB1", + "K11": "GPIOA5", + "F11": "GPIOA6,PS2_CLK3,TA2,F_CS1#", + "J11": "GPIOA7,PS2_DAT3,TB2,F_DIO3", + "H12": "VSPI", + "L11": "GPIOB0", + "D8": "KSO17,GPIOB1,CR_SIN4", + "K10": "GPIOB2,I2C7_SDA0,DSR#", + "J10": "GPIOB3,I2C7_SCL0,DCD#", + "B12": "GPIOB4,I2C0_SDA0", + "C12": "GPIOB5,I2C0_SCL0", + "L9": "GPIOB6,PWM4", + "J7": "GPIOB7,PWM5", + "H8": "GPIOC0,PWM6", + "H9": "GPIOC1,I2C6_SDA0", + "H10": "GPIOC2,PWM1,I2C6_SCL0", + "G9": "GPIOC3,PWM0", + "G8": "GPIOC4,PWM2", + "H7": "GPIOC5,KBRST#", + "D10": "GPIOC6,SMI#", + "F10": "GPIOC7,DTR#_BOUT,ADC11", + "F9": "GPIOD0,I2C3_SDA0", + "F8": "GPIOD1,I2C3_SCL0", + "G7": "PSL_IN1#&GPID2,GPIOD2", + "E10": "GPIOD3,TB1", + "A9": "GPIOD4,CR_SIN3", + "A10": "GPIOD5,INTRUDER#", + "H3": "GPOD6,CR_SOUT3,SHDF_ESPI#", + "A11": "GPIOE2", + "A12": "GPIOE5", + "F6": "GPIOF2,I2C4_SDA1", + "F5": "GPIOF3,I2C4_SCL1", + "E9": "GPIOF4,I2C5_SDA1", + "E8": "GPIOF5,I2C5_SCL1", +} + +type Npcx993 struct { + okay []string // Nodes to enable. +} + +// Name returns the name of the chip. +func (c *Npcx993) Name() string { + return "NPCX993" +} + +// EnabledNodes returns the list of node names that are to +// enabled in DTS. +func (c *Npcx993) EnabledNodes() []string { + return c.okay +} + +// Adc returns the ADC config associated with this pin. +func (c *Npcx993) Adc(p string) string { + s, ok := npcx993_pins[p] + if ok { + // Found the pin, now find the ADC name. + for _, ss := range strings.Split(s, ",") { + if strings.HasPrefix(ss, "ADC") && len(ss) > 3 { + c.okay = append(c.okay, "adc0") // Enable ADC + return ss[3:] + } + } + return "" + } else { + return "" + } +} + +// Gpio returns the GPIO config for this pin. +func (c *Npcx993) Gpio(p string) string { + s, ok := npcx993_pins[p] + if ok { + // Found the pin, now find the GP name. + for _, ss := range strings.Split(s, ",") { + if strings.HasPrefix(ss, "GPO") && len(ss) == 5 { + lc := strings.ToLower(ss) + return fmt.Sprintf("gpio%c %c", lc[3], lc[4]) + } else if strings.HasPrefix(ss, "GPIO") && len(ss) == 6 { + lc := strings.ToLower(ss) + return fmt.Sprintf("gpio%c %c", lc[4], lc[5]) + } + } + return "" + } else { + return "" + } +} + +// I2c returns the I2C config for this pin. +// Searches for the pattern I2Cx_SCLy. +func (c *Npcx993) I2c(p string) string { + s, ok := npcx993_pins[p] + if ok { + // Found the pin, now find the I2C port. + for _, ss := range strings.Split(s, ",") { + if len(ss) != 9 { + continue + } + if strings.HasPrefix(ss, "I2C") && + ss[4:8] == "_SCL" { + i2c := fmt.Sprintf("i2c%c_%c", ss[3], ss[8]) + c.okay = append(c.okay, i2c) + c.okay = append(c.okay, fmt.Sprintf("i2c_ctrl%c", ss[3])) + return i2c + } + } + return "" + } else { + return "" + } +} + +// Pwm returns the PWM config associated with this pin. +func (c *Npcx993) Pwm(p string) string { + s, ok := npcx993_pins[p] + if ok { + // Found the pin, now find the PWM name. + for _, ss := range strings.Split(s, ",") { + if strings.HasPrefix(ss, "PWM") && len(ss) > 3 { + ch := ss[3:] + c.okay = append(c.okay, fmt.Sprintf("pwm%s", ch)) + return fmt.Sprintf("pwm%s %s", ch, ch) + } + } + return "" + } else { + return "" + } +} diff --git a/util/pinmap/chips/npcx993_test.go b/util/pinmap/chips/npcx993_test.go new file mode 100644 index 0000000000..572e2a0f5a --- /dev/null +++ b/util/pinmap/chips/npcx993_test.go @@ -0,0 +1,93 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package chips_test + +import ( + "testing" + + "reflect" + "sort" + + "pinmap/chips" +) + +func TestName(t *testing.T) { + expName := "NPCX993" + var n chips.Npcx993 + name := n.Name() + if name != expName { + t.Errorf("Expected %s, got %s for Name()", expName, name) + } +} + +func TestMissing(t *testing.T) { + var n chips.Npcx993 + + none := "None" + if n.Adc(none) != "" { + t.Errorf("Expected empty string, got %s for Adc()", n.Adc(none)) + } + if n.Gpio(none) != "" { + t.Errorf("Expected empty string, got %s for Gpio()", n.Gpio(none)) + } + if n.Pwm(none) != "" { + t.Errorf("Expected empty string, got %s for Pwm()", n.Pwm(none)) + } + if n.I2c(none) != "" { + t.Errorf("Expected empty string, got %s for I2c()", n.I2c(none)) + } +} + +func TestMulti(t *testing.T) { + var n chips.Npcx993 + + pin := "F4" + if n.Adc(pin) != "10" { + t.Errorf("Expected \"10\", got %s for Adc()", n.Adc(pin)) + } + if n.Gpio(pin) != "gpioe 0" { + t.Errorf("Expected \"gpioe 0\", got %s for Gpio()", n.Gpio(pin)) + } + if n.Pwm(pin) != "" { + t.Errorf("Expected empty string, got %s for Pwm()", n.Pwm(pin)) + } + if n.I2c(pin) != "" { + t.Errorf("Expected empty string, got %s for I2c()", n.I2c(pin)) + } + pin = "L9" + if n.Pwm(pin) != "pwm4 4" { + t.Errorf("Expected \"pwm4 4\", got %s for Pwm()", n.Pwm(pin)) + } + pin = "F8" + if n.I2c(pin) != "i2c3_0" { + t.Errorf("Expected \"i2c3_0\", got %s for I2c()", n.I2c(pin)) + } +} + +func TestAdcEnable(t *testing.T) { + var n chips.Npcx993 + + pin := "F4" + if n.Adc(pin) != "10" { + t.Errorf("Expected \"10\", got %s for Adc()", n.Adc(pin)) + } + exp := []string{"adc0"} + if !reflect.DeepEqual(n.EnabledNodes(), exp) { + t.Errorf("Expected %v, got %v for EnabledNodes()", exp, n.EnabledNodes()) + } +} + +func TestI2cEnable(t *testing.T) { + var n chips.Npcx993 + + n.I2c("F5") // i2c4_1 + n.I2c("C12") // i2c0_0 + exp := []string{"i2c0_0", "i2c4_1", "i2c_ctrl0", "i2c_ctrl4"} + nodes := n.EnabledNodes() + sort.Strings(nodes) + if !reflect.DeepEqual(nodes, exp) { + t.Errorf("Expected %v, got %v for EnabledNodes()", exp, n.EnabledNodes()) + } +} diff --git a/util/pinmap/chips/register.go b/util/pinmap/chips/register.go new file mode 100644 index 0000000000..96b655814e --- /dev/null +++ b/util/pinmap/chips/register.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package chips + +import ( + "pinmap/pm" +) + +// init registers the chips. +func init() { + pm.RegisterChip(&It81302{}) + pm.RegisterChip(&Npcx993{}) +} diff --git a/util/pinmap/go.mod b/util/pinmap/go.mod new file mode 100644 index 0000000000..7abf2b9886 --- /dev/null +++ b/util/pinmap/go.mod @@ -0,0 +1,3 @@ +module pinmap + +go 1.15 diff --git a/util/pinmap/pinmap/main.go b/util/pinmap/pinmap/main.go new file mode 100644 index 0000000000..2bc5a94e24 --- /dev/null +++ b/util/pinmap/pinmap/main.go @@ -0,0 +1,73 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package main + +import ( + "flag" + "fmt" + "os" + + _ "pinmap/chips" + "pinmap/pm" + _ "pinmap/readers/csv" +) + +var chipFlag = flag.String("chip", "", "Chip to use for pinmap") +var output = flag.String("output", "gpio.dts", "Output file") +var reader = flag.String("reader", "csv", "Input source type") +var force = flag.Bool("force", false, "Overwrite output file") + +func main() { + flag.Usage = Usage + flag.Parse() + if len(flag.Args()) == 0 { + Error("No input arguments") + } + chip := pm.FindChip(*chipFlag) + if chip == nil { + Error(fmt.Sprintf("No matching chip for '%s'", *chipFlag)) + } + pins, err := pm.ReadPins(*reader, *chipFlag, flag.Arg(0)) + if err != nil { + Error(fmt.Sprintf("%s - %s: %v", *reader, flag.Arg(0), err)) + } + if !*force && fileExists(*output) { + Error(fmt.Sprintf("%s already exists - use --force to overwrite", *output)) + } + out, err := os.Create(*output) + defer out.Close() + if err != nil { + Error(fmt.Sprintf("Failed to create %s: %v", *output, err)) + } + pm.Generate(out, pins, chip) +} + +// fileExists returns true if the file currently exists. +func fileExists(name string) bool { + _, err := os.Stat(name) + return err == nil +} + +// Error prints an error message to stderr and prints the usage. +func Error(msg string) { + fmt.Fprintf(os.Stderr, "%s\n", msg) + Usage() +} + +// Usage prints the usage of the command. +func Usage() { + fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "%s [ flags ] input-argument\n", os.Args[0]) + flag.PrintDefaults() + fmt.Fprintf(os.Stderr, "Available chips are:\n") + for _, c := range pm.Chips() { + fmt.Fprintf(os.Stderr, "%s\n", c) + } + fmt.Fprintf(os.Stderr, "Available readers are:\n") + for _, r := range pm.Readers() { + fmt.Fprintf(os.Stderr, "%s\n", r) + } + os.Exit(1) +} diff --git a/util/pinmap/pm/chip.go b/util/pinmap/pm/chip.go new file mode 100644 index 0000000000..292efaec97 --- /dev/null +++ b/util/pinmap/pm/chip.go @@ -0,0 +1,73 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm + +/* + * Chip represents an Embedded Controller IC, where + * pin names can be used to lookup various types of + * pin usages such as I2C buses, GPIOs etc. + * The pins are referenced as physical pin names such as "A4" etc. + */ +type Chip interface { + /* + * Name returns the name of the chip + */ + Name() string + /* + * EnabledNodes returns a list of names of DTS nodes that + * require enabling i.e adding 'status = "okay"' on the nodes. + */ + EnabledNodes() []string + /* + * Adc will return a DTS reference to the appropriate ADC + * that is connected to this pin. + */ + Adc(pin string) string + /* + * Gpio will return a DTS reference to the appropriate GPIO + * that is connected to this pin. + */ + Gpio(pin string) string + /* + * I2C will return a DTS reference to the appropriate I2C + * bus that is connected to this pin. The pin is assumed to be + * the I2C clock pin of the 2 wire bus. + */ + I2c(pin string) string + /* + * Pwm will return a DTS reference to the appropriate PWM + * that is connected to this pin. + */ + Pwm(pin string) string +} + +// chipList contains a list of registered chips. +// Each chip has a unique name that is used to match it. +var chipList []Chip + +// RegisterChip adds this chip into the list of registered chips. +func RegisterChip(chip Chip) { + chipList = append(chipList, chip) +} + +// FindChip returns the registered chip matching this name, or nil +// if none are found. +func FindChip(name string) Chip { + for _, c := range chipList { + if c.Name() == name { + return c + } + } + return nil +} + +// Chips returns the list of names of the registered chips. +func Chips() []string { + var l []string + for _, c := range chipList { + l = append(l, c.Name()) + } + return l +} diff --git a/util/pinmap/pm/chip_test.go b/util/pinmap/pm/chip_test.go new file mode 100644 index 0000000000..031eefa2a8 --- /dev/null +++ b/util/pinmap/pm/chip_test.go @@ -0,0 +1,68 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm_test + +import ( + "testing" + + "reflect" + "sort" + + "pinmap/pm" +) + +type testChip struct { + name string + nodes []string + adc string + gpio string + i2c string + pwm string +} + +func (c *testChip) Name() string { + return c.name +} + +func (c *testChip) EnabledNodes() []string { + return c.nodes +} + +func (c *testChip) Adc(pin string) string { + return c.adc +} + +func (c *testChip) Gpio(pin string) string { + return c.gpio +} + +func (c *testChip) I2c(pin string) string { + return c.i2c +} + +func (c *testChip) Pwm(pin string) string { + return c.pwm +} + +func TestName(t *testing.T) { + n1 := "Test1" + n2 := "Test2" + tc1 := &testChip{name: n1} + tc2 := &testChip{name: n2} + pm.RegisterChip(tc1) + pm.RegisterChip(tc2) + if pm.FindChip(n1) != tc1 { + t.Errorf("Did not match tc1") + } + if pm.FindChip(n2) != tc2 { + t.Errorf("Did not match tc2") + } + chips := pm.Chips() + sort.Strings(chips) + exp := []string{n1, n2} + if !reflect.DeepEqual(exp, chips) { + t.Errorf("Expected %v, got %v", exp, chips) + } +} diff --git a/util/pinmap/pm/generate.go b/util/pinmap/pm/generate.go new file mode 100644 index 0000000000..0548a4a4db --- /dev/null +++ b/util/pinmap/pm/generate.go @@ -0,0 +1,172 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm + +import ( + "fmt" + "io" + "sort" + "strings" + "time" +) + +const header = `/* Copyright %d The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { +` + +// Generate creates the DTS configuration from the pins using the chip as a +// reference and writes the DTS to the output. +func Generate(out io.Writer, pins *Pins, chip Chip) { + // Write header with date. + fmt.Fprintf(out, header, time.Now().Year()) + pinConfig(out, "named-adc-channels", pins.Adc, chip, adcConfig) + pinConfig(out, "named-gpios", pins.Gpio, chip, gpioConfig) + pinConfig(out, "named-i2c-ports", pins.I2c, chip, i2cConfig) + pinConfig(out, "named-pwms", pins.Pwm, chip, pwmConfig) + fmt.Fprintf(out, "};\n") + // Retrieve the enabled nodes, sort, de-dup and + // generate overlays. + en := chip.EnabledNodes() + if len(en) != 0 { + sort.Strings(en) + var prev string + for _, s := range en { + if s == prev { + continue + } + fmt.Fprintf(out, "\n&%s {\n", s) + fmt.Fprintf(out, "\tstatus = \"okay\";\n") + fmt.Fprintf(out, "};\n") + prev = s + } + } +} + +// pinConfig creates the DTS for a single pin. +func pinConfig(out io.Writer, block string, pins []*Pin, chip Chip, cfunc func(io.Writer, *Pin, Chip)) { + if len(pins) == 0 { + return + } + // Sort the pins into alphbetical order. + sort.Slice(pins, func(i, j int) bool { + return pins[j].Signal > pins[i].Signal + }) + // Generate start of block. + fmt.Fprintf(out, "\n\t%s {\n", block) + fmt.Fprintf(out, "\t\tcompatible = \"%s\";\n\n", block) + for _, p := range pins { + cfunc(out, p, chip) + } + fmt.Fprintf(out, "\t};\n") +} + +// adcConfig is the handler for ADC pins. +func adcConfig(out io.Writer, pin *Pin, chip Chip) { + if pin.PinType != ADC { + fmt.Printf("Unknown ADC type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin) + return + } + c := chip.Adc(pin.Pin) + if len(c) == 0 { + fmt.Printf("No matching ADC for pin %s, ignored\n", pin.Pin) + return + } + lc := strings.ToLower(pin.Signal) + fmt.Fprintf(out, "\t\tadc_%s: %s {\n", lc, lc) + fmt.Fprintf(out, "\t\t\tlabel = \"%s\";\n", pin.Signal) + if len(pin.Enum) > 0 { + fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) + } + fmt.Fprintf(out, "\t\t\tchannel = <%s>;\n", c) + fmt.Fprintf(out, "\t\t};\n") +} + +// gpioConfig is the handler for GPIO pins. +func gpioConfig(out io.Writer, pin *Pin, chip Chip) { + c := chip.Gpio(pin.Pin) + if len(c) == 0 { + fmt.Printf("No matching GPIO for pin %s, ignored\n", pin.Pin) + return + } + var gtype string + switch pin.PinType { + default: + fmt.Printf("Unknown GPIO type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin) + return + case Input: + gtype = "GPIO_INPUT" + case InputPU: + gtype = "GPIO_INPUT_PULL_UP" + case InputPD: + gtype = "GPIO_INPUT_PULL_DOWN" + case Output: + gtype = "GPIO_OUTPUT" + case OutputOD: + gtype = "GPIO_ODR_HIGH" + case OutputODL: + gtype = "GPIO_ODR_LOW" + } + lc := strings.ToLower(pin.Signal) + fmt.Fprintf(out, "\t\tgpio_%s: %s {\n", lc, lc) + fmt.Fprintf(out, "\t\t\t#gpio-cells = <0>;\n") + fmt.Fprintf(out, "\t\t\tgpios = <&%s %s>;\n", c, gtype) + if len(pin.Enum) > 0 { + fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) + } + fmt.Fprintf(out, "\t\t};\n") +} + +// i2cConfig is the handler for I2C pins. +func i2cConfig(out io.Writer, pin *Pin, chip Chip) { + if pin.PinType != I2C { + fmt.Printf("Unknown I2C type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin) + return + } + c := chip.I2c(pin.Pin) + if len(c) == 0 { + fmt.Printf("No matching I2C for pin %s, ignored\n", pin.Pin) + return + } + // Trim off trailing clock name (if any) + lc := strings.TrimRight(strings.ToLower(pin.Signal), "_scl") + fmt.Fprintf(out, "\t\ti2c_%s: %s {\n", lc, lc) + fmt.Fprintf(out, "\t\t\ti2c-port = <&%s>;\n", c) + if len(pin.Enum) > 0 { + fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) + } + fmt.Fprintf(out, "\t\t};\n") +} + +// pwmConfig is the handler for PWM pins. +func pwmConfig(out io.Writer, pin *Pin, chip Chip) { + var inv string + switch pin.PinType { + default: + fmt.Printf("Unknown PWM type (%d) for pin %s, ignored\n", pin.PinType, pin.Pin) + return + case PWM: + inv = "0" + case PWM_INVERT: + inv = "1" + } + c := chip.Pwm(pin.Pin) + if len(c) == 0 { + fmt.Printf("No matching PWM for pin %s, ignored\n", pin.Pin) + return + } + lc := strings.ToLower(pin.Signal) + fmt.Fprintf(out, "\t\tpwm_%s: %s {\n", lc, lc) + fmt.Fprintf(out, "\t\t\tpwms = <&%s %s>;\n", c, inv) + if len(pin.Enum) > 0 { + fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) + } + fmt.Fprintf(out, "\t\t};\n") +} diff --git a/util/pinmap/pm/generate_test.go b/util/pinmap/pm/generate_test.go new file mode 100644 index 0000000000..e899e7fa28 --- /dev/null +++ b/util/pinmap/pm/generate_test.go @@ -0,0 +1,166 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm_test + +import ( + "testing" + + "bytes" + "fmt" + "strings" + "time" + + "pinmap/pm" +) + +type genChip struct { +} + +func (c *genChip) Name() string { + return "Test" +} + +func (c *genChip) EnabledNodes() []string { + return []string{"adc0", "i2c0", "pwm1"} +} + +func (c *genChip) Adc(pin string) string { + return pin +} + +func (c *genChip) Gpio(pin string) string { + return fmt.Sprintf("gpio %s", pin) +} + +func (c *genChip) I2c(pin string) string { + return "i2c0" +} + +func (c *genChip) Pwm(pin string) string { + return "pwm1" +} + +func TestGenerate(t *testing.T) { + pins := &pm.Pins{ + Adc: []*pm.Pin{ + &pm.Pin{pm.ADC, "A1", "EC_ADC_1", "ENUM_ADC_1"}, + }, + I2c: []*pm.Pin{ + &pm.Pin{pm.I2C, "B2", "EC_I2C_CLK_0", "ENUM_I2C_0"}, + }, + Gpio: []*pm.Pin{ + &pm.Pin{pm.Input, "C3", "EC_IN_1", "ENUM_IN_1"}, + &pm.Pin{pm.Output, "D4", "EC_OUT_2", "ENUM_OUT_2"}, + &pm.Pin{pm.InputPU, "G7", "EC_IN_3", "ENUM_IN_3"}, + &pm.Pin{pm.InputPD, "H8", "EC_IN_4", "ENUM_IN_4"}, + }, + Pwm: []*pm.Pin{ + &pm.Pin{pm.PWM, "E5", "EC_LED_1", "ENUM_LED_1"}, + &pm.Pin{pm.PWM_INVERT, "F6", "EC_LED_2", "ENUM_LED_2"}, + }, + } + var out bytes.Buffer + pm.Generate(&out, pins, &genChip{}) + /* + * Rather than doing a golden output text compare, it would be better + * to parse the device tree directly and ensuing it is correct. + * However this would considerably complicate this test. + */ + expFmt := + `/* Copyright %d The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_adc_1: ec_adc_1 { + label = "EC_ADC_1"; + enum-name = "ENUM_ADC_1"; + channel = <A1>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_ec_in_1: ec_in_1 { + #gpio-cells = <0>; + gpios = <&gpio C3 GPIO_INPUT>; + enum-name = "ENUM_IN_1"; + }; + gpio_ec_in_3: ec_in_3 { + #gpio-cells = <0>; + gpios = <&gpio G7 GPIO_INPUT_PULL_UP>; + enum-name = "ENUM_IN_3"; + }; + gpio_ec_in_4: ec_in_4 { + #gpio-cells = <0>; + gpios = <&gpio H8 GPIO_INPUT_PULL_DOWN>; + enum-name = "ENUM_IN_4"; + }; + gpio_ec_out_2: ec_out_2 { + #gpio-cells = <0>; + gpios = <&gpio D4 GPIO_OUTPUT>; + enum-name = "ENUM_OUT_2"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_clk_0: ec_i2c_clk_0 { + i2c-port = <&i2c0>; + enum-name = "ENUM_I2C_0"; + }; + }; + + named-pwms { + compatible = "named-pwms"; + + pwm_ec_led_1: ec_led_1 { + pwms = <&pwm1 0>; + enum-name = "ENUM_LED_1"; + }; + pwm_ec_led_2: ec_led_2 { + pwms = <&pwm1 1>; + enum-name = "ENUM_LED_2"; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; +` + exp := fmt.Sprintf(expFmt, time.Now().Year()) + got := out.String() + if exp != got { + // Split each string into lines and compare the lines. + expLines := strings.Split(exp, "\n") + gotLines := strings.Split(got, "\n") + if len(expLines) != len(gotLines) { + t.Errorf("Expected %d lines, got %d lines", len(expLines), len(gotLines)) + } + for i := range expLines { + if i < len(gotLines) && expLines[i] != gotLines[i] { + t.Errorf("%d: exp %s, got %s", i+1, expLines[i], gotLines[i]) + } + } + } +} diff --git a/util/pinmap/pm/pins.go b/util/pinmap/pm/pins.go new file mode 100644 index 0000000000..bb48fa8b92 --- /dev/null +++ b/util/pinmap/pm/pins.go @@ -0,0 +1,35 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm + +// Pin types enum constants +const ( + ADC = iota + PWM + PWM_INVERT + I2C + Input + InputPU + InputPD + Output + OutputOD + OutputODL +) + +// Pin represents one EC pin. +type Pin struct { + PinType int // Type of pin (from above) + Pin string // The reference of the physical pin. + Signal string // The net (circuit) name of the pin + Enum string // If set, the internal s/w name of the pin +} + +// The accumulated pins of the EC. +type Pins struct { + Adc []*Pin // Analogue to digital converters + I2c []*Pin // I2C busses + Gpio []*Pin // GPIO pins + Pwm []*Pin // Pwm pins +} diff --git a/util/pinmap/pm/reader.go b/util/pinmap/pm/reader.go new file mode 100644 index 0000000000..d518b7fc3a --- /dev/null +++ b/util/pinmap/pm/reader.go @@ -0,0 +1,43 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm + +import ( + "fmt" +) + +// Reader reads the pin configuration from a source. +type Reader interface { + Name() string + Read(arg string, chip string) (*Pins, error) +} + +// readerlist is registered list of readers. +var readerList []Reader + +// ReadPins will use the selected reader and the chip to +// read the EC pin data. +func ReadPins(reader, chip, arg string) (*Pins, error) { + for _, r := range readerList { + if r.Name() == reader { + return r.Read(chip, arg) + } + } + return nil, fmt.Errorf("%s: unknown reader", reader) +} + +// Readers returns a list of the reader names. +func Readers() []string { + var l []string + for _, r := range readerList { + l = append(l, r.Name()) + } + return l +} + +// RegisterReader will add this reader to the registered list of readers. +func RegisterReader(reader Reader) { + readerList = append(readerList, reader) +} diff --git a/util/pinmap/pm/reader_test.go b/util/pinmap/pm/reader_test.go new file mode 100644 index 0000000000..3f3929e103 --- /dev/null +++ b/util/pinmap/pm/reader_test.go @@ -0,0 +1,52 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package pm_test + +import ( + "testing" + + "reflect" + + "pinmap/pm" +) + +type testReader struct { + name string + arg string + chip string + pins pm.Pins +} + +func (r *testReader) Name() string { + return r.name +} + +func (r *testReader) Read(arg, chip string) (*pm.Pins, error) { + r.arg = arg + r.chip = chip + return &r.pins, nil +} + +func TestReader(t *testing.T) { + n := "Test1" + tr1 := &testReader{name: n} + pm.RegisterReader(tr1) + p, err := pm.ReadPins(n, "arg1", "chiptest") + if err != nil { + t.Errorf("Error %v on reading pins", err) + } + if p != &tr1.pins { + t.Errorf("Did not match Pins") + } + p, err = pm.ReadPins("notMine", "arg1", "chiptest") + if err == nil { + t.Errorf("Should heve returned error") + } + readers := pm.Readers() + exp := []string{n} + if !reflect.DeepEqual(exp, readers) { + t.Errorf("Expected %v, got %v", exp, readers) + } +} diff --git a/util/pinmap/readers/csv/csv.go b/util/pinmap/readers/csv/csv.go new file mode 100644 index 0000000000..e7677671de --- /dev/null +++ b/util/pinmap/readers/csv/csv.go @@ -0,0 +1,117 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package csv + +import ( + "bufio" + "encoding/csv" + "fmt" + "os" + + "pinmap/pm" +) + +// CSVReader reads the EC pin references from a comma separated +// values file. +type CSVReader struct { +} + +// Name returns the name of this reader. +func (r *CSVReader) Name() string { + return "csv" +} + +// Read reads the CSV file (provided as the argument) and extracts +// the pin reference data. The first line is expected to be column +// titles that are used to identify the columns. +func (r *CSVReader) Read(chipName, arg string) (*pm.Pins, error) { + f, err := os.Open(arg) + if err != nil { + return nil, err + } + defer f.Close() + rdr := csv.NewReader(bufio.NewReader(f)) + data, err := rdr.ReadAll() + if err != nil { + return nil, err + } + if len(data) < 2 { + return nil, fmt.Errorf("no data in file") + } + // Put the CSV headers into a map. + cmap := make(map[string]int) + for c, s := range data[0] { + cmap[s] = c + } + // Find the matching columns that are needed. + signal, ok := cmap["Signal Name"] + if !ok { + return nil, fmt.Errorf("missing 'Signal Name' column") + } + // Find chip column + chip, ok := cmap[chipName] + if !ok { + return nil, fmt.Errorf("missing '%s' chip column", chipName) + } + ptype, ok := cmap["Type"] + if !ok { + return nil, fmt.Errorf("missing 'Type' column") + } + enum, ok := cmap["Enum"] + if !ok { + return nil, fmt.Errorf("missing 'Enum' column") + } + var pins pm.Pins + // Read the rest of the rows. + for i, row := range data[1:] { + p := new(pm.Pin) + switch row[ptype] { + default: + fmt.Printf("%s:%d: Unknown signal type (%s) - ignored", arg, i+1, row[ptype]) + continue + case "OTHER": + // Skipped + continue + case "ADC": + p.PinType = pm.ADC + pins.Adc = append(pins.Adc, p) + case "PWM": + p.PinType = pm.PWM + pins.Pwm = append(pins.Pwm, p) + case "PWM_INVERT": + p.PinType = pm.PWM_INVERT + pins.Pwm = append(pins.Pwm, p) + case "I2C_DATA": + // Only the clock pin is used for the config + continue + case "I2C_CLOCK": + p.PinType = pm.I2C + pins.I2c = append(pins.I2c, p) + case "INPUT": + p.PinType = pm.Input + pins.Gpio = append(pins.Gpio, p) + case "INPUT_PU": + p.PinType = pm.InputPU + pins.Gpio = append(pins.Gpio, p) + case "INPUT_PD": + p.PinType = pm.InputPD + pins.Gpio = append(pins.Gpio, p) + case "OUTPUT": + p.PinType = pm.Output + pins.Gpio = append(pins.Gpio, p) + case "OUTPUT_ODL": + p.PinType = pm.OutputODL + pins.Gpio = append(pins.Gpio, p) + case "OUTPUT_ODR": + p.PinType = pm.OutputOD + pins.Gpio = append(pins.Gpio, p) + } + p.Signal = row[signal] + p.Pin = row[chip] + p.Enum = row[enum] + } + + return &pins, nil +} diff --git a/util/pinmap/readers/csv/csv_test.go b/util/pinmap/readers/csv/csv_test.go new file mode 100644 index 0000000000..94b134ee79 --- /dev/null +++ b/util/pinmap/readers/csv/csv_test.go @@ -0,0 +1,63 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package csv_test + +import ( + "testing" + + "path/filepath" + "reflect" + + "pinmap/pm" + "pinmap/readers/csv" +) + +const chipName = "MyCHIP" + +func TestName(t *testing.T) { + var r csv.CSVReader + if r.Name() != "csv" { + t.Errorf("expected %s, got %s", "csv", r.Name()) + } + pins, err := r.Read(chipName, filepath.Join("testdata", "data.csv")) + if err != nil { + t.Fatalf("data.csv: %v", err) + } + exp := &pm.Pins{ + Adc: []*pm.Pin{ + &pm.Pin{pm.ADC, "A1", "EC_ADC_1", "ENUM_ADC_1"}, + }, + I2c: []*pm.Pin{ + &pm.Pin{pm.I2C, "G7", "EC_I2C_CLK_0", "SENSOR"}, + }, + Gpio: []*pm.Pin{ + &pm.Pin{pm.Input, "D4", "EC_GPIO_1", "GPIO1"}, + &pm.Pin{pm.Output, "E5", "EC_GPIO_2", "GPIO2"}, + &pm.Pin{pm.OutputODL, "F6", "EC_GPIO_3", ""}, + &pm.Pin{pm.InputPU, "K10", "EC_GPIO_4", ""}, + }, + Pwm: []*pm.Pin{ + &pm.Pin{pm.PWM, "C3", "EC_PWM_1", "FAN_1"}, + &pm.Pin{pm.PWM_INVERT, "J9", "EC_PWM_2", "LED_1"}, + }, + } + check(t, "ADc", exp.Adc, pins.Adc) + check(t, "I2c", exp.I2c, pins.I2c) + check(t, "Gpio", exp.Gpio, pins.Gpio) + check(t, "Pwm", exp.Pwm, pins.Pwm) +} + +func check(t *testing.T, name string, exp, got []*pm.Pin) { + if !reflect.DeepEqual(exp, got) { + t.Errorf("%s - expected:", name) + for _, p := range exp { + t.Errorf("%v", *p) + } + t.Errorf("got:") + for _, p := range got { + t.Errorf("%v", *p) + } + } +} diff --git a/util/pinmap/readers/csv/register.go b/util/pinmap/readers/csv/register.go new file mode 100644 index 0000000000..b2f2529061 --- /dev/null +++ b/util/pinmap/readers/csv/register.go @@ -0,0 +1,13 @@ +// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package csv + +import ( + "pinmap/pm" +) + +func init() { + pm.RegisterReader(&CSVReader{}) +} diff --git a/util/pinmap/readers/csv/testdata/data.csv b/util/pinmap/readers/csv/testdata/data.csv new file mode 100644 index 0000000000..6c7ac5ace9 --- /dev/null +++ b/util/pinmap/readers/csv/testdata/data.csv @@ -0,0 +1,11 @@ +Signal Name,MyCHIP,Type,Enum +EC_ADC_1,A1,ADC,ENUM_ADC_1 +EC_IGNORED_1,B2,OTHER, +EC_PWM_1,C3,PWM,FAN_1 +EC_PWM_2,J9,PWM_INVERT,LED_1 +EC_GPIO_1,D4,INPUT,GPIO1 +EC_GPIO_2,E5,OUTPUT,GPIO2 +EC_GPIO_3,F6,OUTPUT_ODL, +EC_I2C_CLK_0,G7,I2C_CLOCK,SENSOR +EC_I2C_DATA_0,H8,I2C_DATA, +EC_GPIO_4,K10,INPUT_PU, diff --git a/util/tagbranch.sh b/util/tagbranch.sh index 3e196b6f25..e925ddf33a 100755 --- a/util/tagbranch.sh +++ b/util/tagbranch.sh @@ -29,7 +29,7 @@ # - the remote git server name shows up in 'git config -l' output in the # line starting with "remote.cros.url=" # - firmware branch names have format of firmware-<board>-XXXXXX -# - the current branch was cut off of <remote name>/master +# - the current branch was cut off of <remote name>/main # # The tag name generated by this script would be the XXXXX string with dots, # if any, replaced by underscores. @@ -44,10 +44,10 @@ fi export ORIGIN_NAME="cros" ORIGIN="$(git config "remote.${ORIGIN_NAME}.url")" -# The last common patch between this branch and the master. -BRANCH_POINT="$(git merge-base "${UPSTREAM}" "${ORIGIN_NAME}/master")" +# The last common patch between this branch and main. +BRANCH_POINT="$(git merge-base "${UPSTREAM}" "${ORIGIN_NAME}/main")" if [[ -z "${BRANCH_POINT}" ]]; then - echo "Failed to determine cros/master branch point" >&2 + echo "Failed to determine cros/main branch point" >&2 exit 1 fi @@ -56,8 +56,8 @@ TAG_BASE="$(sed 's/.*-// # drop everything up to including the last - s/\./_/g # replace dots and dashes with underscores ' <<< "${UPSTREAM}" )" -if [[ "${TAG_BASE}" == "master" ]]; then - echo "Nothing to tag in master branch" >&2 +if [[ "${TAG_BASE}" == "main" ]]; then + echo "Nothing to tag in main branch" >&2 exit 1 fi diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index f76690be19..c0646e5ebb 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -61,6 +61,12 @@ if(DEFINED CONFIG_PLATFORM_EC) set_property(TARGET app PROPERTY INTERPROCEDURAL_OPTIMIZATION True) endif() endif() + + set_compiler_property(APPEND PROPERTY warning_base + # TODO(b/210501420): Make EC code compatible with + # -W-address-of-packed-member + -Wno-address-of-packed-member + ) endif() # Switch from the "zephyr" library to the "app" library for all Chromium OS @@ -121,15 +127,13 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/base32.c" zephyr_library_sources_ifdef(CONFIG_HAS_TASK_POWERBTN "${PLATFORM_EC}/common/power_button_x86.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCEL_BMA255 - "${PLATFORM_EC}/driver/accel_bma2x2.c" - "${PLATFORM_EC}/common/math_util.c") + "${PLATFORM_EC}/driver/accel_bma2x2.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCEL_KX022 "${PLATFORM_EC}/driver/accel_kionix.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCEL_LIS2DW12 "${PLATFORM_EC}/driver/accel_lis2dw12.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_BMI - "${PLATFORM_EC}/driver/accelgyro_bmi_common.c" - "${PLATFORM_EC}/common/math_util.c") + "${PLATFORM_EC}/driver/accelgyro_bmi_common.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_BMI160 "${PLATFORM_EC}/driver/accelgyro_bmi160.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_BMI260 @@ -138,6 +142,10 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_ICM "${PLATFORM_EC}/driver/accelgyro_icm_common.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_ICM426XX "${PLATFORM_EC}/driver/accelgyro_icm426xx.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_ICM42607 + "${PLATFORM_EC}/driver/accelgyro_icm42607.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO + "${PLATFORM_EC}/driver/accelgyro_lsm6dso.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ACCEL_FIFO "${PLATFORM_EC}/common/motion_sense_fifo.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ADC_CMD @@ -168,6 +176,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_ISL9238 "${PLATFORM_EC}/driver/charger/isl923x.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_ISL9238C "${PLATFORM_EC}/driver/charger/isl923x.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_RAA489000 + "${PLATFORM_EC}/driver/charger/isl923x.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_ISL9241 "${PLATFORM_EC}/driver/charger/isl9241.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER_BQ25710 @@ -196,7 +206,7 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_DPTF "${PLATFORM_EC}/common/dptf.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ "${PLATFORM_EC}/common/chipset.c") -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI "${PLATFORM_EC}/common/espi.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/extpower_common.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_EXTPOWER_GPIO @@ -260,8 +270,7 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_PWM zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_ONOFF_STATES "${PLATFORM_EC}/common/led_onoff_states.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LID_ANGLE - "${PLATFORM_EC}/common/motion_lid.c" - "${PLATFORM_EC}/common/math_util.c") + "${PLATFORM_EC}/common/motion_lid.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE "${PLATFORM_EC}/common/lid_angle.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LID_SWITCH @@ -290,6 +299,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_INTEL "${PLATFORM_EC}/power/intel_x86.c") 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") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_MT8192 "${PLATFORM_EC}/power/mt8192.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_POWERSEQ_SC7180 @@ -318,6 +329,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_TEMP_SENSOR "${PLATFORM_EC}/common/temp_sensor.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_THERMISTOR "${PLATFORM_EC}/driver/temp_sensor/thermistor.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_TEMP_SENSOR_TMP112 + "${PLATFORM_EC}/driver/temp_sensor/tmp112.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_THROTTLE_AP "${PLATFORM_EC}/common/throttle_ap.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_TIMER @@ -359,6 +372,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_MUX_IT5205 "${PLATFORM_EC}/driver/usb_mux/it5205.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_MUX_PS8743 "${PLATFORM_EC}/driver/usb_mux/ps8743.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_MUX_TUSB1044 + "${PLATFORM_EC}/driver/usb_mux/tusb1064.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_MUX_VIRTUAL "${PLATFORM_EC}/driver/usb_mux/virtual.c") @@ -399,6 +414,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_DRP_ACC_TRYSRC zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PRL_SM "${PLATFORM_EC}/common/usbc/usb_prl_sm.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447 + "${PLATFORM_EC}/driver/tcpm/anx7447.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_NCT38XX "${PLATFORM_EC}/driver/tcpm/nct38xx.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8751 @@ -407,8 +424,12 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8805 "${PLATFORM_EC}/driver/tcpm/ps8xxx.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8815 "${PLATFORM_EC}/driver/tcpm/ps8xxx.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000 + "${PLATFORM_EC}/driver/tcpm/raa489000.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_RT1715 "${PLATFORM_EC}/driver/tcpm/rt1715.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_RT1718S + "${PLATFORM_EC}/driver/tcpm/rt1718s.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_TUSB422 "${PLATFORM_EC}/driver/tcpm/tusb422.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_TCPCI @@ -424,12 +445,16 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC "${PLATFORM_EC}/common/usbc_ppc.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_AOZ1380 "${PLATFORM_EC}/driver/ppc/aoz1380.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_KTU1125 + "${PLATFORM_EC}/driver/ppc/ktu1125.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_NX20P3483 "${PLATFORM_EC}/driver/ppc/nx20p348x.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_SN5S330 "${PLATFORM_EC}/driver/ppc/sn5s330.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_SYV682X "${PLATFORM_EC}/driver/ppc/syv682x.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC_RT1718S + "${PLATFORM_EC}/driver/ppc/rt1718s.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_VBOOT_HASH "${PLATFORM_EC}/common/vboot_hash.c") @@ -443,3 +468,5 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_VSTORE "${PLATFORM_EC}/common/vstore.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_RTC "${PLATFORM_EC}/common/rtc.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_MATH_UTIL + "${PLATFORM_EC}/common/math_util.c") diff --git a/zephyr/Kconfig b/zephyr/Kconfig index d0ef3fc711..496e169ee9 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -43,6 +43,7 @@ rsource "Kconfig.defaults" rsource "Kconfig.espi" rsource "Kconfig.flash" rsource "Kconfig.header" +rsource "Kconfig.host_interface" rsource "Kconfig.init_priority" rsource "Kconfig.ioex" rsource "Kconfig.keyboard" @@ -71,7 +72,7 @@ rsource "Kconfig.watchdog" config PLATFORM_EC_ACPI bool "Advanced Confiugration and Power Interface (ACPI)" - default y if AP_X86 && PLATFORM_EC_ESPI + default y if AP_X86 && PLATFORM_EC_HOST_INTERFACE_ESPI help Enable the Advanced Configuration and Power Interface (ACPI) in the EC. ACPI is a standard interface to the Application Processor (AP) @@ -176,7 +177,7 @@ choice PLATFORM_EC_CBI_STORAGE_TYPE See here for detailed information on CBI: - https://chromium.googlesource.com/chromiumos/docs/+/master/design_docs/cros_board_info.md + https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md config PLATFORM_EC_CBI_EEPROM bool "CBI EEPROM support" @@ -331,23 +332,6 @@ config PLATFORM_EC_EMULATED_SYSRQ This option enables support for sending emulated SysRq events to AP (on designs with a keyboard, SysRq is passed as normal key presses). -menuconfig PLATFORM_EC_ESPI - bool "eSPI" - depends on ESPI && AP - default y - help - Enable the Enhanced Serial Peripheral Interface (eSPI) shim layer. - eSPI supports a shared physical connection between several on-board - devices, similar to SPI. It adds a few optional signals and a protocol - layer to provide independent 'channels' for each device to communicate - over. - - eSPI is the replacement for LPC (Low-Pin-Count bus). - - See here for information about eSPI: - - https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0_cb.pdf - config PLATFORM_EC_EXTPOWER_GPIO bool "GPIO-based external power detection" depends on PLATFORM_EC_HOOKS && PLATFORM_EC_HOSTCMD @@ -400,6 +384,9 @@ menuconfig PLATFORM_EC_HOSTCMD responds when able. An interrupt can be used to indicate to the AP that the EC has something for it. + The host interface type is selected based on the AP type, but can be + changed though the CONFIG_PLATFORM_EC_HOST_INTERFACE_TYPE choice. + config PLATFORM_EC_HOSTCMD_GET_UPTIME_INFO bool "Host command: EC_CMD_GET_UPTIME_INFO" default PLATFORM_EC_HOSTCMD @@ -549,6 +536,13 @@ config PLATFORM_EC_LOW_POWER_IDLE enabled when the Zephyr power management options are enabled with the PM option. +config PLATFORM_EC_POWER_COMMON + bool + default y + depends on PLATFORM_EC_POWERSEQ + help + Compile common code for AP power state machine. + config PLATFORM_EC_MKBP_EVENT bool "MKBP event" help @@ -753,6 +747,7 @@ config PLATFORM_EC_SYSTEM_UNLOCKED config PLATFORM_EC_THROTTLE_AP bool "CPU throttling" + depends on PLATFORM_EC_TEMP_SENSOR help Enable throttling the CPU based on the temperature sensors. When they detect that the CPU is getting too hot, the CPU is throttled to @@ -865,7 +860,7 @@ config PLATFORM_EC_I2C_PASSTHRU_RESTRICTED config PLATFORM_EC_HOST_COMMAND_STATUS bool "Return in-progress status for slow host commands" - default n + default y if PLATFORM_EC_HOST_INTERFACE_SHI help When the AP is attached to the EC via a serialized bus such as I2C or SPI, it needs a way to minimize the length of time an EC command will @@ -894,4 +889,11 @@ config PLATFORM_EC_AMD_STT to temporarily boost above the sustainable power limit, while the chassis skin temperatures are below limits. +config PLATFORM_EC_MATH_UTIL + bool "Math utility" + default y + help + Math utilities including bitmask manipulation, division rounding, + trigonometric function, etc. + endif # PLATFORM_EC diff --git a/zephyr/Kconfig.battery b/zephyr/Kconfig.battery index 16664d20cf..cfe9dfae6a 100644 --- a/zephyr/Kconfig.battery +++ b/zephyr/Kconfig.battery @@ -209,6 +209,17 @@ config PLATFORM_EC_CHARGER_BQ25720 wide range of input power sources are supported such as high voltage USB-C power delivery. +config PLATFORM_EC_CHARGER_RAA489000 + bool "Use the RAA489000 charger" + depends on PLATFORM_EC_I2C + depends on PLATFORM_EC_CHARGER_SENSE_RESISTOR > 0 + depends on PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC > 0 + select PLATFORM_EC_CHARGER_NARROW_VDC + select PLATFORM_EC_CHARGER_TRICKLE + help + Enables the driver for the Renesas RAA489000 battery charger + with integrated USB-C TCPC. + config PLATFORM_EC_CHARGER_DISCHARGE_ON_AC bool "Board supports discharge mode" help @@ -270,6 +281,25 @@ config PLATFORM_EC_CHARGER_BQ25710_CMP_REF_1P2 voltage to 1.2 V. The power-on default is 2.3 V. This must be enabled if the board was designed for 1.2 V instead of 2.3 V. +config PLATFORM_EC_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM + bool "PKPWR_TOVLD_DEG override" + default n + depends on PLATFORM_EC_CHARGER_BQ25710 || PLATFORM_EC_CHARGER_BQ25720 + help + Enable customizing the charger's PKPWR_TOVLD_DEG period. + +config PLATFORM_EC_CHARGER_BQ25710_PKPWR_TOVLD_DEG + int "PKPWR_TOVLD_DEG period" + range 0 3 + default 0 + depends on PLATFORM_EC_CHARGER_BQ25710 || PLATFORM_EC_CHARGER_BQ25720 + help + Sets the input overload time when in peak power mode + (PKPWR_TOVLD_DEG). This limits how long the charger can draw + ILIM2 from the adapter. This is a 2 bit field. On the bq25710 + 1 ms to 20 ms can be encoded. On the bq25720 1 ms to 10 ms can + be encoded. + config PLATFORM_EC_CHARGER_BQ25710_EN_ACOC bool "Enable AC over-current protection" default n @@ -324,6 +354,15 @@ config PLATFORM_EC_CHARGER_BQ25710_PP_ACOK Sets the PP_ACOK in Prochot Option 1 register. This causes PROCHOT to be pulsed when the AC adapter is removed. +config PLATFORM_EC_CHARGER_BQ25720_PP_IDCHG2 + bool "Enable PROCHOT on battery current exceeding IDCHG_TH2" + default n + depends on PLATFORM_EC_CHARGER_BQ25720 + help + Sets the PP_IDCHG2 bit in Charge Option 4 register. This + causes PROCHOT to be pulsed when the battery discharge current + exceeds IDCHG_TH2. + config PLATFORM_EC_CHARGER_BQ25710_SENSE_RESISTOR int "Value of the charge sense-resistor, in mOhms" default 10 @@ -342,6 +381,25 @@ config PLATFORM_EC_CHARGER_BQ25710_SENSE_RESISTOR_AC external AC power supply. Its value must be known for the calculation to be correct. The value is typically around 10 mOhms. +config PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM + bool "ILIM2_VTH override" + depends on PLATFORM_EC_CHARGER_BQ25710 || PLATFORM_EC_CHARGER_BQ25720 + help + Enable customizing the charhger's ILIM2_VTH threshold + +config PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH + int "ILIM2 threshold" + range 1 30 + default 9 + depends on PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM + help + Set percentage of IDPM as threshold. ICRIT threshold is set to be 110% + of ILIM2. Input overcurrent protection (ACOC) threshold is also 1.33x + or 2x of ILIM2 (1.33x or 2x based on ACOC limit field). + 1 - 25: 110% - 230%, step is 5%. + 26 - 30: 250% - 450%, step is 50%. + 31: Out of range (ignored). + config PLATFORM_EC_CHARGER_BQ25720_VSYS_TH2_CUSTOM bool "VSYS_TH2 override" depends on PLATFORM_EC_CHARGER_BQ25720 @@ -458,6 +516,14 @@ config PLATFORM_EC_CHARGER_NARROW_VDC This should be enabled by charger drivers which need it. It cannot be set otherwise, even in prj.conf +config PLATFORM_EC_CHARGER_TRICKLE + bool + help + Select this if the charger allows trickle charging, which allows + the battery to charge with a minimum voltage. + + This should be enabled by charger drivers which need it. + config PLATFORM_EC_CHARGER_OTG_SUPPORTED bool help @@ -602,6 +668,12 @@ config PLATFORM_EC_CONSOLE_CMD_CHGRAMP OC 1: s0 oc_det0 icl0 OC 2: s0 oc_det0 icl0 +config PLATFORM_EC_CONSOLE_CMD_CHARGER_DUMP + bool "Console command: charger dump" + help + Enable the "charger dump" subcommand. If the charger driver provides + a dump_registers() function, this command shows its register dump. + endif # PLATFORM_EC_CHARGER config PLATFORM_EC_BATTERY_CRITICAL_SHUTDOWN_CUT_OFF @@ -689,7 +761,7 @@ choice PLATFORM_EC_BATTERY_API Select the battery API version. V2 is required on dual-battery-systems and hostless bases with a battery. V1 should not be used except for testing on legacy boards. - + config PLATFORM_EC_BATTERY_V1 bool "Enable battery API v1" depends on !PLATFORM_EC_BATTERY_V2 @@ -704,6 +776,14 @@ config PLATFORM_EC_BATTERY_V2 batteries and full size string values in the battery information including manufacturer, model, chemistry. +config PLATFORM_EC_BATTERY_TYPE_NO_AUTO_DETECT + bool "Disable battery auto detection" + help + Enable this option when the battery type cannot be distinguished + based on only the manufacturer and device name. Your board code + must call battery_set_fixed_battery_type() to set the fixed battery + type, during board initialization. + endchoice if PLATFORM_EC_BATTERY_V2 diff --git a/zephyr/Kconfig.console b/zephyr/Kconfig.console index 809c03c1e0..a8c2a9c22a 100644 --- a/zephyr/Kconfig.console +++ b/zephyr/Kconfig.console @@ -53,3 +53,12 @@ config PLATFORM_EC_HOSTCMD_CONSOLE_BUF_SIZE modular arithmetic is used. endif # PLATFORM_EC_HOSTCMD_CONSOLE + +menuconfig PLATFORM_EC_CONSOLE_DEBUG + bool "Console Debug" + depends on CONSOLE + default n + help + Write all zephyr_print() messages to printk() also. Not recommended + outside of tests. + diff --git a/zephyr/Kconfig.espi b/zephyr/Kconfig.espi index 81b9f11e57..92c55b8884 100644 --- a/zephyr/Kconfig.espi +++ b/zephyr/Kconfig.espi @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -if PLATFORM_EC_ESPI +if PLATFORM_EC_HOST_INTERFACE_ESPI config PLATFORM_EC_ESPI_VW_SLP_S3 bool "SLP_S3 is an eSPI virtual wire instead of a GPIO" @@ -16,6 +16,12 @@ config PLATFORM_EC_ESPI_VW_SLP_S4 For power sequencing, use an eSPI virtual wire instead of defining GPIO_PCH_SLP_S4 in gpio_map.h. +config PLATFORM_EC_ESPI_VW_SLP_S5 + bool "SLP_S5 is an eSPI virtual wire instead of an alias for SLP_S4" + help + For power sequencing, use an eSPI virtual wire to read the SLP_S5 line, + as opposed to merging it into the same net as SLP_S4. + config PLATFORM_EC_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST bool "Reset SLP VW signals on eSPI reset" help @@ -25,4 +31,4 @@ config PLATFORM_EC_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST maintain these pins' states per request. Note that this is currently unimplemented for Zephyr. Please see b/183148073. -endif # PLATFORM_EC_ESPI
\ No newline at end of file +endif # PLATFORM_EC_HOST_INTERFACE_ESPI
\ No newline at end of file diff --git a/zephyr/Kconfig.host_interface b/zephyr/Kconfig.host_interface new file mode 100644 index 0000000000..242406a14e --- /dev/null +++ b/zephyr/Kconfig.host_interface @@ -0,0 +1,59 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +if PLATFORM_EC_HOSTCMD + +choice PLATFORM_EC_HOST_INTERFACE_TYPE + prompt "Select the host interface type" + default PLATFORM_EC_HOST_INTERFACE_ESPI if AP_X86 + default PLATFORM_EC_HOST_INTERFACE_SHI if AP_ARM + help + The AP communicates with the EC using one of several host interface + types. The selection of the host interface type is based on the + capability of both the AP and the EC. + + x86-compatible application processors typically use the enhanced SPI + (ESPI) interface while other application processors use the SPI host + interface (SHI). + +config PLATFORM_EC_HOST_INTERFACE_ESPI + bool "eSPI" + depends on ESPI && AP + help + Enable the Enhanced Serial Peripheral Interface (eSPI) host interface. + eSPI supports a shared physical connection between several on-board + devices, similar to SPI. It adds a few optional signals and a protocol + layer to provide independent 'channels' for each device to communicate + over. + + eSPI is the replacement for LPC (Low-Pin-Count bus). + + See here for information about eSPI: + + https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0_cb.pdf + +config PLATFORM_EC_HOST_INTERFACE_HECI + bool "HECI" + depends on AP + help + Enable the Host Embedded Controller Interface (HECI). + + +config PLATFORM_EC_HOST_INTERFACE_LPC + bool "LPC" + depends on AP + help + Enable the Low-Pin-Count (LPC) bus. + +config PLATFORM_EC_HOST_INTERFACE_SHI + bool "SPI Host Interface" + depends on AP + help + Enable the SPI Host Interface (SHI). This is a traditional SPI (serial + peripheral interface), where the AP is the SPI controller and the EC + is the SPI peripheral. + +endchoice # PLATFORM_EC_HOST_INTERFACE_TYPE + +endif # PLATFORM_EC_HOSTCMD
\ No newline at end of file diff --git a/zephyr/Kconfig.led b/zephyr/Kconfig.led index 5374d039d1..6e0eeb8aa5 100644 --- a/zephyr/Kconfig.led +++ b/zephyr/Kconfig.led @@ -44,6 +44,96 @@ config PLATFORM_EC_CONSOLE_CMD_LEDTEST ledtest 0 disable +config PLATFORM_EC_LED_PWM_CHARGE_COLOR + int "Battery charging LED color" + default 5 + range 0 5 + help + Configure the color of LED when battery is charging: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + +config PLATFORM_EC_LED_PWM_CHARGE_ERROR_COLOR + int "Charging error LED color" + default 0 + range 0 5 + help + Configure the color of LED when Charging error or battery not present: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + +config PLATFORM_EC_LED_PWM_NEAR_FULL_COLOR + int "Battery almost full LED color" + default 1 + range 0 5 + help + Configure the color of LED when charge battery is almost full: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + +config PLATFORM_EC_LED_PWM_SOC_ON_COLOR + int "AP powered on LED color" + default 1 + range 0 5 + help + Configure the color of LED when AP powered on: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + +config PLATFORM_EC_LED_PWM_SOC_SUSPEND_COLOR + int "AP suspended LED color" + default 1 + range 0 5 + help + Configure the color of LED when AP suspended: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + +config PLATFORM_EC_LED_PWM_LOW_BATT_COLOR + int "Low battery LED color" + default 5 + range 0 5 + help + Configure the color of LED when battery is low: + 0 - EC_LED_COLOR_RED + 1 - EC_LED_COLOR_GREEN + 2 - EC_LED_COLOR_BLUE + 3 - EC_LED_COLOR_YELLOW + 4 - EC_LED_COLOR_WHITE + 5 - EC_LED_COLOR_AMBER + + This value is mapped directly to enum ec_led_colors. + endif # PLATFORM_EC_LED_PWM config PLATFORM_EC_LED_ONOFF_STATES diff --git a/zephyr/Kconfig.motionsense b/zephyr/Kconfig.motionsense index 69980f33da..01a7eb1698 100644 --- a/zephyr/Kconfig.motionsense +++ b/zephyr/Kconfig.motionsense @@ -98,6 +98,7 @@ config PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT config PLATFORM_EC_LID_ANGLE bool "Lid Angle" + select PLATFORM_EC_MATH_UTIL help Enable this to detect lid angle with two accelerometers. The andgle calculation requires the information about which sensor is on the lid @@ -187,12 +188,4 @@ config PLATFORM_EC_CONSOLE_CMD_ACCEL_SPOOF endif # PLATFORM_EC_ACCEL_SPOOF_MODE -config PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL - bool "Disable deferred call that probes motion sensors on boot-up" - help - Disables deferred call that probes motion sensors on boot-up. - If this option is enabled, board logic code must call - board_detect_motionsensor manually. This is useful if board needs - manual control of sensors probing. - rsource "Kconfig.sensor_devices" diff --git a/zephyr/Kconfig.port80 b/zephyr/Kconfig.port80 index b3ff8ab60b..adeea08d20 100644 --- a/zephyr/Kconfig.port80 +++ b/zephyr/Kconfig.port80 @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -if PLATFORM_EC_ESPI +if PLATFORM_EC_HOST_INTERFACE_ESPI config PLATFORM_EC_PORT80_4_BYTE bool "Allow accept 4-byte Port80 codes" @@ -11,4 +11,4 @@ config PLATFORM_EC_PORT80_4_BYTE codes when AP sends 4-byte Port80 codes via eSPI PUT_IOWR_SHORT protocol in a single transaction. -endif # PLATFORM_EC_ESPI +endif # PLATFORM_EC_HOST_INTERFACE_ESPI diff --git a/zephyr/Kconfig.powerseq b/zephyr/Kconfig.powerseq index 27abd68e7c..305fdf74b9 100644 --- a/zephyr/Kconfig.powerseq +++ b/zephyr/Kconfig.powerseq @@ -109,6 +109,16 @@ config PLATFORM_EC_POWERSEQ_S0IX option, Intel's low-power idle sleep state, also known as "modern sleep". +config PLATFORM_EC_POWERSEQ_S4 + bool "Advertise S4 residency" + depends on PLATFORM_EC_ESPI_VW_SLP_S5 + default y if AP_X86_INTEL_TGL + default y if AP_X86_INTEL_ADL + help + Advertise S4 residency capabilities to the AP. This is required for + AP hibernate (suspend-to-disk) on Intel platforms with Key Locker + support (TGL+) + config PLATFORM_EC_POWERSEQ_COMETLAKE bool "Use common Comet Lake code for power sequencing" depends on AP_X86_INTEL_CML @@ -160,6 +170,13 @@ config PLATFORM_EC_POWERSEQ_MT8192 help Use the MT8192 code for power sequencing. +config PLATFORM_EC_POWERSEQ_MT8186 + bool "Use common MT8186 code for power sequencing" + default y + depends on AP_ARM_MTK_MT8186 + help + Use the MT8186 code for power sequencing. + config PLATFORM_EC_POWERSEQ_SC7180 bool "SC7180 power sequencing" depends on AP_ARM_QUALCOMM_SC7180 diff --git a/zephyr/Kconfig.sensor_devices b/zephyr/Kconfig.sensor_devices index 94204b7b35..2d01f41249 100644 --- a/zephyr/Kconfig.sensor_devices +++ b/zephyr/Kconfig.sensor_devices @@ -6,6 +6,7 @@ menu "Sensor Devices" config PLATFORM_EC_ACCELGYRO_BMI bool "Config used to include common accelgyro BMI features" + select PLATFORM_EC_MATH_UTIL help Do not set this directly in a .conf file. This value should be set using an `select` statement in other BMI family of drivers such as @@ -20,6 +21,7 @@ config PLATFORM_EC_ACCELGYRO_ICM config PLATFORM_EC_ACCEL_BMA255 bool "BMA2X2 Accelerometer Family Driver" + select PLATFORM_EC_MATH_UTIL help The driver supports Bosch's a triaxial, low-g acceleration sensor. It allows measurements of acceleration in three perpendicular axes. @@ -52,7 +54,7 @@ config PLATFORM_EC_ACCEL_LIS2DW12_AS_BASE help The LIS2DW driver supports fifo and interrupt, but letting lid accel sensor work at polling mode is a common selection in current usage - model. This option will select interrupt (foced mode). + model. This option will select interrupt (forced mode). config PLATFORM_EC_ACCELGYRO_BMI160 bool "BMI160 Accelgyrometer Driver" @@ -98,6 +100,21 @@ config PLATFORM_EC_ACCELGYRO_ICM42607 The driver supports ICM42607 which provides both accelerometer and gyroscope readings. +config PLATFORM_EC_ACCELGYRO_LSM6DSO + bool "LSM6DSO Accelgyro Driver" + select PLATFORM_EC_STM_MEMS_COMMON + help + The driver supports ST's LSM6DSO 3D digital accelerometer sensor. + It allows measurements of acceleration in three perpendicular axes. + +config PLATFORM_EC_ACCELGYRO_LSM6DSO_AS_BASE + bool "LSM6DSO Interrupt force mode" + depends on PLATFORM_EC_ACCELGYRO_LSM6DSO + help + The LSM6DSO driver supports fifo and interrupt, but letting lid accel + sensor work at polling mode is a common selection in current usage + model. This option will select interrupt (forced mode). + config PLATFORM_EC_STM_MEMS_COMMON bool help diff --git a/zephyr/Kconfig.stacks b/zephyr/Kconfig.stacks index 2ffe64b341..367564de7e 100644 --- a/zephyr/Kconfig.stacks +++ b/zephyr/Kconfig.stacks @@ -107,3 +107,14 @@ config TASK_USB_CHG_STACK_SIZE endif # SOC_SERIES_NPCX9 ############################################################################## + +############################################################################## +if SOC_SERIES_RISCV32_IT8XXX2 + +# Zephyr internal stack sizes + +config SHELL_STACK_SIZE + default 1560 + +endif # SOC_SERIES_RISCV32_IT8XXX2 +############################################################################## diff --git a/zephyr/Kconfig.temperature b/zephyr/Kconfig.temperature index 4af5aa99f8..8affeae907 100644 --- a/zephyr/Kconfig.temperature +++ b/zephyr/Kconfig.temperature @@ -10,6 +10,13 @@ menuconfig PLATFORM_EC_TEMP_SENSOR if PLATFORM_EC_TEMP_SENSOR +config PLATFORM_EC_TEMP_SENSOR_POWER + bool "Temperature sensors are not always powered on" + help + If enabled, temperature sensors require enabling power rail before + being read. Enabling it requires to define a pin enabling the power + as GPIO_TEMP_SENSOR_POWER. + config PLATFORM_EC_DPTF bool "Dynamic Platform and Thermal Framework" default y if PLATFORM_EC_ACPI @@ -31,6 +38,12 @@ config PLATFORM_EC_THERMISTOR Enables support for thermistors (resistor whose resistance is strongly dependent on temperature) as temperature-sensor type. +config PLATFORM_EC_TEMP_SENSOR_TMP112 + bool "TMP112 support" + help + Enables support for the CrosEC TMP112 driver, an i2c peripheral + temperature sensor from TI. + endif # PLATFORM_EC_TEMP_SENSOR diff --git a/zephyr/Kconfig.usbc b/zephyr/Kconfig.usbc index 343de8b4a7..f799a6cb05 100644 --- a/zephyr/Kconfig.usbc +++ b/zephyr/Kconfig.usbc @@ -33,6 +33,7 @@ config PLATFORM_EC_USB_PORT_POWER_DUMB_CUSTOM_HOOK menuconfig PLATFORM_EC_USBC bool "USB Type-C" default y if PLATFORM_EC_BATTERY + depends on PLATFORM_EC_MATH_UTIL help Enable this to support various USB Type-C features chosen by the options below. USB-C is widely used on modern Chromebooks and the EC's @@ -392,9 +393,15 @@ config PLATFORM_EC_USB_PD_VBUS_MEASURE_TCPC config PLATFORM_EC_USB_PD_VBUS_MEASURE_ADC_EACH_PORT bool "VBUS on each port is measured using an ADC channel" help - Enable this is there is a separate ADC channel for each USB-C VBUS + Enable this if there is a separate ADC channel for each USB-C VBUS voltage. +config PLATFORM_EC_USB_PD_VBUS_MEASURE_BY_BOARD + bool "VBUS on each port is measured per board specific" + help + Enable this if there are different VBUS measurement approaches on + the board, and also `board_get_vbus_voltage()` has to be implemented. + endchoice # Measuring VBUS voltage config PLATFORM_EC_USBC_VCONN @@ -450,7 +457,6 @@ config PLATFORM_EC_USB_PD_FRS_PPC config PLATFORM_EC_USB_PD_FRS_TCPC bool "TCPC" - depends on PLATFORM_EC_USBC_TCPC help Enable this if the Fast Role Swap trigger is implemented in the Type-C Port Controller (TCPC). @@ -535,6 +541,14 @@ config PLATFORM_EC_USB_PD_ALT_MODE differential pairs. If all are used for the alternate mode, then USB transmission is not available at all while in this mode. +config PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY + bool "USB Power delivery requires AP to enter alternate modes" + depends on PLATFORM_EC_USB_PD_ALT_MODE + help + 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. + config PLATFORM_EC_USB_PD_ALT_MODE_DFP bool "Downward Facing Port support" default y @@ -585,6 +599,14 @@ config PLATFORM_EC_USB_PD_DP_HPD_GPIO_CUSTOM int svdm_get_hpd_gpio(int port); +config PLATFORM_EC_USB_PD_DATA_RESET_MSG + bool "Enable the PD Data Reset Message." + depends on PLATFORM_EC_USB_PD_REV30 + help + Enable this to support the Data Reset PD message flows. This is + mandatory for products supporting USB4 but optional for other PD 3.0 + products. + choice "VBUS detection method" prompt "Select the method to detect VBUS" @@ -830,6 +852,30 @@ config PLATFORM_EC_USBC_PPC_AOZ1380 provide all the functionality and protection needed for sourcing and sinking current through a USB Type-C port with PD capability. +config PLATFORM_EC_USBC_PPC_RT1718S + bool "Richtek RT1718S TCPC/PPC" + select PLATFORM_EC_USB_PD_TCPM_RT1718S + select PLATFORM_EC_USBC_OCP + select PLATFORM_EC_USBC_PPC_POLARITY + select PLATFORM_EC_USBC_PPC_SBU + select PLATFORM_EC_USBC_PPC_VCONN if PLATFORM_EC_USBC_VCONN + help + RT1718S integrates several high voltage protection switch of + SBU1/SBU2/DP/DM from high voltage VBUS touching the adjacent pins. The + AMR of SBU OVP switch is 24V. High Voltage USB 2.0 Switches also + support HV DCP & fast charging protocols. The GPIOs in RT1718S can + be also configured to control system block such as USB3.0 to DP Mux + for alternated mode usage. VCONN Switch with OVP/OCP/RVP/RCP/UVP + protection is also integrated. + +config PLATFORM_EC_USBC_PPC_KTU1125 + bool "Kinetic KTU1125 Power Path Controller" + select PLATFORM_EC_USBC_OCP + help + KTU1125 integrates power switches to provide a compact protection + solution to USB Type-C applications by eliminating the dependence + on external components. + config PLATFORM_EC_USBC_PPC_NX20P3483 bool "NX20P3483 High Voltage Sink/Source Combo Switch" select PLATFORM_EC_USBC_OCP @@ -870,6 +916,14 @@ config PLATFORM_EC_USBC_PPC_SYV682C rer (to on/off Vconn) when smart discahrge is enabled. This allows us to re-enable the smart discharge on boards using SYV682C. +config PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM + int "SYV682X high-voltage current limit" + depends on PLATFORM_EC_USBC_PPC_SYV682X + default 2 + help + SYV682x PPC high voltage power path current limit. Valid values are + 0 (1.25A), 1 (1.75A), 2 (3.3A), or 3 (5.5A). See syv682x.h. + config PLATFORM_EC_USBC_PPC_SYV682X_NO_CC bool "SYV682X does not pass through CC" help @@ -932,6 +986,7 @@ choice "Type-C Port Manager (TCPM)" config PLATFORM_EC_USB_PD_TCPM_TCPCI bool "Use TCPCI" + select PLATFORM_EC_USBC_OCP help Enable a TCPC compatible with the Type-C Port Controller Interface (TCPCI) Specification. This driver supports both Rev1 v1.2 and Rev2 @@ -946,7 +1001,6 @@ config PLATFORM_EC_USB_PD_TCPM_TCPCI # CONFIG_USB_PD_TCPM_ANX3429 # CONFIG_USB_PD_TCPM_ANX740X # CONFIG_USB_PD_TCPM_ANX741X -# CONFIG_USB_PD_TCPM_ANX7447 # CONFIG_USB_PD_TCPM_ANX7688 # CONFIG_USB_PD_TCPM_MT6370 # CONFIG_USB_PD_TCPM_RAA489000 @@ -1122,6 +1176,40 @@ config PLATFORM_EC_USB_PD_TCPM_MULTI_PS8XXX PS8805_PRODUCT_ID PS8815_PRODUCT_ID +config PLATFORM_EC_USB_PD_TCPM_ANX7447 + bool "Analogix ANX7447 USB-C Gen 2 Type-C Port Controller" + select PLATFORM_EC_USB_PD_TCPM_MUX + help + The Analogix ANX7447 is a USB Type-C Port Controller (TCPC) + for USB Type-C v1.2 Host, USB3.1 Gen2 and DisplayPort applications. + It has an on-chip microcontroller (OCM) to manage the signal + switching. It supports Power Delivery Rev. 3.0 and the DisplayPort + Alt Mode version 1.4a HBR3. + + Supported chips are: + ANX3447 + ANX7447 + +if PLATFORM_EC_USB_PD_TCPM_ANX7447 +config PLATFORM_EC_USB_PD_TCPM_ANX7447_AUX_PU_PD + bool "Enable ANX77447 AUX_N internal PU, and AUX_P internal PD." + depends on PLATFORM_EC_USB_PD_TCPM_ANX7447 + help + Use this config option to enable and internal pullup resistor on the + AUX_N and internal pulldown resistor on the AUX_P line. Only use this + config option if there are no external pu/pd resistors on these + signals. This configuration should be used to avoid noise issues on + the DDI1_AUX_N & DDI1_AUX_P signals (b/122873171) + +config PLATFORM_EC_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND + bool "Enable console command to erase ANX7447 OCM flash" + depends on PLATFORM_EC_USB_PD_TCPM_ANX7447 + help + Adds an EC console command to erase the ANX7447 OCM flash. + Note: this is intended to be a temporary option and won't be needed + when ANX7447 are put on boards with OCM already erased +endif # PLATFORM_EC_USB_PD_TCPM_ANX7447 + config PLATFORM_EC_USB_PD_TCPM_NCT38XX bool "Nuvoton 3807/8 Single/Dual Port Controller with Power Delivery" help @@ -1180,8 +1268,15 @@ config PLATFORM_EC_USB_PD_TCPM_PS8815_FORCE_DID chip version register and force the correct device ID. endif # PLATFORM_EC_USB_PD_TCPM_PS8815 +config PLATFORM_EC_USB_PD_TCPM_RAA489000 + bool "Renesas RAA489000 Type-C port controller and battery charger" + select PLATFORM_EC_USB_PD_PPC + help + Build drivers for the RAA489000, a combined battery charger and USB-C + TCPCI. + config PLATFORM_EC_USB_PD_TCPM_RT1715 - bool "Ricktek RT1715 Type-C Port Controller" + bool "Richtek RT1715 Type-C Port Controller" help The RT1715 is a USB Type-C controller, integrating a complete Type-C Transceiver including the Rp and Rd resistors. It does the USB Type-C @@ -1190,6 +1285,16 @@ config PLATFORM_EC_USB_PD_TCPM_RT1715 100W of power and role swap. The BMC PD block enables full support for alternative interfaces of the Type-C specification. +config PLATFORM_EC_USB_PD_TCPM_RT1718S + bool "Richtek RT1718S Type-C Port Controller" + select PLATFORM_EC_USBC_PPC_RT17182S + help + The RT1718S is an integrated USB Type-C TCPC controller which + includes IEC-61000-4-2 ESD protection cell for CC/SBU/DP/DM. + High voltage USB 2.0 switches also support HV DCP & fast charging + protocols. RT1718S supports TCPC Version 1.2, and Battery Charging + version 1.2 (BC1.2). + config PLATFORM_EC_USB_PD_TCPM_TUSB422 bool "TI TUSB422 Port Control with USB PD" help @@ -1241,6 +1346,14 @@ config PLATFORM_EC_USB_PD_TCPM_DRIVER_IT8XXX2 endif # PLATFORM_EC_USBC_PPC +config PLATFORM_EC_USB_PD_PULLUP + int "Default source Rp value" + default 1 + help + Default pull-up value on the USB-C ports when they are used as source. + Valid values are 0 (USB default current), 1 (1.5A), and 2 (3.0A). See + enum tcpc_rp_value. + config PLATFORM_EC_USB_PD_ONLY_FIXED_PDOS bool "Only support FIXED type PDOs" help diff --git a/zephyr/app/ec/ec_app_main.c b/zephyr/app/ec/ec_app_main.c index 7cc5b170f1..0aa95502ce 100644 --- a/zephyr/app/ec/ec_app_main.c +++ b/zephyr/app/ec/ec_app_main.c @@ -61,7 +61,7 @@ void ec_app_main(void) button_init(); } - if (IS_ENABLED(CONFIG_PLATFORM_EC_ESPI)) { + if (IS_ENABLED(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI)) { if (zephyr_shim_setup_espi() < 0) { printk("Failed to init eSPI!\n"); } diff --git a/zephyr/app/ec/soc/Kconfig b/zephyr/app/ec/soc/Kconfig index d7befb39b7..1fd4e26e16 100644 --- a/zephyr/app/ec/soc/Kconfig +++ b/zephyr/app/ec/soc/Kconfig @@ -1,3 +1,7 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + menuconfig AP bool "Enable AP SoC support code" default y @@ -40,6 +44,12 @@ config AP_ARM_MTK_MT8192 help The application processor is a MediaTek MT8192 processor. +config AP_ARM_MTK_MT8186 + bool "MediaTek MT8186" + select AP_AARCH64 + help + The application processor is a MediaTek MT8186 processor. + config AP_ARM_QUALCOMM_SC7180 bool "Qualcomm Snapdragon SC7180" select AP_AARCH64 diff --git a/zephyr/boards/arm/brya/brya.dts b/zephyr/boards/arm/brya/brya.dts index 33f014981b..02dfee6d1c 100644 --- a/zephyr/boards/arm/brya/brya.dts +++ b/zephyr/boards/arm/brya/brya.dts @@ -18,6 +18,7 @@ zephyr,console = &uart1; zephyr,shell-uart = &uart1; zephyr,flash = &flash0; + cros,rtc = &mtc; }; named-i2c-ports { @@ -25,47 +26,42 @@ i2c_sensor: sensor { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; tcpc0_2 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_USB_C0_C2_TCPC"; - label = "TCPC0,2"; }; tcpc1 { i2c-port = <&i2c4_1>; enum-name = "I2C_PORT_USB_C1_TCPC"; - label = "TCPC1"; }; ppc0_2 { i2c-port = <&i2c2_0>; enum-name = "I2C_PORT_USB_C0_C2_PPC"; - label = "PPC0,2"; }; ppc1 { i2c-port = <&i2c6_1>; enum-name = "I2C_PORT_USB_C1_PPC"; - label = "PPC1"; }; retimer0_2 { i2c-port = <&i2c3_0>; enum-name = "I2C_PORT_USB_C0_C2_MUX"; - label = "RETIMER0,2"; }; battery { i2c-port = <&i2c5_0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; eeprom { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; charger { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_CHARGER"; - label = "EEPROM"; + }; + mp2964 { + i2c-port = <&i2c7_0>; + enum-name = "I2C_PORT_MP2964"; }; }; @@ -100,7 +96,7 @@ named-temp-sensors { ddr_soc { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "DDR and SOC"; enum-name = "TEMP_SENSOR_1_DDR_SOC"; @@ -112,7 +108,7 @@ adc = <&adc_ddr_soc>; }; ambient { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "Ambient"; enum-name = "TEMP_SENSOR_2_AMBIENT"; @@ -124,7 +120,7 @@ adc = <&adc_ambient>; }; charger { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "Charger"; enum-name = "TEMP_SENSOR_3_CHARGER"; @@ -136,7 +132,7 @@ adc = <&adc_charger>; }; wwan { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "WWAN"; enum-name = "TEMP_SENSOR_4_WWAN"; @@ -149,6 +145,11 @@ }; }; + vsby-psl-in-list { + /* Use PSL_IN1/2/3 as detection pins from hibernate mode */ + psl-in-pads = <&psl_in1 &psl_in2 &psl_in3>; + }; + def-lvol-io-list { compatible = "nuvoton,npcx-lvolctrl-def"; }; @@ -226,6 +227,12 @@ &i2c7_0 { status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; + + pmic_mp2964: pmic_mp2964@20 { + compatible = "mps,mp2964"; + reg = <0x20>; + label = "I2C_ADDR_MP2964_FLAGS"; + }; }; &i2c_ctrl7 { @@ -264,6 +271,22 @@ status = "okay"; }; +/* Power switch logic input pads */ +/* LID_OPEN_OD */ +&psl_in1 { + flag = <NPCX_PSL_RISING_EDGE>; +}; + +/* ACOK_EC_OD */ +&psl_in2 { + flag = <NPCX_PSL_RISING_EDGE>; +}; + +/* GSC_EC_PWR_BTN_ODL */ +&psl_in3 { + flag = <NPCX_PSL_FALLING_EDGE>; +}; + &thermistor_3V3_30K9_47K_4050B { status = "okay"; }; diff --git a/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9.dts b/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9.dts index cdf998c13f..2103b59c1d 100644 --- a/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9.dts +++ b/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9.dts @@ -50,14 +50,12 @@ named-pwms { compatible = "named-pwms"; - kblight: kblight { + kblight: kb_bl_pwm { pwms = <&pwm3 0 0>; - label = "KBLIGHT"; frequency = <10000>; }; - displight: displight { + displight: ecl_bl_pwm_r { pwms = <&pwm5 0 0>; - label = "DISPLIGHT"; frequency = <4800>; }; }; @@ -66,14 +64,14 @@ compatible = "named-adc-channels"; vbus { - label = "ADC_VBUS"; + label = "VBUS"; enum-name = "ADC_VBUS"; channel = <1>; /* Measure VBUS through a 1/10 voltage divider */ mul = <10>; }; amon_bmon { - label = "ADC_AMON_BMON"; + label = "AMON_BMON"; enum-name = "ADC_AMON_BMON"; channel = <2>; /* @@ -85,7 +83,7 @@ div = <18>; }; psys { - label = "ADC_PSYS"; + label = "PSYS"; enum-name = "ADC_PSYS"; channel = <3>; /* diff --git a/zephyr/boards/arm/npcx9/npcx9.dts b/zephyr/boards/arm/npcx9/npcx9.dts index ab44d8119e..143cdf8926 100644 --- a/zephyr/boards/arm/npcx9/npcx9.dts +++ b/zephyr/boards/arm/npcx9/npcx9.dts @@ -6,9 +6,7 @@ /dts-v1/; #include <cros/nuvoton/npcx9.dtsi> -#include <dt-bindings/adc/adc.h> #include <dt-bindings/gpio_defines.h> -#include <dt-bindings/wake_mask_event_defines.h> #include <nuvoton/npcx9m3f.dtsi> / { @@ -32,51 +30,6 @@ named-i2c-ports { compatible = "named-i2c-ports"; - i2c_sensor: sensor { - i2c-port = <&i2c0_0>; - enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; - }; - tcpc0_2 { - i2c-port = <&i2c1_0>; - enum-name = "I2C_PORT_USB_C0_C2_TCPC"; - label = "TCPC0,2"; - }; - tcpc1 { - i2c-port = <&i2c4_1>; - enum-name = "I2C_PORT_USB_C1_TCPC"; - label = "TCPC1"; - }; - ppc0_2 { - i2c-port = <&i2c2_0>; - enum-name = "I2C_PORT_USB_C0_C2_PPC"; - label = "PPC0,2"; - }; - ppc1 { - i2c-port = <&i2c6_1>; - enum-name = "I2C_PORT_USB_C1_PPC"; - label = "PPC1"; - }; - retimer0_2 { - i2c-port = <&i2c3_0>; - enum-name = "I2C_PORT_USB_C0_C2_MUX"; - label = "RETIMER0,2"; - }; - battery { - i2c-port = <&i2c5_0>; - enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; - }; - eeprom { - i2c-port = <&i2c7_0>; - enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; - }; - charger { - i2c-port = <&i2c7_0>; - enum-name = "I2C_PORT_CHARGER"; - label = "EEPROM"; - }; }; named-pwms { @@ -98,78 +51,6 @@ pinctrl-0 = <&altj_cr_sin1_sl2 &altj_cr_sout1_sl2>; }; -&i2c0_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST>; -}; - -&i2c_ctrl0 { - status = "okay"; -}; - -&i2c1_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST_PLUS>; -}; - -&i2c_ctrl1 { - status = "okay"; -}; - -&i2c2_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST_PLUS>; -}; - -&i2c_ctrl2 { - status = "okay"; -}; - -&i2c3_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST_PLUS>; -}; - -&i2c_ctrl3 { - status = "okay"; -}; - -&i2c4_1 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST>; -}; - -&i2c_ctrl4 { - status = "okay"; -}; - -&i2c5_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_STANDARD>; -}; - -&i2c_ctrl5 { - status = "okay"; -}; - -&i2c6_1 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST>; -}; - -&i2c_ctrl6 { - status = "okay"; -}; - -&i2c7_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_FAST>; -}; - -&i2c_ctrl7 { - status = "okay"; -}; - &cros_kb_raw { status = "okay"; /* No KSO2 (it's inverted and implemented by GPIO) */ diff --git a/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi index 61a1e79783..4995cd8af3 100644 --- a/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi +++ b/zephyr/boards/arm/npcx_evb/npcx_evb.dtsi @@ -22,27 +22,22 @@ i2c_evb_0_0 { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_EVB_0"; - label = "I2C0_0"; }; i2c_evb_1_0 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_EVB_1"; - label = "I2C1_0"; }; i2c_evb_2_0 { i2c-port = <&i2c2_0>; enum-name = "I2C_PORT_EVB_2"; - label = "I2C2_0"; }; i2c_evb_3_0 { i2c-port = <&i2c3_0>; enum-name = "I2C_PORT_EVB_3"; - label = "I2C3_0"; }; i2c_evb_7_0 { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_EVB_7"; - label = "I2C7_0"; }; }; diff --git a/zephyr/boards/arm/trogdor/trogdor.dts b/zephyr/boards/arm/trogdor/trogdor.dts index a13861ad09..3b9c6178e8 100644 --- a/zephyr/boards/arm/trogdor/trogdor.dts +++ b/zephyr/boards/arm/trogdor/trogdor.dts @@ -63,62 +63,51 @@ power { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_POWER"; - label = "POWER"; }; battery { i2c-port = <&i2c0_0>; remote-port = <0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; virtual-battery { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_VIRTUAL_BATTERY"; - label = "VIRTUAL"; }; charger { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; tcpc0 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_TCPC0"; - label = "TCPC0"; }; tcpc1 { i2c-port = <&i2c2_0>; enum-name = "I2C_PORT_TCPC1"; - label = "TCPC1"; }; eeprom { i2c-port = <&i2c5_0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; i2c_sensor: sensor { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; accel { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; }; named-pwms { compatible = "named-pwms"; - kblight: kblight { + kblight: kb_bl_pwm { pwms = <&pwm3 0 0>; - label = "KBLIGHT"; frequency = <10000>; }; - displight: displight { + displight: edp_bkltctl { pwms = <&pwm5 0 0>; - label = "DISPLIGHT"; frequency = <4800>; }; }; @@ -127,14 +116,14 @@ compatible = "named-adc-channels"; vbus { - label = "ADC_VBUS"; + label = "VBUS"; enum-name = "ADC_VBUS"; channel = <1>; /* Measure VBUS through a 1/10 voltage divider */ mul = <10>; }; amon_bmon { - label = "ADC_AMON_BMON"; + label = "AMON_BMON"; enum-name = "ADC_AMON_BMON"; channel = <2>; /* @@ -146,7 +135,7 @@ div = <18>; }; psys { - label = "ADC_PSYS"; + label = "PSYS"; enum-name = "ADC_PSYS"; channel = <3>; /* diff --git a/zephyr/boards/arm/volteer/volteer.dts b/zephyr/boards/arm/volteer/volteer.dts index f25363f03f..79d08170af 100644 --- a/zephyr/boards/arm/volteer/volteer.dts +++ b/zephyr/boards/arm/volteer/volteer.dts @@ -53,48 +53,39 @@ i2c_sensor: sensor { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; i2c-accel { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; i2c_usb_c0: usb-c0 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_USB_C0"; - label = "USB_C0"; }; i2c_usb_c1: usb-c1 { i2c-port = <&i2c2_0>; enum-name = "I2C_PORT_USB_C1"; - label = "USB_C1"; }; usb1-mix { i2c-port = <&i2c3_0>; enum-name = "I2C_PORT_USB_1_MIX"; - label = "USB_1_MIX"; }; power { i2c-port = <&i2c5_0>; enum-name = "I2C_PORT_POWER"; - label = "POWER"; }; battery { i2c-port = <&i2c5_0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; eeprom { i2c-port = <&i2c7_0>; remote-port = <7>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; charger { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; }; @@ -102,22 +93,22 @@ compatible = "named-adc-channels"; adc_charger: charger { - label = "ADC_TEMP_SENSOR_CHARGER"; + label = "TEMP_CHARGER"; enum-name = "ADC_TEMP_SENSOR_CHARGER"; channel = <0>; }; adc_pp3300_regulator: pp3300_regulator { - label = "ADC_TEMP_SENSOR_PP3300_REGULATOR"; + label = "TEMP_PP3300_REGULATOR"; enum-name = "ADC_TEMP_SENSOR_PP3300_REGULATOR"; channel = <1>; }; adc_ddr_soc: ddr_soc { - label = "ADC_TEMP_SENSOR_DDR_SOC"; + label = "TEMP_DDR_SOC"; enum-name = "ADC_TEMP_SENSOR_DDR_SOC"; channel = <8>; }; adc_fan: fan { - label = "ADC_TEMP_SENSOR_FAN"; + label = "TEMP_FAN"; enum-name = "ADC_TEMP_SENSOR_FAN"; channel = <3>; }; @@ -125,7 +116,7 @@ named-temp-sensors { charger { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "TEMP_SENSOR_CHARGER"; enum-name = "TEMP_SENSOR_CHARGER"; @@ -137,7 +128,7 @@ adc = <&adc_charger>; }; pp3300_regulator { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "TEMP_SENSOR_PP3300_REGULATOR"; enum-name = "TEMP_SENSOR_PP3300_REGULATOR"; @@ -149,7 +140,7 @@ adc = <&adc_pp3300_regulator>; }; ddr_soc { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "TEMP_SENSOR_DDR_SOC"; enum-name = "TEMP_SENSOR_DDR_SOC"; @@ -161,7 +152,7 @@ adc = <&adc_ddr_soc>; }; fan { - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; thermistor = <&thermistor_3V3_30K9_47K_4050B>; label = "TEMP_SENSOR_FAN"; enum-name = "TEMP_SENSOR_FAN"; diff --git a/zephyr/boards/riscv/asurada/Kconfig.defconfig b/zephyr/boards/riscv/asurada/Kconfig.defconfig index e76e1cb2d1..463b0c30f3 100644 --- a/zephyr/boards/riscv/asurada/Kconfig.defconfig +++ b/zephyr/boards/riscv/asurada/Kconfig.defconfig @@ -15,9 +15,6 @@ config IDLE_STACK_SIZE config ISR_STACK_SIZE default 800 -config SHELL_STACK_SIZE - default 1048 - config SYSTEM_WORKQUEUE_STACK_SIZE default 1024 diff --git a/zephyr/boards/riscv/asurada/asurada.dts b/zephyr/boards/riscv/asurada/asurada.dts index 8dc3c2abb7..9b8cf91283 100644 --- a/zephyr/boards/riscv/asurada/asurada.dts +++ b/zephyr/boards/riscv/asurada/asurada.dts @@ -43,41 +43,41 @@ compatible = "named-adc-channels"; adc_vbus_c0 { - label = "ADC_VBUS_C0"; + label = "VBUS_C0"; enum-name = "ADC_VBUS_C0"; channel = <0>; mul = <10>; }; adc_board_id0 { - label = "ADC_BOARD_ID_0"; + label = "BOARD_ID_0"; enum-name = "ADC_BOARD_ID_0"; channel = <1>; }; adc_board_id1 { - label = "ADC_BOARD_ID_1"; + label = "BOARD_ID_1"; enum-name = "ADC_BOARD_ID_1"; channel = <2>; }; adc_charger_amon_r { - label = "ADC_AMON_BMON"; + label = "AMON_BMON"; enum-name = "ADC_AMON_BMON"; channel = <3>; mul = <1000>; div = <18>; }; adc_vbus_c1 { - label = "ADC_VBUS_C1"; + label = "VBUS_C1"; enum-name = "ADC_VBUS_C1"; channel = <5>; mul = <10>; }; adc_charger_pmon { - label = "ADC_PMON"; + label = "PMON"; enum-name = "ADC_PMON"; channel = <6>; }; adc-psys { - label = "ADC_PSYS"; + label = "PSYS"; enum-name = "ADC_PSYS"; channel = <6>; }; @@ -89,81 +89,55 @@ power { i2c-port = <&i2c0>; enum-name = "I2C_PORT_POWER"; - label = "POWER"; }; battery { i2c-port = <&i2c0>; remote-port = <0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; virtual-battery { i2c-port = <&i2c0>; enum-name = "I2C_PORT_VIRTUAL_BATTERY"; - label = "VIRTUAL_BATTERY"; }; eeprom { i2c-port = <&i2c0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; charger { i2c-port = <&i2c0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; i2c_sensor: sensor { i2c-port = <&i2c1>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; i2c-accel { i2c-port = <&i2c1>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; ppc0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_PPC0"; - label = "PPC0"; }; ppc1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_PPC1"; - label = "PPC1"; }; usb-c0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_C0"; - label = "USB_C0"; }; usb-c1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_C1"; - label = "USB_C1"; }; usb-mux0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_MUX0"; - label = "USB_MUX0"; }; usb-mux1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_MUX1"; - label = "USB_MUX1"; - }; - }; - - soc { - /delete-node/ kscan@f01d00; - - cros_kb_raw: cros-kb-raw@f01d00 { - compatible = "ite,it8xxx2-cros-kb-raw"; - reg = <0x00f01d00 0x29>; - label = "CROS_KB_RAW_0"; - interrupt-parent = <&intc>; - interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; }; }; }; @@ -174,6 +148,10 @@ clock-frequency = <1804800>; }; +&ite_uart1_wrapper { + status = "okay"; +}; + &adc0 { status = "okay"; }; diff --git a/zephyr/boards/riscv/asurada/asurada_defconfig b/zephyr/boards/riscv/asurada/asurada_defconfig index 60c04020f7..c5a3d306fa 100644 --- a/zephyr/boards/riscv/asurada/asurada_defconfig +++ b/zephyr/boards/riscv/asurada/asurada_defconfig @@ -40,6 +40,9 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y CONFIG_PLATFORM_EC_FLASH_CROS=y CONFIG_SOC_FLASH_ITE_IT8XXX2=y +# Hook tick +CONFIG_CROS_EC_HOOK_TICK_INTERVAL=500000 + # I2C CONFIG_I2C_ITE_IT8XXX2=y CONFIG_PLATFORM_EC_I2C=y @@ -64,6 +67,11 @@ CONFIG_PINMUX_ITE_IT8XXX2=y # Power Button CONFIG_PLATFORM_EC_POWER_BUTTON=y +# Power Management +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_POLICY_APP=y + # Power Sequencing CONFIG_PLATFORM_EC_POWERSEQ=y CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y @@ -81,9 +89,6 @@ CONFIG_PWM_ITE_IT8XXX2=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y -# Serial Host Interface (SHI) device. -CONFIG_CROS_SHI_IT8XXX2=y - # Timer configuration CONFIG_ITE_IT8XXX2_TIMER=y diff --git a/zephyr/boards/riscv/it8xxx2/Kconfig.defconfig b/zephyr/boards/riscv/it8xxx2/Kconfig.defconfig index 875969c7e4..1b1472dfe1 100644 --- a/zephyr/boards/riscv/it8xxx2/Kconfig.defconfig +++ b/zephyr/boards/riscv/it8xxx2/Kconfig.defconfig @@ -15,9 +15,6 @@ config IDLE_STACK_SIZE config ISR_STACK_SIZE default 800 -config SHELL_STACK_SIZE - default 1048 - config SYSTEM_WORKQUEUE_STACK_SIZE default 1024 diff --git a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts index 2a2cd2539d..7673872dfc 100644 --- a/zephyr/boards/riscv/it8xxx2/it8xxx2.dts +++ b/zephyr/boards/riscv/it8xxx2/it8xxx2.dts @@ -5,10 +5,9 @@ /dts-v1/; -#include <cros/ite/it8xxx2.dtsi> #include <dt-bindings/gpio_defines.h> +#include <cros/ite/it8xxx2.dtsi> #include <it8xxx2.dtsi> -#include <dt-bindings/wake_mask_event_defines.h> / { model = "Google IT8XXX2 Baseboard"; @@ -21,33 +20,15 @@ zephyr,flash-controller = &flashctrl; }; - ec-mkbp-host-event-wakeup-mask { - compatible = "ec-wake-mask-event"; - wakeup-mask = <( - HOST_EVENT_MASK(HOST_EVENT_AC_CONNECTED) | - HOST_EVENT_MASK(HOST_EVENT_AC_DISCONNECTED) | - HOST_EVENT_MASK(HOST_EVENT_LID_OPEN) | - HOST_EVENT_MASK(HOST_EVENT_POWER_BUTTON) | - HOST_EVENT_MASK(HOST_EVENT_HANG_DETECT) | - HOST_EVENT_MASK(HOST_EVENT_MODE_CHANGE))>; - }; - - ec-mkbp-event-wakeup-mask { - compatible = "ec-wake-mask-event"; - wakeup-mask = <(MKBP_EVENT_KEY_MATRIX | - MKBP_EVENT_HOST_EVENT)>; - }; - + /* Override keyboard scanning */ soc { /delete-node/ kscan@f01d00; cros_kb_raw: cros-kb-raw@f01d00 { compatible = "ite,it8xxx2-cros-kb-raw"; reg = <0x00f01d00 0x29>; - label = "CROS_KB_RAW_0"; interrupt-parent = <&intc>; interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; }; }; }; @@ -58,6 +39,10 @@ clock-frequency = <1804800>; }; -&cros_kb_raw { +&ite_uart1_wrapper { status = "okay"; }; + +&cros_kb_raw { + status = "okay"; /* Override in project dts if not required */ +}; diff --git a/zephyr/boards/riscv/it8xxx2/it8xxx2_defconfig b/zephyr/boards/riscv/it8xxx2/it8xxx2_defconfig index b0a2db9686..252abf0972 100644 --- a/zephyr/boards/riscv/it8xxx2/it8xxx2_defconfig +++ b/zephyr/boards/riscv/it8xxx2/it8xxx2_defconfig @@ -9,10 +9,6 @@ CONFIG_SOC_IT8XXX2=y # Platform Configuration CONFIG_BOARD_IT8XXX2=y -# SoC configuration -CONFIG_AP=y -CONFIG_AP_ARM_MTK_MT8192=y - # Console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y @@ -35,6 +31,9 @@ CONFIG_CLOCK_CONTROL=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32768 CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 +# Hook tick +CONFIG_CROS_EC_HOOK_TICK_INTERVAL=500000 + # Flash CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y CONFIG_PLATFORM_EC_FLASH_CROS=y @@ -44,19 +43,6 @@ CONFIG_SOC_FLASH_ITE_IT8XXX2=y CONFIG_I2C_ITE_IT8XXX2=y CONFIG_PLATFORM_EC_I2C=y -# Keyboard -CONFIG_PLATFORM_EC_KEYBOARD=y -CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y - -# Lid Switch -CONFIG_PLATFORM_EC_LID_SWITCH=y - -# MKBP -CONFIG_PLATFORM_EC_MKBP_EVENT=y -CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y -CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=y -CONFIG_PLATFORM_EC_MKBP_USE_GPIO=y - # Pinmux Driver CONFIG_PINMUX=y CONFIG_PINMUX_ITE_IT8XXX2=y @@ -64,13 +50,6 @@ CONFIG_PINMUX_ITE_IT8XXX2=y # Power Button CONFIG_PLATFORM_EC_POWER_BUTTON=y -# Power Sequencing -CONFIG_PLATFORM_EC_POWERSEQ=y -CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y -CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n -CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y -CONFIG_PLATFORM_EC_CHIPSET_RESET_HOOK=y - # PWM CONFIG_PWM=y CONFIG_PWM_SHELL=n @@ -81,9 +60,6 @@ CONFIG_PWM_ITE_IT8XXX2=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y -# Serial Host Interface (SHI) device. -CONFIG_CROS_SHI_IT8XXX2=y - # Timer configuration CONFIG_ITE_IT8XXX2_TIMER=y diff --git a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index a1b61d02ec..52ee525eae 100644 --- a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -26,103 +26,67 @@ power_button_l: power_button_l { gpios = <&gpioe 4 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "POWER_BUTTON_L"; }; lid_open: lid_open { gpios = <&gpioe 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; wp_l { gpios = <&gpioi 4 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_WP_L"; - label = "WP_L"; }; pch_pltrst_l { gpios = <&gpioe 3 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_PCH_RSMRST_L"; - label = "PCH_PLTRST_L"; }; uart1_rx { gpios = <&gpiob 0 GPIO_INPUT_PULL_UP>; #enum-name = "GPIO_UART1_RX"; - label = "UART1_RX"; - }; - pch_smi_l { - gpios = <&gpiod 3 GPIO_OUT_HIGH>; - #enum-name = "GPIO_PCH_SMI_L"; - label = "PCH_SMI_L"; - }; - pch_sci_l { - gpios = <&gpiod 4 GPIO_OUT_HIGH>; - #enum-name = "GPIO_PCH_SCI_L"; - label = "PCH_SCI_L"; - }; - gate_a20_h { - gpios = <&gpiob 5 GPIO_OUT_HIGH>; - #enum-name = "GPIO_GATE_A20_H"; - label = "GATE_A20_H"; }; sys_reset_l { gpios = <&gpiob 6 GPIO_OUT_HIGH>; enum-name = "GPIO_SYS_RESET_L"; - label = "SYS_RESET_L"; - }; - lpc_clkrun_l { - gpios = <&gpioh 0 GPIO_OUT_LOW>; - #enum-name = "GPIO_LPC_CLKRUN_L"; - label = "LPC_CLKRUN_L"; }; pch_wake_l { gpios = <&gpiob 7 GPIO_OUT_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "PCH_WAKE_L"; }; i2c_a_scl { gpios = <&gpiob 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SCL"; - label = "I2C_A_SCL"; }; i2c_a_sda { gpios = <&gpiob 4 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SDA"; - label = "I2C_A_SDA"; }; i2c_b_scl { gpios = <&gpioc 1 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SCL"; - label = "I2C_B_SCL"; }; i2c_b_sda { gpios = <&gpioc 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SDA"; - label = "I2C_B_SDA"; }; i2c_c_scl { gpios = <&gpiof 6 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SCL"; - label = "I2C_C_SCL"; }; i2c_c_sda { gpios = <&gpiof 7 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SDA"; - label = "I2C_C_SDA"; }; i2c_e_scl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SCL"; - label = "I2C_E_SCL"; }; i2c_e_sda { gpios = <&gpioe 7 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SDA"; - label = "I2C_E_SDA"; }; spi0_cs { gpios = <&gpiom 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_SPI0_CS"; - label = "SPI0_CS"; }; }; @@ -173,43 +137,167 @@ battery { i2c-port = <&i2c2>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; evb-1 { i2c-port = <&i2c0>; enum-name = "I2C_PORT_EVB_1"; - label = "EVB_1"; }; evb-2 { i2c-port = <&i2c1>; enum-name = "I2C_PORT_EVB_2"; - label = "EVB_2"; }; opt-4 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_OPT_4"; - label = "OPT_4"; }; }; named-pwms { compatible = "named-pwms"; + /* NOTE: &pwm number needs same with channel number */ - test0 { - pwms = <&pwm7 PWM_CHANNEL_7 PWM_POLARITY_INVERTED>; - label = "TEST0"; + pwm_test: test { + pwms = <&pwm0 PWM_CHANNEL_0 PWM_POLARITY_NORMAL>; /* * If we need pwm output in ITE chip power saving * mode, then we should set frequency <=324Hz. */ frequency = <324>; }; - test1 { - pwms = <&pwm0 PWM_CHANNEL_0 PWM_POLARITY_NORMAL>; - label = "TEST1"; + pwm_fan: fan { + pwms = <&pwm7 PWM_CHANNEL_7 PWM_POLARITY_NORMAL>; frequency = <30000>; }; }; + + named-fans { + compatible = "named-fans"; + + fan_0 { + label = "FAN_0"; + pwm = <&pwm_fan>; + tach = <&tach0>; + rpm_min = <1500>; + rpm_start = <1500>; + rpm_max = <6500>; + }; + }; + + unused-pins { + compatible = "unused-gpios"; + + unused-gpios = + /* gpioa1 */ + <&gpioa 1 GPIO_INPUT_PULL_DOWN>, + /* gpioa2 */ + <&gpioa 2 GPIO_INPUT_PULL_DOWN>, + /* gpioa3 */ + <&gpioa 3 GPIO_INPUT_PULL_DOWN>, + /* gpioa4 */ + <&gpioa 4 GPIO_INPUT_PULL_DOWN>, + /* gpioa5 */ + <&gpioa 5 GPIO_INPUT_PULL_DOWN>, + + /* gpiob2 */ + <&gpiob 2 GPIO_INPUT_PULL_DOWN>, + /* gpiob5 */ + <&gpiob 5 GPIO_INPUT_PULL_DOWN>, + + /* gpioc0 */ + <&gpioc 0 GPIO_INPUT_PULL_DOWN>, + /* gpioc4 */ + <&gpioc 4 GPIO_INPUT_PULL_DOWN>, + /* gpioc6 */ + <&gpioc 6 GPIO_INPUT_PULL_DOWN>, + /* gpioc7 */ + <&gpioc 7 GPIO_INPUT_PULL_DOWN>, + + /* gpiod0 */ + <&gpiod 0 GPIO_INPUT_PULL_DOWN>, + /* gpiod1 */ + <&gpiod 1 GPIO_INPUT_PULL_DOWN>, + /* gpiod2 */ + <&gpiod 2 GPIO_INPUT_PULL_DOWN>, + /* gpiod3 */ + <&gpiod 3 GPIO_INPUT_PULL_DOWN>, + /* gpiod4 */ + <&gpiod 4 GPIO_INPUT_PULL_DOWN>, + /* gpiod5 */ + <&gpiod 5 GPIO_INPUT_PULL_DOWN>, + /* gpiod7 */ + <&gpiod 7 GPIO_INPUT_PULL_DOWN>, + + /* gpioe1 */ + <&gpioe 1 GPIO_INPUT_PULL_DOWN>, + /* gpioe5 */ + <&gpioe 5 GPIO_INPUT_PULL_DOWN>, + /* gpioe6 */ + <&gpioe 6 GPIO_INPUT_PULL_DOWN>, + + /* gpiof0 */ + <&gpiof 0 GPIO_INPUT_PULL_DOWN>, + /* gpiof1 */ + <&gpiof 1 GPIO_INPUT_PULL_DOWN>, + /* gpiof2 */ + <&gpiof 2 GPIO_INPUT_PULL_DOWN>, + /* gpiof3 */ + <&gpiof 3 GPIO_INPUT_PULL_DOWN>, + /* gpiof4 */ + <&gpiof 4 GPIO_INPUT_PULL_DOWN>, + /* gpiof5 */ + <&gpiof 5 GPIO_INPUT_PULL_DOWN>, + + /* gpiog1 */ + <&gpiog 1 GPIO_INPUT_PULL_DOWN>, + /* gpiog6 */ + <&gpiog 6 GPIO_INPUT_PULL_UP>, + + /* gpioh0 */ + <&gpioh 0 GPIO_INPUT_PULL_DOWN>, + /* gpioh3 */ + <&gpioh 3 GPIO_INPUT_PULL_DOWN>, + /* gpioh4 */ + <&gpioh 4 GPIO_INPUT_PULL_DOWN>, + /* gpioh5 */ + <&gpioh 5 GPIO_INPUT_PULL_DOWN>, + /* gpioh6 */ + <&gpioh 6 GPIO_INPUT_PULL_DOWN>, + + /* gpioi6 */ + <&gpioi 6 GPIO_INPUT_PULL_DOWN>, + /* gpioi7 */ + <&gpioi 7 GPIO_INPUT_PULL_DOWN>, + + /* gpioj0 */ + <&gpioj 0 GPIO_INPUT_PULL_DOWN>, + /* gpioj1 */ + <&gpioj 1 GPIO_INPUT_PULL_DOWN>, + /* gpioj2 */ + <&gpioj 2 GPIO_INPUT_PULL_DOWN>, + /* gpioj3 */ + <&gpioj 3 GPIO_INPUT_PULL_DOWN>, + /* gpioj4 */ + <&gpioj 4 GPIO_INPUT_PULL_DOWN>, + /* gpioj5 */ + <&gpioj 5 GPIO_INPUT_PULL_DOWN>, + /* gpioj6 */ + <&gpioj 6 GPIO_OUT_LOW>, + /* gpioj7 */ + <&gpioj 7 GPIO_OUT_LOW>, + + /* gpiom0 */ + <&gpiom 0 GPIO_INPUT_PULL_DOWN>, + /* gpiom1 */ + <&gpiom 1 GPIO_INPUT_PULL_DOWN>, + /* gpiom2 */ + <&gpiom 2 GPIO_INPUT_PULL_DOWN>, + /* gpiom3 */ + <&gpiom 3 GPIO_INPUT_PULL_DOWN>, + /* gpiom4 */ + <&gpiom 4 GPIO_INPUT_PULL_DOWN>, + /* gpiom6 */ + <&gpiom 6 GPIO_INPUT_PULL_DOWN>; + }; }; &adc0 { @@ -242,14 +330,25 @@ clock-frequency = <1804800>; }; -/* TEST1 */ +&ite_uart1_wrapper { + status = "okay"; +}; + +/* pwm for test */ &pwm0 { status = "okay"; prescaler-cx = <PWM_PRESCALER_C6>; }; -/* TEST0 */ +/* pwm for fan */ &pwm7 { status = "okay"; prescaler-cx = <PWM_PRESCALER_C4>; }; + +/* fan tachometer sensor */ +&tach0 { + status = "okay"; + channel = <IT8XXX2_TACH_CHANNEL_A>; + pulses-per-round = <2>; +}; diff --git a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig index d667fac5a1..a85e6fd500 100644 --- a/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig +++ b/zephyr/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig @@ -31,6 +31,9 @@ CONFIG_PWM_SHELL=n CONFIG_PLATFORM_EC_PWM=y CONFIG_PWM_ITE_IT8XXX2=y +# Fan +CONFIG_SENSOR=y + # GPIO Controller CONFIG_GPIO=y CONFIG_GPIO_ITE_IT8XXX2=y @@ -42,6 +45,9 @@ CONFIG_CLOCK_CONTROL=y CONFIG_WATCHDOG=y CONFIG_WDT_ITE_WARNING_LEADING_TIME_MS=500 +# Hook tick +CONFIG_CROS_EC_HOOK_TICK_INTERVAL=500000 + # I2C Controller CONFIG_I2C_ITE_IT8XXX2=y @@ -58,6 +64,11 @@ CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 # Flash CONFIG_SOC_FLASH_ITE_IT8XXX2=y +# Power Management +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_POLICY_APP=y + # Code RAM base for IT8XXX2 CONFIG_CROS_EC_PROGRAM_MEMORY_BASE=0x80000000 CONFIG_CROS_EC_RAM_BASE=0x80100000 diff --git a/zephyr/cmake/compiler/clang/compiler_flags.cmake b/zephyr/cmake/compiler/clang/compiler_flags.cmake index 815078a15a..5f97625a58 100644 --- a/zephyr/cmake/compiler/clang/compiler_flags.cmake +++ b/zephyr/cmake/compiler/clang/compiler_flags.cmake @@ -7,4 +7,7 @@ include("${ZEPHYR_BASE}/cmake/compiler/clang/compiler_flags.cmake") # Disable -fno-freestanding. set_compiler_property(PROPERTY hosted) -check_set_compiler_property(APPEND PROPERTY warning_extended -Wunused-variable -Werror=unused-variable -Werror=missing-braces) +check_set_compiler_property(APPEND PROPERTY warning_extended -Wunused-variable + -Werror=unused-variable -Werror=missing-braces + -Werror=sometimes-uninitialized -Werror=unused-function + -Werror=array-bounds) diff --git a/zephyr/drivers/cros_cbi/CMakeLists.txt b/zephyr/drivers/cros_cbi/CMakeLists.txt index 644865ae77..01b566c676 100644 --- a/zephyr/drivers/cros_cbi/CMakeLists.txt +++ b/zephyr/drivers/cros_cbi/CMakeLists.txt @@ -1,4 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_EEPROM cros_cbi.c) -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_GPIO cros_cbi.c) +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_EEPROM + cros_cbi.c cros_cbi_ssfc.c cros_cbi_fw_config.c) +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_GPIO + cros_cbi.c cros_cbi_ssfc.c cros_cbi_fw_config.c) diff --git a/zephyr/drivers/cros_cbi/cros_cbi.c b/zephyr/drivers/cros_cbi/cros_cbi.c index 2f647272d4..af1776a477 100644 --- a/zephyr/drivers/cros_cbi/cros_cbi.c +++ b/zephyr/drivers/cros_cbi/cros_cbi.c @@ -4,201 +4,15 @@ */ #include <drivers/cros_cbi.h> -#include "cros_board_info.h" -#include <logging/log.h> - -LOG_MODULE_REGISTER(cros_cbi, LOG_LEVEL_ERR); - -/* CBI SSFC part */ - -/* This part of the driver is about CBI SSFC part. - * Actually, two "compatible" values are handle here - - * named_cbi_ssfc_value and named_cbi_ssfc. named_cbi_ssfc_value nodes are - * grandchildren of the named_cbi_ssfc node. named_cbi_ssfc_value is introduced - * to iterate over grandchildren of the named_cbi_ssfc(macro - * DT_FOREACH_CHILD can not be nested) and it can be pointed by a sensor dts to - * indicate alternative usage. - */ -#define DT_DRV_COMPAT named_cbi_ssfc_value - -BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(named_cbi_ssfc) < 2, - "More than 1 CBI SSFS node"); -#define CBI_SSFC_NODE DT_INST(0, named_cbi_ssfc) - -#define CBI_SSFC_INIT_DEFAULT_ID(id, data) \ - do { \ - if (DT_PROP(id, default)) { \ - data->cached_ssfc.CBI_SSFC_UNION_ENTRY_NAME( \ - DT_PARENT(id)) = DT_PROP(id, value); \ - } \ - } while (0); - -#define CBI_SSFC_INIT_DEFAULT(inst, data) \ - CBI_SSFC_INIT_DEFAULT_ID(DT_DRV_INST(inst), data) - -#define CBI_SSFC_VALUE_ARRAY_ID(id) \ - [CBI_SSFC_VALUE_ID(id)] = DT_PROP(id, value), - -#define CBI_SSFC_VALUE_ARRAY(inst) CBI_SSFC_VALUE_ARRAY_ID(DT_DRV_INST(inst)) - -#define CBI_SSFC_VALUE_BUILD_ASSERT(inst) \ - BUILD_ASSERT(DT_INST_PROP(inst, value) <= UINT8_MAX, \ - "CBI SSFS value too big"); - -#define CBI_SSFC_PARENT_VALUE_CASE_GENERATE(value_id, value_parent, value) \ - case value_id: \ - *value = value_parent; \ - break; - -#define CBI_SSFC_PARENT_VALUE_CASE_ID(id, cached_ssfc, value) \ - CBI_SSFC_PARENT_VALUE_CASE_GENERATE( \ - CBI_SSFC_VALUE_ID(id), \ - cached_ssfc.CBI_SSFC_UNION_ENTRY_NAME(DT_PARENT(id)), value) - -#define CBI_SSFC_PARENT_VALUE_CASE(inst, cached_ssfc, value) \ - CBI_SSFC_PARENT_VALUE_CASE_ID(DT_DRV_INST(inst), cached_ssfc, value) - -#define CBI_SSFC_UNION_ENTRY_NAME(id) DT_CAT(cbi_ssfc_, id) -#define CBI_SSFC_UNION_ENTRY(id) \ - uint32_t CBI_SSFC_UNION_ENTRY_NAME(id) \ - : DT_PROP(id, size); - -#define CBI_SSFC_PLUS_FIELD_SIZE(id) +DT_PROP(id, size) -#define CBI_SSFC_FIELDS_SIZE \ - (0 COND_CODE_1( \ - DT_NODE_EXISTS(CBI_SSFC_NODE), \ - (DT_FOREACH_CHILD(CBI_SSFC_NODE, CBI_SSFC_PLUS_FIELD_SIZE)), \ - ())) - -BUILD_ASSERT(CBI_SSFC_FIELDS_SIZE <= 32, "CBI SSFS is bigger than 32 bits"); - -/* - * Define union bit fields based on the device tree entries. Example: - * cbi-ssfc { - * compatible = "named-cbi-ssfc"; - * - * base_sensor { - * enum-name = "BASE_SENSOR"; - * size = <3>; - * bmi160 { - * compatible = "named-cbi-ssfc-value"; - * status = "okay"; - * value = <1>; - * }; - * }; - * lid_sensor { - * enum-name = "LID_SENSOR"; - * size = <3>; - * bma255 { - * compatible = "named-cbi-ssfc-value"; - * status = "okay"; - * value = <1>; - * }; - * }; - * lightbar { - * enum-name = "LIGHTBAR"; - * size = <2>; - * 10_led { - * compatible = "named-cbi-ssfc-value"; - * status = "okay"; - * value = <1>; - * }; - * }; - * }; - * Should be converted into - * union cbi_ssfc { - * struct { - * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_base_sensor:3 - * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_lid_sensor:3 - * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_lightbar:2 - * uint32_t reserved : 24; - * }; - * uint32_t raw_value; - * }; - */ -union cbi_ssfc { - struct { -#if DT_NODE_EXISTS(CBI_SSFC_NODE) - DT_FOREACH_CHILD(CBI_SSFC_NODE, CBI_SSFC_UNION_ENTRY) - uint32_t reserved : (32 - CBI_SSFC_FIELDS_SIZE); -#endif - }; - uint32_t raw_value; -}; - -BUILD_ASSERT(sizeof(union cbi_ssfc) == sizeof(uint32_t), - "CBI SSFS structure exceeds 32 bits"); - -DT_INST_FOREACH_STATUS_OKAY(CBI_SSFC_VALUE_BUILD_ASSERT) - -static const uint8_t ssfc_values[] = { - DT_INST_FOREACH_STATUS_OKAY(CBI_SSFC_VALUE_ARRAY) -}; - -/* CBI SSFC part end */ -/* Device config */ -struct cros_cbi_config { - /* SSFC values for specific configs */ - const uint8_t *ssfc_values; -}; - -/* Device data */ -struct cros_cbi_data { - /* Cached SSFC configs */ - union cbi_ssfc cached_ssfc; -}; - -/* CBI SSFC part */ - -static void cros_cbi_ssfc_init(const struct device *dev) -{ - struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); - - if (cbi_get_ssfc(&data->cached_ssfc.raw_value) != EC_SUCCESS) { - DT_INST_FOREACH_STATUS_OKAY_VARGS(CBI_SSFC_INIT_DEFAULT, data) - } - - LOG_INF("Read CBI SSFC : 0x%08X\n", data->cached_ssfc.raw_value); -} - -static int cros_cbi_ssfc_get_parent_field_value(union cbi_ssfc cached_ssfc, - enum cbi_ssfc_value_id value_id, - uint32_t *value) -{ - switch (value_id) { - DT_INST_FOREACH_STATUS_OKAY_VARGS(CBI_SSFC_PARENT_VALUE_CASE, - cached_ssfc, value) - default: - LOG_ERR("CBI SSFC parent field value not found: %d\n", - value_id); - return -EINVAL; - } - return 0; -} - -static bool cros_cbi_ec_ssfc_check_match(const struct device *dev, - enum cbi_ssfc_value_id value_id) -{ - struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); - struct cros_cbi_config *cfg = (struct cros_cbi_config *)(dev->config); - int rc; - uint32_t value; - - rc = cros_cbi_ssfc_get_parent_field_value(data->cached_ssfc, - value_id, &value); - if (rc) { - return false; - } - return value == cfg->ssfc_values[value_id]; -} - -/* CBI SSFC part end */ -#undef DT_DRV_COMPAT +#include "cros_board_info.h" +#include "cros_cbi_ssfc.h" +#include "cros_cbi_common.h" static int cros_cbi_ec_init(const struct device *dev) { cros_cbi_ssfc_init(dev); + cros_cbi_fw_config_init(dev); return 0; } @@ -207,6 +21,7 @@ static int cros_cbi_ec_init(const struct device *dev) static const struct cros_cbi_driver_api cros_cbi_driver_api = { .init = cros_cbi_ec_init, .ssfc_check_match = cros_cbi_ec_ssfc_check_match, + .get_fw_config = cros_cbi_ec_get_fw_config, }; static int cbi_init(const struct device *dev) @@ -216,6 +31,16 @@ static int cbi_init(const struct device *dev) return 0; } +/* + * These belong in the SSFC specific code, but the array + * is referenced in the cfg data. + */ +#define DT_DRV_COMPAT named_cbi_ssfc_value +static const uint8_t ssfc_values[] = { + DT_INST_FOREACH_STATUS_OKAY(CBI_SSFC_VALUE_ARRAY) +}; +#undef DT_DRV_COMPAT + static const struct cros_cbi_config cros_cbi_cfg = { .ssfc_values = ssfc_values, }; diff --git a/zephyr/drivers/cros_cbi/cros_cbi_common.h b/zephyr/drivers/cros_cbi/cros_cbi_common.h new file mode 100644 index 0000000000..ef48fdfd11 --- /dev/null +++ b/zephyr/drivers/cros_cbi/cros_cbi_common.h @@ -0,0 +1,32 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_CBI_CROS_CBI_COMMON_H +#define __CROS_CBI_CROS_CBI_COMMON_H + +/* Device config */ +struct cros_cbi_config { + /* SSFC values for specific configs */ + const uint8_t *ssfc_values; +}; + +/* Device data */ +struct cros_cbi_data { + /* Cached SSFC configs */ + union cbi_ssfc cached_ssfc; + /* Cached FW_CONFIG bits */ + uint32_t cached_fw_config; +}; + +void cros_cbi_ssfc_init(const struct device *dev); +bool cros_cbi_ec_ssfc_check_match(const struct device *dev, + enum cbi_ssfc_value_id value_id); +void cros_cbi_fw_config_init(const struct device *dev); +int cros_cbi_ec_get_fw_config(const struct device *dev, + enum cbi_fw_config_field_id field_id, + uint32_t *value); + + +#endif /* __CROS_CBI_CROS_CBI_COMMON_H */ diff --git a/zephyr/drivers/cros_cbi/cros_cbi_fw_config.c b/zephyr/drivers/cros_cbi/cros_cbi_fw_config.c new file mode 100644 index 0000000000..2eacbcf6d4 --- /dev/null +++ b/zephyr/drivers/cros_cbi/cros_cbi_fw_config.c @@ -0,0 +1,189 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <drivers/cros_cbi.h> +#include <logging/log.h> + +#include "cros_board_info.h" +#include "cros_cbi_ssfc.h" +#include "cros_cbi_common.h" + +LOG_MODULE_REGISTER(cros_cbi_fw_config, LOG_LEVEL_ERR); + +/* + * Validation macros. + * These are moved out of header files to avoid exposing them outside + * this file scope. + */ + +/* + * Statically count the number of bits set in a 32 bit constant expression. + */ +#define BIT_SET(v, b) ((v >> b) & 1) +#define BIT_COUNT(v) \ + (BIT_SET(v, 31) + BIT_SET(v, 30) + BIT_SET(v, 29) + BIT_SET(v, 28) + \ + BIT_SET(v, 27) + BIT_SET(v, 26) + BIT_SET(v, 25) + BIT_SET(v, 24) + \ + BIT_SET(v, 23) + BIT_SET(v, 22) + BIT_SET(v, 21) + BIT_SET(v, 20) + \ + BIT_SET(v, 19) + BIT_SET(v, 18) + BIT_SET(v, 17) + BIT_SET(v, 16) + \ + BIT_SET(v, 15) + BIT_SET(v, 14) + BIT_SET(v, 13) + BIT_SET(v, 12) + \ + BIT_SET(v, 11) + BIT_SET(v, 10) + BIT_SET(v, 9) + BIT_SET(v, 8) + \ + BIT_SET(v, 7) + BIT_SET(v, 6) + BIT_SET(v, 5) + BIT_SET(v, 4) + \ + BIT_SET(v, 3) + BIT_SET(v, 2) + BIT_SET(v, 1) + BIT_SET(v, 0)) + +/* + * Shorthand macros to access properties on the field node. + */ +#define FW_START(id) DT_PROP(id, start) +#define FW_SIZE(id) DT_PROP(id, size) + +/* + * Calculate the mask of the field from the size. + */ +#define FW_MASK(id) ((1 << FW_SIZE(id)) - 1) + +/* + * Calculate the mask and shift it to the correct start bit. + */ +#define FW_SHIFT_MASK(id) (FW_MASK(id) << FW_START(id)) + +/* + * For a child "named-cbi-fw-config-value" node, retrieve the + * size of the parent field this value is associated with. + */ +#define FW_PARENT_SIZE(id) DT_PROP(DT_PARENT(id), size) + +/* + * Validation check to ensure total field sizes do not exceed 32 bits. + * The FOREACH loop is nested, one to iterate through all the + * fw_config nodes, and another for the child field nodes in each + * of the fw_config nodes. + */ +#define PLUS_FIELD_SIZE(inst) + DT_PROP(inst, size) +#define FIELDS_ALL_SIZE(inst) \ + DT_FOREACH_CHILD_STATUS_OKAY(inst, PLUS_FIELD_SIZE) + +/* + * Result is the sum of all the field sizes. + */ +#define TOTAL_FW_CONFIG_NODES_SIZE \ + (0 DT_FOREACH_STATUS_OKAY(CBI_FW_CONFIG_COMPAT, FIELDS_ALL_SIZE)) + +BUILD_ASSERT(TOTAL_FW_CONFIG_NODES_SIZE <= 32, + "CBI FW Config is bigger than 32 bits"); + +/* + * Validation check to ensure there are no overlapping fields. + * OR together all the masks, count the bits, and compare against the + * total of the sizes. They should match. + */ +#define OR_FIELD_SHIFT_MASK(id) | FW_SHIFT_MASK(id) +#define FIELDS_ALL_BITS_SET(inst) \ + DT_FOREACH_CHILD_STATUS_OKAY(inst, OR_FIELD_SHIFT_MASK) + +#define TOTAL_BITS_SET \ + (0 DT_FOREACH_STATUS_OKAY(CBI_FW_CONFIG_COMPAT, \ + FIELDS_ALL_BITS_SET)) + +BUILD_ASSERT(BIT_COUNT(TOTAL_BITS_SET) == TOTAL_FW_CONFIG_NODES_SIZE, + "CBI FW Config has overlapping fields"); + +/* + * Validation for each assigned field values. + * The value must fit within the parent's defined size. + */ +#define FW_VALUE_BUILD_ASSERT(inst) \ + BUILD_ASSERT(DT_PROP(inst, value) < \ + (1 << FW_PARENT_SIZE(inst)), \ + "CBI FW Config value too big"); + +DT_FOREACH_STATUS_OKAY(CBI_FW_CONFIG_VALUE_COMPAT, FW_VALUE_BUILD_ASSERT) + +/* + * Define union bit fields based on the device tree entries. Example: + * cbi-fw-config { + * compatible = "named-cbi-fw-config"; + * + * fan { + * enum-name = "FW_CONFIG_FAN"; + * start = <0>; + * size = <1>; + * fan_present { + * enum-name = "FW_FAN_PRESENT" + * compatible = "named-cbi-fw-config-value"; + * value = <1>; + * }; + * }; + * }; + * + * Creates + * switch (field_id) { + * case FW_CONFIG_FAN: + * return (value >> 0) & 1; + * ... + * } + * + */ + +/* + * The per-field case statement. + * Extract the field value using the start and size. + */ +#define FW_FIELD_CASE(id, cached, value) \ + case CBI_FW_CONFIG_ENUM(id): \ + *value = (cached >> FW_START(id)) & FW_MASK(id); \ + break; + +/* + * Create a case for every child of this "named-cbi-fw-config" node. + */ +#define FW_FIELD_NODES(inst, cached, value) \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(inst, FW_FIELD_CASE, cached, value) + +void cros_cbi_fw_config_init(const struct device *dev) +{ + struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); + + if (cbi_get_fw_config(&data->cached_fw_config) != EC_SUCCESS) + /* + * Missing fw config will defaults to all zeros. + */ + data->cached_fw_config = 0; + + LOG_INF("Read CBI FW Config : 0x%08X\n", data->cached_fw_config); +} + +static int cros_cbi_fw_config_get_field( + uint32_t cached_fw_config, + enum cbi_fw_config_field_id field_id, + uint32_t *value) +{ + switch (field_id) { + /* + * Iterate through all the the "named-cbi-fw-config" nodes, + * and create cases for all of their child nodes. + */ + DT_FOREACH_STATUS_OKAY_VARGS(CBI_FW_CONFIG_COMPAT, + FW_FIELD_NODES, + cached_fw_config, + value) + default: + return -EINVAL; + } + return 0; +} + +int cros_cbi_ec_get_fw_config(const struct device *dev, + enum cbi_fw_config_field_id field_id, + uint32_t *value) +{ + struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); + int rc; + + rc = cros_cbi_fw_config_get_field(data->cached_fw_config, + field_id, value); + if (rc) + LOG_ERR("CBI FW Config field not found: %d\n", field_id); + return rc; +} diff --git a/zephyr/drivers/cros_cbi/cros_cbi_ssfc.c b/zephyr/drivers/cros_cbi/cros_cbi_ssfc.c new file mode 100644 index 0000000000..624b0ddc5f --- /dev/null +++ b/zephyr/drivers/cros_cbi/cros_cbi_ssfc.c @@ -0,0 +1,57 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <drivers/cros_cbi.h> +#include <logging/log.h> + +#include "cros_board_info.h" +#include "cros_cbi_ssfc.h" +#include "cros_cbi_common.h" + +#define DT_DRV_COMPAT named_cbi_ssfc_value + +LOG_MODULE_REGISTER(cros_cbi_ssfc, LOG_LEVEL_ERR); + +void cros_cbi_ssfc_init(const struct device *dev) +{ + struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); + + if (cbi_get_ssfc(&data->cached_ssfc.raw_value) != EC_SUCCESS) { + DT_INST_FOREACH_STATUS_OKAY_VARGS(CBI_SSFC_INIT_DEFAULT, data) + } + + LOG_INF("Read CBI SSFC : 0x%08X\n", data->cached_ssfc.raw_value); +} + +static int cros_cbi_ssfc_get_parent_field_value(union cbi_ssfc cached_ssfc, + enum cbi_ssfc_value_id value_id, + uint32_t *value) +{ + switch (value_id) { + DT_INST_FOREACH_STATUS_OKAY_VARGS(CBI_SSFC_PARENT_VALUE_CASE, + cached_ssfc, value) + default: + LOG_ERR("CBI SSFC parent field value not found: %d\n", + value_id); + return -EINVAL; + } + return 0; +} + +bool cros_cbi_ec_ssfc_check_match(const struct device *dev, + enum cbi_ssfc_value_id value_id) +{ + struct cros_cbi_data *data = (struct cros_cbi_data *)(dev->data); + struct cros_cbi_config *cfg = (struct cros_cbi_config *)(dev->config); + int rc; + uint32_t value; + + rc = cros_cbi_ssfc_get_parent_field_value(data->cached_ssfc, + value_id, &value); + if (rc) { + return false; + } + return value == cfg->ssfc_values[value_id]; +} diff --git a/zephyr/drivers/cros_cbi/cros_cbi_ssfc.h b/zephyr/drivers/cros_cbi/cros_cbi_ssfc.h new file mode 100644 index 0000000000..3ee3a7eeb6 --- /dev/null +++ b/zephyr/drivers/cros_cbi/cros_cbi_ssfc.h @@ -0,0 +1,133 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_CBI_CROS_CBI_SSFC_H +#define __CROS_CBI_CROS_CBI_SSFC_H + +/* CBI SSFC part */ + +/* This part of the driver is about CBI SSFC part. + * Actually, two "compatible" values are handle here - + * named_cbi_ssfc_value and named_cbi_ssfc. named_cbi_ssfc_value nodes are + * grandchildren of the named_cbi_ssfc node. named_cbi_ssfc_value is introduced + * to iterate over grandchildren of the named_cbi_ssfc(macro + * DT_FOREACH_CHILD can not be nested) and it can be pointed by a sensor dts to + * indicate alternative usage. + */ +#define DT_DRV_COMPAT named_cbi_ssfc_value + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(named_cbi_ssfc) < 2, + "More than 1 CBI SSFS node"); +#define CBI_SSFC_NODE DT_INST(0, named_cbi_ssfc) + +#define CBI_SSFC_INIT_DEFAULT_ID(id, data) \ + do { \ + if (DT_PROP(id, default)) { \ + data->cached_ssfc.CBI_SSFC_UNION_ENTRY_NAME( \ + DT_PARENT(id)) = DT_PROP(id, value); \ + } \ + } while (0); + +#define CBI_SSFC_INIT_DEFAULT(inst, data) \ + CBI_SSFC_INIT_DEFAULT_ID(DT_DRV_INST(inst), data) + +#define CBI_SSFC_VALUE_ARRAY_ID(id) \ + [CBI_SSFC_VALUE_ID(id)] = DT_PROP(id, value), + +#define CBI_SSFC_VALUE_ARRAY(inst) CBI_SSFC_VALUE_ARRAY_ID(DT_DRV_INST(inst)) + +#define CBI_SSFC_VALUE_BUILD_ASSERT(inst) \ + BUILD_ASSERT(DT_INST_PROP(inst, value) <= UINT8_MAX, \ + "CBI SSFS value too big"); + +#define CBI_SSFC_PARENT_VALUE_CASE_GENERATE(value_id, value_parent, value) \ + case value_id: \ + *value = value_parent; \ + break; + +#define CBI_SSFC_PARENT_VALUE_CASE_ID(id, cached_ssfc, value) \ + CBI_SSFC_PARENT_VALUE_CASE_GENERATE( \ + CBI_SSFC_VALUE_ID(id), \ + cached_ssfc.CBI_SSFC_UNION_ENTRY_NAME(DT_PARENT(id)), value) + +#define CBI_SSFC_PARENT_VALUE_CASE(inst, cached_ssfc, value) \ + CBI_SSFC_PARENT_VALUE_CASE_ID(DT_DRV_INST(inst), cached_ssfc, value) + +#define CBI_SSFC_UNION_ENTRY_NAME(id) DT_CAT(cbi_ssfc_, id) +#define CBI_SSFC_UNION_ENTRY(id) \ + uint32_t CBI_SSFC_UNION_ENTRY_NAME(id) \ + : DT_PROP(id, size); + +#define CBI_SSFC_PLUS_FIELD_SIZE(id) +DT_PROP(id, size) +#define CBI_SSFC_FIELDS_SIZE \ + (0 COND_CODE_1( \ + DT_NODE_EXISTS(CBI_SSFC_NODE), \ + (DT_FOREACH_CHILD(CBI_SSFC_NODE, CBI_SSFC_PLUS_FIELD_SIZE)), \ + ())) + +BUILD_ASSERT(CBI_SSFC_FIELDS_SIZE <= 32, "CBI SSFS is bigger than 32 bits"); + +/* + * Define union bit fields based on the device tree entries. Example: + * cbi-ssfc { + * compatible = "named-cbi-ssfc"; + * + * base_sensor { + * enum-name = "BASE_SENSOR"; + * size = <3>; + * bmi160 { + * compatible = "named-cbi-ssfc-value"; + * status = "okay"; + * value = <1>; + * }; + * }; + * lid_sensor { + * enum-name = "LID_SENSOR"; + * size = <3>; + * bma255 { + * compatible = "named-cbi-ssfc-value"; + * status = "okay"; + * value = <1>; + * }; + * }; + * lightbar { + * enum-name = "LIGHTBAR"; + * size = <2>; + * 10_led { + * compatible = "named-cbi-ssfc-value"; + * status = "okay"; + * value = <1>; + * }; + * }; + * }; + * Should be converted into + * union cbi_ssfc { + * struct { + * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_base_sensor:3 + * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_lid_sensor:3 + * uint32_t cbi_ssfc_DT_N_S_cbi_ssfc_S_lightbar:2 + * uint32_t reserved : 24; + * }; + * uint32_t raw_value; + * }; + */ +union cbi_ssfc { + struct { +#if DT_NODE_EXISTS(CBI_SSFC_NODE) + DT_FOREACH_CHILD(CBI_SSFC_NODE, CBI_SSFC_UNION_ENTRY) + uint32_t reserved : (32 - CBI_SSFC_FIELDS_SIZE); +#endif + }; + uint32_t raw_value; +}; + +BUILD_ASSERT(sizeof(union cbi_ssfc) == sizeof(uint32_t), + "CBI SSFS structure exceeds 32 bits"); + +DT_INST_FOREACH_STATUS_OKAY(CBI_SSFC_VALUE_BUILD_ASSERT) + +#undef DT_DRV_COMPAT + +#endif /* __CROS_CBI_CROS_CBI_SSFC_H */ diff --git a/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c b/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c index f238b1557b..0b1899feda 100644 --- a/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c +++ b/zephyr/drivers/cros_flash/cros_flash_it8xxx2.c @@ -321,7 +321,6 @@ static int flash_it8xxx2_init(const struct device *dev) static struct cros_flash_it8xxx2_data cros_flash_data; -DEVICE_DEFINE(cros_flash_it8xxx2_0, DT_INST_LABEL(0), flash_it8xxx2_init, NULL, - &cros_flash_data, NULL, PRE_KERNEL_1, - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &cros_flash_it8xxx2_driver_api); +DEVICE_DT_INST_DEFINE(0, flash_it8xxx2_init, NULL, &cros_flash_data, NULL, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &cros_flash_it8xxx2_driver_api); diff --git a/zephyr/drivers/cros_kb_raw/Kconfig b/zephyr/drivers/cros_kb_raw/Kconfig index a037cdd451..e8b0112c0d 100644 --- a/zephyr/drivers/cros_kb_raw/Kconfig +++ b/zephyr/drivers/cros_kb_raw/Kconfig @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +if PLATFORM_EC_KEYBOARD + menuconfig CROS_KB_RAW_NPCX bool "Nuvoton NPCX raw-keyboard-scan driver for the Zephyr shim" depends on SOC_FAMILY_NPCX @@ -23,7 +25,7 @@ config CROS_KB_RAW_NPCX_KSO_HIGH_DRIVE endif # CROS_KB_RAW_NPCX -menuconfig CROS_KB_RAW_ITE +config CROS_KB_RAW_ITE bool "ITE raw-keyboard-scan driver for the Zephyr shim" depends on SOC_FAMILY_RISCV_ITE default y @@ -32,3 +34,5 @@ menuconfig CROS_KB_RAW_ITE keyboard-scan peripheral in the chip. This is used instead of the kscan interface so we can continue to use most of the existing keyboard-scanning code in ECOS. + +endif # PLATFORM_EC_KEYBOARD
\ No newline at end of file diff --git a/zephyr/drivers/cros_shi/Kconfig b/zephyr/drivers/cros_shi/Kconfig index 0baa8a5d80..8ca08b6b19 100644 --- a/zephyr/drivers/cros_shi/Kconfig +++ b/zephyr/drivers/cros_shi/Kconfig @@ -2,9 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -menuconfig CROS_SHI_NPCX - bool "Nuvoton NPCX Serial Host Interface driver for the Zephyr shim" +config CROS_SHI_NPCX + bool depends on SOC_FAMILY_NPCX + depends on PLATFORM_EC_HOST_INTERFACE_SHI + default y help This option enables Serial Host Interface driver for the NPCX family of processors. This is used for host-command communication on the @@ -35,9 +37,10 @@ config CROS_SHI_NPCX_DEBUG endif # CROS_SHI_NPCX config CROS_SHI_IT8XXX2 - bool "ITE it81202 spi host interface driver for Zephyr" - depends on SOC_FAMILY_RISCV_ITE && AP_ARM - default y if PLATFORM_EC_HOSTCMD + bool + depends on SOC_FAMILY_RISCV_ITE + depends on PLATFORM_EC_HOST_INTERFACE_SHI + default y 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 522d48ff09..64753e0833 100644 --- a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c +++ b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c @@ -91,9 +91,9 @@ BUILD_ASSERT(ARRAY_SIZE(spi_response_state) == SPI_STATE_COUNT); static void spi_set_state(int state) { - /* SPI slave state machine */ + /* SPI peripheral state machine */ shi_state = state; - /* Response spi slave state */ + /* Response spi peripheral state */ IT83XX_SPI_SPISRDR = spi_response_state[state]; } @@ -142,12 +142,12 @@ static void spi_response_host_data(uint8_t *out_msg_addr, int tx_size) /* * After writing data to Tx FIFO is finished, this bit will - * be to indicate the SPI slave controller. + * be to indicate the SPI peripheral controller. */ IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS; /* End Tx FIFO access */ IT83XX_SPI_TXRXFAR = 0; - /* SPI slave read Tx FIFO */ + /* SPI peripheral read Tx FIFO */ IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF; } @@ -356,7 +356,7 @@ static int cros_shi_ite_init(const struct device *dev) spi_set_state(SPI_STATE_READY_TO_RECV); /* Interrupt status register(write one to clear) */ IT83XX_SPI_ISR = 0xff; - /* SPI slave controller enable (after settings are ready) */ + /* SPI peripheral controller enable (after settings are ready) */ IT83XX_SPI_SPISGCR = IT83XX_SPI_SPISCEN; /* Ensure spi chip select alt function is enabled. */ @@ -365,7 +365,7 @@ static int cros_shi_ite_init(const struct device *dev) config[i].alt_fun); } - /* Enable SPI slave interrupt */ + /* Enable SPI peripheral interrupt */ IRQ_CONNECT(DT_INST_IRQN(0), 0, shi_ite_int_handler, 0, 0); irq_enable(DT_INST_IRQN(0)); diff --git a/zephyr/drivers/cros_shi/cros_shi_npcx.c b/zephyr/drivers/cros_shi/cros_shi_npcx.c index a290e320fc..118c0c40ea 100644 --- a/zephyr/drivers/cros_shi/cros_shi_npcx.c +++ b/zephyr/drivers/cros_shi/cros_shi_npcx.c @@ -54,7 +54,7 @@ LOG_MODULE_REGISTER(cros_shi, LOG_LEVEL_DBG); * practically want to run the SHI interface, since running it slower * significantly impacts firmware update times. */ -#define SHI_CMD_RX_TIMEOUT_MS 9 +#define SHI_CMD_RX_TIMEOUT_US 8192 /* * The AP blindly clocks back bytes over the SPI interface looking for a @@ -237,7 +237,7 @@ static int shi_read_inbuf_wait(struct shi_reg *const inst, uint32_t szbytes) */ while (shi_params.rx_buf == inst->IBUF + shi_read_buf_pointer(inst)) { - if (k_uptime_get() > shi_params.rx_deadline) { + if (k_cycle_get_64() >= shi_params.rx_deadline) { return 0; } } @@ -445,7 +445,8 @@ static void shi_parse_header(struct shi_reg *const inst) DEBUG_CPRINTF("RV-"); /* Setup deadline time for receiving */ - shi_params.rx_deadline = k_uptime_get() + SHI_CMD_RX_TIMEOUT_MS; + shi_params.rx_deadline = + k_cycle_get_64() + k_us_to_cyc_near64(SHI_CMD_RX_TIMEOUT_US); /* Wait for version, command, length bytes */ if (!shi_read_inbuf_wait(inst, 3)) diff --git a/zephyr/dts/bindings/adc/named-adc.yaml b/zephyr/dts/bindings/adc/named-adc.yaml index 11df44f8d9..a21ed82e39 100644 --- a/zephyr/dts/bindings/adc/named-adc.yaml +++ b/zephyr/dts/bindings/adc/named-adc.yaml @@ -13,8 +13,7 @@ child-binding: required: true type: string description: - Human-readable string describing the device (used as - device_get_binding() argument) + String used to describe an ADC channel in the 'adc' console command. channel: required: true type: int @@ -91,12 +90,22 @@ child-binding: - ADC_AMON_BMON - ADC_BOARD_ID_0 - ADC_BOARD_ID_1 + - ADC_CORE_IMON1 + - ADC_ID_0 + - ADC_ID_1 - ADC_PMON + - ADC_PP3300_S5 - ADC_PSYS + - ADC_SOC_IMON2 + - ADC_TEMP_SENSOR_1 + - ADC_TEMP_SENSOR_2 + - ADC_TEMP_SENSOR_3 - ADC_TEMP_SENSOR_CHARGER - ADC_TEMP_SENSOR_DDR_SOC - ADC_TEMP_SENSOR_FAN + - ADC_TEMP_SENSOR_MEMORY - ADC_TEMP_SENSOR_PP3300_REGULATOR + - ADC_TEMP_SENSOR_SOC - ADC_TEMP_SENSOR_1_DDR_SOC - ADC_TEMP_SENSOR_2_AMBIENT - ADC_TEMP_SENSOR_3_CHARGER diff --git a/zephyr/dts/bindings/battery/battery-smart.yaml b/zephyr/dts/bindings/battery/battery-smart.yaml index 3bb64f094f..96f7b6bdd2 100644 --- a/zephyr/dts/bindings/battery/battery-smart.yaml +++ b/zephyr/dts/bindings/battery/battery-smart.yaml @@ -15,6 +15,8 @@ properties: - "as3gwrc3ka,c235-41" - "lgc,ap16l8j" - "lgc,ap18c8k" + - "lgc,l20l3pg2" - "murata,ap18c4k" - "panasonic,ap16l5j" - "panasonic,ap16l5j-009" + - "smp,l20m3pg2" diff --git a/zephyr/dts/bindings/battery/lgc,l20l3pg2.yaml b/zephyr/dts/bindings/battery/lgc,l20l3pg2.yaml new file mode 100644 index 0000000000..bf2b62bc44 --- /dev/null +++ b/zephyr/dts/bindings/battery/lgc,l20l3pg2.yaml @@ -0,0 +1,53 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: "LGC L20L3PG2" +compatible: "lgc,l20l3pg2" + +include: battery-smart.yaml + +properties: + enum-name: + type: string + default: "lgc,l20l3pg2" + + # Fuel gauge + manuf_name: + default: "LGC" + device_name: + default: "L20L3PG2" + 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: 13050 + voltage_normal: + default: 11400 + voltage_min: + default: 9000 + 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: 73 diff --git a/zephyr/dts/bindings/battery/named-batteries.yaml b/zephyr/dts/bindings/battery/named-batteries.yaml index bdd6cc70fa..f382bfd52e 100644 --- a/zephyr/dts/bindings/battery/named-batteries.yaml +++ b/zephyr/dts/bindings/battery/named-batteries.yaml @@ -18,4 +18,6 @@ child-binding: - "c235" - "lgc011" - "lgc_ap18c8k" + - "lgc_l20l3pg2" - "murata_ap18c4k" + - "smp_l20m3pg2" diff --git a/zephyr/dts/bindings/battery/smp,l20m3pg2.yaml b/zephyr/dts/bindings/battery/smp,l20m3pg2.yaml new file mode 100644 index 0000000000..874e1f8d0c --- /dev/null +++ b/zephyr/dts/bindings/battery/smp,l20m3pg2.yaml @@ -0,0 +1,53 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: "SMP L20M3PG2" +compatible: "smp,l20m3pg2" + +include: battery-smart.yaml + +properties: + enum-name: + type: string + default: "smp,l20m3pg2" + + # Fuel gauge + manuf_name: + default: "SMP" + device_name: + default: "L20M3PG2" + ship_mode_reg_addr: + default: 0x34 + ship_mode_reg_data: + default: [ 0x0000, 0x0100 ] + 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: 13050 + voltage_normal: + default: 11250 + voltage_min: + default: 9000 + precharge_current: + default: 256 + start_charging_min_c: + default: 0 + start_charging_max_c: + default: 45 + charging_min_c: + default: 0 + charging_max_c: + default: 45 + discharging_min_c: + default: -20 + discharging_max_c: + default: 60 diff --git a/zephyr/dts/bindings/cbi/named-cbi-fw-config-value.yaml b/zephyr/dts/bindings/cbi/named-cbi-fw-config-value.yaml new file mode 100644 index 0000000000..5d7c48604b --- /dev/null +++ b/zephyr/dts/bindings/cbi/named-cbi-fw-config-value.yaml @@ -0,0 +1,21 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: + Possible CBI FW_CONFIG individual field values. + It has to be defined as a grandchild on the "named-cbi-fw-config" nodes + +compatible: "named-cbi-fw-config-value" + +properties: + enum-name: + type: string + required: true + description: + Name of the value used for description purposes + value: + type: int + required: true + description: + Unique value within the parent CBI FW_CONFIG field diff --git a/zephyr/dts/bindings/cbi/named-cbi-fw-config.yaml b/zephyr/dts/bindings/cbi/named-cbi-fw-config.yaml new file mode 100644 index 0000000000..c8871ddb00 --- /dev/null +++ b/zephyr/dts/bindings/cbi/named-cbi-fw-config.yaml @@ -0,0 +1,52 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: CBI Firmware Config fields (FW_CONFIG) + +compatible: "named-cbi-fw-config" + +child-binding: + description: + CBI Firmware Config fields definition. + Each field is defined via a start bit (from LSB) and a size. + The total size of all FW_CONFIG bit fields must not exceed 32 bits. + properties: + enum-name: + type: string + required: true + description: + Name of field used for description purposes + start: + type: int + required: true + description: The starting bit of the field (LSB = 0) + size: + type: int + required: true + description: The size of the field in bits. + +# Example: +# +# cbi-fw-config { +# compatible = "named-cbi-fw-config"; +# +# fan { +# enum-name = "FAN"; +# start = <0> +# size = <1>; +# fan_absent { +# enum-name = "ABSENT" +# compatible = "named-cbi-fw-config-value"; +# value = <0>; +# fan_present { +# enum-name = "PRESENT" +# compatible = "named-cbi-fw-config-value"; +# value = <1>; +# }; +# }; +# }; +# +# This will generate an enum field id for CBI_FW_CONFIG_FIELD_FAN, +# and separate values for CBI_FW_CONFIG_FIELD_FAN_ABSENT = 0 and +# CBI_FW_CONFIG_FIELD_FAN_PRESENT = 1 diff --git a/zephyr/dts/bindings/cros_pwr_signal/mt8186,power-signal-list.yaml b/zephyr/dts/bindings/cros_pwr_signal/mt8186,power-signal-list.yaml new file mode 100644 index 0000000000..6e9af9ccef --- /dev/null +++ b/zephyr/dts/bindings/cros_pwr_signal/mt8186,power-signal-list.yaml @@ -0,0 +1,20 @@ +# Copyright 2021 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: MediaTek MT8186, Power Signal List +compatible: "mt8186,power-signal-list" + +include: power-signal-list.yaml + +properties: + power-signals-required: + default: 4 + +child-binding: + properties: + power-enum-name: + enum: + - AP_IN_RST + - AP_IN_S3 + - AP_WDT_ASSERTED + - AP_WARM_RST_REQ diff --git a/zephyr/dts/bindings/emul/cros,isl923x_emul.yaml b/zephyr/dts/bindings/emul/cros,isl923x-emul.yaml index be8b1183a2..81663b5509 100644 --- a/zephyr/dts/bindings/emul/cros,isl923x_emul.yaml +++ b/zephyr/dts/bindings/emul/cros,isl923x-emul.yaml @@ -4,9 +4,14 @@ description: ISL923X Charger emulator -compatible: "cros,isl923x_emul" +compatible: "cros,isl923x-emul" include: base.yaml properties: reg: required: true + battery: + type: phandle + required: false + description: + Reference to battery emulator. diff --git a/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml b/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml index 811f77206f..7723998786 100644 --- a/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml +++ b/zephyr/dts/bindings/emul/cros,ln9310-emul.yaml @@ -11,3 +11,9 @@ include: base.yaml properties: reg: required: true + pg_int_gpio: + type: phandle + description: + GPIO that receives interrupt signal from this device. + required: true + diff --git a/zephyr/dts/bindings/emul/cros,sn5s330.yaml b/zephyr/dts/bindings/emul/cros,sn5s330.yaml index b7964b777b..a459f9dafd 100644 --- a/zephyr/dts/bindings/emul/cros,sn5s330.yaml +++ b/zephyr/dts/bindings/emul/cros,sn5s330.yaml @@ -4,9 +4,13 @@ description: sn5s330 emulator -compatible: "cros,sn5s330" +compatible: "cros,sn5s330-emul" include: base.yaml properties: reg: required: true + int_gpio: + type: phandle + description: The GPIO that receives an interrupt signal from this device + required: true diff --git a/zephyr/dts/bindings/emul/zephyr,syv682x.yaml b/zephyr/dts/bindings/emul/zephyr,syv682x.yaml index e1ce84e85d..8652b42b82 100644 --- a/zephyr/dts/bindings/emul/zephyr,syv682x.yaml +++ b/zephyr/dts/bindings/emul/zephyr,syv682x.yaml @@ -13,3 +13,7 @@ properties: type: phandle description: The GPIO that controls FRS enable on this device required: true + alert_gpio: + type: phandle + description: The GPIO that receives the alert signal from this device + required: true diff --git a/zephyr/dts/bindings/gpio/gpio-enum-name.yaml b/zephyr/dts/bindings/gpio/gpio-enum-name.yaml index 2bc19d3ec4..a5a0fb3844 100644 --- a/zephyr/dts/bindings/gpio/gpio-enum-name.yaml +++ b/zephyr/dts/bindings/gpio/gpio-enum-name.yaml @@ -35,6 +35,7 @@ properties: - GPIO_EC_ALS_RGB_INT_L - GPIO_EC_AP_DP_HPD_ODL - GPIO_EC_BL_EN_OD + - GPIO_EC_CBI_WP - GPIO_EC_CHG_LED_B_C1 - GPIO_EC_CHG_LED_W_C0 - GPIO_EC_CHG_LED_W_C1 @@ -55,16 +56,20 @@ properties: - GPIO_EC_I2C7_EEPROM_PWR_SDA_R - GPIO_EC_I2C_SENSOR_SCL - GPIO_EC_I2C_SENSOR_SDA + - GPIO_EC_I2C_USBC_PD_INT - GPIO_EC_IMU_INT_L - GPIO_EC_INT_L - GPIO_EC_PCH_SYS_PWROK - GPIO_EC_PCH_WAKE_ODL - GPIO_EC_PCORE_INT_ODL + - GPIO_EC_PEN_CHG_DIS_ODL - GPIO_EC_PMIC_EN_ODL - GPIO_EC_PMIC_WATCHDOG_L - GPIO_EC_PROCHOT_IN_L - GPIO_EC_PWR_BTN_ODL - GPIO_EC_RST_ODL + - GPIO_EC_SOC_PWR_GOOD + - GPIO_EC_SC_RST - GPIO_EC_WP_L - GPIO_EC_X_GPIO1 - GPIO_EC_X_GPIO3 @@ -87,12 +92,14 @@ properties: - GPIO_EN_PWR_A - GPIO_EN_PWR_PCORE_S0_R - GPIO_EN_PWR_S0_R + - GPIO_EN_PWR_S3 - GPIO_EN_S5_RAILS - GPIO_EN_SLP_Z - GPIO_EN_ULP - GPIO_EN_USB_A_5V - GPIO_HDMI_PRSNT_ODL - GPIO_HIBERNATE_L + - GPIO_HUB_RST - GPIO_I2C_A_SCL - GPIO_I2C_A_SDA - GPIO_I2C_B_SCL @@ -122,16 +129,20 @@ properties: - GPIO_PCH_SLP_S5_L - GPIO_PCH_SLP_SUS_L - GPIO_PCH_SYS_PWROK + - GPIO_PCORE_OCP_L - GPIO_PGOOD_FAN - GPIO_PG_EC_ALL_SYS_PWRGD - GPIO_PG_EC_DSW_PWROK - GPIO_PG_EC_RSMRST_ODL - GPIO_PG_GROUPC_S0_OD - GPIO_PG_LPDDR4X_S3_OD + - GPIO_PG_LPDDR5_S0_OD + - GPIO_PG_LPDDR5_S3_OD - GPIO_PG_MT6315_GPU_ODL - GPIO_PG_MT6315_PROC_ODL - GPIO_PG_MT6360_ODL - GPIO_PG_PP5000_A_ODL + - GPIO_PG_PP5000_Z2_OD - GPIO_PMIC_EC_PWRGD - GPIO_PMIC_KPD_PWR_ODL - GPIO_PMIC_RESIN_L @@ -142,11 +153,14 @@ properties: - GPIO_QSIP_ON - GPIO_S0_PGOOD - GPIO_S5_PGOOD + - GPIO_SC_0_INT_L - GPIO_SET_VMC_VOLT_AT_1V8 + - GPIO_SHI_CS_L - GPIO_SKU_ID0 - GPIO_SKU_ID1 - GPIO_SKU_ID2 - GPIO_SLP_SUS_L + - GPIO_SOC_THERMTRIP_ODL - GPIO_SPI0_CS - GPIO_SPI_CLK_GPG6 - GPIO_SPI_CS_GPG7 @@ -176,6 +190,7 @@ properties: - GPIO_USB_C0_PPC_INT_ODL - GPIO_USB_C0_SWCTL_INT_ODL - GPIO_USB_C0_TCPC_INT_ODL + - GPIO_USB_C0_TCPC_RST - GPIO_USB_C0_TCPC_RST_L - GPIO_USB_C1_BC12_CHARGER_INT_ODL - GPIO_USB_C1_BC12_INT_L @@ -192,6 +207,8 @@ properties: - GPIO_USB_C1_SWCTL_INT_ODL - GPIO_USB_C1_TCPC_INT_ODL - GPIO_USB_C1_TCPC_RST_L + - GPIO_USB_HUB_FAULT_ODL + - GPIO_USB_FAULT_ODL - GPIO_VCCST_PWRGD_OD - GPIO_VBOB_EN - GPIO_VOLUME_DOWN_L @@ -199,4 +216,5 @@ properties: - GPIO_WARM_RESET_L - GPIO_WP - GPIO_WP_L + - GPIO_X_EC_GPIO1 - GPIO_X_EC_GPIO2 diff --git a/zephyr/dts/bindings/gpio/named-gpios.yaml b/zephyr/dts/bindings/gpio/named-gpios.yaml index 563c841f54..1f694a853b 100644 --- a/zephyr/dts/bindings/gpio/named-gpios.yaml +++ b/zephyr/dts/bindings/gpio/named-gpios.yaml @@ -9,12 +9,6 @@ child-binding: gpios: type: phandle-array required: true - label: - required: true - type: string - description: | - Human readable string describing the device (used as - device_get_binding() argument) "#gpio-cells": type: int required: false diff --git a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml index e27488c9a9..e4981c2dc5 100644 --- a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml +++ b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml @@ -28,6 +28,7 @@ properties: - I2C_PORT_EVB_2 - I2C_PORT_EVB_3 - I2C_PORT_EVB_7 + - I2C_PORT_MP2964 - I2C_PORT_OPT_4 - I2C_PORT_POWER - I2C_PORT_PPC0 @@ -38,6 +39,7 @@ properties: - I2C_PORT_TCPC1 - I2C_PORT_USB_1_MIX - I2C_PORT_USB_C0 + - I2C_PORT_USB_C0_TCPC - I2C_PORT_USB_C0_C2_MUX - I2C_PORT_USB_C0_C2_PPC - I2C_PORT_USB_C0_C2_TCPC @@ -49,12 +51,6 @@ properties: - I2C_PORT_USB_MUX1 - I2C_PORT_VIRTUAL_BATTERY - I2C_PORT_WLC - label: - required: true - type: string - description: - Human readable string describing the device (used as device_get_binding() - argument). dynamic-speed: type: boolean required: false diff --git a/zephyr/dts/bindings/motionsense/driver/bmi160.yaml b/zephyr/dts/bindings/motionsense/driver/bmi160.yaml index 8f490254a3..6ca096d87a 100644 --- a/zephyr/dts/bindings/motionsense/driver/bmi160.yaml +++ b/zephyr/dts/bindings/motionsense/driver/bmi160.yaml @@ -10,7 +10,7 @@ include: motionsense-sensor-base.yaml properties: i2c-spi-addr-flags: type: string - description: i2c address or SPI slave logic GPIO + description: i2c address or SPI peripheral logic GPIO enum: - "BMI160_ADDR0_FLAGS" default: "BMI160_ADDR0_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,bma255.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,bma255.yaml index 77d6282d7f..cbd9e82f2d 100644 --- a/zephyr/dts/bindings/motionsense/driver/cros-ec,bma255.yaml +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,bma255.yaml @@ -12,7 +12,7 @@ include: motionsense-sensor-base.yaml properties: i2c-spi-addr-flags: type: string - description: i2c address or SPI slave logic GPIO + description: i2c address or SPI peripheral logic GPIO enum: - "BMA2x2_I2C_ADDR1_FLAGS" - "BMA2x2_I2C_ADDR2_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-accel.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-accel.yaml new file mode 100644 index 0000000000..ba7fbb3878 --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-accel.yaml @@ -0,0 +1,13 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: motion sense sensor node for ICM42607 accel + +compatible: "cros-ec,icm42607-accel" + +include: icm42607.yaml + +properties: + default-range: + default: 4 diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-gyro.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-gyro.yaml new file mode 100644 index 0000000000..4707f33d6d --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,icm42607-gyro.yaml @@ -0,0 +1,13 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: motion sense sensor node for ICM42607 gyro + +compatible: "cros-ec,icm42607-gyro" + +include: icm42607.yaml + +properties: + default-range: + default: 1000 diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,kx022.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,kx022.yaml index b90d824575..8aecc32077 100644 --- a/zephyr/dts/bindings/motionsense/driver/cros-ec,kx022.yaml +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,kx022.yaml @@ -12,7 +12,7 @@ include: motionsense-sensor-base.yaml properties: i2c-spi-addr-flags: type: string - description: i2c address or SPI slave logic GPIO + description: i2c address or SPI peripheral logic GPIO enum: - "KX022_ADDR0_FLAGS" - "KX022_ADDR1_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-accel.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-accel.yaml new file mode 100644 index 0000000000..5c3c6172f0 --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-accel.yaml @@ -0,0 +1,13 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: motionsense sensor node for LSM6DSO Accelerometer + +compatible: "cros-ec,lsm6dso-accel" + +include: lsm6dso.yaml + +properties: + default-range: + default: 2 diff --git a/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-gyro.yaml b/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-gyro.yaml new file mode 100644 index 0000000000..a10a98d97f --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/cros-ec,lsm6dso-gyro.yaml @@ -0,0 +1,13 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: motionsense sensor node for LSM6DSO Gyro + +compatible: "cros-ec,lsm6dso-gyro" + +include: lsm6dso.yaml + +properties: + default-range: + default: 1000 diff --git a/zephyr/dts/bindings/motionsense/driver/icm42607.yaml b/zephyr/dts/bindings/motionsense/driver/icm42607.yaml new file mode 100644 index 0000000000..f47e7a2f97 --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/icm42607.yaml @@ -0,0 +1,17 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# common fields for both ICM426xx accel and gyro + +# every motionsense sensor node should include motionsense-sensor-base.yaml +include: motionsense-sensor-base.yaml + +properties: + i2c-spi-addr-flags: + type: string + description: i2c address or SPI peripheral logic GPIO + enum: + - "ICM42607_ADDR0_FLAGS" + - "ICM42607_ADDR1_FLAGS" + default: "ICM42607_ADDR0_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/driver/lsm6dso.yaml b/zephyr/dts/bindings/motionsense/driver/lsm6dso.yaml new file mode 100644 index 0000000000..dd345854be --- /dev/null +++ b/zephyr/dts/bindings/motionsense/driver/lsm6dso.yaml @@ -0,0 +1,19 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# common fields for both LSM6DSO accel and gyro + +# every motionsense sensor node should include motionsense-sensor-base.yaml +include: motionsense-sensor-base.yaml + +properties: + i2c-spi-addr-flags: + type: string + description: i2c address or SPI peripheral logic GPIO + # Address is b'0110101x' where x is determined by the + # logic level on SA0 + enum: + - "LSM6DSO_ADDR0_FLAGS" + - "LSM6DSO_ADDR1_FLAGS" + default: "LSM6DSO_ADDR0_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/driver/tcs3400.yaml b/zephyr/dts/bindings/motionsense/driver/tcs3400.yaml index 2fc3d7eacd..ecad7ec1a7 100644 --- a/zephyr/dts/bindings/motionsense/driver/tcs3400.yaml +++ b/zephyr/dts/bindings/motionsense/driver/tcs3400.yaml @@ -10,7 +10,7 @@ include: motionsense-sensor-base.yaml properties: i2c-spi-addr-flags: type: string - description: i2c address or SPI slave logic GPIO + description: i2c address or SPI peripheral logic GPIO enum: - "TCS3400_I2C_ADDR_FLAGS" default: "TCS3400_I2C_ADDR_FLAGS" diff --git a/zephyr/dts/bindings/motionsense/drvdata/cros-ec,drvdata-lsm6dso.yaml b/zephyr/dts/bindings/motionsense/drvdata/cros-ec,drvdata-lsm6dso.yaml new file mode 100644 index 0000000000..d3a37da9a1 --- /dev/null +++ b/zephyr/dts/bindings/motionsense/drvdata/cros-ec,drvdata-lsm6dso.yaml @@ -0,0 +1,18 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: LSM6DSO driver data node + +compatible: "cros-ec,drvdata-lsm6dso" + +include: drvdata-base.yaml + +# +# examples: +# +# lsm6dso_data: lsm6dso-drv-data { +# compatible = "cros-ec,drvdata-lsm6dso"; +# status = "okay"; +# }; +# diff --git a/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml b/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml index 6adaa22ee5..9e4aa8e3f7 100644 --- a/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml +++ b/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml @@ -58,13 +58,10 @@ properties: type: phandle description: phandle to another sensor that can be swapped with this one at runtime. - alternate-indicator: + alternate-ssfc-indicator: type: phandle - description: phandle to CBI SSGC value indicating that the sensor + description: phandle to CBI SSFC value indicating that the sensor should be used - runtime-probe: - type: boolean - description: runtime probing of sensor will be executed if true int-signal: type: phandle description: pin which triggers interrupt for sensor diff --git a/zephyr/projects/corsola/kingler/BUILD.py b/zephyr/dts/bindings/pmic/mps,mp2964.yaml index 5a4b9722ea..db35aa07b2 100644 --- a/zephyr/projects/corsola/kingler/BUILD.py +++ b/zephyr/dts/bindings/pmic/mps,mp2964.yaml @@ -2,8 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -register_npcx_project( - project_name="kingler", - zephyr_board="npcx9", - dts_overlays=["battery.dts", "gpio.dts", "i2c.dts"], -) +description: MPS MP2964 Power Management IC + +compatible: "mps,mp2964" + +include: i2c-device.yaml diff --git a/zephyr/dts/bindings/pwm/named-pwms.yaml b/zephyr/dts/bindings/pwm/named-pwms.yaml index f01fd5a30a..3e5c1c789f 100644 --- a/zephyr/dts/bindings/pwm/named-pwms.yaml +++ b/zephyr/dts/bindings/pwm/named-pwms.yaml @@ -12,12 +12,6 @@ child-binding: pwms: type: phandle-array required: true - label: - required: true - type: string - description: - Human readable string describing the device (used as - device_get_binding() argument) frequency: required: true type: int diff --git a/zephyr/dts/bindings/temp/cros_ec_temp_sensor.yaml b/zephyr/dts/bindings/temp/cros_ec_temp_sensor.yaml index a60cdda954..f1f1dcd41c 100644 --- a/zephyr/dts/bindings/temp/cros_ec_temp_sensor.yaml +++ b/zephyr/dts/bindings/temp/cros_ec_temp_sensor.yaml @@ -7,18 +7,7 @@ description: > Zero values in degrees K(-273 in degrees C)in thermal thresholds will be ignored -compatible: cros-ec,temp-sensor - properties: - adc: - required: true - type: phandle - description: The named adc channel - - thermistor: - type: phandle - description: Underlying thermistor device if used - label: required: true type: string @@ -32,10 +21,16 @@ properties: description: Enum values used in the source code to refer to the temperature sensors enum: + - TEMP_SENSOR_1 + - TEMP_SENSOR_2 + - TEMP_SENSOR_AMB - TEMP_SENSOR_CHARGER + - TEMP_SENSOR_CPU - TEMP_SENSOR_DDR_SOC - TEMP_SENSOR_FAN + - TEMP_SENSOR_MEMORY - TEMP_SENSOR_PP3300_REGULATOR + - TEMP_SENSOR_SOC - TEMP_SENSOR_1_DDR_SOC - TEMP_SENSOR_2_AMBIENT - TEMP_SENSOR_3_CHARGER diff --git a/zephyr/dts/bindings/temp/cros_ec_temp_sensor_thermistor.yaml b/zephyr/dts/bindings/temp/cros_ec_temp_sensor_thermistor.yaml new file mode 100644 index 0000000000..34acbebcae --- /dev/null +++ b/zephyr/dts/bindings/temp/cros_ec_temp_sensor_thermistor.yaml @@ -0,0 +1,20 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: > + Properties for a thermistor temperature sensor + +include: cros_ec_temp_sensor.yaml + +compatible: cros-ec,temp-sensor-thermistor + +properties: + adc: + required: true + type: phandle + description: The named adc channel + + thermistor: + type: phandle + description: Underlying thermistor device diff --git a/zephyr/dts/bindings/temp/cros_ec_temp_sensor_tmp112.yaml b/zephyr/dts/bindings/temp/cros_ec_temp_sensor_tmp112.yaml new file mode 100644 index 0000000000..0cf05f48a0 --- /dev/null +++ b/zephyr/dts/bindings/temp/cros_ec_temp_sensor_tmp112.yaml @@ -0,0 +1,35 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: > + Properties for a TMP112 I2C temperature sensor + +include: cros_ec_temp_sensor.yaml + +compatible: cros-ec,temp-sensor-tmp112 + +properties: + tmp112-name: + type: string + required: true + description: + Enum value to index into the TMP112 specific sensors + enum: + - TMP112_SOC + - TMP112_AMB + + port: + required: true + type: phandle + description: phandle to the named i2c port + + i2c-addr-flags: + required: true + type: string + description: I2C address of chip + enum: + - TMP112_I2C_ADDR_FLAGS0 + - TMP112_I2C_ADDR_FLAGS1 + - TMP112_I2C_ADDR_FLAGS2 + - TMP112_I2C_ADDR_FLAGS3 diff --git a/zephyr/dts/bindings/usbc/nuvoton,nct38xx.yaml b/zephyr/dts/bindings/usbc/nuvoton,nct38xx.yaml new file mode 100644 index 0000000000..2d85d14f79 --- /dev/null +++ b/zephyr/dts/bindings/usbc/nuvoton,nct38xx.yaml @@ -0,0 +1,14 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: Nuvoton NCT38XX USB TCPC binding + +compatible: "nuvoton,nct38xx" + +properties: + gpio-dev: + type: phandle + description: | + Pointer to the NCT38XX GPIO device. This is used to binding the Cros TCPC + port index to Zephyr NCT38XX GPIO device. diff --git a/zephyr/dts/bindings/usbc/pericom,pi3usb9201.yaml b/zephyr/dts/bindings/usbc/pericom,pi3usb9201.yaml index d72fa20a47..41e1501684 100644 --- a/zephyr/dts/bindings/usbc/pericom,pi3usb9201.yaml +++ b/zephyr/dts/bindings/usbc/pericom,pi3usb9201.yaml @@ -11,7 +11,6 @@ properties: irq: type: phandles - required: true description: | GPIO interrupt from BC1.2 diff --git a/zephyr/dts/bindings/usbc/silergy,syv682x.yaml b/zephyr/dts/bindings/usbc/silergy,syv682x.yaml index 51484e1792..046f9e09fe 100644 --- a/zephyr/dts/bindings/usbc/silergy,syv682x.yaml +++ b/zephyr/dts/bindings/usbc/silergy,syv682x.yaml @@ -11,4 +11,4 @@ properties: - "SYV682X_ADDR0_FLAGS" - "SYV682X_ADDR1_FLAGS" - "SYV682X_ADDR2_FLAGS" - - "SYV682x_ADDR3_FLAGS" + - "SYV682X_ADDR3_FLAGS" diff --git a/zephyr/dts/bindings/vendor-prefixes.txt b/zephyr/dts/bindings/vendor-prefixes.txt index 856fa81426..7402b7e579 100644 --- a/zephyr/dts/bindings/vendor-prefixes.txt +++ b/zephyr/dts/bindings/vendor-prefixes.txt @@ -6,3 +6,4 @@ # Zephyr module. The format is: # vendor-prefix<TAB>vendor name cros-ec The Chromium OS Embedded Controller Project +cros The Chromium OS Embedded Controller Project diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt index 030ae7cc51..8d96d46029 100644 --- a/zephyr/emul/CMakeLists.txt +++ b/zephyr/emul/CMakeLists.txt @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +add_subdirectory("tcpc") + zephyr_library_sources_ifdef(CONFIG_EMUL_COMMON_I2C emul_common_i2c.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SMART_BATTERY emul_smart_battery.c) zephyr_library_sources_ifdef(CONFIG_EMUL_BMA255 emul_bma255.c) @@ -17,7 +19,4 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_LIS2DW12 emul_lis2dw12.c) zephyr_library_sources_ifdef(CONFIG_I2C_MOCK i2c_mock.c) zephyr_library_sources_ifdef(CONFIG_EMUL_ISL923X emul_isl923x.c) zephyr_library_sources_ifdef(CONFIG_EMUL_CLOCK_CONTROL emul_clock_control.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI emul_tcpci.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SN5S330 emul_sn5s330.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_PS8XXX emul_ps8xxx.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_CHARGER emul_charger.c) diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig index a6b39405c6..7e1e869b39 100644 --- a/zephyr/emul/Kconfig +++ b/zephyr/emul/Kconfig @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +rsource "tcpc/Kconfig" + config EMUL_COMMON_I2C bool "Common handler for I2C emulator messages" help @@ -72,5 +74,4 @@ rsource "Kconfig.lis2dw12" rsource "Kconfig.i2c_mock" rsource "Kconfig.isl923x" rsource "Kconfig.clock_control" -rsource "Kconfig.tcpci" rsource "Kconfig.sn5s330" diff --git a/zephyr/emul/Kconfig.ln9310 b/zephyr/emul/Kconfig.ln9310 index 5773cf3721..c9e3e6fbc9 100644 --- a/zephyr/emul/Kconfig.ln9310 +++ b/zephyr/emul/Kconfig.ln9310 @@ -8,6 +8,7 @@ menuconfig EMUL_LN9310 bool "LN9310 switchcap emulator" default $(dt_compat_enabled,$(DT_COMPAT_LN9310_EMUL)) depends on I2C_EMUL + depends on ASSERT help Enable the LN9310 emulator. This driver uses the emulated I2C bus. It is used to test the ln9310 driver. Emulator API is available in diff --git a/zephyr/emul/Kconfig.sn5s330 b/zephyr/emul/Kconfig.sn5s330 index aba3bb9028..bb3e5eeea8 100644 --- a/zephyr/emul/Kconfig.sn5s330 +++ b/zephyr/emul/Kconfig.sn5s330 @@ -8,6 +8,7 @@ menuconfig EMUL_SN5S330 bool "sn5s330 emulator" default $(dt_compat_enabled,$(DT_COMPAT_SN5S330_EMUL)) depends on I2C_EMUL + depends on ASSERT help Enable the sn5s330 emulator. This driver uses the emulated I2C bus. It is used to test the sn5s330 driver. Emulator API is available in diff --git a/zephyr/emul/Kconfig.tcpci b/zephyr/emul/Kconfig.tcpci deleted file mode 100644 index fc4b1bcda4..0000000000 --- a/zephyr/emul/Kconfig.tcpci +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -DT_COMPAT_TCPCI_EMUL := cros,tcpci-emul - -menuconfig EMUL_TCPCI - bool "TCPCI emulator" - default $(dt_compat_enabled,$(DT_COMPAT_TCPCI_EMUL)) - depends on I2C_EMUL - help - Enable the TCPCI emulator. This driver uses the emulated I2C bus. - It is used to test tcpci code. It supports reads and writes to all - emulator registers. Generic TCPCI emulator can be used as the base - for specific TCPC device emulator that follow TCPCI specification. - TCPCI emulator API is available in zephyr/include/emul/emul_tcpci.h - -if EMUL_TCPCI - -module = TCPCI_EMUL -module-str = tcpci_emul -source "subsys/logging/Kconfig.template.log_config" - -config EMUL_PS8XXX - bool "Parade PS8XXX emulator" - help - Enable emulator for PS8XXX family of TCPC. This emulator is extenstion - for TCPCI emulator. PS8XXX specific API is available in - zephyr/include/emul/emul_tcpci.h - -config EMUL_CHARGER - bool "USB-C charger emulator" - help - Enable USB-C charger emulator which may be attached to TCPCI emulator. - API of charger emulator is available in - zephyr/include/emul/emul_charger.h - -endif # EMUL_TCPCI diff --git a/zephyr/emul/emul_charger.c b/zephyr/emul/emul_charger.c deleted file mode 100644 index d584ab882b..0000000000 --- a/zephyr/emul/emul_charger.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <logging/log.h> -LOG_MODULE_REGISTER(charger_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL); - -#include <zephyr.h> - -#include "common.h" -#include "emul/emul_charger.h" -#include "emul/emul_tcpci.h" -#include "usb_pd.h" - -/** Structure of message used by USB-C charger emulator */ -struct charger_emul_msg { - /** Reserved for k_fifo_* usage */ - void *fifo_reserved; - /** TCPCI emulator message */ - struct tcpci_emul_msg msg; - /** Time when message should be sent if message is delayed */ - uint64_t time; -}; - -/** - * @brief Allocate message - * - * @param size Size of message buffer - * - * @return Pointer to new message on success - * @return NULL on error - */ -static struct charger_emul_msg *charger_emul_alloc_msg(size_t size) -{ - struct charger_emul_msg *new_msg; - - new_msg = k_malloc(sizeof(struct charger_emul_msg)); - if (new_msg == NULL) { - return NULL; - } - - new_msg->msg.buf = k_malloc(size); - if (new_msg->msg.buf == NULL) { - k_free(new_msg); - return NULL; - } - - /* TCPCI message size count include type byte */ - new_msg->msg.cnt = size + 1; - - return new_msg; -} - -/** - * @brief Free message's memory - * - * @param msg Pointer to message - */ -static void charger_emul_free_msg(struct charger_emul_msg *msg) -{ - k_free(msg->msg.buf); - k_free(msg); -} - -/** - * @brief Set header of the message - * - * @param data Pointer to USB-C charger emulator - * @param msg Pointer to message - * @param type Type of message - * @param cnt Number of data objects - */ -static void charger_emul_set_header(struct charger_emul_data *data, - struct charger_emul_msg *msg, - int type, int cnt) -{ - /* Header msg id has only 3 bits and wraps around after 8 messages */ - uint16_t msg_id = data->msg_id & 0x7; - uint16_t header = PD_HEADER(type, PD_ROLE_SOURCE, PD_ROLE_UFP, msg_id, - cnt, PD_REV20, 0 /* ext */); - data->msg_id++; - - msg->msg.buf[1] = (header >> 8) & 0xff; - msg->msg.buf[0] = header & 0xff; -} - -/** - * @brief Work function which sends delayed messages - * - * @param work Pointer to work structure - */ -static void charger_emul_delayed_send(struct k_work *work) -{ - struct k_work_delayable *kwd = k_work_delayable_from_work(work); - struct charger_emul_data *data = CONTAINER_OF(kwd, - struct charger_emul_data, - delayed_send); - struct charger_emul_msg *msg; - uint64_t now; - int ec; - - while (!k_fifo_is_empty(&data->to_send)) { - /* - * It is safe to not check msg == NULL, because this thread is - * the only one consumer - */ - msg = k_fifo_peek_head(&data->to_send); - - now = k_uptime_get(); - if (now >= msg->time) { - k_fifo_get(&data->to_send, K_FOREVER); - ec = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg, - true /* send alert */); - if (ec) { - charger_emul_free_msg(msg); - } - } else { - k_work_reschedule(kwd, K_MSEC(msg->time - now)); - break; - } - } -} - -/** - * @brief Send message to TCPCI emulator or schedule message - * - * @param data Pointer to USB-C charger emulator - * @param msg Pointer to message to send - * @param delay Optional delay - * - * @return 0 on success - * @return -EINVAL on TCPCI emulator add RX message error - */ -static int charger_emul_send_msg(struct charger_emul_data *data, - struct charger_emul_msg *msg, uint64_t delay) -{ - uint64_t now; - int ec; - - if (delay == 0) { - ec = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg, true); - if (ec) { - charger_emul_free_msg(msg); - } - - return ec; - } - - now = k_uptime_get(); - msg->time = now + delay; - k_fifo_put(&data->to_send, msg); - /* - * This will change execution time of delayed_send only if it is not - * already scheduled - */ - k_work_schedule(&data->delayed_send, K_MSEC(delay)); - - return 0; -} - -/** - * @brief Send capability message which for now is hardcoded - * - * @param data Pointer to USB-C charger emulator - * @param delay Optional delay - * - * @return 0 on success - * @return -ENOMEM when there is no free memory for message - * @return -EINVAL on TCPCI emulator add RX message error - */ -static int charger_emul_send_capability_msg(struct charger_emul_data *data, - uint64_t delay) -{ - struct charger_emul_msg *msg; - - msg = charger_emul_alloc_msg(6); - if (msg == NULL) { - return -ENOMEM; - } - - /* Capability with 5v@3A */ - charger_emul_set_header(data, msg, PD_DATA_SOURCE_CAP, 1); - - /* Fixed supply (type of supply) 0xc0 */ - msg->msg.buf[5] = 0x00; - /* Dual role capable 0x20 */ - msg->msg.buf[5] |= 0x00; - /* Unconstrained power 0x08 */ - msg->msg.buf[5] |= 0x08; - - /* 5V on bits 19-10 */ - msg->msg.buf[4] = 0x1; - msg->msg.buf[3] = 0x90; - /* 3A on bits 9-0 */ - msg->msg.buf[3] |= 0x1; - msg->msg.buf[2] = 0x2c; - - /* Fill tcpci message structure */ - msg->msg.type = TCPCI_MSG_SOP; - - return charger_emul_send_msg(data, msg, delay); -} - -/** - * @brief Send control message with optional delay - * - * @param data Pointer to USB-C charger emulator - * @param type Type of message - * @param delay Optional delay - * - * @return 0 on success - * @return -ENOMEM when there is no free memory for message - * @return -EINVAL on TCPCI emulator add RX message error - */ -static int charger_emul_send_control_msg(struct charger_emul_data *data, - enum pd_ctrl_msg_type type, - uint64_t delay) -{ - struct charger_emul_msg *msg; - - msg = charger_emul_alloc_msg(2); - if (msg == NULL) { - return -ENOMEM; - } - - charger_emul_set_header(data, msg, type, 0); - - /* Fill tcpci message structure */ - msg->msg.type = TCPCI_MSG_SOP; - - return charger_emul_send_msg(data, msg, delay); -} - -/** - * @brief Function called when TCPM wants to transmit message. Accept received - * message and generate response. - * - * @param emul Pointer to TCPCI emulator - * @param ops Pointer to partner operations structure - * @param tx_msg Pointer to TX message buffer - * @param type Type of message - * @param retry Count of retries - */ -static void charger_emul_transmit_op(const struct emul *emul, - const struct tcpci_emul_partner_ops *ops, - const struct tcpci_emul_msg *tx_msg, - enum tcpci_msg_type type, - int retry) -{ - struct charger_emul_data *data = CONTAINER_OF(ops, - struct charger_emul_data, - ops); - uint16_t header; - - /* Acknowledge that message was sent successfully */ - tcpci_emul_partner_msg_status(emul, TCPCI_EMUL_TX_SUCCESS); - - /* Handle only SOP messages */ - if (type != TCPCI_MSG_SOP) { - return; - } - - LOG_HEXDUMP_DBG(tx_msg->buf, tx_msg->cnt, "Charger received message"); - - header = (tx_msg->buf[1] << 8) | tx_msg->buf[0]; - - if (PD_HEADER_CNT(header)) { - /* Handle data message */ - switch (PD_HEADER_TYPE(header)) { - case PD_DATA_REQUEST: - charger_emul_send_control_msg(data, PD_CTRL_ACCEPT, 0); - /* PS ready after 15 ms */ - charger_emul_send_control_msg(data, PD_CTRL_PS_RDY, 15); - break; - case PD_DATA_VENDOR_DEF: - /* VDM (vendor defined message) - ignore */ - break; - default: - charger_emul_send_control_msg(data, PD_CTRL_REJECT, 0); - break; - } - } else { - /* Handle control message */ - switch (PD_HEADER_TYPE(header)) { - case PD_CTRL_GET_SOURCE_CAP: - charger_emul_send_capability_msg(data, 0); - break; - case PD_CTRL_GET_SINK_CAP: - charger_emul_send_control_msg(data, PD_CTRL_REJECT, 0); - break; - case PD_CTRL_DR_SWAP: - charger_emul_send_control_msg(data, PD_CTRL_REJECT, 0); - break; - case PD_CTRL_SOFT_RESET: - data->msg_id = 0; - charger_emul_send_control_msg(data, PD_CTRL_ACCEPT, 0); - /* Send capability after 15 ms to establish PD again */ - charger_emul_send_capability_msg(data, 15); - break; - default: - charger_emul_send_control_msg(data, PD_CTRL_REJECT, 0); - break; - } - } -} - -/** - * @brief Function called when TCPM consumes message. Free message that is no - * longer needed. - * - * @param emul Pointer to TCPCI emulator - * @param ops Pointer to partner operations structure - * @param rx_msg Message that was consumed by TCPM - */ -static void charger_emul_rx_consumed_op( - const struct emul *emul, - const struct tcpci_emul_partner_ops *ops, - const struct tcpci_emul_msg *rx_msg) -{ - struct charger_emul_msg *msg = CONTAINER_OF(rx_msg, - struct charger_emul_msg, - msg); - - charger_emul_free_msg(msg); -} - -/** Check description in emul_charger.h */ -int charger_emul_connect_to_tcpci(struct charger_emul_data *data, - const struct emul *tcpci_emul) -{ - int ec; - - tcpci_emul_set_partner_ops(tcpci_emul, &data->ops); - ec = tcpci_emul_connect_partner(tcpci_emul, PD_ROLE_SOURCE, - TYPEC_CC_VOLT_RP_3_0, - TYPEC_CC_VOLT_OPEN, POLARITY_CC1); - if (ec) { - return ec; - } - - data->tcpci_emul = tcpci_emul; - - return charger_emul_send_capability_msg(data, 0); -} - -/** Check description in emul_charger.h */ -void charger_emul_init(struct charger_emul_data *data) -{ - k_work_init_delayable(&data->delayed_send, charger_emul_delayed_send); - k_fifo_init(&data->to_send); - - data->ops.transmit = charger_emul_transmit_op; - data->ops.rx_consumed = charger_emul_rx_consumed_op; -} diff --git a/zephyr/emul/emul_isl923x.c b/zephyr/emul/emul_isl923x.c index e7a286e6fb..05ec6bdc52 100644 --- a/zephyr/emul/emul_isl923x.c +++ b/zephyr/emul/emul_isl923x.c @@ -16,6 +16,7 @@ #include "driver/charger/isl923x_public.h" #include "emul/emul_common_i2c.h" #include "emul/emul_isl923x.h" +#include "emul/emul_smart_battery.h" #include "i2c.h" #include <logging/log.h> @@ -28,6 +29,9 @@ LOG_MODULE_REGISTER(isl923x_emul, CONFIG_ISL923X_EMUL_LOG_LEVEL); /** Mask used for the charge current register */ #define REG_CHG_CURRENT_MASK GENMASK(12, 2) +/** Mask used for the system voltage min register */ +#define REG_SYS_VOLTAGE_MIN_MASK GENMASK(13, 8) + /** Mask used for the system voltage max register */ #define REG_SYS_VOLTAGE_MAX_MASK GENMASK(14, 3) @@ -49,12 +53,22 @@ LOG_MODULE_REGISTER(isl923x_emul, CONFIG_ISL923X_EMUL_LOG_LEVEL); /** Mask used for the control 3 register */ #define REG_CONTROL3_MASK GENMASK(15, 0) +/** Mask used for the control 4 register */ +#define REG_CONTROL4_MASK GENMASK(15, 0) + +/** Mask used for the control 8 register */ +#define REG_CONTROL8_MASK GENMASK(15, 0) + /** Mask used for the AC PROCHOT register */ #define REG_PROCHOT_AC_MASK GENMASK(12, 7) /** Mask used for the DC PROCHOT register */ #define REG_PROCHOT_DC_MASK GENMASK(13, 8) +#define DEFAULT_R_SNS 10 +#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR +#define REG_TO_CURRENT(REG) ((REG) * DEFAULT_R_SNS / R_SNS) + struct isl923x_emul_data { /** Common I2C data */ struct i2c_common_emul_data common; @@ -64,6 +78,8 @@ struct isl923x_emul_data { uint16_t adapter_current_limit1_reg; /** Emulated adapter current limit 2 register */ uint16_t adapter_current_limit2_reg; + /** Emulated min voltage register */ + uint16_t min_volt_reg; /** Emulated max voltage register */ uint16_t max_volt_reg; /** Emulated manufacturer ID register */ @@ -78,12 +94,20 @@ struct isl923x_emul_data { uint16_t control_2_reg; /** Emulated control 3 register */ uint16_t control_3_reg; + /** Emulated control 4 register */ + uint16_t control_4_reg; + /** Emulated control 8 register (RAA489000-only) */ + uint16_t control_8_reg; + /** Emulated info 2 reg */ + uint16_t info_2_reg; /** Emulated AC PROCHOT register */ uint16_t ac_prochot_reg; /** Emulated DC PROCHOT register */ uint16_t dc_prochot_reg; /** Emulated ADC vbus register */ uint16_t adc_vbus_reg; + /** Pointer to battery emulator. */ + int battery_ord; }; struct isl923x_emul_cfg { @@ -109,9 +133,11 @@ void isl923x_emul_reset(const struct emul *emulator) { struct isl923x_emul_data *data = emulator->data; struct i2c_common_emul_data common_backup = data->common; + int battery_ord = data->battery_ord; memset(data, 0, sizeof(struct isl923x_emul_data)); data->common = common_backup; + data->battery_ord = battery_ord; } void isl923x_emul_set_manufacturer_id(const struct emul *emulator, @@ -157,6 +183,27 @@ void isl923x_emul_set_adc_vbus(const struct emul *emulator, data->adc_vbus_reg = value & GENMASK(13, 6); } +void raa489000_emul_set_acok_pin(const struct emul *emulator, uint16_t value) +{ + struct isl923x_emul_data *data = emulator->data; + + if (value) + data->info_2_reg |= RAA489000_INFO2_ACOK; + else + data->info_2_reg &= ~RAA489000_INFO2_ACOK; +} + +/** Convenience macro for reading 16-bit registers */ +#define READ_REG_16(REG, BYTES, OUT) \ + do { \ + __ASSERT_NO_MSG((BYTES) == 0 || (BYTES) == 1); \ + if ((BYTES) == 0) \ + *(OUT) = (uint8_t)((REG)&0xff); \ + else \ + *(OUT) = (uint8_t)(((REG) >> 8) & 0xff); \ + break; \ + } while (0) + static int isl923x_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, int bytes) { @@ -164,109 +211,84 @@ static int isl923x_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, switch (reg) { case ISL923X_REG_CHG_CURRENT: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->current_limit_reg & 0xff); - else - *val = (uint8_t)((data->current_limit_reg >> 8) & 0xff); + READ_REG_16(data->current_limit_reg, bytes, val); + break; + case ISL923X_REG_SYS_VOLTAGE_MIN: + READ_REG_16(data->min_volt_reg, bytes, val); break; case ISL923X_REG_SYS_VOLTAGE_MAX: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->max_volt_reg & 0xff); - else - *val = (uint8_t)((data->max_volt_reg >> 8) & 0xff); + READ_REG_16(data->max_volt_reg, bytes, val); break; case ISL923X_REG_ADAPTER_CURRENT_LIMIT1: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->adapter_current_limit1_reg & - 0xff); - else - *val = (uint8_t)((data->adapter_current_limit1_reg >> - 8) & - 0xff); + READ_REG_16(data->adapter_current_limit1_reg, bytes, val); break; case ISL923X_REG_ADAPTER_CURRENT_LIMIT2: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->adapter_current_limit2_reg & - 0xff); - else - *val = (uint8_t)((data->adapter_current_limit2_reg >> - 8) & - 0xff); + READ_REG_16(data->adapter_current_limit2_reg, bytes, val); break; case ISL923X_REG_MANUFACTURER_ID: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->manufacturer_id_reg & 0xff); - else - *val = (uint8_t)((data->manufacturer_id_reg >> 8) & - 0xff); + READ_REG_16(data->manufacturer_id_reg, bytes, val); break; case ISL923X_REG_DEVICE_ID: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->device_id_reg & 0xff); - else - *val = (uint8_t)((data->device_id_reg >> 8) & 0xff); + READ_REG_16(data->device_id_reg, bytes, val); break; case ISL923X_REG_CONTROL0: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->control_0_reg & 0xff); - else - *val = (uint8_t)((data->control_0_reg >> 8) & 0xff); + READ_REG_16(data->control_0_reg, bytes, val); break; case ISL923X_REG_CONTROL1: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->control_1_reg & 0xff); - else - *val = (uint8_t)((data->control_1_reg >> 8) & 0xff); + READ_REG_16(data->control_1_reg, bytes, val); break; case ISL923X_REG_CONTROL2: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->control_2_reg & 0xff); - else - *val = (uint8_t)((data->control_2_reg >> 8) & 0xff); + READ_REG_16(data->control_2_reg, bytes, val); break; case ISL9238_REG_CONTROL3: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->control_3_reg & 0xff); - else - *val = (uint8_t)((data->control_3_reg >> 8) & 0xff); + READ_REG_16(data->control_3_reg, bytes, val); + break; + case ISL9238_REG_CONTROL4: + READ_REG_16(data->control_4_reg, bytes, val); + break; + case RAA489000_REG_CONTROL8: + READ_REG_16(data->control_8_reg, bytes, val); + break; + case ISL9238_REG_INFO2: + READ_REG_16(data->info_2_reg, bytes, val); break; case ISL923X_REG_PROCHOT_AC: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->ac_prochot_reg & 0xff); - else - *val = (uint8_t)((data->ac_prochot_reg >> 8) & 0xff); + READ_REG_16(data->ac_prochot_reg, bytes, val); break; case ISL923X_REG_PROCHOT_DC: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->dc_prochot_reg & 0xff); - else - *val = (uint8_t)((data->dc_prochot_reg >> 8) & 0xff); + READ_REG_16(data->dc_prochot_reg, bytes, val); break; case RAA489000_REG_ADC_VBUS: - __ASSERT_NO_MSG(bytes == 0 || bytes == 1); - if (bytes == 0) - *val = (uint8_t)(data->adc_vbus_reg & 0xff); - else - *val = (uint8_t)((data->adc_vbus_reg >> 8) & 0xff); + READ_REG_16(data->adc_vbus_reg, bytes, val); break; default: + __ASSERT(false, "Attempt to read unimplemented reg 0x%02x", + reg); return -EINVAL; } return 0; } +uint16_t isl923x_emul_peek_reg(struct i2c_emul *i2c_emul, int reg) +{ + uint8_t bytes[2]; + + isl923x_emul_read_byte(i2c_emul, reg, &bytes[0], 0); + isl923x_emul_read_byte(i2c_emul, reg, &bytes[1], 1); + + return bytes[1] << 8 | bytes[0]; +} + +/** Convenience macro for writing 16-bit registers */ +#define WRITE_REG_16(REG, BYTES, VAL, MASK) \ + do { \ + __ASSERT_NO_MSG((BYTES) == 1 || (BYTES) == 2); \ + if ((BYTES) == 1) \ + (REG) = (VAL) & (MASK); \ + else \ + (REG) |= ((VAL) << 8) & (MASK); \ + } while (0) + static int isl923x_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, int bytes) { @@ -274,89 +296,97 @@ static int isl923x_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, switch (reg) { case ISL923X_REG_CHG_CURRENT: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->current_limit_reg = val & REG_CHG_CURRENT_MASK; - else - data->current_limit_reg |= (val << 8) & - REG_CHG_CURRENT_MASK; + WRITE_REG_16(data->current_limit_reg, bytes, val, + REG_CHG_CURRENT_MASK); + break; + case ISL923X_REG_SYS_VOLTAGE_MIN: + WRITE_REG_16(data->min_volt_reg, bytes, val, + REG_SYS_VOLTAGE_MIN_MASK); break; case ISL923X_REG_SYS_VOLTAGE_MAX: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->max_volt_reg = val & REG_SYS_VOLTAGE_MAX_MASK; - else - data->max_volt_reg |= (val << 8) & - REG_SYS_VOLTAGE_MAX_MASK; + WRITE_REG_16(data->max_volt_reg, bytes, val, + REG_SYS_VOLTAGE_MAX_MASK); break; case ISL923X_REG_ADAPTER_CURRENT_LIMIT1: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->adapter_current_limit1_reg = - val & REG_ADAPTER_CURRENT_LIMIT1_MASK; - else - data->adapter_current_limit1_reg |= - (val << 8) & REG_ADAPTER_CURRENT_LIMIT1_MASK; + WRITE_REG_16(data->adapter_current_limit1_reg, bytes, val, + REG_ADAPTER_CURRENT_LIMIT1_MASK); break; case ISL923X_REG_ADAPTER_CURRENT_LIMIT2: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->adapter_current_limit2_reg = - val & REG_ADAPTER_CURRENT_LIMIT2_MASK; - else - data->adapter_current_limit2_reg |= - (val << 8) & REG_ADAPTER_CURRENT_LIMIT2_MASK; + WRITE_REG_16(data->adapter_current_limit2_reg, bytes, val, + REG_ADAPTER_CURRENT_LIMIT2_MASK); break; case ISL923X_REG_CONTROL0: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->control_0_reg = val & REG_CONTROL0_MASK; - else - data->control_0_reg |= (val << 8) & REG_CONTROL0_MASK; + WRITE_REG_16(data->control_0_reg, bytes, val, + REG_CONTROL0_MASK); break; case ISL923X_REG_CONTROL1: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->control_1_reg = val & REG_CONTROL1_MASK; - else - data->control_1_reg |= (val << 8) & REG_CONTROL1_MASK; + WRITE_REG_16(data->control_1_reg, bytes, val, + REG_CONTROL1_MASK); break; case ISL923X_REG_CONTROL2: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->control_2_reg = val & REG_CONTROL2_MASK; - else - data->control_2_reg |= (val << 8) & REG_CONTROL2_MASK; + WRITE_REG_16(data->control_2_reg, bytes, val, + REG_CONTROL2_MASK); break; case ISL9238_REG_CONTROL3: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->control_3_reg = val & REG_CONTROL3_MASK; - else - data->control_3_reg |= (val << 8) & REG_CONTROL3_MASK; + WRITE_REG_16(data->control_3_reg, bytes, val, + REG_CONTROL3_MASK); + break; + case ISL9238_REG_CONTROL4: + WRITE_REG_16(data->control_4_reg, bytes, val, + REG_CONTROL4_MASK); + break; + case RAA489000_REG_CONTROL8: + WRITE_REG_16(data->control_8_reg, bytes, val, + REG_CONTROL8_MASK); + break; + case ISL9238_REG_INFO2: + __ASSERT(false, "Write to read-only reg ISL9238_REG_INFO2"); break; case ISL923X_REG_PROCHOT_AC: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->ac_prochot_reg = val & REG_PROCHOT_AC_MASK; - else - data->ac_prochot_reg |= (val << 8) & - REG_PROCHOT_AC_MASK; + WRITE_REG_16(data->ac_prochot_reg, bytes, val, + REG_PROCHOT_AC_MASK); break; case ISL923X_REG_PROCHOT_DC: - __ASSERT_NO_MSG(bytes == 1 || bytes == 2); - if (bytes == 1) - data->dc_prochot_reg = val & REG_PROCHOT_DC_MASK; - else - data->dc_prochot_reg |= (val << 8) & - REG_PROCHOT_DC_MASK; + WRITE_REG_16(data->dc_prochot_reg, bytes, val, + REG_PROCHOT_DC_MASK); break; default: + __ASSERT(false, "Attempt to write unimplemented reg 0x%02x", + reg); return -EINVAL; } return 0; } +static int isl923x_emul_finish_write(struct i2c_emul *emul, int reg, int bytes) +{ + struct isl923x_emul_data *data = ISL923X_DATA_FROM_I2C_EMUL(emul); + struct i2c_emul *battery_i2c_emul; + struct sbat_emul_bat_data *bat; + int16_t current; + + switch (reg) { + case ISL923X_REG_CHG_CURRENT: + /* Write current to battery. */ + if (data->battery_ord >= 0) { + battery_i2c_emul = sbat_emul_get_ptr(data->battery_ord); + if (battery_i2c_emul != NULL) { + bat = sbat_emul_get_bat_data(battery_i2c_emul); + if (bat != NULL) { + current = REG_TO_CURRENT( + data->current_limit_reg); + if (current > 0) + bat->cur = current; + else + bat->cur = -5; + } + } + } + break; + } + return 0; +} + static int emul_isl923x_init(const struct emul *emul, const struct device *parent) { @@ -378,7 +408,12 @@ static int emul_isl923x_init(const struct emul *emul, .common = { \ .write_byte = isl923x_emul_write_byte, \ .read_byte = isl923x_emul_read_byte, \ + .finish_write = isl923x_emul_finish_write, \ }, \ + .battery_ord = COND_CODE_1( \ + DT_INST_NODE_HAS_PROP(n, battery), \ + (DT_DEP_ORD(DT_INST_PROP(n, battery))), \ + (-1)), \ }; \ static struct isl923x_emul_cfg isl923x_emul_cfg_##n = { \ .common = { \ diff --git a/zephyr/emul/emul_lis2dw12.c b/zephyr/emul/emul_lis2dw12.c index 07fba6091f..e14c184504 100644 --- a/zephyr/emul/emul_lis2dw12.c +++ b/zephyr/emul/emul_lis2dw12.c @@ -29,10 +29,20 @@ struct lis2dw12_emul_data { struct i2c_common_emul_data common; /** Emulated who-am-i register */ uint8_t who_am_i_reg; + /** Emulated ctrl1 register */ + uint8_t ctrl1_reg; /** Emulated ctrl2 register */ uint8_t ctrl2_reg; + /** Emulated ctrl3 register */ + uint8_t ctrl3_reg; + /** Emulated ctrl6 register */ + uint8_t ctrl6_reg; + /** Emulated status register */ + uint8_t status_reg; /** Soft reset count */ uint32_t soft_reset_count; + /** Current X, Y, and Z output data registers */ + int16_t accel_data[3]; }; struct lis2dw12_emul_cfg { @@ -59,8 +69,14 @@ void lis2dw12_emul_reset(const struct emul *emul) i2c_common_emul_set_read_func(i2c_emul, NULL, NULL); i2c_common_emul_set_write_func(i2c_emul, NULL, NULL); data->who_am_i_reg = LIS2DW12_WHO_AM_I; + data->ctrl1_reg = 0; data->ctrl2_reg = 0; + data->ctrl3_reg = 0; + data->ctrl6_reg = 0; + data->status_reg = 0; data->soft_reset_count = 0; + + memset(data->accel_data, 0, sizeof(data->accel_data)); } void lis2dw12_emul_set_who_am_i(const struct emul *emul, uint8_t who_am_i) @@ -87,16 +103,103 @@ static int lis2dw12_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, __ASSERT_NO_MSG(bytes == 0); *val = data->who_am_i_reg; break; + case LIS2DW12_CTRL1_ADDR: + __ASSERT_NO_MSG(bytes == 0); + *val = data->ctrl1_reg; + break; case LIS2DW12_CTRL2_ADDR: __ASSERT_NO_MSG(bytes == 0); *val = data->ctrl2_reg; break; + case LIS2DW12_CTRL3_ADDR: + __ASSERT_NO_MSG(bytes == 0); + *val = data->ctrl3_reg; + break; + case LIS2DW12_CTRL6_ADDR: + __ASSERT_NO_MSG(bytes == 0); + *val = data->ctrl6_reg; + break; + case LIS2DW12_STATUS_REG: + __ASSERT_NO_MSG(bytes == 0); + *val = data->status_reg; + break; + case LIS2DW12_OUT_X_L_ADDR: + case LIS2DW12_OUT_X_H_ADDR: + case LIS2DW12_OUT_Y_L_ADDR: + case LIS2DW12_OUT_Y_H_ADDR: + case LIS2DW12_OUT_Z_L_ADDR: + case LIS2DW12_OUT_Z_H_ADDR: + /* Allow multi-byte reads within this range of registers. + * `bytes` is actually an offset past the starting register + * `reg`. + */ + + __ASSERT_NO_MSG(LIS2DW12_OUT_X_L_ADDR + bytes <= + LIS2DW12_OUT_Z_H_ADDR); + + /* 0 is OUT_X_L_ADDR .. 5 is OUT_Z_H_ADDR */ + int offset_into_odrs = reg - LIS2DW12_OUT_X_L_ADDR + bytes; + + /* Which of the 3 channels we're reading. 0 = X, 1 = Y, 2 = Z */ + int channel = offset_into_odrs / 2; + + if (offset_into_odrs % 2 == 0) { + /* Get the LSB (L reg) */ + *val = data->accel_data[channel] & 0xFF; + } else { + /* Get the MSB (H reg) */ + *val = (data->accel_data[channel] >> 8) & 0xFF; + } + break; default: + __ASSERT(false, "No read handler for register 0x%02x", reg); return -EINVAL; } return 0; } +uint8_t lis2dw12_emul_peek_reg(struct i2c_emul *emul, int reg) +{ + __ASSERT(emul, "emul is NULL"); + + uint8_t val; + int rv; + + rv = lis2dw12_emul_read_byte(emul, reg, &val, 0); + __ASSERT(rv == 0, "Read function returned non-zero: %d", rv); + + return val; +} + +uint8_t lis2dw12_emul_peek_odr(struct i2c_emul *emul) +{ + __ASSERT(emul, "emul is NULL"); + + uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_ODR_ADDR); + + return (reg & LIS2DW12_ACC_ODR_MASK) >> + __builtin_ctz(LIS2DW12_ACC_ODR_MASK); +} + +uint8_t lis2dw12_emul_peek_mode(struct i2c_emul *emul) +{ + __ASSERT(emul, "emul is NULL"); + + uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_MODE_ADDR); + + return (reg & LIS2DW12_ACC_MODE_MASK) >> + __builtin_ctz(LIS2DW12_ACC_MODE_MASK); +} + +uint8_t lis2dw12_emul_peek_lpmode(struct i2c_emul *emul) +{ + __ASSERT(emul, "emul is NULL"); + + uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_LPMODE_ADDR); + + return (reg & LIS2DW12_ACC_LPMODE_MASK); +} + static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, int bytes) { @@ -106,6 +209,9 @@ static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, case LIS2DW12_WHO_AM_I_REG: LOG_ERR("Can't write to who-am-i register"); return -EINVAL; + case LIS2DW12_CTRL1_ADDR: + data->ctrl1_reg = val; + break; case LIS2DW12_CTRL2_ADDR: __ASSERT_NO_MSG(bytes == 1); if ((val & LIS2DW12_SOFT_RESET_MASK) != 0) { @@ -114,7 +220,28 @@ static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, } data->ctrl2_reg = val & ~LIS2DW12_SOFT_RESET_MASK; break; + case LIS2DW12_CTRL3_ADDR: + data->ctrl3_reg = val; + break; + case LIS2DW12_CTRL6_ADDR: + data->ctrl6_reg = val; + break; + case LIS2DW12_STATUS_REG: + __ASSERT(false, + "Attempt to write to read-only status register"); + return -EINVAL; + case LIS2DW12_OUT_X_L_ADDR: + case LIS2DW12_OUT_X_H_ADDR: + case LIS2DW12_OUT_Y_L_ADDR: + case LIS2DW12_OUT_Y_H_ADDR: + case LIS2DW12_OUT_Z_L_ADDR: + case LIS2DW12_OUT_Z_H_ADDR: + __ASSERT(false, + "Attempt to write to data output register 0x%02x", + reg); + return -EINVAL; default: + __ASSERT(false, "No write handler for register 0x%02x", reg); return -EINVAL; } return 0; @@ -137,6 +264,37 @@ static int emul_lis2dw12_init(const struct emul *emul, return i2c_emul_register(parent, emul->dev_label, &data->common.emul); } +int lis2dw12_emul_set_accel_reading(const struct emul *emul, intv3_t reading) +{ + __ASSERT(emul, "emul is NULL"); + struct lis2dw12_emul_data *data = emul->data; + + for (int i = X; i <= Z; i++) { + /* Ensure we fit in a 14-bit signed integer */ + if (reading[i] < LIS2DW12_SAMPLE_MIN || + reading[i] > LIS2DW12_SAMPLE_MAX) { + return -EINVAL; + } + /* Readings are left-aligned, so shift over by 2 */ + data->accel_data[i] = reading[i] * 4; + } + + /* Set the DRDY (data ready) bit */ + data->status_reg |= LIS2DW12_STS_DRDY_UP; + + return 0; +} + +void lis2dw12_emul_clear_accel_reading(const struct emul *emul) +{ + __ASSERT(emul, "emul is NULL"); + struct lis2dw12_emul_data *data = emul->data; + + /* Zero out the registers and reset DRDY bit */ + memset(data->accel_data, 0, sizeof(data->accel_data)); + data->status_reg &= ~LIS2DW12_STS_DRDY_UP; +} + #define INIT_LIS2DW12(n) \ static struct lis2dw12_emul_data lis2dw12_emul_data_##n = { \ .common = { \ diff --git a/zephyr/emul/emul_ln9310.c b/zephyr/emul/emul_ln9310.c index 3e6be65591..4b74c537cf 100644 --- a/zephyr/emul/emul_ln9310.c +++ b/zephyr/emul/emul_ln9310.c @@ -6,6 +6,8 @@ #define DT_DRV_COMPAT cros_ln9310_emul #include <device.h> +#include <devicetree/gpio.h> +#include <drivers/gpio/gpio_emul.h> #include <drivers/i2c.h> #include <drivers/i2c_emul.h> #include <emul.h> @@ -37,6 +39,10 @@ enum functional_mode { struct ln9310_emul_data { /** Common I2C data */ struct i2c_common_emul_data common; + /** Emulated int_gpio port */ + const struct device *gpio_int_port; + /** Emulated int_gpio pin */ + gpio_pin_t gpio_int_pin; /** The current emulated battery cell type */ enum battery_cell_type battery_cell_type; /** Current Functional Mode */ @@ -100,22 +106,28 @@ struct i2c_emul *ln9310_emul_get_i2c_emul(const struct emul *emulator) return &(data->common.emul); } -static void do_ln9310_interrupt(struct ln9310_emul_data *data) +static void ln9310_emul_set_int_pin(struct ln9310_emul_data *data, bool val) { - /* - * TODO(b/201437348): Use gpio interrupt pins properly instead of - * making direct interrupt call as part of this or system test - */ + int res = gpio_emul_input_set(data->gpio_int_port, data->gpio_int_pin, + val); + __ASSERT_NO_MSG(res == 0); +} +static void ln9310_emul_assert_interrupt(struct ln9310_emul_data *data) +{ data->int1_reg |= LN9310_INT1_MODE; - ln9310_interrupt(0); + ln9310_emul_set_int_pin(data, false); } -static void mode_change(struct ln9310_emul_data *data) +static void ln9310_emul_deassert_interrupt(struct ln9310_emul_data *data) { + ln9310_emul_set_int_pin(data, true); +} +static void mode_change(struct ln9310_emul_data *data) +{ bool new_mode_in_standby = data->startup_ctrl_reg & - LN9310_STARTUP_STANDBY_EN; + LN9310_STARTUP_STANDBY_EN; bool new_mode_in_switching_21 = ((data->power_ctrl_reg & LN9310_PWR_OP_MODE_MASK) == LN9310_PWR_OP_MODE_SWITCH21) && @@ -131,41 +143,35 @@ static void mode_change(struct ln9310_emul_data *data) switch (data->current_mode) { case FUNCTIONAL_MODE_STANDBY: if (new_mode_in_switching_21) { - data->current_mode = - FUNCTIONAL_MODE_SWITCHING_21; + data->current_mode = FUNCTIONAL_MODE_SWITCHING_21; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } else if (new_mode_in_switching_31) { - data->current_mode = - FUNCTIONAL_MODE_SWITCHING_31; + data->current_mode = FUNCTIONAL_MODE_SWITCHING_31; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } break; case FUNCTIONAL_MODE_SWITCHING_21: if (new_mode_in_standby) { - data->current_mode = - FUNCTIONAL_MODE_STANDBY; + data->current_mode = FUNCTIONAL_MODE_STANDBY; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } else if (new_mode_in_switching_31) { - data->current_mode = - FUNCTIONAL_MODE_SWITCHING_31; + data->current_mode = FUNCTIONAL_MODE_SWITCHING_31; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } break; case FUNCTIONAL_MODE_SWITCHING_31: if (new_mode_in_standby) { - data->current_mode = - FUNCTIONAL_MODE_STANDBY; + data->current_mode = FUNCTIONAL_MODE_STANDBY; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } else if (new_mode_in_switching_21) { - data->current_mode = - FUNCTIONAL_MODE_SWITCHING_21; + data->current_mode = FUNCTIONAL_MODE_SWITCHING_21; data->sys_sts_reg = data->current_mode; - do_ln9310_interrupt(data); + ln9310_emul_assert_interrupt(data); } break; default: @@ -183,10 +189,17 @@ void ln9310_emul_reset(const struct emul *emulator) struct ln9310_emul_data *data = emulator->data; struct i2c_common_emul_data common = data->common; + gpio_pin_t gpio_int_pin = data->gpio_int_pin; + const struct device *gpio_int_port = data->gpio_int_port; + /* Only Reset the LN9310 Register Data */ memset(data, 0, sizeof(struct ln9310_emul_data)); data->common = common; data->current_mode = LN9310_SYS_STANDBY; + data->gpio_int_pin = gpio_int_pin; + data->gpio_int_port = gpio_int_port; + + ln9310_emul_deassert_interrupt(data); } void ln9310_emul_set_battery_cell_type(const struct emul *emulator, @@ -253,104 +266,87 @@ static int ln9310_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, { struct ln9310_emul_data *data = LN9310_DATA_FROM_I2C_EMUL(emul); + __ASSERT(bytes == 1, "bytes 0x%x != 0x1 on reg 0x%x", bytes, reg); + switch (reg) { case LN9310_REG_INT1: - __ASSERT_NO_MSG(bytes == 1); data->int1_reg = val; break; case LN9310_REG_SYS_STS: - __ASSERT_NO_MSG(bytes == 1); data->sys_sts_reg = val; break; case LN9310_REG_INT1_MSK: - __ASSERT_NO_MSG(bytes == 1); data->int1_msk_reg = val; break; case LN9310_REG_STARTUP_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->startup_ctrl_reg = val; break; case LN9310_REG_LION_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->lion_ctrl_reg = val; break; case LN9310_REG_BC_STS_B: - __ASSERT_NO_MSG(bytes == 1); data->bc_sts_b_reg = val; break; case LN9310_REG_BC_STS_C: - LOG_ERR("Can't write to BC STS C register"); - return -EINVAL; + __ASSERT(false, + "Write to an unverified as safe " + "read-only register on 0x%x", + reg); + break; case LN9310_REG_CFG_0: - __ASSERT_NO_MSG(bytes == 1); data->cfg_0_reg = val; break; case LN9310_REG_CFG_4: - __ASSERT_NO_MSG(bytes == 1); data->cfg_4_reg = val; break; case LN9310_REG_CFG_5: - __ASSERT_NO_MSG(bytes == 1); data->cfg_5_reg = val; break; case LN9310_REG_PWR_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->power_ctrl_reg = val; break; case LN9310_REG_TIMER_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->timer_ctrl_reg = val; break; case LN9310_REG_LB_CTRL: - __ASSERT_NO_MSG(bytes = 1); data->lower_bound_ctrl_reg = val; break; case LN9310_REG_SPARE_0: - __ASSERT_NO_MSG(bytes == 1); data->spare_0_reg = val; break; case LN9310_REG_SWAP_CTRL_0: - __ASSERT_NO_MSG(bytes == 1); data->swap_ctrl_0_reg = val; break; case LN9310_REG_SWAP_CTRL_1: - __ASSERT_NO_MSG(bytes == 1); data->swap_ctrl_1_reg = val; break; case LN9310_REG_SWAP_CTRL_2: - __ASSERT_NO_MSG(bytes == 1); data->swap_ctrl_2_reg = val; break; case LN9310_REG_SWAP_CTRL_3: - __ASSERT_NO_MSG(bytes == 1); data->swap_ctrl_3_reg = val; break; case LN9310_REG_TRACK_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->track_ctrl_reg = val; break; case LN9310_REG_MODE_CHANGE_CFG: - __ASSERT_NO_MSG(bytes == 1); data->mode_change_cfg_reg = val; break; case LN9310_REG_SYS_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->sys_ctrl_reg = val; break; case LN9310_REG_FORCE_SC21_CTRL_1: - __ASSERT_NO_MSG(bytes == 1); data->force_sc21_ctrl_1_reg = val; break; case LN9310_REG_FORCE_SC21_CTRL_2: - __ASSERT_NO_MSG(bytes == 1); data->force_sc21_ctrl_2_reg = val; break; case LN9310_REG_TEST_MODE_CTRL: - __ASSERT_NO_MSG(bytes == 1); data->test_mode_ctrl_reg = val; break; default: - return -EINVAL; + __ASSERT(false, "Unimplemented Register Access Error on 0x%x", + reg); } mode_change(data); return 0; @@ -379,101 +375,82 @@ static int ln9310_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, { struct ln9310_emul_data *data = LN9310_DATA_FROM_I2C_EMUL(emul); + __ASSERT(bytes == 0, "bytes 0x%x != 0x0 on reg 0x%x", bytes, reg); + switch (reg) { case LN9310_REG_INT1: - __ASSERT_NO_MSG(bytes == 0); *val = data->int1_reg; + /* Reading clears interrupts */ + data->int1_reg = 0; + ln9310_emul_deassert_interrupt(data); break; case LN9310_REG_SYS_STS: - __ASSERT_NO_MSG(bytes == 0); *val = data->sys_sts_reg; break; case LN9310_REG_INT1_MSK: - __ASSERT_NO_MSG(bytes == 0); *val = data->int1_msk_reg; break; case LN9310_REG_STARTUP_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->startup_ctrl_reg; break; case LN9310_REG_LION_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->lion_ctrl_reg; break; case LN9310_REG_BC_STS_B: - __ASSERT_NO_MSG(bytes == 0); *val = data->bc_sts_b_reg; break; case LN9310_REG_BC_STS_C: - __ASSERT_NO_MSG(bytes == 0); *val = data->bc_sts_c_reg; break; case LN9310_REG_CFG_0: - __ASSERT_NO_MSG(bytes == 0); *val = data->cfg_0_reg; break; case LN9310_REG_CFG_4: - __ASSERT_NO_MSG(bytes == 0); *val = data->cfg_4_reg; break; case LN9310_REG_CFG_5: - __ASSERT_NO_MSG(bytes == 0); *val = data->cfg_5_reg; break; case LN9310_REG_PWR_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->power_ctrl_reg; break; case LN9310_REG_TIMER_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->timer_ctrl_reg; break; case LN9310_REG_LB_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->lower_bound_ctrl_reg; break; case LN9310_REG_SPARE_0: - __ASSERT_NO_MSG(bytes == 0); *val = data->spare_0_reg; break; case LN9310_REG_SWAP_CTRL_0: - __ASSERT_NO_MSG(bytes == 0); *val = data->swap_ctrl_0_reg; break; case LN9310_REG_SWAP_CTRL_1: - __ASSERT_NO_MSG(bytes == 0); *val = data->swap_ctrl_1_reg; break; case LN9310_REG_SWAP_CTRL_2: - __ASSERT_NO_MSG(bytes == 0); *val = data->swap_ctrl_2_reg; break; case LN9310_REG_SWAP_CTRL_3: - __ASSERT_NO_MSG(bytes == 0); *val = data->swap_ctrl_3_reg; break; case LN9310_REG_TRACK_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->track_ctrl_reg; break; case LN9310_REG_MODE_CHANGE_CFG: - __ASSERT_NO_MSG(bytes == 0); *val = data->mode_change_cfg_reg; break; case LN9310_REG_SYS_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->sys_ctrl_reg; break; case LN9310_REG_FORCE_SC21_CTRL_1: - __ASSERT_NO_MSG(bytes == 0); *val = data->force_sc21_ctrl_1_reg; break; case LN9310_REG_FORCE_SC21_CTRL_2: - __ASSERT_NO_MSG(bytes == 0); *val = data->force_sc21_ctrl_2_reg; break; case LN9310_REG_TEST_MODE_CTRL: - __ASSERT_NO_MSG(bytes == 0); *val = data->test_mode_ctrl_reg; break; default: @@ -506,6 +483,12 @@ static int emul_ln9310_init(const struct emul *emul, return i2c_emul_register(parent, emul->dev_label, &data->common.emul); } +#define LN9310_GET_GPIO_INT_PORT(n) \ + DEVICE_DT_GET(DT_GPIO_CTLR(DT_INST_PROP(n, pg_int_gpio), gpios)) + +#define LN9310_GET_GPIO_INT_PIN(n) \ + DT_GPIO_PIN(DT_INST_PROP(n, pg_int_gpio), gpios) + #define INIT_LN9310(n) \ const struct ln9310_config_t ln9310_config = { \ .i2c_port = NAMED_I2C(power), \ @@ -521,6 +504,8 @@ static int emul_ln9310_init(const struct emul *emul, .finish_read = ln9310_emul_finish_read, \ .access_reg = ln9310_emul_access_reg, \ }, \ + .gpio_int_port = LN9310_GET_GPIO_INT_PORT(n), \ + .gpio_int_pin = LN9310_GET_GPIO_INT_PIN(n), \ }; \ static const struct i2c_common_emul_cfg ln9310_emul_cfg_##n = { \ .i2c_label = DT_INST_BUS_LABEL(n), \ diff --git a/zephyr/emul/emul_sn5s330.c b/zephyr/emul/emul_sn5s330.c index f6b3217372..238815b11c 100644 --- a/zephyr/emul/emul_sn5s330.c +++ b/zephyr/emul/emul_sn5s330.c @@ -11,6 +11,8 @@ #include <emul.h> #include <errno.h> #include <sys/__assert.h> +#include <devicetree/gpio.h> +#include <drivers/gpio/gpio_emul.h> #include "driver/ppc/sn5s330.h" #include "driver/ppc/sn5s330_public.h" @@ -28,6 +30,10 @@ LOG_MODULE_REGISTER(sn5s330_emul, CONFIG_SN5S330_EMUL_LOG_LEVEL); struct sn5s330_emul_data { /** Common I2C data */ struct i2c_common_emul_data common; + /** Emulated int_gpio port */ + const struct device *gpio_int_port; + /** Emulated int_gpio pin */ + gpio_pin_t gpio_int_pin; /** Emulated FUNC_SET1 register */ uint8_t func_set1_reg; /** Emulated FUNC_SET2 register */ @@ -60,9 +66,14 @@ struct sn5s330_emul_data { uint8_t int_status_reg3; /** Emulated INT_STATUS_REG4 register */ /* - * TODO(b:205754232): Register name discrepancy + * TODO(b/205754232): Register name discrepancy */ uint8_t int_status_reg4; + /* + * TODO(b/203364783): For all falling edge registers, implement + * interrupt and bit change to correspond to change in interrupt status + * registers. + */ /** Emulated INT_MASK_RISE_REG1 register */ uint8_t int_mask_rise_reg1; /** Emulated INT_MASK_RISE_REG2 register */ @@ -94,123 +105,122 @@ struct sn5s330_emul_cfg { const struct i2c_common_emul_cfg common; }; -struct i2c_emul *sn5s330_emul_to_i2c_emul(const struct emul *emul) +test_mockable_static void sn5s330_emul_interrupt_set_stub(void) { - struct sn5s330_emul_data *data = emul->data; - - return &(data->common.emul); + /* Stub to be used by fff fakes during test */ } -int sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint32_t *val) +struct i2c_emul *sn5s330_emul_to_i2c_emul(const struct emul *emul) { struct sn5s330_emul_data *data = emul->data; - switch (reg) { - case SN5S330_FUNC_SET1: - *val = data->func_set1_reg; - break; - default: - return -EINVAL; - } - return 0; + return &(data->common.emul); } -static int sn5s330_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, - int bytes) +/* Workhorse for mapping i2c reg to internal emulator data access */ +static uint8_t *sn5s330_emul_get_reg_ptr(struct sn5s330_emul_data *data, + int reg) { - struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul); - - __ASSERT(bytes == 0, "bytes 0x%x != 0x0 on reg 0x%x", bytes, reg); - switch (reg) { case SN5S330_FUNC_SET1: - *val = data->func_set1_reg; - break; + return &(data->func_set1_reg); case SN5S330_FUNC_SET2: - *val = data->func_set2_reg; - break; + return &(data->func_set2_reg); case SN5S330_FUNC_SET3: - *val = data->func_set3_reg; - break; + return &(data->func_set3_reg); case SN5S330_FUNC_SET4: - *val = data->func_set4_reg; - break; + return &(data->func_set4_reg); case SN5S330_FUNC_SET5: - *val = data->func_set5_reg; - break; + return &(data->func_set5_reg); case SN5S330_FUNC_SET6: - *val = data->func_set6_reg; - break; + return &(data->func_set6_reg); case SN5S330_FUNC_SET7: - *val = data->func_set7_reg; - break; + return &(data->func_set7_reg); case SN5S330_FUNC_SET8: - *val = data->func_set8_reg; - break; + return &(data->func_set8_reg); case SN5S330_FUNC_SET9: - *val = data->func_set9_reg; - break; + return &(data->func_set9_reg); case SN5S330_FUNC_SET10: - *val = data->func_set10_reg; - break; + return &(data->func_set10_reg); case SN5S330_FUNC_SET11: - *val = data->func_set11_reg; - break; + return &(data->func_set11_reg); case SN5S330_FUNC_SET12: - *val = data->func_set12_reg; - break; + return &(data->func_set12_reg); case SN5S330_INT_STATUS_REG1: - *val = data->int_status_reg1; - break; + return &(data->int_status_reg1); case SN5S330_INT_STATUS_REG2: - *val = data->int_status_reg2; - break; + return &(data->int_status_reg2); case SN5S330_INT_STATUS_REG3: - *val = data->int_status_reg3; - break; + return &(data->int_status_reg3); case SN5S330_INT_STATUS_REG4: - *val = data->int_status_reg4; - break; + return &(data->int_status_reg4); case SN5S330_INT_MASK_RISE_REG1: - *val = data->int_mask_rise_reg1; - break; + return &(data->int_mask_rise_reg1); case SN5S330_INT_MASK_RISE_REG2: - *val = data->int_mask_rise_reg2; - break; + return &(data->int_mask_rise_reg2); case SN5S330_INT_MASK_RISE_REG3: - *val = data->int_mask_rise_reg3; - break; + return &(data->int_mask_rise_reg3); case SN5S330_INT_MASK_FALL_REG1: - *val = data->int_mask_fall_reg1; - break; + return &(data->int_mask_fall_reg1); case SN5S330_INT_MASK_FALL_REG2: - *val = data->int_mask_fall_reg2; - break; + return &(data->int_mask_fall_reg2); case SN5S330_INT_MASK_FALL_REG3: - *val = data->int_mask_fall_reg3; - break; + return &(data->int_mask_fall_reg3); case SN5S330_INT_TRIP_RISE_REG1: - *val = data->int_trip_rise_reg1; - break; + return &(data->int_trip_rise_reg1); case SN5S330_INT_TRIP_RISE_REG2: - *val = data->int_trip_rise_reg2; - break; + return &(data->int_trip_rise_reg2); case SN5S330_INT_TRIP_RISE_REG3: - *val = data->int_trip_rise_reg3; - break; + return &(data->int_trip_rise_reg3); case SN5S330_INT_TRIP_FALL_REG1: - *val = data->int_trip_fall_reg1; - break; + return &(data->int_trip_fall_reg1); case SN5S330_INT_TRIP_FALL_REG2: - *val = data->int_trip_fall_reg2; - break; + return &(data->int_trip_fall_reg2); case SN5S330_INT_TRIP_FALL_REG3: - *val = data->int_trip_fall_reg3; - break; + return &(data->int_trip_fall_reg3); default: __ASSERT(false, "Unimplemented Register Access Error on 0x%x", reg); + /* Statement never reached, required for compiler warnings */ + return NULL; } +} + +void sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint8_t *val) +{ + struct sn5s330_emul_data *data = emul->data; + uint8_t *data_reg = sn5s330_emul_get_reg_ptr(data, reg); + + *val = *data_reg; +} + +static void sn5s330_emul_set_int_pin(struct i2c_emul *emul, bool val) +{ + struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul); + int res = gpio_emul_input_set(data->gpio_int_port, data->gpio_int_pin, + val); + __ASSERT_NO_MSG(res == 0); +} + +static void sn5s330_emul_assert_interrupt(struct i2c_emul *emul) +{ + sn5s330_emul_interrupt_set_stub(); + sn5s330_emul_set_int_pin(emul, false); +} + +static void sn5s330_emul_deassert_interrupt(struct i2c_emul *emul) +{ + sn5s330_emul_set_int_pin(emul, true); +} + +static int sn5s330_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val, + int bytes) +{ + struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul); + uint8_t *reg_to_read = sn5s330_emul_get_reg_ptr(data, reg); + + __ASSERT(bytes == 0, "bytes 0x%x != 0x0 on reg 0x%x", bytes, reg); + *val = *reg_to_read; return 0; } @@ -219,45 +229,30 @@ static int sn5s330_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, int bytes) { struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul); + uint8_t *reg_to_write; + bool deassert_int = false; __ASSERT(bytes == 1, "bytes 0x%x != 0x1 on reg 0x%x", bytes, reg); + /* Specially check for read-only reg */ switch (reg) { - case SN5S330_FUNC_SET1: - data->func_set1_reg = val; - break; - case SN5S330_FUNC_SET2: - data->func_set2_reg = val; - break; - case SN5S330_FUNC_SET3: - data->func_set3_reg = val; - break; - case SN5S330_FUNC_SET4: - data->func_set4_reg = val; - break; - case SN5S330_FUNC_SET5: - data->func_set5_reg = val; - break; - case SN5S330_FUNC_SET6: - data->func_set6_reg = val; - break; - case SN5S330_FUNC_SET7: - data->func_set7_reg = val; - break; - case SN5S330_FUNC_SET8: - data->func_set8_reg = val; - break; - case SN5S330_FUNC_SET9: - data->func_set9_reg = val; - break; - case SN5S330_FUNC_SET10: - data->func_set10_reg = val; - break; - case SN5S330_FUNC_SET11: - data->func_set11_reg = val; - break; - case SN5S330_FUNC_SET12: - data->func_set12_reg = val; + case SN5S330_INT_TRIP_RISE_REG1: + /* fallthrough */ + case SN5S330_INT_TRIP_RISE_REG2: + /* fallthrough */ + case SN5S330_INT_TRIP_RISE_REG3: + /* fallthrough */ + case SN5S330_INT_TRIP_FALL_REG1: + /* fallthrough */ + case SN5S330_INT_TRIP_FALL_REG2: + /* fallthrough */ + case SN5S330_INT_TRIP_FALL_REG3: + reg_to_write = sn5s330_emul_get_reg_ptr(data, reg); + /* Clearing any bit deasserts /INT interrupt signal */ + deassert_int = (*reg_to_write & val) != 0; + /* Write 0 is noop and 1 clears the bit. */ + val = (~val & *reg_to_write); + *reg_to_write = val; break; case SN5S330_INT_STATUS_REG1: /* fallthrough */ @@ -269,61 +264,65 @@ static int sn5s330_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val, "0x%x", reg); /* fallthrough for checkpath */ - case SN5S330_INT_STATUS_REG4: - data->int_status_reg4 = val; - break; - case SN5S330_INT_MASK_RISE_REG1: - data->int_mask_rise_reg1 = val; - break; - case SN5S330_INT_MASK_RISE_REG2: - data->int_mask_rise_reg2 = val; - break; - case SN5S330_INT_MASK_RISE_REG3: - data->int_mask_rise_reg3 = val; - break; - case SN5S330_INT_MASK_FALL_REG1: - data->int_mask_fall_reg1 = val; - break; - case SN5S330_INT_MASK_FALL_REG2: - data->int_mask_fall_reg2 = val; - break; - case SN5S330_INT_MASK_FALL_REG3: - data->int_mask_fall_reg3 = val; - break; - case SN5S330_INT_TRIP_RISE_REG1: - data->int_trip_rise_reg1 = val; - break; - case SN5S330_INT_TRIP_RISE_REG2: - data->int_trip_rise_reg2 = val; - break; - case SN5S330_INT_TRIP_RISE_REG3: - data->int_trip_rise_reg3 = val; - break; - case SN5S330_INT_TRIP_FALL_REG1: - data->int_trip_fall_reg1 = val; - break; - case SN5S330_INT_TRIP_FALL_REG2: - data->int_trip_fall_reg2 = val; - break; - case SN5S330_INT_TRIP_FALL_REG3: - data->int_trip_fall_reg3 = val; - break; default: - __ASSERT(false, "Unimplemented Register Access Error on 0x%x", - reg); + reg_to_write = sn5s330_emul_get_reg_ptr(data, reg); + *reg_to_write = val; } + if (deassert_int) + sn5s330_emul_deassert_interrupt(emul); + return 0; } +void sn5s330_emul_make_vbus_overcurrent(const struct emul *emul) +{ + struct sn5s330_emul_data *data = emul->data; + struct i2c_emul *i2c_emul = &data->common.emul; + + data->int_status_reg1 |= SN5S330_ILIM_PP1_MASK; + data->int_trip_rise_reg1 |= SN5S330_ILIM_PP1_MASK; + + /* driver disabled this interrupt trigger */ + if (data->int_mask_rise_reg1 & SN5S330_ILIM_PP1_MASK) + return; + + sn5s330_emul_assert_interrupt(i2c_emul); +} + +void sn5s330_emul_lower_vbus_below_minv(const struct emul *emul) +{ + struct sn5s330_emul_data *data = emul->data; + struct i2c_emul *i2c_emul = &data->common.emul; + + data->int_status_reg4 |= SN5S330_VSAFE0V_STAT; + + /* driver disabled this interrupt trigger */ + if (data->int_status_reg4 & SN5S330_VSAFE0V_MASK) + return; + + sn5s330_emul_assert_interrupt(i2c_emul); +} + void sn5s330_emul_reset(const struct emul *emul) { struct sn5s330_emul_data *data = emul->data; struct i2c_common_emul_data common = data->common; + const struct device *gpio_int_port = data->gpio_int_port; + gpio_pin_t gpio_int_pin = data->gpio_int_pin; + + sn5s330_emul_deassert_interrupt(&data->common.emul); + + /* + * TODO(b/203364783): Some registers reset with set bits; this should be + * reflected in the emul_reset function. + */ /* Only Reset the sn5s330 Register Data */ memset(data, 0, sizeof(struct sn5s330_emul_data)); data->common = common; + data->gpio_int_port = gpio_int_port; + data->gpio_int_pin = gpio_int_pin; } static int emul_sn5s330_init(const struct emul *emul, @@ -332,6 +331,8 @@ static int emul_sn5s330_init(const struct emul *emul, const struct sn5s330_emul_cfg *cfg = emul->cfg; struct sn5s330_emul_data *data = emul->data; + sn5s330_emul_deassert_interrupt(&data->common.emul); + data->common.emul.api = &i2c_common_emul_api; data->common.emul.addr = cfg->common.addr; data->common.emul.parent = emul; @@ -342,12 +343,20 @@ static int emul_sn5s330_init(const struct emul *emul, return i2c_emul_register(parent, emul->dev_label, &data->common.emul); } +#define SN5S330_GET_GPIO_INT_PORT(n) \ + DEVICE_DT_GET(DT_GPIO_CTLR(DT_INST_PROP(n, int_gpio), gpios)) + +#define SN5S330_GET_GPIO_INT_PIN(n) \ + DT_GPIO_PIN(DT_INST_PROP(n, int_gpio), gpios) + #define INIT_SN5S330(n) \ static struct sn5s330_emul_data sn5s330_emul_data_##n = { \ .common = { \ .write_byte = sn5s330_emul_write_byte, \ .read_byte = sn5s330_emul_read_byte, \ }, \ + .gpio_int_port = SN5S330_GET_GPIO_INT_PORT(n), \ + .gpio_int_pin = SN5S330_GET_GPIO_INT_PIN(n), \ }; \ static struct sn5s330_emul_cfg sn5s330_emul_cfg_##n = { \ .common = { \ diff --git a/zephyr/emul/emul_syv682x.c b/zephyr/emul/emul_syv682x.c index b9d2dc57c7..51a61aaf0e 100644 --- a/zephyr/emul/emul_syv682x.c +++ b/zephyr/emul/emul_syv682x.c @@ -29,6 +29,8 @@ struct syv682x_emul_data { const struct device *i2c; const struct device *frs_en_gpio_port; gpio_pin_t frs_en_gpio_pin; + const struct device *alert_gpio_port; + gpio_pin_t alert_gpio_pin; /** Configuration information */ const struct syv682x_emul_cfg *cfg; /** Current state of all emulated SYV682x registers */ @@ -39,6 +41,11 @@ struct syv682x_emul_data { */ uint8_t status_cond; uint8_t control_4_cond; + /** + * How many CONTROL_3 reads the busy bit should stay set. 0 means not + * busy. + */ + int busy_read_count; }; /** Static configuration for the emulator */ @@ -51,6 +58,15 @@ struct syv682x_emul_cfg { struct syv682x_emul_data *data; }; +/* Asserts or deasserts the interrupt signal to the EC. */ +static void syv682x_emul_set_alert(struct syv682x_emul_data *data, bool alert) +{ + int res = gpio_emul_input_set(data->alert_gpio_port, + /* The signal is inverted. */ + data->alert_gpio_pin, !alert); + __ASSERT_NO_MSG(res == 0); +} + int syv682x_emul_set_reg(struct i2c_emul *emul, int reg, uint8_t val) { struct syv682x_emul_data *data; @@ -64,48 +80,36 @@ int syv682x_emul_set_reg(struct i2c_emul *emul, int reg, uint8_t val) return 0; } -void syv682x_emul_set_status(struct i2c_emul *emul, uint8_t val) +void syv682x_emul_set_condition(struct i2c_emul *emul, uint8_t status, + uint8_t control_4) { + uint8_t control_4_interrupt = control_4 & SYV682X_CONTROL_4_INT_MASK; struct syv682x_emul_data *data = CONTAINER_OF(emul, struct syv682x_emul_data, emul); int frs_en_gpio = gpio_emul_output_get(data->frs_en_gpio_port, data->frs_en_gpio_pin); - /* Only assert FRS status if FRS is enabled. */ __ASSERT_NO_MSG(frs_en_gpio >= 0); + + /* Only assert FRS status if FRS is enabled. */ if (!frs_en_gpio) - val &= ~SYV682X_STATUS_FRS; + status &= ~SYV682X_STATUS_FRS; - data->status_cond = val; - data->reg[SYV682X_STATUS_REG] |= val; + data->status_cond = status; + data->reg[SYV682X_STATUS_REG] |= status; - if (val & (SYV682X_STATUS_TSD | SYV682X_STATUS_OVP | + data->control_4_cond = control_4_interrupt; + /* Only update the interrupting bits of CONTROL_4. */ + data->reg[SYV682X_CONTROL_4_REG] &= ~SYV682X_CONTROL_4_INT_MASK; + data->reg[SYV682X_CONTROL_4_REG] |= control_4_interrupt; + + /* These conditions disable the power path. */ + if (status & (SYV682X_STATUS_TSD | SYV682X_STATUS_OVP | SYV682X_STATUS_OC_HV)) { data->reg[SYV682X_CONTROL_1_REG] |= SYV682X_CONTROL_1_PWR_ENB; } /* - * TODO(b/190519131): Make this emulator trigger GPIO-based interrupts - * by itself based on the status. In real life, the device should turn - * the power path off when either of these conditions occurs, and they - * should quickly dissipate. If they somehow stay set, the device should - * interrupt continuously. Relatedly, the emulator should only generate - * an interrupt based on FRS status if the FRS enable pin was asserted. - */ -} - -void syv682x_emul_set_control_4(struct i2c_emul *emul, uint8_t val) -{ - struct syv682x_emul_data *data; - uint8_t val_interrupt = val & SYV682X_CONTROL_4_INT_MASK; - - data = CONTAINER_OF(emul, struct syv682x_emul_data, emul); - data->control_4_cond = val_interrupt; - /* Only update the interrupting bits. */ - data->reg[SYV682X_CONTROL_4_REG] &= ~SYV682X_CONTROL_4_INT_MASK; - data->reg[SYV682X_CONTROL_4_REG] |= val_interrupt; - - /* * Note: The description of CONTROL_4 suggests that setting VCONN_OC * will turn off the VCONN channel. The "VCONN Channel Over Current * Response" plot shows that VCONN the device will merely throttle VCONN @@ -114,12 +118,25 @@ void syv682x_emul_set_control_4(struct i2c_emul *emul, uint8_t val) */ /* VBAT_OVP disconnects CC and VCONN. */ - if (val_interrupt & SYV682X_CONTROL_4_VBAT_OVP) { + if (control_4_interrupt & SYV682X_CONTROL_4_VBAT_OVP) { data->reg[SYV682X_CONTROL_4_REG] &= ~(SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS | SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2); } + + syv682x_emul_set_alert(data, status | control_4_interrupt); +} + +void syv682x_emul_set_busy_reads(struct i2c_emul *emul, int reads) +{ + struct syv682x_emul_data *data = + CONTAINER_OF(emul, struct syv682x_emul_data, emul); + data->busy_read_count = reads; + if (reads) + data->reg[SYV682X_CONTROL_3_REG] |= SYV682X_BUSY; + else + data->reg[SYV682X_CONTROL_3_REG] &= ~SYV682X_BUSY; } int syv682x_emul_get_reg(struct i2c_emul *emul, int reg, uint8_t *val) @@ -217,6 +234,15 @@ static int syv682x_emul_transfer(struct i2c_emul *emul, struct i2c_msg *msgs, case SYV682X_STATUS_REG: syv682x_emul_set_reg(emul, reg, data->status_cond); break; + case SYV682X_CONTROL_3_REG: + /* Update CONTROL_3[BUSY] based on the busy count. */ + if (data->busy_read_count > 0) { + if (--data->busy_read_count == 0) { + data->reg[SYV682X_CONTROL_3_REG] &= + ~SYV682X_BUSY; + } + } + break; case SYV682X_CONTROL_4_REG: syv682x_emul_set_reg(emul, reg, (*buf & ~SYV682X_CONTROL_4_INT_MASK) | @@ -248,7 +274,7 @@ static struct i2c_emul_api syv682x_emul_api = { * @param emul Emulation information * @param parent Device to emulate * - * @return 0 indicating success (always) + * @return 0 on success or an error code on failure */ static int syv682x_emul_init(const struct emul *emul, const struct device *parent) @@ -264,6 +290,15 @@ static int syv682x_emul_init(const struct emul *emul, memset(data->reg, 0, sizeof(data->reg)); ret = i2c_emul_register(parent, emul->dev_label, &data->emul); + if (ret) + return ret; + + syv682x_emul_set_alert(data, false); + data->reg[SYV682X_CONTROL_1_REG] = + (SYV682X_HV_ILIM_3_30 << SYV682X_HV_ILIM_BIT_SHIFT) | + (SYV682X_5V_ILIM_3_30 << SYV682X_5V_ILIM_BIT_SHIFT) | + /* HV_DR = 0 */ + SYV682X_CONTROL_1_CH_SEL; return ret; } @@ -274,6 +309,10 @@ static int syv682x_emul_init(const struct emul *emul, DT_INST_PROP(n, frs_en_gpio), gpios)), \ .frs_en_gpio_pin = DT_GPIO_PIN( \ DT_INST_PROP(n, frs_en_gpio), gpios), \ + .alert_gpio_port = DEVICE_DT_GET(DT_GPIO_CTLR( \ + DT_INST_PROP(n, alert_gpio), gpios)), \ + .alert_gpio_pin = DT_GPIO_PIN( \ + DT_INST_PROP(n, alert_gpio), gpios), \ }; \ static const struct syv682x_emul_cfg syv682x_emul_cfg_##n = { \ .i2c_label = DT_INST_BUS_LABEL(n), \ diff --git a/zephyr/emul/tcpc/CMakeLists.txt b/zephyr/emul/tcpc/CMakeLists.txt new file mode 100644 index 0000000000..ba00d766e2 --- /dev/null +++ b/zephyr/emul/tcpc/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI emul_tcpci.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_PS8XXX emul_ps8xxx.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI_PARTNER_SRC emul_tcpci_partner_src.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI_PARTNER_COMMON emul_tcpci_partner_common.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI_PARTNER_SNK emul_tcpci_partner_snk.c) diff --git a/zephyr/emul/tcpc/Kconfig b/zephyr/emul/tcpc/Kconfig new file mode 100644 index 0000000000..424773be3f --- /dev/null +++ b/zephyr/emul/tcpc/Kconfig @@ -0,0 +1,56 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +DT_COMPAT_TCPCI_EMUL := cros,tcpci-emul + +menuconfig EMUL_TCPCI + bool "TCPCI emulator" + default $(dt_compat_enabled,$(DT_COMPAT_TCPCI_EMUL)) + depends on I2C_EMUL + help + Enable the TCPCI emulator. This driver uses the emulated I2C bus. + It is used to test tcpci code. It supports reads and writes to all + emulator registers. Generic TCPCI emulator can be used as the base + for specific TCPC device emulator that follow TCPCI specification. + TCPCI emulator API is available in + zephyr/include/emul/tcpc/emul_tcpci.h + +if EMUL_TCPCI + +module = TCPCI_EMUL +module-str = tcpci_emul +source "subsys/logging/Kconfig.template.log_config" + +config EMUL_TCPCI_PARTNER_COMMON + bool + help + This option is selected automatically by specific TCPCI partner + emulators. Enable common code that can be used by TCPCI partner device + emulators. It covers sending delayed messages. API of common functions + is available in zephyr/include/emul/tcpc/emul_common_tcpci_partner.h + +config EMUL_PS8XXX + bool "Parade PS8XXX emulator" + help + Enable emulator for PS8XXX family of TCPC. This emulator is extenstion + for TCPCI emulator. PS8XXX specific API is available in + zephyr/include/emul/tcpc/emul_ps8xxx.h + +config EMUL_TCPCI_PARTNER_SRC + bool "USB-C source device emulator" + select EMUL_TCPCI_PARTNER_COMMON + help + Enable USB-C source device emulator which may be attached to TCPCI + emulator. API of source device emulator is available in + zephyr/include/emul/tcpc/emul_tcpci_partner_src.h + +config EMUL_TCPCI_PARTNER_SNK + bool "USB-C sink device emulator" + select EMUL_TCPCI_PARTNER_COMMON + help + Enable USB-C sink device emulator which may be attached to TCPCI + emulator. API of source device emulator is available in + zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h + +endif # EMUL_TCPCI diff --git a/zephyr/emul/emul_ps8xxx.c b/zephyr/emul/tcpc/emul_ps8xxx.c index 0a8cc61fba..5a36f39cd1 100644 --- a/zephyr/emul/emul_ps8xxx.c +++ b/zephyr/emul/tcpc/emul_ps8xxx.c @@ -16,8 +16,8 @@ LOG_MODULE_REGISTER(ps8xxx_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL); #include "tcpm/tcpci.h" #include "emul/emul_common_i2c.h" -#include "emul/emul_ps8xxx.h" -#include "emul/emul_tcpci.h" +#include "emul/tcpc/emul_ps8xxx.h" +#include "emul/tcpc/emul_tcpci.h" #include "driver/tcpm/ps8xxx.h" diff --git a/zephyr/emul/emul_tcpci.c b/zephyr/emul/tcpc/emul_tcpci.c index b2c21c2ec4..660f62ead0 100644 --- a/zephyr/emul/emul_tcpci.c +++ b/zephyr/emul/tcpc/emul_tcpci.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(tcpci_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL); #include "tcpm/tcpci.h" #include "emul/emul_common_i2c.h" -#include "emul/emul_tcpci.h" +#include "emul/tcpc/emul_tcpci.h" #define TCPCI_DATA_FROM_I2C_EMUL(_emul) \ CONTAINER_OF(CONTAINER_OF(_emul, struct i2c_common_emul_data, emul), \ @@ -380,8 +380,8 @@ int tcpci_emul_connect_partner(const struct emul *emul, enum tcpc_cc_voltage_status partner_cc2, enum tcpc_cc_polarity polarity) { + uint16_t cc_status, alert, role_ctrl, power_status; enum tcpc_cc_voltage_status cc1_v, cc2_v; - uint16_t cc_status, alert, role_ctrl; enum tcpc_cc_pull cc1_r, cc2_r; if (polarity == POLARITY_CC1) { @@ -424,10 +424,16 @@ int tcpci_emul_connect_partner(const struct emul *emul, alert | TCPC_REG_ALERT_CC_STATUS); if (partner_power_role == PD_ROLE_SOURCE) { - /* Set TCPCI emulator VBUS to present (connected, above 4V) */ - tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, - TCPC_REG_POWER_STATUS_VBUS_PRES | - TCPC_REG_POWER_STATUS_VBUS_DET); + tcpci_emul_get_reg(emul, TCPC_REG_POWER_STATUS, &power_status); + if (power_status & TCPC_REG_POWER_STATUS_VBUS_DET) { + /* + * Set TCPCI emulator VBUS to present (connected, + * above 4V) only if VBUS detection is enabled + */ + tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, + TCPC_REG_POWER_STATUS_VBUS_PRES | + power_status); + } } tcpci_emul_alert_changed(emul); @@ -436,6 +442,46 @@ int tcpci_emul_connect_partner(const struct emul *emul, } /** Check description in emul_tcpci.h */ +int tcpci_emul_disconnect_partner(const struct emul *emul) +{ + struct tcpci_emul_data *data = emul->data; + uint16_t power_status; + uint16_t val; + uint16_t term; + int rc; + + data->partner = NULL; + /* Set both CC lines to open to indicate disconnect. */ + rc = tcpci_emul_get_reg(emul, TCPC_REG_CC_STATUS, &val); + if (rc != 0) + return rc; + + term = TCPC_REG_CC_STATUS_TERM(val); + + rc = tcpci_emul_set_reg(emul, TCPC_REG_CC_STATUS, + TCPC_REG_CC_STATUS_SET(term, TYPEC_CC_VOLT_OPEN, + TYPEC_CC_VOLT_OPEN)); + if (rc != 0) + return rc; + + data->reg[TCPC_REG_ALERT] |= TCPC_REG_ALERT_CC_STATUS; + rc = tcpci_emul_alert_changed(emul); + if (rc != 0) + return rc; + /* TODO: Wait until DisableSourceVbus (TCPC_REG_COMMAND_SRC_CTRL_LOW?), + * and then set VBUS present = 0 and vSafe0V = 1 after appropriate + * delays. + */ + + /* Clear VBUS present in case if source partner is disconnected */ + tcpci_emul_get_reg(emul, TCPC_REG_POWER_STATUS, &power_status); + tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, + power_status & ~TCPC_REG_POWER_STATUS_VBUS_PRES); + + return 0; +} + +/** Check description in emul_tcpci.h */ void tcpci_emul_partner_msg_status(const struct emul *emul, enum tcpci_emul_tx_status status) { diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_common.c b/zephyr/emul/tcpc/emul_tcpci_partner_common.c new file mode 100644 index 0000000000..f6bff888af --- /dev/null +++ b/zephyr/emul/tcpc/emul_tcpci_partner_common.c @@ -0,0 +1,247 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <logging/log.h> +LOG_MODULE_REGISTER(tcpci_partner, CONFIG_TCPCI_EMUL_LOG_LEVEL); + +#include <sys/byteorder.h> +#include <zephyr.h> + +#include "common.h" +#include "emul/tcpc/emul_tcpci_partner_common.h" +#include "emul/tcpc/emul_tcpci.h" +#include "usb_pd.h" + +/** Length of PDO, RDO and BIST request object in SOP message in bytes */ +#define TCPCI_MSG_DO_LEN 4 +/** Length of header in SOP message in bytes */ +#define TCPCI_MSG_HEADER_LEN 2 + +/** Check description in emul_common_tcpci_partner.h */ +struct tcpci_partner_msg *tcpci_partner_alloc_msg(int data_objects) +{ + struct tcpci_partner_msg *new_msg; + size_t size = TCPCI_MSG_HEADER_LEN + TCPCI_MSG_DO_LEN * data_objects; + + new_msg = k_malloc(sizeof(struct tcpci_partner_msg)); + if (new_msg == NULL) { + return NULL; + } + + new_msg->msg.buf = k_malloc(size); + if (new_msg->msg.buf == NULL) { + k_free(new_msg); + return NULL; + } + + /* Set default message type to SOP */ + new_msg->msg.type = TCPCI_MSG_SOP; + /* TCPCI message size count include type byte */ + new_msg->msg.cnt = size + 1; + new_msg->data_objects = data_objects; + + return new_msg; +} + +/** Check description in emul_common_tcpci_partner.h */ +void tcpci_partner_free_msg(struct tcpci_partner_msg *msg) +{ + k_free(msg->msg.buf); + k_free(msg); +} + +/** Check description in emul_common_tcpci_partner.h */ +void tcpci_partner_set_header(struct tcpci_partner_data *data, + struct tcpci_partner_msg *msg) +{ + /* Header msg id has only 3 bits and wraps around after 8 messages */ + uint16_t msg_id = data->msg_id & 0x7; + uint16_t header = PD_HEADER(msg->type, data->power_role, + data->data_role, msg_id, msg->data_objects, + data->rev, 0 /* ext */); + data->msg_id++; + + msg->msg.buf[1] = (header >> 8) & 0xff; + msg->msg.buf[0] = header & 0xff; +} + +/** + * @brief Work function which sends delayed messages + * + * @param work Pointer to work structure + */ +static void tcpci_partner_delayed_send(struct k_work *work) +{ + struct k_work_delayable *kwd = k_work_delayable_from_work(work); + struct tcpci_partner_data *data = + CONTAINER_OF(kwd, struct tcpci_partner_data, delayed_send); + struct tcpci_partner_msg *msg; + uint64_t now; + int ret; + + do { + ret = k_mutex_lock(&data->to_send_mutex, K_FOREVER); + } while (ret); + + while (!sys_slist_is_empty(&data->to_send)) { + msg = SYS_SLIST_PEEK_HEAD_CONTAINER(&data->to_send, msg, node); + + now = k_uptime_get(); + if (now >= msg->time) { + sys_slist_get_not_empty(&data->to_send); + k_mutex_unlock(&data->to_send_mutex); + + tcpci_partner_set_header(data, msg); + ret = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg, + true /* send alert */); + if (ret) { + tcpci_partner_free_msg(msg); + } + + do { + ret = k_mutex_lock(&data->to_send_mutex, + K_FOREVER); + } while (ret); + } else { + k_work_reschedule(kwd, K_MSEC(msg->time - now)); + break; + } + } + + k_mutex_unlock(&data->to_send_mutex); +} + +/** Check description in emul_common_tcpci_partner.h */ +int tcpci_partner_send_msg(struct tcpci_partner_data *data, + struct tcpci_partner_msg *msg, uint64_t delay) +{ + struct tcpci_partner_msg *next_msg; + struct tcpci_partner_msg *prev_msg; + uint64_t now; + int ret; + + if (delay == 0) { + tcpci_partner_set_header(data, msg); + ret = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg, true); + if (ret) { + tcpci_partner_free_msg(msg); + } + + return ret; + } + + now = k_uptime_get(); + msg->time = now + delay; + + ret = k_mutex_lock(&data->to_send_mutex, K_FOREVER); + if (ret) { + tcpci_partner_free_msg(msg); + + return ret; + } + + prev_msg = SYS_SLIST_PEEK_HEAD_CONTAINER(&data->to_send, prev_msg, + node); + /* Current message should be sent first */ + if (prev_msg == NULL || prev_msg->time > msg->time) { + sys_slist_prepend(&data->to_send, &msg->node); + k_work_reschedule(&data->delayed_send, K_MSEC(delay)); + k_mutex_unlock(&data->to_send_mutex); + return 0; + } + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&data->to_send, prev_msg, next_msg, + node) { + /* + * If we reach tail or next message should be sent after new + * message, insert new message to the list. + */ + if (next_msg == NULL || next_msg->time > msg->time) { + sys_slist_insert(&data->to_send, &prev_msg->node, + &msg->node); + k_mutex_unlock(&data->to_send_mutex); + return 0; + } + } + + __ASSERT(0, "Message should be always inserted to the list"); + + return -1; +} + +/** Check description in emul_common_tcpci_partner.h */ +int tcpci_partner_send_control_msg(struct tcpci_partner_data *data, + enum pd_ctrl_msg_type type, + uint64_t delay) +{ + struct tcpci_partner_msg *msg; + + msg = tcpci_partner_alloc_msg(0); + if (msg == NULL) { + return -ENOMEM; + } + + msg->type = type; + + return tcpci_partner_send_msg(data, msg, delay); +} + +/** Check description in emul_common_tcpci_partner.h */ +int tcpci_partner_send_data_msg(struct tcpci_partner_data *data, + enum pd_data_msg_type type, + uint32_t *data_obj, int data_obj_num, + uint64_t delay) +{ + struct tcpci_partner_msg *msg; + int addr; + + msg = tcpci_partner_alloc_msg(data_obj_num); + if (msg == NULL) { + return -ENOMEM; + } + + for (int i = 0; i < data_obj_num; i++) { + /* Address of given data object in message buffer */ + addr = TCPCI_MSG_HEADER_LEN + i * TCPCI_MSG_DO_LEN; + sys_put_le32(data_obj[i], msg->msg.buf + addr); + } + + msg->type = type; + + return tcpci_partner_send_msg(data, msg, delay); +} + +/** Check description in emul_common_tcpci_partner.h */ +int tcpci_partner_clear_msg_queue(struct tcpci_partner_data *data) +{ + struct tcpci_partner_msg *msg; + int ret; + + k_work_cancel_delayable(&data->delayed_send); + + ret = k_mutex_lock(&data->to_send_mutex, K_FOREVER); + if (ret) { + return ret; + } + + while (!sys_slist_is_empty(&data->to_send)) { + msg = SYS_SLIST_CONTAINER( + sys_slist_get_not_empty(&data->to_send), + msg, node); + tcpci_partner_free_msg(msg); + } + + k_mutex_unlock(&data->to_send_mutex); + + return 0; +} + +/** Check description in emul_common_tcpci_partner.h */ +void tcpci_partner_init(struct tcpci_partner_data *data) +{ + k_work_init_delayable(&data->delayed_send, tcpci_partner_delayed_send); + sys_slist_init(&data->to_send); + k_mutex_init(&data->to_send_mutex); +} diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c new file mode 100644 index 0000000000..2f4d8628b5 --- /dev/null +++ b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c @@ -0,0 +1,433 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <logging/log.h> +LOG_MODULE_REGISTER(tcpci_snk_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL); + +#include <sys/byteorder.h> +#include <zephyr.h> + +#include "common.h" +#include "emul/tcpc/emul_tcpci.h" +#include "emul/tcpc/emul_tcpci_partner_common.h" +#include "emul/tcpc/emul_tcpci_partner_snk.h" +#include "usb_pd.h" + +/** Length of PDO, RDO and BIST request object in SOP message in bytes */ +#define TCPCI_MSG_DO_LEN 4 +/** Length of header in SOP message in bytes */ +#define TCPCI_MSG_HEADER_LEN 2 + +/** + * @brief Get number of PDOs that will be present in sink capability message + * + * @param data Pointer to USB-C sink emulator + * + * @return Number of PDOs that will be present in sink capability message + */ +static int tcpci_snk_emul_num_of_pdos(struct tcpci_snk_emul_data *data) +{ + for (int pdos = 0; pdos < PDO_MAX_OBJECTS; pdos++) { + if (data->pdo[pdos] == 0) { + return pdos; + } + } + + return PDO_MAX_OBJECTS; +} + +/** + * @brief Send capability message constructed from USB-C sink emulator PDOs + * + * @param data Pointer to USB-C sink emulator + * @param delay Optional delay + * + * @return 0 on success + * @return -ENOMEM when there is no free memory for message + * @return -EINVAL on TCPCI emulator add RX message error + */ +static int tcpci_snk_emul_send_capability_msg(struct tcpci_snk_emul_data *data, + uint64_t delay) +{ + int pdos; + + /* Find number of PDOs */ + pdos = tcpci_snk_emul_num_of_pdos(data); + + return tcpci_partner_send_data_msg(&data->common_data, + PD_DATA_SINK_CAP, + data->pdo, pdos, delay); +} + +/** + * @brief Check if given source PDO satisfy given sink PDO + * + * @param src_pdo PDO presented in source capabilities + * @param snk_pdo PDO presented in sink capabilities + * + * @return 0 on success + * @return -1 if PDOs are different types, PDOs type is unknown or source + * voltage not satisfy sink + * @return Positive value when voltage is OK, but source cannot provide enough + * current for sink. Amount of missing current is returned value in + * 10mA units. + */ +static int tcpci_snk_emul_are_pdos_complementary(uint32_t src_pdo, + uint32_t snk_pdo) +{ + uint32_t pdo_type = src_pdo & PDO_TYPE_MASK; + int missing_current; + + if ((snk_pdo & PDO_TYPE_MASK) != pdo_type) { + return -1; + } + + switch (pdo_type) { + case PDO_TYPE_FIXED: + if (PDO_FIXED_VOLTAGE(snk_pdo) != PDO_FIXED_VOLTAGE(src_pdo)) { + /* Voltage doesn't match */ + return -1; + } + missing_current = PDO_FIXED_CURRENT(snk_pdo) - + PDO_FIXED_CURRENT(src_pdo); + break; + case PDO_TYPE_BATTERY: + if ((PDO_BATT_MIN_VOLTAGE(snk_pdo) < + PDO_BATT_MIN_VOLTAGE(src_pdo)) || + (PDO_BATT_MAX_VOLTAGE(snk_pdo) > + PDO_BATT_MAX_VOLTAGE(src_pdo))) { + /* Voltage not in range */ + return -1; + } + /* + * Convert to current I * 10[mA] = P * 250[mW] / V * 50[mV] + * = P / V * 5 [A] = P / V * 500 * 10[mA] + */ + missing_current = (PDO_BATT_MAX_POWER(snk_pdo) - + PDO_BATT_MAX_POWER(src_pdo)) * 500 / + PDO_BATT_MAX_VOLTAGE(src_pdo); + break; + case PDO_TYPE_VARIABLE: + if ((PDO_VAR_MIN_VOLTAGE(snk_pdo) < + PDO_VAR_MIN_VOLTAGE(src_pdo)) || + (PDO_VAR_MAX_VOLTAGE(snk_pdo) > + PDO_VAR_MAX_VOLTAGE(src_pdo))) { + /* Voltage not in range */ + return -1; + } + missing_current = PDO_VAR_MAX_CURRENT(snk_pdo) - + PDO_VAR_MAX_CURRENT(src_pdo); + break; + default: + /* Unknown PDO type */ + return -1; + } + + if (missing_current > 0) { + /* Voltage is correct, but src doesn't offer enough current */ + return missing_current; + } + + return 0; +} + +/** + * @brief Get given PDO from source capability message + * + * @param msg Source capability message + * @param pdo_num Number of PDO to get. First PDO is 0. + * + * @return PDO on success + * @return 0 when there is no PDO of given index in message + */ +static uint32_t tcpci_snk_emul_get_pdo_from_cap( + const struct tcpci_emul_msg *msg, int pdo_num) +{ + int addr; + + /* Get address of PDO in message */ + addr = TCPCI_MSG_HEADER_LEN + pdo_num * TCPCI_MSG_DO_LEN; + + if (addr >= msg->cnt) { + return 0; + } + + return sys_get_le32(msg->buf + addr); +} + +/** + * @brief Create RDO for given sink and source PDOs + * + * @param src_pdo Selected source PDO + * @param snk_pdo Matching sink PDO + * @param src_pdo_num Index of source PDO in capability message. First PDO is 1. + * + * @return RDO on success + * @return 0 When type of PDOs doesn't match + */ +static uint32_t tcpci_snk_emul_create_rdo(uint32_t src_pdo, uint32_t snk_pdo, + int src_pdo_num) +{ + uint32_t pdo_type = src_pdo & PDO_TYPE_MASK; + int flags; + int pow; + int cur; + + if ((snk_pdo & PDO_TYPE_MASK) != pdo_type) { + return 0; + } + + switch (pdo_type) { + case PDO_TYPE_FIXED: + if (PDO_FIXED_CURRENT(snk_pdo) > PDO_FIXED_CURRENT(src_pdo)) { + flags = RDO_CAP_MISMATCH; + cur = PDO_FIXED_CURRENT(src_pdo); + } else { + flags = 0; + cur = PDO_FIXED_CURRENT(snk_pdo); + } + + /* + * Force mismatch flag if higher capability bit is set. Flags + * should be set only in the first PDO (vSafe5V). This statment + * will only be true for sink which requries higher voltage than + * 5V and doesn't found it in source capabilities. + */ + if (snk_pdo & PDO_FIXED_SNK_HIGHER_CAP) { + flags = RDO_CAP_MISMATCH; + } + + return RDO_FIXED(src_pdo_num, cur, PDO_FIXED_CURRENT(snk_pdo), + flags); + case PDO_TYPE_BATTERY: + if (PDO_BATT_MAX_POWER(snk_pdo) > PDO_BATT_MAX_POWER(src_pdo)) { + flags = RDO_CAP_MISMATCH; + pow = PDO_BATT_MAX_POWER(src_pdo); + } else { + flags = 0; + pow = PDO_BATT_MAX_POWER(snk_pdo); + } + + return RDO_BATT(src_pdo_num, pow, PDO_BATT_MAX_POWER(snk_pdo), + flags); + case PDO_TYPE_VARIABLE: + if (PDO_VAR_MAX_CURRENT(snk_pdo) > + PDO_VAR_MAX_CURRENT(src_pdo)) { + flags = RDO_CAP_MISMATCH; + cur = PDO_VAR_MAX_CURRENT(src_pdo); + } else { + flags = 0; + cur = PDO_VAR_MAX_CURRENT(snk_pdo); + } + return RDO_FIXED(src_pdo_num, cur, PDO_VAR_MAX_CURRENT(snk_pdo), + flags); + } + + return 0; +} + +/** + * @brief Respond to source capability message + * + * @param data Pointer to USB-C sink emulator + * @param msg Source capability message + */ +static void tcpci_snk_emul_handle_source_cap(struct tcpci_snk_emul_data *data, + const struct tcpci_emul_msg *msg) +{ + uint32_t rdo = 0; + uint32_t pdo; + int missing_current; + int skip_first_pdo; + int snk_pdos; + int src_pdos; + + /* If higher capability bit is set, skip matching to first (5V) PDO */ + if (data->pdo[0] & PDO_FIXED_SNK_HIGHER_CAP) { + skip_first_pdo = 1; + } else { + skip_first_pdo = 0; + } + + /* Find number of PDOs */ + snk_pdos = tcpci_snk_emul_num_of_pdos(data); + src_pdos = (msg->cnt - TCPCI_MSG_HEADER_LEN) / TCPCI_MSG_DO_LEN; + + /* Find if any source PDO satisfy any sink PDO */ + for (int pdo_num = 0; pdo_num < src_pdos; pdo_num++) { + pdo = tcpci_snk_emul_get_pdo_from_cap(msg, pdo_num); + + for (int i = skip_first_pdo; i < snk_pdos; i++) { + missing_current = tcpci_snk_emul_are_pdos_complementary( + pdo, data->pdo[i]); + if (missing_current == 0) { + rdo = tcpci_snk_emul_create_rdo(pdo, + data->pdo[i], + pdo_num + 1); + break; + } + } + + /* Correct PDO already found */ + if (rdo != 0) { + break; + } + } + + if (rdo == 0) { + /* Correct PDO wasn't found, let's use 5V */ + pdo = tcpci_snk_emul_get_pdo_from_cap(msg, 0); + rdo = tcpci_snk_emul_create_rdo(pdo, data->pdo[0], 1); + } + + tcpci_partner_send_data_msg(&data->common_data, PD_DATA_REQUEST, &rdo, + 1 /* = data_obj_num */, 0 /* = delay */); +} + +/** + * @brief Function called when TCPM wants to transmit message. Accept received + * message and generate response. + * + * @param emul Pointer to TCPCI emulator + * @param ops Pointer to partner operations structure + * @param tx_msg Pointer to TX message buffer + * @param type Type of message + * @param retry Count of retries + */ +static void tcpci_snk_emul_transmit_op(const struct emul *emul, + const struct tcpci_emul_partner_ops *ops, + const struct tcpci_emul_msg *tx_msg, + enum tcpci_msg_type type, + int retry) +{ + struct tcpci_snk_emul_data *data = + CONTAINER_OF(ops, struct tcpci_snk_emul_data, ops); + uint16_t header; + + /* Acknowledge that message was sent successfully */ + tcpci_emul_partner_msg_status(emul, TCPCI_EMUL_TX_SUCCESS); + + /* Handle hard reset */ + if (type == TCPCI_MSG_TX_HARD_RESET) { + tcpci_partner_clear_msg_queue(&data->common_data); + data->common_data.msg_id = 0; + return; + } + + /* Handle only SOP messages */ + if (type != TCPCI_MSG_SOP) { + return; + } + + LOG_HEXDUMP_INF(tx_msg->buf, tx_msg->cnt, + "USB-C sink received message"); + + header = sys_get_le16(tx_msg->buf); + + if (PD_HEADER_CNT(header)) { + /* Handle data message */ + switch (PD_HEADER_TYPE(header)) { + case PD_DATA_SOURCE_CAP: + tcpci_snk_emul_handle_source_cap(data, tx_msg); + break; + case PD_DATA_VENDOR_DEF: + /* VDM (vendor defined message) - ignore */ + break; + default: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + } + } else { + /* Handle control message */ + switch (PD_HEADER_TYPE(header)) { + case PD_CTRL_GET_SOURCE_CAP: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + case PD_CTRL_GET_SINK_CAP: + tcpci_snk_emul_send_capability_msg(data, 0); + break; + case PD_CTRL_DR_SWAP: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + case PD_CTRL_SOFT_RESET: + data->common_data.msg_id = 0; + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_ACCEPT, 0); + break; + case PD_CTRL_ACCEPT: + break; + case PD_CTRL_REJECT: + break; + case PD_CTRL_PING: + break; + case PD_CTRL_PS_RDY: + break; + default: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + } + } +} + +/** + * @brief Function called when TCPM consumes message. Free message that is no + * longer needed. + * + * @param emul Pointer to TCPCI emulator + * @param ops Pointer to partner operations structure + * @param rx_msg Message that was consumed by TCPM + */ +static void tcpci_snk_emul_rx_consumed_op( + const struct emul *emul, + const struct tcpci_emul_partner_ops *ops, + const struct tcpci_emul_msg *rx_msg) +{ + struct tcpci_partner_msg *msg = CONTAINER_OF(rx_msg, + struct tcpci_partner_msg, + msg); + + tcpci_partner_free_msg(msg); +} + +/** Check description in emul_tcpci_snk.h */ +int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data, + const struct emul *tcpci_emul) +{ + int ret; + + tcpci_emul_set_partner_ops(tcpci_emul, &data->ops); + ret = tcpci_emul_connect_partner(tcpci_emul, PD_ROLE_SINK, + TYPEC_CC_VOLT_RD, + TYPEC_CC_VOLT_OPEN, POLARITY_CC1); + if (!ret) { + data->common_data.tcpci_emul = tcpci_emul; + } + + return ret; +} + +/** Check description in emul_tcpci_snk.h */ +void tcpci_snk_emul_init(struct tcpci_snk_emul_data *data) +{ + tcpci_partner_init(&data->common_data); + + data->common_data.data_role = PD_ROLE_DFP; + data->common_data.power_role = PD_ROLE_SINK; + data->common_data.rev = PD_REV20; + + data->ops.transmit = tcpci_snk_emul_transmit_op; + data->ops.rx_consumed = tcpci_snk_emul_rx_consumed_op; + data->ops.control_change = NULL; + + /* By default there is only PDO 5v@500mA */ + data->pdo[0] = PDO_FIXED(5000, 500, 0); + for (int i = 1; i < PDO_MAX_OBJECTS; i++) { + data->pdo[i] = 0; + } +} diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_src.c b/zephyr/emul/tcpc/emul_tcpci_partner_src.c new file mode 100644 index 0000000000..8dad1c9c5e --- /dev/null +++ b/zephyr/emul/tcpc/emul_tcpci_partner_src.c @@ -0,0 +1,279 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <logging/log.h> +LOG_MODULE_REGISTER(tcpci_src_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL); + +#include <zephyr.h> + +#include "common.h" +#include "emul/tcpc/emul_tcpci_partner_common.h" +#include "emul/tcpc/emul_tcpci_partner_src.h" +#include "emul/tcpc/emul_tcpci.h" +#include "usb_pd.h" + +/** + * @brief Send capability message constructed from source device emulator PDOs + * + * @param data Pointer to USB-C source device emulator + * @param delay Optional delay + * + * @return 0 on success + * @return -ENOMEM when there is no free memory for message + * @return -EINVAL on TCPCI emulator add RX message error + */ +static int tcpci_src_emul_send_capability_msg(struct tcpci_src_emul_data *data, + uint64_t delay) +{ + int pdos; + + /* Find number of PDOs */ + for (pdos = 0; pdos < PDO_MAX_OBJECTS; pdos++) { + if (data->pdo[pdos] == 0) { + break; + } + } + + return tcpci_partner_send_data_msg(&data->common_data, + PD_DATA_SOURCE_CAP, + data->pdo, pdos, delay); +} + +/** + * @brief Function called when TCPM wants to transmit message. Accept received + * message and generate response. + * + * @param emul Pointer to TCPCI emulator + * @param ops Pointer to partner operations structure + * @param tx_msg Pointer to TX message buffer + * @param type Type of message + * @param retry Count of retries + */ +static void tcpci_src_emul_transmit_op(const struct emul *emul, + const struct tcpci_emul_partner_ops *ops, + const struct tcpci_emul_msg *tx_msg, + enum tcpci_msg_type type, + int retry) +{ + struct tcpci_src_emul_data *data = + CONTAINER_OF(ops, struct tcpci_src_emul_data, ops); + uint16_t header; + + /* Acknowledge that message was sent successfully */ + tcpci_emul_partner_msg_status(emul, TCPCI_EMUL_TX_SUCCESS); + + /* Handle only SOP messages */ + if (type != TCPCI_MSG_SOP) { + return; + } + + LOG_HEXDUMP_DBG(tx_msg->buf, tx_msg->cnt, "Source received message"); + + header = (tx_msg->buf[1] << 8) | tx_msg->buf[0]; + + if (PD_HEADER_CNT(header)) { + /* Handle data message */ + switch (PD_HEADER_TYPE(header)) { + case PD_DATA_REQUEST: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_ACCEPT, 0); + /* PS ready after 15 ms */ + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_PS_RDY, 15); + break; + case PD_DATA_VENDOR_DEF: + /* VDM (vendor defined message) - ignore */ + break; + default: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + } + } else { + /* Handle control message */ + switch (PD_HEADER_TYPE(header)) { + case PD_CTRL_GET_SOURCE_CAP: + tcpci_src_emul_send_capability_msg(data, 0); + break; + case PD_CTRL_GET_SINK_CAP: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + case PD_CTRL_DR_SWAP: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + case PD_CTRL_SOFT_RESET: + data->common_data.msg_id = 0; + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_ACCEPT, 0); + /* Send capability after 15 ms to establish PD again */ + tcpci_src_emul_send_capability_msg(data, 15); + break; + default: + tcpci_partner_send_control_msg(&data->common_data, + PD_CTRL_REJECT, 0); + break; + } + } +} + +/** + * @brief Function called when TCPM consumes message. Free message that is no + * longer needed. + * + * @param emul Pointer to TCPCI emulator + * @param ops Pointer to partner operations structure + * @param rx_msg Message that was consumed by TCPM + */ +static void tcpci_src_emul_rx_consumed_op( + const struct emul *emul, + const struct tcpci_emul_partner_ops *ops, + const struct tcpci_emul_msg *rx_msg) +{ + struct tcpci_partner_msg *msg = CONTAINER_OF(rx_msg, + struct tcpci_partner_msg, + msg); + + tcpci_partner_free_msg(msg); +} + +/** Check description in emul_tcpci_partner_src.h */ +int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data, + const struct emul *tcpci_emul) +{ + int ec; + + tcpci_emul_set_partner_ops(tcpci_emul, &data->ops); + ec = tcpci_emul_connect_partner(tcpci_emul, PD_ROLE_SOURCE, + TYPEC_CC_VOLT_RP_3_0, + TYPEC_CC_VOLT_OPEN, POLARITY_CC1); + if (ec) { + return ec; + } + + data->common_data.tcpci_emul = tcpci_emul; + + return tcpci_src_emul_send_capability_msg(data, 0); +} + +#define PDO_FIXED_FLAGS_MASK \ + (PDO_FIXED_DUAL_ROLE | PDO_FIXED_UNCONSTRAINED | \ + PDO_FIXED_COMM_CAP | PDO_FIXED_DATA_SWAP) + +/** Check description in emul_tcpci_parnter_src.h */ +enum check_pdos_res tcpci_src_emul_check_pdos(struct tcpci_src_emul_data *data) +{ + int volt_i_min; + int volt_i_max; + int volt_min; + int volt_max; + int i; + + /* Check that first PDO is fixed 5V */ + if ((data->pdo[0] & PDO_TYPE_MASK) != PDO_TYPE_FIXED || + PDO_FIXED_VOLTAGE(data->pdo[0]) != 5000) { + return TCPCI_SRC_EMUL_FIRST_PDO_NO_FIXED_5V; + } + + /* Check fixed PDOs are before other types and are in correct order */ + for (i = 1, volt_min = -1; + i < PDO_MAX_OBJECTS && data->pdo[i] != 0 && + (data->pdo[i] & PDO_TYPE_MASK) != PDO_TYPE_FIXED; + i++) { + volt_i_min = PDO_FIXED_VOLTAGE(data->pdo[i]); + /* Each voltage should be only once */ + if (volt_i_min == volt_min || volt_i_min == 5000) { + return TCPCI_SRC_EMUL_FIXED_VOLT_REPEATED; + } + /* Check that voltage is increasing in next PDO */ + if (volt_i_min < volt_min) { + return TCPCI_SRC_EMUL_FIXED_VOLT_NOT_IN_ORDER; + } + /* Check that fixed PDOs (except first) have cleared flags */ + if (data->pdo[i] & PDO_FIXED_FLAGS_MASK) { + return TCPCI_SRC_EMUL_NON_FIRST_PDO_FIXED_FLAGS; + } + /* Save current voltage */ + volt_min = volt_i_min; + } + + /* Check battery PDOs are before variable type and are in order */ + for (volt_min = -1, volt_max = -1; + i < PDO_MAX_OBJECTS && data->pdo[i] != 0 && + (data->pdo[i] & PDO_TYPE_MASK) != PDO_TYPE_BATTERY; + i++) { + volt_i_min = PDO_BATT_MIN_VOLTAGE(data->pdo[i]); + volt_i_max = PDO_BATT_MAX_VOLTAGE(data->pdo[i]); + /* Each voltage range should be only once */ + if (volt_i_min == volt_min && volt_i_max == volt_max) { + return TCPCI_SRC_EMUL_BATT_VOLT_REPEATED; + } + /* + * Lower minimal voltage should be first, than lower maximal + * voltage. + */ + if (volt_i_min < volt_min || + (volt_i_min == volt_min && volt_i_max < volt_max)) { + return TCPCI_SRC_EMUL_BATT_VOLT_NOT_IN_ORDER; + } + /* Save current voltage */ + volt_min = volt_i_min; + volt_max = volt_i_max; + } + + /* Check variable PDOs are last and are in correct order */ + for (volt_min = -1, volt_max = -1; + i < PDO_MAX_OBJECTS && data->pdo[i] != 0 && + (data->pdo[i] & PDO_TYPE_MASK) != PDO_TYPE_VARIABLE; + i++) { + volt_i_min = PDO_VAR_MIN_VOLTAGE(data->pdo[i]); + volt_i_max = PDO_VAR_MAX_VOLTAGE(data->pdo[i]); + /* Each voltage range should be only once */ + if (volt_i_min == volt_min && volt_i_max == volt_max) { + return TCPCI_SRC_EMUL_VAR_VOLT_REPEATED; + } + /* + * Lower minimal voltage should be first, than lower maximal + * voltage. + */ + if (volt_i_min < volt_min || + (volt_i_min == volt_min && volt_i_max < volt_max)) { + return TCPCI_SRC_EMUL_VAR_VOLT_NOT_IN_ORDER; + } + /* Save current voltage */ + volt_min = volt_i_min; + volt_max = volt_i_max; + } + + /* Check that all PDOs after first 0 are unused and set to 0 */ + for (; i < PDO_MAX_OBJECTS; i++) { + if (data->pdo[i] != 0) { + return TCPCI_SRC_EMUL_PDO_AFTER_ZERO; + } + } + + return TCPCI_SRC_EMUL_CHECK_PDO_OK; +} + +/** Check description in emul_tcpci_parnter_src.h */ +void tcpci_src_emul_init(struct tcpci_src_emul_data *data) +{ + tcpci_partner_init(&data->common_data); + + data->common_data.data_role = PD_ROLE_UFP; + data->common_data.power_role = PD_ROLE_SOURCE; + data->common_data.rev = PD_REV20; + + data->ops.transmit = tcpci_src_emul_transmit_op; + data->ops.rx_consumed = tcpci_src_emul_rx_consumed_op; + data->ops.control_change = NULL; + + /* By default there is only PDO 5v@3A */ + data->pdo[0] = PDO_FIXED(5000, 3000, PDO_FIXED_UNCONSTRAINED); + for (int i = 1; i < PDO_MAX_OBJECTS; i++) { + data->pdo[i] = 0; + } +} diff --git a/zephyr/include/cros/ite/it8xxx2.dtsi b/zephyr/include/cros/ite/it8xxx2.dtsi index 54ca7f63e3..d835d9d4f1 100644 --- a/zephyr/include/cros/ite/it8xxx2.dtsi +++ b/zephyr/include/cros/ite/it8xxx2.dtsi @@ -4,8 +4,18 @@ */ #include <cros/binman.dtsi> +#include <it8xxx2.dtsi> / { + chosen { + cros-ec,adc = &adc0; + cros-ec,bbram = &bbram; + cros-ec,espi = &espi0; + cros-ec,flash = &fiu0; + cros-ec,raw-kb = &cros_kb_raw; + cros-ec,watchdog = &twd0; + }; + named-bbram-regions { compatible = "named-bbram-regions"; @@ -67,6 +77,17 @@ reg = <0x80000000 0x100000>; label = "FLASH"; }; + + /delete-node/ kscan@f01d00; + + cros_kb_raw: cros-kb-raw@f01d00 { + compatible = "ite,it8xxx2-cros-kb-raw"; + reg = <0x00f01d00 0x29>; + label = "CROS_KB_RAW_0"; + interrupt-parent = <&intc>; + interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; }; /* it8xxx2 has 1MB of flash. currently, we use 512KB from flash. */ diff --git a/zephyr/include/cros/nuvoton/npcx.dtsi b/zephyr/include/cros/nuvoton/npcx.dtsi index 8767ee7c5b..0a658663a8 100644 --- a/zephyr/include/cros/nuvoton/npcx.dtsi +++ b/zephyr/include/cros/nuvoton/npcx.dtsi @@ -10,6 +10,14 @@ #include <nuvoton/npcx.dtsi> / { + chosen { + cros-ec,adc = &adc0; + cros-ec,bbram = &bbram; + cros-ec,espi = &espi0; + cros-ec,flash = &fiu0; + cros-ec,raw-kb = &cros_kb_raw; + cros-ec,watchdog = &twd0; + }; named-bbram-regions { compatible = "named-bbram-regions"; diff --git a/zephyr/include/drivers/cros_cbi.h b/zephyr/include/drivers/cros_cbi.h index 0aecbb4d19..15c94bcb19 100644 --- a/zephyr/include/drivers/cros_cbi.h +++ b/zephyr/include/drivers/cros_cbi.h @@ -15,12 +15,17 @@ #include <device.h> #include <devicetree.h> +/* + * Macros are _INST_ types, so require DT_DRV_COMPAT to be defined. + */ +#define DT_DRV_COMPAT named_cbi_ssfc_value +#define CROS_CBI_LABEL "cros_cbi" + #define CBI_SSFC_VALUE_COMPAT named_cbi_ssfc_value #define CBI_SSFC_VALUE_ID(id) DT_CAT(CBI_SSFC_VALUE_, id) #define CBI_SSFC_VALUE_ID_WITH_COMMA(id) CBI_SSFC_VALUE_ID(id), #define CBI_SSFC_VALUE_INST_ENUM(inst, _) \ CBI_SSFC_VALUE_ID_WITH_COMMA(DT_INST(inst, CBI_SSFC_VALUE_COMPAT)) -#define CROS_CBI_LABEL "cros_cbi" enum cbi_ssfc_value_id { UTIL_LISTIFY(DT_NUM_INST_STATUS_OKAY(CBI_SSFC_VALUE_COMPAT), @@ -28,6 +33,57 @@ enum cbi_ssfc_value_id { CBI_SSFC_VALUE_COUNT }; +#undef DT_DRV_COMPAT + +/* + * Macros to help generate the enum list of field and value names + * for the FW_CONFIG CBI data. + */ +#define CBI_FW_CONFIG_COMPAT named_cbi_fw_config +#define CBI_FW_CONFIG_VALUE_COMPAT named_cbi_fw_config_value + +/* + * Retrieve the enum-name property for this node. + */ +#define CBI_FW_CONFIG_ENUM(node) DT_STRING_TOKEN(node, enum_name) + +/* + * Create an enum entry without a value (an enum with a following comma). + */ +#define CBI_FW_CONFIG_ENUM_WITH_COMMA(node) \ + CBI_FW_CONFIG_ENUM(node), + +/* + * Create a single enum entry with assignment to the node's value, + * along with a following comma. + */ +#define CBI_FW_CONFIG_ENUM_WITH_VALUE(node) \ + CBI_FW_CONFIG_ENUM(node) = DT_PROP(node, value), + +/* + * Generate a list of enum entries without a value. + */ +#define CBI_FW_CONFIG_CHILD_ENUM_LIST(node) \ + DT_FOREACH_CHILD_STATUS_OKAY(node, CBI_FW_CONFIG_ENUM_WITH_COMMA) + +/* + * Enum list of all fields. + */ +enum cbi_fw_config_field_id { + DT_FOREACH_STATUS_OKAY(CBI_FW_CONFIG_COMPAT, + CBI_FW_CONFIG_CHILD_ENUM_LIST) + CBI_FW_CONFIG_FIELDS_COUNT +}; + +/* + * enum list of all child values. + */ +enum cbi_fw_config_value_id { + DT_FOREACH_STATUS_OKAY(CBI_FW_CONFIG_VALUE_COMPAT, + CBI_FW_CONFIG_ENUM_WITH_VALUE) + CBI_FW_CONFIG_VALUES_LAST /* added to ensure at least one entry */ +}; + /** * @cond INTERNAL_HIDDEN * @@ -38,10 +94,14 @@ enum cbi_ssfc_value_id { typedef int (*cros_cbi_api_init)(const struct device *dev); typedef bool (*cros_cbi_api_ssfc_check_match)(const struct device *dev, enum cbi_ssfc_value_id value_id); +typedef int (*cros_cbi_api_get_fw_config)(const struct device *dev, + enum cbi_fw_config_field_id field_id, + uint32_t *value); __subsystem struct cros_cbi_driver_api { cros_cbi_api_init init; cros_cbi_api_ssfc_check_match ssfc_check_match; + cros_cbi_api_get_fw_config get_fw_config; }; /** @@ -88,14 +148,42 @@ z_impl_cros_cbi_ssfc_check_match(const struct device *dev, const struct cros_cbi_driver_api *api = (const struct cros_cbi_driver_api *)dev->api; - if (!api->ssfc_check_match) { + if (!api->ssfc_check_match) return -ENOTSUP; - } return api->ssfc_check_match(dev, value_id); } /** + * @brief Retrieve the value of the FW_CONFIG field + * + * @param dev Pointer to the device. + * @param field_id Enum identifying the field to return. + * @param value Pointer to the returned value. + * + * @return 0 if value found and returned. + * @retval -ENOTSUP Not supported api function. + * @retval -EINVAL Invalid field_id. + */ +__syscall int cros_cbi_get_fw_config(const struct device *dev, + enum cbi_fw_config_field_id field_id, + uint32_t *value); + +static inline int +z_impl_cros_cbi_get_fw_config(const struct device *dev, + enum cbi_fw_config_field_id field_id, + uint32_t *value) +{ + const struct cros_cbi_driver_api *api = + (const struct cros_cbi_driver_api *)dev->api; + + if (!api->get_fw_config) + return -ENOTSUP; + + return api->get_fw_config(dev, field_id, value); +} + +/** * @} */ #include <syscalls/cros_cbi.h> diff --git a/zephyr/include/emul/emul_charger.h b/zephyr/include/emul/emul_charger.h deleted file mode 100644 index 87303181e8..0000000000 --- a/zephyr/include/emul/emul_charger.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * @file - * - * @brief Backend API for USB-C charger emulator - */ - -#ifndef __EMUL_CHARGER_H -#define __EMUL_CHARGER_H - -#include <emul.h> -#include "emul/emul_tcpci.h" - -/** - * @brief USB-C charger emulator backend API - * @defgroup charger_emul USB-C charger emulator - * @{ - * - * USB-C charger emulator can be attached to TCPCI emulator. It is able to - * respond to some TCPM messages. It always attach as source and present - * hardcoded set of source capabilities. - */ - -/** Structure describing charger emulator */ -struct charger_emul_data { - /** Operations used by TCPCI emulator */ - struct tcpci_emul_partner_ops ops; - /** Work used to send message with delay */ - struct k_work_delayable delayed_send; - /** Pointer to connected TCPCI emulator */ - const struct emul *tcpci_emul; - /** Queue for delayed messages */ - struct k_fifo to_send; - /** Next SOP message id */ - int msg_id; -}; - -/** - * @brief Initialise USB-C charger emulator. Need to be called before any other - * function. - * - * @param data Pointer to USB-C charger emulator - */ -void charger_emul_init(struct charger_emul_data *data); - -/** - * @brief Connect emulated device to TCPCI - * - * @param data Pointer to USB-C charger emulator - * @param tcpci_emul Poinetr to TCPCI emulator to connect - * - * @return 0 on success - * @return negative on TCPCI connect error or send source capabilities error - */ -int charger_emul_connect_to_tcpci(struct charger_emul_data *data, - const struct emul *tcpci_emul); - -/** - * @} - */ - -#endif /* __EMUL_CHARGER */ diff --git a/zephyr/include/emul/emul_isl923x.h b/zephyr/include/emul/emul_isl923x.h index f24922afd5..2edae32d84 100644 --- a/zephyr/include/emul/emul_isl923x.h +++ b/zephyr/include/emul/emul_isl923x.h @@ -79,4 +79,22 @@ void isl923x_emul_set_learn_mode_enabled(const struct emul *emulator, void isl923x_emul_set_adc_vbus(const struct emul *emulator, uint16_t value); +/** + * @brief Set the state of the ACOK pin, which is reflected in the INFO2 + * register + * + * @param value If 1, AC adapter is present. If 0, no adapter is present + */ +void raa489000_emul_set_acok_pin(const struct emul *emulator, uint16_t value); + +/** + * @brief Peek at a register value. This function will assert if the requested + * register does is unimplemented. + * + * @param emulator Reference to the I2C emulator being used + * @param reg The address of the register to query + * @return The 16-bit value of the register + */ +uint16_t isl923x_emul_peek_reg(struct i2c_emul *i2c_emul, int reg); + #endif /* ZEPHYR_INCLUDE_EMUL_EMUL_ISL923X_H_ */ diff --git a/zephyr/include/emul/emul_lis2dw12.h b/zephyr/include/emul/emul_lis2dw12.h index b136e24f0a..0d630af215 100644 --- a/zephyr/include/emul/emul_lis2dw12.h +++ b/zephyr/include/emul/emul_lis2dw12.h @@ -45,4 +45,56 @@ void lis2dw12_emul_set_who_am_i(const struct emul *emul, uint8_t who_am_i); */ uint32_t lis2dw12_emul_get_soft_reset_count(const struct emul *emul); +/** + * @brief Peeks at the value of a register without doing any I2C transaction. + * If the register is unsupported, or `emul` is NULL, this function + * asserts. + * + * @param emul The emulator to query + * @param reg The register to access + * @return The value of the register + */ +uint8_t lis2dw12_emul_peek_reg(struct i2c_emul *emul, int reg); + +/** + * @brief Retrieves the ODR[3:0] bits from CRTL1 register + * + * @param emul The emulator to query + * @return The ODR bits, right-aligned + */ +uint8_t lis2dw12_emul_peek_odr(struct i2c_emul *emul); + +/** + * @brief Retrieves the MODE[1:0] bits from CRTL1 register + * + * @param emul The emulator to query + * @return The MODE bits, right-aligned + */ +uint8_t lis2dw12_emul_peek_mode(struct i2c_emul *emul); + +/** + * @brief Retrieves the LPMODE[1:0] bits from CRTL1 register + * + * @param emul The emulator to query + * @return The LPMODE bits, right-aligned + */ +uint8_t lis2dw12_emul_peek_lpmode(struct i2c_emul *emul); + +/** + * @brief Updates the current 3-axis acceleromter reading and + * sets the DRDY (data ready) flag. + * @param emul Reference to current LIS2DW12 emulator. + * @param reading array of int X, Y, and Z readings. + * @return 0 on success, or -EINVAL if readings are out of bounds. + */ +int lis2dw12_emul_set_accel_reading(const struct emul *emul, + intv3_t reading); + +/** + * @brief Clears the current accelerometer reading and resets the + * DRDY (data ready) flag. + * @param emul Reference to current LIS2DW12 emulator. + */ +void lis2dw12_emul_clear_accel_reading(const struct emul *emul); + #endif /* ZEPHYR_INCLUDE_EMUL_EMUL_LIS2DW12_H_ */ diff --git a/zephyr/include/emul/emul_sn5s330.h b/zephyr/include/emul/emul_sn5s330.h index 00b473e206..c6ea31b6d6 100644 --- a/zephyr/include/emul/emul_sn5s330.h +++ b/zephyr/include/emul/emul_sn5s330.h @@ -23,9 +23,8 @@ struct i2c_emul *sn5s330_emul_to_i2c_emul(const struct emul *emul); * @param emul The emulator to query * @param reg The register to read * @param val Pointer to write the register value to - * @return 0 on success */ -int sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint32_t *val); +void sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint8_t *val); /** * @brief Reset the sn5s330 emulator @@ -34,4 +33,18 @@ int sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint32_t *val); */ void sn5s330_emul_reset(const struct emul *emul); +/** + * @brief Emulate vbus overcurrent clamping condition. + * + * @param emul The sn5s330 chip emulator. + */ +void sn5s330_emul_make_vbus_overcurrent(const struct emul *emul); + +/** + * @brief Emulate vbus voltage is below min 0.6V. + * + * @param emul The sn5s330 chip emulator. + */ +void sn5s330_emul_lower_vbus_below_minv(const struct emul *emul); + #endif /* ZEPHYR_INCLUDE_EMUL_EMUL_SN5S330_H_ */ diff --git a/zephyr/include/emul/emul_syv682x.h b/zephyr/include/emul/emul_syv682x.h index 46580e8257..3cf9d9e6de 100644 --- a/zephyr/include/emul/emul_syv682x.h +++ b/zephyr/include/emul/emul_syv682x.h @@ -24,15 +24,16 @@ #define SYV682X_CONTROL_4_REG 0x04 /* Status Register */ -#define SYV682X_STATUS_OC_HV BIT(7) -#define SYV682X_STATUS_RVS BIT(6) -#define SYV682X_STATUS_OC_5V BIT(5) -#define SYV682X_STATUS_OVP BIT(4) -#define SYV682X_STATUS_FRS BIT(3) -#define SYV682X_STATUS_TSD BIT(2) -#define SYV682X_STATUS_VSAFE_5V BIT(1) -#define SYV682X_STATUS_VSAFE_0V BIT(0) -#define SYV682X_STATUS_INT_MASK 0xfc +#define SYV682X_STATUS_OC_HV BIT(7) +#define SYV682X_STATUS_RVS BIT(6) +#define SYV682X_STATUS_OC_5V BIT(5) +#define SYV682X_STATUS_OVP BIT(4) +#define SYV682X_STATUS_FRS BIT(3) +#define SYV682X_STATUS_TSD BIT(2) +#define SYV682X_STATUS_VSAFE_5V BIT(1) +#define SYV682X_STATUS_VSAFE_0V BIT(0) +#define SYV682X_STATUS_INT_MASK 0xfc +#define SYV682X_STATUS_NONE 0 /* Control Register 1 */ #define SYV682X_CONTROL_1_CH_SEL BIT(1) @@ -89,6 +90,7 @@ #define SYV682X_OVP_17_9 5 #define SYV682X_OVP_21_6 6 #define SYV682X_OVP_23_7 7 +#define SYV682X_CONTROL_3_NONE 0 /* Control Register 4 */ #define SYV682X_CONTROL_4_CC1_BPS BIT(7) @@ -99,6 +101,7 @@ #define SYV682X_CONTROL_4_VCONN_OCP BIT(2) #define SYV682X_CONTROL_4_CC_FRS BIT(1) #define SYV682X_CONTROL_4_INT_MASK 0x0c +#define SYV682X_CONTROL_4_NONE 0 /** * @brief Get pointer to SYV682x emulator using device tree order number. @@ -110,24 +113,27 @@ struct i2c_emul *syv682x_emul_get(int ord); /** - * @brief Set the underlying interrupt conditions affecting the status register + * @brief Set the underlying interrupt conditions affecting the SYV682x * - * @param emul SYV682x emulator - * @param val A status register value corresponding to the underlying - * conditions + * @param emul SYV682x emulator + * @param status A status register value corresponding to the underlying + * conditions + * @param control_4 A control 4 register value corresponding to the underlying + * conditions; only the bits in SYV682X_CONTROL_4_INT_MASK have + * an effect. */ -void syv682x_emul_set_status(struct i2c_emul *emul, uint8_t val); +void syv682x_emul_set_condition(struct i2c_emul *emul, uint8_t status, + uint8_t control_4); /** - * @brief Set the underlying interrupt conditions affecting the control 4 - * register + * @brief Cause CONTROL_3[BUSY] to be set for a number of reads. This bit + * signals that I2C writes will be ignored. Each call overrides any + * previous setting. * - * @param emul SYV682x emulator - * @param val A control 4 register value corresponding to the underlying - * conditions; only the bits in SYV682X_CONTROL_4_INT_MASK have an - * effect. + * @param emul SYV682x emulator + * @param reads The number of reads of CONTROL_3 to keep BUSY set for */ -void syv682x_emul_set_control_4(struct i2c_emul *emul, uint8_t val); +void syv682x_emul_set_busy_reads(struct i2c_emul *emul, int reads); /** * @brief Set value of a register of SYV682x diff --git a/zephyr/include/emul/emul_ps8xxx.h b/zephyr/include/emul/tcpc/emul_ps8xxx.h index 110def22ec..110def22ec 100644 --- a/zephyr/include/emul/emul_ps8xxx.h +++ b/zephyr/include/emul/tcpc/emul_ps8xxx.h diff --git a/zephyr/include/emul/emul_tcpci.h b/zephyr/include/emul/tcpc/emul_tcpci.h index 7be5b2711c..3a5a3047d7 100644 --- a/zephyr/include/emul/emul_tcpci.h +++ b/zephyr/include/emul/tcpc/emul_tcpci.h @@ -299,6 +299,14 @@ int tcpci_emul_connect_partner(const struct emul *emul, enum tcpc_cc_voltage_status partner_cc2, enum tcpc_cc_polarity polarity); +/** @brief Emulate the disconnection of the partner device to emulated TCPCI + * + * @param emul Pointer to TCPCI emulator + * + * @return 0 on success + */ +int tcpci_emul_disconnect_partner(const struct emul *emul); + /** * @brief Allows port partner to select if message was received correctly * diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h new file mode 100644 index 0000000000..0275161d73 --- /dev/null +++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h @@ -0,0 +1,161 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * @file + * + * @brief Common code used by TCPCI partner device emulators + */ + +#ifndef __EMUL_TCPCI_PARTNER_COMMON_H +#define __EMUL_TCPCI_PARTNER_COMMON_H + +#include <emul.h> +#include "emul/tcpc/emul_tcpci.h" + +#include "ec_commands.h" +#include "usb_pd.h" + +/** + * @brief Common code used by TCPCI partner device emulators + * @defgroup tcpci_partner Common code for TCPCI partner device emulators + * @{ + * + * Common code for TCPCI partner device emulators allows to send SOP messages + * in generic way using optional delay. + */ + +/** Common data for TCPCI partner device emulators */ +struct tcpci_partner_data { + /** Work used to send message with delay */ + struct k_work_delayable delayed_send; + /** Pointer to connected TCPCI emulator */ + const struct emul *tcpci_emul; + /** Queue for delayed messages */ + sys_slist_t to_send; + /** Mutex for to_send queue */ + struct k_mutex to_send_mutex; + /** Next SOP message id */ + int msg_id; + /** Power role (used in message header) */ + enum pd_power_role power_role; + /** Data role (used in message header) */ + enum pd_data_role data_role; + /** Revision (used in message header) */ + enum pd_rev_type rev; +}; + +/** Structure of message used by TCPCI partner emulator */ +struct tcpci_partner_msg { + /** Reserved for sys_slist_* usage */ + sys_snode_t node; + /** TCPCI emulator message */ + struct tcpci_emul_msg msg; + /** Time when message should be sent if message is delayed */ + uint64_t time; + /** Type of the message */ + int type; + /** Number of data objects */ + int data_objects; +}; + +/** + * @brief Initialise common TCPCI partner emulator. Need to be called before + * any other function. + * + * @param data Pointer to USB-C charger emulator + */ +void tcpci_partner_init(struct tcpci_partner_data *data); + +/** + * @brief Allocate message with space for header and given number of data + * objects. Type of message is set to TCPCI_MSG_SOP by default. + * + * @param data_objects Number of data objects in message + * + * @return Pointer to new message on success + * @return NULL on error + */ +struct tcpci_partner_msg *tcpci_partner_alloc_msg(int data_objects); + +/** + * @brief Free message's memory + * + * @param msg Pointer to message + */ +void tcpci_partner_free_msg(struct tcpci_partner_msg *msg); + +/** + * @brief Set header of the message + * + * @param data Pointer to TCPCI partner emulator + * @param msg Pointer to message + */ +void tcpci_partner_set_header(struct tcpci_partner_data *data, + struct tcpci_partner_msg *msg); + +/** + * @brief Send message to TCPCI emulator or schedule message. On error message + * is freed. + * + * @param data Pointer to TCPCI partner emulator + * @param msg Pointer to message to send + * @param delay Optional delay + * + * @return 0 on success + * @return negative on failure + */ +int tcpci_partner_send_msg(struct tcpci_partner_data *data, + struct tcpci_partner_msg *msg, uint64_t delay); + +/** + * @brief Send control message with optional delay + * + * @param data Pointer to TCPCI partner emulator + * @param type Type of message + * @param delay Optional delay + * + * @return 0 on success + * @return -ENOMEM when there is no free memory for message + * @return negative on failure + */ +int tcpci_partner_send_control_msg(struct tcpci_partner_data *data, + enum pd_ctrl_msg_type type, + uint64_t delay); + +/** + * @brief Send data message with optional delay. Data objects are copied to + * message. + * + * @param data Pointer to TCPCI partner emulator + * @param type Type of message + * @param data_obj Pointer to array of data objects + * @param data_obj_num Number of data objects + * @param delay Optional delay + * + * @return 0 on success + * @return -ENOMEM when there is no free memory for message + * @return negative on failure + */ +int tcpci_partner_send_data_msg(struct tcpci_partner_data *data, + enum pd_data_msg_type type, + uint32_t *data_obj, int data_obj_num, + uint64_t delay); + +/** + * @brief Remove all messages that are in delayed message queue + * + * @param data Pointer to TCPCI partner emulator + * + * @return 0 on success + * @return negative on failure + */ +int tcpci_partner_clear_msg_queue(struct tcpci_partner_data *data); + +/** + * @} + */ + +#endif /* __EMUL_TCPCI_PARTNER_COMMON_H */ diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h new file mode 100644 index 0000000000..7e2482a4ad --- /dev/null +++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h @@ -0,0 +1,65 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * @file + * + * @brief Backend API for USB-C sink device emulator + */ + +#ifndef __EMUL_TCPCI_PARTNER_SNK_H +#define __EMUL_TCPCI_PARTNER_SNK_H + +#include <emul.h> +#include "emul/tcpc/emul_tcpci_partner_common.h" +#include "emul/tcpc/emul_tcpci.h" +#include "usb_pd.h" + +/** + * @brief USB-C sink device emulator backend API + * @defgroup tcpci_snk_emul USB-C sink device emulator + * @{ + * + * USB-C sink device emulator can be attached to TCPCI emulator. It is able to + * respond to some TCPM messages. It always attach as sink and present + * sink capabilities constructed from given PDOs. + */ + +/** Structure describing sink device emulator */ +struct tcpci_snk_emul_data { + /** Common TCPCI partner data */ + struct tcpci_partner_data common_data; + /** Operations used by TCPCI emulator */ + struct tcpci_emul_partner_ops ops; + /** Power data objects returned in sink capabilities message */ + uint32_t pdo[PDO_MAX_OBJECTS]; +}; + +/** + * @brief Initialise USB-C sink device emulator. Need to be called before + * any other function. + * + * @param data Pointer to USB-C sink device emulator + */ + +void tcpci_snk_emul_init(struct tcpci_snk_emul_data *data); + +/** + * @brief Connect emulated device to TCPCI + * + * @param data Pointer to USB-C sink device emulator + * @param tcpci_emul Pointer to TCPCI emulator to connect + * + * @return 0 on success + * @return negative on TCPCI connect error + */ +int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data, + const struct emul *tcpci_emul); + +/** + * @} + */ + +#endif /* __EMUL_TCPCI_PARTNER_SNK_H */ diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h new file mode 100644 index 0000000000..549afb5cc0 --- /dev/null +++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h @@ -0,0 +1,106 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * @file + * + * @brief Backend API for USB-C source device emulator + */ + +#ifndef __EMUL_TCPCI_PARTNER_SRC_H +#define __EMUL_TCPCI_PARTNER_SRC_H + +#include <emul.h> +#include "emul/tcpc/emul_tcpci_partner_common.h" +#include "emul/tcpc/emul_tcpci.h" +#include "usb_pd.h" + +/** + * @brief USB-C source device emulator backend API + * @defgroup tcpci_src_emul USB-C source device emulator + * @{ + * + * USB-C source device emulator can be attached to TCPCI emulator. It is able to + * respond to some TCPM messages. It always attach as source and present + * source capabilities constructed from given PDOs. + */ + +/** Structure describing source device emulator */ +struct tcpci_src_emul_data { + /** Common TCPCI partner data */ + struct tcpci_partner_data common_data; + /** Operations used by TCPCI emulator */ + struct tcpci_emul_partner_ops ops; + /** Power data objects returned in source capabilities message */ + uint32_t pdo[PDO_MAX_OBJECTS]; +}; + +/** Return values of @ref tcpci_src_emul_check_pdos function */ +enum check_pdos_res { + TCPCI_SRC_EMUL_CHECK_PDO_OK = 0, + TCPCI_SRC_EMUL_FIRST_PDO_NO_FIXED_5V, + TCPCI_SRC_EMUL_FIXED_VOLT_REPEATED, + TCPCI_SRC_EMUL_FIXED_VOLT_NOT_IN_ORDER, + TCPCI_SRC_EMUL_NON_FIRST_PDO_FIXED_FLAGS, + TCPCI_SRC_EMUL_BATT_VOLT_REPEATED, + TCPCI_SRC_EMUL_BATT_VOLT_NOT_IN_ORDER, + TCPCI_SRC_EMUL_VAR_VOLT_REPEATED, + TCPCI_SRC_EMUL_VAR_VOLT_NOT_IN_ORDER, + TCPCI_SRC_EMUL_PDO_AFTER_ZERO, +}; + +/** + * @brief Initialise USB-C source device emulator. Need to be called before + * any other function. + * + * @param data Pointer to USB-C source device emulator + */ +void tcpci_src_emul_init(struct tcpci_src_emul_data *data); + +/** + * @brief Connect emulated device to TCPCI + * + * @param data Pointer to USB-C source device emulator + * @param tcpci_emul Poinetr to TCPCI emulator to connect + * + * @return 0 on success + * @return negative on TCPCI connect error or send source capabilities error + */ +int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data, + const struct emul *tcpci_emul); + +/** + * @brief Check if PDOs of given source device emulator are in correct order + * + * @param data Pointer to USB-C source device emulator + * + * @return TCPCI_SRC_EMUL_CHECK_PDO_OK if PDOs are correct + * @return TCPCI_SRC_EMUL_FIRST_PDO_NO_FIXED_5V if first PDO is not + * fixed type 5V + * @return TCPCI_SRC_EMUL_FIXED_VOLT_REPEATED if two or more fixed type PDOs + * have the same voltage + * @return TCPCI_SRC_EMUL_FIXED_VOLT_NOT_IN_ORDER if fixed PDO with higher + * voltage is before the one with lower voltage + * @return TCPCI_SRC_EMUL_NON_FIRST_PDO_FIXED_FLAGS if PDO different than first + * has some flags set + * @return TCPCI_SRC_EMUL_BATT_VOLT_REPEATED if two or more battery type PDOs + * have the same min and max voltage + * @return TCPCI_SRC_EMUL_BATT_VOLT_NOT_IN_ORDER if battery PDO with higher + * voltage is before the one with lower voltage + * @return TCPCI_SRC_EMUL_VAR_VOLT_REPEATED if two or more variable type PDOs + * have the same min and max voltage + * @return TCPCI_SRC_EMUL_VAR_VOLT_NOT_IN_ORDER if variable PDO with higher + * voltage is before the one with lower voltage + * @return TCPCI_SRC_EMUL_PDO_AFTER_ZERO if PDOs of different types are not in + * correct order (fixed, battery, variable) or non-zero PDO is placed + * after zero PDO + */ +enum check_pdos_res tcpci_src_emul_check_pdos(struct tcpci_src_emul_data *data); + +/** + * @} + */ + +#endif /* __EMUL_TCPCI_PARTNER_SRC_H */ diff --git a/zephyr/projects/asurada/hayato/gpio.dts b/zephyr/projects/asurada/hayato/gpio.dts index 380df3103d..de0f95c962 100644 --- a/zephyr/projects/asurada/hayato/gpio.dts +++ b/zephyr/projects/asurada/hayato/gpio.dts @@ -8,316 +8,255 @@ compatible = "named-gpios"; power_button_l: power_button_l { - gpios = <&gpioe 4 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpioe 4 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "POWER_BUTTON_L"; }; lid_open: lid_open { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; tablet_mode_l { gpios = <&gpioj 7 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; ap_ec_warm_rst_req { gpios = <&gpiod 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_AP_EC_WARM_RST_REQ"; - label = "AP_EC_WARM_RST_REQ"; }; ap_ec_watchdog_l: ap_ec_watchdog_l { gpios = <&gpioc 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | GPIO_ACTIVE_LOW)>; enum-name = "GPIO_AP_EC_WATCHDOG_L"; - label = "AP_EC_WATCHDOG_L"; }; ap_in_sleep_l: ap_in_sleep_l { - gpios = <&gpiof 2 (GPIO_INPUT | GPIO_PULL_DOWN | + gpios = <&gpiof 2 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8 | GPIO_ACTIVE_LOW)>; enum-name = "GPIO_AP_IN_SLEEP_L"; - label = "AP_IN_SLEEP_L"; }; - ap-xhci-init-done { - gpios = <&gpiod 2 (GPIO_INPUT | GPIO_PULL_DOWN | + ap_xhci_init_done { + gpios = <&gpiod 2 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_AP_XHCI_INIT_DONE"; - label = "AP_XHCI_INIT_DONE"; }; pmic_ec_pwrgd: pmic_ec_pwrgd { - gpios = <&gpiof 3 (GPIO_INPUT | GPIO_PULL_DOWN | + gpios = <&gpiof 3 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8 | GPIO_ACTIVE_HIGH)>; enum-name = "GPIO_PMIC_EC_PWRGD"; - label = "PMIC_EC_PWRGD"; }; gpio_accel_gyro_int_l: base_imu_int_l { gpios = <&gpioj 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_IMU_INT_L"; - label = "BASE_IMU_INT_L"; }; lid_accel_int_l { gpios = <&gpioj 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_LID_ACCEL_INT_L"; - label = "LID_ACCEL_INT_L"; }; als_rgb_int_odl { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_ALS_RGB_INT_ODL"; - label = "ALS_RGB_INT_ODL"; }; usb_c0_ppc_int_odl { gpios = <&gpiod 1 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PPC_INT_ODL"; - label = "USB_C0_PPC_INT_ODL"; }; usb_c0_bc12_int_odl { gpios = <&gpioj 6 GPIO_INPUT>; enum-name = "GPIO_USB_C0_BC12_INT_ODL"; - label = "USB_C0_BC12_INT_ODL"; }; usb_c1_bc12_int_l { gpios = <&gpioj 4 GPIO_INPUT>; enum-name = "GPIO_USB_C1_BC12_INT_L"; - label = "USB_C1_BC12_INT_L"; }; volume_down_l { - gpios = <&gpiod 5 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiod 5 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "VOLUME_DOWN_L"; }; volume_up_l { - gpios = <&gpiod 6 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiod 6 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_UP_L"; - label = "VOLUME_UP_L"; }; ac_present: ac_present { gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "AC_PRESENT"; }; wp { gpios = <&gpioi 4 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_WP"; - label = "WP"; }; spi0_cs { gpios = <&gpiom 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_SPI0_CS"; - label = "SPI0_CS"; }; x_ec_gpio2 { gpios = <&gpiob 2 GPIO_ODR_HIGH>; enum-name = "GPIO_X_EC_GPIO2"; - label = "X_EC_GPIO2"; }; ec_pmic_en_odl { gpios = <&gpiod 0 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_PMIC_EN_ODL"; - label = "EC_PMIC_EN_ODL"; }; ec_pmic_watchdog_l { gpios = <&gpioh 0 (GPIO_ODR_LOW | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_PMIC_WATCHDOG_L"; - label = "EC_PMIC_WATCHDOG_L"; }; en_pp5000_a { gpios = <&gpioc 6 GPIO_OUT_HIGH>; enum-name = "GPIO_EN_PP5000_A"; - label = "EN_PP5000_A"; }; pg_mt6315_proc_odl { gpios = <&gpioe 1 GPIO_INPUT>; enum-name = "GPIO_PG_MT6315_PROC_ODL"; - label = "PG_MT6315_PROC_ODL"; }; pg_mt6360_odl { gpios = <&gpiof 1 GPIO_INPUT>; enum-name = "GPIO_PG_MT6360_ODL"; - label = "PG_MT6360_ODL"; }; pg_pp5000_a_odl { gpios = <&gpioa 6 GPIO_INPUT>; enum-name = "GPIO_PG_PP5000_A_ODL"; - label = "PG_PP5000_A_ODL"; }; en_slp_z { gpios = <&gpioe 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_SLP_Z"; - label = "EN_SLP_Z"; }; sys_rst_odl { gpios = <&gpiob 6 GPIO_ODR_LOW>; enum-name = "GPIO_SYS_RST_ODL"; - label = "SYS_RST_ODL"; }; ec_bl_en_od { gpios = <&gpiob 5 (GPIO_ODR_LOW | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_BL_EN_OD"; - label = "EC_BL_EN_OD"; }; ec_int_l { gpios = <&gpioe 6 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_INT_L"; - label = "EC_INT_L"; }; dp_aux_path_sel { gpios = <&gpiog 0 GPIO_OUT_HIGH>; enum-name = "GPIO_DP_AUX_PATH_SEL"; - label = "DP_AUX_PATH_SEL"; }; ec_dpbrdg_hpd_odl { gpios = <&gpioj 0 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_DPBRDG_HPD_ODL"; - label = "EC_DPBRDG_HPD_ODL"; }; en_pp5000_usb_a0_vbus { gpios = <&gpiob 7 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000_USB_A0_VBUS"; - label = "EN_PP5000_USB_A0_VBUS"; }; usb_c0_frs_en { gpios = <&gpioh 3 GPIO_OUT_LOW>; enum-name = "GPIO_USB_C0_FRS_EN"; - label = "USB_C0_FRS_EN"; }; ec_batt_pres_odl { gpios = <&gpioc 0 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; bc12_det_en { gpios = <&gpioj 5 GPIO_OUT_LOW>; enum-name = "GPIO_BC12_DET_EN"; - label = "BC12_DET_EN"; }; en_ec_id_odl { gpios = <&gpioh 5 GPIO_ODR_LOW>; enum-name = "GPIO_EN_EC_ID_ODL"; - label = "EN_EC_ID_ODL"; }; entering_rw { gpios = <&gpioc 5 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "ENTERING_RW"; }; en_5v_usm { gpios = <&gpiod 7 GPIO_OUT_LOW>; enum-name = "GPIO_EN_5V_USM"; - label = "EN_5V_USM"; }; i2c_b_scl { gpios = <&gpiob 3 GPIO_INPUT>; enum-name = "GPIO_I2C_B_SCL"; - label = "I2C_B_SCL"; }; i2c_b_sda { gpios = <&gpiob 4 GPIO_INPUT>; enum-name = "GPIO_I2C_B_SDA"; - label = "I2C_B_SDA"; }; i2c_c_scl { gpios = <&gpioc 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_C_SCL"; - label = "I2C_C_SCL"; }; i2c_c_sda { gpios = <&gpioc 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_C_SDA"; - label = "I2C_C_SDA"; }; i2c_e_scl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_I2C_E_SCL"; - label = "I2C_E_SCL"; }; i2c_e_sda { gpios = <&gpioe 7 GPIO_INPUT>; enum-name = "GPIO_I2C_E_SDA"; - label = "I2C_E_SDA"; }; i2c_f_scl { gpios = <&gpiof 6 GPIO_INPUT>; enum-name = "GPIO_I2C_F_SCL"; - label = "I2C_F_SCL"; }; i2c_f_sda { gpios = <&gpiof 7 GPIO_INPUT>; enum-name = "GPIO_I2C_F_SDA"; - label = "I2C_F_SDA"; }; ec_x_gpio1 { gpios = <&gpioh 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_X_GPIO1"; - label = "EC_X_GPIO1"; }; ec_x_gpio3 { gpios = <&gpioj 1 GPIO_INPUT>; enum-name = "GPIO_EC_X_GPIO3"; - label = "EC_X_GPIO3"; }; set_vmc_volt_at_1v8 { - gpios = <&gpiod 4 (GPIO_INPUT | GPIO_PULL_DOWN | + gpios = <&gpiod 4 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_SET_VMC_VOLT_AT_1V8"; - label = "SET_VMC_VOLT_AT_1V8"; }; en_pp3000_vmc_pmu { - gpios = <&gpiod 2 (GPIO_INPUT | GPIO_PULL_DOWN | + gpios = <&gpiod 2 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EN_PP3000_VMC_PMU"; - label = "EN_PP3000_VMC_PMU"; }; packet_mode_en { - gpios = <&gpioa 3 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioa 3 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_PACKET_MODE_EN"; - label = "PACKET_MODE_EN"; }; usb_a0_fault_odl { gpios = <&gpioa 7 GPIO_INPUT>; enum-name = "GPIO_USB_A0_FAULT_ODL"; - label = "USB_A0_FAULT_ODL"; }; charger_prochot_odl { gpios = <&gpioc 3 GPIO_INPUT>; enum-name = "GPIO_CHARGER_PROCHOT_ODL"; - label = "CHARGER_PROCHOT_ODL"; }; pg_mt6315_gpu_odl { gpios = <&gpioh 6 GPIO_INPUT>; enum-name = "GPIO_PG_MT6315_GPU_ODL"; - label = "PG_MT6315_GPU_ODL"; }; en_pp3000_sd_u { - gpios = <&gpiog 1 (GPIO_INPUT | GPIO_PULL_DOWN | + gpios = <&gpiog 1 (GPIO_INPUT_PULL_DOWN | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EN_PP3000_SD_U"; - label = "EN_PP3000_SD_U"; }; ccd_mode_odl { gpios = <&gpioc 4 GPIO_INPUT>; enum-name = "GPIO_CCD_MODE_ODL"; - label = "CCD_MODE_ODL"; }; spi_clk_gpg6 { - gpios = <&gpiog 6 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiog 6 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_SPI_CLK_GPG6"; - label = "SPI_CLK_GPG6"; }; spi_mosi_gpg4 { gpios = <&gpiog 4 GPIO_OUT_LOW>; enum-name = "GPIO_SPI_MOSI_GPG4"; - label = "SPI_MOSI_GPG4"; }; spi_miso_gpg5 { gpios = <&gpiog 5 GPIO_OUT_LOW>; enum-name = "GPIO_SPI_MISO_GPG5"; - label = "SPI_MISO_GPG5"; }; spi_cs_gpg7 { gpios = <&gpiog 7 GPIO_OUT_LOW>; enum-name = "GPIO_SPI_CS_GPG7"; - label = "SPI_CS_GPG7"; }; }; @@ -348,17 +287,15 @@ compatible = "unused-gpios"; unused-gpios = - /* uart1_rx */ - <&gpiob 0 GPIO_INPUT>, /* nc_gpg3 */ <&gpiog 3 GPIO_OUT_LOW>, /* nc_gpi7 */ <&gpioi 7 GPIO_OUT_LOW>, /* nc_gpm2 */ - <&gpiom 2 (GPIO_INPUT | GPIO_PULL_DOWN)>, + <&gpiom 2 GPIO_INPUT_PULL_DOWN>, /* nc_gpm3 */ - <&gpiom 3 (GPIO_INPUT | GPIO_PULL_DOWN)>, + <&gpiom 3 GPIO_INPUT_PULL_DOWN>, /* nc_gpm6 */ - <&gpiom 6 (GPIO_INPUT | GPIO_PULL_DOWN)>; + <&gpiom 6 GPIO_INPUT_PULL_DOWN>; }; }; diff --git a/zephyr/projects/asurada/hayato/pwm.dts b/zephyr/projects/asurada/hayato/pwm.dts index f86448cc8e..3aba3b7f3c 100644 --- a/zephyr/projects/asurada/hayato/pwm.dts +++ b/zephyr/projects/asurada/hayato/pwm.dts @@ -7,26 +7,23 @@ named-pwms { compatible = "named-pwms"; /* NOTE: &pwm number needs same with channel number */ - led1: led1 { + led1: led1_sub_odl { #pwm-cells = <0>; pwms = <&pwm0 PWM_CHANNEL_0 PWM_POLARITY_INVERTED>; - label = "LED1"; /* * If we need pwm output in ITE chip power saving * mode, then we should set frequency <=324Hz. */ frequency = <324>; }; - led2: led2 { + led2: led2_sub_odl { #pwm-cells = <0>; pwms = <&pwm1 PWM_CHANNEL_1 PWM_POLARITY_INVERTED>; - label = "LED2"; frequency = <324>; }; - led3: led3 { + led3: led3_sub_odl { #pwm-cells = <0>; pwms = <&pwm2 PWM_CHANNEL_2 PWM_POLARITY_INVERTED>; - label = "LED3"; frequency = <324>; }; }; diff --git a/zephyr/projects/brya/brya/BUILD.py b/zephyr/projects/brya/brya/BUILD.py index 70696c1f3f..45d6dca977 100644 --- a/zephyr/projects/brya/brya/BUILD.py +++ b/zephyr/projects/brya/brya/BUILD.py @@ -5,5 +5,11 @@ register_npcx_project( project_name="brya", zephyr_board="brya", - dts_overlays=["gpio.dts"], + dts_overlays=[ + "cbi_eeprom.dts", + "fan.dts", + "gpio.dts", + "motionsense.dts", + "pwm.dts", + ], ) diff --git a/zephyr/projects/brya/brya/CMakeLists.txt b/zephyr/projects/brya/brya/CMakeLists.txt index 59af20ebfe..c5f11ebf5f 100644 --- a/zephyr/projects/brya/brya/CMakeLists.txt +++ b/zephyr/projects/brya/brya/CMakeLists.txt @@ -7,4 +7,11 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(brya) -zephyr_include_directories(include) +set(PLATFORM_EC_BASEBOARD "${PLATFORM_EC}/baseboard/brya" CACHE PATH + "Path to the platform/ec baseboard directory") + +zephyr_include_directories(include + "${PLATFORM_EC_BASEBOARD}") + +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_EEPROM + "${PLATFORM_EC_BASEBOARD}/cbi.c") diff --git a/zephyr/projects/brya/brya/cbi_eeprom.dts b/zephyr/projects/brya/brya/cbi_eeprom.dts new file mode 100644 index 0000000000..f584c56afd --- /dev/null +++ b/zephyr/projects/brya/brya/cbi_eeprom.dts @@ -0,0 +1,17 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +&i2c7_0 { + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + label = "EEPROM_CBI"; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + wp-gpios = <&gpio_ec_wp_l>; + }; +}; diff --git a/zephyr/projects/brya/brya/fan.dts b/zephyr/projects/brya/brya/fan.dts new file mode 100644 index 0000000000..cccd6315bf --- /dev/null +++ b/zephyr/projects/brya/brya/fan.dts @@ -0,0 +1,29 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-fans { + compatible = "named-fans"; + + fan_0 { + label = "FAN_0"; + pwm = <&pwm_fan>; + rpm_min = <2200>; + rpm_start = <2200>; + rpm_max = <4200>; + tach = <&tach1>; + enable_gpio = <&gpio_en_pp5000_fan>; + }; + }; +}; + +/* Tachemeter for fan speed measurement */ +&tach1 { + status = "okay"; + pinctrl-0 = <&alt3_ta1_sl1>; /* Use TA1 as input pin */ + port = <NPCX_TACH_PORT_A>; /* port-A is selected */ + sample-clk = <NPCX_TACH_FREQ_LFCLK>; /* Use LFCLK as sampling clock */ + pulses-per-round = <2>; /* number of pulses per round of encoder */ +}; diff --git a/zephyr/projects/brya/brya/gpio.dts b/zephyr/projects/brya/brya/gpio.dts index 9ec2af0a12..68549c7b68 100644 --- a/zephyr/projects/brya/brya/gpio.dts +++ b/zephyr/projects/brya/brya/gpio.dts @@ -10,137 +10,136 @@ lid_open: lid_open { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; - gsc_ec_pwr_btn_odl: power_btn { + gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "GSC_EC_PWR_BTN_ODL"; }; - wp_l { + gpio_ec_wp_l: ec_wp_odl { + #gpio-cells = <0>; gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "EC_WP_ODL"; }; ec_chg_led_y_c1 { gpios = <&gpioc 3 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C1"; - label = "EC_CHG_LED_Y_C1"; }; ec_chg_led_b_c1 { gpios = <&gpioc 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_B_C1"; - label = "EC_CHG_LED_B_C1"; }; - packet_mode_en { + ec_gsc_packet_mode { gpios = <&gpio7 5 GPIO_OUT_LOW>; enum-name = "GPIO_PACKET_MODE_EN"; - label = "EC_GSC_PACKET_MODE"; + }; + gpio_ec_accel_int_l: ec_accel_int_l { + gpios = <&gpio8 1 GPIO_INPUT>; + enum-name = "GPIO_EC_ACCEL_INT"; + }; + gpio_ec_imu_int_l: gpio_ec_imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + enum-name = "GPIO_EC_IMU_INT_L"; + }; + gpio_ec_als_rgb_int_l: gpio_ec_als_rgb_int_l { + gpios = <&gpiod 4 GPIO_INPUT>; + enum-name = "GPIO_EC_ALS_RGB_INT_L"; + }; + tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; }; acok_od: acok_od { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "ACOK_OD"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; - pch_wake_odl { + ec_pch_wake_r_odl { gpios = <&gpioc 0 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "EC_PCH_WAKE_R_ODL"; }; - pch_int_odl { + ec_pch_int_odl { gpios = <&gpiob 0 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_INT_L"; - label = "EC_PCH_INT_ODL"; }; pg_ec_dsw_pwrok { gpios = <&gpioc 7 GPIO_INPUT>; enum-name = "GPIO_PG_EC_DSW_PWROK"; - label = "PG_EC_DSW_PWROK"; }; en_s5_rails { gpios = <&gpiob 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_S5_RAILS"; - label = "EN_S5_RAILS"; }; sys_rst_odl { gpios = <&gpioc 5 GPIO_ODR_HIGH>; enum-name = "GPIO_SYS_RESET_L"; - label = "SYS_RST_ODL"; }; pg_ec_rsmrst_odl { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_PG_EC_RSMRST_ODL"; - label = "PG_EC_RSMRST_ODL"; }; ec_pch_rsmrst_odl { gpios = <&gpioa 6 GPIO_OUT_LOW>; enum-name = "GPIO_PCH_RSMRST_L"; - label = "EC_PCH_RSMRST_ODL"; }; pg_ec_all_sys_pwrgd { gpios = <&gpiof 4 GPIO_INPUT>; enum-name = "GPIO_PG_EC_ALL_SYS_PWRGD"; - label = "PG_EC_ALL_SYS_PWRGD"; }; slp_s0_l { gpios = <&gpiod 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S0_L"; - label = "SLP_S0_L"; }; slp_s3_l { gpios = <&gpioa 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S3_L"; - label = "SLP_S3_L"; }; vccst_pwrgd_od { gpios = <&gpioa 4 GPIO_ODR_LOW>; enum-name = "GPIO_VCCST_PWRGD_OD"; - label = "VCCST_PWRGD_OD"; }; ec_prochot_odl { gpios = <&gpio6 3 GPIO_ODR_HIGH>; enum-name = "GPIO_CPU_PROCHOT"; - label = "EC_PROCHOT_ODL"; }; ec_pch_pwr_btn_odl { gpios = <&gpioc 1 GPIO_ODR_HIGH>; enum-name = "GPIO_PCH_PWRBTN_L"; - label = "EC_PCH_PWR_BTN_ODL"; }; slp_sus_l { gpios = <&gpiof 1 GPIO_INPUT>; enum-name = "GPIO_SLP_SUS_L"; - label = "SLP_SUS_L"; }; pch_pwrok { gpios = <&gpio7 2 GPIO_OUT_LOW>; enum-name = "GPIO_PCH_PWROK"; - label = "PCH_PWROK"; }; ec_pch_sys_pwrok { gpios = <&gpio3 7 GPIO_OUT_LOW>; enum-name = "GPIO_EC_PCH_SYS_PWROK"; - label = "EC_PCH_SYS_PWROK"; }; imvp9_vrrdy_od { gpios = <&gpio4 3 GPIO_INPUT>; enum-name = "GPIO_IMVP9_VRRDY_OD"; - label = "IMVP9_VRRDY_OD"; }; ec_edp_bl_en { gpios = <&gpiod 3 GPIO_OUT_HIGH>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_EDP_BL_EN"; + }; + ec_prochot_in_l { + gpios = <&gpiof 0 GPIO_INPUT>; + enum-name = "GPIO_EC_PROCHOT_IN_L"; + }; + gpio_en_pp5000_fan: en_pp5000_fan { + gpios = <&gpio6 1 GPIO_OUT_HIGH>; + enum-name = "GPIO_EN_PP5000_FAN"; }; }; diff --git a/zephyr/projects/brya/brya/include/gpio_map.h b/zephyr/projects/brya/brya/include/gpio_map.h index 978b0a921c..953d0d453a 100644 --- a/zephyr/projects/brya/brya/include/gpio_map.h +++ b/zephyr/projects/brya/brya/include/gpio_map.h @@ -12,6 +12,32 @@ #define GPIO_ENTERING_RW GPIO_UNIMPLEMENTED #define GPIO_WP_L GPIO_UNIMPLEMENTED +#ifdef CONFIG_PLATFORM_EC_ALS_TCS3400 +#define TCS3400_INT(gpio, edge) GPIO_INT(gpio, edge, tcs3400_interrupt) +#else +#define TCS3400_INT(gpio, edge) +#endif + +#ifdef CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO +#define LSM6DSO_INT(gpio, edge) GPIO_INT(gpio, edge, lsm6dso_interrupt) +#else +#define LSM6DSO_INT(gpio, edge) +#endif + +#ifdef CONFIG_PLATFORM_EC_ACCEL_LIS2DW12 +#define LIS2DW12_INT(gpio, edge) GPIO_INT(gpio, edge, lis2dw12_interrupt) +#else +#define LIS2DW12_INT(gpio, edge) +#endif + +#ifdef CONFIG_PLATFORM_EC_GMR_TABLET_MODE +#define GMR_TABLET_MODE_INT(gpio, edge) GPIO_INT(gpio, edge, \ + gmr_tablet_switch_isr) +#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L +#else +#define GMR_TABLET_MODE_INT(gpio, edge) +#endif + /* * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. * @@ -31,21 +57,29 @@ #ifdef CONFIG_PLATFORM_EC_POWERSEQ #define POWER_SIGNAL_INT(gpio, edge) \ GPIO_INT(gpio, edge, power_signal_interrupt) +#define AP_PROCHOT_INT(gpio, edge) \ + GPIO_INT(gpio, edge, throttle_ap_prochot_input_interrupt) #else #define POWER_SIGNAL_INT(gpio, edge) +#define AP_PROCHOT_INT(gpio, edge) #endif #define EC_CROS_GPIO_INTERRUPTS \ + GMR_TABLET_MODE_INT(GPIO_TABLET_MODE_L, GPIO_INT_EDGE_BOTH) \ GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \ GPIO_INT(GPIO_POWER_BUTTON_L, GPIO_INT_EDGE_BOTH, \ power_button_interrupt) \ GPIO_INT(GPIO_WP_L, GPIO_INT_EDGE_BOTH, switch_interrupt) \ GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \ + LIS2DW12_INT(GPIO_EC_ACCEL_INT, GPIO_INT_EDGE_FALLING) \ + LSM6DSO_INT(GPIO_EC_IMU_INT_L, GPIO_INT_EDGE_FALLING) \ POWER_SIGNAL_INT(GPIO_PCH_SLP_S0_L, GPIO_INT_EDGE_BOTH) \ POWER_SIGNAL_INT(GPIO_PCH_SLP_S3_L, GPIO_INT_EDGE_BOTH) \ POWER_SIGNAL_INT(GPIO_SLP_SUS_L, GPIO_INT_EDGE_BOTH) \ POWER_SIGNAL_INT(GPIO_PG_EC_DSW_PWROK, GPIO_INT_EDGE_BOTH) \ POWER_SIGNAL_INT(GPIO_PG_EC_RSMRST_ODL, GPIO_INT_EDGE_BOTH) \ - POWER_SIGNAL_INT(GPIO_PG_EC_ALL_SYS_PWRGD, GPIO_INT_EDGE_BOTH) + POWER_SIGNAL_INT(GPIO_PG_EC_ALL_SYS_PWRGD, GPIO_INT_EDGE_BOTH) \ + TCS3400_INT(GPIO_EC_ALS_RGB_INT_L, GPIO_INT_EDGE_FALLING) \ + AP_PROCHOT_INT(GPIO_EC_PROCHOT_IN_L, GPIO_INT_EDGE_BOTH) #endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/projects/brya/brya/motionsense.dts b/zephyr/projects/brya/brya/motionsense.dts new file mode 100644 index 0000000000..a4276c3255 --- /dev/null +++ b/zephyr/projects/brya/brya/motionsense.dts @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022 The Chromium OS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * motion sense's <>_INT_EVENT is handled + * by alias. Using the alias, each driver creates + * its own <>_INT_EVENT. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + tcs3400-int = &als_clear; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + mutex_lis2dw12: lis2dw12-mutex { + label = "LIS2DW12_MUTEX"; + }; + + mutex_lsm6dso: lsm6dso-mutex { + label = "LSM6DSO_MUTEX"; + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <0 1 0 + 1 0 0 + 0 0 (-1)>; + }; + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + + lsm6dso_data: lsm6dso-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + tcs_clear_data: tcs3400-clear-drv-data { + compatible = "cros-ec,drvdata-tcs3400-clear"; + status = "okay"; + + als-drv-data { + compatible = "cros-ec,accelgyro-als-drv-data"; + als-cal { + scale = <1>; + uscale = <0>; + offset = <0>; + als-channel-scale { + compatible = + "cros-ec,accelgyro-als-channel-scale"; + k-channel-scale = <1>; + cover-scale = <1>; + }; + }; + }; + }; + + tcs_rgb_data: tcs3400-rgb-drv-data { + compatible = "cros-ec,drvdata-tcs3400-rgb"; + status = "okay"; + + /* node for rgb_calibration_t defined in accelgyro.h */ + rgb_calibration { + compatible = + "cros-ec,accelgyro-rgb-calibration"; + + irt = <1>; + + rgb-cal-x { + offset = <0>; + coeff = <0 0 0 1>; + als-channel-scale { + compatible = + "cros-ec,accelgyro-als-channel-scale"; + k-channel-scale = <1>; + cover-scale = <1>; + }; + }; + rgb-cal-y { + offset = <0>; + coeff = <0 0 0 1>; + als-channel-scale { + compatible = + "cros-ec,accelgyro-als-channel-scale"; + k-channel-scale = <1>; + cover-scale = <1>; + }; + }; + rgb-cal-z { + offset = <0>; + coeff = <0 0 0 1>; + als-channel-scale { + compatible = + "cros-ec,accelgyro-als-channel-scale"; + k-channel-scale = <1>; + cover-scale = <1>; + }; + }; + }; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The label "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + label = "Lid Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&mutex_lis2dw12>; + port = <&i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + label = "Base Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&mutex_lsm6dso>; + port = <&i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <4>; + drv-data = <&lsm6dso_data>; + i2c-spi-addr-flags = "LSM6DSO_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(13000 | ROUND_UP_FLAG)>; + ec-rate = <(100 * USEC_PER_MSEC)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + ec-rate = <(100 * USEC_PER_MSEC)>; + }; + }; + }; + + base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + label = "Base Gyro"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&mutex_lsm6dso>; + port = <&i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ + drv-data = <&lsm6dso_data>; + i2c-spi-addr-flags = "LSM6DSO_ADDR0_FLAGS"; + }; + + als_clear: base-als-clear { + compatible = "cros-ec,tcs3400-clear"; + status = "okay"; + + label = "Clear Light"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_CAMERA"; + port = <&i2c_sensor>; + default-range = <0x10000>; + drv-data = <&tcs_clear_data>; + i2c-spi-addr-flags = "TCS3400_I2C_ADDR_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + /* Run ALS sensor in S0 */ + label = "SENSOR_CONFIG_EC_S0"; + odr = <1000>; + }; + }; + }; + + base-als-rgb { + compatible = "cros-ec,tcs3400-rgb"; + status = "okay"; + + label = "RGB Light"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_CAMERA"; + default-range = <0x10000>; /* scale = 1x, uscale = 0 */ + drv-data = <&tcs_rgb_data>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* list of entries for motion_als_sensors */ + als-sensors = <&als_clear>; + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&gpio_ec_imu_int_l &gpio_ec_als_rgb_int_l + &gpio_ec_accel_int_l>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel &als_clear>; + }; +}; diff --git a/zephyr/projects/brya/brya/prj.conf b/zephyr/projects/brya/brya/prj.conf index 13ef01133f..1bfd3ce95b 100644 --- a/zephyr/projects/brya/brya/prj.conf +++ b/zephyr/projects/brya/brya/prj.conf @@ -7,6 +7,7 @@ CONFIG_PLATFORM_EC=y CONFIG_PLATFORM_EC_BRINGUP=y CONFIG_SHIMMED_TASKS=y CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_CBI_EEPROM=y CONFIG_PLATFORM_EC_LID_SWITCH=y CONFIG_PLATFORM_EC_SWITCH=y CONFIG_LTO=y @@ -17,7 +18,8 @@ CONFIG_PLATFORM_EC_VBOOT_HASH=y CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y CONFIG_PLATFORM_EC_I2C=y -CONFIG_PLATFORM_EC_BACKLIGHT_LID=y + +CONFIG_PLATFORM_EC_ADC_CHANNELS_RUNTIME_CONFIG=y # SoC configuration CONFIG_AP=y @@ -25,17 +27,73 @@ CONFIG_AP_X86_INTEL_ADL=y CONFIG_FPU=y CONFIG_ARM_MPU=y +# eSPI CONFIG_ESPI=y -CONFIG_PLATFORM_EC_ESPI=y CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4=y +CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5=y + +# Power Sequencing +CONFIG_PLATFORM_EC_POWERSEQ=y +CONFIG_PLATFORM_EC_POWERSEQ_RTC_RESET=y +CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y +CONFIG_PLATFORM_EC_POWERSEQ_S4=y +CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y # Host command CONFIG_PLATFORM_EC_HOSTCMD=y +# Console command +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y + +# Sensors +CONFIG_PLATFORM_EC_MOTIONSENSE=y +CONFIG_PLATFORM_EC_ACCEL_FIFO=y +CONFIG_PLATFORM_EC_ACCEL_INTERRUPTS=y +CONFIG_PLATFORM_EC_ALS=y +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y +CONFIG_PLATFORM_EC_GMR_TABLET_MODE=y +CONFIG_PLATFORM_EC_LID_ANGLE=y +CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y +CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y +CONFIG_PLATFORM_EC_TABLET_MODE=y +CONFIG_PLATFORM_EC_TABLET_MODE_SWITCH=y + +# Sensor Drivers +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_SPI=y +CONFIG_PLATFORM_EC_ACCELGYRO_ICM_COMM_SPI=y +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12_AS_BASE=y +CONFIG_PLATFORM_EC_ALS_TCS3400=y + +# Fan +CONFIG_PLATFORM_EC_FAN=y +CONFIG_SENSOR=y +CONFIG_SENSOR_SHELL=n +CONFIG_TACH_NPCX=y + # Temperature sensors CONFIG_PLATFORM_EC_TEMP_SENSOR=y CONFIG_PLATFORM_EC_THERMISTOR=y +# Miscellaneous configs +CONFIG_PLATFORM_EC_HIBERNATE_PSL=y + +# MKBP event +CONFIG_PLATFORM_EC_MKBP_EVENT=y +CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y +CONFIG_PLATFORM_EC_MKBP_USE_HOST_EVENT=y + +# MKBP event mask +CONFIG_PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK=y +CONFIG_PLATFORM_EC_MKBP_HOST_EVENT_WAKEUP_MASK=y + +# PMIC +CONFIG_PLATFORM_EC_PMIC=y +CONFIG_PLATFORM_EC_MP2964=y + # Keyboard CONFIG_PLATFORM_EC_KEYBOARD=y CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y @@ -48,9 +106,12 @@ CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y CONFIG_SYSCON=y +# PWM +CONFIG_PWM=y +CONFIG_PWM_SHELL=n +CONFIG_PLATFORM_EC_PWM=y + # TODO(b/188605676): bring these features up -CONFIG_PLATFORM_EC_BACKLIGHT_LID=n -CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n # Power Sequencing @@ -62,3 +123,7 @@ CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y # Treat 2nd reset from H1 as Power-On CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y + +# RTC +CONFIG_PLATFORM_EC_RTC=y diff --git a/zephyr/projects/brya/brya/pwm.dts b/zephyr/projects/brya/brya/pwm.dts new file mode 100644 index 0000000000..4b71b235ba --- /dev/null +++ b/zephyr/projects/brya/brya/pwm.dts @@ -0,0 +1,74 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-pwms { + compatible = "named-pwms"; + + led1: led1 { + #pwm-cells = <0>; + pwms = <&pwm2 0 PWM_POLARITY_INVERTED>; + frequency = <4800>; + }; + led2: led2 { + #pwm-cells = <0>; + pwms = <&pwm0 0 PWM_POLARITY_INVERTED>; + frequency = <4800>; + }; + led3: led3 { + #pwm-cells = <0>; + pwms = <&pwm1 0 PWM_POLARITY_INVERTED>; + frequency = <4800>; + }; + led4: led4 { + #pwm-cells = <0>; + pwms = <&pwm7 0 PWM_POLARITY_INVERTED>; + frequency = <4800>; + }; + kblight: kblight { + pwms = <&pwm3 0 0>; + frequency = <2400>; + }; + pwm_fan: fan { + pwms = <&pwm5 0 0>; + frequency = <1000>; + }; + }; +}; + +/* LED2 */ +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +/* LED3 */ +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +/* LED1 */ +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +/* Keyboard backlight */ +&pwm3 { + status = "okay"; +}; + +/* Fan control */ +&pwm5 { + status = "okay"; + drive-open-drain; +}; + +/* LED4 */ +&pwm7 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; diff --git a/zephyr/projects/corsola/BUILD.py b/zephyr/projects/corsola/BUILD.py new file mode 100644 index 0000000000..1254b01003 --- /dev/null +++ b/zephyr/projects/corsola/BUILD.py @@ -0,0 +1,50 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Default chip is it8xxx2, some variants will use NPCX9X. + + +def register_corsola_project( + project_name, + chip="it8xxx2", + extra_dts_overlays=(), + extra_kconfig_files=(), +): + register_func = register_binman_project + if chip.startswith("npcx9"): + register_func = register_npcx_project + + register_func( + project_name=project_name, + zephyr_board=chip, + dts_overlays=[here / "power_signal.dts", *extra_dts_overlays], + kconfig_files=[here / "prj.conf", *extra_kconfig_files], + ) + + +register_corsola_project( + "krabby", + extra_dts_overlays=[ + here / "adc_krabby.dts", + here / "battery_krabby.dts", + here / "gpio_krabby.dts", + here / "i2c_krabby.dts", + here / "motionsense_krabby.dts", + here / "pwm_krabby.dts", + ], + extra_kconfig_files=[here / "prj_krabby.conf"], +) + +register_corsola_project( + project_name="kingler", + chip="npcx9", + extra_dts_overlays=[ + here / "adc_kingler.dts", + here / "battery_kingler.dts", + here / "i2c_kingler.dts", + here / "cbi_eeprom_kingler.dts", + here / "gpio_kingler.dts", + ], + extra_kconfig_files=[here / "prj_kingler.conf"], +) diff --git a/zephyr/projects/corsola/CMakeLists.txt b/zephyr/projects/corsola/CMakeLists.txt new file mode 100644 index 0000000000..3e9cac9f83 --- /dev/null +++ b/zephyr/projects/corsola/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cmake_minimum_required(VERSION 3.13.1) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +zephyr_library_include_directories(include) + +# Include selected EC source from the baseboard +zephyr_library_sources( + "src/board_chipset.c" + "src/hibernate.c" +) + +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/usbc_config.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/usb_pd_policy.c") +zephyr_library_sources_ifdef(CONFIG_VARIANT_CORSOLA_DB_DETECTION + "src/variant_db_detection.c") + +if(DEFINED CONFIG_BOARD_KRABBY) + project(krabby) + zephyr_library_sources("src/krabby/hooks.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C "src/krabby/i2c.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON + "src/krabby/led.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC + "src/krabby/usb_pd_policy.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC + "src/krabby/usbc_config.c") +elseif(DEFINED CONFIG_BOARD_KINGLER) + project(kingler) +endif() + diff --git a/zephyr/projects/corsola/Kconfig b/zephyr/projects/corsola/Kconfig new file mode 100644 index 0000000000..746c8b8cc8 --- /dev/null +++ b/zephyr/projects/corsola/Kconfig @@ -0,0 +1,32 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config BOARD_KRABBY + bool "Google Krabby Board" + help + Build Google Krabby reference board. Krabby has MediaTek MT8186 SoC + with ITE it81202-bx EC. + +config BOARD_KINGLER + bool "Google Kingler Board" + help + Build Google Kingler reference board. Krabby has MediaTek MT8186 SoC + with NPCX993FA0BX EC. + +config VARIANT_CORSOLA_DB_DETECTION + bool "Corsola Platform Runtime Daughter Board Detection" + help + Daughter board detection for Type-C subboard or HDMI subboard. This + includes pin configuration and driver loading. + default y + +config VARIANT_CORSOLA_USBA + bool "Corsola Platform USB-A support" + help + Support Corsola USB-A related functions. Enable this function if + it has USB-A ports. + depends on PLATFORM_EC_USBC + default y + +source "Kconfig.zephyr" diff --git a/zephyr/projects/corsola/adc_kingler.dts b/zephyr/projects/corsola/adc_kingler.dts new file mode 100644 index 0000000000..7b2e9817e4 --- /dev/null +++ b/zephyr/projects/corsola/adc_kingler.dts @@ -0,0 +1,41 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-adc-channels { + compatible = "named-adc-channels"; + + adc_charger_pmon_r { + label = "ADC_CHARGER_PMON_R"; + enum-name = "ADC_PSYS"; + channel = <0>; + /* + * ISL9238C PSYS output is 1.44 uA/W over 33K resistor. + */ + mul = <21043>; + }; + adc_ec_id0 { + label = "ADC_EC_ID0"; + enum-name = "ADC_ID_0"; + channel = <1>; + }; + adc_ec_id1 { + label = "ADC_EC_ID1"; + enum-name = "ADC_ID_1"; + channel = <2>; + }; + adc_charger_amon_r { + label = "ADC_AMON_R"; + enum-name = "ADC_AMON_BMON"; + channel = <3>; + mul = <1000>; + div = <18>; + }; + }; +}; + +&adc0 { + status = "okay"; +}; diff --git a/zephyr/projects/corsola/krabby/adc.dts b/zephyr/projects/corsola/adc_krabby.dts index 7f308c04f9..938fc42cd1 100644 --- a/zephyr/projects/corsola/krabby/adc.dts +++ b/zephyr/projects/corsola/adc_krabby.dts @@ -8,44 +8,27 @@ compatible = "named-adc-channels"; adc_vbus_c0 { - label = "ADC_VBUS_C0"; + label = "VBUS_C0"; enum-name = "ADC_VBUS_C0"; channel = <0>; mul = <10>; }; adc_board_id0 { - label = "ADC_BOARD_ID_0"; + label = "BOARD_ID_0"; enum-name = "ADC_BOARD_ID_0"; channel = <1>; }; adc_board_id1 { - label = "ADC_BOARD_ID_1"; + label = "BOARD_ID_1"; enum-name = "ADC_BOARD_ID_1"; channel = <2>; }; - adc_charger_amon_r { - label = "ADC_AMON_BMON"; - enum-name = "ADC_AMON_BMON"; - channel = <3>; - mul = <1000>; - div = <18>; - }; adc_vbus_c1 { - label = "ADC_VBUS_C1"; + label = "VBUS_C1"; enum-name = "ADC_VBUS_C1"; - channel = <5>; + channel = <7>; mul = <10>; }; - adc_charger_pmon { - label = "ADC_PMON"; - enum-name = "ADC_PMON"; - channel = <6>; - }; - adc-psys { - label = "ADC_PSYS"; - enum-name = "ADC_PSYS"; - channel = <6>; - }; }; }; diff --git a/zephyr/projects/guybrush/battery.dts b/zephyr/projects/corsola/battery_kingler.dts index 02a6d0d3b9..c234dca7c9 100644 --- a/zephyr/projects/guybrush/battery.dts +++ b/zephyr/projects/corsola/battery_kingler.dts @@ -5,8 +5,11 @@ / { batteries { - default_battery: aec_5477109 { - compatible = "aec,5477109"; + default_battery: smp_l20m3pg2 { + compatible = "smp,l20m3pg2"; + }; + lgc_l20l3pg2 { + compatible = "lgc,l20l3pg2"; }; }; }; diff --git a/zephyr/projects/corsola/krabby/battery.dts b/zephyr/projects/corsola/battery_krabby.dts index deb803bb8c..deb803bb8c 100644 --- a/zephyr/projects/corsola/krabby/battery.dts +++ b/zephyr/projects/corsola/battery_krabby.dts diff --git a/zephyr/projects/corsola/cbi_eeprom_kingler.dts b/zephyr/projects/corsola/cbi_eeprom_kingler.dts new file mode 100644 index 0000000000..0886a05280 --- /dev/null +++ b/zephyr/projects/corsola/cbi_eeprom_kingler.dts @@ -0,0 +1,17 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + &i2c_pwr_cbi { + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + label = "EEPROM_CBI"; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + wp-gpios = <&gpio_ec_wp_l>; + }; +}; diff --git a/zephyr/projects/corsola/gpio_kingler.dts b/zephyr/projects/corsola/gpio_kingler.dts new file mode 100644 index 0000000000..4ea7b30710 --- /dev/null +++ b/zephyr/projects/corsola/gpio_kingler.dts @@ -0,0 +1,242 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-gpios { + compatible = "named-gpios"; + + base_imu_int_l { + gpios = <&gpio5 6 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_BASE_IMU_INT_L"; + }; + spi_ap_clk_ec { + gpios = <&gpio5 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + spi_ap_cs_ec_l { + gpios = <&gpio5 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_SHI_CS_L"; + }; + spi_ap_do_ec_di { + gpios = <&gpio4 6 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + spi_ap_di_ec_do { + gpios = <&gpio4 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ap_ec_warm_rst_req: ap_ec_warm_rst_req { + gpios = <&gpio5 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_HIGH)>; + enum-name = "GPIO_AP_EC_WARM_RST_REQ"; + }; + ap_ec_wdtrst_l: ap_ec_wdtrst_l { + gpios = <&gpio5 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; + enum-name = "GPIO_AP_EC_WDTRST_L"; + }; + ap_in_sleep_l: ap_in_sleep_l { + gpios = <&gpio5 4 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; + enum-name = "GPIO_AP_IN_SLEEP_L"; + }; + en_ulp { + gpios = <&gpioc 6 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_ULP"; + }; + en_ec_id_odl { + gpios = <&gpio7 6 GPIO_ODR_LOW>; + enum-name = "GPIO_EN_EC_ID_ODL"; + }; + sys_rst_odl { + gpios = <&gpioc 5 (GPIO_ODR_LOW | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_SYS_RST_ODL"; + }; + ec_i2c_sensor_scl { + gpios = <&gpiob 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec_i2c_sensor_sda { + gpios = <&gpiob 4 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec_i2c_usb_c0_scl { + gpios = <&gpio9 0 GPIO_INPUT>; + }; + ec_i2c_usb_c0_sda { + gpios = <&gpio8 7 GPIO_INPUT>; + }; + ec_i2c_usb_c1_scl { + gpios = <&gpio9 2 GPIO_INPUT>; + }; + ec_i2c_usb_c1_sda { + gpios = <&gpio9 1 GPIO_INPUT>; + }; + ec_i2c_pwr_cbi_scl { + gpios = <&gpiod 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec_i2c_pwr_cbi_sda { + gpios = <&gpiod 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec_i2c_batt_scl { + gpios = <&gpio3 3 GPIO_INPUT>; + }; + ec_i2c_batt_sda { + gpios = <&gpio3 6 GPIO_INPUT>; + }; + ec_pen_chg_dis_odl { + gpios = <&gpioe 4 GPIO_INPUT>; + enum-name = "GPIO_EC_PEN_CHG_DIS_ODL"; + }; + gpio_ec_wp_l: ec_wp_odl { + #gpio-cells = <0>; + gpios = <&gpioe 3 (GPIO_OPEN_DRAIN)>; + enum-name = "GPIO_WP_L"; + }; + lid_accel_int_l { + gpios = <&gpiob 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_LID_ACCEL_INT_L"; + }; + tablet_mode_l { + gpios = <&gpiob 2 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + ec_ap_int_odl { + gpios = <&gpioc 1 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_EC_INT_L"; + }; + ec_kso_02_inv { + gpios = <&gpio1 7 GPIO_OUT_LOW>; + enum-name = "GPIO_KBD_KSO2"; + }; + usb_c0_bc12_int_odl { + gpios = <&gpio8 3 GPIO_INPUT>; + }; + ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUT_LOW>; + enum-name = "GPIO_ENTERING_RW"; + }; + charger_prochot_odl { + gpios = <&gpiob 1 GPIO_INPUT>; + enum-name = "GPIO_CHARGER_PROCHOT_ODL"; + }; + ec_rst_odl { + gpios = <&gpio7 7 GPIO_INPUT>; + enum-name = "GPIO_EC_RST_ODL"; + }; + lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + acok_od { + gpios = <&gpio0 0 GPIO_INPUT>; + enum-name = "GPIO_AC_PRESENT"; + }; + gsc_ec_pwr_btn_odl { + gpios = <&gpio0 1 GPIO_INPUT>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + en_5v_usm { + gpios = <&gpio0 2 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_5V_USM"; + }; + packet_mode_en { + gpios = <&gpio0 2 GPIO_OUT_LOW>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + x_ec_gpio2 { + gpios = <&gpiod 4 GPIO_INPUT>; + enum-name = "GPIO_X_EC_GPIO2"; + }; + ap_sysrst_odl_r: ap_sysrst_odl_r { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; + enum-name = "GPIO_AP_EC_SYSRST_ODL"; + }; + ap_xhci_init_done { + gpios = <&gpioa 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_AP_XHCI_INIT_DONE"; + }; + usb_c0_ppc_int_odl { + gpios = <&gpio6 7 GPIO_INPUT>; + enum-name = "GPIO_USB_C0_PPC_INT_ODL"; + }; + pg_pp5000_z2_od { + gpios = <&gpio7 0 GPIO_INPUT>; + enum-name = "GPIO_PG_PP5000_Z2_OD"; + }; + ec_x_gpio1 { + gpios = <&gpio6 2 GPIO_OUT_LOW>; + enum-name = "GPIO_EC_X_GPIO1"; + }; + dp_aux_path_sel { + gpios = <&gpio6 3 GPIO_OUT_LOW>; + enum-name = "GPIO_DP_AUX_PATH_SEL"; + }; + ec_bl_en_od { + gpios = <&gpio4 0 (GPIO_ODR_LOW | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_EC_BL_EN_OD"; + }; + ec_x_gpio3 { + gpios = <&gpiod 3 GPIO_OUT_LOW>; + enum-name = "GPIO_EC_X_GPIO3"; + }; + usb_c0_tcpc_int_odl { + gpios = <&gpio7 3 GPIO_INPUT>; + enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; + }; + usb_c0_tcpc_rst { + gpios = <&gpioc 0 GPIO_OUT_LOW>; + enum-name = "GPIO_USB_C0_TCPC_RST"; + }; + en_pp5000_usb_a0_vbus_x { + gpios = <&gpio6 0 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_PP5000_USB_A0_VBUS"; + }; + hdmi_prsnt_odl { + gpios = <&gpio3 7 GPIO_INPUT>; + enum-name = "GPIO_HDMI_PRSNT_ODL"; + }; + en_pp5000_z2 { + gpios = <&gpio3 4 GPIO_OUT_HIGH>; + enum-name = "GPIO_EN_PP5000_Z2"; + }; + usb_c1_tcpc_int_odl { + gpios = <&gpioe 1 GPIO_INPUT>; + enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; + }; + ec_batt_pres_odl { + gpios = <&gpioe 0 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + usb_a0_fault_odl { + gpios = <&gpioc 7 GPIO_INPUT>; + enum-name = "GPIO_USB_A0_FAULT_ODL"; + }; + ec_ap_dp_hpd_odl { + gpios = <&gpio6 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_AP_DP_HPD_ODL"; + }; + ec_pmic_en_odl { + gpios = <&gpio7 4 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; + enum-name = "GPIO_EC_PMIC_EN_ODL"; + }; + ec_volup_btn_odl { + gpios = <&gpiod 5 GPIO_INPUT>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + ec_voldn_btn_odl { + gpios = <&gpioe 2 GPIO_INPUT>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + }; + + def-lvol-io-list { + compatible = "nuvoton,npcx-lvolctrl-def"; + lvol-io-pads = < + &lvol_ioe3 /* GPIOE3 GPIO_EC_WP_L */ + &lvol_io40 /* GPIO40 GPIO_EC_BL_EN_OD */ + >; + }; +}; diff --git a/zephyr/projects/corsola/krabby/gpio.dts b/zephyr/projects/corsola/gpio_krabby.dts index 29fc7dd879..9ecf5e007f 100644 --- a/zephyr/projects/corsola/krabby/gpio.dts +++ b/zephyr/projects/corsola/gpio_krabby.dts @@ -3,280 +3,226 @@ * found in the LICENSE file. */ -/ { - gpiox: gpio@0 { - status = "okay"; - compatible = "zephyr,gpio-emul"; - label = "GPIO_UNIMPLEMENTED"; - reg = <0x800 0x4>; - rising-edge; - falling-edge; - high-level; - low-level; - gpio-controller; - #gpio-cells = <2>; - }; +#include <dt-bindings/gpio_defines.h> +#include <dt-bindings/wake_mask_event_defines.h> +/ { named-gpios { compatible = "named-gpios"; power_button_l: power_button_l { gpios = <&gpioe 4 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "POWER_BUTTON_L"; }; lid_open: lid_open { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; tablet_mode_l: tablet_mode_l { gpios = <&gpioj 7 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; ap_ec_warm_rst_req: ap_ec_warm_rst_req { - gpios = <&gpiod 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + gpios = <&gpiod 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_HIGH)>; enum-name = "GPIO_AP_EC_WARM_RST_REQ"; - label = "AP_EC_WARM_RST_REQ"; }; ap_in_sleep_l: ap_in_sleep_l { - gpios = <&gpiob 6 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + gpios = <&gpiob 6 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; enum-name = "GPIO_AP_IN_SLEEP_L"; - label = "AP_IN_SLEEP_L"; }; base_imu_int_l: base_imu_int_l { gpios = <&gpiom 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_BASE_IMU_INT_L"; - label = "BASE_IMU_INT_L"; }; lid_accel_int_l: lid_accel_int_l { gpios = <&gpiom 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_LID_ACCEL_INT_L"; - label = "LID_ACCEL_INT_L"; }; volume_down_l: volume_down_l { gpios = <&gpiod 5 GPIO_INPUT>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "VOLUME_DOWN_L"; }; volume_up_l: volume_up_l { gpios = <&gpiod 6 GPIO_INPUT>; enum-name = "GPIO_VOLUME_UP_L"; - label = "VOLUME_UP_L"; }; ap_xhci_init_done: ap_xhci_init_done { gpios = <&gpioj 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_AP_XHCI_INIT_DONE"; - label = "AP_XHCI_INIT_DONE"; }; ac_present: ac_present { gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "AC_PRESENT"; }; - wp: wp { + ec_flash_wp_odl: ec_flash_wp_odl { gpios = <&gpioi 4 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; - enum-name = "GPIO_WP"; - label = "WP"; + enum-name = "GPIO_WP_L"; }; spi0_cs: spi0_cs { gpios = <&gpiom 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_SPI0_CS"; - label = "SPI0_CS"; }; x_ec_gpio2: x_ec_gpio2 { gpios = <&gpiob 2 (GPIO_INPUT | GPIO_ODR_HIGH)>; enum-name = "GPIO_X_EC_GPIO2"; - label = "X_EC_GPIO2"; }; usb_c0_ppc_bc12_int_odl: usb_c0_ppc_bc12_int_odl { gpios = <&gpiod 1 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PPC_BC12_INT_ODL"; - label = "USB_C0_PPC_BC12_INT_ODL"; }; usb_c1_bc12_charger_int_odl: usb_c1_bc12_charger_int_odl { gpios = <&gpioj 4 GPIO_INPUT>; enum-name = "GPIO_USB_C1_BC12_CHARGER_INT_ODL"; - label = "USB_C1_BC12_CHARGER_INT_ODL"; }; ec_pmic_en_odl: ec_pmic_en_odl { gpios = <&gpiod 0 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_PMIC_EN_ODL"; - label = "EC_PMIC_EN_ODL"; }; en_pp5000_z2: en_pp5000_z2 { gpios = <&gpioc 6 GPIO_OUT_HIGH>; enum-name = "GPIO_EN_PP5000_Z2"; - label = "EN_PP5000_Z2"; }; en_ulp: en_ulp { gpios = <&gpioe 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_ULP"; - label = "EN_ULP"; }; sys_rst_odl: sys_rst_odl { gpios = <&gpiog 1 GPIO_ODR_LOW>; enum-name = "GPIO_SYS_RST_ODL"; - label = "SYS_RST_ODL"; }; ec_bl_en_od: ec_bl_en_od { gpios = <&gpiob 5 (GPIO_ODR_LOW | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_BL_EN_OD"; - label = "EC_BL_EN_OD"; }; - ap_ec_sysrst_odl: ap_ec_sysrst_odl { - gpios = <&gpioj 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + ap_sysrst_odl_r: ap_ec_sysrst_odl { + gpios = <&gpioj 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; enum-name = "GPIO_AP_EC_SYSRST_ODL"; - label = "AP_EC_SYSRST_ODL"; }; ap_ec_wdtrst_l: ap_ec_wdtrst_l { - gpios = <&gpioc 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + gpios = <&gpioc 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8 | + GPIO_ACTIVE_LOW)>; enum-name = "GPIO_AP_EC_WDTRST_L"; - label = "AP_EC_WDTRST_L"; }; ec_int_l: ec_int_l { gpios = <&gpioe 6 (GPIO_ODR_HIGH | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_EC_INT_L"; - label = "EC_INT_L"; }; dp_aux_path_sel: dp_aux_path_sel { gpios = <&gpiog 0 GPIO_OUT_HIGH>; enum-name = "GPIO_DP_AUX_PATH_SEL"; - label = "DP_AUX_PATH_SEL"; }; ec_ap_dp_hpd_odl: ec_ap_dp_hpd_odl { gpios = <&gpioj 0 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_AP_DP_HPD_ODL"; - label = "EC_AP_DP_HPD_ODL"; }; en_pp5000_usb_a0_vbus: en_pp5000_usb_a0_vbus { gpios = <&gpiob 7 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000_USB_A0_VBUS"; - label = "EN_PP5000_USB_A0_VBUS"; }; usb_c0_ppc_frsinfo: usb_c0_ppc_frsinfo { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PPC_FRSINFO"; - label = "USB_C0_PPC_FRSINFO"; }; ec_batt_pres_odl: ec_batt_pres_odl { gpios = <&gpioc 0 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "BATT_PRES_ODL"; }; en_ec_id_odl: en_ec_id_odl { gpios = <&gpioh 5 GPIO_ODR_LOW>; enum-name = "GPIO_EN_EC_ID_ODL"; - label = "EN_EC_ID_ODL"; }; entering_rw: entering_rw { gpios = <&gpioc 5 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "ENTERING_RW"; }; en_5v_usm: en_5v_usm { gpios = <&gpiog 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_5V_USM"; - label = "EN_5V_USM"; }; usb_a0_fault_odl: usb_a0_fault_odl { gpios = <&gpioj 6 GPIO_INPUT>; enum-name = "GPIO_USB_A0_FAULT_ODL"; - label = "USB_A0_FAULT_ODL"; }; i2c_a_scl: i2c_a_scl { gpios = <&gpiob 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_A_SCL"; - label = "I2C_A_SCL"; }; i2c_a_sda: i2c_a_sda { gpios = <&gpiob 4 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_A_SDA"; - label = "I2C_A_SDA"; }; i2c_b_scl: i2c_b_scl { gpios = <&gpioc 1 GPIO_INPUT>; enum-name = "GPIO_I2C_B_SCL"; - label = "I2C_B_SCL"; }; i2c_b_sda: i2c_b_sda { gpios = <&gpioc 2 GPIO_INPUT>; enum-name = "GPIO_I2C_B_SDA"; - label = "I2C_B_SDA"; }; i2c_c_scl: i2c_c_scl { gpios = <&gpiof 6 GPIO_INPUT>; enum-name = "GPIO_I2C_C_SCL"; - label = "I2C_C_SCL"; }; i2c_c_sda: i2c_c_sda { gpios = <&gpiof 7 GPIO_INPUT>; enum-name = "GPIO_I2C_C_SDA"; - label = "I2C_C_SDA"; }; i2c_d_scl: i2c_d_scl { gpios = <&gpiof 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_D_SCL"; - label = "I2C_D_SCL"; }; i2c_d_sda: i2c_d_sda { gpios = <&gpiof 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; enum-name = "GPIO_I2C_D_SDA"; - label = "I2C_D_SDA"; }; i2c_e_scl: i2c_e_scl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_I2C_E_SCL"; - label = "I2C_E_SCL"; }; i2c_e_sda: i2c_e_sda { gpios = <&gpioe 7 GPIO_INPUT>; enum-name = "GPIO_I2C_E_SDA"; - label = "I2C_E_SDA"; }; i2c_f_scl: i2c_f_scl { gpios = <&gpioa 4 GPIO_INPUT>; enum-name = "GPIO_I2C_F_SCL"; - label = "I2C_F_SCL"; }; i2c_f_sda: i2c_f_sda { gpios = <&gpioa 5 GPIO_INPUT>; enum-name = "GPIO_I2C_F_SDA"; - label = "I2C_F_SDA"; }; ec_x_gpio1: ec_x_gpio1 { gpios = <&gpioh 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_X_GPIO1"; - label = "EC_X_GPIO1"; }; ec_x_gpio3: ec_x_gpio3 { gpios = <&gpioj 1 GPIO_INPUT>; enum-name = "GPIO_EC_X_GPIO3"; - label = "EC_X_GPIO3"; }; hdmi_prsnt_odl: hdmi_prsnt_odl { gpios = <&gpioj 3 GPIO_INPUT>; enum-name = "GPIO_HDMI_PRSNT_ODL"; - label = "HDMI_PRSNT_ODL"; }; + }; - /* pins used in power/mt8192, to be removed */ - ap_ec_watchdog_l: ap_ec_watchdog_l { - gpios = <&gpiox 0 GPIO_INPUT>; - enum-name = "GPIO_AP_EC_WATCHDOG_L"; - label = "AP_EC_WATCHDOG_L"; - }; - ec_pmic_watchdog_l: ec_pmic_watchdog_l { - gpios = <&gpiox 0 GPIO_INPUT>; - enum-name = "GPIO_EC_PMIC_WATCHDOG_L"; - label = "EC_PMIC_WATCHDOG_L"; - }; - pmic_ec_pwrgd: pmic_ec_pwrgd { - gpios = <&gpiox 0 GPIO_INPUT>; - enum-name = "GPIO_PMIC_EC_PWRGD"; - label = "PMIC_EC_PWRGD"; - }; + ec-mkbp-host-event-wakeup-mask { + compatible = "ec-wake-mask-event"; + wakeup-mask = <( + HOST_EVENT_MASK(HOST_EVENT_AC_CONNECTED) | + HOST_EVENT_MASK(HOST_EVENT_AC_DISCONNECTED) | + HOST_EVENT_MASK(HOST_EVENT_LID_OPEN) | + HOST_EVENT_MASK(HOST_EVENT_POWER_BUTTON) | + HOST_EVENT_MASK(HOST_EVENT_HANG_DETECT) | + HOST_EVENT_MASK(HOST_EVENT_MODE_CHANGE))>; + }; + + ec-mkbp-event-wakeup-mask { + compatible = "ec-wake-mask-event"; + wakeup-mask = <(MKBP_EVENT_KEY_MATRIX | + MKBP_EVENT_HOST_EVENT)>; }; hibernate-wake-pins { @@ -286,22 +232,6 @@ &lid_open>; }; - power_signal_list: power-signal-list { - compatible = "mt8192,power-signal-list"; - pmic_pwr_good { - power-enum-name = "PMIC_PWR_GOOD"; - power-gpio-pin = <&pmic_ec_pwrgd>; - }; - ap_in_s3_l { - power-enum-name = "AP_IN_S3_L"; - power-gpio-pin = <&ap_in_sleep_l>; - }; - ap_wdt_asserted { - power-enum-name = "AP_WDT_ASSERTED"; - power-gpio-pin = <&ap_ec_watchdog_l>; - }; - }; - unused-pins { compatible = "unused-gpios"; @@ -316,21 +246,21 @@ <&gpioh 3 GPIO_ODR_HIGH>, /* ccd_mode_odl */ <&gpioc 4 GPIO_INPUT>, - /* uart1_rx */ - <&gpiob 0 GPIO_INPUT>, /* unnamed nc pins */ - <&gpioa 3 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioa 6 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioa 7 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioc 3 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpiod 7 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpiof 1 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioh 0 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioh 6 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpioi 7 (GPIO_INPUT | GPIO_PULL_DOWN)>, - <&gpiom 6 (GPIO_INPUT | GPIO_PULL_DOWN)>, + <&gpioa 3 GPIO_INPUT_PULL_DOWN>, + <&gpioa 6 GPIO_INPUT_PULL_DOWN>, + <&gpioa 7 GPIO_INPUT_PULL_DOWN>, + <&gpioc 3 GPIO_INPUT_PULL_DOWN>, + <&gpiod 7 GPIO_INPUT_PULL_DOWN>, + <&gpiof 1 GPIO_INPUT_PULL_DOWN>, + <&gpioh 0 GPIO_INPUT_PULL_DOWN>, + <&gpioh 6 GPIO_INPUT_PULL_DOWN>, + <&gpioi 3 GPIO_INPUT_PULL_DOWN>, + <&gpioi 5 GPIO_INPUT_PULL_DOWN>, + <&gpioi 6 GPIO_INPUT_PULL_DOWN>, + <&gpiom 6 GPIO_INPUT_PULL_DOWN>, /* spi_clk_gpg6 */ - <&gpiog 6 (GPIO_INPUT | GPIO_PULL_UP)>, + <&gpiog 6 GPIO_INPUT_PULL_UP>, /* spi_mosi_gpg4 */ <&gpiog 4 GPIO_OUT_LOW>, /* spi_miso_gpg5 */ diff --git a/zephyr/projects/corsola/i2c_kingler.dts b/zephyr/projects/corsola/i2c_kingler.dts new file mode 100644 index 0000000000..21701bddb2 --- /dev/null +++ b/zephyr/projects/corsola/i2c_kingler.dts @@ -0,0 +1,93 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_sensor: sensor { + i2c-port = <&i2c0_0>; + enum-name = "I2C_PORT_SENSOR"; + }; + i2c_usb_c0: usb-c0 { + i2c-port = <&i2c1_0>; + enum-name = "I2C_PORT_USB_C0"; + }; + i2c_usb_c1: usb-c1 { + i2c-port = <&i2c2_0>; + enum-name = "I2C_PORT_USB_C1"; + }; + tcpc1 { + i2c-port = <&i2c2_0>; + enum-name = "I2C_PORT_USB_C1_TCPC"; + }; + ppc1 { + i2c-port = <&i2c2_0>; + enum-name = "I2C_PORT_USB_C1_PPC"; + }; + eeprom { + i2c-port = <&i2c3_0>; + enum-name = "I2C_PORT_EEPROM"; + }; + charger { + i2c-port = <&i2c3_0>; + enum-name = "I2C_PORT_POWER"; + }; + battery { + i2c-port = <&i2c5_0>; + enum-name = "I2C_PORT_BATTERY"; + }; + }; +}; + +&i2c0_0 { + label = "I2C_SENSOR"; + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c1_0 { + label = "I2C_USB_C0"; + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c2_0 { + label = "I2C_USB_C1"; + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c_ctrl2 { + status = "okay"; +}; + +i2c_pwr_cbi: &i2c3_0 { + label = "I2C_PWR_CBI"; + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c5_0 { + label = "I2C_BATTERY"; + status = "okay"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&i2c_ctrl5 { + status = "okay"; +}; diff --git a/zephyr/projects/corsola/krabby/i2c.dts b/zephyr/projects/corsola/i2c_krabby.dts index 7205bf19bc..1dbfd83782 100644 --- a/zephyr/projects/corsola/krabby/i2c.dts +++ b/zephyr/projects/corsola/i2c_krabby.dts @@ -7,71 +7,50 @@ named-i2c-ports { compatible = "named-i2c-ports"; - power { - i2c-port = <&i2c0>; - enum-name = "I2C_PORT_POWER"; - label = "POWER"; - }; battery { - i2c-port = <&i2c0>; - remote-port = <0>; + i2c-port = <&i2c1>; + remote-port = <1>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; virtual-battery { - i2c-port = <&i2c0>; + i2c-port = <&i2c1>; enum-name = "I2C_PORT_VIRTUAL_BATTERY"; - label = "VIRTUAL_BATTERY"; }; eeprom { i2c-port = <&i2c0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; charger { i2c-port = <&i2c0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; i2c_sensor: sensor { - i2c-port = <&i2c1>; + i2c-port = <&i2c3>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; - }; - i2c-accel { - i2c-port = <&i2c1>; - enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; ppc0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_PPC0"; - label = "PPC0"; }; ppc1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_PPC1"; - label = "PPC1"; }; usb-c0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_C0"; - label = "USB_C0"; }; usb-c1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_C1"; - label = "USB_C1"; }; usb-mux0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_MUX0"; - label = "USB_MUX0"; }; usb-mux1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_MUX1"; - label = "USB_MUX1"; }; }; @@ -79,24 +58,42 @@ &i2c0 { /* EC_I2C_PWR_CBI */ + label = "I2C_PWR_CBI"; status = "okay"; - clock-frequency = <I2C_BITRATE_STANDARD>; + clock-frequency = <I2C_BITRATE_FAST>; }; &i2c1 { - /* EC_I2C_SENSOR */ + /* EC_I2C_BATTERY */ + label = "I2C_BATTERY"; status = "okay"; - clock-frequency = <I2C_BITRATE_FAST>; + clock-frequency = <I2C_BITRATE_STANDARD>; }; &i2c2 { /* EC_I2C_USB_C0 */ + label = "I2C_USB_C0"; + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3 { + /* EC_I2C_SENSOR */ + label = "I2C_SENSOR"; status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; + /* + * b/210800948: i2c3 is not working at this moment. + * + * The driver support for i2c3 on GPF2/F3 is under review in + * following PR. + * https://github.com/zephyrproject-rtos/zephyr/pull/41389 + */ }; &i2c4 { /* EC_I2C_USB_C1 */ + label = "I2C_USB_C1"; status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; }; diff --git a/zephyr/projects/corsola/include/baseboard_usbc_config.h b/zephyr/projects/corsola/include/baseboard_usbc_config.h new file mode 100644 index 0000000000..8fa0ff5cd6 --- /dev/null +++ b/zephyr/projects/corsola/include/baseboard_usbc_config.h @@ -0,0 +1,15 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Corsola daughter board detection */ + +#ifndef __CROS_EC_BASEBOARD_USBC_CONFIG_H +#define __CROS_EC_BASEBOARD_USBC_CONFIG_H + +#include "gpio.h" + +void ppc_interrupt(enum gpio_signal signal); + +#endif /* __CROS_EC_BASEBOARD_USBC_CONFIG_H */ diff --git a/zephyr/projects/corsola/include/gpio_map.h b/zephyr/projects/corsola/include/gpio_map.h new file mode 100644 index 0000000000..8fda7b77d0 --- /dev/null +++ b/zephyr/projects/corsola/include/gpio_map.h @@ -0,0 +1,171 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __ZEPHYR_GPIO_MAP_H +#define __ZEPHYR_GPIO_MAP_H + +#include <devicetree.h> +#include <gpio_signal.h> + +#define GPIO_BATT_PRES_ODL NAMED_GPIO(ec_batt_pres_odl) + +#define GPIO_ENTERING_RW GPIO_UNIMPLEMENTED + +/* daughterboard GPIO remap */ +#define GPIO_EN_HDMI_PWR GPIO_EC_X_GPIO1 +#define GPIO_USB_C1_FRS_EN GPIO_EC_X_GPIO1 +#define GPIO_USB_C1_PPC_INT_ODL GPIO_X_EC_GPIO2 +#define GPIO_PS185_EC_DP_HPD GPIO_X_EC_GPIO2 +#define GPIO_USB_C1_DP_IN_HPD GPIO_EC_X_GPIO3 +#define GPIO_PS185_PWRDN_ODL GPIO_EC_X_GPIO3 + +#ifdef CONFIG_PLATFORM_EC_POWER_BUTTON + #define PWRBTN_INT() GPIO_INT(GPIO_POWER_BUTTON_L, \ + GPIO_INT_EDGE_BOTH, \ + power_button_interrupt) +#else + #define PWRBTN_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_VOLUME_BUTTONS + #define VOLBTN_INT(pin) GPIO_INT(pin, \ + GPIO_INT_EDGE_BOTH, \ + button_interrupt) +#else + #define VOLBTN_INT(pin) +#endif + +#ifdef CONFIG_SOC_IT8XXX2 + #define AP_SPI_INT() GPIO_INT(GPIO_SPI0_CS, \ + GPIO_INT_EDGE_BOTH, \ + spi_event) +#elif defined(CONFIG_SOC_NPCX9M3F) + /* The interrupt is configured by dts */ + #define AP_SPI_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_TABLET_MODE + #define GMR_TABLET_INT() GPIO_INT(GPIO_TABLET_MODE_L, \ + GPIO_INT_EDGE_BOTH, \ + gmr_tablet_switch_isr) +#else + #define GMR_TABLET_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_POWERSEQ_MT8186 + #define WARM_RST_REQ_INT() GPIO_INT(GPIO_AP_EC_WARM_RST_REQ, \ + GPIO_INT_EDGE_RISING, \ + chipset_reset_request_interrupt) + + #define AP_IN_SLEEP_INT() GPIO_INT(GPIO_AP_IN_SLEEP_L, \ + GPIO_INT_EDGE_BOTH, \ + power_signal_interrupt) + + #define AP_IN_RST_INT() GPIO_INT(GPIO_AP_EC_SYSRST_ODL, \ + GPIO_INT_EDGE_BOTH, \ + power_signal_interrupt) + + #define AP_EC_WDTRST_INT() GPIO_INT(GPIO_AP_EC_WDTRST_L, \ + GPIO_INT_EDGE_BOTH, \ + power_signal_interrupt) +#else + #define WARM_RST_REQ_INT() + #define AP_IN_SLEEP_INT() + #define AP_IN_RST_INT() + #define AP_EC_WDTRST_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_ACCEL_LIS2DW12 + #define LID_ACCEL_INT() GPIO_INT(GPIO_LID_ACCEL_INT_L, \ + GPIO_INT_EDGE_FALLING, \ + lis2dw12_interrupt) +#else + #define LID_ACCEL_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_EXTPOWER_GPIO + #define EXTPWR_INT() GPIO_INT(GPIO_AC_PRESENT, \ + GPIO_INT_EDGE_BOTH, \ + extpower_interrupt) +#else + #define EXTPWR_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_LID_SWITCH + #define LID_SWITCH_INT() GPIO_INT(GPIO_LID_OPEN, \ + GPIO_INT_EDGE_BOTH, \ + lid_interrupt) +#else + #define LID_SWITCH_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_SWITCH + #define SWITCH_INT() GPIO_INT(GPIO_WP_L, \ + GPIO_INT_EDGE_BOTH, \ + switch_interrupt) +#else + #define SWITCH_INT() +#endif + +#ifdef CONFIG_VARIANT_CORSOLA_DB_DETECTION + #define X_EC_GPIO2_INT() GPIO_INT(GPIO_X_EC_GPIO2, \ + GPIO_INT_EDGE_BOTH, \ + x_ec_interrupt) +#else + #define X_EC_GPIO2_INT() +#endif + +#ifdef CONFIG_VARIANT_CORSOLA_USBA + #define USBA_INT() GPIO_INT(GPIO_AP_XHCI_INIT_DONE, \ + GPIO_INT_EDGE_BOTH, \ + usb_a0_interrupt) +#else + #define USBA_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_GMR_TABLET_MODE +#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L +#endif + +/* TODO: remove after icm426xx driver added */ +static inline void motion_interrupt(enum gpio_signal signal) +{ +} + +/* + * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. + * + * Each GPIO_INT requires three parameters: + * gpio_signal - The enum gpio_signal for the interrupt gpio + * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH) + * handler - The platform/ec interrupt handler. + * + * Ensure that this files includes all necessary headers to declare all + * referenced handler functions. + * + * For example, one could use the follow definition: + * #define EC_CROS_GPIO_INTERRUPTS \ + * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print) + */ +#define EC_CROS_GPIO_INTERRUPTS \ + PWRBTN_INT() \ + VOLBTN_INT(GPIO_VOLUME_DOWN_L) \ + VOLBTN_INT(GPIO_VOLUME_UP_L) \ + LID_SWITCH_INT() \ + WARM_RST_REQ_INT() \ + AP_IN_SLEEP_INT() \ + AP_IN_RST_INT() \ + AP_EC_WDTRST_INT() \ + GMR_TABLET_INT() \ + GPIO_INT(GPIO_BASE_IMU_INT_L, \ + GPIO_INT_EDGE_FALLING, motion_interrupt) \ + LID_ACCEL_INT() \ + USBA_INT() \ + EXTPWR_INT() \ + SWITCH_INT() \ + AP_SPI_INT() \ + X_EC_GPIO2_INT() + +#endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/projects/corsola/krabby/include/i2c_map.h b/zephyr/projects/corsola/include/i2c_map.h index 898d5c398c..898d5c398c 100644 --- a/zephyr/projects/corsola/krabby/include/i2c_map.h +++ b/zephyr/projects/corsola/include/i2c_map.h diff --git a/zephyr/projects/corsola/include/variant_db_detection.h b/zephyr/projects/corsola/include/variant_db_detection.h new file mode 100644 index 0000000000..40853016f8 --- /dev/null +++ b/zephyr/projects/corsola/include/variant_db_detection.h @@ -0,0 +1,32 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Corsola daughter board detection */ + +#ifndef __CROS_EC_CORSOLA_DB_DETECTION_H +#define __CROS_EC_CORSOLA_DB_DETECTION_H + +enum corsola_db_type { + CORSOLA_DB_NONE = -1, + CORSOLA_DB_TYPEC, + CORSOLA_DB_HDMI, + CORSOLA_DB_COUNT, +}; + +#ifdef CONFIG_VARIANT_CORSOLA_DB_DETECTION +/* + * Get the connected daughterboard type. + * + * @return The daughterboard type. + */ +enum corsola_db_type corsola_get_db_type(void); +#else +inline enum corsola_db_type corsola_get_db_type(void) +{ + return CORSOLA_DB_NONE; +}; +#endif /* CONFIG_VARIANT_CORSOLA_DB_DETECTION */ + +#endif /* __CROS_EC_CORSOLA_DB_DETECTION_H */ diff --git a/zephyr/projects/corsola/kingler/gpio.dts b/zephyr/projects/corsola/kingler/gpio.dts deleted file mode 100644 index 638e95c9fb..0000000000 --- a/zephyr/projects/corsola/kingler/gpio.dts +++ /dev/null @@ -1,337 +0,0 @@ -/ { - named-gpios { - compatible = "named-gpios"; - - ec_wp_l { - gpios = <&gpio5 0 GPIO_INPUT>; - label = "EC_WP_L"; - enum-name = "GPIO_WP_L"; - }; - ccd_mode_odl { - gpios = <&gpioc 6 GPIO_ODR_HIGH>; - label = "CCD_MODE_ODL"; - }; - ec_gsc_packet_mode { - gpios = <&gpiob 1 GPIO_OUT_LOW>; - label = "EC_GSC_PACKET_MODE"; - }; - mech_pwr_btn_odl { - gpios = <&gpiod 2 GPIO_INPUT>; - label = "MECH_PWR_BTN_ODL"; - enum-name = "GPIO_POWER_BUTTON_L"; - }; - ec_pwr_btn_odl { - gpios = <&gpio0 1 GPIO_INPUT>; - label = "EC_PWR_BTN_ODL"; - enum-name = "GPIO_EC_PWR_BTN_ODL"; - }; - slp_s3_l { - gpios = <&gpio6 1 GPIO_INPUT>; - label = "SLP_S3_L"; - enum-name = "GPIO_PCH_SLP_S3_L"; - }; - slp_s5_l { - gpios = <&gpio7 2 GPIO_INPUT>; - label = "SLP_S5_L"; - enum-name = "GPIO_PCH_SLP_S5_L"; - }; - slp_s3_s0i3_l { - gpios = <&gpio7 4 GPIO_INPUT>; - label = "SLP_S3_S0I3_L"; - enum-name = "GPIO_PCH_SLP_S0_L"; - }; - pg_pwr_s5 { - gpios = <&gpioc 0 GPIO_INPUT>; - label = "PG_PWR_S5"; - enum-name = "GPIO_S5_PGOOD"; - }; - pg_pcore_s0_r_od { - gpios = <&gpiob 6 GPIO_INPUT>; - label = "PG_PCORE_S0_R_OD"; - enum-name = "GPIO_S0_PGOOD"; - }; - acok_od { - gpios = <&gpio0 0 GPIO_INPUT>; - label = "ACOK_OD"; - enum-name = "GPIO_AC_PRESENT"; - }; - ec_pcore_int_odl { - gpios = <&gpiof 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PCORE_INT_ODL"; - enum-name = "GPIO_EC_PCORE_INT_ODL"; - }; - pg_groupc_s0_od { - gpios = <&gpioa 3 GPIO_INPUT>; - label = "PG_GROUPC_S0_OD"; - enum-name = "GPIO_PG_GROUPC_S0_OD"; - }; - pg_lpddr4x_s3_od { - gpios = <&gpio9 5 GPIO_INPUT>; - label = "PG_LPDDR4X_S3_OD"; - enum-name = "GPIO_PG_LPDDR4X_S3_OD"; - }; - en_pwr_s5 { - gpios = <&gpiob 7 GPIO_OUT_LOW>; - label = "EN_PWR_S5"; - enum-name = "GPIO_EN_PWR_A"; - }; - en_pwr_s0_r { - gpios = <&gpiof 1 GPIO_OUT_LOW>; - label = "EN_PWR_S0_R"; - enum-name = "GPIO_EN_PWR_S0_R"; - }; - en_pwr_pcore_s0_r { - gpios = <&gpioe 1 GPIO_OUT_LOW>; - label = "EN_PWR_PCORE_S0_R"; - enum-name = "GPIO_EN_PWR_PCORE_S0_R"; - }; - ec_entering_rw { - gpios = <&gpio6 6 GPIO_OUT_LOW>; - label = "EC_ENTERING_RW"; - enum-name = "GPIO_ENTERING_RW"; - }; - ec_sys_rst_l { - gpios = <&gpio7 6 GPIO_ODR_HIGH>; - label = "EC_SYS_RST_L"; - enum-name = "GPIO_SYS_RESET_L"; - }; - ec_soc_rsmrst_l { - gpios = <&gpioc 5 GPIO_OUT_LOW>; - label = "EC_SOC_RSMRST_L"; - enum-name = "GPIO_PCH_RSMRST_L"; - }; - ec_clr_cmos { - gpios = <&gpioa 1 GPIO_OUT_LOW>; - label = "EC_CLR_CMOS"; - }; - ec_mem_event { - gpios = <&gpioa 5 GPIO_OUT_LOW>; - label = "EC_MEM_EVENT"; - }; - ec_soc_pwr_btn_l { - gpios = <&gpio6 3 GPIO_OUT_HIGH>; - label = "EC_SOC_PWR_BTN_L"; - enum-name = "GPIO_PCH_PWRBTN_L"; - }; - ec_soc_pwr_good { - gpios = <&gpiod 3 GPIO_OUT_LOW>; - label = "EC_SOC_PWR_GOOD"; - enum-name = "GPIO_PCH_SYS_PWROK"; - }; - ec_soc_wake_l { - gpios = <&gpio0 3 GPIO_OUT_HIGH>; - label = "EC_SOC_WAKE_L"; - enum-name = "GPIO_EC_PCH_WAKE_ODL"; - }; - ec_soc_int_l { - gpios = <&gpio8 3 GPIO_OUT_HIGH>; - label = "EC_SOC_INT_L"; - }; - prochot_odl { - gpios = <&gpiod 5 GPIO_ODR_HIGH>; - label = "PROCHOT_ODL"; - enum-name = "GPIO_CPU_PROCHOT"; - }; - soc_alert_ec_l { - gpios = <&gpioe 2 GPIO_INPUT>; - label = "SOC_ALERT_EC_L"; - }; - soc_thermtrip_odl { - gpios = <&gpioe 5 GPIO_INPUT>; - label = "SOC_THERMTRIP_ODL"; - }; - usb_c0_tcpc_int_odl { - gpios = <&gpioe 0 GPIO_INPUT>; - label = "USB_C0_TCPC_INT_ODL"; - }; - usb_c1_tcpc_int_odl { - gpios = <&gpioc 7 GPIO_INPUT>; - label = "USB_C1_TCPC_INT_ODL"; - }; - usb_c0_ppc_int_odl { - gpios = <&gpio7 5 GPIO_INPUT>; - label = "USB_C0_PPC_INT_ODL"; - }; - usb_c1_ppc_int_odl { - gpios = <&gpiod 4 GPIO_INPUT>; - label = "USB_C1_PPC_INT_ODL"; - }; - usb_c0_bc12_int_odl { - gpios = <&gpioa 4 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "USB_C0_BC12_INT_ODL"; - }; - usb_c1_bc12_int_odl { - gpios = <&gpio9 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "USB_C1_BC12_INT_ODL"; - }; - usb_c0_c1_fault_odl { - gpios = <&gpio7 3 GPIO_ODR_HIGH>; - label = "USB_C0_C1_FAULT_ODL"; - }; - usb_c0_tcpc_rst_l { - gpios = <&gpio3 4 GPIO_OUT_HIGH>; - label = "USB_C0_TCPC_RST_L"; - }; - usb_c1_tcpc_rst_l { - gpios = <&gpio3 7 GPIO_OUT_HIGH>; - label = "USB_C1_TCPC_RST_L"; - }; - usb_c0_hpd { - gpios = <&gpiof 5 GPIO_OUT_LOW>; - label = "USB_C0_HPD"; - }; - usb_c1_hpd { - gpios = <&gpiof 4 GPIO_OUT_LOW>; - label = "USB_C1_HPD"; - }; - 3axis_int_l { - gpios = <&gpioa 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "3AXIS_INT_L"; - }; - lid_open { - gpios = <&gpio0 2 GPIO_INPUT>; - label = "LID_OPEN"; - enum-name = "GPIO_LID_OPEN"; - }; - voldn_btn_odl { - gpios = <&gpioa 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "VOLDN_BTN_ODL"; - enum-name = "GPIO_VOLUME_DOWN_L"; - }; - volup_btn_odl { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "VOLUP_BTN_ODL"; - enum-name = "GPIO_VOLUME_UP_L"; - }; - ec_batt_pres_odl { - gpios = <&gpio9 4 GPIO_INPUT>; - label = "EC_BATT_PRES_ODL"; - enum-name = "GPIO_BATT_PRES_ODL"; - }; - ec_disable_disp_bl { - gpios = <&gpioa 6 GPIO_OUT_HIGH>; - label = "EC_DISABLE_DISP_BL"; - }; - ec_i2c_usb_a0_c0_scl { - gpios = <&gpiob 5 GPIO_INPUT>; - label = "EC_I2C_USB_A0_C0_SCL"; - }; - ec_i2c_usb_a0_c0_sda { - gpios = <&gpiob 4 GPIO_INPUT>; - label = "EC_I2C_USB_A0_C0_SDA"; - }; - ec_i2c_usb_a1_c1_scl { - gpios = <&gpio9 0 GPIO_INPUT>; - label = "EC_I2C_USB_A1_C1_SCL"; - }; - ec_i2c_usb_a1_c1_sda { - gpios = <&gpio8 7 GPIO_INPUT>; - label = "EC_I2C_USB_A1_C1_SDA"; - }; - ec_i2c_batt_scl { - gpios = <&gpio9 2 GPIO_INPUT>; - label = "EC_I2C_BATT_SCL"; - }; - ec_i2c_batt_sda { - gpios = <&gpio9 1 GPIO_INPUT>; - label = "EC_I2C_BATT_SDA"; - }; - ec_i2c_usbc_mux_scl { - gpios = <&gpiod 1 GPIO_INPUT>; - label = "EC_I2C_USBC_MUX_SCL"; - }; - ec_i2c_usbc_mux_sda { - gpios = <&gpiod 0 GPIO_INPUT>; - label = "EC_I2C_USBC_MUX_SDA"; - }; - ec_i2c_power_scl { - gpios = <&gpiof 3 GPIO_INPUT>; - label = "EC_I2C_POWER_SCL"; - }; - ec_i2c_power_sda { - gpios = <&gpiof 2 GPIO_INPUT>; - label = "EC_I2C_POWER_SDA"; - }; - ec_i2c_cbi_scl { - gpios = <&gpio3 3 GPIO_INPUT>; - label = "EC_I2C_CBI_SCL"; - }; - ec_i2c_cbi_sda { - gpios = <&gpio3 6 GPIO_INPUT>; - label = "EC_I2C_CBI_SDA"; - }; - ec_i2c_sensor_scl { - gpios = <&gpioe 4 GPIO_INPUT>; - label = "EC_I2C_SENSOR_SCL"; - }; - ec_i2c_sensor_sda { - gpios = <&gpioe 3 GPIO_INPUT>; - label = "EC_I2C_SENSOR_SDA"; - }; - ec_i2c_soc_sic { - gpios = <&gpiob 3 GPIO_INPUT>; - label = "EC_I2C_SOC_SIC"; - }; - ec_i2c_soc_sid { - gpios = <&gpiob 2 GPIO_INPUT>; - label = "EC_I2C_SOC_SID"; - }; - en_kb_bl { - gpios = <&gpio9 7 GPIO_OUT_HIGH>; - label = "EN_KB_BL"; - }; - ec_kso_02_inv { - gpios = <&gpio1 7 GPIO_OUT_LOW>; - label = "EC_KSO_02_INV"; - enum-name = "GPIO_KBD_KSO2"; - }; - ec_espi_rst_l { - gpios = <&gpio5 4 GPIO_PULL_UP>; - label = "EC_ESPI_RST_L"; - }; - 6axis_int_l { - gpios = <&gpioa 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "6AXIS_INT_L"; - }; - tablet_mode { - gpios = <&gpioc 1 GPIO_INPUT>; - label = "TABLET_MODE"; - }; - ec_gpio56 { - gpios = <&gpio5 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIO56"; - }; - ec_ps2_clk { - gpios = <&gpio6 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_CLK"; - }; - ec_ps2_dat { - gpios = <&gpio7 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_DAT"; - }; - ec_ps2_rst { - gpios = <&gpio6 2 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_RST"; - }; - ec_gpiob0 { - gpios = <&gpiob 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIOB0"; - }; - ec_gpio81 { - gpios = <&gpio8 1 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIO81"; - }; - ec_flprg2 { - gpios = <&gpio8 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_FLPRG2"; - }; - ec_psl_gpo { - gpios = <&gpiod 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PSL_GPO"; - }; - ec_pwm7 { - gpios = <&gpio6 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PWM7"; - }; - }; -}; diff --git a/zephyr/projects/corsola/kingler/i2c.dts b/zephyr/projects/corsola/kingler/i2c.dts deleted file mode 100644 index 699c4b9b7b..0000000000 --- a/zephyr/projects/corsola/kingler/i2c.dts +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/ { - aliases { - i2c-0 = &i2c0_0; - i2c-1 = &i2c1_0; - i2c-2 = &i2c2_0; - i2c-3 = &i2c3_0; - i2c-4 = &i2c4_1; - i2c-5 = &i2c5_0; - i2c-7 = &i2c7_0; - }; - - named-i2c-ports { - compatible = "named-i2c-ports"; - - battery { - i2c-port = <&i2c2_0>; - remote-port = <0>; - enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; - }; - }; - - -}; - -&i2c2_0 { - status = "okay"; - clock-frequency = <I2C_BITRATE_STANDARD>; -}; - -&i2c_ctrl2 { - status = "okay"; -}; diff --git a/zephyr/projects/corsola/kingler/prj.conf b/zephyr/projects/corsola/kingler/prj.conf deleted file mode 100644 index d09697de5d..0000000000 --- a/zephyr/projects/corsola/kingler/prj.conf +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -CONFIG_CROS_EC=y -CONFIG_PLATFORM_EC=y -CONFIG_SHIMMED_TASKS=y -CONFIG_ESPI=y - -# Shell features -CONFIG_SHELL_HELP=y -CONFIG_SHELL_HISTORY=y -CONFIG_SHELL_TAB_AUTOCOMPLETION=y -CONFIG_KERNEL_SHELL=y - -CONFIG_PLATFORM_EC_VBOOT_EFS2=n - -# Power sequencing -CONFIG_AP=y - -# Power button -CONFIG_PLATFORM_EC_POWER_BUTTON=y - -# External power -CONFIG_PLATFORM_EC_HOSTCMD=y -CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y -CONFIG_PLATFORM_EC_BACKLIGHT_LID=n - -# Lid switch -CONFIG_PLATFORM_EC_LID_SWITCH=y - -# Keyboard -CONFIG_PLATFORM_EC_KEYBOARD=y -CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y -CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y - -CONFIG_SYSCON=y - -# Battery -CONFIG_PLATFORM_EC_BATTERY=y -CONFIG_PLATFORM_EC_BATTERY_SMART=y -CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y -CONFIG_PLATFORM_EC_BATTERY_CUT_OFF=n -CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y - -CONFIG_PLATFORM_EC_CHARGER=n -CONFIG_PLATFORM_EC_USBC=n - -# This is not yet supported -CONFIG_PLATFORM_EC_ADC=n -CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n -CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n diff --git a/zephyr/projects/corsola/krabby/CMakeLists.txt b/zephyr/projects/corsola/krabby/CMakeLists.txt deleted file mode 100644 index dd59e4e2fb..0000000000 --- a/zephyr/projects/corsola/krabby/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2021 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -cmake_minimum_required(VERSION 3.13.1) -add_compile_definitions(BOARD_KRABBY) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(krabby) - -zephyr_library_include_directories(include) - -set(PLATFORM_EC_BASEBOARD "${PLATFORM_EC}/baseboard/corsola" CACHE PATH - "Path to the platform/ec baseboard directory") -set(PLATFORM_EC_BOARD "${PLATFORM_EC}/board/krabby" CACHE PATH - "Path to the platform/ec board directory") - -# Include selected EC source from the baseboard -zephyr_library_sources( - "${PLATFORM_EC_BASEBOARD}/board_chipset.c" - "${PLATFORM_EC_BASEBOARD}/board_id.c" - "${PLATFORM_EC_BASEBOARD}/hibernate.c" - "${PLATFORM_EC_BASEBOARD}/regulator.c" - "${PLATFORM_EC_BASEBOARD}/usbc_config.c" - "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c") - -# Include selected EC source from the board -zephyr_library_sources( - "${PLATFORM_EC_BOARD}/hooks.c" - "${PLATFORM_EC_BOARD}/led.c") - -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C - "src/i2c.c") diff --git a/zephyr/projects/corsola/krabby/include/gpio_map.h b/zephyr/projects/corsola/krabby/include/gpio_map.h deleted file mode 100644 index 9122c85ffc..0000000000 --- a/zephyr/projects/corsola/krabby/include/gpio_map.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef __ZEPHYR_GPIO_MAP_H -#define __ZEPHYR_GPIO_MAP_H - -#include <devicetree.h> -#include <gpio_signal.h> - -#define GPIO_ENTERING_RW GPIO_UNIMPLEMENTED -#define GPIO_WP_L GPIO_UNIMPLEMENTED - -#ifdef CONFIG_PLATFORM_EC_GMR_TABLET_MODE -#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L -#endif - -/* TODO: remove after icm426xx driver added */ -static inline void motion_interrupt(enum gpio_signal signal) -{ -} - -/* - * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. - * - * Each GPIO_INT requires three parameters: - * gpio_signal - The enum gpio_signal for the interrupt gpio - * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH) - * handler - The platform/ec interrupt handler. - * - * Ensure that this files includes all necessary headers to declare all - * referenced handler functions. - * - * For example, one could use the follow definition: - * #define EC_CROS_GPIO_INTERRUPTS \ - * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print) - */ -#define EC_CROS_GPIO_INTERRUPTS \ - GPIO_INT(GPIO_POWER_BUTTON_L, \ - GPIO_INT_EDGE_BOTH, power_button_interrupt) \ - GPIO_INT(GPIO_LID_OPEN, \ - GPIO_INT_EDGE_BOTH, lid_interrupt) \ - GPIO_INT(GPIO_TABLET_MODE_L, \ - GPIO_INT_EDGE_BOTH, gmr_tablet_switch_isr) \ - GPIO_INT(GPIO_AP_EC_WARM_RST_REQ, \ - GPIO_INT_EDGE_RISING, chipset_reset_request_interrupt) \ - GPIO_INT(GPIO_AP_IN_SLEEP_L, \ - GPIO_INT_EDGE_BOTH, power_signal_interrupt) \ - GPIO_INT(GPIO_BASE_IMU_INT_L, \ - GPIO_INT_EDGE_FALLING, motion_interrupt) \ - GPIO_INT(GPIO_LID_ACCEL_INT_L, \ - GPIO_INT_EDGE_FALLING, lis2dw12_interrupt) \ - GPIO_INT(GPIO_VOLUME_DOWN_L, \ - GPIO_INT_EDGE_BOTH, button_interrupt) \ - GPIO_INT(GPIO_VOLUME_UP_L, \ - GPIO_INT_EDGE_BOTH, button_interrupt) \ - GPIO_INT(GPIO_AP_XHCI_INIT_DONE, \ - GPIO_INT_EDGE_BOTH, usb_a0_interrupt) \ - GPIO_INT(GPIO_AC_PRESENT, \ - GPIO_INT_EDGE_BOTH, extpower_interrupt) \ - GPIO_INT(GPIO_WP, \ - GPIO_INT_EDGE_BOTH, switch_interrupt) \ - GPIO_INT(GPIO_SPI0_CS, \ - GPIO_INT_EDGE_FALLING, spi_event) \ - GPIO_INT(GPIO_X_EC_GPIO2, \ - GPIO_INT_EDGE_BOTH, x_ec_interrupt) - -#endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/projects/corsola/krabby/motionsense.dts b/zephyr/projects/corsola/motionsense_krabby.dts index 00434e6be9..00434e6be9 100644 --- a/zephyr/projects/corsola/krabby/motionsense.dts +++ b/zephyr/projects/corsola/motionsense_krabby.dts diff --git a/zephyr/projects/corsola/power_signal.dts b/zephyr/projects/corsola/power_signal.dts new file mode 100644 index 0000000000..2603a53bb4 --- /dev/null +++ b/zephyr/projects/corsola/power_signal.dts @@ -0,0 +1,26 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + power_signal_list: power-signal-list { + compatible = "mt8186,power-signal-list"; + ap_in_rst { + power-enum-name = "AP_IN_RST"; + power-gpio-pin = <&ap_sysrst_odl_r>; + }; + ap_in_s3 { + power-enum-name = "AP_IN_S3"; + power-gpio-pin = <&ap_in_sleep_l>; + }; + ap_wdt_asserted { + power-enum-name = "AP_WDT_ASSERTED"; + power-gpio-pin = <&ap_ec_wdtrst_l>; + }; + ap_warm_rst_req { + power-enum-name = "AP_WARM_RST_REQ"; + power-gpio-pin = <&ap_ec_warm_rst_req>; + }; + }; +}; diff --git a/zephyr/shim/chip/posix/CMakeLists.txt b/zephyr/projects/corsola/prj.conf index 70e8b6269a..80f1d03d96 100644 --- a/zephyr/shim/chip/posix/CMakeLists.txt +++ b/zephyr/projects/corsola/prj.conf @@ -1,5 +1,3 @@ # Copyright 2021 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI espi.c)
\ No newline at end of file diff --git a/zephyr/projects/corsola/prj_kingler.conf b/zephyr/projects/corsola/prj_kingler.conf new file mode 100644 index 0000000000..d86036816c --- /dev/null +++ b/zephyr/projects/corsola/prj_kingler.conf @@ -0,0 +1,75 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Cros EC +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_PLATFORM_EC_BRINGUP=y +CONFIG_SHIMMED_TASKS=y +CONFIG_PLATFORM_EC_SWITCH=y + +# Variant config +CONFIG_BOARD_KINGLER=y +CONFIG_VARIANT_CORSOLA_DB_DETECTION=n +CONFIG_VARIANT_CORSOLA_USBA=n + +# Shell features +CONFIG_KERNEL_SHELL=y +CONFIG_SHELL_HELP=y +CONFIG_SHELL_TAB=y +CONFIG_SHELL_TAB_AUTOCOMPLETION=y +CONFIG_SHELL_HISTORY=y + +# Bring up options +CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y + +CONFIG_PLATFORM_EC_VBOOT_EFS2=n + +# ADC +CONFIG_ADC=y +CONFIG_PLATFORM_EC_ADC=y + +# CBI +CONFIG_PLATFORM_EC_CBI_EEPROM=y +CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=y + +# Host command +CONFIG_PLATFORM_EC_HOSTCMD=y + +# I2C +CONFIG_I2C=y +CONFIG_PLATFORM_EC_I2C=y + +# Power sequencing +CONFIG_AP=y +CONFIG_AP_ARM_MTK_MT8186=y +CONFIG_PLATFORM_EC_POWERSEQ_MT8186=y + +# Treat 2nd reset from H1 as Power-On +CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y +CONFIG_PLATFORM_EC_POWERSEQ=y +CONFIG_PLATFORM_EC_POWERSEQ_S4=n +CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n + +# Button +CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y + +# Sensors +CONFIG_PLATFORM_EC_LID_SWITCH=y + +# External power +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n +CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y + +# Keyboard +CONFIG_PLATFORM_EC_KEYBOARD=n +CONFIG_CROS_KB_RAW_NPCX=n + +CONFIG_SYSCON=y + +CONFIG_PLATFORM_EC_CHARGER=n +CONFIG_PLATFORM_EC_USBC=n + +CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n diff --git a/zephyr/projects/corsola/krabby/prj.conf b/zephyr/projects/corsola/prj_krabby.conf index ad86923679..0a3ddcaf6e 100644 --- a/zephyr/projects/corsola/krabby/prj.conf +++ b/zephyr/projects/corsola/prj_krabby.conf @@ -6,10 +6,26 @@ CONFIG_CROS_EC=y CONFIG_PLATFORM_EC=y CONFIG_SHIMMED_TASKS=y +CONFIG_BOARD_KRABBY=y + +# AP SoC configuration +CONFIG_AP=y +CONFIG_AP_ARM_MTK_MT8186=y + # Bring up options CONFIG_KERNEL_SHELL=y CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y -CONFIG_GPIO_EMUL=y +CONFIG_PLATFORM_EC_BRINGUP=y + +# Power Sequencing +CONFIG_PLATFORM_EC_POWERSEQ=y +CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y +CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n +CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y +CONFIG_PLATFORM_EC_CHIPSET_RESET_HOOK=y + +# Lid Switch +CONFIG_PLATFORM_EC_LID_SWITCH=y # Battery CONFIG_PLATFORM_EC_BATTERY=y @@ -26,7 +42,6 @@ CONFIG_PLATFORM_EC_CHARGE_MANAGER=y CONFIG_PLATFORM_EC_CHARGE_RAMP_HW=y CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC=y CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC_CHARGER=y -CONFIG_PLATFORM_EC_CHARGER_ISL9238C=y CONFIG_PLATFORM_EC_CHARGER_MAINTAIN_VBAT=y CONFIG_PLATFORM_EC_CHARGER_OTG=y CONFIG_PLATFORM_EC_CHARGER_PSYS=y @@ -42,7 +57,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_ADC_AMON_BMON=y CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y -CONFIG_PLATFORM_EC_HOSTCMD_REGULATOR=y CONFIG_PLATFORM_EC_HOST_COMMAND_STATUS=y # LED @@ -51,6 +65,8 @@ CONFIG_PLATFORM_EC_LED_ONOFF_STATES=y CONFIG_PLATFORM_EC_LED_ONOFF_STATES_BAT_LOW=10 # MKBP event mask +CONFIG_PLATFORM_EC_MKBP_EVENT=y +CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y CONFIG_PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK=y CONFIG_PLATFORM_EC_MKBP_HOST_EVENT_WAKEUP_MASK=y CONFIG_PLATFORM_EC_MKBP_USE_GPIO=y @@ -85,7 +101,6 @@ CONFIG_PLATFORM_EC_USB_A_PORT_COUNT=1 # USB-C CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y -CONFIG_PLATFORM_EC_BC12_DETECT_MT6360=y CONFIG_PLATFORM_EC_BC12_SINGLE_DRIVER=n CONFIG_PLATFORM_EC_SMBUS_PEC=y CONFIG_PLATFORM_EC_USBC_PPC_DEDICATED_INT=y diff --git a/zephyr/projects/corsola/krabby/pwm.dts b/zephyr/projects/corsola/pwm_krabby.dts index f86448cc8e..40eb8f5048 100644 --- a/zephyr/projects/corsola/krabby/pwm.dts +++ b/zephyr/projects/corsola/pwm_krabby.dts @@ -7,26 +7,23 @@ named-pwms { compatible = "named-pwms"; /* NOTE: &pwm number needs same with channel number */ - led1: led1 { + led1: ec_led1_odl { #pwm-cells = <0>; pwms = <&pwm0 PWM_CHANNEL_0 PWM_POLARITY_INVERTED>; - label = "LED1"; /* * If we need pwm output in ITE chip power saving * mode, then we should set frequency <=324Hz. */ frequency = <324>; }; - led2: led2 { + led2: ec_led2_odl { #pwm-cells = <0>; pwms = <&pwm1 PWM_CHANNEL_1 PWM_POLARITY_INVERTED>; - label = "LED2"; frequency = <324>; }; - led3: led3 { + led3: ec_led3_odl { #pwm-cells = <0>; pwms = <&pwm2 PWM_CHANNEL_2 PWM_POLARITY_INVERTED>; - label = "LED3"; frequency = <324>; }; }; diff --git a/baseboard/corsola/board_chipset.c b/zephyr/projects/corsola/src/board_chipset.c index 7e06a49792..7e06a49792 100644 --- a/baseboard/corsola/board_chipset.c +++ b/zephyr/projects/corsola/src/board_chipset.c diff --git a/baseboard/corsola/hibernate.c b/zephyr/projects/corsola/src/hibernate.c index c3752358bf..c3752358bf 100644 --- a/baseboard/corsola/hibernate.c +++ b/zephyr/projects/corsola/src/hibernate.c diff --git a/board/kingler/battery.c b/zephyr/projects/corsola/src/krabby/battery.c index f07c38e1b8..f07c38e1b8 100644 --- a/board/kingler/battery.c +++ b/zephyr/projects/corsola/src/krabby/battery.c diff --git a/board/krabby/hooks.c b/zephyr/projects/corsola/src/krabby/hooks.c index cea6667650..cea6667650 100644 --- a/board/krabby/hooks.c +++ b/zephyr/projects/corsola/src/krabby/hooks.c diff --git a/zephyr/projects/corsola/krabby/src/i2c.c b/zephyr/projects/corsola/src/krabby/i2c.c index 12f626847c..12f626847c 100644 --- a/zephyr/projects/corsola/krabby/src/i2c.c +++ b/zephyr/projects/corsola/src/krabby/i2c.c diff --git a/board/krabby/led.c b/zephyr/projects/corsola/src/krabby/led.c index 1d3108c47b..d07ec46004 100644 --- a/board/krabby/led.c +++ b/zephyr/projects/corsola/src/krabby/led.c @@ -8,7 +8,6 @@ #include "led_common.h" #include "led_onoff_states.h" #include "chipset.h" -#include "driver/bc12/mt6360.h" __override const int led_charge_lvl_1 = 5; __override const int led_charge_lvl_2 = 95; @@ -49,42 +48,14 @@ const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); __override void led_set_color_battery(enum ec_led_colors color) { - mt6360_led_set_brightness(MT6360_LED_RGB2, 50); - mt6360_led_set_brightness(MT6360_LED_RGB3, 50); - - switch (color) { - case EC_LED_COLOR_AMBER: - mt6360_led_enable(MT6360_LED_RGB2, 0); - mt6360_led_enable(MT6360_LED_RGB3, 1); - break; - case EC_LED_COLOR_WHITE: - mt6360_led_enable(MT6360_LED_RGB2, 1); - mt6360_led_enable(MT6360_LED_RGB3, 0); - break; - default: /* LED_OFF and other unsupported colors */ - mt6360_led_enable(MT6360_LED_RGB2, 0); - mt6360_led_enable(MT6360_LED_RGB3, 0); - break; - } } __override void led_set_color_power(enum ec_led_colors color) { - mt6360_led_set_brightness(MT6360_LED_RGB1, 1); - mt6360_led_enable(MT6360_LED_RGB1, color == EC_LED_COLOR_WHITE); } void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { - if (led_id == EC_LED_ID_BATTERY_LED) { - brightness_range[EC_LED_COLOR_AMBER] = - MT6360_LED_BRIGHTNESS_MAX; - brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - } else if (led_id == EC_LED_ID_POWER_LED) { - brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) diff --git a/zephyr/projects/corsola/src/krabby/usb_pd_policy.c b/zephyr/projects/corsola/src/krabby/usb_pd_policy.c new file mode 100644 index 0000000000..8d28364664 --- /dev/null +++ b/zephyr/projects/corsola/src/krabby/usb_pd_policy.c @@ -0,0 +1,89 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "adc.h" +#include "charge_manager.h" +#include "chipset.h" +#include "usb_charge.h" +#include "usb_pd.h" +#include "usbc_ppc.h" + +int pd_snk_is_vbus_provided(int port) +{ + static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; + int vbus; + + /* + * (b:181203590#comment20) TODO(yllin): use + * PD_VSINK_DISCONNECT_PD for non-5V case. + */ + vbus = adc_read_channel(board_get_vbus_adc(port)) >= + PD_V_SINK_DISCONNECT_MAX; + +#ifdef CONFIG_USB_CHARGER + /* + * There's no PPC to inform VBUS change for usb_charger, so inform + * the usb_charger now. + */ + if (!!(vbus_prev[port] != vbus)) + usb_charger_vbus_change(port, vbus); + + if (vbus) + atomic_or(&vbus_prev[port], 1); + else + atomic_clear(&vbus_prev[port]); +#endif + return vbus; +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + prev_en = ppc_is_sourcing_vbus(port); + + /* Disable VBUS. */ + 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); +} + +int pd_check_vconn_swap(int port) +{ + /* Allow Vconn swap if AP is on. */ + return chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_ON); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + /* Disable charging. */ + rv = ppc_vbus_sink_enable(port, 0); + if (rv) + return rv; + + pd_set_vbus_discharge(port, 0); + + /* Provide Vbus. */ + 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); + + return EC_SUCCESS; +} + +int board_vbus_source_enabled(int port) +{ + return ppc_is_sourcing_vbus(port); +} diff --git a/baseboard/corsola/usbc_config.c b/zephyr/projects/corsola/src/krabby/usbc_config.c index 30859fdc0d..578881a8ba 100644 --- a/baseboard/corsola/usbc_config.c +++ b/zephyr/projects/corsola/src/krabby/usbc_config.c @@ -3,115 +3,44 @@ * found in the LICENSE file. */ -/* Corsola baseboard-specific USB-C configuration */ +/* Krabby board-specific USB-C configuration */ #include "adc.h" -#include "baseboard_common.h" +#include "baseboard_usbc_config.h" #include "bc12/pi3usb9201_public.h" -#include "bc12/mt6360_public.h" -#include "button.h" +#include "charge_manager.h" #include "charger.h" -#include "charge_state_v2.h" -#include "charger/isl923x_public.h" #include "console.h" -#include "ec_commands.h" -#include "extpower.h" -#include "gpio.h" +#include "driver/tcpm/it83xx_pd.h" +#include "driver/usb_mux/ps8743.h" #include "hooks.h" -#include "i2c.h" -#include "lid_switch.h" -#include "task.h" #include "ppc/syv682x_public.h" -#include "power.h" -#include "power_button.h" -#include "spi.h" -#include "switch.h" -#include "tablet_mode.h" -#include "tcpm/it8xxx2_pd_public.h" -#include "uart.h" -#include "usbc_ppc.h" -#include "usb_charge.h" -#include "usb_mux.h" -#include "usb_mux/ps8743_public.h" #include "usb_mux/it5205_public.h" -#include "usb_pd_tcpm.h" #include "usbc_ppc.h" +#include "variant_db_detection.h" + #define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) #define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) +/* charger */ const struct charger_config_t chg_chips[] = { { .i2c_port = I2C_PORT_CHARGER, - .i2c_addr_flags = ISL923X_ADDR_FLAGS, - .drv = &isl923x_drv, + .i2c_addr_flags = 0, + .drv = NULL, }, }; -/* Baseboard */ - -static void baseboard_init(void) -{ - gpio_enable_interrupt(GPIO_USB_C0_PPC_BC12_INT_ODL); - gpio_enable_interrupt(GPIO_AP_XHCI_INIT_DONE); -} -DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT-1); - -/* Sub-board */ - -enum board_sub_board board_get_sub_board(void) -{ - static enum board_sub_board sub = SUB_BOARD_NONE; - - if (sub != SUB_BOARD_NONE) - return sub; - - /* HDMI board has external pull high. */ - if (gpio_get_level(GPIO_EC_X_GPIO3)) { - sub = SUB_BOARD_HDMI; - /* Only has 1 PPC with HDMI subboard */ - ppc_cnt = 1; - /* EC_X_GPIO1 */ - gpio_set_flags(GPIO_EN_HDMI_PWR, GPIO_OUT_HIGH); - /* X_EC_GPIO2 */ - gpio_set_flags(GPIO_PS185_EC_DP_HPD, GPIO_INT_BOTH); - /* EC_X_GPIO3 */ - gpio_set_flags(GPIO_PS185_PWRDN_ODL, GPIO_ODR_HIGH); - } else { - sub = SUB_BOARD_TYPEC; - /* EC_X_GPIO1 */ - gpio_set_flags(GPIO_USB_C1_FRS_EN, GPIO_OUT_LOW); - /* X_EC_GPIO2 */ - gpio_set_flags(GPIO_USB_C1_PPC_INT_ODL, - GPIO_INT_BOTH | GPIO_PULL_UP); - /* EC_X_GPIO3 */ - gpio_set_flags(GPIO_USB_C1_DP_IN_HPD, GPIO_OUT_LOW); +const struct pi3usb9201_config_t + pi3usb9201_bc12_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { + /* [0]: unused */ + [1] = { + .i2c_port = I2C_PORT_PPC1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, } - - CPRINTS("Detect %s SUB", sub == SUB_BOARD_HDMI ? "HDMI" : "TYPEC"); - return sub; -} - -static void sub_board_init(void) -{ - board_get_sub_board(); -} -DECLARE_HOOK(HOOK_INIT, sub_board_init, HOOK_PRIO_INIT_I2C - 1); - -/* Detect subboard */ -static void board_tcpc_init(void) -{ - /* C1: GPIO_USB_C1_PPC_INT_ODL & HDMI: GPIO_PS185_EC_DP_HPD */ - gpio_enable_interrupt(GPIO_X_EC_GPIO2); - - /* If this is not a Type-C subboard, disable the task. */ - if (board_get_sub_board() != SUB_BOARD_TYPEC) - task_disable_task(TASK_ID_PD_C1); -} -/* Must be done after I2C and subboard */ -DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); - +}; /* PPC */ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { { @@ -129,23 +58,8 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { }; unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); -/* BC12 */ -const struct mt6360_config_t mt6360_config = { - .i2c_port = I2C_PORT_POWER, - .i2c_addr_flags = MT6360_PMU_I2C_ADDR_FLAGS, -}; - -const struct pi3usb9201_config_t - pi3usb9201_bc12_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { - /* [0]: unused */ - [1] = { - .i2c_port = I2C_PORT_PPC1, - .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, - } -}; - struct bc12_config bc12_ports[CONFIG_USB_PD_PORT_MAX_COUNT] = { - { .drv = &mt6360_drv }, + { .drv = NULL }, { .drv = &pi3usb9201_drv }, }; @@ -154,9 +68,10 @@ void bc12_interrupt(enum gpio_signal signal) task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12); } + static void board_sub_bc12_init(void) { - if (board_get_sub_board() == SUB_BOARD_TYPEC) + if (corsola_get_db_type() == CORSOLA_DB_TYPEC) gpio_enable_interrupt(GPIO_USB_C1_BC12_CHARGER_INT_ODL); else /* If this is not a Type-C subboard, disable the task. */ @@ -165,91 +80,11 @@ static void board_sub_bc12_init(void) /* Must be done after I2C and subboard */ DECLARE_HOOK(HOOK_INIT, board_sub_bc12_init, HOOK_PRIO_INIT_I2C + 1); -__override uint8_t board_get_usb_pd_port_count(void) -{ - if (board_get_sub_board() == SUB_BOARD_TYPEC) - return CONFIG_USB_PD_PORT_MAX_COUNT; - else - return CONFIG_USB_PD_PORT_MAX_COUNT - 1; -} - -/* USB-A */ -const int usb_port_enable[] = { - GPIO_EN_PP5000_USB_A0_VBUS, -}; -BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT); - -void usb_a0_interrupt(enum gpio_signal signal) -{ - enum usb_charge_mode mode = gpio_get_level(signal) ? - USB_CHARGE_MODE_ENABLED : USB_CHARGE_MODE_DISABLED; - - for (int i = 0; i < USB_PORT_COUNT; i++) - usb_charge_set_mode(i, mode, USB_ALLOW_SUSPEND_CHARGE); -} - -static int board_ps8743_mux_set(const struct usb_mux *me, - mux_state_t mux_state) -{ - int rv = EC_SUCCESS; - int reg = 0; - - rv = ps8743_read(me, PS8743_REG_MODE, ®); - if (rv) - return rv; - - /* Disable FLIP pin, enable I2C control. */ - reg |= PS8743_MODE_FLIP_REG_CONTROL; - /* Disable CE_USB pin, enable I2C control. */ - reg |= PS8743_MODE_USB_REG_CONTROL; - /* Disable CE_DP pin, enable I2C control. */ - reg |= PS8743_MODE_DP_REG_CONTROL; - - /* - * DP specific config - * - * Enable/Disable IN_HPD on the DB. - */ - gpio_set_level(GPIO_USB_C1_DP_IN_HPD, - mux_state & USB_PD_MUX_DP_ENABLED); - - return ps8743_write(me, PS8743_REG_MODE, reg); -} - -const struct usb_mux usbc0_virtual_mux = { - .usb_port = 0, - .driver = &virtual_usb_mux_driver, - .hpd_update = &virtual_hpd_update, -}; - -const struct usb_mux usbc1_virtual_mux = { - .usb_port = 1, - .driver = &virtual_usb_mux_driver, - .hpd_update = &virtual_hpd_update, -}; - -const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { - { - .usb_port = 0, - .i2c_port = I2C_PORT_USB_MUX0, - .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS, - .driver = &it5205_usb_mux_driver, - .next_mux = &usbc0_virtual_mux, - }, - { - .usb_port = 1, - .i2c_port = I2C_PORT_USB_MUX1, - .i2c_addr_flags = PS8743_I2C_ADDR0_FLAG, - .driver = &ps8743_usb_mux_driver, - .next_mux = &usbc1_virtual_mux, - .board_set = &board_ps8743_mux_set, - }, -}; - -void board_overcurrent_event(int port, int is_overcurrented) +static void board_usbc_init(void) { - /* TODO: check correct operation for Corsola */ + gpio_enable_interrupt(GPIO_USB_C0_PPC_BC12_INT_ODL); } +DECLARE_HOOK(HOOK_INIT, board_usbc_init, HOOK_PRIO_DEFAULT-1); /* TCPC */ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { @@ -269,6 +104,57 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { }, }; +void board_usb_mux_init(void) +{ + if (corsola_get_db_type() == CORSOLA_DB_TYPEC) { + ps8743_tune_usb_eq(&usb_muxes[1], + PS8743_USB_EQ_TX_12_8_DB, + PS8743_USB_EQ_RX_12_8_DB); + ps8743_write(&usb_muxes[1], + PS8743_REG_HS_DET_THRESHOLD, + PS8743_USB_HS_THRESH_NEG_10); + } +} +DECLARE_HOOK(HOOK_INIT, board_usb_mux_init, HOOK_PRIO_INIT_I2C + 1); + +void ppc_interrupt(enum gpio_signal signal) +{ + if (signal == GPIO_USB_C1_PPC_INT_ODL) + syv682x_interrupt(1); +} + +int ppc_get_alert_status(int port) +{ + if (port == 0) + return gpio_get_level(GPIO_USB_C0_PPC_BC12_INT_ODL) == 0; + if (port == 1 && corsola_get_db_type() == CORSOLA_DB_TYPEC) + return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0; + + return 0; +} + +const struct cc_para_t *board_get_cc_tuning_parameter(enum usbpd_port port) +{ + const static struct cc_para_t + cc_parameter[CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT] = { + { + .rising_time = IT83XX_TX_PRE_DRIVING_TIME_1_UNIT, + .falling_time = IT83XX_TX_PRE_DRIVING_TIME_2_UNIT, + }, + { + .rising_time = IT83XX_TX_PRE_DRIVING_TIME_1_UNIT, + .falling_time = IT83XX_TX_PRE_DRIVING_TIME_2_UNIT, + }, + }; + + return &cc_parameter[port]; +} + +void board_overcurrent_event(int port, int is_overcurrented) +{ + /* TODO: check correct operation for Corsola */ +} + uint16_t tcpc_get_alert_status(void) { /* @@ -286,27 +172,10 @@ void board_reset_pd_mcu(void) */ } -void board_set_charge_limit(int port, int supplier, int charge_ma, - int max_ma, int charge_mv) -{ - charge_set_input_current_limit( - MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); -} - -void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int 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. - */ -} - int board_set_active_charge_port(int port) { int i; - int is_valid_port = port == 0 || (port == 1 && board_get_sub_board() == - SUB_BOARD_TYPEC); + int is_valid_port = (port >= 0 && port < board_get_usb_pd_port_count()); if (!is_valid_port && port != CHARGE_PORT_NONE) return EC_ERROR_INVAL; @@ -356,57 +225,64 @@ int board_set_active_charge_port(int port) return EC_SUCCESS; } -/** - * Handle PS185 HPD changing state. - */ -int debounced_hpd; - -static void ps185_hdmi_hpd_deferred(void) -{ - const int new_hpd = gpio_get_level(GPIO_PS185_EC_DP_HPD); - - /* HPD status not changed, probably a glitch, just return. */ - if (debounced_hpd == new_hpd) - return; - - debounced_hpd = new_hpd; - - gpio_set_level(GPIO_EC_AP_DP_HPD_ODL, !debounced_hpd); - CPRINTS(debounced_hpd ? "HDMI plug" : "HDMI unplug"); -} -DECLARE_DEFERRED(ps185_hdmi_hpd_deferred); +const struct usb_mux usbc0_virtual_mux = { + .usb_port = 0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; -#define PS185_HPD_DEBOUCE 250 +const struct usb_mux usbc1_virtual_mux = { + .usb_port = 1, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, +}; -static void hdmi_hpd_interrupt(enum gpio_signal signal) +static int board_ps8743_mux_set(const struct usb_mux *me, + mux_state_t mux_state) { - hook_call_deferred(&ps185_hdmi_hpd_deferred_data, PS185_HPD_DEBOUCE); -} + int rv = EC_SUCCESS; + int reg = 0; -/* HDMI/TYPE-C function shared subboard interrupt */ -void x_ec_interrupt(enum gpio_signal signal) -{ - int sub = board_get_sub_board(); + rv = ps8743_read(me, PS8743_REG_MODE, ®); + if (rv) + return rv; - if (sub == SUB_BOARD_TYPEC) - /* C1: PPC interrupt */ - syv682x_interrupt(1); - else if (sub == SUB_BOARD_HDMI) - hdmi_hpd_interrupt(signal); - else - CPRINTS("Undetected subboard interrupt."); -} + /* Disable FLIP pin, enable I2C control. */ + reg |= PS8743_MODE_FLIP_REG_CONTROL; + /* Disable CE_USB pin, enable I2C control. */ + reg |= PS8743_MODE_USB_REG_CONTROL; + /* Disable CE_DP pin, enable I2C control. */ + reg |= PS8743_MODE_DP_REG_CONTROL; -int ppc_get_alert_status(int port) -{ - if (port == 0) - return gpio_get_level(GPIO_USB_C0_PPC_BC12_INT_ODL) == 0; - if (port == 1 && board_get_sub_board() == SUB_BOARD_TYPEC) - return gpio_get_level(GPIO_USB_C1_PPC_INT_ODL) == 0; + /* + * DP specific config + * + * Enable/Disable IN_HPD on the DB. + */ + gpio_set_level(GPIO_USB_C1_DP_IN_HPD, + mux_state & USB_PD_MUX_DP_ENABLED); - return 0; + return ps8743_write(me, PS8743_REG_MODE, reg); } +const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .usb_port = 0, + .i2c_port = I2C_PORT_USB_MUX0, + .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS, + .driver = &it5205_usb_mux_driver, + .next_mux = &usbc0_virtual_mux, + }, + { + .usb_port = 1, + .i2c_port = I2C_PORT_USB_MUX1, + .i2c_addr_flags = PS8743_I2C_ADDR0_FLAG, + .driver = &ps8743_usb_mux_driver, + .next_mux = &usbc1_virtual_mux, + .board_set = &board_ps8743_mux_set, + }, +}; + #ifdef CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT enum adc_channel board_get_vbus_adc(int port) { diff --git a/baseboard/corsola/regulator.c b/zephyr/projects/corsola/src/regulator.c index 35670bda82..35670bda82 100644 --- a/baseboard/corsola/regulator.c +++ b/zephyr/projects/corsola/src/regulator.c diff --git a/baseboard/corsola/usb_pd_policy.c b/zephyr/projects/corsola/src/usb_pd_policy.c index d0c576a398..54322811a2 100644 --- a/baseboard/corsola/usb_pd_policy.c +++ b/zephyr/projects/corsola/src/usb_pd_policy.c @@ -2,10 +2,8 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#include "adc.h" + #include "atomic.h" -#include "baseboard_common.h" -#include "charge_manager.h" #include "chipset.h" #include "timer.h" #include "usb_dp_alt_mode.h" @@ -152,81 +150,3 @@ __override void svdm_exit_dp_mode(int port) baseboard_mst_enable_control(port, 0); #endif } - -int pd_snk_is_vbus_provided(int port) -{ - static int vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; - int vbus; - - /* - * (b:181203590#comment20) TODO(yllin): use - * PD_VSINK_DISCONNECT_PD for non-5V case. - */ - vbus = adc_read_channel(board_get_vbus_adc(port)) >= - PD_V_SINK_DISCONNECT_MAX; - -#ifdef CONFIG_USB_CHARGER - /* - * There's no PPC to inform VBUS change for usb_charger, so inform - * the usb_charger now. - */ - if (!!(vbus_prev[port] != vbus)) - usb_charger_vbus_change(port, vbus); - - if (vbus) - atomic_or(&vbus_prev[port], 1); - else - atomic_clear(&vbus_prev[port]); -#endif - return vbus; -} - -void pd_power_supply_reset(int port) -{ - int prev_en; - - prev_en = ppc_is_sourcing_vbus(port); - - /* Disable VBUS. */ - 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); -} - -int pd_check_vconn_swap(int port) -{ - /* Allow Vconn swap if AP is on. */ - return chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_ON); -} - -int pd_set_power_supply_ready(int port) -{ - int rv; - - /* Disable charging. */ - rv = ppc_vbus_sink_enable(port, 0); - if (rv) - return rv; - - pd_set_vbus_discharge(port, 0); - - /* Provide Vbus. */ - 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); - - return EC_SUCCESS; -} - -int board_vbus_source_enabled(int port) -{ - return ppc_is_sourcing_vbus(port); -} diff --git a/zephyr/projects/corsola/src/usbc_config.c b/zephyr/projects/corsola/src/usbc_config.c new file mode 100644 index 0000000000..c4917b252d --- /dev/null +++ b/zephyr/projects/corsola/src/usbc_config.c @@ -0,0 +1,135 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Corsola baseboard-specific USB-C configuration */ + +#include "adc.h" +#include "baseboard_usbc_config.h" +#include "button.h" +#include "charger.h" +#include "charge_state_v2.h" +#include "console.h" +#include "ec_commands.h" +#include "extpower.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "lid_switch.h" +#include "task.h" +#include "ppc/syv682x_public.h" +#include "power.h" +#include "power_button.h" +#include "spi.h" +#include "switch.h" +#include "tablet_mode.h" +#include "uart.h" +#include "usb_charge.h" +#include "usb_mux.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" + +#include "variant_db_detection.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) + +/* Baseboard */ +static void baseboard_init(void) +{ + gpio_enable_interrupt(GPIO_AP_XHCI_INIT_DONE); +} +DECLARE_HOOK(HOOK_INIT, baseboard_init, HOOK_PRIO_DEFAULT-1); + +static void board_tcpc_init(void) +{ + /* C1: GPIO_USB_C1_PPC_INT_ODL & HDMI: GPIO_PS185_EC_DP_HPD */ + gpio_enable_interrupt(GPIO_X_EC_GPIO2); + + /* If this is not a Type-C subboard, disable the task. */ + if (corsola_get_db_type() != CORSOLA_DB_TYPEC) + task_disable_task(TASK_ID_PD_C1); +} +/* Must be done after I2C and subboard */ +DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); + +__override uint8_t board_get_usb_pd_port_count(void) +{ + if (corsola_get_db_type() == CORSOLA_DB_TYPEC) + return CONFIG_USB_PD_PORT_MAX_COUNT; + else + return CONFIG_USB_PD_PORT_MAX_COUNT - 1; +} + +/* USB-A */ +const int usb_port_enable[] = { + GPIO_EN_PP5000_USB_A0_VBUS, +}; +BUILD_ASSERT(ARRAY_SIZE(usb_port_enable) == USB_PORT_COUNT); + +void usb_a0_interrupt(enum gpio_signal signal) +{ + enum usb_charge_mode mode = gpio_get_level(signal) ? + USB_CHARGE_MODE_ENABLED : USB_CHARGE_MODE_DISABLED; + + for (int i = 0; i < USB_PORT_COUNT; i++) + usb_charge_set_mode(i, mode, USB_ALLOW_SUSPEND_CHARGE); +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_set_input_current_limit( + MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); +} + +void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int 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. + */ +} + +/** + * Handle PS185 HPD changing state. + */ +int debounced_hpd; + +static void ps185_hdmi_hpd_deferred(void) +{ + const int new_hpd = gpio_get_level(GPIO_PS185_EC_DP_HPD); + + /* HPD status not changed, probably a glitch, just return. */ + if (debounced_hpd == new_hpd) + return; + + debounced_hpd = new_hpd; + + gpio_set_level(GPIO_EC_AP_DP_HPD_ODL, !debounced_hpd); + CPRINTS(debounced_hpd ? "HDMI plug" : "HDMI unplug"); +} +DECLARE_DEFERRED(ps185_hdmi_hpd_deferred); + +#define PS185_HPD_DEBOUCE 250 + +static void hdmi_hpd_interrupt(enum gpio_signal signal) +{ + hook_call_deferred(&ps185_hdmi_hpd_deferred_data, PS185_HPD_DEBOUCE); +} + +/* HDMI/TYPE-C function shared subboard interrupt */ +void x_ec_interrupt(enum gpio_signal signal) +{ + int sub = corsola_get_db_type(); + + if (sub == CORSOLA_DB_TYPEC) + /* C1: PPC interrupt */ + ppc_interrupt(signal); + else if (sub == CORSOLA_DB_HDMI) + hdmi_hpd_interrupt(signal); + else + CPRINTS("Undetected subboard interrupt."); +} diff --git a/zephyr/projects/corsola/src/variant_db_detection.c b/zephyr/projects/corsola/src/variant_db_detection.c new file mode 100644 index 0000000000..340d54a196 --- /dev/null +++ b/zephyr/projects/corsola/src/variant_db_detection.c @@ -0,0 +1,65 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Corsola daughter board detection */ + +#include "console.h" +#include "gpio.h" +#include "hooks.h" + +#include "variant_db_detection.h" + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) + +static void corsola_db_config(enum corsola_db_type type) +{ + switch (type) { + case CORSOLA_DB_HDMI: + /* EC_X_GPIO1 */ + gpio_set_flags(GPIO_EN_HDMI_PWR, GPIO_OUT_HIGH); + /* X_EC_GPIO2 */ + gpio_set_flags(GPIO_PS185_EC_DP_HPD, GPIO_INT_BOTH); + /* EC_X_GPIO3 */ + gpio_set_flags(GPIO_PS185_PWRDN_ODL, GPIO_ODR_HIGH); + return; + case CORSOLA_DB_TYPEC: + /* EC_X_GPIO1 */ + gpio_set_flags(GPIO_USB_C1_FRS_EN, GPIO_OUT_LOW); + /* X_EC_GPIO2 */ + gpio_set_flags(GPIO_USB_C1_PPC_INT_ODL, + GPIO_INT_BOTH | GPIO_PULL_UP); + /* EC_X_GPIO3 */ + gpio_set_flags(GPIO_USB_C1_DP_IN_HPD, GPIO_OUT_LOW); + return; + default: + break; + + } +} + +enum corsola_db_type corsola_get_db_type(void) +{ + static enum corsola_db_type db = CORSOLA_DB_NONE; + + if (db != CORSOLA_DB_NONE) + return db; + + if (!gpio_get_level(GPIO_HDMI_PRSNT_ODL)) + db = CORSOLA_DB_HDMI; + else + db = CORSOLA_DB_TYPEC; + + corsola_db_config(db); + + CPRINTS("Detect %s DB", db == CORSOLA_DB_HDMI ? "HDMI" : "TYPEC"); + return db; +} + +static void corsola_db_init(void) +{ + corsola_get_db_type(); +} +DECLARE_HOOK(HOOK_INIT, corsola_db_init, HOOK_PRIO_INIT_I2C - 1); diff --git a/zephyr/projects/corsola/krabby/BUILD.py b/zephyr/projects/drawcia_riscv/BUILD.py index e533544d8c..ef839c0927 100644 --- a/zephyr/projects/corsola/krabby/BUILD.py +++ b/zephyr/projects/drawcia_riscv/BUILD.py @@ -2,15 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Reworked drawcia with RISCV ITE EC + register_binman_project( - project_name="krabby", + project_name="drawcia_riscv", zephyr_board="it8xxx2", - dts_overlays=[ - "adc.dts", - "battery.dts", - "gpio.dts", - "i2c.dts", - "motionsense.dts", - "pwm.dts", - ], + dts_overlays=["gpio.dts"], ) diff --git a/zephyr/projects/corsola/kingler/CMakeLists.txt b/zephyr/projects/drawcia_riscv/CMakeLists.txt index 33e56afc0e..5a80325e31 100644 --- a/zephyr/projects/corsola/kingler/CMakeLists.txt +++ b/zephyr/projects/drawcia_riscv/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(kingler) zephyr_library_include_directories(include) + +project(drawcia_riscv) diff --git a/zephyr/projects/drawcia_riscv/Kconfig b/zephyr/projects/drawcia_riscv/Kconfig new file mode 100644 index 0000000000..de87f7973e --- /dev/null +++ b/zephyr/projects/drawcia_riscv/Kconfig @@ -0,0 +1,12 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config BOARD_DRAWCIA_RISCV + bool "Google Drawcia Board" + help + Build reworked Google Drawcia reference board with ITE81302. + This chip is a pin-compatible chip for the existing EC, but + is the RISCV version. + +source "Kconfig.zephyr" diff --git a/zephyr/projects/drawcia_riscv/gpio.dts b/zephyr/projects/drawcia_riscv/gpio.dts new file mode 100644 index 0000000000..2aeb4bdca7 --- /dev/null +++ b/zephyr/projects/drawcia_riscv/gpio.dts @@ -0,0 +1,67 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/gpio_defines.h> + +/ { + named-gpios { + compatible = "named-gpios"; + + ec_wp_od { + gpios = <&gpioa 6 GPIO_INPUT>; + enum-name = "GPIO_WP_L"; + }; + ec_entering_rw { + gpios = <&gpiog 0 GPIO_OUTPUT_LOW>; + enum-name = "GPIO_ENTERING_RW"; + }; + h1_ec_pwr_btn_odl { + gpios = <&gpioe 2 GPIO_INPUT>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + lid_open { + gpios = <&gpiof 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + ec_ap_mkbp_int_l { + gpios = <&gpiol 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + eeprom { + i2c-port = <&i2c0>; + enum-name = "I2C_PORT_EEPROM"; + }; + i2c_sensor: sensor { + i2c-port = <&i2c2>; + enum-name = "I2C_PORT_SENSOR"; + }; + }; + named-pwms { + compatible = "named-pwms"; + }; + +}; + +&i2c0 { + /* I2C_PORT_EEPROM */ + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c2 { + /* I2C_PORT_SENSOR */ + status = "okay"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm0 { + status = "okay"; + prescaler-cx = <PWM_PRESCALER_C4>; +}; diff --git a/zephyr/projects/corsola/kingler/include/gpio_map.h b/zephyr/projects/drawcia_riscv/include/gpio_map.h index 025bb78743..51f270bd4a 100644 --- a/zephyr/projects/corsola/kingler/include/gpio_map.h +++ b/zephyr/projects/drawcia_riscv/include/gpio_map.h @@ -9,6 +9,9 @@ #include <devicetree.h> #include <gpio_signal.h> +#define GPIO_AC_PRESENT GPIO_UNIMPLEMENTED +#define GPIO_ENABLE_BACKLIGHT GPIO_UNIMPLEMENTED + /* * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. * diff --git a/zephyr/projects/drawcia_riscv/prj.conf b/zephyr/projects/drawcia_riscv/prj.conf new file mode 100644 index 0000000000..813454f875 --- /dev/null +++ b/zephyr/projects/drawcia_riscv/prj.conf @@ -0,0 +1,39 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_SHIMMED_TASKS=y + +CONFIG_BOARD_DRAWCIA_RISCV=y +CONFIG_AP=n +CONFIG_PLATFORM_EC_POWERSEQ=n +CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=n +CONFIG_PLATFORM_EC_LID_SWITCH=y + +# Bring up options +CONFIG_KERNEL_SHELL=y +CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y + +# Host Commands +CONFIG_PLATFORM_EC_HOSTCMD=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y +CONFIG_PLATFORM_EC_HOST_COMMAND_STATUS=y + +# VBoot without EFS2 +CONFIG_PLATFORM_EC_VBOOT_EFS2=n +CONFIG_PLATFORM_EC_VBOOT_HASH=y + +# MKBP event mask +CONFIG_PLATFORM_EC_MKBP_EVENT=y +CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y +CONFIG_PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK=y +CONFIG_PLATFORM_EC_MKBP_HOST_EVENT_WAKEUP_MASK=y +CONFIG_PLATFORM_EC_MKBP_USE_GPIO=y + +# Keyboard +CONFIG_PLATFORM_EC_KEYBOARD=y +CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=y +CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y +CONFIG_PLATFORM_EC_CMD_BUTTON=y diff --git a/zephyr/projects/guybrush/gpio.dts b/zephyr/projects/guybrush/gpio.dts deleted file mode 100644 index 8781885759..0000000000 --- a/zephyr/projects/guybrush/gpio.dts +++ /dev/null @@ -1,349 +0,0 @@ -/ { - named-gpios { - compatible = "named-gpios"; - - ec_wp_l { - gpios = <&gpio5 0 GPIO_INPUT>; - label = "EC_WP_L"; - enum-name = "GPIO_WP_L"; - }; - ccd_mode_odl { - gpios = <&gpioc 6 GPIO_ODR_HIGH>; - label = "CCD_MODE_ODL"; - }; - ec_gsc_packet_mode { - gpios = <&gpiob 1 GPIO_OUT_LOW>; - label = "EC_GSC_PACKET_MODE"; - }; - mech_pwr_btn_odl { - gpios = <&gpiod 2 GPIO_INPUT>; - label = "MECH_PWR_BTN_ODL"; - enum-name = "GPIO_POWER_BUTTON_L"; - }; - ec_pwr_btn_odl { - gpios = <&gpio0 1 GPIO_INPUT>; - label = "EC_PWR_BTN_ODL"; - enum-name = "GPIO_EC_PWR_BTN_ODL"; - }; - slp_s3_l { - gpios = <&gpio6 1 GPIO_INPUT>; - label = "SLP_S3_L"; - enum-name = "GPIO_PCH_SLP_S3_L"; - }; - slp_s5_l { - gpios = <&gpio7 2 GPIO_INPUT>; - label = "SLP_S5_L"; - enum-name = "GPIO_PCH_SLP_S5_L"; - }; - slp_s3_s0i3_l { - gpios = <&gpio7 4 GPIO_INPUT>; - label = "SLP_S3_S0I3_L"; - enum-name = "GPIO_PCH_SLP_S0_L"; - }; - pg_pwr_s5 { - gpios = <&gpioc 0 GPIO_INPUT>; - label = "PG_PWR_S5"; - enum-name = "GPIO_S5_PGOOD"; - }; - gpio_s0_pgood: pg_pcore_s0_r_od { - gpios = <&gpiob 6 GPIO_INPUT>; - label = "PG_PCORE_S0_R_OD"; - enum-name = "GPIO_S0_PGOOD"; - }; - acok_od { - gpios = <&gpio0 0 GPIO_INPUT>; - label = "ACOK_OD"; - enum-name = "GPIO_AC_PRESENT"; - }; - ec_pcore_int_odl { - gpios = <&gpiof 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PCORE_INT_ODL"; - enum-name = "GPIO_EC_PCORE_INT_ODL"; - }; - pg_groupc_s0_od { - gpios = <&gpioa 3 GPIO_INPUT>; - label = "PG_GROUPC_S0_OD"; - enum-name = "GPIO_PG_GROUPC_S0_OD"; - }; - pg_lpddr4x_s3_od { - gpios = <&gpio9 5 GPIO_INPUT>; - label = "PG_LPDDR4X_S3_OD"; - enum-name = "GPIO_PG_LPDDR4X_S3_OD"; - }; - en_pwr_s5 { - gpios = <&gpiob 7 GPIO_OUT_LOW>; - label = "EN_PWR_S5"; - enum-name = "GPIO_EN_PWR_A"; - }; - en_pwr_s0_r { - gpios = <&gpiof 1 GPIO_OUT_LOW>; - label = "EN_PWR_S0_R"; - enum-name = "GPIO_EN_PWR_S0_R"; - }; - en_pwr_pcore_s0_r { - gpios = <&gpioe 1 GPIO_OUT_LOW>; - label = "EN_PWR_PCORE_S0_R"; - enum-name = "GPIO_EN_PWR_PCORE_S0_R"; - }; - ec_entering_rw { - gpios = <&gpio6 6 GPIO_OUT_LOW>; - label = "EC_ENTERING_RW"; - enum-name = "GPIO_ENTERING_RW"; - }; - ec_sys_rst_l { - gpios = <&gpio7 6 GPIO_ODR_HIGH>; - label = "EC_SYS_RST_L"; - enum-name = "GPIO_SYS_RESET_L"; - }; - ec_soc_rsmrst_l { - gpios = <&gpioc 5 GPIO_OUT_LOW>; - label = "EC_SOC_RSMRST_L"; - enum-name = "GPIO_PCH_RSMRST_L"; - }; - ec_clr_cmos { - gpios = <&gpioa 1 GPIO_OUT_LOW>; - label = "EC_CLR_CMOS"; - }; - ec_mem_event { - gpios = <&gpioa 5 GPIO_OUT_LOW>; - label = "EC_MEM_EVENT"; - }; - ec_soc_pwr_btn_l { - gpios = <&gpio6 3 GPIO_OUT_HIGH>; - label = "EC_SOC_PWR_BTN_L"; - enum-name = "GPIO_PCH_PWRBTN_L"; - }; - ec_soc_pwr_good { - gpios = <&gpiod 3 GPIO_OUT_LOW>; - label = "EC_SOC_PWR_GOOD"; - enum-name = "GPIO_PCH_SYS_PWROK"; - }; - ec_soc_wake_l { - gpios = <&gpio0 3 GPIO_OUT_HIGH>; - label = "EC_SOC_WAKE_L"; - enum-name = "GPIO_EC_PCH_WAKE_ODL"; - }; - ec_soc_int_l { - gpios = <&gpio8 3 GPIO_OUT_HIGH>; - label = "EC_SOC_INT_L"; - }; - prochot_odl { - gpios = <&gpiod 5 GPIO_ODR_HIGH>; - label = "PROCHOT_ODL"; - enum-name = "GPIO_CPU_PROCHOT"; - }; - soc_alert_ec_l { - gpios = <&gpioe 2 GPIO_INPUT>; - label = "SOC_ALERT_EC_L"; - }; - soc_thermtrip_odl { - gpios = <&gpioe 5 GPIO_INPUT>; - label = "SOC_THERMTRIP_ODL"; - }; - usb_c0_tcpc_int_odl { - gpios = <&gpioe 0 GPIO_INPUT>; - label = "USB_C0_TCPC_INT_ODL"; - enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; - }; - usb_c1_tcpc_int_odl { - gpios = <&gpioc 7 GPIO_INPUT>; - label = "USB_C1_TCPC_INT_ODL"; - enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; - }; - usb_c0_ppc_int_odl { - gpios = <&gpio7 5 GPIO_INPUT>; - label = "USB_C0_PPC_INT_ODL"; - enum-name = "GPIO_USB_C0_PPC_INT_ODL"; - }; - usb_c1_ppc_int_odl { - gpios = <&gpiod 4 GPIO_INPUT>; - label = "USB_C1_PPC_INT_ODL"; - enum-name = "GPIO_USB_C1_PPC_INT_ODL"; - }; - usb_c0_bc12_int_odl { - gpios = <&gpioa 4 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "USB_C0_BC12_INT_ODL"; - enum-name = "GPIO_USB_C0_BC12_INT_ODL"; - }; - usb_c1_bc12_int_odl { - gpios = <&gpio9 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "USB_C1_BC12_INT_ODL"; - enum-name = "GPIO_USB_C1_BC12_INT_ODL"; - }; - usb_c0_c1_fault_odl { - gpios = <&gpio7 3 GPIO_ODR_HIGH>; - label = "USB_C0_C1_FAULT_ODL"; - enum-name = "GPIO_USB_C0_C1_FAULT_ODL"; - }; - usb_c0_tcpc_rst_l { - gpios = <&gpio3 4 GPIO_OUT_HIGH>; - label = "USB_C0_TCPC_RST_L"; - enum-name = "GPIO_USB_C0_TCPC_RST_L"; - }; - usb_c1_tcpc_rst_l { - gpios = <&gpio3 7 GPIO_OUT_HIGH>; - label = "USB_C1_TCPC_RST_L"; - enum-name = "GPIO_USB_C1_TCPC_RST_L"; - }; - usb_c0_hpd { - gpios = <&gpiof 5 GPIO_OUT_LOW>; - label = "USB_C0_HPD"; - enum-name = "GPIO_USB_C0_DP_HPD"; - }; - usb_c1_hpd { - gpios = <&gpiof 4 GPIO_OUT_LOW>; - label = "USB_C1_HPD"; - enum-name = "GPIO_USB_C1_DP_HPD"; - }; - 3axis_int_l { - gpios = <&gpioa 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "3AXIS_INT_L"; - }; - lid_open { - gpios = <&gpio0 2 GPIO_INPUT>; - label = "LID_OPEN"; - enum-name = "GPIO_LID_OPEN"; - }; - voldn_btn_odl { - gpios = <&gpioa 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "VOLDN_BTN_ODL"; - enum-name = "GPIO_VOLUME_DOWN_L"; - }; - volup_btn_odl { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "VOLUP_BTN_ODL"; - enum-name = "GPIO_VOLUME_UP_L"; - }; - ec_batt_pres_odl { - gpios = <&gpio9 4 GPIO_INPUT>; - label = "EC_BATT_PRES_ODL"; - enum-name = "GPIO_BATT_PRES_ODL"; - }; - ec_disable_disp_bl { - gpios = <&gpioa 6 GPIO_OUT_HIGH>; - label = "EC_DISABLE_DISP_BL"; - }; - ec_i2c_usb_a0_c0_scl { - gpios = <&gpiob 5 GPIO_INPUT>; - label = "EC_I2C_USB_A0_C0_SCL"; - }; - ec_i2c_usb_a0_c0_sda { - gpios = <&gpiob 4 GPIO_INPUT>; - label = "EC_I2C_USB_A0_C0_SDA"; - }; - ec_i2c_usb_a1_c1_scl { - gpios = <&gpio9 0 GPIO_INPUT>; - label = "EC_I2C_USB_A1_C1_SCL"; - }; - ec_i2c_usb_a1_c1_sda { - gpios = <&gpio8 7 GPIO_INPUT>; - label = "EC_I2C_USB_A1_C1_SDA"; - }; - ec_i2c_batt_scl { - gpios = <&gpio9 2 GPIO_INPUT>; - label = "EC_I2C_BATT_SCL"; - }; - ec_i2c_batt_sda { - gpios = <&gpio9 1 GPIO_INPUT>; - label = "EC_I2C_BATT_SDA"; - }; - ec_i2c_usbc_mux_scl { - gpios = <&gpiod 1 GPIO_INPUT>; - label = "EC_I2C_USBC_MUX_SCL"; - }; - ec_i2c_usbc_mux_sda { - gpios = <&gpiod 0 GPIO_INPUT>; - label = "EC_I2C_USBC_MUX_SDA"; - }; - ec_i2c_power_scl { - gpios = <&gpiof 3 GPIO_INPUT>; - label = "EC_I2C_POWER_SCL"; - }; - ec_i2c_power_sda { - gpios = <&gpiof 2 GPIO_INPUT>; - label = "EC_I2C_POWER_SDA"; - }; - ec_i2c_cbi_scl { - gpios = <&gpio3 3 GPIO_INPUT>; - label = "EC_I2C_CBI_SCL"; - }; - ec_i2c_cbi_sda { - gpios = <&gpio3 6 GPIO_INPUT>; - label = "EC_I2C_CBI_SDA"; - }; - ec_i2c_sensor_scl { - gpios = <&gpioe 4 GPIO_INPUT>; - label = "EC_I2C_SENSOR_SCL"; - }; - ec_i2c_sensor_sda { - gpios = <&gpioe 3 GPIO_INPUT>; - label = "EC_I2C_SENSOR_SDA"; - }; - ec_i2c_soc_sic { - gpios = <&gpiob 3 GPIO_INPUT>; - label = "EC_I2C_SOC_SIC"; - }; - ec_i2c_soc_sid { - gpios = <&gpiob 2 GPIO_INPUT>; - label = "EC_I2C_SOC_SID"; - }; - en_kb_bl { - gpios = <&gpio9 7 GPIO_OUT_HIGH>; - label = "EN_KB_BL"; - enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; - }; - ec_kso_02_inv { - gpios = <&gpio1 7 GPIO_OUT_LOW>; - label = "EC_KSO_02_INV"; - enum-name = "GPIO_KBD_KSO2"; - }; - ec_espi_rst_l { - gpios = <&gpio5 4 GPIO_PULL_UP>; - label = "EC_ESPI_RST_L"; - }; - 6axis_int_l { - gpios = <&gpioa 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "6AXIS_INT_L"; - }; - tablet_mode { - gpios = <&gpioc 1 GPIO_INPUT>; - label = "TABLET_MODE"; - }; - ec_gpio56 { - gpios = <&gpio5 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIO56"; - }; - ec_ps2_clk { - gpios = <&gpio6 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_CLK"; - }; - ec_ps2_dat { - gpios = <&gpio7 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_DAT"; - }; - ec_ps2_rst { - gpios = <&gpio6 2 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PS2_RST"; - }; - ec_gpiob0 { - gpios = <&gpiob 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIOB0"; - }; - ec_gpio81 { - gpios = <&gpio8 1 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_GPIO81"; - }; - ec_flprg2 { - gpios = <&gpio8 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_FLPRG2"; - }; - ec_psl_gpo { - gpios = <&gpiod 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PSL_GPO"; - }; - ec_pwm7 { - gpios = <&gpio6 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_PWM7"; - }; - }; -}; diff --git a/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt b/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt index dfccaf12c6..9b21ee77bd 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt +++ b/zephyr/projects/herobrine/herobrine_npcx9/CMakeLists.txt @@ -17,3 +17,5 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON "src/led.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C "src/i2c.c") +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC + "src/alt_dev_replacement.c") diff --git a/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts b/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts index 152f033db4..f1c3bc5fea 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts +++ b/zephyr/projects/herobrine/herobrine_npcx9/gpio.dts @@ -10,282 +10,238 @@ usb_c0_pd_int_odl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PD_INT_ODL"; - label = "USB_C0_PD_INT_ODL"; }; usb_c1_pd_int_odl { gpios = <&gpiof 5 GPIO_INPUT>; enum-name = "GPIO_USB_C1_PD_INT_ODL"; - label = "USB_C1_PD_INT_ODL"; }; usb_c0_swctl_int_odl { gpios = <&gpio0 3 GPIO_INPUT>; enum-name = "GPIO_USB_C0_SWCTL_INT_ODL"; - label = "USB_C0_SWCTL_INT_ODL"; }; usb_c1_swctl_int_odl { gpios = <&gpio4 0 GPIO_INPUT>; enum-name = "GPIO_USB_C1_SWCTL_INT_ODL"; - label = "USB_C1_SWCTL_INT_ODL"; }; gpio_usb_c0_bc12_int_l: usb_c0_bc12_int_l { - gpios = <&gpio6 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio6 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C0_BC12_INT_L"; - label = "USB_C0_BC12_INT_L"; }; gpio_usb_c1_bc12_int_l: usb_c1_bc12_int_l { - gpios = <&gpio8 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio8 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C1_BC12_INT_L"; - label = "USB_C1_BC12_INT_L"; }; usb_a0_oc_odl { - gpios = <&gpiof 4 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiof 4 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_A0_OC_ODL"; - label = "USB_A0_OC_ODL"; }; gpio_chg_acok_od: chg_acok_od { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "CHG_ACOK_OD"; }; gpio_ec_pwr_btn_odl: ec_pwr_btn_odl { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "EC_PWR_BTN_ODL"; }; ec_voldn_btn_odl { - gpios = <&gpio6 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio6 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "EC_VOLDN_BTN_ODL"; }; ec_volup_btn_odl { - gpios = <&gpioc 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpioc 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_UP_L"; - label = "EC_VOLUP_BTN_ODL"; }; ec_wp_odl { gpios = <&gpiod 3 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "EC_WP_ODL"; }; gpio_lid_open_ec: lid_open_ec { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN_EC"; }; ap_rst_l { gpios = <&gpio5 1 GPIO_INPUT>; enum-name = "GPIO_AP_RST_L"; - label = "AP_RST_L"; }; ps_hold { - gpios = <&gpioa 6 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioa 6 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_PS_HOLD"; - label = "PS_HOLD"; }; ap_suspend { gpios = <&gpio5 7 GPIO_INPUT>; enum-name = "GPIO_AP_SUSPEND"; - label = "AP_SUSPEND"; }; - power_good { - gpios = <&gpio3 7 (GPIO_INPUT | GPIO_PULL_DOWN)>; + mb_power_good { + gpios = <&gpio3 7 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_POWER_GOOD"; - label = "MB_POWER_GOOD"; }; warm_reset_l { gpios = <&gpiob 0 GPIO_INPUT>; enum-name = "GPIO_WARM_RESET_L"; - label = "WARM_RESET_L"; }; ap_ec_spi_cs_l { - gpios = <&gpio5 3 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CS_L"; + gpios = <&gpio5 3 GPIO_INPUT_PULL_DOWN>; }; tablet_mode_l { gpios = <&gpioc 6 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; gpio_accel_gyro_int_l: accel_gyro_int_l { gpios = <&gpioa 3 GPIO_INPUT>; enum-name = "GPIO_ACCEL_GYRO_INT_L"; - label = "ACCEL_GYRO_INT_L"; }; gpio_rtc_ec_wake_odl: rtc_ec_wake_odl { #gpio-cells = <0>; gpios = <&gpio0 2 GPIO_INPUT>; enum-name = "GPIO_EC_RST_ODL"; - label = "EC_RST_ODL"; }; ec_entering_rw { gpios = <&gpio7 2 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "EC_ENTERING_RW"; }; ccd_mode_odl { gpios = <&gpio6 3 GPIO_INPUT>; enum-name = "GPIO_CCD_MODE_ODL"; - label = "CCD_MODE_ODL"; }; ec_batt_pres_odl { gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; ec_gsc_packet_mode { gpios = <&gpio8 3 GPIO_OUT_LOW>; enum-name = "GPIO_PACKET_MODE_EN"; - label = "EC_GSC_PACKET_MODE"; }; pmic_resin_l { gpios = <&gpioa 0 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_RESIN_L"; - label = "PMIC_RESIN_L"; }; pmic_kpd_pwr_odl { gpios = <&gpioa 2 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_KPD_PWR_ODL"; - label = "PMIC_KPD_PWR_ODL"; }; ap_ec_int_l { gpios = <&gpio5 6 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_INT_L"; - label = "AP_EC_INT_L"; }; gpio_switchcap_on: switchcap_on { gpios = <&gpiod 5 GPIO_OUT_LOW>; enum-name = "GPIO_SWITCHCAP_ON"; - label = "SWITCHCAP_ON"; }; en_pp5000_s5 { gpios = <&gpio7 3 GPIO_OUT_HIGH>; enum-name = "GPIO_EN_PP5000"; - label = "EN_PP5000_S5"; }; ec_bl_disable_l { - gpios = <&gpiob 6 GPIO_OUT_LOW>; + /* The PMIC controls backlight enable and this pin must + * be HiZ for normal operation. But the backlight can + * be enabled by setting this pin low and configuring it + * as an output. + */ + gpios = <&gpiob 6 GPIO_INPUT>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_BL_DISABLE_L"; }; lid_accel_int_l { gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_LID_ACCEL_INT_L"; - label = "LID_ACCEL_INT_L"; }; tp_int_gate { gpios = <&gpio7 4 GPIO_OUT_LOW>; enum-name = "GPIO_TRACKPAD_INT_GATE"; - label = "TP_INT_GATE"; }; usb_c0_pd_rst_l { gpios = <&gpiof 1 GPIO_OUT_HIGH>; enum-name = "GPIO_USB_C0_PD_RST_L"; - label = "USB_C0_PD_RST_L"; }; usb_c1_pd_rst_l { gpios = <&gpioe 4 GPIO_OUT_HIGH>; enum-name = "GPIO_USB_C1_PD_RST_L"; - label = "USB_C1_PD_RST_L"; }; dp_mux_oe_l { gpios = <&gpiob 1 GPIO_ODR_HIGH>; enum-name = "GPIO_DP_MUX_OE_L"; - label = "DP_MUX_OE_L"; }; dp_mux_sel { gpios = <&gpio4 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_MUX_SEL"; - label = "DP_MUX_SEL"; }; dp_hot_plug_det_r { gpios = <&gpio9 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_HOT_PLUG_DET"; - label = "DP_HOT_PLUG_DET_R"; }; en_usb_a_5v { gpios = <&gpiof 0 GPIO_OUT_LOW>; enum-name = "GPIO_EN_USB_A_5V"; - label = "EN_USB_A_5V"; }; usb_a_cdp_ilim_en_l { gpios = <&gpio7 5 GPIO_OUT_HIGH>; - label = "USB_A_CDP_ILIM_EN_L"; + }; + usb_c0_frs_en { + gpios = <&gpioc 5 GPIO_OUT_LOW>; + enum-name = "GPIO_USB_C0_FRS_EN"; + }; + usb_c1_frs_en { + gpios = <&gpioc 1 GPIO_OUT_LOW>; + enum-name = "GPIO_USB_C1_FRS_EN"; }; ec_chg_led_y_c0 { gpios = <&gpio6 0 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C0"; - label = "EC_CHG_LED_Y_C0"; }; ec_chg_led_w_c0 { gpios = <&gpioc 0 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_W_C0"; - label = "EC_CHG_LED_W_C0"; }; ec_chg_led_y_c1 { gpios = <&gpioc 3 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C1"; - label = "EC_CHG_LED_Y_C1"; }; ec_chg_led_w_c1 { gpios = <&gpioc 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_W_C1"; - label = "EC_CHG_LED_W_C1"; }; ap_ec_spi_mosi { - gpios = <&gpio4 6 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MOSI"; + gpios = <&gpio4 6 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_miso { - gpios = <&gpio4 7 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MISO"; + gpios = <&gpio4 7 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_clk { - gpios = <&gpio5 5 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CLK"; + gpios = <&gpio5 5 GPIO_INPUT_PULL_DOWN>; }; gpio_brd_id0: brd_id0 { gpios = <&gpio9 4 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION1"; - label = "BRD_ID0"; }; gpio_brd_id1: brd_id1 { gpios = <&gpio9 7 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION2"; - label = "BRD_ID1"; }; gpio_brd_id2: brd_id2 { gpios = <&gpioa 5 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION3"; - label = "BRD_ID2"; }; gpio_sku_id0: sku_id0 { gpios = <&gpio6 7 GPIO_INPUT>; enum-name = "GPIO_SKU_ID0"; - label = "SKU_ID0"; }; gpio_sku_id1: sku_id1 { gpios = <&gpio7 0 GPIO_INPUT>; enum-name = "GPIO_SKU_ID1"; - label = "SKU_ID1"; }; gpio_sku_id2: sku_id2 { gpios = <&gpioe 1 GPIO_INPUT>; enum-name = "GPIO_SKU_ID2"; - label = "SKU_ID2"; }; gpio_switchcap_pg: src_vph_pwr_pg { - gpios = <&gpioe 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioe 2 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_SWITCHCAP_PG"; - label = "SRC_VPH_PWR_PG"; }; arm_x86 { gpios = <&gpio6 6 GPIO_OUT_LOW>; - label = "ARM_X86"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; }; @@ -342,11 +298,9 @@ <&gpio5 2 0>, <&gpio5 4 0>, <&gpio7 6 0>, - <&gpioc 5 0>, <&gpiod 1 0>, <&gpiod 0 0>, <&gpioe 3 0>, - <&gpioc 1 0>, <&gpio0 4 0>, <&gpiod 6 0>, <&gpio3 2 0>, @@ -362,7 +316,8 @@ <&gpio9 3 0>, <&gpioa 7 0>, <&gpio5 0 0>, - <&gpio8 1 0>; + <&gpio8 1 0>, + <&gpiob 7 0>; }; }; diff --git a/zephyr/projects/herobrine/herobrine_npcx9/i2c.dts b/zephyr/projects/herobrine/herobrine_npcx9/i2c.dts index 44bc9c6707..d8cb226710 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/i2c.dts +++ b/zephyr/projects/herobrine/herobrine_npcx9/i2c.dts @@ -20,53 +20,43 @@ i2c_power: power { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_POWER"; - label = "POWER"; }; battery { i2c-port = <&i2c0_0>; remote-port = <0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; virtual-battery { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_VIRTUAL_BATTERY"; - label = "VIRTUAL"; }; charger { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; i2c_tcpc0: tcpc0 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_TCPC0"; - label = "TCPC0"; }; i2c_tcpc1: tcpc1 { i2c-port = <&i2c2_0>; enum-name = "I2C_PORT_TCPC1"; - label = "TCPC1"; }; rtc { i2c-port = <&i2c4_1>; enum-name = "I2C_PORT_RTC"; - label = "RTC"; }; i2c_eeprom: eeprom { i2c-port = <&i2c5_0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; i2c_sensor: sensor { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; accel { i2c-port = <&i2c7_0>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; }; @@ -74,6 +64,7 @@ }; &i2c0_0 { + label = "I2C_POWER"; status = "okay"; clock-frequency = <I2C_BITRATE_STANDARD>; @@ -89,6 +80,7 @@ }; &i2c1_0 { + label = "I2C_USB_C0_PD"; status = "okay"; /* * TODO(b/200280341): PS8805 SPI ROM access @@ -107,6 +99,7 @@ }; &i2c2_0 { + label = "I2C_USB_C1_PD"; status = "okay"; /* TODO(b/200280341): PS8805 SPI ROM access */ clock-frequency = <I2C_BITRATE_FAST>; @@ -121,11 +114,8 @@ clock-frequency = <I2C_BITRATE_FAST>; }; -&i2c_ctrl3 { - status = "okay"; -}; - &i2c4_1 { + label = "I2C_RTC"; status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; @@ -142,6 +132,7 @@ }; &i2c5_0 { + label = "I2C_EEPROM"; status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; }; @@ -151,6 +142,7 @@ }; &i2c7_0 { + label = "I2C_SENSOR"; status = "okay"; clock-frequency = <I2C_BITRATE_FAST>; }; diff --git a/zephyr/projects/herobrine/herobrine_npcx9/prj.conf b/zephyr/projects/herobrine/herobrine_npcx9/prj.conf index aeb9f6e36f..503cdc1e27 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/prj.conf +++ b/zephyr/projects/herobrine/herobrine_npcx9/prj.conf @@ -14,6 +14,7 @@ CONFIG_PLATFORM_EC_POWER_BUTTON=y CONFIG_PLATFORM_EC_CBI_GPIO=y CONFIG_I2C=y CONFIG_KERNEL_SHELL=y +CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y # Shell history and tab autocompletion (for convenience) CONFIG_SHELL_HELP=y @@ -138,9 +139,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_RTC_ALARM=y # EC software sync CONFIG_PLATFORM_EC_VBOOT_HASH=y -# Serial Host Interface (SHI) device. -CONFIG_CROS_SHI_NPCX=y - # Sensors CONFIG_PLATFORM_EC_MOTIONSENSE=y CONFIG_PLATFORM_EC_ACCEL_FIFO=y diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/alt_dev_replacement.c b/zephyr/projects/herobrine/herobrine_npcx9/src/alt_dev_replacement.c new file mode 100644 index 0000000000..fe3f06fca5 --- /dev/null +++ b/zephyr/projects/herobrine/herobrine_npcx9/src/alt_dev_replacement.c @@ -0,0 +1,35 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <logging/log.h> +#include "usbc/ppc.h" +#include "hooks.h" +#include "cros_board_info.h" + +LOG_MODULE_REGISTER(alt_dev_replacement); + +#define BOARD_VERSION_UNKNOWN 0xffffffff + +/* Check board version to decide which ppc is used. */ +static bool board_has_syv_ppc(void) +{ + static uint32_t board_version = BOARD_VERSION_UNKNOWN; + + if (board_version == BOARD_VERSION_UNKNOWN) { + if (cbi_get_board_version(&board_version) != EC_SUCCESS) { + LOG_ERR("Failed to get board version."); + board_version = 0; + } + } + + return (board_version >= 1); +} + +static void check_alternate_devices(void) +{ + /* Configure the PPC driver */ + if (board_has_syv_ppc()) + PPC_ENABLE_ALTERNATE(ppc_port0_syv); +} +DECLARE_HOOK(HOOK_INIT, check_alternate_devices, HOOK_PRIO_DEFAULT); diff --git a/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c b/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c index 20536752f2..1bce0c51b3 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c +++ b/zephyr/projects/herobrine/herobrine_npcx9/src/usbc_config.c @@ -62,23 +62,6 @@ void usba_oc_interrupt(enum gpio_signal signal) hook_call_deferred(&usba_oc_deferred_data, 0); } -#define BOARD_VERSION_UNKNOWN 0xffffffff - -/* Check board version to decide which ppc is used. */ -static bool board_has_syv_ppc(void) -{ - static uint32_t board_version = BOARD_VERSION_UNKNOWN; - - if (board_version == BOARD_VERSION_UNKNOWN) { - if (cbi_get_board_version(&board_version) != EC_SUCCESS) { - CPRINTS("Failed to get board version."); - board_version = 0; - } - } - - return (board_version >= 1); -} - void ppc_interrupt(enum gpio_signal signal) { switch (signal) { @@ -190,10 +173,6 @@ static void board_init_usbc(void) { /* Enable USB-A overcurrent interrupt */ gpio_enable_interrupt(GPIO_USB_A0_OC_ODL); - - /* Configure the PPC driver */ - if (board_has_syv_ppc()) - PPC_ENABLE_ALTERNATE(ppc_port0_syv); } DECLARE_HOOK(HOOK_INIT, board_init_usbc, HOOK_PRIO_DEFAULT); diff --git a/zephyr/projects/herobrine/herobrine_npcx9/usbc.dts b/zephyr/projects/herobrine/herobrine_npcx9/usbc.dts index c910c8ec03..af440c4f7e 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/usbc.dts +++ b/zephyr/projects/herobrine/herobrine_npcx9/usbc.dts @@ -47,7 +47,7 @@ compatible = "silergy,syv682x"; status = "okay"; port = <&i2c_tcpc0>; - i2c-addr-flags = "SYV682X_ADDR0_FLAGS"; + i2c-addr-flags = "SYV682X_ADDR1_FLAGS"; alternate-for = <&ppc_port0>; }; }; diff --git a/zephyr/projects/it8xxx2_evb/prj.conf b/zephyr/projects/it8xxx2_evb/prj.conf index 23a7ab2275..ffc59fb420 100644 --- a/zephyr/projects/it8xxx2_evb/prj.conf +++ b/zephyr/projects/it8xxx2_evb/prj.conf @@ -16,6 +16,9 @@ CONFIG_PLATFORM_EC_ADC=y # I2C CONFIG_PLATFORM_EC_I2C=y +# Fan +CONFIG_PLATFORM_EC_FAN=y + # Flash CONFIG_PLATFORM_EC_FLASH_CROS=y CONFIG_PLATFORM_EC_CONSOLE_CMD_FLASH=y diff --git a/zephyr/projects/nissa/BUILD.py b/zephyr/projects/nissa/BUILD.py new file mode 100644 index 0000000000..f54168380b --- /dev/null +++ b/zephyr/projects/nissa/BUILD.py @@ -0,0 +1,45 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Nivviks has NPCX993F, Nereid has ITE81302 + + +def register_nissa_project( + project_name, + chip="it8xxx2", + extra_dts_overlays=(), + extra_kconfig_files=(), +): + register_func = register_binman_project + if chip.startswith("npcx9"): + register_func = register_npcx_project + + register_func( + project_name=project_name, + zephyr_board=chip, + dts_overlays=[*extra_dts_overlays], + kconfig_files=[here / "prj.conf", *extra_kconfig_files], + ) + + +register_nissa_project( + project_name="nivviks", + chip="npcx9", + extra_dts_overlays=[ + here / "nivviks_generated.dts", + here / "nivviks_overlay.dts", + here / "nivviks_motionsense.dts", + ], + extra_kconfig_files=[here / "prj_nivviks.conf"], +) + +register_nissa_project( + project_name="nereid", + chip="it8xxx2", + extra_dts_overlays=[ + here / "nereid_generated.dts", + here / "nereid_overlay.dts", + ], + extra_kconfig_files=[here / "prj_nereid.conf"], +) diff --git a/zephyr/projects/nissa/CMakeLists.txt b/zephyr/projects/nissa/CMakeLists.txt new file mode 100644 index 0000000000..fae80277f9 --- /dev/null +++ b/zephyr/projects/nissa/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cmake_minimum_required(VERSION 3.13.1) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +zephyr_include_directories(include) + +if(DEFINED CONFIG_BOARD_NIVVIKS) + project(nivviks) + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "src/usbc.c") + zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CHARGER "src/charger.c") +endif() +if(DEFINED CONFIG_BOARD_NEREID) + project(nereid) +endif() diff --git a/zephyr/projects/nissa/Kconfig b/zephyr/projects/nissa/Kconfig new file mode 100644 index 0000000000..3f8196bf8a --- /dev/null +++ b/zephyr/projects/nissa/Kconfig @@ -0,0 +1,17 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config BOARD_NIVVIKS + bool "Google Nivviks Board" + help + Build Google Nivviks reference board. Nivviks has Intel ADL-N SoC + with NPCX993FA0BX EC. + +config BOARD_NEREID + bool "Google Nereid Board" + help + Build Google Nereid reference board. Nereid has Intel ADL-N SoC + with IT81302 EC. + +source "Kconfig.zephyr" diff --git a/zephyr/projects/nissa/include/gpio_map.h b/zephyr/projects/nissa/include/gpio_map.h new file mode 100644 index 0000000000..661f8d403e --- /dev/null +++ b/zephyr/projects/nissa/include/gpio_map.h @@ -0,0 +1,84 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __ZEPHYR_GPIO_MAP_H +#define __ZEPHYR_GPIO_MAP_H + +#include <devicetree.h> +#include <gpio_signal.h> + +/* + * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. + * + * Each GPIO_INT requires three parameters: + * gpio_signal - The enum gpio_signal for the interrupt gpio + * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH) + * handler - The platform/ec interrupt handler. + * + * Ensure that this files includes all necessary headers to declare all + * referenced handler functions. + * + * For example, one could use the follow definition: + * #define EC_CROS_GPIO_INTERRUPTS \ + * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print) + */ +/* Helper macros for generating CROS_EC_GPIO_INTERRUPTS */ + +#ifdef CONFIG_PLATFORM_EC_POWERSEQ +#define POWER_SIGNAL_INT(gpio, edge) \ + GPIO_INT(gpio, edge, power_signal_interrupt) +#define AP_PROCHOT_INT(gpio, edge) \ + GPIO_INT(gpio, edge, throttle_ap_prochot_input_interrupt) +#else +#define POWER_SIGNAL_INT(gpio, edge) +#define AP_PROCHOT_INT(gpio, edge) +#endif + +#ifdef CONFIG_PLATFORM_EC_POWER_BUTTON + #define PWRBTN_INT() GPIO_INT(GPIO_POWER_BUTTON_L, \ + GPIO_INT_EDGE_BOTH, \ + power_button_interrupt) +#else + #define PWRBTN_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_LID_SWITCH + #define LID_INT() GPIO_INT(GPIO_LID_OPEN, \ + GPIO_INT_EDGE_BOTH, \ + lid_interrupt) +#else + #define LID_INT() +#endif + +#ifdef CONFIG_PLATFORM_EC_VOLUME_BUTTONS + #define VOLBTN_INT(pin) GPIO_INT(pin, \ + GPIO_INT_EDGE_BOTH, \ + button_interrupt) +#else + #define VOLBTN_INT(pin) +#endif + +#ifdef CONFIG_PLATFORM_EC_USBC + #define USBC_INT(pin, port) GPIO_INT(pin, \ + GPIO_INT_EDGE_FALLING, \ + usb_c ## port ## _interrupt) +#else + #define USBC_INT(pin, port) +#endif + + +#define EC_CROS_GPIO_INTERRUPTS \ + LID_INT() \ + PWRBTN_INT() \ + VOLBTN_INT(GPIO_VOLUME_DOWN_L) \ + VOLBTN_INT(GPIO_VOLUME_UP_L) \ + POWER_SIGNAL_INT(GPIO_SLP_SUS_L, GPIO_INT_EDGE_BOTH) \ + POWER_SIGNAL_INT(GPIO_PG_EC_DSW_PWROK, GPIO_INT_EDGE_BOTH) \ + POWER_SIGNAL_INT(GPIO_PG_EC_RSMRST_ODL, GPIO_INT_EDGE_BOTH) \ + POWER_SIGNAL_INT(GPIO_PG_EC_ALL_SYS_PWRGD, GPIO_INT_EDGE_BOTH) \ + AP_PROCHOT_INT(GPIO_EC_PROCHOT_ODL, GPIO_INT_EDGE_BOTH) \ + USBC_INT(GPIO_USB_C0_PD_INT_ODL, 0) \ + USBC_INT(GPIO_USB_C1_PD_INT_ODL, 1) +#endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/projects/nissa/nereid_generated.dts b/zephyr/projects/nissa/nereid_generated.dts new file mode 100644 index 0000000000..0ea7482308 --- /dev/null +++ b/zephyr/projects/nissa/nereid_generated.dts @@ -0,0 +1,363 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + label = "EC_VSENSE_PP3300_S5"; + enum-name = "ADC_PP3300_S5"; + channel = <0>; + }; + adc_temp_sensor_1: temp_sensor_1 { + label = "TEMP_SENSOR_1"; + enum-name = "ADC_TEMP_SENSOR_1"; + channel = <2>; + }; + adc_temp_sensor_2: temp_sensor_2 { + label = "TEMP_SENSOR_2"; + enum-name = "ADC_TEMP_SENSOR_2"; + channel = <3>; + }; + adc_temp_sensor_3: temp_sensor_3 { + label = "TEMP_SENSOR_3"; + enum-name = "ADC_TEMP_SENSOR_3"; + channel = <13>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + #gpio-cells = <0>; + gpios = <&gpioc 0 GPIO_INPUT>; + enum-name = "GPIO_LID_ACCEL_INT_L"; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + #gpio-cells = <0>; + gpios = <&gpiob 7 GPIO_INPUT>; + enum-name = "GPIO_PG_EC_ALL_SYS_PWRGD"; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + #gpio-cells = <0>; + gpios = <&gpioh 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + #gpio-cells = <0>; + gpios = <&gpiog 1 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + #gpio-cells = <0>; + gpios = <&gpioi 4 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + #gpio-cells = <0>; + gpios = <&gpioj 5 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + #gpio-cells = <0>; + gpios = <&gpiok 4 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + #gpio-cells = <0>; + gpios = <&gpioc 7 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + #gpio-cells = <0>; + gpios = <&gpioh 1 GPIO_INPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + #gpio-cells = <0>; + gpios = <&gpioi 1 GPIO_INPUT>; + enum-name = "GPIO_CPU_PROCHOT"; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + #gpio-cells = <0>; + gpios = <&gpiol 7 GPIO_OUTPUT>; + enum-name = "GPIO_PG_EC_DSW_PWROK"; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + #gpio-cells = <0>; + gpios = <&gpiok 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + #gpio-cells = <0>; + gpios = <&gpiob 2 GPIO_ODR_LOW>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + #gpio-cells = <0>; + gpios = <&gpiod 6 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWROK"; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + #gpio-cells = <0>; + gpios = <&gpiob 6 GPIO_ODR_LOW>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + #gpio-cells = <0>; + gpios = <&gpioh 0 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_RSMRST_L"; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + #gpio-cells = <0>; + gpios = <&gpiok 2 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_RTCRST"; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + #gpio-cells = <0>; + gpios = <&gpiof 2 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_SYS_PWROK"; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + #gpio-cells = <0>; + gpios = <&gpioe 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_VCCST_PWRGD_OD"; + }; + gpio_ec_soc_wake_odl: ec_soc_wake_odl { + #gpio-cells = <0>; + gpios = <&gpiod 5 GPIO_ODR_LOW>; + enum-name = "GPIO_EC_PCH_WAKE_ODL"; + }; + gpio_ec_wp_odl: ec_wp_odl { + #gpio-cells = <0>; + gpios = <&gpioa 6 GPIO_INPUT>; + enum-name = "GPIO_WP_L"; + }; + gpio_en_kb_bl: en_kb_bl { + #gpio-cells = <0>; + gpios = <&gpioj 3 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + #gpio-cells = <0>; + gpios = <&gpioc 5 GPIO_OUTPUT>; + enum-name = "GPIO_EN_PP3300_A"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + #gpio-cells = <0>; + gpios = <&gpiob 5 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + #gpio-cells = <0>; + gpios = <&gpiok 5 GPIO_OUTPUT>; + enum-name = "GPIO_EN_PP5000"; + }; + gpio_en_slp_z: en_slp_z { + #gpio-cells = <0>; + gpios = <&gpiok 3 GPIO_OUTPUT>; + enum-name = "GPIO_EN_SLP_Z"; + }; + gpio_en_sub_usb_a1_vbus: en_sub_usb_a1_vbus { + #gpio-cells = <0>; + gpios = <&gpiof 0 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + #gpio-cells = <0>; + gpios = <&gpiol 6 GPIO_OUTPUT>; + enum-name = "GPIO_EN_USB_A_5V"; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + #gpio-cells = <0>; + gpios = <&gpioe 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + #gpio-cells = <0>; + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + #gpio-cells = <0>; + gpios = <&gpioj 0 GPIO_INPUT>; + enum-name = "GPIO_EC_IMU_INT_L"; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + #gpio-cells = <0>; + gpios = <&gpioj 4 GPIO_INPUT>; + enum-name = "GPIO_IMVP9_VRRDY_OD"; + }; + gpio_lid_open: lid_open { + #gpio-cells = <0>; + gpios = <&gpiof 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + #gpio-cells = <0>; + gpios = <&gpioj 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + #gpio-cells = <0>; + gpios = <&gpiod 3 GPIO_INPUT>; + }; + gpio_pg_pp1050_proc: pg_pp1050_proc { + #gpio-cells = <0>; + gpios = <&gpiol 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + #gpio-cells = <0>; + gpios = <&gpioe 3 GPIO_INPUT>; + enum-name = "GPIO_PG_PP5000_A_ODL"; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + #gpio-cells = <0>; + gpios = <&gpioe 1 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_PG_EC_RSMRST_ODL"; + }; + gpio_slp_s0_l: slp_s0_l { + #gpio-cells = <0>; + gpios = <&gpioe 4 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S0_L"; + }; + gpio_slp_s3_l: slp_s3_l { + #gpio-cells = <0>; + gpios = <&gpioh 3 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S3_L"; + }; + gpio_slp_s4_l: slp_s4_l { + #gpio-cells = <0>; + gpios = <&gpioi 5 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S4_L"; + }; + gpio_slp_sus_l: slp_sus_l { + #gpio-cells = <0>; + gpios = <&gpiog 2 GPIO_INPUT>; + enum-name = "GPIO_SLP_SUS_L"; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + #gpio-cells = <0>; + gpios = <&gpiof 1 GPIO_OUTPUT>; + }; + gpio_sys_rst_odl: sys_rst_odl { + #gpio-cells = <0>; + gpios = <&gpiod 1 GPIO_ODR_LOW>; + enum-name = "GPIO_SYS_RESET_L"; + }; + gpio_tablet_mode_l: tablet_mode_l { + #gpio-cells = <0>; + gpios = <&gpioa 7 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + #gpio-cells = <0>; + gpios = <&gpiol 5 GPIO_OUTPUT>; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + #gpio-cells = <0>; + gpios = <&gpiok 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_USB_C0_PD_INT_ODL"; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + #gpio-cells = <0>; + gpios = <&gpiod 0 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + #gpio-cells = <0>; + gpios = <&gpiok 1 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + #gpio-cells = <0>; + gpios = <&gpioi 6 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + #gpio-cells = <0>; + gpios = <&gpioi 7 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c1>; + enum-name = "I2C_PORT_BATTERY"; + }; + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0>; + enum-name = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c2>; + enum-name = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c4>; + enum-name = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c5>; + enum-name = "I2C_PORT_USB_C0_TCPC"; + }; + }; + + named-pwms { + compatible = "named-pwms"; + + pwm_pwm_kb_bl: pwm_kb_bl { + pwms = <&pwm0 0 0>; + }; + pwm_pwm_led_1_odl: pwm_led_1_odl { + pwms = <&pwm1 1 1>; + }; + pwm_pwm_led_2_odl: pwm_led_2_odl { + pwms = <&pwm2 2 1>; + }; + pwm_pwm_led_3_odl: pwm_led_3_odl { + pwms = <&pwm3 3 1>; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/nereid_overlay.dts b/zephyr/projects/nissa/nereid_overlay.dts new file mode 100644 index 0000000000..5b591bdb0f --- /dev/null +++ b/zephyr/projects/nissa/nereid_overlay.dts @@ -0,0 +1,128 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-pins = < + &gpio_gsc_ec_pwr_btn_odl + &gpio_lid_open + >; + }; + + named-temp-sensors { + memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "DDR and SOC"; + enum-name = "TEMP_SENSOR_1"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_1>; + }; + charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "Charger"; + enum-name = "TEMP_SENSOR_CHARGER"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_2>; + }; + ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "Ambiient"; + enum-name = "TEMP_SENSOR_AMB"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_3>; + }; + }; + + /* + * Alias kblist to correct node. + */ + named-pwms { + compatible = "named-pwms"; + + kblight: pwm_kb_bl { + }; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +/* Set bus speeds for I2C */ +&i2c0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c1 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&i2c2 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c4 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c5 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +/* PWM config */ +&pwm0 { + prescaler-cx = <PWM_PRESCALER_C4>; +}; + +&pwm1 { + prescaler-cx = <PWM_PRESCALER_C4>; +}; + +&pwm2 { + prescaler-cx = <PWM_PRESCALER_C4>; +}; + +&pwm3 { + prescaler-cx = <PWM_PRESCALER_C4>; +}; + +&pwm_pwm_kb_bl { + frequency = <10000>; +}; + +&pwm_pwm_led_1_odl { + frequency = <324>; +}; + +&pwm_pwm_led_2_odl { + frequency = <324>; +}; + +&pwm_pwm_led_3_odl { + frequency = <324>; +}; diff --git a/zephyr/projects/nissa/nivviks_generated.dts b/zephyr/projects/nissa/nivviks_generated.dts new file mode 100644 index 0000000000..430ffcf6c7 --- /dev/null +++ b/zephyr/projects/nissa/nivviks_generated.dts @@ -0,0 +1,379 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file is auto-generated - do not edit! + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + label = "EC_VSENSE_PP3300_S5"; + enum-name = "ADC_PP3300_S5"; + channel = <6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + label = "TEMP_SENSOR_1"; + enum-name = "ADC_TEMP_SENSOR_1"; + channel = <0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + label = "TEMP_SENSOR_2"; + enum-name = "ADC_TEMP_SENSOR_2"; + channel = <1>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + #gpio-cells = <0>; + gpios = <&gpio5 0 GPIO_INPUT>; + enum-name = "GPIO_LID_ACCEL_INT_L"; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + #gpio-cells = <0>; + gpios = <&gpioa 7 GPIO_INPUT>; + enum-name = "GPIO_PG_EC_ALL_SYS_PWRGD"; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + #gpio-cells = <0>; + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + #gpio-cells = <0>; + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + #gpio-cells = <0>; + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + #gpio-cells = <0>; + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + #gpio-cells = <0>; + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + #gpio-cells = <0>; + gpios = <&gpio7 5 GPIO_INPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + #gpio-cells = <0>; + gpios = <&gpio1 7 GPIO_OUTPUT>; + enum-name = "GPIO_KBD_KSO2"; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + #gpio-cells = <0>; + gpios = <&gpiof 1 GPIO_INPUT>; + enum-name = "GPIO_CPU_PROCHOT"; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + #gpio-cells = <0>; + gpios = <&gpio6 1 GPIO_OUTPUT>; + enum-name = "GPIO_PG_EC_DSW_PWROK"; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + #gpio-cells = <0>; + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + #gpio-cells = <0>; + gpios = <&gpiob 0 GPIO_ODR_LOW>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + #gpio-cells = <0>; + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWROK"; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + #gpio-cells = <0>; + gpios = <&gpioc 1 GPIO_ODR_LOW>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + #gpio-cells = <0>; + gpios = <&gpioa 6 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_RSMRST_L"; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + #gpio-cells = <0>; + gpios = <&gpio7 6 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_RTCRST"; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + #gpio-cells = <0>; + gpios = <&gpio3 7 GPIO_OUTPUT>; + enum-name = "GPIO_PCH_SYS_PWROK"; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + #gpio-cells = <0>; + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + enum-name = "GPIO_VCCST_PWRGD_OD"; + }; + gpio_ec_soc_wake_odl: ec_soc_wake_odl { + #gpio-cells = <0>; + gpios = <&gpio8 0 GPIO_ODR_LOW>; + enum-name = "GPIO_EC_PCH_WAKE_ODL"; + }; + gpio_ec_wp_odl: ec_wp_odl { + #gpio-cells = <0>; + gpios = <&gpioa 1 GPIO_INPUT>; + enum-name = "GPIO_WP_L"; + }; + gpio_en_kb_bl: en_kb_bl { + #gpio-cells = <0>; + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + #gpio-cells = <0>; + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_EN_PP3300_A"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + #gpio-cells = <0>; + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + #gpio-cells = <0>; + gpios = <&gpio4 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_PP5000"; + }; + gpio_en_slp_z: en_slp_z { + #gpio-cells = <0>; + gpios = <&gpioe 1 GPIO_OUTPUT>; + enum-name = "GPIO_EN_SLP_Z"; + }; + gpio_en_sub_usb_a1_vbus: en_sub_usb_a1_vbus { + #gpio-cells = <0>; + gpios = <&gpiod 4 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + #gpio-cells = <0>; + gpios = <&gpio9 1 GPIO_OUTPUT>; + enum-name = "GPIO_EN_USB_A_5V"; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + #gpio-cells = <0>; + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + #gpio-cells = <0>; + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + #gpio-cells = <0>; + gpios = <&gpio5 6 GPIO_INPUT>; + enum-name = "GPIO_EC_IMU_INT_L"; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + #gpio-cells = <0>; + gpios = <&gpio4 3 GPIO_INPUT>; + enum-name = "GPIO_IMVP9_VRRDY_OD"; + }; + gpio_lid_open: lid_open { + #gpio-cells = <0>; + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + #gpio-cells = <0>; + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + #gpio-cells = <0>; + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp1050_proc: pg_pp1050_proc { + #gpio-cells = <0>; + gpios = <&gpio4 1 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + #gpio-cells = <0>; + gpios = <&gpio4 2 GPIO_INPUT>; + enum-name = "GPIO_PG_PP5000_A_ODL"; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + #gpio-cells = <0>; + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_PG_EC_RSMRST_ODL"; + }; + gpio_slp_s0_l: slp_s0_l { + #gpio-cells = <0>; + gpios = <&gpio9 7 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S0_L"; + }; + gpio_slp_s3_l: slp_s3_l { + #gpio-cells = <0>; + gpios = <&gpioa 5 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S3_L"; + }; + gpio_slp_s4_l: slp_s4_l { + #gpio-cells = <0>; + gpios = <&gpio7 0 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S4_L"; + }; + gpio_slp_sus_l: slp_sus_l { + #gpio-cells = <0>; + gpios = <&gpio6 2 GPIO_INPUT>; + enum-name = "GPIO_SLP_SUS_L"; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + #gpio-cells = <0>; + gpios = <&gpiod 5 GPIO_OUTPUT>; + }; + gpio_sys_rst_odl: sys_rst_odl { + #gpio-cells = <0>; + gpios = <&gpioc 5 GPIO_ODR_LOW>; + enum-name = "GPIO_SYS_RESET_L"; + }; + gpio_tablet_mode_l: tablet_mode_l { + #gpio-cells = <0>; + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + #gpio-cells = <0>; + gpios = <&gpio8 5 GPIO_OUTPUT>; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + #gpio-cells = <0>; + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_USB_C0_PD_INT_ODL"; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + #gpio-cells = <0>; + gpios = <&gpio9 2 GPIO_INPUT>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + #gpio-cells = <0>; + gpios = <&gpioe 3 GPIO_INPUT>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + #gpio-cells = <0>; + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + #gpio-cells = <0>; + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-name = "I2C_PORT_BATTERY"; + }; + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-name = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-name = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-name = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-name = "I2C_PORT_USB_C0_TCPC"; + }; + }; + + named-pwms { + compatible = "named-pwms"; + + pwm_pwm_kb_bl: pwm_kb_bl { + pwms = <&pwm6 6 0>; + }; + pwm_pwm_led_1_odl: pwm_led_1_odl { + pwms = <&pwm2 2 1>; + }; + pwm_pwm_led_2_odl: pwm_led_2_odl { + pwms = <&pwm0 0 1>; + }; + pwm_pwm_led_3_odl: pwm_led_3_odl { + pwms = <&pwm1 1 1>; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&i2c0_0 { + status = "okay"; +}; + +&i2c1_0 { + status = "okay"; +}; + +&i2c3_0 { + status = "okay"; +}; + +&i2c5_1 { + status = "okay"; +}; + +&i2c7_0 { + status = "okay"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm6 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/nivviks_motionsense.dts b/zephyr/projects/nissa/nivviks_motionsense.dts new file mode 100644 index 0000000000..1f244cab6f --- /dev/null +++ b/zephyr/projects/nissa/nivviks_motionsense.dts @@ -0,0 +1,155 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lid-mutex { + label = "LID_MUTEX"; + }; + + base_mutex: base-mutex { + label = "BASE_MUTEX"; + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <(-1) 0 0 + 0 (-1) 0 + 0 0 1>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_data: lsm6dso-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The label "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + */ + motionsense-sensor { + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + label = "Base Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + label = "Base Gyro"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_data>; + }; + + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + label = "Lid Accel"; + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + label = "SENSOR_CONFIG_EC_S0"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + label = "SENSOR_CONFIG_EC_S3"; + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&gpio_imu_int_l>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/nivviks_overlay.dts b/zephyr/projects/nissa/nivviks_overlay.dts new file mode 100644 index 0000000000..bac45f91c1 --- /dev/null +++ b/zephyr/projects/nissa/nivviks_overlay.dts @@ -0,0 +1,186 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-pins = < + &gpio_gsc_ec_pwr_btn_odl + &gpio_lid_open + >; + }; + + named-gpios { + /* + * TODO(b:212490923): decide what to do with these sorts of + * signals that have varying function depending on the present + * sub-board. + */ + gpio_sub_usb_c1_int_odl: sub_usb_c1_int_odl { + #gpio-cells = <0>; + gpios = <&gpio0 2 GPIO_INPUT>; + enum-name = "GPIO_USB_C1_PD_INT_ODL"; + }; + }; + + named-temp-sensors { + memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "DDR and SOC"; + enum-name = "TEMP_SENSOR_1"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_1>; + }; + charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + label = "Charger"; + enum-name = "TEMP_SENSOR_2"; + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + adc = <&adc_temp_sensor_2>; + }; + }; + + /* + * Alias kblist to correct node. + * It would be nice to use alias here, but the code + * uses DT_NODELABEL to directly reference the node label. + */ + named-pwms { + compatible = "named-pwms"; + + kblight: pwm_kb_bl { + }; + }; + + usbc { + port0 { + bc12 { + compatible = "pericom,pi3usb9201"; + port = <&i2c_ec_i2c_usb_c0>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1 { + bc12 { + compatible = "pericom,pi3usb9201"; + port = <&i2c_ec_i2c_sub_usb_c1>; + }; + }; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +/* Power switch logic input pads */ +/* LID_OPEN_OD */ +&psl_in1 { + flag = <NPCX_PSL_RISING_EDGE>; +}; + +/* ACOK_EC_OD */ +&psl_in2 { + flag = <NPCX_PSL_RISING_EDGE>; +}; + +/* GSC_EC_PWR_BTN_ODL */ +&psl_in3 { + flag = <NPCX_PSL_FALLING_EDGE>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + label = "EEPROM_CBI"; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + wp-gpios = <&gpio_ec_wp_odl>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +/* PWM frequencies */ + +&pwm_pwm_kb_bl { + frequency = <10000>; +}; + +&pwm_pwm_led_1_odl { + frequency = <324>; +}; + +&pwm_pwm_led_2_odl { + frequency = <324>; +}; + +&pwm_pwm_led_3_odl { + frequency = <324>; +}; + +/* Enable LEDs to work while CPU suspended */ +&pwm0 { + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +&pwm1 { + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; + +&pwm2 { + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; +}; diff --git a/zephyr/projects/nissa/prj.conf b/zephyr/projects/nissa/prj.conf new file mode 100644 index 0000000000..80f1d03d96 --- /dev/null +++ b/zephyr/projects/nissa/prj.conf @@ -0,0 +1,3 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. diff --git a/zephyr/projects/nissa/prj_nereid.conf b/zephyr/projects/nissa/prj_nereid.conf new file mode 100644 index 0000000000..d3294b9853 --- /dev/null +++ b/zephyr/projects/nissa/prj_nereid.conf @@ -0,0 +1,77 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_SHIMMED_TASKS=y + +# Variant config +CONFIG_BOARD_NEREID=y + +# Bringup options +CONFIG_KERNEL_SHELL=y +CONFIG_PLATFORM_EC_SYSTEM_UNLOCKED=y +CONFIG_PLATFORM_EC_HOSTCMD=n + +CONFIG_PLATFORM_EC_POWER_BUTTON=n +CONFIG_PLATFORM_EC_LID_SWITCH=y +CONFIG_PLATFORM_EC_SWITCH=n +CONFIG_LTO=y +CONFIG_PLATFORM_EC_VBOOT_EFS2=n +CONFIG_PLATFORM_EC_VBOOT_HASH=n +CONFIG_PLATFORM_EC_I2C=y +CONFIG_PLATFORM_EC_BACKLIGHT_LID=y + +# SoC configuration +CONFIG_AP=n +#CONFIG_AP_X86_INTEL_ADL=y + +# Host command +#CONFIG_PLATFORM_EC_HOSTCMD=y +#CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y +#CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y +#CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y +#CONFIG_PLATFORM_EC_HOST_COMMAND_STATUS=y + +# Temperature sensors - disabled until host interface is available +#CONFIG_PLATFORM_EC_TEMP_SENSOR=y +#CONFIG_PLATFORM_EC_THERMISTOR=y + +# PWM +CONFIG_PWM=y +CONFIG_PWM_SHELL=y +CONFIG_PLATFORM_EC_PWM=y +#CONFIG_PLATFORM_EC_PWM_KBLIGHT=y + +# Keyboard - disabled until host interface is available +CONFIG_CROS_KB_RAW_ITE=n +CONFIG_PLATFORM_EC_KEYBOARD=n +#CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y +#CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y +#CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y +#CONFIG_PLATFORM_EC_CMD_BUTTON=y + +# MKBP event mask +#CONFIG_PLATFORM_EC_MKBP_EVENT=y +#CONFIG_PLATFORM_EC_MKBP_INPUT_DEVICES=y +#CONFIG_PLATFORM_EC_MKBP_EVENT_WAKEUP_MASK=y +#CONFIG_PLATFORM_EC_MKBP_HOST_EVENT_WAKEUP_MASK=y +#CONFIG_PLATFORM_EC_MKBP_USE_GPIO=y + +# TODO(b/188605676): bring these features up +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n +CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n +CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n + +# Power Sequencing +# TODO(b/203446068): Implement ADL-N power sequence. +#CONFIG_PLATFORM_EC_POWERSEQ=y +#CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n +#CONFIG_CHIPSET_ALDERLAKE_SLG4BD44540=y +#CONFIG_PLATFORM_EC_POWERSEQ_RTC_RESET=n +#CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y +#CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y +# Treat 2nd reset from H1 as Power-On +CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y diff --git a/zephyr/projects/nissa/prj_nivviks.conf b/zephyr/projects/nissa/prj_nivviks.conf new file mode 100644 index 0000000000..12b77dcf1b --- /dev/null +++ b/zephyr/projects/nissa/prj_nivviks.conf @@ -0,0 +1,126 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y + +# Bringup +CONFIG_PLATFORM_EC_BRINGUP=y +CONFIG_SHIMMED_TASKS=y +CONFIG_SHELL_MINIMAL=n +CONFIG_LOG=y +CONFIG_LOG_BACKEND_UART=y + +# Variant config +CONFIG_BOARD_NIVVIKS=y + +CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_LID_SWITCH=y +CONFIG_PLATFORM_EC_SWITCH=y +CONFIG_LTO=y +CONFIG_CROS_FLASH_NPCX=y +CONFIG_CROS_SYSTEM_NPCX=y +CONFIG_PLATFORM_EC_VBOOT_EFS2=y +CONFIG_PLATFORM_EC_VBOOT_HASH=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_SYSINFO=y +CONFIG_PLATFORM_EC_I2C=y +CONFIG_PLATFORM_EC_BACKLIGHT_LID=y + +# SoC configuration +CONFIG_AP=y +CONFIG_AP_X86_INTEL_ADL=y +CONFIG_FPU=y +CONFIG_ARM_MPU=y + +# eSPI +CONFIG_ESPI=y +CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4=y + +# Host command +CONFIG_PLATFORM_EC_HOSTCMD=y + +# Sensors +CONFIG_PLATFORM_EC_LID_ANGLE=y +CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y +CONFIG_PLATFORM_EC_MOTIONSENSE=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCELS=y +CONFIG_PLATFORM_EC_CONSOLE_CMD_ACCEL_INFO=y +CONFIG_PLATFORM_EC_ACCEL_FIFO=y +CONFIG_PLATFORM_EC_ACCEL_INTERRUPTS=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO_AS_BASE=y +CONFIG_PLATFORM_EC_ACCEL_LIS2DW12=y + +# Temperature sensors +CONFIG_PLATFORM_EC_TEMP_SENSOR=y +CONFIG_PLATFORM_EC_THERMISTOR=y + +# Miscellaneous configs +CONFIG_PLATFORM_EC_HIBERNATE_PSL=y + +# PWM +CONFIG_PWM=y +CONFIG_PWM_SHELL=n +CONFIG_PLATFORM_EC_PWM=y +CONFIG_PLATFORM_EC_PWM_KBLIGHT=y + +# Keyboard +CONFIG_PLATFORM_EC_KEYBOARD=y +CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042=y +CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y +CONFIG_PLATFORM_EC_VOLUME_BUTTONS=y +CONFIG_PLATFORM_EC_CMD_BUTTON=n +CONFIG_CROS_KB_RAW_NPCX=y + +CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API=y + +CONFIG_SYSCON=y + +# CBI EEPROM +CONFIG_PLATFORM_EC_CBI_EEPROM=y +CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=y + +# USB-C/PD +CONFIG_PLATFORM_EC_USBC=y +CONFIG_PLATFORM_EC_USB_VID=0x18d1 +CONFIG_PLATFORM_EC_USB_PID=0x505a +CONFIG_PLATFORM_EC_USB_PD_PORT_MAX_COUNT=2 + +# TCPC+PPC: both C0 and C1 are RAA489000, but C1 may not be present +CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=y +CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE_TCPC=y + +CONFIG_PLATFORM_EC_USB_MUX_VIRTUAL=y +CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y + +# TODO(b/211693800): configure USB retimers + +# Charger/battery +CONFIG_PLATFORM_EC_BATTERY=y +CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y +CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y +CONFIG_PLATFORM_EC_BATTERY_SMART=y + +CONFIG_PLATFORM_EC_CHARGER=y +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10 + +# TODO(b/188605676): bring these features up +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n + +# Power Sequencing +# TODO(b/203446068): Implement ADL-N power sequence. +#CONFIG_PLATFORM_EC_POWERSEQ=y +#CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n +#CONFIG_CHIPSET_ALDERLAKE_SLG4BD44540=y +#CONFIG_PLATFORM_EC_POWERSEQ_RTC_RESET=n +#CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y +#CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y +# Treat 2nd reset from H1 as Power-On +CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y diff --git a/zephyr/projects/nissa/src/charger.c b/zephyr/projects/nissa/src/charger.c new file mode 100644 index 0000000000..32dff4c403 --- /dev/null +++ b/zephyr/projects/nissa/src/charger.c @@ -0,0 +1,37 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "usb_pd.h" + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_USB_C0_TCPC, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, + /* + * TODO(b:212490923) port 1 is present on sub-boards 1 and 2 with same + * configuration as port 0 but on I2C_PORT_USB_C1_TCPC. + */ +}; +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} diff --git a/zephyr/projects/nissa/src/usbc.c b/zephyr/projects/nissa/src/usbc.c new file mode 100644 index 0000000000..4fd2335d01 --- /dev/null +++ b/zephyr/projects/nissa/src/usbc.c @@ -0,0 +1,286 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "usbc_ppc.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) + +struct ppc_config_t ppc_chips[] = {}; +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0, + }, + /* + * TODO(b:212490923) port 1 is present on sub-boards 1 and 2 with same + * configuration as port 0 but on I2C_PORT_USB_C1_TCPC. + */ +}; + +struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .usb_port = 0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + }, + /* + * TODO(b:212490923) port 1 is present on sub-boards 1 and 2 with same + * configuration. + */ +}; + +__override uint8_t board_get_usb_pd_port_count(void) +{ + /* TODO(b:212490923) enable port 1 if present (by returning 2). */ + return 1; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + int icl = MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT); + + /* + * Assume charger overdraws by about 4%, keeping the actual draw + * within spec. This adjustment can be changed with characterization + * of actual hardware. + */ + icl = icl * 96 / 100; + charge_set_input_current_limit(icl, charge_mv); +} + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && + port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + CPRINTS("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + CPRINTS("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + CPRINTS("p%d: sink path disable failed.", i); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + CPRINTS("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL)) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + /* TODO(b:212490923) ignore C1 interrupts if port is not present. */ + if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL)) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on. */ + return chipset_in_state(CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_ON); +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + task_set_event(PD_PORT_TO_TASK_ID(port), USB_CHG_EVENT_BC12); +} + +#define USBC_INT_POLL_DATA(port) poll_c ## port ## _int_data +#define USBC_INT_POLL(port) \ + static void poll_c ## port ## _int (void) \ + { \ + if (!gpio_get_level(GPIO_USB_C ## port ## _PD_INT_ODL)) { \ + usbc_interrupt_trigger(port); \ + hook_call_deferred(&USBC_INT_POLL_DATA(port), \ + USBC_INT_POLL_DELAY_US); \ + } \ + } + +USBC_INT_POLL(0) +USBC_INT_POLL(1) + +void usb_c0_interrupt(enum gpio_signal gpio) +{ + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(&USBC_INT_POLL_DATA(0), -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(0); + /* Check for lost interrupts in a bit */ + hook_call_deferred(&USBC_INT_POLL_DATA(0), USBC_INT_POLL_DELAY_US); +} + +void usb_c1_interrupt(enum gpio_signal gpio) +{ + hook_call_deferred(&USBC_INT_POLL_DATA(1), -1); + usbc_interrupt_trigger(1); + hook_call_deferred(&USBC_INT_POLL_DATA(1), USBC_INT_POLL_DELAY_US); +} + +static void usbc_init(void) +{ + gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL); +} +DECLARE_HOOK(HOOK_INIT, usbc_init, HOOK_PRIO_DEFAULT); diff --git a/zephyr/projects/npcx_evb/npcx7/gpio.dts b/zephyr/projects/npcx_evb/npcx7/gpio.dts index fb8f83803f..df28dad76c 100644 --- a/zephyr/projects/npcx_evb/npcx7/gpio.dts +++ b/zephyr/projects/npcx_evb/npcx7/gpio.dts @@ -8,62 +8,50 @@ compatible = "named-gpios"; recovery_l { - gpios = <&gpio0 3 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "RECOVERY_L"; + gpios = <&gpio0 3 GPIO_INPUT_PULL_UP>; }; wp_l { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_WP_L"; - label = "WP_L"; }; gpio_ac_present: ac_present { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "AC_PRESENT"; }; gpio_power_button_l: power_button_l { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "POWER_BUTTON_L"; }; gpio_lid_open: lid_open { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; entering_rw { gpios = <&gpio3 6 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "ENTERING_RW"; }; pch_wake_l { gpios = <&gpio5 0 GPIO_OUT_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "PCH_WAKE_L"; }; gpio_pgood_fan: pgood_fan { - gpios = <&gpioc 7 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpioc 7 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_PGOOD_FAN"; - label = "PGOOD_FAN"; }; spi_cs_l { gpios = <&gpioa 5 GPIO_OUT_HIGH>; - label = "SPI_CS_L"; }; board_version1 { gpios = <&gpio6 4 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION1"; - label = "BOARD_VERSION1"; }; board_version2 { gpios = <&gpio6 5 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION2"; - label = "BOARD_VERSION2"; }; board_version3 { gpios = <&gpio6 6 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION3"; - label = "BOARD_VERSION3"; }; }; diff --git a/zephyr/projects/npcx_evb/npcx7/pwm.dts b/zephyr/projects/npcx_evb/npcx7/pwm.dts index 73312f684c..448fc53f7a 100644 --- a/zephyr/projects/npcx_evb/npcx7/pwm.dts +++ b/zephyr/projects/npcx_evb/npcx7/pwm.dts @@ -9,12 +9,10 @@ pwm_fan: fan { pwms = <&pwm0 0 0>; - label = "FAN"; frequency = <25000>; }; kblight: kblight { pwms = <&pwm2 0 0>; - label = "KBLIGHT"; frequency = <10000>; }; }; diff --git a/zephyr/projects/npcx_evb/npcx9/gpio.dts b/zephyr/projects/npcx_evb/npcx9/gpio.dts index fb8f83803f..df28dad76c 100644 --- a/zephyr/projects/npcx_evb/npcx9/gpio.dts +++ b/zephyr/projects/npcx_evb/npcx9/gpio.dts @@ -8,62 +8,50 @@ compatible = "named-gpios"; recovery_l { - gpios = <&gpio0 3 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "RECOVERY_L"; + gpios = <&gpio0 3 GPIO_INPUT_PULL_UP>; }; wp_l { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_WP_L"; - label = "WP_L"; }; gpio_ac_present: ac_present { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "AC_PRESENT"; }; gpio_power_button_l: power_button_l { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "POWER_BUTTON_L"; }; gpio_lid_open: lid_open { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN"; }; entering_rw { gpios = <&gpio3 6 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "ENTERING_RW"; }; pch_wake_l { gpios = <&gpio5 0 GPIO_OUT_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "PCH_WAKE_L"; }; gpio_pgood_fan: pgood_fan { - gpios = <&gpioc 7 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpioc 7 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_PGOOD_FAN"; - label = "PGOOD_FAN"; }; spi_cs_l { gpios = <&gpioa 5 GPIO_OUT_HIGH>; - label = "SPI_CS_L"; }; board_version1 { gpios = <&gpio6 4 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION1"; - label = "BOARD_VERSION1"; }; board_version2 { gpios = <&gpio6 5 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION2"; - label = "BOARD_VERSION2"; }; board_version3 { gpios = <&gpio6 6 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION3"; - label = "BOARD_VERSION3"; }; }; diff --git a/zephyr/projects/npcx_evb/npcx9/pwm.dts b/zephyr/projects/npcx_evb/npcx9/pwm.dts index 73312f684c..448fc53f7a 100644 --- a/zephyr/projects/npcx_evb/npcx9/pwm.dts +++ b/zephyr/projects/npcx_evb/npcx9/pwm.dts @@ -9,12 +9,10 @@ pwm_fan: fan { pwms = <&pwm0 0 0>; - label = "FAN"; frequency = <25000>; }; kblight: kblight { pwms = <&pwm2 0 0>; - label = "KBLIGHT"; frequency = <10000>; }; }; diff --git a/zephyr/projects/skyrim/BUILD.py b/zephyr/projects/skyrim/BUILD.py new file mode 100644 index 0000000000..03bade7c2f --- /dev/null +++ b/zephyr/projects/skyrim/BUILD.py @@ -0,0 +1,30 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +def register_variant(project_name): + register_npcx_project( + project_name=project_name, + zephyr_board="npcx9", + dts_overlays=[ + # Common to all projects. + here / "adc.dts", + here / "battery.dts", + here / "fan.dts", + here / "gpio.dts", + here / "i2c.dts", + here / "pwm.dts", + # Project-specific DTS customizations. + here / f"{project_name}.dts", + ], + kconfig_files=[ + here / f"prj_{project_name}.conf", + ], + ) + + +register_variant(project_name="skyrim") + +# TODO: Deprecate guybrush build after skyrim hardware is readily available. +register_variant(project_name="guybrush") diff --git a/zephyr/projects/guybrush/CMakeLists.txt b/zephyr/projects/skyrim/CMakeLists.txt index 30e8b8c611..f75113bc21 100644 --- a/zephyr/projects/guybrush/CMakeLists.txt +++ b/zephyr/projects/skyrim/CMakeLists.txt @@ -7,9 +7,11 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(guybrush) -zephyr_library_include_directories(include) +zephyr_library_include_directories_ifdef(CONFIG_BOARD_SKYRIM include) +zephyr_library_include_directories_ifdef(CONFIG_BOARD_GUYBRUSH include_guybrush) -zephyr_library_sources("power_signals.c") +zephyr_library_sources_ifdef(CONFIG_BOARD_SKYRIM "power_signals.c") +zephyr_library_sources_ifdef(CONFIG_BOARD_GUYBRUSH "power_signals_guybrush.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "usbc_config.c" diff --git a/zephyr/projects/skyrim/Kconfig b/zephyr/projects/skyrim/Kconfig new file mode 100644 index 0000000000..ea68baf71b --- /dev/null +++ b/zephyr/projects/skyrim/Kconfig @@ -0,0 +1,17 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +config BOARD_GUYBRUSH + bool "Google Guybrush Board" + help + Build Google Guybrush reference board. This board build is a + prototype rather than a releasing product. + +config BOARD_SKYRIM + bool "Google Skyrim Board" + help + Build Google Skyrim reference board. This board uses an AMD SoC + and NPCX9 EC + +source "Kconfig.zephyr" diff --git a/zephyr/projects/skyrim/adc.dts b/zephyr/projects/skyrim/adc.dts new file mode 100644 index 0000000000..fa9db4ece8 --- /dev/null +++ b/zephyr/projects/skyrim/adc.dts @@ -0,0 +1,85 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + named-adc-channels { + compatible = "named-adc-channels"; + + adc_temp_charger: temp-charger { + label = "CHARGER"; + enum-name = "ADC_TEMP_SENSOR_CHARGER"; + channel = <1>; + }; + adc_temp_memory: temp-memory { + label = "MEMORY"; + enum-name = "ADC_TEMP_SENSOR_MEMORY"; + channel = <2>; + }; + adc_core_imon1: core-imon1 { + label = "CORE_I"; + enum-name = "ADC_CORE_IMON1"; + channel = <3>; + }; + adc_core_imon2: core-imon2 { + label = "SOC_I"; + enum-name = "ADC_SOC_IMON2"; + channel = <4>; + }; + }; + + named-temp-sensors { + soc-tmp112 { + compatible = "cros-ec,temp-sensor-tmp112"; + label = "SOC"; + enum-name = "TEMP_SENSOR_SOC"; + tmp112-name = "TMP112_SOC"; + port = <&i2c_sensor>; + i2c-addr-flags = "TMP112_I2C_ADDR_FLAGS0"; + temp_host_high = <100>; + temp_host_halt = <105>; + temp_host_release_high = <80>; + temp_fan_off = <0>; + temp_fan_max = <70>; + }; + charger-thermistor { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + label = "Charger"; + enum-name = "TEMP_SENSOR_CHARGER"; + temp_host_high = <100>; + temp_host_halt = <105>; + temp_host_release_high = <80>; + adc = <&adc_temp_charger>; + }; + memory-thermistor { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_30K9_47K_4050B>; + label = "Memory"; + enum-name = "TEMP_SENSOR_MEMORY"; + temp_host_high = <100>; + temp_host_halt = <105>; + temp_host_release_high = <80>; + adc = <&adc_temp_memory>; + }; + amb-tmp112 { + compatible = "cros-ec,temp-sensor-tmp112"; + label = "Ambient"; + enum-name = "TEMP_SENSOR_AMB"; + tmp112-name = "TMP112_AMB"; + port = <&i2c_sensor>; + i2c-addr-flags = "TMP112_I2C_ADDR_FLAGS1"; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&thermistor_3V3_30K9_47K_4050B { + status = "okay"; +}; diff --git a/zephyr/projects/corsola/kingler/battery.dts b/zephyr/projects/skyrim/battery.dts index 02a6d0d3b9..02a6d0d3b9 100644 --- a/zephyr/projects/corsola/kingler/battery.dts +++ b/zephyr/projects/skyrim/battery.dts diff --git a/zephyr/projects/guybrush/fan.dts b/zephyr/projects/skyrim/fan.dts index 7ab15229e1..7ab15229e1 100644 --- a/zephyr/projects/guybrush/fan.dts +++ b/zephyr/projects/skyrim/fan.dts diff --git a/zephyr/projects/skyrim/gpio.dts b/zephyr/projects/skyrim/gpio.dts new file mode 100644 index 0000000000..8e55257f7f --- /dev/null +++ b/zephyr/projects/skyrim/gpio.dts @@ -0,0 +1,216 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* GPIOs shared by all boards */ + named-gpios { + compatible = "named-gpios"; + + ccd_mode_odl { + gpios = <&gpioc 6 GPIO_ODR_HIGH>; + }; + ec_gsc_packet_mode { + gpios = <&gpiob 1 GPIO_OUT_LOW>; + }; + mech_pwr_btn_odl { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + slp_s3_l { + gpios = <&gpio6 1 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S3_L"; + }; + slp_s5_l { + gpios = <&gpio7 2 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S5_L"; + }; + pg_pwr_s5 { + gpios = <&gpioc 0 GPIO_INPUT>; + enum-name = "GPIO_S5_PGOOD"; + }; + gpio_s0_pgood: pg_pcore_s0_r_od { + gpios = <&gpiob 6 GPIO_INPUT>; + enum-name = "GPIO_S0_PGOOD"; + }; + acok_od { + gpios = <&gpio0 0 GPIO_INPUT>; + enum-name = "GPIO_AC_PRESENT"; + }; + en_pwr_s5 { + gpios = <&gpiob 7 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_PWR_A"; + }; + en_pwr_s0_r { + gpios = <&gpiof 1 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_PWR_S0_R"; + }; + en_pwr_pcore_s0_r { + gpios = <&gpioe 1 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_PWR_PCORE_S0_R"; + }; + ec_sys_rst_l { + gpios = <&gpio7 6 GPIO_ODR_HIGH>; + enum-name = "GPIO_SYS_RESET_L"; + }; + ec_soc_rsmrst_l { + gpios = <&gpioc 5 GPIO_OUT_LOW>; + enum-name = "GPIO_PCH_RSMRST_L"; + }; + ec_soc_wake_l { + gpios = <&gpio0 3 GPIO_OUT_HIGH>; + enum-name = "GPIO_EC_PCH_WAKE_ODL"; + }; + prochot_odl { + gpios = <&gpiod 5 GPIO_ODR_HIGH>; + enum-name = "GPIO_CPU_PROCHOT"; + }; + soc_alert_ec_l { + gpios = <&gpioe 2 GPIO_INPUT>; + }; + usb_c0_tcpc_int_odl { + gpios = <&gpioe 0 GPIO_INPUT>; + enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; + }; + usb_c1_tcpc_int_odl { + gpios = <&gpioc 7 GPIO_INPUT>; + enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; + }; + usb_c0_ppc_int_odl { + gpios = <&gpio7 5 GPIO_INPUT>; + enum-name = "GPIO_USB_C0_PPC_INT_ODL"; + }; + usb_c1_ppc_int_odl { + gpios = <&gpiod 4 GPIO_INPUT>; + enum-name = "GPIO_USB_C1_PPC_INT_ODL"; + }; + usb_c0_bc12_int_odl { + gpios = <&gpioa 4 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_USB_C0_BC12_INT_ODL"; + }; + usb_c1_bc12_int_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_USB_C1_BC12_INT_ODL"; + }; + usb_c0_tcpc_rst_l { + gpios = <&gpio3 4 GPIO_OUT_HIGH>; + enum-name = "GPIO_USB_C0_TCPC_RST_L"; + }; + usb_c1_tcpc_rst_l { + gpios = <&gpio3 7 GPIO_OUT_HIGH>; + enum-name = "GPIO_USB_C1_TCPC_RST_L"; + }; + usb_c0_hpd { + gpios = <&gpiof 5 GPIO_OUT_LOW>; + enum-name = "GPIO_USB_C0_DP_HPD"; + }; + usb_c1_hpd { + gpios = <&gpiof 4 GPIO_OUT_LOW>; + enum-name = "GPIO_USB_C1_DP_HPD"; + }; + lid_open { + gpios = <&gpio0 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + ec_batt_pres_odl { + gpios = <&gpio9 4 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + ec_disable_disp_bl { + gpios = <&gpioa 6 GPIO_OUT_HIGH>; + }; + ec_i2c_usb_a0_c0_scl { + gpios = <&gpiob 5 GPIO_INPUT>; + }; + ec_i2c_usb_a0_c0_sda { + gpios = <&gpiob 4 GPIO_INPUT>; + }; + ec_i2c_usb_a1_c1_scl { + gpios = <&gpio9 0 GPIO_INPUT>; + }; + ec_i2c_usb_a1_c1_sda { + gpios = <&gpio8 7 GPIO_INPUT>; + }; + ec_i2c_batt_scl { + gpios = <&gpio9 2 GPIO_INPUT>; + }; + ec_i2c_batt_sda { + gpios = <&gpio9 1 GPIO_INPUT>; + }; + ec_i2c_usbc_mux_scl { + gpios = <&gpiod 1 GPIO_INPUT>; + }; + ec_i2c_usbc_mux_sda { + gpios = <&gpiod 0 GPIO_INPUT>; + }; + ec_i2c_power_scl { + gpios = <&gpiof 3 GPIO_INPUT>; + }; + ec_i2c_power_sda { + gpios = <&gpiof 2 GPIO_INPUT>; + }; + ec_i2c_cbi_scl { + gpios = <&gpio3 3 GPIO_INPUT>; + }; + ec_i2c_cbi_sda { + gpios = <&gpio3 6 GPIO_INPUT>; + }; + ec_i2c_sensor_scl { + gpios = <&gpioe 4 GPIO_INPUT>; + }; + ec_i2c_sensor_sda { + gpios = <&gpioe 3 GPIO_INPUT>; + }; + ec_i2c_soc_sic { + gpios = <&gpiob 3 GPIO_INPUT>; + }; + ec_i2c_soc_sid { + gpios = <&gpiob 2 GPIO_INPUT>; + }; + en_kb_bl { + gpios = <&gpio9 7 GPIO_OUT_HIGH>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + ec_kso_02_inv { + gpios = <&gpio1 7 GPIO_OUT_LOW>; + enum-name = "GPIO_KBD_KSO2"; + }; + ec_espi_rst_l { + gpios = <&gpio5 4 GPIO_PULL_UP>; + }; + 6axis_int_l { + gpios = <&gpioa 0 GPIO_INPUT_PULL_UP>; + }; + tablet_mode { + gpios = <&gpioc 1 GPIO_INPUT>; + }; + ec_gpio56 { + gpios = <&gpio5 6 GPIO_INPUT_PULL_UP>; + }; + ec_flprg2 { + gpios = <&gpio8 6 GPIO_INPUT_PULL_UP>; + }; + }; + + vsby-psl-in-list { + /* PSL_IN1/2/4 are used to wake */ + psl-in-pads = <&psl_in1 &psl_in2 &psl_in4>; + }; +}; + +/* PSL input pads*/ +&psl_in1 { + /* MECH_PWR_BTN_ODL */ + flag = <NPCX_PSL_FALLING_EDGE>; +}; + +&psl_in2 { + /* ACOK_OD */ + flag = <NPCX_PSL_RISING_EDGE>; +}; + +&psl_in4 { + /* LID_OPEN */ + flag = <NPCX_PSL_RISING_EDGE>; +}; diff --git a/zephyr/projects/skyrim/guybrush.dts b/zephyr/projects/skyrim/guybrush.dts new file mode 100644 index 0000000000..9fbc31c2bc --- /dev/null +++ b/zephyr/projects/skyrim/guybrush.dts @@ -0,0 +1,111 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-gpios { + /* Guybrush-specific GPIO customizations */ + ec_wp_l { + gpios = <&gpio5 0 GPIO_INPUT>; + enum-name = "GPIO_WP_L"; + }; + ec_pwr_btn_odl { + gpios = <&gpio0 1 GPIO_INPUT>; + enum-name = "GPIO_EC_PWR_BTN_ODL"; + }; + slp_s3_s0i3_l { + gpios = <&gpio7 4 GPIO_INPUT>; + enum-name = "GPIO_PCH_SLP_S0_L"; + }; + ec_pcore_int_odl { + gpios = <&gpiof 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_EC_PCORE_INT_ODL"; + }; + pg_groupc_s0_od { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_PG_GROUPC_S0_OD"; + }; + pg_lpddr4x_s3_od { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_PG_LPDDR4X_S3_OD"; + }; + ec_soc_pwr_good { + gpios = <&gpiod 3 GPIO_OUT_LOW>; + enum-name = "GPIO_PCH_SYS_PWROK"; + }; + ec_entering_rw { + gpios = <&gpio6 6 GPIO_OUT_LOW>; + enum-name = "GPIO_ENTERING_RW"; + }; + ec_clr_cmos { + gpios = <&gpioa 1 GPIO_OUT_LOW>; + }; + ec_mem_event { + gpios = <&gpioa 5 GPIO_OUT_LOW>; + }; + ec_soc_pwr_btn_l { + gpios = <&gpio6 3 GPIO_OUT_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + ec_soc_int_l { + gpios = <&gpio8 3 GPIO_OUT_HIGH>; + }; + soc_thermtrip_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + }; + usb_c0_c1_fault_odl { + gpios = <&gpio7 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_USB_C0_C1_FAULT_ODL"; + }; + 3axis_int_l { + gpios = <&gpioa 2 GPIO_INPUT_PULL_DOWN>; + }; + voldn_btn_odl { + gpios = <&gpioa 7 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + volup_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + ec_ps2_clk { + gpios = <&gpio6 7 GPIO_INPUT_PULL_UP>; + }; + ec_ps2_dat { + gpios = <&gpio7 0 GPIO_INPUT_PULL_UP>; + }; + ec_ps2_rst { + gpios = <&gpio6 2 GPIO_INPUT_PULL_UP>; + }; + ec_gpiob0 { + gpios = <&gpiob 0 GPIO_INPUT_PULL_UP>; + }; + ec_gpio81 { + gpios = <&gpio8 1 GPIO_INPUT_PULL_UP>; + }; + ec_psl_gpo { + gpios = <&gpiod 7 GPIO_INPUT_PULL_UP>; + }; + ec_pwm7 { + gpios = <&gpio6 0 GPIO_INPUT_PULL_UP>; + }; + }; + + def-lvol-io-list { + compatible = "nuvoton,npcx-lvolctrl-def"; + + /* Low voltage on I2C6_1 */ + lvol-io-pads = <&lvol_ioe4 &lvol_ioe3>; + }; + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_temp_soc: temp-soc { + label = "SOC"; + enum-name = "ADC_TEMP_SENSOR_SOC"; + channel = <0>; + }; + }; +}; diff --git a/zephyr/projects/guybrush/i2c.dts b/zephyr/projects/skyrim/i2c.dts index 7b4c0753bc..e12591c7bd 100644 --- a/zephyr/projects/guybrush/i2c.dts +++ b/zephyr/projects/skyrim/i2c.dts @@ -20,32 +20,37 @@ i2c_tcpc0: tcpc0 { i2c-port = <&i2c0_0>; enum-name = "I2C_PORT_TCPC0"; - label = "TCPC0"; }; i2c_tcpc1: tcpc1 { i2c-port = <&i2c1_0>; enum-name = "I2C_PORT_TCPC1"; - label = "TCPC1"; }; battery { i2c-port = <&i2c2_0>; remote-port = <0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; usb_mux { i2c-port = <&i2c3_0>; enum-name = "I2C_PORT_USB_MUX"; - label = "USB_MUX"; }; charger { i2c-port = <&i2c4_1>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; + }; + + eeprom { + i2c-port = <&i2c5_0>; + enum-name = "I2C_PORT_EEPROM"; + }; + + i2c_sensor: sensor { + i2c-port = <&i2c6_1>; + enum-name = "I2C_PORT_SENSOR"; }; }; @@ -96,3 +101,26 @@ &i2c_ctrl4 { status = "okay"; }; + +&i2c5_0 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + reg = <0x50>; + label = "EEPROM_CBI"; + }; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c6_1 { + status = "okay"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c_ctrl6 { + status = "okay"; +}; diff --git a/zephyr/projects/skyrim/include/gpio_map.h b/zephyr/projects/skyrim/include/gpio_map.h new file mode 100644 index 0000000000..89caf99a88 --- /dev/null +++ b/zephyr/projects/skyrim/include/gpio_map.h @@ -0,0 +1,72 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __ZEPHYR_GPIO_MAP_H +#define __ZEPHYR_GPIO_MAP_H + +#include <devicetree.h> +#include <gpio_signal.h> + +/* Power input signals */ +enum power_signal { + X86_SLP_S3_N, /* SOC -> SLP_S3_L */ + X86_SLP_S5_N, /* SOC -> SLP_S5_L */ + + X86_S0_PGOOD, /* PMIC -> S0_PWROK_OD */ + X86_S5_PGOOD, /* PMIC -> S5_PWROK */ + + /* Number of X86 signals */ + POWER_SIGNAL_COUNT, +}; + +#define GPIO_ENTERING_RW GPIO_UNIMPLEMENTED +#define GPIO_PCH_SYS_PWROK GPIO_UNIMPLEMENTED + +/* + * Set EC_CROS_GPIO_INTERRUPTS to a space-separated list of GPIO_INT items. + * + * Each GPIO_INT requires three parameters: + * gpio_signal - The enum gpio_signal for the interrupt gpio + * interrupt_flags - The interrupt-related flags (e.g. GPIO_INT_EDGE_BOTH) + * handler - The platform/ec interrupt handler. + * + * Ensure that this files includes all necessary headers to declare all + * referenced handler functions. + * + * For example, one could use the follow definition: + * #define EC_CROS_GPIO_INTERRUPTS \ + * GPIO_INT(NAMED_GPIO(h1_ec_pwr_btn_odl), GPIO_INT_EDGE_BOTH, button_print) + */ +#define EC_CROS_GPIO_INTERRUPTS \ + GPIO_INT(GPIO_LID_OPEN, GPIO_INT_EDGE_BOTH, lid_interrupt) \ + GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \ + GPIO_INT(GPIO_POWER_BUTTON_L, GPIO_INT_EDGE_BOTH, \ + power_button_interrupt) \ + GPIO_INT(GPIO_PCH_SLP_S3_L, GPIO_INT_EDGE_BOTH, baseboard_en_pwr_s0) \ + GPIO_INT(GPIO_PCH_SLP_S5_L, GPIO_INT_EDGE_BOTH, \ + power_signal_interrupt) \ + GPIO_INT(GPIO_S5_PGOOD, GPIO_INT_EDGE_BOTH, baseboard_en_pwr_s0) \ + GPIO_INT(GPIO_S0_PGOOD, GPIO_INT_EDGE_BOTH, power_signal_interrupt) \ + GPIO_INT(GPIO_PG_GROUPC_S0_OD, GPIO_INT_EDGE_BOTH, \ + baseboard_set_en_pwr_pcore) \ + GPIO_INT(GPIO_PG_LPDDR5_S3_OD, GPIO_INT_EDGE_BOTH, \ + baseboard_set_en_pwr_pcore) \ + GPIO_INT(GPIO_PG_LPDDR5_S0_OD, GPIO_INT_EDGE_BOTH, \ + baseboard_set_soc_pwr_pgood) \ + GPIO_INT(GPIO_VOLUME_UP_L, GPIO_INT_EDGE_BOTH, button_interrupt) \ + GPIO_INT(GPIO_USB_C0_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + tcpc_alert_event) \ + GPIO_INT(GPIO_USB_C1_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + tcpc_alert_event) \ + GPIO_INT(GPIO_USB_C0_PPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + ppc_interrupt) \ + GPIO_INT(GPIO_USB_C1_PPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + ppc_interrupt) \ + GPIO_INT(GPIO_USB_C0_BC12_INT_ODL, GPIO_INT_EDGE_FALLING, \ + bc12_interrupt) \ + GPIO_INT(GPIO_USB_C1_BC12_INT_ODL, GPIO_INT_EDGE_FALLING, \ + bc12_interrupt) + +#endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/projects/guybrush/include/gpio_map.h b/zephyr/projects/skyrim/include_guybrush/gpio_map.h index 77abf0919a..77abf0919a 100644 --- a/zephyr/projects/guybrush/include/gpio_map.h +++ b/zephyr/projects/skyrim/include_guybrush/gpio_map.h diff --git a/zephyr/projects/guybrush/led.c b/zephyr/projects/skyrim/led.c index 6a2a2e4609..6a2a2e4609 100644 --- a/zephyr/projects/guybrush/led.c +++ b/zephyr/projects/skyrim/led.c diff --git a/zephyr/projects/skyrim/power_signals.c b/zephyr/projects/skyrim/power_signals.c new file mode 100644 index 0000000000..9f39edf505 --- /dev/null +++ b/zephyr/projects/skyrim/power_signals.c @@ -0,0 +1,110 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "chipset.h" +#include "config.h" +#include "gpio.h" +#include "hooks.h" +#include "power.h" +#include "timer.h" + +/* Power Signal Input List */ +const struct power_signal_info power_signal_list[] = { + [X86_SLP_S3_N] = { + .gpio = GPIO_PCH_SLP_S3_L, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "SLP_S3_DEASSERTED", + }, + [X86_SLP_S5_N] = { + .gpio = GPIO_PCH_SLP_S5_L, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "SLP_S5_DEASSERTED", + }, + [X86_S0_PGOOD] = { + .gpio = GPIO_S0_PGOOD, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "S0_PGOOD", + }, + [X86_S5_PGOOD] = { + .gpio = GPIO_S5_PGOOD, + .flags = POWER_SIGNAL_ACTIVE_HIGH, + .name = "S5_PGOOD", + }, +}; +BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT); + +static void baseboard_interrupt_init(void) +{ + /* Enable Power Group interrupts. */ + gpio_enable_interrupt(GPIO_PG_GROUPC_S0_OD); + gpio_enable_interrupt(GPIO_PG_LPDDR5_S0_OD); + gpio_enable_interrupt(GPIO_PG_LPDDR5_S3_OD); +} +DECLARE_HOOK(HOOK_INIT, baseboard_interrupt_init, HOOK_PRIO_INIT_I2C + 1); + +/** + * b/175324615: On G3->S5, wait for RSMRST_L to be deasserted before asserting + * PCH_PWRBTN_L. + */ +void board_pwrbtn_to_pch(int level) +{ + timestamp_t start; + const uint32_t timeout_rsmrst_rise_us = 30 * MSEC; + + /* Add delay for G3 exit if asserting PWRBTN_L and RSMRST_L is low. */ + if (!level && !gpio_get_level(GPIO_PCH_RSMRST_L)) { + start = get_time(); + do { + usleep(200); + if (gpio_get_level(GPIO_PCH_RSMRST_L)) + break; + } while (time_since32(start) < timeout_rsmrst_rise_us); + + if (!gpio_get_level(GPIO_PCH_RSMRST_L)) + ccprints("Error pwrbtn: RSMRST_L still low"); + + msleep(16); + } + gpio_set_level(GPIO_PCH_PWRBTN_L, level); +} + +/* Note: signal parameter unused */ +void baseboard_set_soc_pwr_pgood(enum gpio_signal unused) +{ + gpio_set_level(GPIO_EC_SOC_PWR_GOOD, + gpio_get_level(GPIO_EN_PWR_PCORE_S0_R) && + gpio_get_level(GPIO_PG_LPDDR5_S0_OD)); +} + +/* Note: signal parameter unused */ +void baseboard_set_en_pwr_pcore(enum gpio_signal unused) +{ + /* + * EC must AND signals PG_LPDDR5_S3_OD, PG_GROUPC_S0_OD, and + * EN_PWR_S0_R + */ + gpio_set_level(GPIO_EN_PWR_PCORE_S0_R, + gpio_get_level(GPIO_PG_LPDDR5_S3_OD) && + gpio_get_level(GPIO_PG_GROUPC_S0_OD) && + gpio_get_level(GPIO_EN_PWR_S0_R)); + + /* Update EC_SOC_PWR_GOOD based on our results */ + baseboard_set_soc_pwr_pgood(unused); +} + +void baseboard_en_pwr_s0(enum gpio_signal signal) +{ + + /* EC must AND signals SLP_S3_L and PG_PWR_S5 */ + gpio_set_level(GPIO_EN_PWR_S0_R, + gpio_get_level(GPIO_PCH_SLP_S3_L) && + gpio_get_level(GPIO_S5_PGOOD)); + + /* Change EN_PWR_PCORE_S0_R if needed*/ + baseboard_set_en_pwr_pcore(signal); + + /* Now chain off to the normal power signal interrupt handler. */ + power_signal_interrupt(signal); +} diff --git a/zephyr/projects/guybrush/power_signals.c b/zephyr/projects/skyrim/power_signals_guybrush.c index eb27ea6c14..eb27ea6c14 100644 --- a/zephyr/projects/guybrush/power_signals.c +++ b/zephyr/projects/skyrim/power_signals_guybrush.c diff --git a/zephyr/projects/guybrush/prj.conf b/zephyr/projects/skyrim/prj.conf index 5adf663ad3..7d06df7aba 100644 --- a/zephyr/projects/guybrush/prj.conf +++ b/zephyr/projects/skyrim/prj.conf @@ -10,6 +10,7 @@ CONFIG_ESPI=y # Shell features CONFIG_SHELL_HELP=y CONFIG_SHELL_HISTORY=y +CONFIG_SHELL_TAB=y CONFIG_SHELL_TAB_AUTOCOMPLETION=y CONFIG_KERNEL_SHELL=y @@ -25,6 +26,19 @@ CONFIG_PLATFORM_EC_PORT80=y # Power button CONFIG_PLATFORM_EC_POWER_BUTTON=y +# ADC +CONFIG_PLATFORM_EC_ADC=y + +# CBI +CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=y +CONFIG_PLATFORM_EC_CBI_EEPROM=y + +# Temperature Sensors +CONFIG_PLATFORM_EC_TEMP_SENSOR=y +CONFIG_PLATFORM_EC_TEMP_SENSOR_TMP112=y +CONFIG_PLATFORM_EC_THERMISTOR=y +CONFIG_PLATFORM_EC_THROTTLE_AP=y + # External power CONFIG_PLATFORM_EC_HOSTCMD=y CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y @@ -99,6 +113,6 @@ CONFIG_PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG=n CONFIG_PLATFORM_EC_USB_PD_USB4=n CONFIG_PLATFORM_EC_USB_PD_VBUS_MEASURE_CHARGER=y -# This is not yet supported -CONFIG_PLATFORM_EC_BOARD_VERSION_CBI=n -CONFIG_PLATFORM_EC_BOARD_VERSION_GPIO=n +# Hibernate and wake +CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON=y +CONFIG_PLATFORM_EC_HIBERNATE_PSL=y diff --git a/zephyr/projects/guybrush/BUILD.py b/zephyr/projects/skyrim/prj_guybrush.conf index 03f3abe37f..fb82542eee 100644 --- a/zephyr/projects/guybrush/BUILD.py +++ b/zephyr/projects/skyrim/prj_guybrush.conf @@ -2,8 +2,5 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -register_npcx_project( - project_name="guybrush", - zephyr_board="npcx9", - dts_overlays=["battery.dts", "fan.dts", "gpio.dts", "i2c.dts", "pwm.dts"], -) +# Guybrush board-specific Kconfig settings. +CONFIG_BOARD_GUYBRUSH=y diff --git a/zephyr/projects/skyrim/prj_skyrim.conf b/zephyr/projects/skyrim/prj_skyrim.conf new file mode 100644 index 0000000000..a4da8a0562 --- /dev/null +++ b/zephyr/projects/skyrim/prj_skyrim.conf @@ -0,0 +1,6 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Skyrim reference-board-specific Kconfig settings. +CONFIG_BOARD_SKYRIM=y diff --git a/zephyr/projects/guybrush/pwm.dts b/zephyr/projects/skyrim/pwm.dts index dd9fc94eaa..8853615074 100644 --- a/zephyr/projects/guybrush/pwm.dts +++ b/zephyr/projects/skyrim/pwm.dts @@ -7,24 +7,20 @@ named-pwms { compatible = "named-pwms"; - pwm_fan: fan { + pwm_fan: ec_fan_pwm { pwms = <&pwm0 0 0>; - label = "FAN"; frequency = <25000>; }; - kblight: kblight { + kblight: pwm_kb_bl { pwms = <&pwm1 0 0>; - label = "KBLIGHT"; frequency = <100>; }; - led_charge: led_charge { + led_charge: ec_pwm_led_chrg_l { pwms = <&pwm2 0 0>; - label = "LED_CHARGE"; frequency = <100>; }; - led_full: led_full { + led_full: ec_pwm_led_full_l { pwms = <&pwm3 0 0>; - label = "LED_FULL"; frequency = <100>; }; }; diff --git a/zephyr/projects/skyrim/skyrim.dts b/zephyr/projects/skyrim/skyrim.dts new file mode 100644 index 0000000000..c55c57a655 --- /dev/null +++ b/zephyr/projects/skyrim/skyrim.dts @@ -0,0 +1,105 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + named-gpios { + /* Skyrim-specific GPIO customizations */ + usb_fault_odl { + gpios = <&gpio5 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_USB_FAULT_ODL"; + }; + en_pwr_s3 { + gpios = <&gpio7 4 GPIO_OUT_LOW>; + enum-name = "GPIO_EN_PWR_S3"; + }; + pg_groupc_s0_od { + gpios = <&gpiof 0 GPIO_INPUT>; + enum-name = "GPIO_PG_GROUPC_S0_OD"; + }; + /* TODO: Add interrupt handler */ + ec_i2c_usbc_pd_int { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_EC_I2C_USBC_PD_INT"; + }; + /* TODO: Add interrupt handler */ + soc_thermtrip_odl { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_SOC_THERMTRIP_ODL"; + }; + hub_rst { + gpios = <&gpio6 6 GPIO_OUT_LOW>; + enum-name = "GPIO_HUB_RST"; + }; + ec_soc_int_l { + gpios = <&gpioa 1 GPIO_OUT_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + ec_soc_pwr_good { + gpios = <&gpiod 3 GPIO_OUT_LOW>; + enum-name = "GPIO_EC_SOC_PWR_GOOD"; + }; + /* TODO: Add interrupt handler to shut down */ + pcore_ocp_r_l { + gpios = <&gpioa 5 GPIO_INPUT>; + enum-name = "GPIO_PCORE_OCP_L"; + }; + /* TODO: Add interrupt handler */ + sc_0_int_l { + gpios = <&gpio6 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_SC_0_INT_L"; + }; + /* TODO: Add interrupt handler */ + usb_hub_fault_q_odl { + gpios = <&gpioe 5 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_USB_HUB_FAULT_ODL"; + }; + pg_lpddr5_s3_od { + gpios = <&gpio7 3 GPIO_INPUT>; + enum-name = "GPIO_PG_LPDDR5_S3_OD"; + }; + 3axis_int_l { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + }; + ec_soc_pwr_btn_l { + gpios = <&gpioa 7 GPIO_OUT_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + volup_btn_odl { + gpios = <&gpio6 7 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + voldn_btn_odl { + gpios = <&gpio7 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + ec_sc_rst { + gpios = <&gpiob 0 GPIO_OUT_LOW>; + enum-name = "GPIO_EC_SC_RST"; + }; + /* TODO: Add CBI_WP feature config */ + ec_cbi_wp { + gpios = <&gpio8 1 GPIO_OUT_LOW>; + enum-name = "GPIO_EC_CBI_WP"; + }; + ec_wp_l { + gpios = <&gpiod 7 GPIO_INPUT>; + enum-name = "GPIO_WP_L"; + }; + pg_lpddr5_s0_od { + gpios = <&gpio6 0 GPIO_INPUT>; + enum-name = "GPIO_PG_LPDDR5_S0_OD"; + }; + }; + + def-lvol-io-list { + compatible = "nuvoton,npcx-lvolctrl-def"; + + /* + * Low voltage on I2C2_0, I2C6_1, I2C7_0, USB_FAUT_ODL + */ + lvol-io-pads = <&lvol_io92 &lvol_io91 &lvol_ioe4 &lvol_ioe3 + &lvol_iob3 &lvol_iob2 &lvol_io50>; + }; +}; diff --git a/zephyr/projects/guybrush/usb_pd_policy.c b/zephyr/projects/skyrim/usb_pd_policy.c index 0aa21293fe..0aa21293fe 100644 --- a/zephyr/projects/guybrush/usb_pd_policy.c +++ b/zephyr/projects/skyrim/usb_pd_policy.c diff --git a/zephyr/projects/guybrush/usbc_config.c b/zephyr/projects/skyrim/usbc_config.c index 43484d6751..6e6d429fb2 100644 --- a/zephyr/projects/guybrush/usbc_config.c +++ b/zephyr/projects/skyrim/usbc_config.c @@ -624,6 +624,8 @@ void baseboard_a1_retimer_setup(void) } DECLARE_DEFERRED(baseboard_a1_retimer_setup); +/* TODO: Remove when guybrush is no longer supported */ +#ifdef CONFIG_BOARD_GUYBRUSH void board_overcurrent_event(int port, int is_overcurrented) { switch (port) { @@ -636,3 +638,4 @@ void board_overcurrent_event(int port, int is_overcurrented) break; } } +#endif diff --git a/zephyr/projects/trogdor/lazor/CMakeLists.txt b/zephyr/projects/trogdor/lazor/CMakeLists.txt index 7ab5d6a92e..24184946b4 100644 --- a/zephyr/projects/trogdor/lazor/CMakeLists.txt +++ b/zephyr/projects/trogdor/lazor/CMakeLists.txt @@ -17,8 +17,8 @@ set(PLATFORM_EC_BOARD "${PLATFORM_EC}/board/lazor" CACHE PATH zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "${PLATFORM_EC_BASEBOARD}/hibernate.c" "${PLATFORM_EC_BASEBOARD}/power.c" - "${PLATFORM_EC_BASEBOARD}/usbc_config.c" - "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c") + "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c" + "${PLATFORM_EC_BOARD}/usbc_config.c") zephyr_library_sources( "${PLATFORM_EC_BOARD}/hibernate.c" diff --git a/zephyr/projects/trogdor/lazor/gpio.dts b/zephyr/projects/trogdor/lazor/gpio.dts index 282ea97bb4..c8742ebbcf 100644 --- a/zephyr/projects/trogdor/lazor/gpio.dts +++ b/zephyr/projects/trogdor/lazor/gpio.dts @@ -10,363 +10,287 @@ usb_c0_pd_int_odl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PD_INT_ODL"; - label = "USB_C0_PD_INT_ODL"; }; usb_c1_pd_int_odl { gpios = <&gpiof 5 GPIO_INPUT>; enum-name = "GPIO_USB_C1_PD_INT_ODL"; - label = "USB_C1_PD_INT_ODL"; }; usb_c0_swctl_int_odl { gpios = <&gpio0 3 GPIO_INPUT>; enum-name = "GPIO_USB_C0_SWCTL_INT_ODL"; - label = "USB_C0_SWCTL_INT_ODL"; }; usb_c1_swctl_int_odl { gpios = <&gpio4 0 GPIO_INPUT>; enum-name = "GPIO_USB_C1_SWCTL_INT_ODL"; - label = "USB_C1_SWCTL_INT_ODL"; }; usb_c0_bc12_int_l { - gpios = <&gpio6 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio6 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C0_BC12_INT_L"; - label = "USB_C0_BC12_INT_L"; }; usb_c1_bc12_int_l { - gpios = <&gpio8 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio8 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C1_BC12_INT_L"; - label = "USB_C1_BC12_INT_L"; }; usb_a0_oc_odl { - gpios = <&gpiod 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiod 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_A0_OC_ODL"; - label = "USB_A0_OC_ODL"; }; gpio_acok_od: acok_od { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "ACOK_OD"; }; ccd_mode_odl { gpios = <&gpioe 3 GPIO_INPUT>; enum-name = "GPIO_CCD_MODE_ODL"; - label = "CCD_MODE_ODL"; }; gpio_ec_pwr_btn_odl: ec_pwr_btn_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "EC_PWR_BTN_ODL"; }; ec_voldn_btn_odl { - gpios = <&gpio7 0 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio7 0 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "EC_VOLDN_BTN_ODL"; }; ec_volup_btn_odl { - gpios = <&gpiof 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiof 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_UP_L"; - label = "EC_VOLUP_BTN_ODL"; }; ec_wp_odl { gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "EC_WP_ODL"; }; gpio_lid_open_ec: lid_open_ec { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN_EC"; }; ap_rst_l { gpios = <&gpioc 1 GPIO_INPUT>; enum-name = "GPIO_AP_RST_L"; - label = "AP_RST_L"; }; ps_hold { - gpios = <&gpioa 4 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioa 4 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_PS_HOLD"; - label = "PS_HOLD"; }; ap_suspend { gpios = <&gpio5 7 GPIO_INPUT>; enum-name = "GPIO_AP_SUSPEND"; - label = "AP_SUSPEND"; }; deprecated_ap_rst_req { - gpios = <&gpioc 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioc 2 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_DEPRECATED_AP_RST_REQ"; - label = "DEPRECATED_AP_RST_REQ"; }; power_good { - gpios = <&gpio5 4 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpio5 4 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_POWER_GOOD"; - label = "POWER_GOOD"; }; warm_reset_l { gpios = <&gpiof 4 GPIO_INPUT>; enum-name = "GPIO_WARM_RESET_L"; - label = "WARM_RESET_L"; }; ap_ec_spi_cs_l { - gpios = <&gpio5 3 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CS_L"; + gpios = <&gpio5 3 GPIO_INPUT_PULL_DOWN>; }; tablet_mode_l { gpios = <&gpioc 6 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; gpio_accel_gyro_int_l: accel_gyro_int_l { gpios = <&gpioa 0 GPIO_INPUT>; enum-name = "GPIO_ACCEL_GYRO_INT_L"; - label = "ACCEL_GYRO_INT_L"; }; da9313_gpio0 { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_DA9313_GPIO0"; - label = "DA9313_GPIO0"; }; switchcap_pg_int_l { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_SWITCHCAP_PG_INT_L"; - label = "SWITCHCAP_PG_INT_L"; }; gpio_ec_rst_odl: ec_rst_odl { gpios = <&gpio0 2 GPIO_INPUT>; enum-name = "GPIO_EC_RST_ODL"; - label = "EC_RST_ODL"; }; ec_entering_rw { gpios = <&gpioe 1 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "EC_ENTERING_RW"; }; ec_batt_pres_odl { gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; pm845_resin_l { gpios = <&gpio3 2 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_RESIN_L"; - label = "PM845_RESIN_L"; }; pmic_kpd_pwr_odl { gpios = <&gpiod 6 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_KPD_PWR_ODL"; - label = "PMIC_KPD_PWR_ODL"; }; ec_int_l { gpios = <&gpioa 2 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_INT_L"; - label = "EC_INT_L"; }; qsip_on { gpios = <&gpio5 0 GPIO_OUT_LOW>; enum-name = "GPIO_QSIP_ON"; - label = "QSIP_ON"; }; hibernate_l { gpios = <&gpio5 2 GPIO_OUT_HIGH>; enum-name = "GPIO_HIBERNATE_L"; - label = "HIBERNATE_L"; }; switchcap_on { gpios = <&gpiod 5 GPIO_OUT_LOW>; enum-name = "GPIO_SWITCHCAP_ON"; - label = "SWITCHCAP_ON"; }; switchcap_on_l { gpios = <&gpiod 5 GPIO_OUT_LOW>; enum-name = "GPIO_SWITCHCAP_ON_L"; - label = "SWITCHCAP_ON_L"; }; vbob_en { gpios = <&gpiod 3 GPIO_OUT_LOW>; enum-name = "GPIO_VBOB_EN"; - label = "VBOB_EN"; }; en_pp3300_a { gpios = <&gpioa 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP3300_A"; - label = "EN_PP3300_A"; }; en_pp5000_a { gpios = <&gpio6 7 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000"; - label = "EN_PP5000_A"; }; ec_bl_disable_l { gpios = <&gpiob 6 GPIO_OUT_LOW>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_BL_DISABLE_L"; }; lid_accel_int_l { gpios = <&gpio5 6 GPIO_INPUT>; enum-name = "GPIO_LID_ACCEL_INT_L"; - label = "LID_ACCEL_INT_L"; }; trackpad_int_gate { gpios = <&gpio7 4 GPIO_OUT_LOW>; enum-name = "GPIO_TRACKPAD_INT_GATE"; - label = "TRACKPAD_INT_GATE"; }; usb_c0_pd_rst_l { gpios = <&gpiof 1 GPIO_ODR_HIGH>; enum-name = "GPIO_USB_C0_PD_RST_L"; - label = "USB_C0_PD_RST_L"; }; usb_c1_pd_rst_l { gpios = <&gpioe 4 GPIO_ODR_HIGH>; enum-name = "GPIO_USB_C1_PD_RST_L"; - label = "USB_C1_PD_RST_L"; }; dp_mux_oe_l { gpios = <&gpio9 6 GPIO_ODR_HIGH>; enum-name = "GPIO_DP_MUX_OE_L"; - label = "DP_MUX_OE_L"; }; dp_mux_sel { gpios = <&gpio4 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_MUX_SEL"; - label = "DP_MUX_SEL"; }; dp_hot_plug_det { gpios = <&gpio9 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_HOT_PLUG_DET"; - label = "DP_HOT_PLUG_DET"; }; en_usb_a_5v { gpios = <&gpio8 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_USB_A_5V"; - label = "EN_USB_A_5V"; }; usb_a_cdp_ilim_en { gpios = <&gpio7 5 GPIO_OUT_HIGH>; - label = "USB_A_CDP_ILIM_EN"; }; ec_chg_led_y_c1 { gpios = <&gpioc 3 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C1"; - label = "EC_CHG_LED_Y_C1"; }; ec_chg_led_b_c1 { gpios = <&gpioc 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_B_C1"; - label = "EC_CHG_LED_B_C1"; }; ap_ec_spi_mosi { - gpios = <&gpio4 6 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MOSI"; + gpios = <&gpio4 6 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_miso { - gpios = <&gpio4 7 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MISO"; + gpios = <&gpio4 7 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_clk { - gpios = <&gpio5 5 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CLK"; + gpios = <&gpio5 5 GPIO_INPUT_PULL_DOWN>; }; kb_bl_pwm { gpios = <&gpio8 0 GPIO_INPUT>; - label = "KB_BL_PWM"; }; edp_bkltctl { gpios = <&gpiob 7 GPIO_INPUT>; - label = "EDP_BKLTCTL"; }; ppvar_boostin_sense { gpios = <&gpio4 4 GPIO_INPUT>; - label = "PPVAR_BOOSTIN_SENSE"; }; charger_iadp { gpios = <&gpio4 3 GPIO_INPUT>; - label = "CHARGER_IADP"; }; charger_pmon { gpios = <&gpio4 2 GPIO_INPUT>; - label = "CHARGER_PMON"; }; ec_i2c_power_scl { gpios = <&gpiob 5 GPIO_INPUT>; - label = "EC_I2C_POWER_SCL"; }; ec_i2c_power_sda { gpios = <&gpiob 4 GPIO_INPUT>; - label = "EC_I2C_POWER_SDA"; }; ec_i2c_usb_c0_pd_scl { gpios = <&gpio9 0 GPIO_INPUT>; - label = "EC_I2C_USB_C0_PD_SCL"; }; ec_i2c_usb_c0_pd_sda { gpios = <&gpio8 7 GPIO_INPUT>; - label = "EC_I2C_USB_C0_PD_SDA"; }; ec_i2c_usb_c1_pd_scl { gpios = <&gpio9 2 GPIO_INPUT>; - label = "EC_I2C_USB_C1_PD_SCL"; }; ec_i2c_usb_c1_pd_sda { gpios = <&gpio9 1 GPIO_INPUT>; - label = "EC_I2C_USB_C1_PD_SDA"; }; ec_i2c_eeprom_scl { gpios = <&gpio3 3 GPIO_INPUT>; - label = "EC_I2C_EEPROM_SCL"; }; ec_i2c_eeprom_sda { gpios = <&gpio3 6 GPIO_INPUT>; - label = "EC_I2C_EEPROM_SDA"; }; ec_i2c_sensor_scl { gpios = <&gpiob 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C_SENSOR_SCL"; - label = "EC_I2C_SENSOR_SCL"; }; ec_i2c_sensor_sda { gpios = <&gpiob 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C_SENSOR_SDA"; - label = "EC_I2C_SENSOR_SDA"; }; gpio_brd_id0: brd_id0 { gpios = <&gpioc 7 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION1"; - label = "BRD_ID0"; }; gpio_brd_id1: brd_id1 { gpios = <&gpio9 3 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION2"; - label = "BRD_ID1"; }; gpio_brd_id2: brd_id2 { gpios = <&gpio6 3 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION3"; - label = "BRD_ID2"; }; gpio_sku_id0: sku_id0 { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_SKU_ID0"; - label = "SKU_ID0"; }; gpio_sku_id1: sku_id1 { gpios = <&gpio4 1 GPIO_INPUT>; enum-name = "GPIO_SKU_ID1"; - label = "SKU_ID1"; }; gpio_sku_id2: sku_id2 { gpios = <&gpiod 4 GPIO_INPUT>; enum-name = "GPIO_SKU_ID2"; - label = "SKU_ID2"; }; arm_x86 { gpios = <&gpio6 6 GPIO_OUT_LOW>; - label = "ARM_X86"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; }; diff --git a/zephyr/projects/trogdor/lazor/prj.conf b/zephyr/projects/trogdor/lazor/prj.conf index 59ab01cc0a..f47eb7e437 100644 --- a/zephyr/projects/trogdor/lazor/prj.conf +++ b/zephyr/projects/trogdor/lazor/prj.conf @@ -127,9 +127,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_RTC=y # EC software sync CONFIG_PLATFORM_EC_VBOOT_HASH=y -# Serial Host Interface (SHI) device. -CONFIG_CROS_SHI_NPCX=y - # Sensors CONFIG_PLATFORM_EC_MOTIONSENSE=y CONFIG_PLATFORM_EC_ACCEL_FIFO=y diff --git a/zephyr/projects/trogdor/trogdor/CMakeLists.txt b/zephyr/projects/trogdor/trogdor/CMakeLists.txt index 99c72e1b81..fc85da38a1 100644 --- a/zephyr/projects/trogdor/trogdor/CMakeLists.txt +++ b/zephyr/projects/trogdor/trogdor/CMakeLists.txt @@ -16,8 +16,8 @@ set(PLATFORM_EC_BOARD "${PLATFORM_EC}/board/trogdor" CACHE PATH zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "${PLATFORM_EC_BASEBOARD}/hibernate.c" - "${PLATFORM_EC_BASEBOARD}/usbc_config.c" - "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c") + "${PLATFORM_EC_BASEBOARD}/usb_pd_policy.c" + "${PLATFORM_EC_BOARD}/usbc_config.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_LED_COMMON "${PLATFORM_EC_BOARD}/led.c") diff --git a/zephyr/projects/trogdor/trogdor/gpio.dts b/zephyr/projects/trogdor/trogdor/gpio.dts index 956db72960..52c18658b7 100644 --- a/zephyr/projects/trogdor/trogdor/gpio.dts +++ b/zephyr/projects/trogdor/trogdor/gpio.dts @@ -10,311 +10,247 @@ usb_c0_pd_int_odl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PD_INT_ODL"; - label = "USB_C0_PD_INT_ODL"; }; usb_c1_pd_int_odl { gpios = <&gpiof 5 GPIO_INPUT>; enum-name = "GPIO_USB_C1_PD_INT_ODL"; - label = "USB_C1_PD_INT_ODL"; }; usb_c0_swctl_int_odl { gpios = <&gpio0 3 GPIO_INPUT>; enum-name = "GPIO_USB_C0_SWCTL_INT_ODL"; - label = "USB_C0_SWCTL_INT_ODL"; }; usb_c1_swctl_int_odl { gpios = <&gpio4 0 GPIO_INPUT>; enum-name = "GPIO_USB_C1_SWCTL_INT_ODL"; - label = "USB_C1_SWCTL_INT_ODL"; }; usb_c0_bc12_int_l { - gpios = <&gpio6 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio6 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C0_BC12_INT_L"; - label = "USB_C0_BC12_INT_L"; }; usb_c1_bc12_int_l { - gpios = <&gpio8 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio8 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C1_BC12_INT_L"; - label = "USB_C1_BC12_INT_L"; }; usb_a0_oc_odl { - gpios = <&gpiod 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiod 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_A0_OC_ODL"; - label = "USB_A0_OC_ODL"; }; gpio_chg_acok_od: chg_acok_od { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "CHG_ACOK_OD"; }; gpio_ec_pwr_btn_odl: ec_pwr_btn_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "EC_PWR_BTN_ODL"; }; ec_voldn_btn_odl { - gpios = <&gpio7 0 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio7 0 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "EC_VOLDN_BTN_ODL"; }; ec_volup_btn_odl { - gpios = <&gpiof 2 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpiof 2 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_UP_L"; - label = "EC_VOLUP_BTN_ODL"; }; ec_wp_odl { gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "EC_WP_ODL"; }; gpio_lid_open_ec: lid_open_ec { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "LID_OPEN_EC"; }; ap_rst_l { gpios = <&gpioc 1 GPIO_INPUT>; enum-name = "GPIO_AP_RST_L"; - label = "AP_RST_L"; }; ps_hold { - gpios = <&gpioa 4 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioa 4 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_PS_HOLD"; - label = "PS_HOLD"; }; ap_suspend { gpios = <&gpio5 7 GPIO_INPUT>; enum-name = "GPIO_AP_SUSPEND"; - label = "AP_SUSPEND"; }; deprecated_ap_rst_req { - gpios = <&gpioc 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioc 2 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_DEPRECATED_AP_RST_REQ"; - label = "DEPRECATED_AP_RST_REQ"; }; power_good { - gpios = <&gpio5 4 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpio5 4 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_POWER_GOOD"; - label = "POWER_GOOD"; }; warm_reset_l { gpios = <&gpiof 4 GPIO_INPUT>; enum-name = "GPIO_WARM_RESET_L"; - label = "WARM_RESET_L"; }; ap_ec_spi_cs_l { - gpios = <&gpio5 3 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CS_L"; + gpios = <&gpio5 3 GPIO_INPUT_PULL_DOWN>; }; tablet_mode_l { gpios = <&gpioc 6 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; gpio_accel_gyro_int_l: accel_gyro_int_l { gpios = <&gpioa 0 GPIO_INPUT>; enum-name = "GPIO_ACCEL_GYRO_INT_L"; - label = "ACCEL_GYRO_INT_L"; }; gpio_ec_rst_odl: ec_rst_odl { gpios = <&gpio0 2 GPIO_INPUT>; enum-name = "GPIO_EC_RST_ODL"; - label = "EC_RST_ODL"; }; ec_entering_rw { gpios = <&gpioe 1 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "EC_ENTERING_RW"; }; ccd_mode_odl { gpios = <&gpioe 3 GPIO_INPUT>; enum-name = "GPIO_CCD_MODE_ODL"; - label = "CCD_MODE_ODL"; }; ec_batt_pres_odl { gpios = <&gpioe 5 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; pmic_resin_l { gpios = <&gpio3 2 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_RESIN_L"; - label = "PMIC_RESIN_L"; }; pmic_kpd_pwr_odl { gpios = <&gpiod 6 GPIO_ODR_HIGH>; enum-name = "GPIO_PMIC_KPD_PWR_ODL"; - label = "PMIC_KPD_PWR_ODL"; }; ec_int_l { gpios = <&gpioa 2 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_INT_L"; - label = "EC_INT_L"; }; hibernate_l { gpios = <&gpio5 2 GPIO_ODR_HIGH>; enum-name = "GPIO_HIBERNATE_L"; - label = "HIBERNATE_L"; }; switchcap_on { gpios = <&gpiod 5 GPIO_OUT_LOW>; enum-name = "GPIO_SWITCHCAP_ON"; - label = "SWITCHCAP_ON"; }; en_pp3300_a { gpios = <&gpioa 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP3300_A"; - label = "EN_PP3300_A"; }; en_pp5000_a { gpios = <&gpio6 7 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000"; - label = "EN_PP5000_A"; }; ec_bl_disable_l { gpios = <&gpiob 6 GPIO_OUT_LOW>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_BL_DISABLE_L"; }; lid_accel_int_l { gpios = <&gpio5 6 GPIO_INPUT>; enum-name = "GPIO_LID_ACCEL_INT_L"; - label = "LID_ACCEL_INT_L"; }; trackpad_int_gate { gpios = <&gpio7 4 GPIO_OUT_LOW>; enum-name = "GPIO_TRACKPAD_INT_GATE"; - label = "TRACKPAD_INT_GATE"; }; usb_c0_pd_rst_l { gpios = <&gpiof 1 GPIO_OUT_HIGH>; enum-name = "GPIO_USB_C0_PD_RST_L"; - label = "USB_C0_PD_RST_L"; }; usb_c1_pd_rst_l { gpios = <&gpioe 4 GPIO_OUT_HIGH>; enum-name = "GPIO_USB_C1_PD_RST_L"; - label = "USB_C1_PD_RST_L"; }; dp_mux_oe_l { gpios = <&gpio9 6 GPIO_ODR_HIGH>; enum-name = "GPIO_DP_MUX_OE_L"; - label = "DP_MUX_OE_L"; }; dp_mux_sel { gpios = <&gpio4 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_MUX_SEL"; - label = "DP_MUX_SEL"; }; dp_hot_plug_det { gpios = <&gpio9 5 GPIO_OUT_LOW>; enum-name = "GPIO_DP_HOT_PLUG_DET"; - label = "DP_HOT_PLUG_DET"; }; en_usb_a_5v { gpios = <&gpio8 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_USB_A_5V"; - label = "EN_USB_A_5V"; }; usb_a_cdp_ilim_en_l { gpios = <&gpio7 5 GPIO_OUT_HIGH>; - label = "USB_A_CDP_ILIM_EN_L"; }; ec_chg_led_y_c0 { gpios = <&gpio6 0 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C0"; - label = "EC_CHG_LED_Y_C0"; }; ec_chg_led_w_c0 { gpios = <&gpioc 0 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_W_C0"; - label = "EC_CHG_LED_W_C0"; }; ec_chg_led_y_c1 { gpios = <&gpioc 3 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_Y_C1"; - label = "EC_CHG_LED_Y_C1"; }; ec_chg_led_w_c1 { gpios = <&gpioc 4 GPIO_OUT_LOW>; enum-name = "GPIO_EC_CHG_LED_W_C1"; - label = "EC_CHG_LED_W_C1"; }; ap_ec_spi_mosi { - gpios = <&gpio4 6 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MOSI"; + gpios = <&gpio4 6 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_miso { - gpios = <&gpio4 7 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_MISO"; + gpios = <&gpio4 7 GPIO_INPUT_PULL_DOWN>; }; ap_ec_spi_clk { - gpios = <&gpio5 5 (GPIO_INPUT | GPIO_PULL_DOWN)>; - label = "AP_EC_SPI_CLK"; + gpios = <&gpio5 5 GPIO_INPUT_PULL_DOWN>; }; kb_bl_pwm { gpios = <&gpio8 0 GPIO_INPUT>; - label = "KB_BL_PWM"; }; edp_bkltctl { gpios = <&gpiob 7 GPIO_INPUT>; - label = "EDP_BKLTCTL"; }; ppvar_boostin_sense { gpios = <&gpio4 4 GPIO_INPUT>; - label = "PPVAR_BOOSTIN_SENSE"; }; charger_iadp { gpios = <&gpio4 3 GPIO_INPUT>; - label = "CHARGER_IADP"; }; charger_pmon { gpios = <&gpio4 2 GPIO_INPUT>; - label = "CHARGER_PMON"; }; brd_id0 { gpios = <&gpioc 7 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION1"; - label = "BRD_ID0"; }; brd_id1 { gpios = <&gpio9 3 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION2"; - label = "BRD_ID1"; }; brd_id2 { gpios = <&gpio6 3 GPIO_INPUT>; enum-name = "GPIO_BOARD_VERSION3"; - label = "BRD_ID2"; }; sku_id0 { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_SKU_ID0"; - label = "SKU_ID0"; }; sku_id1 { gpios = <&gpio4 1 GPIO_INPUT>; enum-name = "GPIO_SKU_ID1"; - label = "SKU_ID1"; }; sku_id2 { gpios = <&gpiod 4 GPIO_INPUT>; enum-name = "GPIO_SKU_ID2"; - label = "SKU_ID2"; }; switchcap_gpio_1 { - gpios = <&gpioe 2 (GPIO_INPUT | GPIO_PULL_DOWN)>; + gpios = <&gpioe 2 GPIO_INPUT_PULL_DOWN>; enum-name = "GPIO_SWITCHCAP_PG"; - label = "SWITCHCAP_GPIO_1"; }; arm_x86 { gpios = <&gpio6 6 GPIO_OUT_LOW>; - label = "ARM_X86"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; }; diff --git a/zephyr/projects/trogdor/trogdor/prj.conf b/zephyr/projects/trogdor/trogdor/prj.conf index e2d944c196..a0bbc76b01 100644 --- a/zephyr/projects/trogdor/trogdor/prj.conf +++ b/zephyr/projects/trogdor/trogdor/prj.conf @@ -122,9 +122,6 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_RTC=y # EC software sync CONFIG_PLATFORM_EC_VBOOT_HASH=y -# Serial Host Interface (SHI) device. -CONFIG_CROS_SHI_NPCX=y - # Sensors CONFIG_PLATFORM_EC_MOTIONSENSE=y CONFIG_PLATFORM_EC_ACCEL_FIFO=y diff --git a/zephyr/projects/volteer/delbin/gpio.dts b/zephyr/projects/volteer/delbin/gpio.dts index f7fdc35921..cfdabb9d0b 100644 --- a/zephyr/projects/volteer/delbin/gpio.dts +++ b/zephyr/projects/volteer/delbin/gpio.dts @@ -10,328 +10,256 @@ ec_lid_open { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "EC_LID_OPEN"; }; ec_wp_l { gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "EC_WP_L"; }; h1_ec_pwr_btn_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "H1_EC_PWR_BTN_ODL"; }; acok_od { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "ACOK_OD"; }; slp_s0_l { gpios = <&gpiod 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S0_L"; - label = "SLP_S0_L"; }; slp_s3_l { gpios = <&gpioa 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S3_L"; - label = "SLP_S3_L"; }; slp_sus_l { gpios = <&gpiod 7 GPIO_INPUT>; enum-name = "GPIO_SLP_SUS_L"; - label = "SLP_SUS_L"; }; pg_ec_rsmrst_odl { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_PG_EC_RSMRST_ODL"; - label = "PG_EC_RSMRST_ODL"; }; dsw_pwrok { gpios = <&gpioc 7 GPIO_INPUT>; enum-name = "GPIO_PG_EC_DSW_PWROK"; - label = "DSW_PWROK"; }; pg_ec_all_sys_pwrgd { gpios = <&gpiof 4 GPIO_INPUT>; enum-name = "GPIO_PG_EC_ALL_SYS_PWRGD"; - label = "PG_EC_ALL_SYS_PWRGD"; }; gpio_ec_imu_int_l: ec_imu_int_l { gpios = <&gpio5 6 GPIO_INPUT>; enum-name = "GPIO_EC_IMU_INT_L"; - label = "EC_IMU_INT_L"; }; tablet_mode_l { gpios = <&gpio9 5 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; ec_accel_int { - gpios = <&gpio8 1 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_ACCEL_INT"; + gpios = <&gpio8 1 GPIO_INPUT_PULL_UP>; }; usb_c0_tcpc_int_odl { gpios = <&gpioe 0 GPIO_INPUT>; - label = "USB_C0_TCPC_INT_ODL"; }; usb_c1_tcpc_int_odl { gpios = <&gpioa 2 GPIO_INPUT>; - label = "USB_C1_TCPC_INT_ODL"; }; usb_c0_ppc_int_odl { gpios = <&gpio6 2 GPIO_INPUT>; - label = "USB_C0_PPC_INT_ODL"; }; usb_c1_ppc_int_odl { gpios = <&gpiof 5 GPIO_INPUT>; - label = "USB_C1_PPC_INT_ODL"; }; usb_c0_bc12_int_odl { gpios = <&gpioe 4 GPIO_INPUT>; - label = "USB_C0_BC12_INT_ODL"; }; usb_c1_mix_int_odl { gpios = <&gpio0 3 GPIO_INPUT>; - label = "USB_C1_MIX_INT_ODL"; }; ec_voldn_btn_odl { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_VOLDN_BTN_ODL"; + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; }; ec_volup_btn_odl { - gpios = <&gpio9 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_VOLUP_BTN_ODL"; + gpios = <&gpio9 7 GPIO_INPUT_PULL_UP>; }; en_pp3300_a { gpios = <&gpioa 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP3300_A"; - label = "EN_PP3300_A"; }; en_pp5000_a { gpios = <&gpioa 4 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000"; - label = "EN_PP5000_A"; }; en_ppvar_vccin { gpios = <&gpio4 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PPVAR_VCCIN"; - label = "EN_PPVAR_VCCIN"; }; ec_rst_odl { gpios = <&gpio0 2 GPIO_INPUT>; - label = "EC_RST_ODL"; }; ec_pch_sys_pwrok { gpios = <&gpio3 7 GPIO_OUT_LOW>; enum-name = "GPIO_EC_PCH_SYS_PWROK"; - label = "EC_PCH_SYS_PWROK"; }; ec_pch_rsmrst_odl { gpios = <&gpioa 6 GPIO_ODR_LOW>; enum-name = "GPIO_PCH_RSMRST_L"; - label = "EC_PCH_RSMRST_ODL"; }; ec_pch_pwr_btn_odl { gpios = <&gpioc 1 GPIO_ODR_HIGH>; enum-name = "GPIO_PCH_PWRBTN_L"; - label = "EC_PCH_PWR_BTN_ODL"; }; ec_pch_rtcrst { gpios = <&gpio7 6 GPIO_OUT_LOW>; enum-name = "GPIO_PCH_RTCRST"; - label = "EC_PCH_RTCRST"; }; ec_pch_wake_odl { gpios = <&gpio7 4 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "EC_PCH_WAKE_ODL"; }; ec_entering_rw { gpios = <&gpioe 3 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "EC_ENTERING_RW"; }; ec_prochot_odl { gpios = <&gpio6 3 GPIO_ODR_HIGH>; enum-name = "GPIO_CPU_PROCHOT"; - label = "EC_PROCHOT_ODL"; }; ec_prochot_in_l { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_EC_PROCHOT_IN_L"; - label = "EC_PROCHOT_IN_L"; }; sys_rst_odl { gpios = <&gpioc 5 GPIO_ODR_HIGH>; enum-name = "GPIO_SYS_RESET_L"; - label = "SYS_RST_ODL"; }; ec_pch_int_odl { gpios = <&gpiob 0 GPIO_ODR_HIGH>; - label = "EC_PCH_INT_ODL"; }; en_pp5000_usba { gpios = <&gpioc 6 GPIO_OUT_LOW>; - label = "EN_PP5000_USBA"; }; usb_a_low_pwr_od { gpios = <&gpio6 6 GPIO_ODR_LOW>; - label = "USB_A_LOW_PWR_OD"; }; usb_c0_rt_rst_odl { gpios = <&gpiod 4 GPIO_ODR_LOW>; - label = "USB_C0_RT_RST_ODL"; }; usb_c1_rt_rst_odl { gpios = <&gpio8 3 GPIO_ODR_LOW>; - label = "USB_C1_RT_RST_ODL"; }; usb_c0_oc_odl { gpios = <&gpiob 1 GPIO_ODR_HIGH>; - label = "USB_C0_OC_ODL"; }; usb_c1_oc_odl { gpios = <&gpio5 0 GPIO_ODR_HIGH>; - label = "USB_C1_OC_ODL"; }; uart2_ec_rx { gpios = <&gpio7 5 GPIO_OUT_LOW>; - label = "UART2_EC_RX"; }; led_1_l { gpios = <&gpioc 4 GPIO_OUT_HIGH>; - label = "LED_1_L"; }; led_2_l { gpios = <&gpioc 3 GPIO_OUT_HIGH>; - label = "LED_2_L"; }; led_3_l { gpios = <&gpioc 2 GPIO_OUT_HIGH>; - label = "LED_3_L"; }; ccd_mode_odl { gpios = <&gpioe 5 GPIO_INPUT>; - label = "CCD_MODE_ODL"; }; ec_kb_bl_en { gpios = <&gpio8 6 GPIO_OUT_LOW>; - label = "EC_KB_BL_EN"; }; unused_gpio34 { - gpios = <&gpio3 4 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIO34"; + gpios = <&gpio3 4 GPIO_INPUT_PULL_UP>; }; unused_gpio41 { - gpios = <&gpio4 1 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIO41"; + gpios = <&gpio4 1 GPIO_INPUT_PULL_UP>; }; unused_gpio72 { - gpios = <&gpio7 2 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIO72"; + gpios = <&gpio7 2 GPIO_INPUT_PULL_UP>; }; unused_gpio96 { - gpios = <&gpio9 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIO96"; + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; }; unused_gpioa7 { - gpios = <&gpioa 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIOA7"; + gpios = <&gpioa 7 GPIO_INPUT_PULL_UP>; }; unused_gpioc0 { - gpios = <&gpioc 0 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIOC0"; + gpios = <&gpioc 0 GPIO_INPUT_PULL_UP>; }; unused_gpiof2 { - gpios = <&gpiof 2 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "UNUSED_GPIOF2"; + gpios = <&gpiof 2 GPIO_INPUT_PULL_UP>; }; ec_edp_bl_en { gpios = <&gpiod 3 GPIO_OUT_HIGH>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_EDP_BL_EN"; }; ec_i2c0_sensor_scl { gpios = <&gpiob 5 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SCL"; - label = "EC_I2C0_SENSOR_SCL"; }; ec_i2c0_sensor_sda { gpios = <&gpiob 4 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SDA"; - label = "EC_I2C0_SENSOR_SDA"; }; ec_i2c1_usb_c0_scl { gpios = <&gpio9 0 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SCL"; - label = "EC_I2C1_USB_C0_SCL"; }; ec_i2c1_usb_c0_sda { gpios = <&gpio8 7 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SDA"; - label = "EC_I2C1_USB_C0_SDA"; }; ec_i2c2_usb_c1_scl { gpios = <&gpio9 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SCL"; - label = "EC_I2C2_USB_C1_SCL"; }; ec_i2c2_usb_c1_sda { gpios = <&gpio9 1 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SDA"; - label = "EC_I2C2_USB_C1_SDA"; }; ec_i2c3_usb_1_mix_scl { gpios = <&gpiod 1 GPIO_INPUT>; enum-name = "GPIO_EC_I2C3_USB_1_MIX_SCL"; - label = "EC_I2C3_USB_1_MIX_SCL"; }; ec_i2c3_usb_1_mix_sda { gpios = <&gpiod 0 GPIO_INPUT>; enum-name = "GPIO_EC_I2C3_USB_1_MIX_SDA"; - label = "EC_I2C3_USB_1_MIX_SDA"; }; ec_i2c5_power_scl { gpios = <&gpio3 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SCL"; - label = "EC_I2C5_POWER_SCL"; }; ec_i2c5_power_sda { gpios = <&gpio3 6 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SDA"; - label = "EC_I2C5_POWER_SDA"; }; ec_i2c7_eeprom_scl { gpios = <&gpiob 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C7_EEPROM_PWR_SCL_R"; - label = "EC_I2C7_EEPROM_SCL"; }; ec_i2c7_eeprom_sda { gpios = <&gpiob 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C7_EEPROM_PWR_SDA_R"; - label = "EC_I2C7_EEPROM_SDA"; }; ec_batt_pres_odl { gpios = <&gpioe 1 GPIO_INPUT>; - label = "EC_BATT_PRES_ODL"; }; usb_c0_dp_hpd { gpios = <&gpiof 3 GPIO_INPUT>; - label = "USB_C0_DP_HPD"; }; usb_c1_dp_hpd { gpios = <&gpio7 0 GPIO_INPUT>; - label = "USB_C1_DP_HPD"; }; en_pp5000_fan { gpios = <&gpio6 1 GPIO_OUT_LOW>; - label = "EN_PP5000_FAN"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; }; diff --git a/zephyr/projects/volteer/delbin/prj.conf b/zephyr/projects/volteer/delbin/prj.conf index dd2ca0a2f5..03444ce2ac 100644 --- a/zephyr/projects/volteer/delbin/prj.conf +++ b/zephyr/projects/volteer/delbin/prj.conf @@ -14,6 +14,7 @@ CONFIG_PLATFORM_EC_VBOOT_EFS2=n CONFIG_ESPI=y CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4=y +CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5=y CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y CONFIG_PLATFORM_EC_LID_SWITCH=y @@ -24,6 +25,9 @@ CONFIG_AP=y CONFIG_AP_X86_INTEL_TGL=y CONFIG_PLATFORM_EC_POWERSEQ=y CONFIG_PLATFORM_EC_POWERSEQ_RTC_RESET=y +CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y +CONFIG_PLATFORM_EC_POWERSEQ_S4=y +CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y CONFIG_PLATFORM_EC_THROTTLE_AP=y CONFIG_PLATFORM_EC_KEYBOARD_COL2_INVERTED=y @@ -43,6 +47,8 @@ CONFIG_PLATFORM_EC_LID_ANGLE=y CONFIG_PLATFORM_EC_LID_ANGLE_UPDATE=y CONFIG_PLATFORM_EC_SENSOR_TIGHT_TIMESTAMPS=y CONFIG_PLATFORM_EC_TABLET_MODE=y +CONFIG_PLATFORM_EC_THERMISTOR=y +CONFIG_PLATFORM_EC_TEMP_SENSOR=y # Sensor Drivers CONFIG_PLATFORM_EC_ACCEL_BMA255=y diff --git a/zephyr/projects/volteer/volteer/gpio.dts b/zephyr/projects/volteer/volteer/gpio.dts index 06381d6492..59a77917f6 100644 --- a/zephyr/projects/volteer/volteer/gpio.dts +++ b/zephyr/projects/volteer/volteer/gpio.dts @@ -10,350 +10,280 @@ ec_lid_open { gpios = <&gpiod 2 GPIO_INPUT>; enum-name = "GPIO_LID_OPEN"; - label = "EC_LID_OPEN"; }; gpio_ec_wp_l: ec_wp_l { #gpio-cells = <0>; gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_EC_WP_L"; - label = "EC_WP_L"; }; wp_l { gpios = <&gpioa 1 GPIO_INPUT>; enum-name = "GPIO_WP_L"; - label = "WP_L"; }; h1_ec_pwr_btn_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_POWER_BUTTON_L"; - label = "H1_EC_PWR_BTN_ODL"; }; acok_od { gpios = <&gpio0 0 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "ACOK_OD"; }; slp_s0_l { gpios = <&gpiod 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S0_L"; - label = "SLP_S0_L"; }; slp_s3_l { gpios = <&gpioa 5 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_S3_L"; - label = "SLP_S3_L"; }; pch_slp_sus_l { gpios = <&gpiod 7 GPIO_INPUT>; enum-name = "GPIO_PCH_SLP_SUS_L"; - label = "PCH_SLP_SUS_L"; }; slp_sus_l { gpios = <&gpiod 7 GPIO_INPUT>; enum-name = "GPIO_SLP_SUS_L"; - label = "SLP_SUS_L"; }; pg_ec_rsmrst_odl { gpios = <&gpioe 2 GPIO_INPUT>; enum-name = "GPIO_PG_EC_RSMRST_ODL"; - label = "PG_EC_RSMRST_ODL"; }; pg_ec_dsw_pwrok { gpios = <&gpioc 7 GPIO_INPUT>; enum-name = "GPIO_PG_EC_DSW_PWROK"; - label = "PG_EC_DSW_PWROK"; }; pg_ec_all_sys_pwrgd { gpios = <&gpiof 4 GPIO_INPUT>; enum-name = "GPIO_PG_EC_ALL_SYS_PWRGD"; - label = "PG_EC_ALL_SYS_PWRGD"; }; gpio_ec_imu_int_l: ec_imu_int_l { gpios = <&gpio5 6 GPIO_INPUT>; enum-name = "GPIO_EC_IMU_INT_L"; - label = "EC_IMU_INT_L"; }; gpio_ec_als_rgb_int_l: ec_als_rgb_int_l { gpios = <&gpiod 4 GPIO_INPUT>; enum-name = "GPIO_EC_ALS_RGB_INT_L"; - label = "EC_ALS_RGB_INT_L"; }; tablet_mode_l { gpios = <&gpio9 5 GPIO_INPUT>; enum-name = "GPIO_TABLET_MODE_L"; - label = "TABLET_MODE_L"; }; ec_accel_int { - gpios = <&gpio8 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio8 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_EC_ACCEL_INT"; - label = "EC_ACCEL_INT"; }; usb_c0_tcpc_int_odl { gpios = <&gpioe 0 GPIO_INPUT>; enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; - label = "USB_C0_TCPC_INT_ODL"; }; usb_c1_tcpc_int_odl { gpios = <&gpioa 2 GPIO_INPUT>; enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; - label = "USB_C1_TCPC_INT_ODL"; }; usb_c0_ppc_int_odl { gpios = <&gpio6 2 GPIO_INPUT>; enum-name = "GPIO_USB_C0_PPC_INT_ODL"; - label = "USB_C0_PPC_INT_ODL"; }; usb_c1_ppc_int_odl { gpios = <&gpiof 5 GPIO_INPUT>; enum-name = "GPIO_USB_C1_PPC_INT_ODL"; - label = "USB_C1_PPC_INT_ODL"; }; gpio_usb_c0_bc12_int_odl: usb_c0_bc12_int_odl { gpios = <&gpioe 4 GPIO_INPUT>; enum-name = "GPIO_USB_C0_BC12_INT_ODL"; - label = "USB_C0_BC12_INT_ODL"; }; gpio_usb_c1_mix_int_odl: usb_c1_mix_int_odl { #gpio-cells = <0>; gpios = <&gpio0 3 GPIO_INPUT>; enum-name = "GPIO_USB_C1_MIX_INT_ODL"; - label = "USB_C1_MIX_INT_ODL"; }; gpio_usb_c1_bc12_int_odl: usb_c1_bc12_int_odl { #gpio-cells = <0>; gpios = <&gpio0 3 GPIO_INPUT>; enum-name = "GPIO_USB_C1_BC12_INT_ODL"; - label = "USB_C1_BC12_INT_ODL"; }; usb_c1_frs_en { gpios = <&gpio9 4 GPIO_OUT_LOW>; enum-name = "GPIO_USB_C1_FRS_EN"; - label = "USB_C1_FRS_EN"; }; ec_voldn_btn_odl { - gpios = <&gpio9 3 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_DOWN_L"; - label = "EC_VOLDN_BTN_ODL"; }; ec_volup_btn_odl { - gpios = <&gpio9 7 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio9 7 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_VOLUME_UP_L"; - label = "EC_VOLUP_BTN_ODL"; }; en_pp3300_a { gpios = <&gpioa 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP3300_A"; - label = "EN_PP3300_A"; }; en_pp5000 { gpios = <&gpioa 4 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000"; - label = "EN_PP5000"; }; en_pp5000_a { gpios = <&gpioa 4 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000_A"; - label = "EN_PP5000_A"; }; en_ppvar_vccin { gpios = <&gpio4 3 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PPVAR_VCCIN"; - label = "EN_PPVAR_VCCIN"; }; ec_pch_dsw_pwrok { gpios = <&gpioc 0 GPIO_OUT_LOW>; enum-name = "GPIO_PCH_DSW_PWROK"; - label = "EC_PCH_DSW_PWROK"; }; ec_rst_odl { gpios = <&gpio0 2 GPIO_INPUT>; - label = "EC_RST_ODL"; }; ec_pch_sys_pwrok { gpios = <&gpio3 7 GPIO_OUT_LOW>; enum-name = "GPIO_EC_PCH_SYS_PWROK"; - label = "EC_PCH_SYS_PWROK"; }; ec_pch_rsmrst_odl { gpios = <&gpioa 6 GPIO_ODR_LOW>; enum-name = "GPIO_PCH_RSMRST_L"; - label = "EC_PCH_RSMRST_ODL"; }; ec_pch_pwr_btn_odl { gpios = <&gpioc 1 GPIO_ODR_HIGH>; enum-name = "GPIO_PCH_PWRBTN_L"; - label = "EC_PCH_PWR_BTN_ODL"; }; ec_pch_rtcrst { gpios = <&gpio7 6 GPIO_OUT_LOW>; enum-name = "GPIO_PCH_RTCRST"; - label = "EC_PCH_RTCRST"; }; ec_pch_wake_odl { gpios = <&gpio7 4 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "EC_PCH_WAKE_ODL"; }; ec_entering_rw { gpios = <&gpioe 3 GPIO_OUT_LOW>; enum-name = "GPIO_ENTERING_RW"; - label = "EC_ENTERING_RW"; }; ec_prochot_odl { gpios = <&gpio6 3 GPIO_ODR_HIGH>; enum-name = "GPIO_CPU_PROCHOT"; - label = "EC_PROCHOT_ODL"; }; ec_prochot_in_l { gpios = <&gpiof 0 GPIO_INPUT>; enum-name = "GPIO_EC_PROCHOT_IN_L"; - label = "EC_PROCHOT_IN_L"; }; sys_rst_odl { gpios = <&gpioc 5 GPIO_ODR_HIGH>; enum-name = "GPIO_SYS_RESET_L"; - label = "SYS_RST_ODL"; }; ec_pch_int_odl { gpios = <&gpiob 0 GPIO_ODR_HIGH>; enum-name = "GPIO_EC_INT_L"; - label = "EC_PCH_INT_ODL"; }; en_pp5000_usba { gpios = <&gpioc 6 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000_USBA"; - label = "EN_PP5000_USBA"; }; usb_a_low_pwr_od { gpios = <&gpio6 6 GPIO_ODR_LOW>; enum-name = "GPIO_USB_A_LOW_PWR_OD"; - label = "USB_A_LOW_PWR_OD"; }; gpio_usb_c1_rt_rst_odl_boardid_0: usb_c1_rt_rst_odl_boardid_0 { #gpio-cells = <0>; gpios = <&gpio3 2 GPIO_ODR_LOW>; - label = "USB_C1_RT_RST_ODL_BOARDID_0"; }; gpio_usb_c1_rt_rst_odl: usb_c1_rt_rst_odl { #gpio-cells = <0>; gpios = <&gpio8 3 GPIO_ODR_LOW>; enum-name = "GPIO_USB_C1_RT_RST_ODL"; - label = "USB_C1_RT_RST_ODL"; }; usb_c0_oc_odl { gpios = <&gpiob 1 GPIO_ODR_HIGH>; enum-name = "GPIO_USB_C0_OC_ODL"; - label = "USB_C0_OC_ODL"; }; usb_c1_oc_odl { gpios = <&gpio5 0 GPIO_ODR_HIGH>; enum-name = "GPIO_USB_C1_OC_ODL"; - label = "USB_C1_OC_ODL"; }; usb_c1_rt_int_odl { gpios = <&gpiof 3 GPIO_INPUT>; - label = "USB_C1_RT_INT_ODL"; }; ec_h1_packet_mode { gpios = <&gpio7 5 GPIO_OUT_LOW>; enum-name = "GPIO_PACKET_MODE_EN"; - label = "EC_H1_PACKET_MODE"; }; m2_ssd_pln { gpios = <&gpioa 0 GPIO_ODR_HIGH>; enum-name = "GPIO_M2_SSD_PLN"; - label = "M2_SSD_PLN"; }; m2_ssd_pla { gpios = <&gpio7 0 GPIO_INPUT>; - label = "M2_SSD_PLA"; }; ccd_mode_odl { gpios = <&gpioe 5 GPIO_INPUT>; - label = "CCD_MODE_ODL"; }; ec_slp_s0ix { - gpios = <&gpio7 2 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_SLP_S0IX"; + gpios = <&gpio7 2 GPIO_INPUT_PULL_UP>; }; gpio_unused_gpio41: unused_gpio41 { #gpio-cells = <0>; - gpios = <&gpio4 1 (GPIO_INPUT | GPIO_PULL_UP)>; + gpios = <&gpio4 1 GPIO_INPUT_PULL_UP>; enum-name = "GPIO_USB_C1_LS_EN"; - label = "UNUSED_GPIO41"; }; ec_kb_bl_en { - gpios = <&gpio8 6 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_KB_BL_EN"; + gpios = <&gpio8 6 GPIO_INPUT_PULL_UP>; }; ec_espi_alert_l { - gpios = <&gpio5 7 (GPIO_INPUT | GPIO_PULL_UP)>; - label = "EC_ESPI_ALERT_L"; + gpios = <&gpio5 7 GPIO_INPUT_PULL_UP>; }; ec_edp_bl_en { gpios = <&gpiod 3 GPIO_OUT_HIGH>; enum-name = "GPIO_ENABLE_BACKLIGHT"; - label = "EC_EDP_BL_EN"; }; ec_i2c0_sensor_scl { gpios = <&gpiob 5 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SCL"; - label = "EC_I2C0_SENSOR_SCL"; }; ec_i2c0_sensor_sda { gpios = <&gpiob 4 GPIO_INPUT>; enum-name = "GPIO_EC_I2C0_SENSOR_SDA"; - label = "EC_I2C0_SENSOR_SDA"; }; ec_i2c1_usb_c0_scl { gpios = <&gpio9 0 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SCL"; - label = "EC_I2C1_USB_C0_SCL"; }; ec_i2c1_usb_c0_sda { gpios = <&gpio8 7 GPIO_INPUT>; enum-name = "GPIO_EC_I2C1_USB_C0_SDA"; - label = "EC_I2C1_USB_C0_SDA"; }; ec_i2c2_usb_c1_scl { gpios = <&gpio9 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SCL"; - label = "EC_I2C2_USB_C1_SCL"; }; ec_i2c2_usb_c1_sda { gpios = <&gpio9 1 GPIO_INPUT>; enum-name = "GPIO_EC_I2C2_USB_C1_SDA"; - label = "EC_I2C2_USB_C1_SDA"; }; ec_i2c3_usb_1_mix_scl { gpios = <&gpiod 1 GPIO_INPUT>; enum-name = "GPIO_EC_I2C3_USB_1_MIX_SCL"; - label = "EC_I2C3_USB_1_MIX_SCL"; }; ec_i2c3_usb_1_mix_sda { gpios = <&gpiod 0 GPIO_INPUT>; enum-name = "GPIO_EC_I2C3_USB_1_MIX_SDA"; - label = "EC_I2C3_USB_1_MIX_SDA"; }; ec_i2c5_battery_scl { gpios = <&gpio3 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SCL"; - label = "EC_I2C5_BATTERY_SCL"; }; ec_i2c5_battery_sda { gpios = <&gpio3 6 GPIO_INPUT>; enum-name = "GPIO_EC_I2C5_BATTERY_SDA"; - label = "EC_I2C5_BATTERY_SDA"; }; ec_i2c7_eeprom_pwr_scl_r { gpios = <&gpiob 3 GPIO_INPUT>; enum-name = "GPIO_EC_I2C7_EEPROM_PWR_SCL_R"; - label = "EC_I2C7_EEPROM_PWR_SCL_R"; }; ec_i2c7_eeprom_pwr_sda_r { gpios = <&gpiob 2 GPIO_INPUT>; enum-name = "GPIO_EC_I2C7_EEPROM_PWR_SDA_R"; - label = "EC_I2C7_EEPROM_PWR_SDA_R"; }; /* * TODO(b:190743662) Cleanup to possibly remove the enum @@ -361,17 +291,14 @@ ec_batt_pres_odl { gpios = <&gpioe 1 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; gpio_en_pp5000_fan: en_pp5000_fan { gpios = <&gpio6 1 GPIO_OUT_LOW>; enum-name = "GPIO_EN_PP5000_FAN"; - label = "EN_PP5000_FAN"; }; ec_kso_02_inv { gpios = <&gpio1 7 GPIO_OUT_LOW>; enum-name = "GPIO_KBD_KSO2"; - label = "EC_KSO_02_INV"; }; }; diff --git a/zephyr/projects/volteer/volteer/include/gpio_map.h b/zephyr/projects/volteer/volteer/include/gpio_map.h index 2d6f5f87ee..fe6e8d08ee 100644 --- a/zephyr/projects/volteer/volteer/include/gpio_map.h +++ b/zephyr/projects/volteer/volteer/include/gpio_map.h @@ -21,7 +21,7 @@ * Note we only need to create aliases for GPIOs that are referenced in common * platform/ec code. */ -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_PG_EC_DSW_PWROK +#define GPIO_TEMP_SENSOR_POWER GPIO_PG_EC_DSW_PWROK /* Helper macros for generating CROS_EC_GPIO_INTERRUPTS */ #ifdef CONFIG_PLATFORM_EC_POWERSEQ diff --git a/zephyr/projects/volteer/volteer/prj.conf b/zephyr/projects/volteer/volteer/prj.conf index a034e65606..77f39a20e6 100644 --- a/zephyr/projects/volteer/volteer/prj.conf +++ b/zephyr/projects/volteer/volteer/prj.conf @@ -15,6 +15,7 @@ CONFIG_ARM_MPU=y # eSPI CONFIG_ESPI=y CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4=y +CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5=y CONFIG_PLATFORM_EC=y CONFIG_SHIMMED_TASKS=y @@ -56,6 +57,7 @@ CONFIG_PLATFORM_EC_CONSOLE_CMD_LEDTEST=n CONFIG_PLATFORM_EC_POWERSEQ=y CONFIG_PLATFORM_EC_POWERSEQ_RTC_RESET=y CONFIG_PLATFORM_EC_POWERSEQ_S0IX=y +CONFIG_PLATFORM_EC_POWERSEQ_S4=y CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y CONFIG_PLATFORM_EC_THROTTLE_AP=y @@ -91,6 +93,7 @@ CONFIG_PLATFORM_EC_ALS_TCS3400=y # Temperature sensors CONFIG_PLATFORM_EC_TEMP_SENSOR=y +CONFIG_PLATFORM_EC_TEMP_SENSOR_POWER=y CONFIG_PLATFORM_EC_THERMISTOR=y # Miscellaneous configs diff --git a/zephyr/projects/volteer/volteer/pwm.dts b/zephyr/projects/volteer/volteer/pwm.dts index ec581f2caf..c551280262 100644 --- a/zephyr/projects/volteer/volteer/pwm.dts +++ b/zephyr/projects/volteer/volteer/pwm.dts @@ -7,38 +7,32 @@ named-pwms { compatible = "named-pwms"; - led1_blue: led1_blue { + led1_blue: led_1_l { #pwm-cells = <0>; pwms = <&pwm2 0 PWM_POLARITY_INVERTED>; - label = "LED1_BLUE"; frequency = <4800>; }; - led2_green: led2_green { + led2_green: led_2_l { #pwm-cells = <0>; pwms = <&pwm0 0 PWM_POLARITY_INVERTED>; - label = "LED2_GREEN"; frequency = <4800>; }; - led3_red: led3_red { + led3_red: led_3_l { #pwm-cells = <0>; pwms = <&pwm1 0 PWM_POLARITY_INVERTED>; - label = "LED3_RED"; frequency = <4800>; }; - led3_sidesel: led3_sidesel { + led3_sidesel: led_sidesel_4_l { #pwm-cells = <0>; pwms = <&pwm7 0 PWM_POLARITY_INVERTED>; - label = "LED4_SIDESEL"; frequency = <2400>; }; - kblight: kblight { + kblight: ec_kb_bl_pwm { pwms = <&pwm3 0 0>; - label = "KBLIGHT"; frequency = <2400>; }; - pwm_fan: fan { + pwm_fan: fan_pwm { pwms = <&pwm5 0 0>; - label = "FAN"; frequency = <25000>; }; }; diff --git a/zephyr/shim/chip/CMakeLists.txt b/zephyr/shim/chip/CMakeLists.txt index 5c76a4163a..59b5a6c739 100644 --- a/zephyr/shim/chip/CMakeLists.txt +++ b/zephyr/shim/chip/CMakeLists.txt @@ -6,7 +6,5 @@ if (DEFINED CONFIG_SOC_FAMILY_NPCX) add_subdirectory(npcx) elseif (DEFINED CONFIG_SOC_FAMILY_RISCV_ITE) add_subdirectory(it8xxx2) -elseif (DEFINED CONFIG_SOC_POSIX) - add_subdirectory(posix) endif() diff --git a/zephyr/shim/chip/it8xxx2/CMakeLists.txt b/zephyr/shim/chip/it8xxx2/CMakeLists.txt index 7a92a3cfb6..6f905a20ba 100644 --- a/zephyr/shim/chip/it8xxx2/CMakeLists.txt +++ b/zephyr/shim/chip/it8xxx2/CMakeLists.txt @@ -5,6 +5,8 @@ zephyr_library_include_directories(include) zephyr_library_sources(clock.c) +zephyr_library_sources(gpio.c) zephyr_library_sources_ifdef(CONFIG_CROS_EC system.c) zephyr_library_sources_ifdef(CONFIG_CROS_EC pinmux.c) zephyr_library_sources_ifdef(CONFIG_CROS_KB_RAW_ITE keyboard_raw.c) +zephyr_library_sources_ifdef(CONFIG_PM_POLICY_APP power_policy.c) diff --git a/zephyr/shim/chip/it8xxx2/gpio.c b/zephyr/shim/chip/it8xxx2/gpio.c new file mode 100644 index 0000000000..148e1a97c9 --- /dev/null +++ b/zephyr/shim/chip/it8xxx2/gpio.c @@ -0,0 +1,55 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <device.h> +#include <kernel.h> + +#include <logging/log.h> + +#include "gpio.h" +#include "gpio/gpio.h" + +LOG_MODULE_REGISTER(shim_cros_gpio, LOG_LEVEL_ERR); + +static const struct unused_pin_config unused_pin_configs[] = { + UNUSED_GPIO_CONFIG_LIST +}; + +int gpio_config_unused_pins(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(unused_pin_configs); ++i) { + int rv; + int flags; + const struct device *dev = + device_get_binding(unused_pin_configs[i].dev_name); + + if (dev == NULL) { + LOG_ERR("Not found (%s)", + unused_pin_configs[i].dev_name); + return -ENOTSUP; + } + + /* + * Set the default setting for the floating IOs. The floating + * IOs cause the leakage current. Set unused pins as input with + * internal PU to prevent extra power consumption. + */ + if (unused_pin_configs[i].flags == 0) + flags = GPIO_INPUT | GPIO_PULL_UP; + else + flags = unused_pin_configs[i].flags; + + rv = gpio_pin_configure(dev, unused_pin_configs[i].pin, flags); + + if (rv < 0) { + LOG_ERR("Config failed %s-%d (%d)", + unused_pin_configs[i].dev_name, + unused_pin_configs[i].pin, rv); + return rv; + } + } + + return 0; +} diff --git a/zephyr/shim/chip/it8xxx2/power_policy.c b/zephyr/shim/chip/it8xxx2/power_policy.c new file mode 100644 index 0000000000..62e2a14ab8 --- /dev/null +++ b/zephyr/shim/chip/it8xxx2/power_policy.c @@ -0,0 +1,41 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <pm/pm.h> +#include <pm/policy.h> +#include <soc.h> +#include <zephyr.h> + +#include "system.h" + +static const struct pm_state_info pm_states[] = + PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0)); + +/* CROS PM policy handler */ +struct pm_state_info pm_policy_next_state(uint8_t cpu, int32_t ticks) +{ + ARG_UNUSED(cpu); + + /* Deep sleep is allowed */ + if (DEEP_SLEEP_ALLOWED) { + /* + * If there are multiple power states, iterating backward + * is needed to take priority into account. + */ + for (int i = 0; i < ARRAY_SIZE(pm_states); i++) { + /* + * To check if given power state is enabled and + * could be used. + */ + if (!pm_constraint_get(pm_states[i].state)) { + continue; + } + + return pm_states[i]; + } + } + + return (struct pm_state_info){PM_STATE_ACTIVE, 0, 0}; +} diff --git a/zephyr/shim/chip/npcx/CMakeLists.txt b/zephyr/shim/chip/npcx/CMakeLists.txt index d3cd4b48fd..585b072ea8 100644 --- a/zephyr/shim/chip/npcx/CMakeLists.txt +++ b/zephyr/shim/chip/npcx/CMakeLists.txt @@ -13,7 +13,6 @@ zephyr_library_include_directories(include) zephyr_library_sources(clock.c) zephyr_library_sources(gpio.c) -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI espi.c) zephyr_library_sources_ifdef(CONFIG_CROS_KB_RAW_NPCX keyboard_raw.c) zephyr_library_sources_ifdef(CONFIG_CROS_SHI_NPCX shi.c) zephyr_library_sources_ifdef(CONFIG_CROS_EC system.c) diff --git a/zephyr/shim/chip/npcx/espi.c b/zephyr/shim/chip/npcx/espi.c deleted file mode 100644 index 2115f388d6..0000000000 --- a/zephyr/shim/chip/npcx/espi.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <device.h> -#include <sys/util.h> - -#include "drivers/espi.h" -#include "soc_espi.h" -#include "zephyr_espi_shim.h" - -bool is_acpi_command(uint32_t data) -{ - struct espi_evt_data_acpi *acpi = (struct espi_evt_data_acpi *)&data; - - return acpi->type; -} - -uint32_t get_acpi_value(uint32_t data) -{ - struct espi_evt_data_acpi *acpi = (struct espi_evt_data_acpi *)&data; - - return acpi->data; -} - -bool is_8042_ibf(uint32_t data) -{ - struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; - - return kbc->evt & HOST_KBC_EVT_IBF; -} - -bool is_8042_obe(uint32_t data) -{ - struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; - - return kbc->evt & HOST_KBC_EVT_OBE; -} - -uint32_t get_8042_type(uint32_t data) -{ - struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; - - return kbc->type; -} - -uint32_t get_8042_data(uint32_t data) -{ - struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; - - return kbc->data; -} diff --git a/zephyr/shim/chip/npcx/power_policy.c b/zephyr/shim/chip/npcx/power_policy.c index 803ac51e9b..5c6b4dc309 100644 --- a/zephyr/shim/chip/npcx/power_policy.c +++ b/zephyr/shim/chip/npcx/power_policy.c @@ -5,27 +5,33 @@ #include <zephyr.h> #include <pm/pm.h> +#include <pm/policy.h> #include <soc.h> #include "console.h" #include "cros_version.h" #include "system.h" -static const struct pm_state_info pm_min_residency[] = - PM_STATE_INFO_DT_ITEMS_LIST(DT_NODELABEL(cpu0)); +static const struct pm_state_info residency_info[] = + PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0)); /* CROS PM policy handler */ -struct pm_state_info pm_policy_next_state(int32_t ticks) +struct pm_state_info pm_policy_next_state(uint8_t cpu, int32_t ticks) { - /* Deep sleep is allowed and console is not in use. */ - if (DEEP_SLEEP_ALLOWED != 0 && !npcx_power_console_is_in_use()) { - for (int i = ARRAY_SIZE(pm_min_residency) - 1; i >= 0; i--) { + ARG_UNUSED(cpu); + + if (DEEP_SLEEP_ALLOWED) { + for (int i = ARRAY_SIZE(residency_info) - 1; i >= 0; i--) { + if (!pm_constraint_get(residency_info[i].state)) { + continue; + } + /* Find suitable power state by residency time */ if (ticks == K_TICKS_FOREVER || ticks >= k_us_to_ticks_ceil32( - pm_min_residency[i] + residency_info[i] .min_residency_us)) { - return pm_min_residency[i]; + return residency_info[i]; } } } diff --git a/zephyr/shim/chip/posix/espi.c b/zephyr/shim/chip/posix/espi.c deleted file mode 100644 index cf348744d7..0000000000 --- a/zephyr/shim/chip/posix/espi.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <sys/util.h> -#include "zephyr_espi_shim.h" - -#define ACPI_TYPE_POS 0U -#define ACPI_DATA_POS 8U - -/* 8042 event data format */ -#define POSIX_8042_EVT_POS 16U -#define POSIX_8042_DATA_POS 8U -#define POSIX_8042_TYPE_POS 0U - -/* 8042 event type format */ -#define POSIX_8042_EVT_IBF BIT(0) -#define POSIX_8042_EVT_OBE BIT(1) - -bool is_acpi_command(uint32_t data) -{ - return (data >> ACPI_TYPE_POS) & 0x01; -} - -uint32_t get_acpi_value(uint32_t data) -{ - return (data >> ACPI_TYPE_POS) & 0xff; -} - -bool is_POSIX_8042_ibf(uint32_t data) -{ - return (data >> POSIX_8042_EVT_POS) & POSIX_8042_EVT_IBF; -} - -bool is_POSIX_8042_obe(uint32_t data) -{ - return (data >> POSIX_8042_EVT_POS) & POSIX_8042_EVT_OBE; -} - -uint32_t get_POSIX_8042_type(uint32_t data) -{ - return (data >> POSIX_8042_TYPE_POS) & 0xFF; -} - -uint32_t get_POSIX_8042_data(uint32_t data) -{ - return (data >> POSIX_8042_DATA_POS) & 0xFF; -} diff --git a/zephyr/shim/include/bbram.h b/zephyr/shim/include/bbram.h deleted file mode 100644 index 3eba4b157b..0000000000 --- a/zephyr/shim/include/bbram.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef ZEPHYR_SHIM_INCLUDE_BBRAM_H_ -#define ZEPHYR_SHIM_INCLUDE_BBRAM_H_ - -#include <devicetree.h> - -#define BBRAM_SIZE DT_REG_SIZE_BY_NAME(DT_NODELABEL(bbram), memory) -#define BBRAM_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(bbram), memory) -#define BBRAM(offset) REG8(BBRAM_ADDR + offset) -#define BBRAM_BKUP_STS BBRAM(CONFIG_BBRAM_BKUP_STS) - -#endif /* ZEPHYR_SHIM_INCLUDE_BBRAM_H_ */ diff --git a/zephyr/shim/include/board.h b/zephyr/shim/include/board.h index a1059eb426..5d480b5615 100644 --- a/zephyr/shim/include/board.h +++ b/zephyr/shim/include/board.h @@ -30,7 +30,7 @@ /* Include board specific sensor configuration if motionsense is enabled */ #ifdef CONFIG_MOTIONSENSE -#include "motionsense_sensors.h" +#include "motionsense_sensors_defs.h" #endif #endif /* __BOARD_H */ diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 9598e2cf5a..66bbc39795 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -162,6 +162,11 @@ #define CONFIG_BATTERY_V2 #endif +#undef CONFIG_BATTERY_TYPE_NO_AUTO_DETECT +#ifdef CONFIG_PLATFORM_EC_BATTERY_TYPE_NO_AUTO_DETECT +#define CONFIG_BATTERY_TYPE_NO_AUTO_DETECT +#endif + #undef CONFIG_BATTERY_COUNT #define CONFIG_BATTERY_COUNT CONFIG_PLATFORM_EC_BATTERY_COUNT @@ -283,11 +288,21 @@ #define CONFIG_CHARGER_ISL9238C #endif +#undef CONFIG_CHARGER_RAA489000 +#ifdef CONFIG_PLATFORM_EC_CHARGER_RAA489000 +#define CONFIG_CHARGER_RAA489000 +#endif + #undef CONFIG_CHARGER_MAINTAIN_VBAT #ifdef CONFIG_PLATFORM_EC_CHARGER_MAINTAIN_VBAT #define CONFIG_CHARGER_MAINTAIN_VBAT #endif +#undef CONFIG_CHARGER_TRICKLE +#ifdef CONFIG_PLATFORM_EC_CHARGER_TRICKLE +#define CONFIG_TRICKLE_CHARGING +#endif + #undef CONFIG_CHARGER_NARROW_VDC #ifdef CONFIG_PLATFORM_EC_CHARGER_NARROW_VDC #define CONFIG_CHARGER_NARROW_VDC @@ -330,40 +345,62 @@ #define CONFIG_EMULATED_SYSRQ #endif -/* eSPI configuration */ -#ifdef CONFIG_PLATFORM_EC_ESPI +/* Host interface selection */ +#undef CONFIG_HOST_INTERFACE_ESPI +#ifdef CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI +#define CONFIG_HOST_INTERFACE_ESPI +#endif + +#undef CONFIG_HOST_INTERFACE_HECI +#ifdef CONFIG_PLATFORM_EC_HOST_INTERFACE_HECI +#define CONFIG_HOST_INTERFACE_HECI +#endif + +#undef CONFIG_HOST_INTERFACE_LPC +#ifdef CONFIG_PLATFORM_EC_HOST_INTERFACE_LPC +#define CONFIG_HOST_INTERFACE_LPC +#endif -#ifdef CONFIG_PLATFORM_EC_HOSTCMD -#define CONFIG_HOSTCMD_ESPI +#undef CONFIG_HOST_INTERFACE_SHI +#ifdef CONFIG_PLATFORM_EC_HOST_INTERFACE_SHI +#define CONFIG_HOST_INTERFACE_SHI #endif /* eSPI signals */ +#undef CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #ifdef CONFIG_PLATFORM_EC_ESPI_VW_SLP_S3 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S3 #endif +#undef CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #ifdef CONFIG_PLATFORM_EC_ESPI_VW_SLP_S4 #define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 #endif +#undef CONFIG_HOSTCMD_ESPI_VW_SLP_S5 +#ifdef CONFIG_PLATFORM_EC_ESPI_VW_SLP_S5 +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S5 +#endif + +#undef CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST #ifdef CONFIG_PLATFORM_EC_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST #define CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST #endif -#endif /* CONFIG_PLATFORM_EC_ESPI */ - -#if DT_NODE_EXISTS(DT_NODELABEL(flash0)) -#define CONFIG_PROGRAM_MEMORY_BASE DT_REG_ADDR(DT_NODELABEL(flash0)) +#if DT_HAS_CHOSEN(zephyr_flash) +#define CONFIG_PROGRAM_MEMORY_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) #else -#define CONFIG_PROGRAM_MEMORY_BASE 0X0 +#error "A zephyr,flash device must be chosen in the device tree" #endif -#if DT_NODE_EXISTS(DT_NODELABEL(sram0)) -#define CONFIG_RAM_BASE DT_REG_ADDR(DT_NODELABEL(sram0)) -#define CONFIG_DATA_RAM_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) -#else +#if DT_HAS_CHOSEN(zephyr_sram) +#define CONFIG_RAM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) +#define CONFIG_DATA_RAM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) +#elif defined(CONFIG_ARCH_POSIX) #define CONFIG_RAM_BASE 0x0 #define CONFIG_DATA_RAM_SIZE 0x0 +#else +#error "A zephyr,sram device must be chosen in the device tree" #endif #define CONFIG_RO_MEM_OFF CONFIG_CROS_EC_RO_MEM_OFF @@ -466,11 +503,21 @@ #define CONFIG_TEMP_SENSOR #endif +#undef CONFIG_TEMP_SENSOR_POWER +#ifdef CONFIG_PLATFORM_EC_TEMP_SENSOR_POWER +#define CONFIG_TEMP_SENSOR_POWER +#endif + #undef CONFIG_THERMISTOR #ifdef CONFIG_PLATFORM_EC_THERMISTOR #define CONFIG_THERMISTOR #endif +#undef CONFIG_TEMP_SENSOR_TMP112 +#ifdef CONFIG_PLATFORM_EC_TEMP_SENSOR_TMP112 +#define CONFIG_TEMP_SENSOR_TMP112 +#endif + #ifdef CONFIG_PLATFORM_EC_I2C /* Also see shim/include/i2c/i2c.h which defines the ports enum */ #define CONFIG_I2C_CONTROLLER @@ -588,6 +635,42 @@ #define CONFIG_LED_PWM_COUNT DT_PROP_LEN(DT_INST(0, cros_ec_pwm_leds), leds) #endif +#ifdef CONFIG_PLATFORM_EC_LED_PWM_CHARGE_COLOR +#undef CONFIG_LED_PWM_CHARGE_COLOR +#define CONFIG_LED_PWM_CHARGE_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_CHARGE_COLOR +#endif + +#ifdef CONFIG_PLATFORM_EC_LED_PWM_NEAR_FULL_COLOR +#undef CONFIG_LED_PWM_NEAR_FULL_COLOR +#define CONFIG_LED_PWM_NEAR_FULL_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_NEAR_FULL_COLOR +#endif + +#ifdef CONFIG_PLATFORM_EC_LED_PWM_CHARGE_ERROR_COLOR +#undef CONFIG_LED_PWM_CHARGE_ERROR_COLOR +#define CONFIG_LED_PWM_CHARGE_ERROR_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_CHARGE_ERROR_COLOR +#endif + +#ifdef CONFIG_PLATFORM_EC_LED_PWM_SOC_ON_COLOR +#undef CONFIG_LED_PWM_SOC_ON_COLOR +#define CONFIG_LED_PWM_SOC_ON_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_SOC_ON_COLOR +#endif + +#ifdef CONFIG_PLATFORM_EC_LED_PWM_SOC_SUSPEND_COLOR +#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR +#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_SOC_SUSPEND_COLOR +#endif + +#ifdef CONFIG_PLATFORM_EC_LED_PWM_LOW_BATT_COLOR +#undef CONFIG_LED_PWM_LOW_BATT_COLOR +#define CONFIG_LED_PWM_LOW_BATT_COLOR \ + CONFIG_PLATFORM_EC_LED_PWM_LOW_BATT_COLOR +#endif + #undef CONFIG_CMD_LEDTEST #ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_LEDTEST #define CONFIG_CMD_LEDTEST @@ -655,6 +738,11 @@ #define CONFIG_POWER_S0IX #endif +#undef CONFIG_POWER_S4_RESIDENCY +#ifdef CONFIG_PLATFORM_EC_POWERSEQ_S4 +#define CONFIG_POWER_S4_RESIDENCY +#endif + #undef CONFIG_POWER_BUTTON_X86 #ifdef CONFIG_PLATFORM_EC_POWERSEQ_INTEL #define CONFIG_POWER_BUTTON_X86 @@ -801,6 +889,11 @@ #define CONFIG_CMD_CHGRAMP #endif +#undef CONFIG_CMD_CHARGER_DUMP +#ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_CHARGER_DUMP +#define CONFIG_CMD_CHARGER_DUMP +#endif + #undef CONFIG_USB_PID #ifdef CONFIG_PLATFORM_EC_USB_PID #define CONFIG_USB_PID CONFIG_PLATFORM_EC_USB_PID @@ -1022,6 +1115,11 @@ #define CONFIG_USB_PD_TCPM_RT1715 #endif +#undef CONFIG_USB_PD_TCPM_RT1718S +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_RT1718S +#define CONFIG_USB_PD_TCPM_RT1718S +#endif + #undef CONFIG_USB_PD_TCPM_TUSB422 #ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_TUSB422 #define CONFIG_USB_PD_TCPM_TUSB422 @@ -1043,6 +1141,8 @@ #undef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 #ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT8XXX2 #define CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 +/* Individual setting CC1 and CC2 resistance. */ +#define IT83XX_USBPD_CC1_CC2_RESISTANCE_SEPARATE #endif #undef CONFIG_USB_PD_TCPM_DRIVER_IT83XX @@ -1050,6 +1150,26 @@ #define CONFIG_USB_PD_TCPM_DRIVER_IT83XX #endif +#undef CONFIG_USB_PD_TCPM_RAA489000 +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000 +#define CONFIG_USB_PD_TCPM_RAA489000 +#endif + +#undef CONFIG_USB_PD_TCPM_ANX7447 +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447 +#define CONFIG_USB_PD_TCPM_ANX7447 +#endif + +#undef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447_AUX_PU_PD +#define CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD +#endif + +#undef CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND +#define CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND +#endif + #undef CONFIG_USB_PD_PORT_MAX_COUNT #ifdef CONFIG_PLATFORM_EC_USB_PD_PORT_MAX_COUNT #define CONFIG_USB_PD_PORT_MAX_COUNT CONFIG_PLATFORM_EC_USB_PD_PORT_MAX_COUNT @@ -1071,11 +1191,21 @@ #define CONFIG_USBC_PPC_AOZ1380 #endif +#undef CONFIG_USBC_PPC_KTU1125 +#ifdef CONFIG_PLATFORM_EC_USBC_PPC_KTU1125 +#define CONFIG_USBC_PPC_KTU1125 +#endif + #undef CONFIG_USBC_PPC_NX20P3483 #ifdef CONFIG_PLATFORM_EC_USBC_PPC_NX20P3483 #define CONFIG_USBC_PPC_NX20P3483 #endif +#undef CONFIG_USBC_PPC_RT1718S +#ifdef CONFIG_PLATFORM_EC_USBC_PPC_RT1718S +#define CONFIG_USBC_PPC_RT1718S +#endif + #undef CONFIG_USBC_PPC_SN5S330 #ifdef CONFIG_PLATFORM_EC_USBC_PPC_SN5S330 #define CONFIG_USBC_PPC_SN5S330 @@ -1091,6 +1221,9 @@ #define CONFIG_USBC_PPC_SYV682C #endif +#undef CONFIG_SYV682X_HV_ILIM +#define CONFIG_SYV682X_HV_ILIM CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM + #undef CONFIG_USBC_PPC_SYV682X_NO_CC #ifdef CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_NO_CC #define CONFIG_USBC_PPC_SYV682X_NO_CC @@ -1468,8 +1601,18 @@ #define CONFIG_ACCELGYRO_ICM42607 #endif +#undef CONFIG_ACCELGYRO_LSM6DSO +#ifdef CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO +#define CONFIG_ACCELGYRO_LSM6DSO +#endif + #endif /* CONFIG_PLATFORM_EC_MOTIONSENSE */ +#undef CONFIG_MATH_UTIL +#ifdef CONFIG_PLATFORM_EC_MATH_UTIL +#define CONFIG_MATH_UTIL +#endif + #undef CONFIG_HOSTCMD_GET_UPTIME_INFO #ifdef CONFIG_PLATFORM_EC_HOSTCMD_GET_UPTIME_INFO #define CONFIG_HOSTCMD_GET_UPTIME_INFO @@ -1714,6 +1857,17 @@ #define CONFIG_CHARGER_BQ25720 #endif +#undef CONFIG_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +#ifdef CONFIG_PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH_CUSTOM +#endif + +#undef CONFIG_CHARGER_BQ257X0_ILIM2_VTH +#ifdef CONFIG_PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH +#define CONFIG_CHARGER_BQ257X0_ILIM2_VTH \ + CONFIG_PLATFORM_EC_CHARGER_BQ257X0_ILIM2_VTH +#endif + #undef CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM #ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25720_VSYS_TH2_CUSTOM #define CONFIG_CHARGER_BQ25720_VSYS_TH2_CUSTOM @@ -1790,6 +1944,17 @@ #define CONFIG_CHARGER_BQ25710_CMP_REF_1P2 #endif +#undef CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM +#ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM +#define CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG_CUSTOM +#endif + +#undef CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG +#ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25710_PKPWR_TOVLD_DEG +#define CONFIG_CHARGER_BQ25710_PKPWR_TOVLD_DEG \ + CONFIG_PLATFORM_EC_CHARGER_BQ25710_PKPWR_TOVLD_DEG +#endif + #undef CONFIG_CHARGER_BQ25710_EN_ACOC #ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25710_EN_ACOC #define CONFIG_CHARGER_BQ25710_EN_ACOC @@ -1832,6 +1997,11 @@ #define CONFIG_CHARGER_BQ25710_PP_ACOK #endif +#undef CONFIG_CHARGER_BQ25720_PP_IDCHG2 +#ifdef CONFIG_PLATFORM_EC_CHARGER_BQ25720_PP_IDCHG2 +#define CONFIG_CHARGER_BQ25720_PP_IDCHG2 +#endif + #undef CONFIG_CHARGER_DISCHARGE_ON_AC #ifdef CONFIG_PLATFORM_EC_CHARGER_DISCHARGE_ON_AC #define CONFIG_CHARGER_DISCHARGE_ON_AC @@ -1874,6 +2044,9 @@ #define CONFIG_CMD_CHARGER_ADC_AMON_BMON #endif +#undef CONFIG_USB_PD_PULLUP +#define CONFIG_USB_PD_PULLUP CONFIG_PLATFORM_EC_USB_PD_PULLUP + #undef CONFIG_USB_PD_ONLY_FIXED_PDOS #ifdef CONFIG_PLATFORM_EC_USB_PD_ONLY_FIXED_PDOS #define CONFIG_USB_PD_ONLY_FIXED_PDOS @@ -1882,6 +2055,8 @@ #undef CONFIG_MP2964 #ifdef CONFIG_PLATFORM_EC_MP2964 #define CONFIG_MP2964 +#define I2C_ADDR_MP2964_FLAGS \ + DT_REG_ADDR(DT_NODELABEL(pmic_mp2964)) #endif #undef CONFIG_ACCELGYRO_ICM_COMM_SPI @@ -1919,6 +2094,11 @@ #define CONFIG_LOW_POWER_IDLE #endif +#undef CONFIG_POWER_COMMON +#ifdef CONFIG_PLATFORM_EC_POWER_COMMON +#define CONFIG_POWER_COMMON +#endif + #undef CONFIG_PORT80_4_BYTE #ifdef CONFIG_PLATFORM_EC_PORT80_4_BYTE #define CONFIG_PORT80_4_BYTE @@ -2005,4 +2185,9 @@ #define CONFIG_IO_EXPANDER_SUPPORT_GET_PORT #endif +#undef CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY +#ifdef CONFIG_PLATFORM_EC_USB_PD_REQUIRE_AP_MODE_ENTRY +#define CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY +#endif + #endif /* __CROS_EC_CONFIG_CHIP_H */ diff --git a/zephyr/shim/include/motionsense_sensors.h b/zephyr/shim/include/motionsense_sensors.h index bfa9aea050..e4ecf5d6de 100644 --- a/zephyr/shim/include/motionsense_sensors.h +++ b/zephyr/shim/include/motionsense_sensors.h @@ -7,105 +7,50 @@ #define __CROS_EC_MOTIONSENSE_SENSORS_H #include <devicetree.h> +#include "motion_sense.h" -#define SENSOR_NODE DT_PATH(motionsense_sensor) -#define SENSOR_INFO_NODE DT_PATH(motionsense_sensor_info) -#define SENSOR_ALT_NODE DT_PATH(motionsense_sensor_alt) +extern struct motion_sensor_t motion_sensors_alt[]; -#define SENSOR_ID(id) DT_CAT(SENSOR_, id) - -/* Define the SENSOR_ID if: - * DT_NODE_HAS_STATUS(id, okay) && !DT_NODE_HAS_PROP(id, alternate_for) - */ -#define SENSOR_ID_WITH_COMMA(id) \ - IF_ENABLED(DT_NODE_HAS_STATUS(id, okay), \ - (COND_CODE_0(DT_NODE_HAS_PROP(id, alternate_for), \ - (SENSOR_ID(id), ), ()))) - -enum sensor_id { -#if DT_NODE_EXISTS(SENSOR_NODE) - DT_FOREACH_CHILD(SENSOR_NODE, SENSOR_ID_WITH_COMMA) -#endif - SENSOR_COUNT, -}; - -#undef SENSOR_ID_WITH_COMMA -/* Define the SENSOR_ID if: - * DT_NODE_HAS_STATUS(id, okay) && DT_NODE_HAS_PROP(id, alternate_for) +/* + * Performs probing of an alternate sensor. + * @param alt_idx Index in motion_sensors_alt of the sensor to be probed. + * It should be gained with SENSOR_ID, + * e.g. with SENSOR_ID(DT_NODELABEL(label)). + * @return EC_SUCCESS if the probe was successful, non-zero otherwise. */ -#define SENSOR_ID_WITH_COMMA(id) \ - IF_ENABLED(DT_NODE_HAS_STATUS(id, okay), \ - (COND_CODE_1(DT_NODE_HAS_PROP(id, alternate_for), \ - (SENSOR_ID(id), ), ()))) -enum sensor_alt_id { -#if DT_NODE_EXISTS(SENSOR_ALT_NODE) - DT_FOREACH_CHILD(SENSOR_ALT_NODE, SENSOR_ID_WITH_COMMA) -#endif - SENSOR_ALT_COUNT, -}; +int motion_sense_probe(enum sensor_alt_id alt_idx); /* - * Find the accelerometers for lid angle calculation. - * - * The angle calculation requires two accelerometers. One is on the lid - * and the other one is on the base. So we need to specify which sensor is - * on the lid and which one is on the base. We use two labels "lid_accel" - * and "base_accel". - * - * base_accel - label for the accelerometer sensor on the base. - * lid_accel - label for the accelerometer sensor on the lid. - * - * e.g) below shows BMA255 is the accelerometer on the lid and bmi260 is - * the accelerometer on the base. - * - * motionsense-sensor { - * lid_accel: lid-accel { - * compatible = "cros-ec,bma255"; - * status = "okay"; - * : - * : - * }; - * - * base_accel: base-accel { - * compatible = "cros-ec,bmi260"; - * status = "okay"; - * : - * : - * }; - * }; + * Performs checking CBI SSFC fields defined in DTS to verify if an alternate + * motion sensor is present. If there is a match, the function replaces + * a default motion sensor in the motion_sensors array. */ -#ifdef CONFIG_LID_ANGLE -#define CONFIG_LID_ANGLE_SENSOR_LID SENSOR_ID(DT_NODELABEL(lid_accel)) -#define CONFIG_LID_ANGLE_SENSOR_BASE SENSOR_ID(DT_NODELABEL(base_accel)) -#endif +void motion_sensors_check_ssfc(void); + +#define ENABLE_ALT_MOTION_SENSOR(alt_id) \ + motion_sensors[SENSOR_ID(DT_PHANDLE(alt_id, alternate_for))] = \ + motion_sensors_alt[SENSOR_ID(alt_id)]; /* - * Get the sensors running in force mode from DT and create a bit mask for it. - * - * e.g) lid accel and als_clear are in accel_force_mode. The macro below finds - * the corresponding bit for each sensor in bit mask and set it. - * motionsense-sensor-info { - * compatible = "cros-ec,motionsense-sensor-info"; - * - * // list of sensors in force mode - * accel-force-mode-sensors = <&lid_accel &als_clear>; - * }; + * Replaces a default motion sensor with an alternate one pointed by nodelabel. */ -#if DT_NODE_HAS_PROP(SENSOR_INFO_NODE, accel_force_mode_sensors) -#define SENSOR_IN_FORCE_MODE(i, id) \ - | BIT(SENSOR_ID(DT_PHANDLE_BY_IDX(id, accel_force_mode_sensors, i))) -#define CONFIG_ACCEL_FORCE_MODE_MASK \ - (0 UTIL_LISTIFY(DT_PROP_LEN(SENSOR_INFO_NODE, \ - accel_force_mode_sensors), SENSOR_IN_FORCE_MODE, \ - SENSOR_INFO_NODE)) -#endif +#define MOTIONSENSE_ENABLE_ALTERNATE(nodelabel) \ + do { \ + BUILD_ASSERT(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \ + "Motionsense alternate node does not exist"); \ + ENABLE_ALT_MOTION_SENSOR(DT_NODELABEL(nodelabel)); \ + } while (0) -/** - * If CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL is enabled, - * this function must be called to perform probing of alternative sensors. +/* + * Probes and replaces a default motion sensor with an alternate one pointed by + * nodelabel, if the probe was successful. */ -#ifdef CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL -void motion_sense_probe_sensors(void); -#endif +#define MOTIONSENSE_PROBE_AND_ENABLE_ALTERNATE(nodelabel) \ + do { \ + BUILD_ASSERT(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \ + "Motionsense alternate node does not exist"); \ + if (!motion_sense_probe(SENSOR_ID(DT_NODELABEL(nodelabel)))) \ + ENABLE_ALT_MOTION_SENSOR(DT_NODELABEL(nodelabel)); \ + } while (0) #endif /* __CROS_EC_MOTIONSENSE_SENSORS_H */ diff --git a/zephyr/shim/include/motionsense_sensors_defs.h b/zephyr/shim/include/motionsense_sensors_defs.h new file mode 100644 index 0000000000..ec2180566e --- /dev/null +++ b/zephyr/shim/include/motionsense_sensors_defs.h @@ -0,0 +1,103 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_MOTIONSENSE_SENSORS_DEFS_H +#define __CROS_EC_MOTIONSENSE_SENSORS_DEFS_H + +#include <devicetree.h> + +#define SENSOR_NODE DT_PATH(motionsense_sensor) +#define SENSOR_INFO_NODE DT_PATH(motionsense_sensor_info) +#define SENSOR_ALT_NODE DT_PATH(motionsense_sensor_alt) + +#define SENSOR_ID(id) DT_CAT(SENSOR_, id) + +/* Define the SENSOR_ID if: + * DT_NODE_HAS_STATUS(id, okay) && !DT_NODE_HAS_PROP(id, alternate_for) + */ +#define SENSOR_ID_WITH_COMMA(id) \ + IF_ENABLED(DT_NODE_HAS_STATUS(id, okay), \ + (COND_CODE_0(DT_NODE_HAS_PROP(id, alternate_for), \ + (SENSOR_ID(id), ), ()))) + +enum sensor_id { +#if DT_NODE_EXISTS(SENSOR_NODE) + DT_FOREACH_CHILD(SENSOR_NODE, SENSOR_ID_WITH_COMMA) +#endif + SENSOR_COUNT, +}; + +#undef SENSOR_ID_WITH_COMMA +/* Define the SENSOR_ID if: + * DT_NODE_HAS_STATUS(id, okay) && DT_NODE_HAS_PROP(id, alternate_for) + */ +#define SENSOR_ID_WITH_COMMA(id) \ + IF_ENABLED(DT_NODE_HAS_STATUS(id, okay), \ + (COND_CODE_1(DT_NODE_HAS_PROP(id, alternate_for), \ + (SENSOR_ID(id), ), ()))) +enum sensor_alt_id { +#if DT_NODE_EXISTS(SENSOR_ALT_NODE) + DT_FOREACH_CHILD(SENSOR_ALT_NODE, SENSOR_ID_WITH_COMMA) +#endif + SENSOR_ALT_COUNT, +}; + +/* + * Find the accelerometers for lid angle calculation. + * + * The angle calculation requires two accelerometers. One is on the lid + * and the other one is on the base. So we need to specify which sensor is + * on the lid and which one is on the base. We use two labels "lid_accel" + * and "base_accel". + * + * base_accel - label for the accelerometer sensor on the base. + * lid_accel - label for the accelerometer sensor on the lid. + * + * e.g) below shows BMA255 is the accelerometer on the lid and bmi260 is + * the accelerometer on the base. + * + * motionsense-sensor { + * lid_accel: lid-accel { + * compatible = "cros-ec,bma255"; + * status = "okay"; + * : + * : + * }; + * + * base_accel: base-accel { + * compatible = "cros-ec,bmi260"; + * status = "okay"; + * : + * : + * }; + * }; + */ +#ifdef CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_SENSOR_LID SENSOR_ID(DT_NODELABEL(lid_accel)) +#define CONFIG_LID_ANGLE_SENSOR_BASE SENSOR_ID(DT_NODELABEL(base_accel)) +#endif + +/* + * Get the sensors running in force mode from DT and create a bit mask for it. + * + * e.g) lid accel and als_clear are in accel_force_mode. The macro below finds + * the corresponding bit for each sensor in bit mask and set it. + * motionsense-sensor-info { + * compatible = "cros-ec,motionsense-sensor-info"; + * + * // list of sensors in force mode + * accel-force-mode-sensors = <&lid_accel &als_clear>; + * }; + */ +#if DT_NODE_HAS_PROP(SENSOR_INFO_NODE, accel_force_mode_sensors) +#define SENSOR_IN_FORCE_MODE(i, id) \ + | BIT(SENSOR_ID(DT_PHANDLE_BY_IDX(id, accel_force_mode_sensors, i))) +#define CONFIG_ACCEL_FORCE_MODE_MASK \ + (0 UTIL_LISTIFY(DT_PROP_LEN(SENSOR_INFO_NODE, \ + accel_force_mode_sensors), SENSOR_IN_FORCE_MODE, \ + SENSOR_INFO_NODE)) +#endif + +#endif /* __CROS_EC_MOTIONSENSE_SENSORS_DEFS_H */ diff --git a/zephyr/shim/include/temp_sensor/temp_sensor.h b/zephyr/shim/include/temp_sensor/temp_sensor.h index b0cadd4303..ef68cc5aa9 100644 --- a/zephyr/shim/include/temp_sensor/temp_sensor.h +++ b/zephyr/shim/include/temp_sensor/temp_sensor.h @@ -23,6 +23,21 @@ enum temp_sensor_id { #undef TEMP_SENSOR_ID_WITH_COMMA +/* TMP112 access array */ +#define ZSHIM_TMP112_SENSOR_ID(node_id) DT_STRING_UPPER_TOKEN(node_id, \ + tmp112_name) +#define TMP112_SENSOR_ID_WITH_COMMA(node_id) ZSHIM_TMP112_SENSOR_ID(node_id), + +enum tmp112_sensor { +#if DT_HAS_COMPAT_STATUS_OKAY(cros_ec_temp_sensor_tmp112) + DT_FOREACH_STATUS_OKAY(cros_ec_temp_sensor_tmp112, + TMP112_SENSOR_ID_WITH_COMMA) +#endif + TMP112_COUNT, +}; + +#undef TMP112_SENSOR_ID_WITH_COMMA + #endif /* CONFIG_PLATFORM_EC_TEMP_SENSOR */ #endif /* ZEPHYR_SHIM_INCLUDE_TEMP_SENSOR_TEMP_SENSOR_H_ */ diff --git a/zephyr/shim/include/usbc/ppc.h b/zephyr/shim/include/usbc/ppc.h index a59436712b..65943a86da 100644 --- a/zephyr/shim/include/usbc/ppc.h +++ b/zephyr/shim/include/usbc/ppc.h @@ -10,6 +10,7 @@ #include <devicetree.h> #include "usbc/ppc_sn5s330.h" #include "usbc/ppc_syv682x.h" +#include "usbc_ppc.h" #define PPC_ID(id) DT_CAT(PPC_, id) #define PPC_ID_WITH_COMMA(id) PPC_ID(id), diff --git a/zephyr/shim/include/usbc/tcpc_nct38xx.h b/zephyr/shim/include/usbc/tcpc_nct38xx.h new file mode 100644 index 0000000000..fa60d1caa9 --- /dev/null +++ b/zephyr/shim/include/usbc/tcpc_nct38xx.h @@ -0,0 +1,18 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_TCPC_NCT38XX_H +#define __CROS_EC_TCPC_NCT38XX_H + +/** + * @brief Get the NCT38XX GPIO device from the TCPC port enumeration + * + * @param port The enumeration of TCPC port + * + * @return NULL if failed, otherwise a pointer to NCT38XX GPIO device + */ +const struct device *nct38xx_get_gpio_device_from_port(const int port); + +#endif /* __CROS_EC_TCPC_NCT38XX_H */ diff --git a/zephyr/shim/include/zephyr_adc.h b/zephyr/shim/include/zephyr_adc.h index 7c0f3f3232..4d279bec86 100644 --- a/zephyr/shim/include/zephyr_adc.h +++ b/zephyr/shim/include/zephyr_adc.h @@ -30,8 +30,12 @@ struct adc_t { struct adc_channel_cfg channel_cfg; }; +#ifndef CONFIG_ADC_CHANNELS_RUNTIME_CONFIG extern const struct adc_t adc_channels[]; #else +extern struct adc_t adc_channels[]; +#endif /* CONFIG_ADC_CHANNELS_RUNTIME_CONFIG */ +#else /* Empty declaration to avoid warnings if adc.h is included */ enum adc_channel { ADC_CH_COUNT diff --git a/zephyr/shim/include/zephyr_host_command.h b/zephyr/shim/include/zephyr_host_command.h index ae8e1f9ee3..138c8636c7 100644 --- a/zephyr/shim/include/zephyr_host_command.h +++ b/zephyr/shim/include/zephyr_host_command.h @@ -24,11 +24,17 @@ .version_mask = _version_mask, \ } #else /* !CONFIG_PLATFORM_EC_HOSTCMD */ -#ifdef __clang__ -#define DECLARE_HOST_COMMAND(command, routine, version_mask) -#else -#define DECLARE_HOST_COMMAND(command, routine, version_mask) \ - enum ec_status (routine)(struct host_cmd_handler_args *args) \ - __attribute__((unused)) -#endif /* __clang__ */ + +/* + * Create a fake routine to call the function. The linker should + * garbage-collect it since it is behind 'if (0)' + */ +#define DECLARE_HOST_COMMAND(command, routine, version_mask) \ + int __remove_ ## command(void) \ + { \ + if (0) \ + routine(NULL); \ + return 0; \ + } + #endif /* CONFIG_PLATFORM_EC_HOSTCMD */ diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt index 0c795f6b9b..4513e32076 100644 --- a/zephyr/shim/src/CMakeLists.txt +++ b/zephyr/shim/src/CMakeLists.txt @@ -21,7 +21,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE battery.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_EEPROM cbi.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CBI_GPIO cbi.c) -zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_ESPI espi.c) +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI + espi.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FAN fan.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_FLASH_CROS flash.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_HOOKS hooks.c) @@ -53,3 +54,5 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_WATCHDOG watchdog.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201 bc12_pi3usb9201.c) zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC_PPC ppc.c) +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USB_PD_TCPM_NCT38XX + tcpc_nct38xx.c) diff --git a/zephyr/shim/src/adc.c b/zephyr/shim/src/adc.c index 4f66774466..4b2de4bd24 100644 --- a/zephyr/shim/src/adc.c +++ b/zephyr/shim/src/adc.c @@ -10,8 +10,11 @@ LOG_MODULE_REGISTER(shim_adc, LOG_LEVEL_ERR); -#define ADC_NODE DT_NODELABEL(adc0) -const struct device *adc_dev; +#if defined(CONFIG_PLATFORM_EC_ADC_CMD) && defined(CONFIG_ADC_SHELL) +#error "Define only one 'adc' console command." +#endif + +#define adc_dev DEVICE_DT_GET(DT_CHOSEN(cros_ec_adc)) #define HAS_NAMED_ADC_CHANNELS DT_NODE_EXISTS(DT_INST(0, named_adc_channels)) @@ -43,11 +46,9 @@ const struct adc_t adc_channels[] = { DT_FOREACH_CHILD( static int init_device_bindings(const struct device *device) { ARG_UNUSED(device); - adc_dev = DEVICE_DT_GET(ADC_NODE); if (!device_is_ready(adc_dev)) { - LOG_ERR("Error: device %s is not ready", adc_dev->name); - return -1; + k_oops(); } #if HAS_NAMED_ADC_CHANNELS diff --git a/zephyr/shim/src/bc12_pi3usb9201.c b/zephyr/shim/src/bc12_pi3usb9201.c index a55b6f394b..d6bf679ef8 100644 --- a/zephyr/shim/src/bc12_pi3usb9201.c +++ b/zephyr/shim/src/bc12_pi3usb9201.c @@ -30,12 +30,10 @@ const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { }; #define BC12_GPIO_ENABLE_INTERRUPT(inst) \ - do { \ - if (DT_INST_NODE_HAS_PROP(inst, irq)) { \ - gpio_enable_interrupt( \ - GPIO_SIGNAL(DT_INST_PHANDLE(inst, irq))); \ - } \ - } while (0); + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, irq), \ + (gpio_enable_interrupt( \ + GPIO_SIGNAL(DT_INST_PHANDLE(inst, irq)))) \ + ); static void bc12_enable_irqs(void) { diff --git a/zephyr/shim/src/console.c b/zephyr/shim/src/console.c index 5a465b2fd4..6b8267935a 100644 --- a/zephyr/shim/src/console.c +++ b/zephyr/shim/src/console.c @@ -109,6 +109,9 @@ int uart_shell_stop(void) return event.signal->result; } +static const struct shell_backend_config_flags shell_cfg_flags = + SHELL_DEFAULT_BACKEND_CONFIG_FLAGS; + static void shell_init_from_work(struct k_work *work) { bool log_backend = CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > 0; @@ -122,8 +125,8 @@ static void shell_init_from_work(struct k_work *work) } /* Initialize the shell and re-enable both RX and TX */ - shell_init(shell_backend_uart_get_ptr(), uart_shell_dev, false, - log_backend, level); + shell_init(shell_backend_uart_get_ptr(), uart_shell_dev, + shell_cfg_flags, log_backend, level); uart_irq_rx_enable(uart_shell_dev); uart_irq_tx_enable(uart_shell_dev); @@ -275,6 +278,8 @@ static void zephyr_print(const char *buff, size_t size) shell_fprintf(shell_zephyr, SHELL_NORMAL, "%s", buff); if (IS_ENABLED(CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE)) console_buf_notify_chars(buff, size); + if (IS_ENABLED(CONFIG_PLATFORM_EC_CONSOLE_DEBUG)) + printk("%s", buff); } } diff --git a/zephyr/shim/src/console_buffer.c b/zephyr/shim/src/console_buffer.c index 191306c80e..b768bb279f 100644 --- a/zephyr/shim/src/console_buffer.c +++ b/zephyr/shim/src/console_buffer.c @@ -52,7 +52,7 @@ void console_buf_notify_chars(const char *s, size_t len) current_snapshot_idx = next_idx(current_snapshot_idx); - console_buf[new_tail] = *s++; + console_buf[tail_idx] = *s++; tail_idx = new_tail; } k_mutex_unlock(&console_write_lock); diff --git a/zephyr/shim/src/espi.c b/zephyr/shim/src/espi.c index 12027a6399..d214f8c05c 100644 --- a/zephyr/shim/src/espi.c +++ b/zephyr/shim/src/espi.c @@ -153,8 +153,7 @@ static void espi_reset_handler(const struct device *dev, } #endif /* CONFIG_PLATFORM_EC_CHIPSET_RESET_HOOK */ -#define ESPI_NODE DT_NODELABEL(espi0) -static const struct device *espi_dev; +#define espi_dev DEVICE_DT_GET(DT_CHOSEN(cros_ec_espi)) int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level) @@ -540,11 +539,8 @@ int zephyr_shim_setup_espi(void) .max_freq = 50, }; - espi_dev = DEVICE_DT_GET(ESPI_NODE); - if (!device_is_ready(espi_dev)) { - LOG_ERR("Error: device %s is not ready", espi_dev->name); - return -1; - } + if (!device_is_ready(espi_dev)) + k_oops(); /* Configure eSPI */ if (espi_config(espi_dev, &cfg)) { @@ -561,3 +557,45 @@ int zephyr_shim_setup_espi(void) return 0; } + +bool is_acpi_command(uint32_t data) +{ + struct espi_evt_data_acpi *acpi = (struct espi_evt_data_acpi *)&data; + + return acpi->type; +} + +uint32_t get_acpi_value(uint32_t data) +{ + struct espi_evt_data_acpi *acpi = (struct espi_evt_data_acpi *)&data; + + return acpi->data; +} + +bool is_8042_ibf(uint32_t data) +{ + struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; + + return kbc->evt & HOST_KBC_EVT_IBF; +} + +bool is_8042_obe(uint32_t data) +{ + struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; + + return kbc->evt & HOST_KBC_EVT_OBE; +} + +uint32_t get_8042_type(uint32_t data) +{ + struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; + + return kbc->type; +} + +uint32_t get_8042_data(uint32_t data) +{ + struct espi_evt_data_kbc *kbc = (struct espi_evt_data_kbc *)&data; + + return kbc->data; +} diff --git a/zephyr/shim/src/flash.c b/zephyr/shim/src/flash.c index 15e32269d2..d82e860e17 100644 --- a/zephyr/shim/src/flash.c +++ b/zephyr/shim/src/flash.c @@ -15,8 +15,11 @@ LOG_MODULE_REGISTER(shim_flash, LOG_LEVEL_ERR); -#define CROS_FLASH_DEV DT_LABEL(DT_NODELABEL(fiu0)) -static const struct device *cros_flash_dev; +#if !DT_HAS_CHOSEN(cros_ec_flash) +#error "cros-ec,flash device must be chosen" +#else +#define cros_flash_dev DEVICE_DT_GET(DT_CHOSEN(cros_ec_flash)) +#endif K_MUTEX_DEFINE(flash_lock); @@ -104,11 +107,8 @@ static int flash_dev_init(const struct device *unused) { ARG_UNUSED(unused); - cros_flash_dev = device_get_binding(CROS_FLASH_DEV); - if (!cros_flash_dev) { - LOG_ERR("Fail to find %s", CROS_FLASH_DEV); - return -ENODEV; - } + if (!device_is_ready(cros_flash_dev)) + k_oops(); cros_flash_init(cros_flash_dev); return 0; diff --git a/zephyr/shim/src/gpio.c b/zephyr/shim/src/gpio.c index 4535674978..e277db2e05 100644 --- a/zephyr/shim/src/gpio.c +++ b/zephyr/shim/src/gpio.c @@ -35,7 +35,7 @@ struct gpio_config { DT_NODE_HAS_PROP(id, enum_name), \ ( \ { \ - .name = DT_LABEL(id), \ + .name = DT_NODE_FULL_NAME(id), \ .dev = DEVICE_DT_GET(DT_PHANDLE(id, gpios)), \ .pin = DT_GPIO_PIN(id, gpios), \ .init_flags = DT_GPIO_FLAGS(id, gpios), \ diff --git a/zephyr/shim/src/i2c.c b/zephyr/shim/src/i2c.c index 40d94e6462..6e0505921c 100644 --- a/zephyr/shim/src/i2c.c +++ b/zephyr/shim/src/i2c.c @@ -33,7 +33,6 @@ #define I2C_PORT_INIT(id) \ { \ - .name = DT_LABEL(id), \ .port = I2C_PORT(id), \ .flags = I2C_PORT_FLAGS(id), \ }, diff --git a/zephyr/shim/src/ioex.c b/zephyr/shim/src/ioex.c index e01f959b65..11255b0407 100644 --- a/zephyr/shim/src/ioex.c +++ b/zephyr/shim/src/ioex.c @@ -39,7 +39,17 @@ struct ioex_gpio_config { int port; }; +#ifdef CONFIG_PLATFORM_EC_IOEX_CROS_DRV #define IOEX_IS_CROS_DRV(config) (config->cros_drv_index >= 0) +#else +/* + * If no legacy cros-ec IOEX drivers are used, we need a stub + * symbol for ioex_config[]. Set the IOEX_IS_CROS_DRV to constant 0 + * which will cause all these checks to compile out. + */ +#define IOEX_IS_CROS_DRV(config) 0 +struct ioexpander_config_t ioex_config[0]; +#endif struct ioex_int_config { const enum ioex_signal signal; diff --git a/zephyr/shim/src/keyboard_raw.c b/zephyr/shim/src/keyboard_raw.c index 8de585a78f..474e1af5da 100644 --- a/zephyr/shim/src/keyboard_raw.c +++ b/zephyr/shim/src/keyboard_raw.c @@ -15,19 +15,17 @@ LOG_MODULE_REGISTER(shim_cros_kb_raw, LOG_LEVEL_ERR); -#define CROS_KB_RAW_NODE DT_NODELABEL(cros_kb_raw) -static const struct device *cros_kb_raw_dev; +BUILD_ASSERT(DT_HAS_CHOSEN(cros_ec_raw_kb), + "a cros-ec,raw-kb device must be chosen"); +#define cros_kb_raw_dev DEVICE_DT_GET(DT_CHOSEN(cros_ec_raw_kb)) /** * Initialize the raw keyboard interface. */ void keyboard_raw_init(void) { - cros_kb_raw_dev = DEVICE_DT_GET(CROS_KB_RAW_NODE); - if (!device_is_ready(cros_kb_raw_dev)) { - LOG_ERR("Error: device %s is not ready", cros_kb_raw_dev->name); - return; - } + if (!device_is_ready(cros_kb_raw_dev)) + k_oops(); LOG_INF("%s", __func__); cros_kb_raw_init(cros_kb_raw_dev); @@ -46,10 +44,7 @@ void keyboard_raw_task_start(void) */ test_mockable void keyboard_raw_drive_column(int col) { - if (cros_kb_raw_dev) - cros_kb_raw_drive_column(cros_kb_raw_dev, col); - else - LOG_ERR("%s: no cros_kb_raw device!", __func__); + cros_kb_raw_drive_column(cros_kb_raw_dev, col); } /** @@ -58,11 +53,7 @@ test_mockable void keyboard_raw_drive_column(int col) */ test_mockable int keyboard_raw_read_rows(void) { - if (cros_kb_raw_dev) - return cros_kb_raw_read_rows(cros_kb_raw_dev); - - LOG_ERR("%s: no cros_kb_raw device!", __func__); - return -EIO; + return cros_kb_raw_read_rows(cros_kb_raw_dev); } /** @@ -70,8 +61,5 @@ test_mockable int keyboard_raw_read_rows(void) */ void keyboard_raw_enable_interrupt(int enable) { - if (cros_kb_raw_dev) - cros_kb_raw_enable_interrupt(cros_kb_raw_dev, enable); - else - LOG_ERR("%s: no cros_kb_raw device!", __func__); + cros_kb_raw_enable_interrupt(cros_kb_raw_dev, enable); } diff --git a/zephyr/shim/src/motionsense_driver/icm42607-drvinfo.inc b/zephyr/shim/src/motionsense_driver/icm42607-drvinfo.inc new file mode 100644 index 0000000000..e8199eaacf --- /dev/null +++ b/zephyr/shim/src/motionsense_driver/icm42607-drvinfo.inc @@ -0,0 +1,57 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "driver/accelgyro_icm_common.h" +#include "driver/accelgyro_icm42607.h" + +/* + * CREATE_SENSOR_DATA which is defined in motionsense_sensors.c is + * the helper to create sensor driver specific data. + * + * CREATE_SENSOR_DATA gets two arguments. One is the compatible + * property value specified in device tree and the other one is the macro + * that actually creates sensor driver specific data. The macro gets + * node id and the name to be used for the sensor driver data. + */ + +/* + * Create driver data. It can be shared among the entries in + * motion_sensors array which are using the same icm42607 driver. + */ +#define CREATE_SENSOR_DATA_ICM42607(id, drvdata_name) \ + static struct icm_drv_data_t drvdata_name; + +/* + * Create driver data for each icm42607 drvinfo instance in device tree. + * (compatible = "cros-ec,drvdata-icm42607") + */ +CREATE_SENSOR_DATA(cros_ec_drvdata_icm42607, CREATE_SENSOR_DATA_ICM42607) +/* + * CREATE_MOTION_SENSOR which is defined in motionsense_sensors.c is + * the macro to create an entry in motion_sensors array. + * The macro gets value of compatible property of + * the sensor in device tree and sensor specific values like chip ID, + * type of sensor, name of driver, default min/max frequency. + * Then using the values, it creates the corresponding motion_sense_t entry + * in motion_sensors array. + */ + +/* + * Here, we call CREATE_MOTION_SENSOR to create a motion_sensor_t entry + * for each icm42607 accel instance(compatible = "cros-ec,icm42607-accel") + * in device tree. + */ +CREATE_MOTION_SENSOR(cros_ec_icm42607_accel, MOTIONSENSE_CHIP_ICM42607, \ + MOTIONSENSE_TYPE_ACCEL, icm42607_drv, \ + ICM42607_ACCEL_MIN_FREQ, ICM42607_ACCEL_MAX_FREQ) + +/* + * Here, we call CREATE_MOTION_SENSOR to create a motion_sensor_t entry + * for each icm42607 gyro instance (compatible = "cros-ec,icm42607-gyro") + * in device tree. + */ +CREATE_MOTION_SENSOR(cros_ec_icm42607_gyro, MOTIONSENSE_CHIP_ICM42607, \ + MOTIONSENSE_TYPE_GYRO, icm42607_drv, \ + ICM42607_GYRO_MIN_FREQ, ICM42607_GYRO_MAX_FREQ) diff --git a/zephyr/shim/src/motionsense_driver/lsm6dso-drvinfo.inc b/zephyr/shim/src/motionsense_driver/lsm6dso-drvinfo.inc new file mode 100644 index 0000000000..a759993ba4 --- /dev/null +++ b/zephyr/shim/src/motionsense_driver/lsm6dso-drvinfo.inc @@ -0,0 +1,57 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "driver/accelgyro_lsm6dso.h" +#include "driver/stm_mems_common.h" + +/* + * CREATE_SENSOR_DATA which is defined in motionsense_sensors.c is + * the helper to create sensor driver specific data. + * + * CREATE_SENSOR_DATA gets two arguments. One is the compatible + * property value specified in device tree and the other one is the macro + * that actually creates sensor driver specific data. The macro gets + * node id and the name to be used for the sensor driver data. + */ + +/* + * Create driver data. It can be shared among the entries in + * motion_sensors array which are using the same lsm6dso driver. + */ +#define CREATE_SENSOR_DATA_LSM6DSO(id, drvdata_name) \ + static struct stprivate_data drvdata_name; + +/* + * Create driver data for each lsm6dso drvinfo instance in device tree. + * (compatible = "cros-ec,drvdata-lsm6dso") + */ +CREATE_SENSOR_DATA(cros_ec_drvdata_lsm6dso, CREATE_SENSOR_DATA_LSM6DSO) +/* + * CREATE_MOTION_SENSOR which is defined in motionsense_sensors.c is + * the macro to create an entry in motion_sensors array. + * The macro gets value of compatible property of + * the sensor in device tree and sensor specific values like chip ID, + * type of sensor, name of driver, default min/max frequency. + * Then using the values, it creates the corresponding motion_sense_t entry + * in motion_sensors array. + */ + +/* + * Here, we call CREATE_MOTION_SENSOR to create a motion_sensor_t entry + * for each lsm6dso accel instance(compatible = "cros-ec,lsm6dso-accel") + * in device tree. + */ +CREATE_MOTION_SENSOR(cros_ec_lsm6dso_accel, MOTIONSENSE_CHIP_LSM6DSO, \ + MOTIONSENSE_TYPE_ACCEL, lsm6dso_drv, \ + LSM6DSO_ODR_MIN_VAL, LSM6DSO_ODR_MAX_VAL) + +/* + * Here, we call CREATE_MOTION_SENSOR to create a motion_sensor_t entry + * for each lsm6dso gyro instance (compatible = "cros-ec,lsm6dso-gyro") + * in device tree. + */ +CREATE_MOTION_SENSOR(cros_ec_lsm6dso_gyro, MOTIONSENSE_CHIP_LSM6DSO, \ + MOTIONSENSE_TYPE_GYRO, lsm6dso_drv, \ + LSM6DSO_ODR_MIN_VAL, LSM6DSO_ODR_MAX_VAL) diff --git a/zephyr/shim/src/motionsense_driver/sensor_drv_list.inc b/zephyr/shim/src/motionsense_driver/sensor_drv_list.inc index 0062dccccd..4138074e95 100644 --- a/zephyr/shim/src/motionsense_driver/sensor_drv_list.inc +++ b/zephyr/shim/src/motionsense_driver/sensor_drv_list.inc @@ -40,3 +40,9 @@ #ifdef CONFIG_PLATFORM_EC_ACCELGYRO_ICM426XX #include "icm426xx-drvinfo.inc" #endif +#ifdef CONFIG_PLATFORM_EC_ACCELGYRO_ICM42607 +#include "icm42607-drvinfo.inc" +#endif +#ifdef CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO +#include "lsm6dso-drvinfo.inc" +#endif diff --git a/zephyr/shim/src/motionsense_sensors.c b/zephyr/shim/src/motionsense_sensors.c index b884f890b2..7ddc22968e 100644 --- a/zephyr/shim/src/motionsense_sensors.c +++ b/zephyr/shim/src/motionsense_sensors.c @@ -8,6 +8,7 @@ #include "accelgyro.h" #include "hooks.h" #include "drivers/cros_cbi.h" +#include "motionsense_sensors.h" LOG_MODULE_REGISTER(shim_cros_motionsense_sensors); @@ -390,75 +391,53 @@ DECLARE_HOOK(HOOK_INIT, sensor_enable_irqs, HOOK_PRIO_DEFAULT); #endif /* Handle the alternative motion sensors */ -#define REPLACE_ALT_MOTION_SENSOR(new_id, old_id) \ - motion_sensors[SENSOR_ID(old_id)] = \ - motion_sensors_alt[SENSOR_ID(new_id)]; - -#define CHECK_AND_REPLACE_ALT_MOTION_SENSOR(id) \ - do { \ - if (cros_cbi_ssfc_check_match( \ - dev, CBI_SSFC_VALUE_ID(DT_PHANDLE( \ - id, alternate_indicator)))) { \ - REPLACE_ALT_MOTION_SENSOR( \ - id, DT_PHANDLE(id, alternate_for)) \ - } \ - } while (0); - -#define ALT_MOTION_SENSOR_INIT_ID(id) \ - COND_CODE_1(UTIL_AND(DT_NODE_HAS_PROP(id, alternate_for), \ - DT_NODE_HAS_PROP(id, alternate_indicator)), \ - (CHECK_AND_REPLACE_ALT_MOTION_SENSOR(id)), ()) - -#define PROBE_SENSOR(id) \ -{ \ - int res; \ - \ - LOG_INF("Probing \"%s\" chip %d type %d loc %d", \ - motion_sensors_alt[SENSOR_ID(id)].name, \ - motion_sensors_alt[SENSOR_ID(id)].chip, \ - motion_sensors_alt[SENSOR_ID(id)].type, \ - motion_sensors_alt[SENSOR_ID(id)].location); \ - \ - __ASSERT(motion_sensors_alt[SENSOR_ID(id)].drv->probe != NULL, \ - "No probing function for alt sensor: %d", SENSOR_ID(id)); \ - res = motion_sensors_alt[SENSOR_ID(id)].drv->probe( \ - &motion_sensors_alt[SENSOR_ID(id)]); \ - LOG_INF("%sfound\n", (res != EC_SUCCESS ? "not " : "")); \ - \ - if (res == EC_SUCCESS) { \ - REPLACE_ALT_MOTION_SENSOR(id, \ - DT_PHANDLE(id, alternate_for)); \ - } \ -} - -#define PROBE_IF_NEEDED(id) \ - COND_CODE_1(DT_PROP(id, runtime_probe), \ - (PROBE_SENSOR(id)), \ - ()) +#define CHECK_SSFC_AND_ENABLE_ALT_SENSOR(id, cbi_dev) \ + do { \ + if (cros_cbi_ssfc_check_match(cbi_dev, CBI_SSFC_VALUE_ID( \ + DT_PHANDLE(id, alternate_ssfc_indicator)))) { \ + LOG_INF("Replacing \"%s\" for \"%s\" based on SSFC", \ + motion_sensors[SENSOR_ID(DT_PHANDLE(id, \ + alternate_for))].name, \ + motion_sensors_alt[SENSOR_ID(id)].name); \ + ENABLE_ALT_MOTION_SENSOR(id); \ + } \ + } while (0) + +#define ALT_SENSOR_CHECK_SSFC_ID(id, cbi_dev) \ + COND_CODE_1(UTIL_AND(DT_NODE_HAS_PROP(id, alternate_for), \ + DT_NODE_HAS_PROP(id, alternate_ssfc_indicator)), \ + (CHECK_SSFC_AND_ENABLE_ALT_SENSOR(id, cbi_dev);), ()) #if DT_NODE_EXISTS(SENSOR_ALT_NODE) -#ifndef CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL -static void motion_sense_probe_sensors(void) -#else -void motion_sense_probe_sensors(void) -#endif + +int motion_sense_probe(enum sensor_alt_id alt_idx) { - DT_FOREACH_CHILD(SENSOR_ALT_NODE, PROBE_IF_NEEDED); + int res; + + LOG_INF("Probing \"%s\" chip %d type %d loc %d", + motion_sensors_alt[alt_idx].name, + motion_sensors_alt[alt_idx].chip, + motion_sensors_alt[alt_idx].type, + motion_sensors_alt[alt_idx].location); + + __ASSERT(motion_sensors_alt[alt_idx].drv->probe != NULL, + "No probing function for alt sensor: %d", alt_idx); + res = motion_sensors_alt[alt_idx].drv->probe( + &motion_sensors_alt[alt_idx]); + LOG_INF("%sfound\n", (res != EC_SUCCESS ? "not " : "")); + + return res; } -static void motion_sensors_init_alt(void) +void motion_sensors_check_ssfc(void) { - const struct device *dev = device_get_binding("cros_cbi"); + const struct device *dev = device_get_binding(CROS_CBI_LABEL); if (dev != NULL) { - DT_FOREACH_CHILD(SENSOR_ALT_NODE, ALT_MOTION_SENSOR_INIT_ID) + DT_FOREACH_CHILD_VARGS(SENSOR_ALT_NODE, + ALT_SENSOR_CHECK_SSFC_ID, dev) } - - if (!IS_ENABLED( - CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL)) - motion_sense_probe_sensors(); } -DECLARE_HOOK(HOOK_INIT, motion_sensors_init_alt, HOOK_PRIO_INIT_I2C + 1); #endif /* DT_NODE_EXISTS(SENSOR_ALT_NODE) */ #define DEF_MOTION_ISR_NAME_ENUM(id) \ diff --git a/zephyr/shim/src/pwm.c b/zephyr/shim/src/pwm.c index 39fd72007e..9aa347fc13 100644 --- a/zephyr/shim/src/pwm.c +++ b/zephyr/shim/src/pwm.c @@ -25,7 +25,7 @@ LOG_MODULE_REGISTER(pwm_shim, LOG_LEVEL_ERR); * This macro is called from within DT_FOREACH_CHILD */ #define INIT_DEV_BINDING(id) { \ - pwm_configs[PWM_CHANNEL(id)].name = DT_LABEL(id); \ + pwm_configs[PWM_CHANNEL(id)].name = DT_NODE_FULL_NAME(id); \ pwm_configs[PWM_CHANNEL(id)].dev = DEVICE_DT_GET( \ DT_PHANDLE(id, pwms)); \ pwm_configs[PWM_CHANNEL(id)].pin = DT_PWMS_CHANNEL(id); \ diff --git a/zephyr/shim/src/system.c b/zephyr/shim/src/system.c index 8db8ba437a..802da6c838 100644 --- a/zephyr/shim/src/system.c +++ b/zephyr/shim/src/system.c @@ -8,7 +8,6 @@ #include <drivers/cros_system.h> #include <logging/log.h> -#include "bbram.h" #include "common.h" #include "console.h" #include "cros_version.h" @@ -31,7 +30,9 @@ LOG_MODULE_REGISTER(shim_system, LOG_LEVEL_ERR); -STATIC_IF_NOT(CONFIG_ZTEST) const struct device *bbram_dev; +static const struct device *const bbram_dev = + COND_CODE_1(DT_HAS_CHOSEN(cros_ec_bbram), + DEVICE_DT_GET(DT_CHOSEN(cros_ec_bbram)), NULL); static const struct device *sys_dev; /* Map idx to a bbram offset/size, or return -1 on invalid idx */ @@ -326,13 +327,10 @@ static int system_preinitialize(const struct device *unused) { ARG_UNUSED(unused); -#if DT_NODE_EXISTS(DT_NODELABEL(bbram)) - bbram_dev = DEVICE_DT_GET(DT_NODELABEL(bbram)); - if (!device_is_ready(bbram_dev)) { + if (bbram_dev && !device_is_ready(bbram_dev)) { LOG_ERR("Error: device %s is not ready", bbram_dev->name); return -1; } -#endif sys_dev = device_get_binding("CROS_SYSTEM"); if (!sys_dev) { diff --git a/zephyr/shim/src/tasks.c b/zephyr/shim/src/tasks.c index 9c6f655a5c..851a179f3e 100644 --- a/zephyr/shim/src/tasks.c +++ b/zephyr/shim/src/tasks.c @@ -55,7 +55,7 @@ struct task_ctx_dyn { /** A wait-able event that is raised when a new task event is posted */ struct k_poll_signal new_event; /** The current platform/ec events set for this task/thread */ - uint32_t event_mask; + atomic_t event_mask; /** * The timer associated with this task, which can be set using * timer_arm(). @@ -117,7 +117,7 @@ __test_only k_tid_t task_get_zephyr_tid(size_t cros_tid) return shimmed_tasks_dyn[cros_tid].zephyr_tid; } -uint32_t *task_get_event_bitmap(task_id_t cros_task_id) +atomic_t *task_get_event_bitmap(task_id_t cros_task_id) { struct task_ctx_dyn *const ctx = &shimmed_tasks_dyn[cros_task_id]; diff --git a/zephyr/shim/src/tcpc_nct38xx.c b/zephyr/shim/src/tcpc_nct38xx.c new file mode 100644 index 0000000000..d18e4ccbbe --- /dev/null +++ b/zephyr/shim/src/tcpc_nct38xx.c @@ -0,0 +1,31 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <device.h> +#include <devicetree.h> + +#include "config.h" +#include "usbc/tcpc_nct38xx.h" + +#define TCPC_PORT(id) DT_REG_ADDR(DT_PARENT(id)) + +#define GPIO_DEV_WITH_COMMA(id) DEVICE_DT_GET(DT_PHANDLE(id, gpio_dev)), + +#define GPIO_DEV_BINDING(id) \ + COND_CODE_1(DT_NODE_HAS_PROP(id, gpio_dev), \ + ([TCPC_PORT(id)] = GPIO_DEV_WITH_COMMA(id)), ()) + +/* NCT38XX GPIO device pool for binding the TCPC port and NCT38XX GPIO device */ +static const struct device + *nct38xx_gpio_devices[CONFIG_PLATFORM_EC_USB_PD_PORT_MAX_COUNT] = { + DT_FOREACH_STATUS_OKAY(nuvoton_nct38xx, GPIO_DEV_BINDING) + }; + +const struct device *nct38xx_get_gpio_device_from_port(const int port) +{ + if (port < 0 || port >= CONFIG_PLATFORM_EC_USB_PD_PORT_MAX_COUNT) + return NULL; + return nct38xx_gpio_devices[port]; +} diff --git a/zephyr/shim/src/temp_sensors.c b/zephyr/shim/src/temp_sensors.c index 4d8be4fa42..a8533202fa 100644 --- a/zephyr/shim/src/temp_sensors.c +++ b/zephyr/shim/src/temp_sensors.c @@ -3,10 +3,11 @@ * found in the LICENSE file. */ +#include "adc.h" #include "temp_sensor.h" #include "temp_sensor/temp_sensor.h" -#include "adc.h" #include "temp_sensor/thermistor.h" +#include "temp_sensor/tmp112.h" #if DT_NODE_EXISTS(DT_PATH(named_temp_sensors)) static int thermistor_get_temp(const struct temp_sensor_t *sensor, @@ -46,7 +47,33 @@ static int thermistor_get_temp(const struct temp_sensor_t *sensor, DT_FOREACH_STATUS_OKAY(cros_ec_thermistor, DEFINE_THERMISTOR_DATA) +#if DT_HAS_COMPAT_STATUS_OKAY(cros_ec_temp_sensor_tmp112) +static int tmp112_get_temp(const struct temp_sensor_t *sensor, int *temp_ptr) +{ + return tmp112_get_val_k(sensor->idx, temp_ptr); +} +#endif /* cros_ec_temp_sensor_tmp112 */ + +#define DEFINE_TMP112_DATA(node_id) \ + [ZSHIM_TMP112_SENSOR_ID(node_id)] = { \ + .i2c_port = I2C_PORT(DT_PHANDLE(node_id, port)), \ + .i2c_addr_flags = DT_STRING_TOKEN(node_id, i2c_addr_flags), \ + }, + +#define TEMP_TMP112(node_id) \ + [ZSHIM_TEMP_SENSOR_ID(node_id)] = { \ + .name = DT_LABEL(node_id), \ + .read = tmp112_get_temp, \ + .idx = ZSHIM_TMP112_SENSOR_ID(node_id), \ + .type = TEMP_SENSOR_TYPE_BOARD, \ + }, + +const struct tmp112_sensor_t tmp112_sensors[TMP112_COUNT] = { + DT_FOREACH_STATUS_OKAY(cros_ec_temp_sensor_tmp112, DEFINE_TMP112_DATA) +}; + const struct temp_sensor_t temp_sensors[] = { - DT_FOREACH_STATUS_OKAY(cros_ec_temp_sensor, TEMP_THERMISTOR) + DT_FOREACH_STATUS_OKAY(cros_ec_temp_sensor_thermistor, TEMP_THERMISTOR) + DT_FOREACH_STATUS_OKAY(cros_ec_temp_sensor_tmp112, TEMP_TMP112) }; #endif /* named_temp_sensors */ diff --git a/zephyr/shim/src/watchdog.c b/zephyr/shim/src/watchdog.c index 4c78ac9b0f..bf5568c596 100644 --- a/zephyr/shim/src/watchdog.c +++ b/zephyr/shim/src/watchdog.c @@ -14,6 +14,8 @@ LOG_MODULE_REGISTER(watchdog_shim, LOG_LEVEL_ERR); +#define wdt DEVICE_DT_GET(DT_CHOSEN(cros_ec_watchdog)) + static void wdt_warning_handler(const struct device *wdt_dev, int channel_id) { /* TODO(b/176523207): watchdog warning message */ @@ -23,10 +25,8 @@ static void wdt_warning_handler(const struct device *wdt_dev, int channel_id) int watchdog_init(void) { int err; - const struct device *wdt; struct wdt_timeout_cfg wdt_config; - wdt = DEVICE_DT_GET(DT_NODELABEL(twd0)); if (!device_is_ready(wdt)) { LOG_ERR("Error: device %s is not ready", wdt->name); return -1; @@ -67,9 +67,6 @@ int watchdog_init(void) void watchdog_reload(void) { - const struct device *wdt; - - wdt = DEVICE_DT_GET(DT_NODELABEL(twd0)); if (!device_is_ready(wdt)) LOG_ERR("Error: device %s is not ready", wdt->name); diff --git a/zephyr/shim/src/ztest_system.c b/zephyr/shim/src/ztest_system.c index 580368d7f9..7da949dd84 100644 --- a/zephyr/shim/src/ztest_system.c +++ b/zephyr/shim/src/ztest_system.c @@ -7,7 +7,7 @@ #include "cros_version.h" /* Ongoing actions preventing going into deep-sleep mode. */ -uint32_t sleep_mask; +atomic_t sleep_mask; void system_common_pre_init(void) { diff --git a/zephyr/test/drivers/include/gpio_map.h b/zephyr/test/drivers/include/gpio_map.h index 5253b0155a..1255348a61 100644 --- a/zephyr/test/drivers/include/gpio_map.h +++ b/zephyr/test/drivers/include/gpio_map.h @@ -17,13 +17,17 @@ * Note we only need to create aliases for GPIOs that are referenced in common * platform/ec code. */ -#define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_PG_EC_DSW_PWROK +#define GPIO_TEMP_SENSOR_POWER GPIO_PG_EC_DSW_PWROK -#define EC_CROS_GPIO_INTERRUPTS \ - GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \ - GPIO_INT(GPIO_USB_C0_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ - tcpc_alert_event) \ - GPIO_INT(GPIO_USB_C1_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ - tcpc_alert_event) +#define EC_CROS_GPIO_INTERRUPTS \ + GPIO_INT(GPIO_AC_PRESENT, GPIO_INT_EDGE_BOTH, extpower_interrupt) \ + GPIO_INT(GPIO_USB_C0_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + tcpc_alert_event) \ + GPIO_INT(GPIO_USB_C1_TCPC_INT_ODL, GPIO_INT_EDGE_FALLING, \ + tcpc_alert_event) \ + GPIO_INT(GPIO_USB_C0_PPC_INT_ODL, GPIO_INT_EDGE_FALLING, ppc_alert) \ + GPIO_INT(GPIO_USB_C1_PPC_INT_ODL, GPIO_INT_EDGE_FALLING, ppc_alert) \ + GPIO_INT(GPIO_SWITCHCAP_PG_INT_L, GPIO_INT_EDGE_FALLING, \ + ln9310_interrupt) \ #endif /* __ZEPHYR_GPIO_MAP_H */ diff --git a/zephyr/test/drivers/include/stubs.h b/zephyr/test/drivers/include/stubs.h index 448d6c883b..af32a988c6 100644 --- a/zephyr/test/drivers/include/stubs.h +++ b/zephyr/test/drivers/include/stubs.h @@ -6,6 +6,7 @@ #ifndef __TEST_DRIVERS_STUBS_H #define __TEST_DRIVERS_STUBS_H +#include "fff.h" #include "power.h" enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; @@ -13,7 +14,16 @@ enum usbc_port { USBC_PORT_C0 = 0, USBC_PORT_C1, USBC_PORT_COUNT }; /* Structure used by usb_mux test. It is part of usb_muxes chain. */ extern struct usb_mux usbc1_virtual_usb_mux; -void set_mock_power_state(enum power_state state); +/** + * @brief Set state which should be returned by power_handle_state() and wake + * chipset task to immediately change state + * + * @param force If true @p state will be used as return for power_handle_state() + * and will wake up chipset task. If false argument of + * power_handle_state() will be used as return value + * @param state Power state to use when @p force is true + */ +void force_power_state(bool force, enum power_state state); /** * @brief Set product ID that should be returned by board_get_ps8xxx_product_id @@ -22,4 +32,7 @@ void set_mock_power_state(enum power_state state); */ void board_set_ps8xxx_product_id(uint16_t product_id); +/* Declare fake function to allow tests to examine calls to this function */ +DECLARE_FAKE_VOID_FUNC(system_hibernate, uint32_t, uint32_t); + #endif /* __TEST_DRIVERS_STUBS_H */ diff --git a/zephyr/test/drivers/include/test_mocks.h b/zephyr/test/drivers/include/test_mocks.h index fe63eea0d3..3630df083f 100644 --- a/zephyr/test/drivers/include/test_mocks.h +++ b/zephyr/test/drivers/include/test_mocks.h @@ -53,7 +53,7 @@ #EXPECTED_REG ") but wrote to reg 0x%02x", \ (CALL_NUM), (EXPECTED_REG), \ FAKE##_fake.arg1_history[(CALL_NUM)]); \ - if (EXPECTED_VAL != MOCK_IGNORE_VALUE) { \ + if ((EXPECTED_VAL) != MOCK_IGNORE_VALUE) { \ zassert_equal( \ FAKE##_fake.arg2_history[(CALL_NUM)], \ (EXPECTED_VAL), \ @@ -70,6 +70,30 @@ */ #define MOCK_IGNORE_VALUE (-1) +/** + * @brief Helper macro for asserting that a certain register read occurred. + * Used when wrapping an I2C emulator mock read function in FFF. Prints + * useful error messages when the assertion fails. + * @param FAKE - name of the fake whose arg history to insepct. Do not include + * '_fake' at the end. + * @param CALL_NUM - Index in to the call history that this write should have + * occurred at. Zero based. + * @param EXPECTED_REG - The register address that was supposed to be read + * from. + */ +#define MOCK_ASSERT_I2C_READ(FAKE, CALL_NUM, EXPECTED_REG) \ + do { \ + zassert_true((CALL_NUM) < FAKE##_fake.call_count, \ + "Call #%d did not occur (%d I2C reads total)", \ + (CALL_NUM), FAKE##_fake.call_count); \ + zassert_equal( \ + FAKE##_fake.arg1_history[(CALL_NUM)], (EXPECTED_REG), \ + "Expected I2C read #%d from register 0x%02x (" \ + #EXPECTED_REG ") but read from reg 0x%02x", \ + (CALL_NUM), (EXPECTED_REG), \ + FAKE##_fake.arg1_history[(CALL_NUM)]); \ + } while (0) + /* * Mock declarations */ diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts index fc0ddc0a6e..f45210d621 100644 --- a/zephyr/test/drivers/overlay.dts +++ b/zephyr/test/drivers/overlay.dts @@ -8,6 +8,11 @@ #include <freq.h> / { + chosen { + cros-ec,adc = &adc0; + cros-ec,espi = &espi0; + }; + aliases { bmi260-int = &ms_bmi260_accel; bmi160-int = &ms_bmi160_accel; @@ -20,12 +25,10 @@ ec_batt_pres_odl { gpios = <&gpio0 1 GPIO_INPUT>; enum-name = "GPIO_BATT_PRES_ODL"; - label = "EC_BATT_PRES_ODL"; }; acok_od { gpios = <&gpio0 2 GPIO_INPUT>; enum-name = "GPIO_AC_PRESENT"; - label = "ACOK_OD"; }; /* In test WP is output because CBI use it, but it is also * input, because test_all_tags set it to enable write @@ -35,54 +38,56 @@ #gpio-cells = <0>; gpios = <&gpio0 3 (GPIO_INPUT | GPIO_OUTPUT)>; enum-name = "GPIO_WP_L"; - label = "WP_L"; }; pg_ec_dsw_pwrok { gpios = <&gpio0 4 GPIO_INPUT>; enum-name = "GPIO_PG_EC_DSW_PWROK"; - label = "PG_EC_DSW_PWROK"; }; ec_pch_wake_odl { gpios = <&gpio0 5 GPIO_OUT_HIGH>; enum-name = "GPIO_EC_PCH_WAKE_ODL"; - label = "EC_PCH_WAKE_ODL"; }; /* Setup USB C1 pin as output to check their state in test */ usb_c1_ls_en { - gpios = <&gpio0 6 (GPIO_INPUT | GPIO_PULL_UP | + gpios = <&gpio0 6 (GPIO_INPUT_PULL_UP | GPIO_OUTPUT)>; enum-name = "GPIO_USB_C1_LS_EN"; - label = "USB_C1_LS_EN"; }; usb_c1_rt_rst_odl { gpios = <&gpio0 7 (GPIO_OUTPUT | GPIO_INPUT)>; enum-name = "GPIO_USB_C1_RT_RST_ODL"; - label = "USB_C1_RT_RST_ODL"; }; gpio_usb_c1_frs_en: usb_c1_frs_en { gpios = <&gpio0 8 (GPIO_OUT_LOW)>; enum-name = "GPIO_USB_C1_FRS_EN"; - label = "USB_C1_FRS_EN"; }; usb_c0_tcpc_int_odl: usb_c0_tcpc_int_odl { gpios = <&gpio0 9 GPIO_INPUT>; enum-name = "GPIO_USB_C0_TCPC_INT_ODL"; - label = "USB_C0_TCPC_INT_ODL"; }; usb_c1_tcpc_int_odl: usb_c1_tcpc_int_odl { gpios = <&gpio0 10 GPIO_INPUT>; enum-name = "GPIO_USB_C1_TCPC_INT_ODL"; - label = "USB_C1_TCPC_INT_ODL"; }; usb_c0_tcpc_rst_l { gpios = <&gpio0 11 (GPIO_OUT_HIGH | GPIO_INPUT)>; enum-name = "GPIO_USB_C0_TCPC_RST_L"; - label = "USB_C0_TCPC_RST_L"; }; usb_c1_tcpc_rst_l { gpios = <&gpio0 12 (GPIO_OUT_HIGH | GPIO_INPUT)>; enum-name = "GPIO_USB_C1_TCPC_RST_L"; - label = "USB_C1_TCPC_RST_L"; + }; + gpio_usb_c1_ppc_int: usb_c1_ppc_int { + gpios = <&gpio0 13 GPIO_INPUT>; + enum-name = "GPIO_USB_C1_PPC_INT_ODL"; + }; + gpio_usb_c0_ppc_int: usb_c0_ppc_int { + gpios = <&gpio0 14 GPIO_INPUT>; + enum-name = "GPIO_USB_C0_PPC_INT_ODL"; + }; + gpio_switchcap_pg_int_l: switchcap_pg_int_l { + gpios = <&gpio0 15 GPIO_INPUT>; + enum-name = "GPIO_SWITCHCAP_PG_INT_L"; }; }; named-i2c-ports { @@ -91,42 +96,34 @@ usb-c0 { i2c-port = <&i2c0>; enum-name = "I2C_PORT_USB_C0"; - label = "USB_C0"; }; usb-c1 { i2c-port = <&i2c1>; enum-name = "I2C_PORT_USB_C1"; - label = "USB_C1"; }; battery { i2c-port = <&i2c0>; enum-name = "I2C_PORT_BATTERY"; - label = "BATTERY"; }; power { i2c-port = <&i2c0>; enum-name = "I2C_PORT_POWER"; - label = "POWER"; }; charger { i2c-port = <&i2c0>; enum-name = "I2C_PORT_CHARGER"; - label = "CHARGER"; }; eeprom { i2c-port = <&i2c0>; enum-name = "I2C_PORT_EEPROM"; - label = "EEPROM"; }; i2c_accel: accel { i2c-port = <&i2c0>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL"; }; i2c_sensor: sensor { i2c-port = <&i2c1>; enum-name = "I2C_PORT_SENSOR"; - label = "SENSOR"; }; }; @@ -157,6 +154,35 @@ }; }; + cbi-fw-config { + compatible = "named-cbi-fw-config"; + field-1 { + enum-name = "FW_CONFIG_FIELD_1"; + start = <0>; + size = <2>; + val-0 { + compatible = "named-cbi-fw-config-value"; + enum-name = "FW_FIELD_1_A"; + value = <0>; + }; + val-1 { + compatible = "named-cbi-fw-config-value"; + enum-name = "FW_FIELD_1_B"; + value = <1>; + }; + }; + field-2 { + enum-name = "FW_CONFIG_FIELD_2"; + start = <5>; + size = <1>; + val-1 { + compatible = "named-cbi-fw-config-value"; + enum-name = "FW_FIELD_2_X"; + value = <1>; + }; + }; + }; + adc0: adc { compatible = "zephyr,adc-emul"; nchannels = <4>; @@ -195,7 +221,7 @@ charger { thermistor = <&thermistor_3V3_13K7_47K_4050B>; status = "okay"; - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; label = "TEMP_SENSOR_CHARGER"; enum-name = "TEMP_SENSOR_CHARGER"; temp_fan_off = <40>; @@ -208,7 +234,7 @@ pp3300-regulator { thermistor = <&thermistor_3V3_30K9_47K_4050B>; status = "okay"; - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; label = "TEMP_SENSOR_PP3300_REGULATOR"; enum-name = "TEMP_SENSOR_PP3300_REGULATOR"; temp_fan_off = <40>; @@ -221,7 +247,7 @@ ddr-soc { thermistor = <&thermistor_3V3_51K1_47K_4050B>; status = "okay"; - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; label = "TEMP_SENSOR_DDR_SOC"; enum-name = "TEMP_SENSOR_DDR_SOC"; temp_fan_off = <35>; @@ -234,7 +260,7 @@ fan { thermistor = <&thermistor_3V0_22K6_47K_4050B>; status = "okay"; - compatible = "cros-ec,temp-sensor"; + compatible = "cros-ec,temp-sensor-thermistor"; label = "TEMP_SENSOR_FAN"; enum-name = "TEMP_SENSOR_FAN"; temp_fan_off = <35>; @@ -500,6 +526,7 @@ reg = <0x41>; label = "SYV682X_EMUL"; frs_en_gpio = <&gpio_usb_c1_frs_en>; + alert_gpio = <&gpio_usb_c1_ppc_int>; }; usb_c1_bb_retimer_emul: bbretimer@42 { @@ -539,7 +566,7 @@ }; &gpio0 { - ngpios = <13>; + ngpios = <16>; }; &i2c0 { @@ -582,6 +609,7 @@ compatible = "cros,sn5s330-emul"; reg = <0x40>; label = "SN5S330_EMUL"; + int_gpio = <&gpio_usb_c0_ppc_int>; }; accel_bmi260: bmi260@68 { @@ -600,6 +628,7 @@ status = "okay"; reg = <0x80>; label = "LN9310"; + pg_int_gpio = <&gpio_switchcap_pg_int_l>; }; lis2dw12_emul: lis2dw12@19 { @@ -621,6 +650,7 @@ status = "okay"; reg = <0x9>; label = "ISL923X_EMUL"; + battery = <&battery>; }; tcpci_emul: tcpci_emul@82 { diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf index ed41ea5357..1d79c2a840 100644 --- a/zephyr/test/drivers/prj.conf +++ b/zephyr/test/drivers/prj.conf @@ -18,6 +18,7 @@ CONFIG_EXCEPTION_STACK_TRACE=y CONFIG_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_OPTIMIZATIONS=y +CONFIG_PLATFORM_EC_CONSOLE_DEBUG=y CONFIG_PLATFORM_EC=y CONFIG_CROS_EC=y @@ -40,6 +41,10 @@ CONFIG_EMUL_BMI=y CONFIG_EMUL_TCS3400=y CONFIG_EMUL_BB_RETIMER=y CONFIG_EMUL_PS8XXX=y +CONFIG_EMUL_TCPCI_PARTNER_SRC=y +CONFIG_EMUL_TCPCI_PARTNER_SNK=y +CONFIG_PLATFORM_EC_CHARGE_MANAGER=y +CONFIG_PLATFORM_EC_CHARGE_RAMP_SW=y CONFIG_PLATFORM_EC_POWERSEQ=y @@ -71,6 +76,7 @@ CONFIG_PLATFORM_EC_USBC_PPC_SN5S330=y CONFIG_PLATFORM_EC_CBI_EEPROM=y CONFIG_PLATFORM_EC_ADC=y CONFIG_PLATFORM_EC_TEMP_SENSOR=y +CONFIG_PLATFORM_EC_TEMP_SENSOR_POWER=y CONFIG_PLATFORM_EC_THERMISTOR=y CONFIG_PLATFORM_EC_SWITCHCAP_LN9310=y CONFIG_PLATFORM_EC_ACCEL_BMA255=y @@ -93,7 +99,6 @@ CONFIG_PLATFORM_EC_USB_PD_TCPM_MULTI_PS8XXX=y CONFIG_ESPI=y CONFIG_ESPI_EMUL=y CONFIG_EMUL_ESPI_HOST=y -CONFIG_PLATFORM_EC_ESPI=y CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION=y CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE=y CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD=y diff --git a/zephyr/test/drivers/src/bb_retimer.c b/zephyr/test/drivers/src/bb_retimer.c index 39af8da2c3..02a712aacb 100644 --- a/zephyr/test/drivers/src/bb_retimer.c +++ b/zephyr/test/drivers/src/bb_retimer.c @@ -441,13 +441,7 @@ static void test_bb_init(void) emul = bb_emul_get(BB_RETIMER_ORD); /* Set AP to normal state and wait for chipset task */ - set_mock_power_state(POWER_S0); - /* - * TODO(b/201420132) - setting power state requires to wake up - * TASK_ID_CHIPSET Sleep is required to run chipset task before - * continuing with test - */ - k_msleep(1); + power_set_state(POWER_S0); /* Setup emulator fail on read */ i2c_common_emul_set_read_fail_reg(emul, BB_RETIMER_REG_VENDOR_ID); @@ -508,13 +502,7 @@ static void test_bb_init(void) NULL); /* Set AP to off state and wait for chipset task */ - set_mock_power_state(POWER_G3); - /* - * TODO(b/201420132) - setting power state requires to wake up - * TASK_ID_CHIPSET Sleep is required to run chipset task before - * continuing with test - */ - k_msleep(1); + power_set_state(POWER_G3); /* With AP off, init should fail and pins should be unset */ zassert_equal(EC_ERROR_NOT_POWERED, diff --git a/zephyr/test/drivers/src/bmi160.c b/zephyr/test/drivers/src/bmi160.c index 080ec2ab96..736077b523 100644 --- a/zephyr/test/drivers/src/bmi160.c +++ b/zephyr/test/drivers/src/bmi160.c @@ -1997,7 +1997,7 @@ static void test_bmi_interrupt_handler(void) * interrupt, and ensure the flag is set. */ - uint32_t *mask; + atomic_t *mask; mask = task_get_event_bitmap(TASK_ID_MOTIONSENSE); zassert_true(mask != NULL, diff --git a/zephyr/test/drivers/src/bmi260.c b/zephyr/test/drivers/src/bmi260.c index fb00288367..fb33a4e888 100644 --- a/zephyr/test/drivers/src/bmi260.c +++ b/zephyr/test/drivers/src/bmi260.c @@ -1913,7 +1913,7 @@ void test_interrupt_handler(void) * interrupt, and ensure the flag is set. */ - uint32_t *mask; + atomic_t *mask; mask = task_get_event_bitmap(TASK_ID_MOTIONSENSE); zassert_true(mask != NULL, diff --git a/zephyr/test/drivers/src/cros_cbi.c b/zephyr/test/drivers/src/cros_cbi.c index ee3666f3f0..5209bb2b7f 100644 --- a/zephyr/test/drivers/src/cros_cbi.c +++ b/zephyr/test/drivers/src/cros_cbi.c @@ -39,10 +39,32 @@ static void test_fail_check_match(void) "Expected cbi ssfc to never match CBI_SSFC_VALUE_COUNT"); } +static void test_fw_config(void) +{ + const struct device *dev = device_get_binding(CROS_CBI_LABEL); + uint32_t value; + int ret; + + zassert_not_null(dev, NULL); + + ret = cros_cbi_get_fw_config(dev, FW_CONFIG_FIELD_1, &value); + zassert_true(ret == 0, + "Expected no error return from cros_cbi_get_fw_config"); + zassert_true(value == FW_FIELD_1_A, + "Expected field value to match FW_FIELD_1_A"); + + ret = cros_cbi_get_fw_config(dev, FW_CONFIG_FIELD_2, &value); + zassert_true(ret == 0, + "Expected no error return from cros_cbi_get_fw_config"); + zassert_false(value == FW_FIELD_2_X, + "Expected field value to not match FW_FIELD_2_X"); +} + void test_suite_cros_cbi(void) { ztest_test_suite(cros_cbi, ztest_unit_test(test_check_match), - ztest_unit_test(test_fail_check_match)); + ztest_unit_test(test_fail_check_match), + ztest_unit_test(test_fw_config)); ztest_run_test_suite(cros_cbi); } diff --git a/zephyr/test/drivers/src/espi.c b/zephyr/test/drivers/src/espi.c index c852f1b771..81cbac30da 100644 --- a/zephyr/test/drivers/src/espi.c +++ b/zephyr/test/drivers/src/espi.c @@ -13,7 +13,8 @@ static void test_host_command_get_protocol_info(void) { struct ec_response_get_protocol_info response; struct host_cmd_handler_args args = - BUILD_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, 0, response); + BUILD_HOST_COMMAND_RESPONSE(EC_CMD_GET_PROTOCOL_INFO, 0, + response); zassert_ok(host_command_process(&args), NULL); zassert_ok(args.result, NULL); diff --git a/zephyr/test/drivers/src/integration_usb.c b/zephyr/test/drivers/src/integration_usb.c new file mode 100644 index 0000000000..c61a706002 --- /dev/null +++ b/zephyr/test/drivers/src/integration_usb.c @@ -0,0 +1,187 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr.h> +#include <ztest.h> +#include <drivers/gpio/gpio_emul.h> + +#include "battery_smart.h" +#include "ec_commands.h" +#include "ec_tasks.h" +#include "emul/emul_smart_battery.h" +#include "emul/tcpc/emul_tcpci.h" +#include "emul/tcpc/emul_tcpci_partner_src.h" +#include "host_command.h" +#include "tcpm/tcpci.h" + +#define TCPCI_EMUL_LABEL DT_NODELABEL(tcpci_emul) +#define BATTERY_ORD DT_DEP_ORD(DT_NODELABEL(battery)) + +#define GPIO_AC_OK_PATH DT_PATH(named_gpios, acok_od) +#define GPIO_AC_OK_PIN DT_GPIO_PIN(GPIO_AC_OK_PATH, gpios) + +static void init_tcpm(void) +{ + const struct emul *tcpci_emul = + emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL)); + struct i2c_emul *i2c_emul; + struct sbat_emul_bat_data *bat; + const struct device *gpio_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_AC_OK_PATH, gpios)); + + set_test_runner_tid(); + zassert_ok(tcpci_tcpm_init(0), 0); + pd_set_suspend(0, 0); + /* Reset to disconnected state. */ + zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul), NULL); + + /* Battery defaults to charging, so reset to not charging. */ + i2c_emul = sbat_emul_get_ptr(BATTERY_ORD); + bat = sbat_emul_get_bat_data(i2c_emul); + bat->cur = -5; + + zassert_ok(gpio_emul_input_set(gpio_dev, GPIO_AC_OK_PIN, 0), NULL); +} + +static void remove_emulated_devices(void) +{ + const struct emul *tcpci_emul = + emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL)); + /* TODO: This function should trigger gpios to signal there is nothing + * attached to the port. + */ + zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul), NULL); +} + +static void test_attach_compliant_charger(void) +{ + const struct emul *tcpci_emul = + emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL)); + struct i2c_emul *i2c_emul; + uint16_t battery_status; + struct tcpci_src_emul_data my_charger; + const struct device *gpio_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_AC_OK_PATH, gpios)); + + /* Verify battery not charging. */ + i2c_emul = sbat_emul_get_ptr(BATTERY_ORD); + zassert_ok(sbat_emul_get_word_val(i2c_emul, SB_BATTERY_STATUS, + &battery_status), + NULL); + zassert_not_equal(battery_status & STATUS_DISCHARGING, 0, + "Battery is not discharging: %d", battery_status); + + /* TODO? Send host command to verify PD_ROLE_DISCONNECTED. */ + + /* Attach emulated charger. */ + zassert_ok(gpio_emul_input_set(gpio_dev, GPIO_AC_OK_PIN, 1), NULL); + tcpci_src_emul_init(&my_charger); + zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger, tcpci_emul), + NULL); + + /* Wait for current ramp. */ + k_sleep(K_SECONDS(10)); + + /* Verify battery charging. */ + zassert_ok(sbat_emul_get_word_val(i2c_emul, SB_BATTERY_STATUS, + &battery_status), + NULL); + zassert_equal(battery_status & STATUS_DISCHARGING, 0, + "Battery is discharging: %d", battery_status); + /* TODO: Also check voltage, current, etc. */ +} + +static void test_attach_pd_charger(void) +{ + const struct emul *tcpci_emul = + emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL)); + struct i2c_emul *i2c_emul; + uint16_t battery_status; + struct tcpci_src_emul_data my_charger; + const struct device *gpio_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_AC_OK_PATH, gpios)); + struct ec_params_charge_state charge_params; + struct ec_response_charge_state charge_response; + struct host_cmd_handler_args args = BUILD_HOST_COMMAND( + EC_CMD_CHARGE_STATE, 0, charge_response, charge_params); + + /* + * TODO(b/209907297): Implement the steps of the test beyond USB default + * charging. + */ + + /* 1. Configure source PDOs of partner (probably fixed source 5V 3A + * and fixed source 20V 3A). Currently, the partner emulator only + * supports the default USB power PDO. + */ + + /* Attach emulated charger. This will send Source Capabilities. */ + zassert_ok(gpio_emul_input_set(gpio_dev, GPIO_AC_OK_PIN, 1), NULL); + tcpci_src_emul_init(&my_charger); + zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger, tcpci_emul), + NULL); + + /* Wait for current ramp. */ + k_sleep(K_SECONDS(10)); + + /* Verify battery charging. */ + i2c_emul = sbat_emul_get_ptr(BATTERY_ORD); + zassert_ok(sbat_emul_get_word_val(i2c_emul, SB_BATTERY_STATUS, + &battery_status), + NULL); + zassert_equal(battery_status & STATUS_DISCHARGING, 0, + "Battery is discharging: %d", battery_status); + + /* + * 2. Check charging current and voltage (should be 5V, default USB + * current); make sure that reports from battery and PD host commands + * match; check that host command reports no active PDO. + */ + /* + * TODO(b/209907297): Also check the corresponding PD state and + * encapsulate this for use in other tests. + */ + charge_params.chgnum = 0; + charge_params.cmd = CHARGE_STATE_CMD_GET_STATE; + zassert_ok(host_command_process(&args), "Failed to get charge state"); + zassert_true(charge_response.get_state.ac, "USB default but AC absent"); + zassert_equal(charge_response.get_state.chg_voltage, 5000, + "USB default volage %dmV", + charge_response.get_state.chg_voltage); + zassert_true(charge_response.get_state.chg_current > 0, + "USB default current %dmA", + charge_response.get_state.chg_current); + + /* + * 3. Wait for SenderResponseTimeout. Expect TCPM to send Request. + * We could verify that the Request references the expected PDO, but + * the voltage/current/PDO checks at the end of the test should all be + * wrong if the requested PDO was wrong here. + */ + + /* + * 4. Send Accept and PS_RDY from partner with appropriate delay between + * them. Emulate supplying VBUS at the requested voltage/current before + * PS_RDY. + */ + + /* + * 5. Check the charging voltage and current. Cross-check the PD state, + * the battery/charger state, and the active PDO as reported by the PD + * state. + */ +} + +void test_suite_integration_usb(void) +{ + ztest_test_suite(integration_usb, + ztest_user_unit_test_setup_teardown( + test_attach_compliant_charger, init_tcpm, + remove_emulated_devices), + ztest_user_unit_test_setup_teardown( + test_attach_pd_charger, init_tcpm, + remove_emulated_devices)); + ztest_run_test_suite(integration_usb); +} diff --git a/zephyr/test/drivers/src/isl923x.c b/zephyr/test/drivers/src/isl923x.c index e1b1dbc020..27ce29984a 100644 --- a/zephyr/test/drivers/src/isl923x.c +++ b/zephyr/test/drivers/src/isl923x.c @@ -5,6 +5,7 @@ #include <ztest.h> #include <drivers/emul.h> +#include <fff.h> #include "battery.h" #include "battery_smart.h" @@ -14,6 +15,7 @@ #include "emul/emul_common_i2c.h" #include "emul/emul_isl923x.h" #include "system.h" +#include "test_mocks.h" BUILD_ASSERT(CONFIG_CHARGER_SENSE_RESISTOR == 10 || CONFIG_CHARGER_SENSE_RESISTOR == 5); @@ -673,24 +675,451 @@ static void test_init(void) system_jumped_late_mock.ret_val = false; } +static void test_isl923x_is_acok(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + enum ec_error_list rv; + bool acok; + + /* Part 1: invalid charger number */ + rv = raa489000_is_acok(board_get_charger_chip_count() + 1, &acok); + zassert_equal(EC_ERROR_INVAL, rv, + "Invalid charger num, but AC OK check succeeded"); + + /* Part 2: error accessing register */ + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_INFO2); + + rv = raa489000_is_acok(CHARGER_NUM, &acok); + zassert_equal(EC_ERROR_INVAL, rv, + "Register read failure, but AC OK check succeeded"); + + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + + /* Part 3: successful path - ACOK is true */ + raa489000_emul_set_acok_pin(isl923x_emul, 1); + + rv = raa489000_is_acok(CHARGER_NUM, &acok); + zassert_equal(EC_SUCCESS, rv, "AC OK check did not return success"); + zassert_true(acok, "AC OK is false"); + + /* Part 3: successful path - ACOK is false */ + raa489000_emul_set_acok_pin(isl923x_emul, 0); + + 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"); +} + +static void test_isl923x_enable_asgate(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + int rv; + + /* Part 1: Try enabling the ASGATE */ + rv = raa489000_enable_asgate(CHARGER_NUM, true); + + zassert_equal(EC_SUCCESS, rv, "Expected return code of %d but got %d", + EC_SUCCESS, rv); + zassert_true( + isl923x_emul_peek_reg(i2c_emul, RAA489000_REG_CONTROL8) & + RAA489000_C8_ASGATE_ON_READY, + "RAA489000_C8_ASGATE_ON_READY bit not set in Control Reg 8"); + + /* Part 2: Turn it back off */ + rv = raa489000_enable_asgate(CHARGER_NUM, false); + + zassert_equal(EC_SUCCESS, rv, "Expected return code of %d but got %d", + EC_SUCCESS, rv); + zassert_false(isl923x_emul_peek_reg(i2c_emul, RAA489000_REG_CONTROL8) & + RAA489000_C8_ASGATE_ON_READY, + "RAA489000_C8_ASGATE_ON_READY bit set in Control Reg 8"); +} + +/* Mock read and write functions to use in the hibernation test */ +FAKE_VALUE_FUNC(int, hibernate_mock_read_fn, struct i2c_emul *, int, uint8_t *, + int, void *); +FAKE_VALUE_FUNC(int, hibernate_mock_write_fn, struct i2c_emul *, int, uint8_t, + int, void *); + +/** + * @brief Setup function for the hibernate tests. + */ +static void hibernate_test_setup(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + /* Reset mocks and make the read/write mocks pass all data through */ + RESET_FAKE(hibernate_mock_read_fn); + RESET_FAKE(hibernate_mock_write_fn); + hibernate_mock_read_fn_fake.return_val = 1; + hibernate_mock_write_fn_fake.return_val = 1; + + i2c_common_emul_set_read_func(i2c_emul, hibernate_mock_read_fn, NULL); + i2c_common_emul_set_write_func(i2c_emul, hibernate_mock_write_fn, NULL); + + /* Don't fail on any register access */ + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + i2c_common_emul_set_write_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); +} + +/** + * @brief Teardown function for the hibernate tests. + */ +static void hibernate_test_teardown(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + /* Clear the mock read/write functions */ + i2c_common_emul_set_read_func(i2c_emul, NULL, NULL); + i2c_common_emul_set_write_func(i2c_emul, NULL, NULL); + + /* Don't fail on any register access */ + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + i2c_common_emul_set_write_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); +} + +static void test_isl923x_hibernate__happy_path(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t actual; + + raa489000_hibernate(CHARGER_NUM, false); + + /* Check ISL923X_REG_CONTROL0 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL0); + + zassert_false(actual & RAA489000_C0_EN_CHG_PUMPS_TO_100PCT, + "RAA489000_C0_EN_CHG_PUMPS_TO_100PCT should not be set"); + zassert_false(actual & RAA489000_C0_BGATE_FORCE_ON, + "RAA489000_C0_BGATE_FORCE_ON should not be set"); + + /* Check ISL923X_REG_CONTROL1 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1); + + zassert_false(actual & RAA489000_C1_ENABLE_SUPP_SUPPORT_MODE, + "RAA489000_C1_ENABLE_SUPP_SUPPORT_MODE should not be set"); + zassert_false(actual & ISL923X_C1_ENABLE_PSYS, + "ISL923X_C1_ENABLE_PSYS should not be set"); + zassert_true(actual & RAA489000_C1_BGATE_FORCE_OFF, + "RAA489000_C1_BGATE_FORCE_OFF should be set"); + zassert_true(actual & ISL923X_C1_DISABLE_MON, + "ISL923X_C1_DISABLE_MON should be set"); + + /* Check ISL9238_REG_CONTROL3 (disable_adc = false) */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3); + + zassert_true(actual & RAA489000_ENABLE_ADC, + "RAA489000_ENABLE_ADC should be set"); + + /* Check ISL9238_REG_CONTROL4 */ + actual = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL4); + + zassert_true(actual & RAA489000_C4_DISABLE_GP_CMP, + "RAA489000_C4_DISABLE_GP_CMP should be set"); + + /* Ensure all expected register reads and writes happened */ + int registers[] = { ISL923X_REG_CONTROL0, ISL923X_REG_CONTROL1, + ISL9238_REG_CONTROL3, ISL9238_REG_CONTROL4 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + /* Each reg has 2 reads and 2 writes because they are 16-bit */ + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, i * 2, + registers[i]); + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, (i * 2) + 1, + registers[i]); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, i * 2, + registers[i], MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, (i * 2) + 1, + registers[i], MOCK_IGNORE_VALUE); + } +} + +static void test_isl923x_hibernate__invalid_charger_number(void) +{ + /* Mocks should just be pass-through */ + RESET_FAKE(hibernate_mock_read_fn); + RESET_FAKE(hibernate_mock_write_fn); + hibernate_mock_read_fn_fake.return_val = 1; + hibernate_mock_write_fn_fake.return_val = 1; + + raa489000_hibernate(board_get_charger_chip_count() + 1, false); + + /* Make sure no I2C activity happened */ + zassert_equal(hibernate_mock_read_fn_fake.call_count, 0, + "No I2C reads should have happened"); + zassert_equal(hibernate_mock_write_fn_fake.call_count, 0, + "No I2C writes should have happened"); +} + +static void test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL0(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL923X_REG_CONTROL0); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * We have no return codes to check, so instead verify that the first + * successful I2C write is to CONTROL1 and not CONTROL0. + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 0, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL1(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL923X_REG_CONTROL1); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL1. (NB: due to 16-bit regs, each write takes + * two calls to the mock_write_fn) + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 0, ISL923X_REG_CONTROL0, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 1, ISL923X_REG_CONTROL0, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 2, ISL9238_REG_CONTROL3, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 3, ISL9238_REG_CONTROL3, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL3(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_CONTROL3); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL3. (NB: due to 16-bit regs, each write takes + * two calls to the mock_write_fn) + */ + + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 2, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 3, ISL923X_REG_CONTROL1, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 4, ISL9238_REG_CONTROL4, + MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 5, ISL9238_REG_CONTROL4, + MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL4(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + + i2c_common_emul_set_read_fail_reg(i2c_emul, ISL9238_REG_CONTROL4); + + raa489000_hibernate(CHARGER_NUM, false); + + /* + * Ensure we skipped CONTROL4. (i.e. the last calls should be to write + * to CONTROL3) + */ + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, + hibernate_mock_write_fn_fake.call_count - 2, + ISL9238_REG_CONTROL3, MOCK_IGNORE_VALUE); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, + hibernate_mock_write_fn_fake.call_count - 1, + ISL9238_REG_CONTROL3, MOCK_IGNORE_VALUE); +} + +static void test_isl923x_hibernate__adc_disable(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t expected; + + raa489000_hibernate(CHARGER_NUM, true); + + /* Check ISL9238_REG_CONTROL3 (disable_adc = true) */ + expected = isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3); + expected &= ~RAA489000_ENABLE_ADC; + + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, 4, ISL9238_REG_CONTROL3); + MOCK_ASSERT_I2C_READ(hibernate_mock_read_fn, 5, ISL9238_REG_CONTROL3); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 4, ISL9238_REG_CONTROL3, + expected & 0xff); + MOCK_ASSERT_I2C_WRITE(hibernate_mock_write_fn, 5, ISL9238_REG_CONTROL3, + expected >> 8); +} + +static void test_isl9238c_hibernate(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t control1_expected, control2_expected, control3_expected; + int rv; + + /* Part 1: Happy path */ + control1_expected = + (isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1) & + ~ISL923X_C1_ENABLE_PSYS) | + ISL923X_C1_DISABLE_MON; + control2_expected = + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2) | + ISL923X_C2_COMPARATOR; + control3_expected = + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3) | + ISL9238_C3_BGATE_OFF; + + rv = isl9238c_hibernate(CHARGER_NUM); + + zassert_equal(EC_SUCCESS, rv, "Expected return code %d but got %d", + EC_SUCCESS, rv); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected); + + /* Part 2: Fail reading each register and check for error code */ + int registers[] = { ISL923X_REG_CONTROL1, ISL923X_REG_CONTROL2, + ISL9238_REG_CONTROL3 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + i2c_common_emul_set_read_fail_reg(i2c_emul, registers[i]); + + rv = isl9238c_hibernate(CHARGER_NUM); + + zassert_equal(EC_ERROR_INVAL, rv, + "Wrong return code. Expected %d but got %d", + EC_ERROR_INVAL, rv); + } +} + +static void test_isl9238c_resume(void) +{ + const struct emul *isl923x_emul = ISL923X_EMUL; + struct i2c_emul *i2c_emul = isl923x_emul_get_i2c_emul(isl923x_emul); + uint16_t control1_expected, control2_expected, control3_expected; + int rv; + + /* Part 1: Happy path */ + control1_expected = + (isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1) & + ~ISL923X_C1_DISABLE_MON) | ISL923X_C1_ENABLE_PSYS + ; + control2_expected = + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2) & + ~ISL923X_C2_COMPARATOR; + control3_expected = + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3) & + ~ISL9238_C3_BGATE_OFF; + + rv = isl9238c_resume(CHARGER_NUM); + + zassert_equal(EC_SUCCESS, rv, "Expected return code %d but got %d", + EC_SUCCESS, rv); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL1), + control1_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL923X_REG_CONTROL2), + control2_expected); + zassert_equal(isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected, + "Unexpected register value 0x%02x. Should be 0x%02x", + isl923x_emul_peek_reg(i2c_emul, ISL9238_REG_CONTROL3), + control3_expected); + + /* Part 2: Fail reading each register and check for error code */ + int registers[] = { ISL923X_REG_CONTROL1, ISL923X_REG_CONTROL2, + ISL9238_REG_CONTROL3 }; + + for (int i = 0; i < ARRAY_SIZE(registers); i++) { + i2c_common_emul_set_read_fail_reg(i2c_emul, registers[i]); + + rv = isl9238c_resume(CHARGER_NUM); + + zassert_equal(EC_ERROR_INVAL, rv, + "Wrong return code. Expected %d but got %d", + EC_ERROR_INVAL, rv); + } +} + void test_suite_isl923x(void) { - ztest_test_suite(isl923x, - ztest_unit_test(test_isl923x_set_current), - ztest_unit_test(test_isl923x_set_voltage), - ztest_unit_test(test_isl923x_set_input_current_limit), - ztest_unit_test(test_manufacturer_id), - ztest_unit_test(test_device_id), - ztest_unit_test(test_options), - ztest_unit_test(test_get_info), - ztest_unit_test(test_status), - ztest_unit_test(test_set_mode), - ztest_unit_test(test_post_init), - ztest_unit_test(test_set_ac_prochot), - ztest_unit_test(test_set_dc_prochot), - ztest_unit_test(test_comparator_inversion), - ztest_unit_test(test_discharge_on_ac), - ztest_unit_test(test_get_vbus_voltage), - ztest_unit_test(test_init)); + ztest_test_suite( + isl923x, ztest_unit_test(test_isl923x_set_current), + ztest_unit_test(test_isl923x_set_voltage), + ztest_unit_test(test_isl923x_set_input_current_limit), + ztest_unit_test(test_manufacturer_id), + ztest_unit_test(test_device_id), ztest_unit_test(test_options), + ztest_unit_test(test_get_info), ztest_unit_test(test_status), + ztest_unit_test(test_set_mode), ztest_unit_test(test_post_init), + ztest_unit_test(test_set_ac_prochot), + ztest_unit_test(test_set_dc_prochot), + ztest_unit_test(test_comparator_inversion), + ztest_unit_test(test_discharge_on_ac), + ztest_unit_test(test_get_vbus_voltage), + ztest_unit_test(test_init), + ztest_unit_test(test_isl923x_is_acok), + ztest_unit_test(test_isl923x_enable_asgate), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__happy_path, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__invalid_charger_number, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL0, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL923X_REG_CONTROL1, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL3, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__fail_at_ISL9238_REG_CONTROL4, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown( + test_isl923x_hibernate__adc_disable, + hibernate_test_setup, hibernate_test_teardown), + ztest_unit_test_setup_teardown(test_isl9238c_hibernate, + hibernate_test_teardown, + hibernate_test_teardown), + ztest_unit_test_setup_teardown(test_isl9238c_resume, + hibernate_test_teardown, + hibernate_test_teardown)); ztest_run_test_suite(isl923x); } diff --git a/zephyr/test/drivers/src/lis2dw12.c b/zephyr/test/drivers/src/lis2dw12.c index 287430e65b..24218aea9f 100644 --- a/zephyr/test/drivers/src/lis2dw12.c +++ b/zephyr/test/drivers/src/lis2dw12.c @@ -14,9 +14,34 @@ #define EMUL_LABEL DT_LABEL(DT_NODELABEL(lis2dw12_emul)) #include <stdio.h> + +#define CHECK_XYZ_EQUALS(VEC1, VEC2) \ + do { \ + zassert_equal((VEC1)[X], (VEC2)[X], \ + "Got %d for X, expected %d", (VEC1)[X], \ + (VEC2)[X]); \ + zassert_equal((VEC1)[Y], (VEC2)[Y], \ + "Got %d for Y, expected %d", (VEC1)[Y], \ + (VEC2)[Y]); \ + zassert_equal((VEC1)[Z], (VEC2)[Z], \ + "Got %d for Z, expected %d", (VEC1)[Z], \ + (VEC2)[Z]); \ + } while (0) + +/** Used with the LIS2DW12 set rate function to control rounding behavior */ +enum lis2dw12_round_mode { + ROUND_DOWN, + ROUND_UP, +}; + static void lis2dw12_setup(void) { lis2dw12_emul_reset(emul_get_binding(EMUL_LABEL)); + + /* Reset certain sensor struct values */ + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + + ms->current_range = 0; } static void test_lis2dw12_init__fail_read_who_am_i(void) @@ -97,23 +122,351 @@ static void test_lis2dw12_init__fail_set_bdu(void) "expected at least one soft reset"); } +static void test_lis2dw12_init__fail_set_lir(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + int rv; + + i2c_common_emul_set_read_fail_reg(lis2dw12_emul_to_i2c_emul(emul), + LIS2DW12_LIR_ADDR); + + rv = ms->drv->init(ms); + zassert_equal(EC_ERROR_INVAL, rv, "init returned %d but expected %d", + rv, EC_ERROR_INVAL); + zassert_true(lis2dw12_emul_get_soft_reset_count(emul) > 0, + "expected at least one soft reset"); +} + +static int lis2dw12_test_mock_write_fail_set_power_mode(struct i2c_emul *emul, + int reg, uint8_t val, + int bytes, void *data) +{ + if (reg == LIS2DW12_ACC_LPMODE_ADDR && bytes == 1 && + (val & LIS2DW12_ACC_LPMODE_MASK) != 0) { + /* Cause an error when trying to set the LPMODE */ + return -EIO; + } + return 1; +} + +static void test_lis2dw12_init__fail_set_power_mode(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + int rv; + + i2c_common_emul_set_write_func( + lis2dw12_emul_to_i2c_emul(emul), + lis2dw12_test_mock_write_fail_set_power_mode, NULL); + + rv = ms->drv->init(ms); + zassert_equal(EC_ERROR_INVAL, rv, "init returned %d but expected %d", + rv, EC_ERROR_INVAL); + zassert_true(lis2dw12_emul_get_soft_reset_count(emul) > 0, + "expected at least one soft reset"); +} + +static void test_lis2dw12_init__success(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + struct stprivate_data *drvdata = ms->drv_data; + + int rv; + + rv = ms->drv->init(ms); + zassert_equal(EC_SUCCESS, rv, "init returned %d but expected %d", rv, + EC_SUCCESS); + zassert_true(lis2dw12_emul_get_soft_reset_count(emul) > 0, + "expected at least one soft reset"); + zassert_equal(LIS2DW12_RESOLUTION, drvdata->resol, + "Expected resolution of %d but got %d", + LIS2DW12_RESOLUTION, drvdata->resol); +} + +static void test_lis2dw12_set_power_mode(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + int rv; + + /* Part 1: happy path */ + rv = lis2dw12_set_power_mode(ms, LIS2DW12_LOW_POWER, + LIS2DW12_LOW_POWER_MODE_2); + zassert_equal(rv, EC_SUCCESS, "Expected %d but got %d", EC_SUCCESS, rv); + + /* Part 2: unimplemented modes */ + rv = lis2dw12_set_power_mode(ms, LIS2DW12_LOW_POWER, + LIS2DW12_LOW_POWER_MODE_1); + zassert_equal(rv, EC_ERROR_UNIMPLEMENTED, "Expected %d but got %d", + EC_ERROR_UNIMPLEMENTED, rv); + + /* Part 3: attempt to set mode but cannot modify reg. */ + i2c_common_emul_set_read_fail_reg(lis2dw12_emul_to_i2c_emul(emul), + LIS2DW12_ACC_MODE_ADDR); + rv = lis2dw12_set_power_mode(ms, LIS2DW12_LOW_POWER, + LIS2DW12_LOW_POWER_MODE_2); + zassert_equal(rv, EC_ERROR_INVAL, "Expected %d but got %d", + EC_ERROR_INVAL, rv); +} + +static void test_lis2dw12_set_range(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + int rv; + + /* Part 1: Happy path. Go above the max range; it will be automatically + * clamped. + */ + + rv = ms->drv->set_range(ms, LIS2DW12_ACCEL_FS_MAX_VAL + 1, 0); + zassert_equal(rv, EC_SUCCESS, "Expected %d but got %d", EC_SUCCESS, rv); + zassert_equal(ms->current_range, LIS2DW12_ACCEL_FS_MAX_VAL, + "Expected %d but got %d", LIS2DW12_ACCEL_FS_MAX_VAL, + ms->current_range); + + /* Part 2: Error accessing register */ + i2c_common_emul_set_read_fail_reg(lis2dw12_emul_to_i2c_emul(emul), + LIS2DW12_FS_ADDR); + rv = ms->drv->set_range(ms, LIS2DW12_ACCEL_FS_MAX_VAL, 0); + zassert_equal(rv, EC_ERROR_INVAL, "Expected %d but got %d", + EC_ERROR_INVAL, rv); +} + +static void test_lis2dw12_set_rate(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct i2c_emul *i2c_emul = lis2dw12_emul_to_i2c_emul(emul); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + struct stprivate_data *drv_data = ms->drv_data; + int rv; + + /* Part 1: Turn off sensor with rate=0 */ + rv = ms->drv->set_data_rate(ms, 0, 0); + + zassert_equal(lis2dw12_emul_peek_odr(i2c_emul), + LIS2DW12_ODR_POWER_OFF_VAL, + "Output data rate should be %d but got %d", + LIS2DW12_ODR_POWER_OFF_VAL, + lis2dw12_emul_peek_odr(i2c_emul)); + zassert_equal(drv_data->base.odr, LIS2DW12_ODR_POWER_OFF_VAL, + "Output data rate should be %d but got %d", + LIS2DW12_ODR_POWER_OFF_VAL, drv_data->base.odr); + zassert_equal(rv, EC_SUCCESS, "Returned %d but expected %d", rv, + EC_SUCCESS); + + /* Part 2: Set some output data rates. We will request a certain rate + * and make sure the closest supported rate is used. + */ + + static const struct { + int requested_rate; /* millihertz */ + enum lis2dw12_round_mode round; + int expected_norm_rate; /* millihertz */ + uint8_t expected_reg_val; + } test_params[] = { + { 1000, ROUND_DOWN, LIS2DW12_ODR_MIN_VAL, + LIS2DW12_ODR_12HZ_VAL }, + { 12501, ROUND_DOWN, 12500, LIS2DW12_ODR_12HZ_VAL }, + { 25001, ROUND_DOWN, 25000, LIS2DW12_ODR_25HZ_VAL }, + { 50001, ROUND_DOWN, 50000, LIS2DW12_ODR_50HZ_VAL }, + { 100001, ROUND_DOWN, 100000, LIS2DW12_ODR_100HZ_VAL }, + { 200001, ROUND_DOWN, 200000, LIS2DW12_ODR_200HZ_VAL }, + { 400001, ROUND_DOWN, 400000, LIS2DW12_ODR_400HZ_VAL }, + { 800001, ROUND_DOWN, 800000, LIS2DW12_ODR_800HZ_VAL }, + { 1600001, ROUND_DOWN, 1600000, LIS2DW12_ODR_1_6kHZ_VAL }, + { 3200001, ROUND_DOWN, LIS2DW12_ODR_MAX_VAL, + LIS2DW12_ODR_1_6kHZ_VAL }, + + { 1000, ROUND_UP, LIS2DW12_ODR_MIN_VAL, LIS2DW12_ODR_12HZ_VAL }, + { 12501, ROUND_UP, 25000, LIS2DW12_ODR_25HZ_VAL }, + { 25001, ROUND_UP, 50000, LIS2DW12_ODR_50HZ_VAL }, + { 50001, ROUND_UP, 100000, LIS2DW12_ODR_100HZ_VAL }, + { 100001, ROUND_UP, 200000, LIS2DW12_ODR_200HZ_VAL }, + { 200001, ROUND_UP, 400000, LIS2DW12_ODR_400HZ_VAL }, + { 400001, ROUND_UP, 800000, LIS2DW12_ODR_800HZ_VAL }, + { 800001, ROUND_UP, 1600000, LIS2DW12_ODR_1_6kHZ_VAL }, + { 1600001, ROUND_UP, LIS2DW12_ODR_MAX_VAL, + LIS2DW12_ODR_1_6kHZ_VAL }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(test_params); i++) { + /* For each test vector in the above array */ + drv_data->base.odr = -1; + rv = ms->drv->set_data_rate(ms, test_params[i].requested_rate, + test_params[i].round); + + /* Check the normalized rate the driver chose */ + zassert_equal( + drv_data->base.odr, test_params[i].expected_norm_rate, + "For requested rate %d, output data rate should be %d but got %d", + test_params[i].requested_rate, + test_params[i].expected_norm_rate, drv_data->base.odr); + + /* Read ODR and mode bits back from CTRL1 register */ + uint8_t odr_bits = lis2dw12_emul_peek_odr(i2c_emul); + + zassert_equal( + odr_bits, test_params[i].expected_reg_val, + "For requested rate %d, ODR bits should be 0x%x but got 0x%x - %d", + test_params[i].requested_rate, + test_params[i].expected_reg_val, odr_bits, + LIS2DW12_ODR_MAX_VAL); + + /* Check if high performance mode was enabled if rate > + * 200,000mHz + */ + + uint8_t mode_bits = lis2dw12_emul_peek_mode(i2c_emul); + uint8_t lpmode_bits = lis2dw12_emul_peek_lpmode(i2c_emul); + + if (odr_bits > LIS2DW12_ODR_200HZ_VAL) { + /* High performance mode, LP mode immaterial */ + zassert_equal(mode_bits, LIS2DW12_HIGH_PERF, + "MODE[1:0] should be 0x%x, but got 0x%x", + LIS2DW12_HIGH_PERF, mode_bits); + + } else { + /* Low power mode, LP mode 2 */ + zassert_equal(mode_bits, LIS2DW12_LOW_POWER, + "MODE[1:0] should be 0x%x, but got 0x%x", + LIS2DW12_LOW_POWER, mode_bits); + + zassert_equal( + lpmode_bits, LIS2DW12_LOW_POWER_MODE_2, + "LPMODE[1:0] should be 0x%x, but got 0x%x", + LIS2DW12_LOW_POWER_MODE_2, lpmode_bits); + } + } +} + +static void test_lis2dw12_read(void) +{ + const struct emul *emul = emul_get_binding(EMUL_LABEL); + struct i2c_emul *i2c_emul = lis2dw12_emul_to_i2c_emul(emul); + struct motion_sensor_t *ms = &motion_sensors[LIS2DW12_SENSOR_ID]; + struct stprivate_data *drvdata = ms->drv_data; + intv3_t sample = { 0, 0, 0 }; + int rv; + + /* Reading requires a range to be set. Use 1 so it has no effect + * when scaling samples. Also need to set the sensor resolution + * manually. + */ + + ms->drv->set_range(ms, 1, 0); + drvdata->resol = LIS2DW12_RESOLUTION; + + /* Part 1: Try to read from sensor, but cannot check status register for + * ready bit + */ + + i2c_common_emul_set_read_fail_reg(i2c_emul, LIS2DW12_STATUS_REG); + + rv = ms->drv->read(ms, sample); + + zassert_equal(rv, EC_ERROR_INVAL, + "Expected return val of %d but got %d", EC_ERROR_INVAL, + rv); + + /* Part 2: Try to read sensor, but no new data is available. In this + * case, the driver should return the reading in from `ms->raw_xyz` + */ + + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + lis2dw12_emul_clear_accel_reading(emul); + ms->raw_xyz[X] = 123; + ms->raw_xyz[Y] = 456; + ms->raw_xyz[Z] = 789; + + rv = ms->drv->read(ms, sample); + + zassert_equal(rv, EC_SUCCESS, "Expected return val of %d but got %d", + EC_SUCCESS, rv); + CHECK_XYZ_EQUALS(sample, ms->raw_xyz); + + /* Part 3: Read from sensor w/ data ready, but an error occurs during + * read. + */ + intv3_t fake_sample = { 100, 200, 300 }; + + i2c_common_emul_set_read_fail_reg(i2c_emul, LIS2DW12_OUT_X_L_ADDR); + lis2dw12_emul_set_accel_reading(emul, fake_sample); + + rv = ms->drv->read(ms, sample); + + zassert_equal(rv, EC_ERROR_INVAL, + "Expected return val of %d but got %d", EC_ERROR_INVAL, + rv); + + /* Part 4: Success */ + + intv3_t expected_sample; + + for (int i = 0; i < ARRAY_SIZE(expected_sample); i++) { + /* The read routine will normalize `fake_sample` to use the full + * range of INT16, so we need to compensate in our expected + * output + */ + + expected_sample[i] = fake_sample[i] * + (1 << (16 - LIS2DW12_RESOLUTION)); + } + + i2c_common_emul_set_read_fail_reg(i2c_emul, + I2C_COMMON_EMUL_NO_FAIL_REG); + + lis2dw12_emul_set_accel_reading(emul, fake_sample); + + rv = ms->drv->read(ms, sample); + + zassert_equal(rv, EC_SUCCESS, "Expected return val of %d but got %d", + EC_SUCCESS, rv); + CHECK_XYZ_EQUALS(sample, expected_sample); +} + void test_suite_lis2dw12(void) { ztest_test_suite(lis2dw12, ztest_unit_test_setup_teardown( test_lis2dw12_init__fail_read_who_am_i, - lis2dw12_setup, unit_test_noop), + lis2dw12_setup, lis2dw12_setup), ztest_unit_test_setup_teardown( test_lis2dw12_init__fail_who_am_i, - lis2dw12_setup, unit_test_noop), + lis2dw12_setup, lis2dw12_setup), ztest_unit_test_setup_teardown( test_lis2dw12_init__fail_write_soft_reset, - lis2dw12_setup, unit_test_noop), + lis2dw12_setup, lis2dw12_setup), ztest_unit_test_setup_teardown( test_lis2dw12_init__timeout_read_soft_reset, - lis2dw12_setup, unit_test_noop), + lis2dw12_setup, lis2dw12_setup), ztest_unit_test_setup_teardown( test_lis2dw12_init__fail_set_bdu, - lis2dw12_setup, unit_test_noop)); + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_init__fail_set_lir, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_init__fail_set_power_mode, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_init__success, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_set_power_mode, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_set_range, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_set_rate, + lis2dw12_setup, lis2dw12_setup), + ztest_unit_test_setup_teardown( + test_lis2dw12_read, + lis2dw12_setup, lis2dw12_setup) + ); ztest_run_test_suite(lis2dw12); } diff --git a/zephyr/test/drivers/src/main.c b/zephyr/test/drivers/src/main.c index 05fe12c8fc..687ea0785e 100644 --- a/zephyr/test/drivers/src/main.c +++ b/zephyr/test/drivers/src/main.c @@ -30,6 +30,8 @@ extern void test_suite_ppc_sn5s330(void); extern void test_suite_cros_cbi(void); extern void test_suite_tcpci(void); extern void test_suite_ps8xxx(void); +extern void test_suite_integration_usb(void); +extern void test_suite_power_common(void); void test_main(void) { @@ -61,4 +63,6 @@ void test_main(void) test_suite_cros_cbi(); test_suite_tcpci(); test_suite_ps8xxx(); + test_suite_integration_usb(); + test_suite_power_common(); } diff --git a/zephyr/test/drivers/src/power_common.c b/zephyr/test/drivers/src/power_common.c new file mode 100644 index 0000000000..86e03ea38c --- /dev/null +++ b/zephyr/test/drivers/src/power_common.c @@ -0,0 +1,677 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <ztest.h> +#include <drivers/gpio.h> +#include <drivers/gpio/gpio_emul.h> +#include <shell/shell.h> +#include <shell/shell_uart.h> + +#include "chipset.h" +#include "common.h" +#include "extpower.h" +#include "hooks.h" +#include "host_command.h" +#include "power.h" +#include "stubs.h" +#include "task.h" + +#include "emul/emul_common_i2c.h" +#include "emul/emul_smart_battery.h" + +#include "battery.h" +#include "battery_smart.h" + +#define BATTERY_ORD DT_DEP_ORD(DT_NODELABEL(battery)) + +#define GPIO_ACOK_OD_NODE DT_PATH(named_gpios, acok_od) +#define GPIO_ACOK_OD_PIN DT_GPIO_PIN(GPIO_ACOK_OD_NODE, gpios) + +/* Description of all power states with chipset state masks */ +static struct { + /* Power state */ + enum power_state p_state; + /* + * CHIPSET_STATE_* to which this state transition (the same as + * transition_from for static states) + */ + int transition_to; + /* CHIPSET_STATE_* from which this state transition */ + int transition_from; +} test_power_state_desc[] = { + { + .p_state = POWER_G3, + .transition_to = CHIPSET_STATE_HARD_OFF, + .transition_from = CHIPSET_STATE_HARD_OFF, + }, + { + .p_state = POWER_G3S5, + .transition_to = CHIPSET_STATE_SOFT_OFF, + .transition_from = CHIPSET_STATE_HARD_OFF, + }, + { + .p_state = POWER_S5G3, + .transition_to = CHIPSET_STATE_HARD_OFF, + .transition_from = CHIPSET_STATE_SOFT_OFF, + }, + { + .p_state = POWER_S5, + .transition_to = CHIPSET_STATE_SOFT_OFF, + .transition_from = CHIPSET_STATE_SOFT_OFF, + }, + { + .p_state = POWER_S5S3, + .transition_to = CHIPSET_STATE_SUSPEND, + .transition_from = CHIPSET_STATE_SOFT_OFF, + }, + { + .p_state = POWER_S3S5, + .transition_to = CHIPSET_STATE_SOFT_OFF, + .transition_from = CHIPSET_STATE_SUSPEND, + }, + { + .p_state = POWER_S3, + .transition_to = CHIPSET_STATE_SUSPEND, + .transition_from = CHIPSET_STATE_SUSPEND, + }, + { + .p_state = POWER_S3S0, + .transition_to = CHIPSET_STATE_ON, + .transition_from = CHIPSET_STATE_SUSPEND, + }, + { + .p_state = POWER_S0S3, + .transition_to = CHIPSET_STATE_SUSPEND, + .transition_from = CHIPSET_STATE_ON, + }, + { + .p_state = POWER_S0, + .transition_to = CHIPSET_STATE_ON, + .transition_from = CHIPSET_STATE_ON, + }, +}; + +/* + * Chipset state masks used by chipset_in_state and + * chipset_in_or_transitioning_to_state tests + */ +static int in_state_test_masks[] = { + CHIPSET_STATE_HARD_OFF, + CHIPSET_STATE_SOFT_OFF, + CHIPSET_STATE_SUSPEND, + CHIPSET_STATE_ON, + CHIPSET_STATE_STANDBY, + CHIPSET_STATE_ANY_OFF, + CHIPSET_STATE_ANY_SUSPEND, + CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_SOFT_OFF, +}; + +/** Test chipset_in_state() for each state */ +static void test_power_chipset_in_state(void) +{ + bool expected_in_state; + bool transition_from; + bool transition_to; + bool in_state; + int mask; + + for (int i = 0; i < ARRAY_SIZE(test_power_state_desc); i++) { + /* Set given power state */ + power_set_state(test_power_state_desc[i].p_state); + /* Test with selected state masks */ + for (int j = 0; j < ARRAY_SIZE(in_state_test_masks); j++) { + mask = in_state_test_masks[j]; + /* + * Currently tested mask match with state if it match + * with transition_to and from chipset states + */ + transition_to = + mask & test_power_state_desc[i].transition_to; + transition_from = + mask & test_power_state_desc[i].transition_from; + expected_in_state = transition_to && transition_from; + in_state = chipset_in_state(mask); + zassert_equal(expected_in_state, in_state, + "Wrong chipset_in_state() == %d, " + "should be %d; mask 0x%x; power state %d " + "in test case %d", + in_state, expected_in_state, mask, + test_power_state_desc[i].p_state, i); + } + } +} + +/** Test chipset_in_or_transitioning_to_state() for each state */ +static void test_power_chipset_in_or_transitioning_to_state(void) +{ + bool expected_in_state; + bool in_state; + int mask; + + for (int i = 0; i < ARRAY_SIZE(test_power_state_desc); i++) { + /* Set given power state */ + power_set_state(test_power_state_desc[i].p_state); + /* Test with selected state masks */ + for (int j = 0; j < ARRAY_SIZE(in_state_test_masks); j++) { + mask = in_state_test_masks[j]; + /* + * Currently tested mask match with state if it match + * with transition_to chipset state + */ + expected_in_state = + mask & test_power_state_desc[i].transition_to; + in_state = chipset_in_or_transitioning_to_state(mask); + zassert_equal(expected_in_state, in_state, + "Wrong " + "chipset_in_or_transitioning_to_state() " + "== %d, should be %d; mask 0x%x; " + "power state %d in test case %d", + in_state, expected_in_state, mask, + test_power_state_desc[i].p_state, i); + } + } +} + +/** Test using chipset_exit_hard_off() in different power states */ +static void test_power_exit_hard_off(void) +{ + /* Force initial state */ + force_power_state(true, POWER_G3); + zassert_equal(POWER_G3, power_get_state(), NULL); + + /* Stop forcing state */ + force_power_state(false, 0); + + /* Test after exit hard off, we reach G3S5 */ + chipset_exit_hard_off(); + /* + * TODO(b/201420132) - chipset_exit_hard_off() is waking up + * TASK_ID_CHIPSET Sleep is required to run chipset task before + * continuing with test + */ + k_msleep(1); + zassert_equal(POWER_G3S5, power_get_state(), NULL); + + /* Go back to G3 and check we stay there */ + force_power_state(true, POWER_G3); + force_power_state(false, 0); + zassert_equal(POWER_G3, power_get_state(), NULL); + + /* Exit G3 again */ + chipset_exit_hard_off(); + /* TODO(b/201420132) - see comment above */ + k_msleep(1); + zassert_equal(POWER_G3S5, power_get_state(), NULL); + + /* Go to S5G3 */ + force_power_state(true, POWER_S5G3); + zassert_equal(POWER_S5G3, power_get_state(), NULL); + + /* Test exit hard off in S5G3 -- should immedietly exit G3 */ + chipset_exit_hard_off(); + /* Go back to G3 and check we exit it to G3S5 */ + force_power_state(true, POWER_G3); + zassert_equal(POWER_G3S5, power_get_state(), NULL); + + /* Test exit hard off is cleared on entering S5 */ + chipset_exit_hard_off(); + force_power_state(true, POWER_S5); + zassert_equal(POWER_S5, power_get_state(), NULL); + /* Go back to G3 and check we stay in G3 */ + force_power_state(true, POWER_G3); + force_power_state(false, 0); + zassert_equal(POWER_G3, power_get_state(), NULL); + + /* Test exit hard off doesn't work on other states */ + force_power_state(true, POWER_S5S3); + force_power_state(false, 0); + zassert_equal(POWER_S5S3, power_get_state(), NULL); + chipset_exit_hard_off(); + /* TODO(b/201420132) - see comment above */ + k_msleep(1); + + /* Go back to G3 and check we stay in G3 */ + force_power_state(true, POWER_G3); + force_power_state(false, 0); + zassert_equal(POWER_G3, power_get_state(), NULL); +} + +/* Test reboot ap on g3 host command is triggering reboot */ +static void test_power_reboot_ap_at_g3(void) +{ + struct ec_params_reboot_ap_on_g3_v1 params; + struct host_cmd_handler_args args = { + .command = EC_CMD_REBOOT_AP_ON_G3, + .version = 0, + .send_response = stub_send_response_callback, + .params = ¶ms, + .params_size = sizeof(params), + }; + int offset_for_still_in_g3_test; + int delay_ms; + + /* Force initial state S0 */ + force_power_state(true, POWER_S0); + zassert_equal(POWER_S0, power_get_state(), NULL); + + /* Test version 0 (no delay argument) */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + /* Go to G3 and check if reboot is triggered */ + force_power_state(true, POWER_G3); + zassert_equal(POWER_G3S5, power_get_state(), NULL); + + /* Test version 1 (with delay argument) */ + args.version = 1; + delay_ms = 3000; + params.reboot_ap_at_g3_delay = delay_ms / 1000; /* in seconds */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + /* Go to G3 and check if reboot is triggered after delay */ + force_power_state(true, POWER_G3); + force_power_state(false, 0); + zassert_equal(POWER_G3, power_get_state(), NULL); + /* + * Arbitrary chosen offset before end of reboot delay to check if G3 + * state wasn't left too soon + */ + offset_for_still_in_g3_test = 50; + k_msleep(delay_ms - offset_for_still_in_g3_test); + /* Test if still in G3 */ + zassert_equal(POWER_G3, power_get_state(), NULL); + /* + * power_common_state() use for loop with 100ms sleeps. msleep() wait at + * least specified time, so wait 10% longer than specified delay to take + * this into account. + */ + k_msleep(offset_for_still_in_g3_test + delay_ms / 10); + /* Test if reboot is triggered */ + zassert_equal(POWER_G3S5, power_get_state(), NULL); +} + +/** Test setting cutoff and stay-up battery levels through host command */ +static void test_power_hc_smart_discharge(void) +{ + struct ec_response_smart_discharge response; + struct ec_params_smart_discharge params; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_SMART_DISCHARGE, 0, response, params); + struct i2c_emul *emul; + int hours_to_zero; + int hibern_drate; + int cutoff_drate; + int stayup_cap; + int cutoff_cap; + + emul = sbat_emul_get_ptr(BATTERY_ORD); + + /* Set up host command parameters */ + params.flags = EC_SMART_DISCHARGE_FLAGS_SET; + + /* Test fail when battery capacity is not available */ + i2c_common_emul_set_read_fail_reg(emul, SB_FULL_CHARGE_CAPACITY); + zassert_equal(EC_RES_UNAVAILABLE, host_command_process(&args), NULL); + i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG); + + /* Setup discharge rates */ + params.drate.hibern = 10; + params.drate.cutoff = 100; + /* Test fail on higher discahrge in hibernation than cutoff */ + zassert_equal(EC_RES_INVALID_PARAM, host_command_process(&args), NULL); + + /* Setup discharge rates */ + params.drate.hibern = 10; + params.drate.cutoff = 0; + /* Test fail on only one discharge rate set to 0 */ + zassert_equal(EC_RES_INVALID_PARAM, host_command_process(&args), NULL); + + /* Setup correct parameters */ + hours_to_zero = 1000; + hibern_drate = 100; /* uA */ + cutoff_drate = 10; /* uA */ + /* Need at least 100 mA capacity to stay 1000h using 0.1mAh */ + stayup_cap = hibern_drate * hours_to_zero / 1000; + /* Need at least 10 mA capacity to stay 1000h using 0.01mAh */ + cutoff_cap = cutoff_drate * hours_to_zero / 1000; + + params.drate.hibern = hibern_drate; + params.drate.cutoff = cutoff_drate; + params.hours_to_zero = hours_to_zero; + + /* Test if correct values are set */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + zassert_equal(hibern_drate, response.drate.hibern, NULL); + zassert_equal(cutoff_drate, response.drate.cutoff, NULL); + zassert_equal(hours_to_zero, response.hours_to_zero, NULL); + zassert_equal(stayup_cap, response.dzone.stayup, NULL); + zassert_equal(cutoff_cap, response.dzone.cutoff, NULL); + + /* Setup discharge rate to 0 */ + params.drate.hibern = 0; + params.drate.cutoff = 0; + /* Update hours to zero */ + hours_to_zero = 2000; + params.hours_to_zero = hours_to_zero; + /* Need at least 200 mA capacity to stay 2000h using 0.1mAh */ + stayup_cap = hibern_drate * hours_to_zero / 1000; + /* Need at least 20 mA capacity to stay 2000h using 0.01mAh */ + cutoff_cap = cutoff_drate * hours_to_zero / 1000; + + /* Test that command doesn't change drate but apply new hours to zero */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + zassert_equal(hibern_drate, response.drate.hibern, NULL); + zassert_equal(cutoff_drate, response.drate.cutoff, NULL); + zassert_equal(hours_to_zero, response.hours_to_zero, NULL); + zassert_equal(stayup_cap, response.dzone.stayup, NULL); + zassert_equal(cutoff_cap, response.dzone.cutoff, NULL); + + /* Setup any parameters != 0 */ + params.drate.hibern = 1000; + params.drate.cutoff = 1000; + /* Clear set flag */ + params.flags = 0; + + /* Test that command doesn't change drate and dzone */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + zassert_equal(hibern_drate, response.drate.hibern, NULL); + zassert_equal(cutoff_drate, response.drate.cutoff, NULL); + zassert_equal(hours_to_zero, response.hours_to_zero, NULL); + zassert_equal(stayup_cap, response.dzone.stayup, NULL); + zassert_equal(cutoff_cap, response.dzone.cutoff, NULL); +} + +/** + * Test if default board_system_is_idle() recognize cutoff and stay-up + * levels correctly. + */ +static void test_power_board_system_is_idle(void) +{ + struct ec_response_smart_discharge response; + struct ec_params_smart_discharge params; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_SMART_DISCHARGE, 0, response, params); + struct sbat_emul_bat_data *bat; + struct i2c_emul *emul; + uint64_t last_shutdown_time = 0; + uint64_t target; + uint64_t now; + + emul = sbat_emul_get_ptr(BATTERY_ORD); + bat = sbat_emul_get_bat_data(emul); + + /* Set up host command parameters */ + params.drate.hibern = 100; /* uA */ + params.drate.cutoff = 10; /* uA */ + params.hours_to_zero = 1000; /* h */ + params.flags = EC_SMART_DISCHARGE_FLAGS_SET; + /* Set stay-up and cutoff zones */ + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + /* Test shutdown ignore is send when target time is in future */ + target = 1125; + now = 1000; + zassert_equal(CRITICAL_SHUTDOWN_IGNORE, + board_system_is_idle(last_shutdown_time, &target, now), + NULL); + + /* Set "now" time after target time */ + now = target + 30; + + /* + * Test hibernation is requested when battery remaining capacity + * is not available + */ + i2c_common_emul_set_read_fail_reg(emul, SB_REMAINING_CAPACITY); + zassert_equal(CRITICAL_SHUTDOWN_HIBERNATE, + board_system_is_idle(last_shutdown_time, &target, now), + NULL); + i2c_common_emul_set_read_fail_reg(emul, I2C_COMMON_EMUL_NO_FAIL_REG); + + /* Setup remaining capacity to trigger cutoff */ + bat->cap = response.dzone.cutoff - 5; + zassert_equal(CRITICAL_SHUTDOWN_CUTOFF, + board_system_is_idle(last_shutdown_time, &target, now), + NULL); + + /* Setup remaining capacity to trigger stay-up and ignore shutdown */ + bat->cap = response.dzone.stayup - 5; + zassert_equal(CRITICAL_SHUTDOWN_IGNORE, + board_system_is_idle(last_shutdown_time, &target, now), + NULL); + + /* Setup remaining capacity to be in safe zone to hibernate */ + bat->cap = response.dzone.stayup + 5; + zassert_equal(CRITICAL_SHUTDOWN_HIBERNATE, + board_system_is_idle(last_shutdown_time, &target, now), + NULL); +} + +/** + * Common setup for hibernation delay tests. Smart discharge zone is setup, + * battery is set in safe zone (which trigger hibernation), power state is + * set to G3 and AC is disabled. system_hibernate mock is reset. + */ +static void setup_hibernation_delay(void) +{ + struct ec_response_smart_discharge response; + struct ec_params_smart_discharge params; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_SMART_DISCHARGE, 0, response, params); + const struct device *acok_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_ACOK_OD_NODE, gpios)); + struct sbat_emul_bat_data *bat; + struct i2c_emul *emul; + + emul = sbat_emul_get_ptr(BATTERY_ORD); + bat = sbat_emul_get_bat_data(emul); + + /* Setup smart discharge zone and set capacity to safe zone */ + params.drate.hibern = 100; /* uA */ + params.drate.cutoff = 10; /* uA */ + params.hours_to_zero = 10000; /* h */ + params.flags = EC_SMART_DISCHARGE_FLAGS_SET; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + /* + * Make sure that battery is in safe zone in good condition to + * not trigger hibernate in charge_state_v2.c + */ + bat->cap = response.dzone.stayup + 5; + bat->volt = battery_get_info()->voltage_normal; + + /* Force initial state */ + force_power_state(true, POWER_G3); + zassert_equal(POWER_G3, power_get_state(), NULL); + + /* Stop forcing state */ + force_power_state(false, 0); + + /* Disable AC */ + zassert_ok(gpio_emul_input_set(acok_dev, GPIO_ACOK_OD_PIN, 0), NULL); + msleep(CONFIG_EXTPOWER_DEBOUNCE_MS + 1); + zassert_equal(0, extpower_is_present(), NULL); + + RESET_FAKE(system_hibernate); +} + +/** Test setting hibernation delay through host command */ +static void test_power_hc_hibernation_delay(void) +{ + struct ec_response_hibernation_delay response; + struct ec_params_hibernation_delay params; + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND(EC_CMD_HIBERNATION_DELAY, 0, response, + params); + const struct device *acok_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_ACOK_OD_NODE, gpios)); + uint32_t h_delay; + int sleep_time; + + /* Set hibernate delay */ + h_delay = 9; + params.seconds = h_delay; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + zassert_equal(0, response.time_g3, "Time from last G3 enter %d != 0", + response.time_g3); + zassert_equal(h_delay, response.time_remaining, + "Time to hibernation %d != %d", + response.time_remaining, h_delay); + zassert_equal(h_delay, response.hibernate_delay, + "Hibernation delay %d != %d", + h_delay, response.hibernate_delay); + + /* Kick chipset task to process new hibernation delay */ + task_wake(TASK_ID_CHIPSET); + /* Wait some arbitrary time less than hibernate delay */ + sleep_time = 6; + k_msleep(sleep_time * 1000); + + /* Get hibernate delay */ + params.seconds = 0; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + zassert_equal(sleep_time, response.time_g3, + "Time from last G3 enter %d != %d", + response.time_g3, sleep_time); + zassert_equal(h_delay - sleep_time, response.time_remaining, + "Time to hibernation %d != %d", + response.time_remaining, h_delay - sleep_time); + zassert_equal(h_delay, response.hibernate_delay, + "Hibernation delay %d != %d", + h_delay, response.hibernate_delay); + zassert_equal(0, system_hibernate_fake.call_count, + "system_hibernate() shouldn't be called before delay"); + + /* Wait to end of the hibenate delay */ + k_msleep((h_delay - sleep_time) * 1000); + + /* Get hibernate delay */ + params.seconds = 0; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + zassert_equal(h_delay, response.time_g3, + "Time from last G3 enter %d != %d", + response.time_g3, h_delay); + zassert_equal(0, response.time_remaining, + "Time to hibernation %d != 0", + response.time_remaining); + zassert_equal(h_delay, response.hibernate_delay, + "Hibernation delay %d != %d", + h_delay, response.hibernate_delay); + zassert_equal(1, system_hibernate_fake.call_count, + "system_hibernate() should be called after delay %d", + system_hibernate_fake.call_count); + + /* Wait some more time */ + k_msleep(2000); + + /* Get hibernate delay */ + params.seconds = 0; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + /* After hibernation, remaining time shouldn't be negative */ + zassert_equal(0, response.time_remaining, + "Time to hibernation %d != 0", + response.time_remaining); + + /* Enable AC */ + zassert_ok(gpio_emul_input_set(acok_dev, GPIO_ACOK_OD_PIN, 1), NULL); + msleep(CONFIG_EXTPOWER_DEBOUNCE_MS + 1); + zassert_equal(1, extpower_is_present(), NULL); + + /* Reset system_hibernate fake to check that it is not called on AC */ + RESET_FAKE(system_hibernate); + /* Allow chipset task to spin with enabled AC */ + task_wake(TASK_ID_CHIPSET); + k_msleep(1); + + /* Get hibernate delay */ + params.seconds = 0; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + zassert_equal(0, response.time_g3, + "Time from last G3 enter %d should be 0 on AC", + response.time_g3); + zassert_equal(0, system_hibernate_fake.call_count, + "system_hibernate() shouldn't be called on AC"); + + /* Disable AC */ + zassert_ok(gpio_emul_input_set(acok_dev, GPIO_ACOK_OD_PIN, 0), NULL); + msleep(CONFIG_EXTPOWER_DEBOUNCE_MS + 1); + zassert_equal(0, extpower_is_present(), NULL); + + /* Go to different state */ + force_power_state(true, POWER_G3S5); + zassert_equal(POWER_G3S5, power_get_state(), NULL); + + /* Stop forcing state */ + force_power_state(false, 0); + + /* Get hibernate delay */ + params.seconds = 0; + zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); + + zassert_equal(0, response.time_g3, + "Time from last G3 enter %d should be 0 on state != G3", + response.time_g3); +} + +/** Test setting hibernation delay through UART command */ +static void test_power_cmd_hibernation_delay(void) +{ + uint32_t h_delay; + int sleep_time; + + /* Test success on call without argument */ + zassert_equal(EC_SUCCESS, + shell_execute_cmd(shell_backend_uart_get_ptr(), + "hibdelay"), NULL); + + /* Test error on hibernation delay argument that is not a number */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(shell_backend_uart_get_ptr(), + "hibdelay test1"), NULL); + + /* Set hibernate delay */ + h_delay = 3; + zassert_equal(EC_SUCCESS, + shell_execute_cmd(shell_backend_uart_get_ptr(), + "hibdelay 3"), NULL); + + /* Kick chipset task to process new hibernation delay */ + task_wake(TASK_ID_CHIPSET); + /* Wait some arbitrary time less than hibernate delay */ + sleep_time = 2; + k_msleep(sleep_time * 1000); + + zassert_equal(0, system_hibernate_fake.call_count, + "system_hibernate() shouldn't be called before delay"); + + /* Wait to end of the hibenate delay */ + k_msleep((h_delay - sleep_time) * 1000); + + zassert_equal(1, system_hibernate_fake.call_count, + "system_hibernate() should be called after delay %d", + system_hibernate_fake.call_count); +} + +void test_suite_power_common(void) +{ + ztest_test_suite(power_common, + ztest_unit_test(test_power_chipset_in_state), + ztest_unit_test( + test_power_chipset_in_or_transitioning_to_state), + ztest_unit_test(test_power_exit_hard_off), + ztest_unit_test(test_power_reboot_ap_at_g3), + ztest_unit_test(test_power_hc_smart_discharge), + ztest_unit_test(test_power_board_system_is_idle), + ztest_unit_test_setup_teardown( + test_power_hc_hibernation_delay, + setup_hibernation_delay, unit_test_noop), + ztest_unit_test_setup_teardown( + test_power_cmd_hibernation_delay, + setup_hibernation_delay, unit_test_noop)); + ztest_run_test_suite(power_common); +} diff --git a/zephyr/test/drivers/src/ppc.c b/zephyr/test/drivers/src/ppc.c index 740c7a0aea..5a729de3d6 100644 --- a/zephyr/test/drivers/src/ppc.c +++ b/zephyr/test/drivers/src/ppc.c @@ -23,6 +23,109 @@ static const int syv682x_port = 1; +static void check_control_1_default_init(uint8_t control_1) +{ + /* + * During init, when not in dead battery mode, the driver should + * configure the high-voltage channel as sink but leave the power path + * disabled. The driver should set the current limits according to + * configuration. + */ + int ilim; + + zassert_true(control_1 & SYV682X_CONTROL_1_PWR_ENB, + "Default init, but power path enabled"); + ilim = (control_1 & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT; + zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM, + "Default init, but HV current limit set to %d", ilim); + zassert_false(control_1 & SYV682X_CONTROL_1_HV_DR, + "Default init, but source mode selected"); + zassert_true(control_1 & SYV682X_CONTROL_1_CH_SEL, + "Default init, but 5V power path selected"); +} + +static void test_ppc_syv682x_init(void) +{ + struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); + const struct device *gpio_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_USB_C1_FRS_EN_PATH, gpios)); + uint8_t reg; + int ilim; + + /* + * With a dead battery, the device powers up sinking VBUS, and the + * driver should keep that going.. + */ + zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG, + SYV682X_CONTROL_1_CH_SEL), NULL); + syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_5V, + SYV682X_CONTROL_4_NONE); + zassert_ok(ppc_init(syv682x_port), "PPC init failed"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + NULL); + zassert_true(reg & SYV682X_CONTROL_1_CH_SEL, + "Dead battery init, but CH_SEL set to 5V power path"); + zassert_false(reg & + (SYV682X_CONTROL_1_PWR_ENB | SYV682X_CONTROL_1_HV_DR), + "Dead battery init, but CONTROL_1 is 0x%x", reg); + zassert_false(ppc_is_sourcing_vbus(syv682x_port), + "Dead battery init, but VBUS source enabled"); + + /* With VBUS at vSafe0V, init should set the default configuration. */ + zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG, + SYV682X_CONTROL_1_PWR_ENB), NULL); + syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_0V, + SYV682X_CONTROL_4_NONE); + zassert_ok(ppc_init(syv682x_port), "PPC init failed"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + NULL); + check_control_1_default_init(reg); + + /* With sink disabled, init should do the same thing. */ + zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG, + SYV682X_CONTROL_1_CH_SEL), NULL); + syv682x_emul_set_condition(emul, SYV682X_STATUS_VSAFE_0V, + SYV682X_CONTROL_4_NONE); + zassert_ok(ppc_init(syv682x_port), "PPC init failed"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + NULL); + check_control_1_default_init(reg); + + /* + * Any init sequence should also disable the FRS GPIO, set the 5V + * current limit according to configuration, set over-current, over- + * voltage, and discharge parameters appropriately, and enable CC lines. + */ + zassert_equal(gpio_emul_output_get(gpio_dev, GPIO_USB_C1_FRS_EN_PORT), + 0, "FRS enabled, but FRS GPIO not asserted"); + ilim = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT; + zassert_equal(ilim, CONFIG_PLATFORM_EC_USB_PD_PULLUP, + "Default init, but 5V current limit set to %d", ilim); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, ®), + NULL); + zassert_equal(reg, (SYV682X_OC_DELAY_10MS << SYV682X_OC_DELAY_SHIFT) | + (SYV682X_DSG_RON_200_OHM << SYV682X_DSG_RON_SHIFT) | + (SYV682X_DSG_TIME_50MS << SYV682X_DSG_TIME_SHIFT), + "Default init, but CONTROL_2 is 0x%x", reg); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_3_REG, ®), + NULL); + zassert_equal(reg, (SYV682X_OVP_23_7 << SYV682X_OVP_BIT_SHIFT) | + SYV682X_RVS_MASK, + "Default init, but CONTROL_3 is 0x%x", reg); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), + NULL); + zassert_equal(reg & ~SYV682X_CONTROL_4_INT_MASK, + SYV682X_CONTROL_4_CC1_BPS | SYV682X_CONTROL_4_CC2_BPS, + "Default init, but CONTROL_4 is 0x%x", reg); + + /* Disable the power path again. */ + zassert_ok(syv682x_emul_set_reg(emul, SYV682X_CONTROL_1_REG, + SYV682X_CONTROL_1_PWR_ENB), NULL); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); + +} + static void test_ppc_syv682x_vbus_enable(void) { struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); @@ -51,21 +154,18 @@ static void test_ppc_syv682x_interrupt(void) uint8_t reg; /* An OC event less than 100 ms should not cause VBUS to turn off. */ - syv682x_emul_set_status(emul, SYV682X_STATUS_OC_5V); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_5V, + SYV682X_CONTROL_4_NONE); msleep(50); - syv682x_interrupt(syv682x_port); zassert_true(ppc_is_sourcing_vbus(syv682x_port), "PPC is not sourcing VBUS after 50 ms OC"); /* But one greater than 100 ms should. */ - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ msleep(60); - syv682x_interrupt(syv682x_port); zassert_false(ppc_is_sourcing_vbus(syv682x_port), "PPC is sourcing VBUS after 100 ms OC"); - syv682x_emul_set_status(emul, 0x0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); /* * TODO(b/190519131): Organize the tests to be more hermetic and avoid * the following issue: The driver triggers overcurrent protection. If @@ -81,24 +181,24 @@ static void test_ppc_syv682x_interrupt(void) */ zassert_ok(ppc_vbus_source_enable(syv682x_port, true), "Source enable failed"); - syv682x_emul_set_status(emul, SYV682X_STATUS_TSD); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_TSD, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_false(ppc_is_sourcing_vbus(syv682x_port), "PPC is sourcing power after TSD"); - syv682x_emul_set_status(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); /* An OVP event should cause the driver to disable the source path. */ zassert_ok(ppc_vbus_source_enable(syv682x_port, true), "Source enable failed"); - syv682x_emul_set_status(emul, SYV682X_STATUS_OVP); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_OVP, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_false(ppc_is_sourcing_vbus(syv682x_port), "PPC is sourcing power after OVP"); - syv682x_emul_set_status(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); /* * A high-voltage OC while sinking should cause the driver to try to @@ -107,52 +207,45 @@ static void test_ppc_syv682x_interrupt(void) */ zassert_ok(ppc_vbus_sink_enable(syv682x_port, true), "Sink enable failed"); - syv682x_emul_set_status(emul, SYV682X_STATUS_OC_HV); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), "Reading CONTROL_1 failed"); zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0, "Power path disabled after HV_OC handled"); - syv682x_emul_set_status(emul, SYV682X_STATUS_OC_HV); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), "Reading CONTROL_1 failed"); zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, 0, "Power path disabled after HV_OC handled"); - syv682x_emul_set_status(emul, SYV682X_STATUS_OC_HV); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_OC_HV, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), "Reading CONTROL_1 failed"); zassert_equal(reg & SYV682X_CONTROL_1_PWR_ENB, SYV682X_CONTROL_1_PWR_ENB, "Power path enabled after HV_OC handled 3 times"); - syv682x_emul_set_status(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); /* * A VCONN OC event less than 100 ms should not cause the driver to turn * VCONN off. */ ppc_set_vconn(syv682x_port, true); - syv682x_emul_set_control_4(emul, SYV682X_CONTROL_4_VCONN_OCP); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_VCONN_OCP); msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), "Reading CONTROL_4 failed"); zassert_true(reg & (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2), "VCONN disabled after initial VCONN OC"); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ msleep(50); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ - msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), "Reading CONTROL_4 failed"); zassert_true(reg & @@ -162,17 +255,14 @@ static void test_ppc_syv682x_interrupt(void) * But if the event keeps going for over 100 ms continuously, the driver * should turn VCONN off. */ - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ msleep(60); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ - msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), "Reading CONTROL_4 failed"); zassert_false(reg & (SYV682X_CONTROL_4_VCONN1 | SYV682X_CONTROL_4_VCONN2), "VCONN enabled after long VCONN OC"); - syv682x_emul_set_control_4(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); /* * A VCONN over-voltage (VBAT_OVP) event will cause the device to @@ -181,9 +271,8 @@ static void test_ppc_syv682x_interrupt(void) * driver should then run generic CC over-voltage handling. */ ppc_set_vconn(syv682x_port, true); - syv682x_emul_set_control_4(emul, SYV682X_CONTROL_4_VBAT_OVP); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_VBAT_OVP); msleep(1); zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_4_REG, ®), "Reading CONTROL_4 failed"); @@ -199,7 +288,8 @@ static void test_ppc_syv682x_interrupt(void) * to a CC over-voltage event. There is currently no easy way to test * that a Hard Reset occurred. */ - syv682x_emul_set_control_4(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); } static void test_ppc_syv682x_frs(void) @@ -252,23 +342,167 @@ static void test_ppc_syv682x_frs(void) * An FRS event when the PPC is Sink should cause the PPC to switch from * Sink to Source. */ - syv682x_emul_set_status(emul, SYV682X_STATUS_FRS); - syv682x_interrupt(syv682x_port); - /* TODO(b/201420132): Simulate passage of time instead of sleeping. */ + syv682x_emul_set_condition(emul, SYV682X_STATUS_FRS, + SYV682X_CONTROL_4_NONE); msleep(1); zassert_true(ppc_is_sourcing_vbus(syv682x_port), "PPC is not sourcing VBUS after FRS signal handled"); - syv682x_emul_set_status(emul, 0); + syv682x_emul_set_condition(emul, SYV682X_STATUS_NONE, + SYV682X_CONTROL_4_NONE); +} + +static void test_ppc_syv682x_source_current_limit(void) +{ + struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); + uint8_t reg; + int ilim_val; + + zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port, + TYPEC_RP_USB), + "Could not set source current limit"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + "Reading CONTROL_1 failed"); + ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT; + zassert_equal(reg & SYV682X_5V_ILIM_MASK, SYV682X_5V_ILIM_1_25, + "Set USB Rp value, but 5V_ILIM is %d", ilim_val); + + zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port, + TYPEC_RP_1A5), + "Could not set source current limit"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + "Reading CONTROL_1 failed"); + ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT; + zassert_equal(ilim_val, SYV682X_5V_ILIM_1_75, + "Set 1.5A Rp value, but 5V_ILIM is %d", ilim_val); + zassert_ok(ppc_set_vbus_source_current_limit(syv682x_port, + TYPEC_RP_3A0), + "Could not set source current limit"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + "Reading CONTROL_1 failed"); + ilim_val = (reg & SYV682X_5V_ILIM_MASK) >> SYV682X_5V_ILIM_BIT_SHIFT; + zassert_equal(ilim_val, SYV682X_5V_ILIM_3_30, + "Set 3.0A Rp value, but 5V_ILIM is %d", ilim_val); } -static void test_ppc_syv682x(void) +static void test_ppc_syv682x_write_busy(void) { - zassert_ok(ppc_init(syv682x_port), "PPC init failed"); + struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); + + /* + * Writes should fail while the BUSY bit is set, except that writes to + * CONTROL_4 should succeed on the SYV682C. 100 reads is intentionally + * many more than the driver is expected to make before reaching its + * timeout. It is not a goal of this test to verify the frequency of + * polling or the exact value of the timeout. + */ + syv682x_emul_set_busy_reads(emul, 100); + zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port, + TYPEC_RP_USB), + EC_ERROR_TIMEOUT, "SYV682 busy, but write completed"); + zassert_ok(ppc_set_frs_enable(syv682x_port, false), + "Could not set CONTROL_4 while busy on SYV682C"); + + /* + * If the busy bit clears before the driver reaches its timeout, the + * write should succeed. + */ + syv682x_emul_set_busy_reads(emul, 1); + zassert_equal(ppc_set_vbus_source_current_limit(syv682x_port, + TYPEC_RP_USB), 0, + "SYV682 not busy, but write failed"); + + syv682x_emul_set_busy_reads(emul, 0); +} + +static void test_ppc_syv682x_dev_is_connected(void) +{ + struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); + uint8_t reg; + + zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SRC), + "Could not connect device as source"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, ®), + "Reading CONTROL_2 failed"); + zassert_false(reg & SYV682X_CONTROL_2_FDSG, + "Connected as source, but force discharge enabled"); + + zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_DISCONNECTED), + "Could not disconnect device"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_2_REG, ®), + "Reading CONTROL_2 failed"); + zassert_true(reg & SYV682X_CONTROL_2_FDSG, + "Disconnected, but force discharge disabled"); + + zassert_ok(ppc_dev_is_connected(syv682x_port, PPC_DEV_SNK), + "Could not connect device as source"); +} + +static void test_ppc_syv682x_vbus_sink_enable(void) +{ + struct i2c_emul *emul = syv682x_emul_get(SYV682X_ORD); + uint8_t reg; + int ilim; + + /* + * If VBUS source is already enabled, disabling VBUS sink should + * trivially succeed. + */ + zassert_ok(ppc_vbus_source_enable(syv682x_port, true), + "VBUS enable failed"); + zassert_ok(ppc_vbus_sink_enable(syv682x_port, false), + "Sink disable failed"); + + /* + * After enabling VBUS sink, the HV power path should be enabled in sink + * mode with the configured current limit. + */ + zassert_ok(ppc_vbus_source_enable(syv682x_port, false), + "VBUS enable failed"); + zassert_ok(ppc_vbus_sink_enable(syv682x_port, true), + "Sink disable failed"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + NULL); + zassert_true(reg & SYV682X_CONTROL_1_CH_SEL, + "Sink enabled, but CH_SEL set to 5V power path"); + zassert_false(reg & SYV682X_CONTROL_1_PWR_ENB, + "Sink enabled, but power path disabled"); + zassert_false(reg & SYV682X_CONTROL_1_HV_DR, + "Sink enabled, but high-voltage path in source mode"); + ilim = (reg & SYV682X_HV_ILIM_MASK) >> SYV682X_HV_ILIM_BIT_SHIFT; + zassert_equal(ilim, CONFIG_PLATFORM_EC_USBC_PPC_SYV682X_HV_ILIM, + "Sink enabled, but HV current limit set to %d", ilim); + zassert_ok(ppc_vbus_sink_enable(syv682x_port, false), + "Sink disable failed"); + zassert_ok(syv682x_emul_get_reg(emul, SYV682X_CONTROL_1_REG, ®), + NULL); + zassert_true(reg & SYV682X_CONTROL_1_PWR_ENB, + "Sink disabled, but power path enabled"); +} + +static void test_ppc_syv682x_ppc_dump(void) +{ + /* + * The ppc_dump command should succeed for this port. Don't check the + * output, since there are no standard requirements for that. + */ + const struct ppc_drv *drv = ppc_chips[syv682x_port].drv; + + zassert_ok(drv->reg_dump(syv682x_port), "ppc_dump command failed"); +} + +static void test_ppc_syv682x(void) +{ + test_ppc_syv682x_init(); test_ppc_syv682x_vbus_enable(); test_ppc_syv682x_interrupt(); test_ppc_syv682x_frs(); + test_ppc_syv682x_source_current_limit(); + test_ppc_syv682x_write_busy(); + test_ppc_syv682x_dev_is_connected(); + test_ppc_syv682x_vbus_sink_enable(); + test_ppc_syv682x_ppc_dump(); } void test_suite_ppc(void) diff --git a/zephyr/test/drivers/src/ppc_sn5s330.c b/zephyr/test/drivers/src/ppc_sn5s330.c index 95556e28cf..429b9b8c26 100644 --- a/zephyr/test/drivers/src/ppc_sn5s330.c +++ b/zephyr/test/drivers/src/ppc_sn5s330.c @@ -3,10 +3,12 @@ * found in the LICENSE file. */ +#include <kernel.h> #include <device.h> #include <devicetree.h> #include <emul.h> #include <ztest.h> +#include <fff.h> #include "driver/ppc/sn5s330.h" #include "driver/ppc/sn5s330_public.h" @@ -17,12 +19,49 @@ /** This must match the index of the sn5s330 in ppc_chips[] */ #define SN5S330_PORT 0 #define EMUL emul_get_binding(DT_LABEL(DT_NODELABEL(sn5s330_emul))) +#define FUNC_SET1_ILIMPP1_MSK 0x1F +#define SN5S330_INTERRUPT_DELAYMS 15 + +FAKE_VOID_FUNC(sn5s330_emul_interrupt_set_stub); /* * TODO(b/203364783): Exclude other threads from interacting with the emulator * to avoid test flakiness */ +struct intercept_write_data { + int reg_to_intercept; + uint8_t val_intercepted; +}; + +struct intercept_read_data { + int reg_to_intercept; + bool replace_reg_val; + uint8_t replacement_val; +}; + +static int intercept_read_func(struct i2c_emul *emul, int reg, uint8_t *val, + int bytes, void *data) +{ + struct intercept_read_data *test_data = data; + + if (test_data->reg_to_intercept && test_data->replace_reg_val) + *val = test_data->replacement_val; + + return EC_SUCCESS; +} + +static int intercept_write_func(struct i2c_emul *emul, int reg, uint8_t val, + int bytes, void *data) +{ + struct intercept_write_data *test_data = data; + + if (test_data->reg_to_intercept == reg) + test_data->val_intercepted = val; + + return 1; +} + static int fail_until_write_func(struct i2c_emul *emul, int reg, uint8_t val, int bytes, void *data) { @@ -40,29 +79,300 @@ static void test_fail_once_func_set1(void) const struct emul *emul = EMUL; struct i2c_emul *i2c_emul = sn5s330_emul_to_i2c_emul(emul); uint32_t count = 1; - uint32_t func_set1_value; + uint8_t func_set1_value; i2c_common_emul_set_write_func(i2c_emul, fail_until_write_func, &count); zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); zassert_equal(count, 0, NULL); - zassert_ok(sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, - &func_set1_value), - NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, &func_set1_value); zassert_true((func_set1_value & SN5S330_ILIM_1_62) != 0, NULL); i2c_common_emul_set_write_func(i2c_emul, NULL, NULL); } +static void test_dead_battery_boot_force_pp2_fets_set(void) +{ + const struct emul *emul = EMUL; + struct i2c_emul *i2c_emul = sn5s330_emul_to_i2c_emul(emul); + struct intercept_write_data test_write_data = { + .reg_to_intercept = SN5S330_FUNC_SET3, + .val_intercepted = 0, + }; + struct intercept_read_data test_read_data = { + .reg_to_intercept = SN5S330_INT_STATUS_REG4, + .replace_reg_val = true, + .replacement_val = SN5S330_DB_BOOT, + }; + + i2c_common_emul_set_write_func(i2c_emul, intercept_write_func, + &test_write_data); + i2c_common_emul_set_read_func(i2c_emul, intercept_read_func, + &test_read_data); + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + /* + * Although the device enables PP2_FET on dead battery boot by setting + * the PP2_EN bit, the driver also force sets this bit during dead + * battery boot by writing that bit to the FUNC_SET3 reg. + * + * TODO(b/207034759): Verify need or remove redundant PP2 set. + */ + zassert_true(test_write_data.val_intercepted & SN5S330_PP2_EN, NULL); + zassert_false(sn5s330_drv.is_sourcing_vbus(SN5S330_PORT), NULL); +} + +static void test_enter_low_power_mode(void) +{ + const struct emul *emul = EMUL; + + uint8_t func_set2_reg; + uint8_t func_set3_reg; + uint8_t func_set4_reg; + uint8_t func_set9_reg; + + /* + * Requirements were extracted from TI's recommended changes for octopus + * to lower power use during hibernate as well as the follow up changes + * we made to allow the device to wake up from hibernate. + * + * For Reference: b/111006203#comment35 + */ + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + zassert_ok(sn5s330_drv.enter_low_power_mode(SN5S330_PORT), NULL); + + /* 1) Verify VBUS power paths are off */ + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_equal(func_set3_reg & SN5S330_PP1_EN, 0, NULL); + zassert_equal(func_set3_reg & SN5S330_PP2_EN, 0, NULL); + + /* 2) Verify VCONN power path is off */ + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET4, &func_set4_reg); + zassert_not_equal(func_set4_reg & SN5S330_CC_EN, 0, NULL); + zassert_equal(func_set4_reg & SN5S330_VCONN_EN, 0, NULL); + + /* 3) Verify SBU FET is off */ + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET2, &func_set2_reg); + zassert_equal(func_set2_reg & SN5S330_SBU_EN, 0, NULL); + + /* 4) Verify VBUS and SBU OVP comparators are off */ + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET9, &func_set9_reg); + zassert_equal(func_set9_reg & SN5S330_FORCE_OVP_EN_SBU, 0, NULL); + zassert_equal(func_set9_reg & SN5S330_PWR_OVR_VBUS, 0, NULL); + zassert_not_equal(func_set9_reg & SN5S330_OVP_EN_CC, 0, NULL); + zassert_equal(func_set9_reg & SN5S330_FORCE_ON_VBUS_OVP, 0, NULL); + zassert_equal(func_set9_reg & SN5S330_FORCE_ON_VBUS_UVP, 0, NULL); +} + +static void test_vbus_source_sink_enable(void) +{ + const struct emul *emul = EMUL; + uint8_t func_set3_reg; + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + /* Test enable/disable VBUS source FET */ + zassert_ok(sn5s330_drv.vbus_source_enable(SN5S330_PORT, true), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_not_equal(func_set3_reg & SN5S330_PP1_EN, 0, NULL); + + zassert_ok(sn5s330_drv.vbus_source_enable(SN5S330_PORT, false), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_equal(func_set3_reg & SN5S330_PP1_EN, 0, NULL); + + /* Test enable/disable VBUS sink FET */ + zassert_ok(sn5s330_drv.vbus_sink_enable(SN5S330_PORT, true), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_not_equal(func_set3_reg & SN5S330_PP2_EN, 0, NULL); + + zassert_ok(sn5s330_drv.vbus_sink_enable(SN5S330_PORT, false), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_equal(func_set3_reg & SN5S330_PP2_EN, 0, NULL); +} + +static void test_vbus_discharge(void) +{ + const struct emul *emul = EMUL; + uint8_t func_set3_reg; + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + /* Test enable/disable VBUS discharging */ + zassert_ok(sn5s330_drv.discharge_vbus(SN5S330_PORT, true), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_not_equal(func_set3_reg & SN5S330_VBUS_DISCH_EN, 0, NULL); + + zassert_ok(sn5s330_drv.discharge_vbus(SN5S330_PORT, false), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET3, &func_set3_reg); + zassert_equal(func_set3_reg & SN5S330_VBUS_DISCH_EN, 0, NULL); +} + +static void test_set_vbus_source_current_limit(void) +{ + const struct emul *emul = EMUL; + uint8_t func_set1_reg; + + /* Test every TCPC Pull Resistance Value */ + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + /* USB */ + zassert_ok(sn5s330_drv.set_vbus_source_current_limit(SN5S330_PORT, + TYPEC_RP_USB), + NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, &func_set1_reg); + zassert_equal(func_set1_reg & FUNC_SET1_ILIMPP1_MSK, SN5S330_ILIM_0_63, + NULL); + + /* 1.5A */ + zassert_ok(sn5s330_drv.set_vbus_source_current_limit(SN5S330_PORT, + TYPEC_RP_1A5), + NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, &func_set1_reg); + zassert_equal(func_set1_reg & FUNC_SET1_ILIMPP1_MSK, SN5S330_ILIM_1_62, + NULL); + + /* 3.0A */ + zassert_ok(sn5s330_drv.set_vbus_source_current_limit(SN5S330_PORT, + TYPEC_RP_3A0), + NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, &func_set1_reg); + zassert_equal(func_set1_reg & FUNC_SET1_ILIMPP1_MSK, SN5S330_ILIM_3_06, + NULL); + + /* Unknown/Reserved - We set result as USB */ + zassert_ok(sn5s330_drv.set_vbus_source_current_limit(SN5S330_PORT, + TYPEC_RP_RESERVED), + NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1, &func_set1_reg); + zassert_equal(func_set1_reg & FUNC_SET1_ILIMPP1_MSK, SN5S330_ILIM_0_63, + NULL); +} + +static void test_sn5s330_set_sbu(void) +#ifdef CONFIG_USBC_PPC_SBU +{ + const struct emul *emul = EMUL; + uint8_t func_set2_reg; + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + /* Verify driver enables SBU FET */ + zassert_ok(sn5s330_drv.set_sbu(SN5S330_PORT, true), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET2, &func_set2_reg); + zassert_not_equal(func_set2_reg & SN5S330_SBU_EN, 0, NULL); + + /* Verify driver disables SBU FET */ + zassert_ok(sn5s330_drv.set_sbu(SN5S330_PORT, false), NULL); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET2, &func_set2_reg); + zassert_equal(func_set2_reg & SN5S330_SBU_EN, 0, NULL); +} +#else +{ + ztest_test_skip(); +} +#endif /* CONFIG_USBC_PPC_SBU */ + +static void test_sn5s330_vbus_overcurrent(void) +{ + const struct emul *emul = EMUL; + uint8_t int_trip_rise_reg1; + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + sn5s330_emul_make_vbus_overcurrent(emul); + /* + * TODO(b/201420132): Replace arbitrary sleeps. + */ + /* Make sure interrupt happens first. */ + k_msleep(SN5S330_INTERRUPT_DELAYMS); + zassert_true(sn5s330_emul_interrupt_set_stub_fake.call_count > 0, NULL); + + /* + * Verify we cleared vbus overcurrent interrupt trip rise bit so the + * driver can detect future overcurrent clamping interrupts. + */ + sn5s330_emul_peek_reg(emul, SN5S330_INT_TRIP_RISE_REG1, + &int_trip_rise_reg1); + zassert_equal(int_trip_rise_reg1 & SN5S330_ILIM_PP1_MASK, 0, NULL); +} + +static void test_sn5s330_disable_vbus_low_interrupt(void) +#ifdef CONFIG_USBC_PPC_VCONN +{ + const struct emul *emul = EMUL; + + /* Interrupt disabled here */ + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + /* Would normally cause a vbus low interrupt */ + sn5s330_emul_lower_vbus_below_minv(emul); + zassert_equal(sn5s330_emul_interrupt_set_stub_fake.call_count, 0, NULL); +} +#else +{ + ztest_test_skip(); +} +#endif /* CONFIG_USBC_PPC_VCONN */ + +static void test_sn5s330_set_vconn_fet(void) +{ + const struct emul *emul = EMUL; + uint8_t func_set4_reg; + + zassert_ok(sn5s330_drv.init(SN5S330_PORT), NULL); + + sn5s330_drv.set_vconn(SN5S330_PORT, false); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET4, &func_set4_reg); + zassert_equal(func_set4_reg & SN5S330_VCONN_EN, 0, NULL); + + sn5s330_drv.set_vconn(SN5S330_PORT, true); + sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET4, &func_set4_reg); + zassert_not_equal(func_set4_reg & SN5S330_VCONN_EN, 0, NULL); +} + static void reset_sn5s330_state(void) { + struct i2c_emul *i2c_emul = sn5s330_emul_to_i2c_emul(EMUL); + + i2c_common_emul_set_write_func(i2c_emul, NULL, NULL); + i2c_common_emul_set_read_func(i2c_emul, NULL, NULL); sn5s330_emul_reset(EMUL); + RESET_FAKE(sn5s330_emul_interrupt_set_stub); } void test_suite_ppc_sn5s330(void) { - ztest_test_suite(ppc_sn5s330, - ztest_unit_test_setup_teardown( - test_fail_once_func_set1, reset_sn5s330_state, - reset_sn5s330_state)); + ztest_test_suite( + ppc_sn5s330, + ztest_unit_test_setup_teardown(test_sn5s330_set_vconn_fet, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown( + test_sn5s330_disable_vbus_low_interrupt, + reset_sn5s330_state, reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_sn5s330_vbus_overcurrent, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_sn5s330_set_sbu, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown( + test_set_vbus_source_current_limit, reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_vbus_discharge, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_vbus_source_sink_enable, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_enter_low_power_mode, + reset_sn5s330_state, + reset_sn5s330_state), + ztest_unit_test_setup_teardown( + test_dead_battery_boot_force_pp2_fets_set, + reset_sn5s330_state, reset_sn5s330_state), + ztest_unit_test_setup_teardown(test_fail_once_func_set1, + reset_sn5s330_state, + reset_sn5s330_state)); ztest_run_test_suite(ppc_sn5s330); } diff --git a/zephyr/test/drivers/src/ps8xxx.c b/zephyr/test/drivers/src/ps8xxx.c index 790eebf2db..a2052b43fc 100644 --- a/zephyr/test/drivers/src/ps8xxx.c +++ b/zephyr/test/drivers/src/ps8xxx.c @@ -8,8 +8,8 @@ #include "common.h" #include "emul/emul_common_i2c.h" -#include "emul/emul_tcpci.h" -#include "emul/emul_ps8xxx.h" +#include "emul/tcpc/emul_tcpci.h" +#include "emul/tcpc/emul_ps8xxx.h" #include "timer.h" #include "i2c.h" #include "stubs.h" @@ -911,7 +911,14 @@ static void test_ps8xxx_tcpci_low_power_mode(void) { const struct emul *ps8xxx_emul = emul_get_binding(PS8XXX_EMUL_LABEL); const struct emul *tcpci_emul = ps8xxx_emul_get_tcpci(ps8xxx_emul); - + /* + * PS8751/PS8815 has the auto sleep function that enters + * low power mode on its own in ~2 seconds. Other chips + * don't have it. Stub it out for PS8751/PS8815. + */ + if (board_get_ps8xxx_product_id(USBC_PORT_C1) == PS8751_PRODUCT_ID || + board_get_ps8xxx_product_id(USBC_PORT_C1) == PS8815_PRODUCT_ID) + return; test_tcpci_low_power_mode(tcpci_emul, USBC_PORT_C1); } diff --git a/zephyr/test/drivers/src/stubs.c b/zephyr/test/drivers/src/stubs.c index 68aab8ba12..85c528a5bd 100644 --- a/zephyr/test/drivers/src/stubs.c +++ b/zephyr/test/drivers/src/stubs.c @@ -11,6 +11,7 @@ #include "charger/isl923x_public.h" #include "charger/isl9241_public.h" #include "config.h" +#include "fff.h" #include "hooks.h" #include "i2c/i2c.h" #include "power.h" @@ -23,6 +24,13 @@ #include "usb_mux.h" #include "usb_pd_tcpm.h" #include "usbc_ppc.h" +#include "charge_state_v2.h" + +#include <logging/log.h> +LOG_MODULE_REGISTER(stubs); + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) /* All of these definitions are just to get the test to link. None of these * functions are useful or behave as they should. Please remove them once the @@ -105,6 +113,56 @@ const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_LGC011; int board_set_active_charge_port(int port) { + int is_real_port = (port >= 0 && + port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + if (port == CHARGE_PORT_NONE) { + CPRINTS("Disabling all charging port"); + + /* Disable all ports. */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + /* + * Do not return early if one fails otherwise we can + * get into a boot loop assertion failure. + */ + if (board_vbus_sink_enable(i, 0)) + CPRINTS("Disabling p%d sink path failed.", i); + } + + return EC_SUCCESS; + } + + /* Check if the port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + CPRINTS("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + + CPRINTS("New charge port: p%d", port); + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (board_vbus_sink_enable(i, 0)) + CPRINTS("p%d: sink path disable failed.", i); + } + + /* Enable requested charge port. */ + if (board_vbus_sink_enable(port, 1)) { + CPRINTS("p%d: sink path enable failed.", port); + return EC_ERROR_UNKNOWN; + } + return EC_SUCCESS; } @@ -116,6 +174,8 @@ int board_is_vbus_too_low(int port, enum chg_ramp_vbus_state ramp_state) void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, int charge_mv) { + charge_set_input_current_limit( + MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); } struct tcpc_config_t tcpc_config[] = { @@ -156,9 +216,16 @@ void board_set_ps8xxx_product_id(uint16_t product_id) ps8xxx_product_id = product_id; } +int board_vbus_sink_enable(int port, int enable) +{ + /* Both ports are controlled by PPC SN5S330 */ + return ppc_vbus_sink_enable(port, enable); +} + int board_is_sourcing_vbus(int port) { - return 0; + /* Both ports are controlled by PPC SN5S330 */ + return ppc_is_sourcing_vbus(port); } struct usb_mux usbc0_virtual_usb_mux = { @@ -235,9 +302,7 @@ struct ppc_config_t ppc_chips[] = { BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT); unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); -void system_hibernate(uint32_t seconds, uint32_t microseconds) -{ -} +DEFINE_FAKE_VOID_FUNC(system_hibernate, uint32_t, uint32_t); uint16_t tcpc_get_alert_status(void) { @@ -265,17 +330,53 @@ enum power_state power_chipset_init(void) return POWER_G3; } -enum power_state mock_state = POWER_G3; +static enum power_state forced_state; +static bool force_state; -void set_mock_power_state(enum power_state state) +void force_power_state(bool force, enum power_state state) { - mock_state = state; - task_wake(TASK_ID_CHIPSET); + forced_state = state; + force_state = force; + + if (force) { + task_wake(TASK_ID_CHIPSET); + /* + * TODO(b/201420132) - setting power state requires to wake up + * TASK_ID_CHIPSET Sleep is required to run chipset task before + * continuing with test + */ + k_msleep(1); + } } enum power_state power_handle_state(enum power_state state) { - return mock_state; + switch (state) { + case POWER_G3S5: + case POWER_S5S3: + case POWER_S3S0: + case POWER_S0S3: + case POWER_S3S5: + case POWER_S5G3: +#ifdef CONFIG_POWER_S0IX + case POWER_S0ixS0: + case POWER_S0S0ix: +#endif + /* + * Wait for event in transition states to prevent dead loop in + * chipset task + */ + task_wait_event(-1); + break; + default: + break; + } + + if (force_state) { + state = forced_state; + } + + return state; } void chipset_reset(enum chipset_shutdown_reason reason) @@ -307,10 +408,24 @@ void tcpc_alert_event(enum gpio_signal signal) schedule_deferred_pd_interrupt(port); } +void ppc_alert(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_USB_C0_PPC_INT_ODL: + ppc_chips[USBC_PORT_C0].drv->interrupt(USBC_PORT_C0); + break; + case GPIO_USB_C1_PPC_INT_ODL: + ppc_chips[USBC_PORT_C1].drv->interrupt(USBC_PORT_C1); + break; + default: + return; + } +} + /* TODO: This code should really be generic, and run based on something in * the dts. */ -static void usbc_interrupt_init(void) +static void stubs_interrupt_init(void) { /* Enable TCPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL); @@ -328,5 +443,12 @@ static void usbc_interrupt_init(void) gpio_set_level(GPIO_USB_C1_TCPC_RST_L, 0); msleep(PS8XXX_RESET_DELAY_MS); gpio_set_level(GPIO_USB_C1_TCPC_RST_L, 1); + + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PPC_INT_ODL); + + /* Enable SwitchCap interrupt */ + gpio_enable_interrupt(GPIO_SWITCHCAP_PG_INT_L); } -DECLARE_HOOK(HOOK_INIT, usbc_interrupt_init, HOOK_PRIO_INIT_I2C + 1); +DECLARE_HOOK(HOOK_INIT, stubs_interrupt_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/zephyr/test/drivers/src/tcpci.c b/zephyr/test/drivers/src/tcpci.c index d67680bacc..cdc13861ab 100644 --- a/zephyr/test/drivers/src/tcpci.c +++ b/zephyr/test/drivers/src/tcpci.c @@ -11,7 +11,7 @@ #include "common.h" #include "ec_tasks.h" #include "emul/emul_common_i2c.h" -#include "emul/emul_tcpci.h" +#include "emul/tcpc/emul_tcpci.h" #include "hooks.h" #include "i2c.h" #include "stubs.h" @@ -295,8 +295,9 @@ static void test_generic_tcpci_mux_init(void) zassert_equal(EC_ERROR_TIMEOUT, tcpci_tcpm_mux_init(tcpci_usb_mux), NULL); - /* Set correct power status for rest of the test */ - tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, 0); + /* Set default power status for rest of the test */ + tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, + TCPC_REG_POWER_STATUS_VBUS_DET); /* Test fail on alert mask write fail */ i2c_common_emul_set_write_fail_reg(i2c_emul, TCPC_REG_ALERT_MASK); diff --git a/zephyr/test/drivers/src/tcpci_test_common.c b/zephyr/test/drivers/src/tcpci_test_common.c index 57cc35b89c..a2925bf3be 100644 --- a/zephyr/test/drivers/src/tcpci_test_common.c +++ b/zephyr/test/drivers/src/tcpci_test_common.c @@ -8,7 +8,7 @@ #include "common.h" #include "emul/emul_common_i2c.h" -#include "emul/emul_tcpci.h" +#include "emul/tcpc/emul_tcpci.h" #include "tcpci_test_common.h" #include "tcpm/tcpci.h" @@ -57,7 +57,8 @@ void test_tcpci_init(const struct emul *emul, enum usbc_port port) TCPC_REG_ALERT_FAULT | TCPC_REG_ALERT_POWER_STATUS; /* Set TCPCI emulator VBUS to safe0v (disconnected) */ - tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, 0); + tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, + TCPC_REG_POWER_STATUS_VBUS_DET); /* Test init with VBUS safe0v without vSafe0V tcpc config flag */ zassert_equal(EC_SUCCESS, drv->init(port), NULL); @@ -69,7 +70,8 @@ void test_tcpci_init(const struct emul *emul, enum usbc_port port) /* Set TCPCI emulator VBUS to present (connected, above 4V) */ tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, - TCPC_REG_POWER_STATUS_VBUS_PRES); + TCPC_REG_POWER_STATUS_VBUS_PRES | + TCPC_REG_POWER_STATUS_VBUS_DET); /* Test init with VBUS present without vSafe0V tcpc config flag */ zassert_equal(EC_SUCCESS, drv->init(port), NULL); @@ -92,7 +94,8 @@ void test_tcpci_init(const struct emul *emul, enum usbc_port port) check_tcpci_reg(emul, TCPC_REG_ALERT_MASK, exp_mask); /* Set TCPCI emulator VBUS to safe0v (disconnected) */ - tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, 0); + tcpci_emul_set_reg(emul, TCPC_REG_POWER_STATUS, + TCPC_REG_POWER_STATUS_VBUS_DET); tcpci_emul_set_reg(emul, TCPC_REG_EXT_STATUS, TCPC_REG_EXT_STATUS_SAFE0V); diff --git a/zephyr/test/drivers/src/usb_mux.c b/zephyr/test/drivers/src/usb_mux.c index cf6190eec9..517bb59107 100644 --- a/zephyr/test/drivers/src/usb_mux.c +++ b/zephyr/test/drivers/src/usb_mux.c @@ -14,6 +14,7 @@ #include "common.h" #include "ec_commands.h" #include "ec_tasks.h" +#include "fff.h" #include "hooks.h" #include "host_command.h" #include "i2c.h" @@ -27,86 +28,151 @@ /** Copy of original usb_muxes[USB_PORT_C1] */ struct usb_mux usb_mux_c1; +/** Number of usb mux proxies in chain */ +#define NUM_OF_PROXY 3 + /** Pointers to original usb muxes chain of port c1 */ -const struct usb_mux *org_mux[3]; +const struct usb_mux *org_mux[NUM_OF_PROXY]; /** Proxy function which check calls from usb_mux framework to driver */ -static int proxy_init(const struct usb_mux *me) +FAKE_VALUE_FUNC1(int, proxy_init, const struct usb_mux *); +static int proxy_init_custom(const struct usb_mux *me) { int i = me->i2c_addr_flags; + int ec = EC_SUCCESS; - ztest_check_expected_value(i); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->driver->init != NULL) { - org_mux[i]->driver->init(org_mux[i]); + ec = org_mux[i]->driver->init(org_mux[i]); + } + + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(proxy_init); } - return ztest_get_return_value(); + /* Discard this call if made from different thread */ + proxy_init_fake.call_count--; + + return ec; } /** Proxy function which check calls from usb_mux framework to driver */ -static int proxy_set(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) +FAKE_VALUE_FUNC3(int, proxy_set, const struct usb_mux *, mux_state_t, bool *); +static int proxy_set_custom(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { int i = me->i2c_addr_flags; + int ec = EC_SUCCESS; - ztest_check_expected_value(i); - ztest_check_expected_value(mux_state); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->driver->set != NULL) { - org_mux[i]->driver->set(org_mux[i], mux_state, ack_required); + ec = org_mux[i]->driver->set(org_mux[i], mux_state, + ack_required); } - return ztest_get_return_value(); + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(proxy_set); + } + + /* Discard this call if made from different thread */ + proxy_set_fake.call_count--; + + return ec; } /** Proxy function which check calls from usb_mux framework to driver */ -static int proxy_get(const struct usb_mux *me, mux_state_t *mux_state) +FAKE_VALUE_FUNC2(int, proxy_get, const struct usb_mux *, mux_state_t *); +/** Sequence of mux_state values returned by proxy_get function */ +static mux_state_t proxy_get_mux_state_seq[NUM_OF_PROXY]; +/** Index of next mux_state to return from proxy_get_function */ +static int proxy_get_mux_state_seq_idx; +/** Set all mux_state in sequence to the same state value */ +static void set_proxy_get_mux_state_seq(mux_state_t state) +{ + proxy_get_mux_state_seq_idx = 0; + for (int i = 0; i < NUM_OF_PROXY; i++) { + proxy_get_mux_state_seq[i] = state; + } +} + +static int proxy_get_custom(const struct usb_mux *me, mux_state_t *mux_state) { int i = me->i2c_addr_flags; + int ec = EC_SUCCESS; - ztest_check_expected_value(i); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->driver->get != NULL) { - org_mux[i]->driver->get(org_mux[i], mux_state); + ec = org_mux[i]->driver->get(org_mux[i], mux_state); + } + + if (task_get_current() == TASK_ID_TEST_RUNNER) { + zassert_true(proxy_get_mux_state_seq_idx < NUM_OF_PROXY, + "%s called too many times without resetting " + "mux_state_seq", __func__); + *mux_state = + proxy_get_mux_state_seq[proxy_get_mux_state_seq_idx]; + proxy_get_mux_state_seq_idx++; + RETURN_FAKE_RESULT(proxy_get); } - *mux_state = ztest_get_return_value(); + /* Discard this call if made from different thread */ + proxy_get_fake.call_count--; - return ztest_get_return_value(); + return ec; } /** Proxy function which check calls from usb_mux framework to driver */ -static int proxy_enter_low_power_mode(const struct usb_mux *me) +FAKE_VALUE_FUNC1(int, proxy_enter_low_power_mode, const struct usb_mux *); +static int proxy_enter_low_power_mode_custom(const struct usb_mux *me) { int i = me->i2c_addr_flags; + int ec = EC_SUCCESS; - ztest_check_expected_value(i); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->driver->enter_low_power_mode != NULL) { - org_mux[i]->driver->enter_low_power_mode(org_mux[i]); + ec = org_mux[i]->driver->enter_low_power_mode(org_mux[i]); } - return ztest_get_return_value(); + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(proxy_enter_low_power_mode); + } + + /* Discard this call if made from different thread */ + proxy_enter_low_power_mode_fake.call_count--; + + return ec; } /** Proxy function which check calls from usb_mux framework to driver */ -static int proxy_chipset_reset(const struct usb_mux *me) +FAKE_VALUE_FUNC1(int, proxy_chipset_reset, const struct usb_mux *); +static int proxy_chipset_reset_custom(const struct usb_mux *me) { int i = me->i2c_addr_flags; + int ec = EC_SUCCESS; - ztest_check_expected_value(i); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->driver->chipset_reset != NULL) { - org_mux[i]->driver->chipset_reset(org_mux[i]); + ec = org_mux[i]->driver->chipset_reset(org_mux[i]); } - return ztest_get_return_value(); + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(proxy_chipset_reset); + } + + /* Discard this call if made from different thread */ + proxy_chipset_reset_fake.call_count--; + + return ec; } /** Proxy function for fw update capability */ @@ -116,16 +182,22 @@ static bool proxy_fw_update_cap(void) } /** Proxy function which check calls from usb_mux framework to driver */ -static void proxy_hpd_update(const struct usb_mux *me, mux_state_t mux_state) +FAKE_VOID_FUNC3(proxy_hpd_update, const struct usb_mux *, mux_state_t, bool *); +static void proxy_hpd_update_custom(const struct usb_mux *me, + mux_state_t mux_state, bool *ack_required) { int i = me->i2c_addr_flags; - ztest_check_expected_value(i); - ztest_check_expected_value(mux_state); + zassert_true(i < NUM_OF_PROXY, "Proxy called for non proxy usb_mux"); if (org_mux[i] != NULL && org_mux[i]->hpd_update != NULL) { - org_mux[i]->hpd_update(org_mux[i], mux_state); + org_mux[i]->hpd_update(org_mux[i], mux_state, ack_required); + } + + if (task_get_current() != TASK_ID_TEST_RUNNER) { + /* Discard this call if made from different thread */ + proxy_hpd_update_fake.call_count--; } } @@ -139,6 +211,71 @@ const struct usb_mux_driver proxy_usb_mux = { .is_retimer_fw_update_capable = &proxy_fw_update_cap, }; +/** Mock function used in init test */ +FAKE_VALUE_FUNC1(int, mock_board_init, const struct usb_mux *); +static int mock_board_init_custom(const struct usb_mux *me) +{ + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(mock_board_init); + } + + /* Discard this call if made from different thread */ + mock_board_init_fake.call_count--; + + return EC_SUCCESS; +} + +/** Mock function used in set test */ +FAKE_VALUE_FUNC2(int, mock_board_set, const struct usb_mux *, mux_state_t); +static int mock_board_set_custom(const struct usb_mux *me, + mux_state_t mux_state) +{ + if (task_get_current() == TASK_ID_TEST_RUNNER) { + RETURN_FAKE_RESULT(mock_board_set); + } + + /* Discard this call if made from different thread */ + mock_board_set_fake.call_count--; + + return EC_SUCCESS; +} + +/** + * Reset state of all fake functions, setup custom fake functions and set + * default return value to EC_SUCCESS (all functions which has return value) + */ +static void reset_proxy_fakes(void) +{ + RESET_FAKE(proxy_init); + RESET_FAKE(proxy_set); + RESET_FAKE(proxy_get); + RESET_FAKE(proxy_enter_low_power_mode); + RESET_FAKE(proxy_chipset_reset); + RESET_FAKE(proxy_hpd_update); + RESET_FAKE(mock_board_init); + RESET_FAKE(mock_board_set); + + /* Setup proxy functions */ + proxy_init_fake.custom_fake = proxy_init_custom; + proxy_set_fake.custom_fake = proxy_set_custom; + proxy_get_fake.custom_fake = proxy_get_custom; + proxy_enter_low_power_mode_fake.custom_fake = + proxy_enter_low_power_mode_custom; + proxy_chipset_reset_fake.custom_fake = proxy_chipset_reset_custom; + proxy_hpd_update_fake.custom_fake = proxy_hpd_update_custom; + mock_board_init_fake.custom_fake = mock_board_init_custom; + mock_board_set_fake.custom_fake = mock_board_set_custom; + + /* Set default return value */ + proxy_init_fake.return_val = EC_SUCCESS; + proxy_set_fake.return_val = EC_SUCCESS; + proxy_get_fake.return_val = EC_SUCCESS; + proxy_enter_low_power_mode_fake.return_val = EC_SUCCESS; + proxy_chipset_reset_fake.return_val = EC_SUCCESS; + mock_board_init_fake.return_val = EC_SUCCESS; + mock_board_set_fake.return_val = EC_SUCCESS; +} + /** Chain of 3 proxy usb muxes */ struct usb_mux proxy_chain_2 = { .usb_port = USBC_PORT_C1, @@ -180,7 +317,7 @@ static void setup_usb_mux_proxy_chain(void) * each proxy */ t = &usb_mux_c1; - for (i = 0; i < 3; i++) { + for (i = 0; i < NUM_OF_PROXY; i++) { org_mux[i] = t; if (t != NULL) { t = t->next_mux; @@ -194,146 +331,96 @@ static void setup_usb_mux_proxy_chain(void) } } -static void suspend_usbc_task(bool suspend) -{ - static const task_id_t cros_tids[] = { - COND_CODE_1(HAS_TASK_PD_C0, (TASK_ID_PD_C0,), ()) - COND_CODE_1(HAS_TASK_PD_C1, (TASK_ID_PD_C1,), ()) - COND_CODE_1(HAS_TASK_PD_C2, (TASK_ID_PD_C2,), ()) - COND_CODE_1(HAS_TASK_PD_C3, (TASK_ID_PD_C3,), ()) - }; - - for (int i = 0; i < ARRAY_SIZE(cros_tids); ++i) - /* - * TODO(b/201420132): pd_set_suspend uses sleeps which we should - * minimize - */ - pd_set_suspend(TASK_ID_TO_PD_PORT(cros_tids[i]), suspend); -} - /** Restore original usb_mux chain without proxy */ -static void resotre_usb_mux_chain(void) +static void restore_usb_mux_chain(void) { - suspend_usbc_task(/*suspend=*/ false); memcpy(&usb_muxes[USBC_PORT_C1], &usb_mux_c1, sizeof(struct usb_mux)); } /** - * Setup expect values for proxy from first to last selected. - * Set value returned by proxy to ec. - */ -static void setup_ztest_proxy_init(int first, int last, int ec) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_init, i, i); - ztest_returns_value(proxy_init, ec); - } -} - -/** - * Setup expect values for proxy from first to last selected. - * Set value returned by proxy to ec. + * Check if given proxy function was called num times and if first argument was + * pointer to the right proxy chain element. First argument is + * const struct usb_mux * for all struct usb_mux_driver callbacks. */ -static void setup_ztest_proxy_set(int first, int last, int ec, mux_state_t exp) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_set, i, i); - ztest_expect_value(proxy_set, mux_state, exp); - ztest_returns_value(proxy_set, ec); - } -} +#define CHECK_PROXY_FAKE_CALL_CNT(proxy, num) \ + do { \ + zassert_equal(num, proxy##_fake.call_count, "%d != %d", \ + num, proxy##_fake.call_count); \ + if (num >= 1) { \ + zassert_equal(&usb_muxes[USBC_PORT_C1], \ + proxy##_fake.arg0_history[0], \ + NULL); \ + } \ + if (num >= 2) { \ + zassert_equal(&proxy_chain_1, \ + proxy##_fake.arg0_history[1], \ + NULL); \ + } \ + if (num >= 3) { \ + zassert_equal(&proxy_chain_2, \ + proxy##_fake.arg0_history[2], \ + NULL); \ + } \ + } while (0) /** - * Setup expect values for proxy from first to last selected. Set value - * returned by proxy to ec and value returned through mux_state to exp. + * Do the same thing as CHECK_PROXY_FAKE_CALL_CNT and check if second argument + * was the same as given state. hpd_update and set callback have mux_state_t + * as second argument. */ -static void setup_ztest_proxy_get(int first, int last, int ec, mux_state_t exp) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_get, i, i); - ztest_returns_value(proxy_get, exp); - ztest_returns_value(proxy_get, ec); - } -} - -/** - * Setup expect values for proxy from first to last selected. - * Set value returned by proxy to ec. - */ -static void setup_ztest_proxy_enter_lpm(int first, int last, int ec) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_enter_low_power_mode, i, i); - ztest_returns_value(proxy_enter_low_power_mode, ec); - } -} - -/** - * Setup expect values for proxy from first to last selected. - * Set value returned by proxy to ec. - */ -static void setup_ztest_proxy_chipset_reset(int first, int last, int ec) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_chipset_reset, i, i); - ztest_returns_value(proxy_chipset_reset, ec); - } -} - -/** Setup expect values for proxy from first to last selected */ -static void setup_ztest_proxy_hpd_update(int first, int last, mux_state_t exp) -{ - for (int i = first; i <= last; i++) { - ztest_expect_value(proxy_hpd_update, i, i); - ztest_expect_value(proxy_hpd_update, mux_state, exp); - } -} - -/** Mock function used in set test */ -static int mock_board_set(const struct usb_mux *me, mux_state_t mux_state) -{ - int i = me->i2c_addr_flags; - - ztest_check_expected_value(i); - - return EC_SUCCESS; -} +#define CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy, num, state) \ + do { \ + CHECK_PROXY_FAKE_CALL_CNT(proxy, num); \ + if (num >= 1) { \ + zassert_equal(state, \ + proxy##_fake.arg1_history[0], \ + "0x%x != 0x%x", state, \ + proxy##_fake.arg1_history[0]); \ + } \ + if (num >= 2) { \ + zassert_equal(state, \ + proxy##_fake.arg1_history[1], \ + "0x%x != 0x%x", state, \ + proxy##_fake.arg1_history[1]); \ + } \ + if (num >= 3) { \ + zassert_equal(state, \ + proxy##_fake.arg1_history[2], \ + "0x%x != 0x%x", state, \ + proxy##_fake.arg1_history[2]); \ + } \ + } while (0) /** Test usb_mux init */ static void test_usb_mux_init(void) { + int fail_on_2nd_ret[] = {EC_SUCCESS, EC_ERROR_NOT_POWERED}; + /* Set AP to normal state to init BB retimer */ - set_mock_power_state(POWER_S0); - /* - * TODO(b/201420132) - setting power state requires to wake up - * TASK_ID_CHIPSET Sleep is required to run chipset task before - * continuing with test - */ - k_msleep(1); + power_set_state(POWER_S0); /* Test successful initialisation */ - setup_ztest_proxy_init(0, 2, EC_SUCCESS); usb_mux_init(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); /* * Test failed initialisation. Muxes that are in chain after * the one which fails shouldn't be called */ - setup_ztest_proxy_init(0, 0, EC_SUCCESS); - setup_ztest_proxy_init(1, 1, EC_ERROR_NOT_POWERED); + reset_proxy_fakes(); + SET_RETURN_SEQ(proxy_init, fail_on_2nd_ret, 2); usb_mux_init(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 2); /* Test board init callback */ - proxy_chain_1.board_init = proxy_init; - setup_ztest_proxy_init(0, 0, EC_SUCCESS); - /* - * board_init of second mux mock is set to init mock function, so it - * should be called two times. - */ - setup_ztest_proxy_init(1, 1, EC_SUCCESS); - setup_ztest_proxy_init(1, 2, EC_SUCCESS); - + proxy_chain_1.board_init = &mock_board_init; + reset_proxy_fakes(); usb_mux_init(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + /* Check if board_init was called for proxy 1 */ + zassert_equal(1, mock_board_init_fake.call_count, NULL); + zassert_equal(&proxy_chain_1, mock_board_init_fake.arg0_history[0], + NULL); proxy_chain_1.board_init = NULL; } @@ -341,40 +428,57 @@ static void test_usb_mux_init(void) /** Test usb_mux setting mux mode */ static void test_usb_mux_set(void) { + int fail_on_2nd_ret[] = {EC_SUCCESS, EC_ERROR_UNKNOWN}; mux_state_t exp_mode; - /* usb mux 1 shouldn't be set with polarity mode */ + /* Set flag for usb mux 1 to disable polarity setting */ proxy_chain_1.flags = USB_MUX_FLAG_SET_WITHOUT_FLIP; /* Test setting mux mode without polarity inversion */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + /* All muxes should have the same mode */ + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test setting mux mode with polarity inversion */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_TBT_COMPAT_ENABLED; - setup_ztest_proxy_set(0, 0, EC_SUCCESS, - exp_mode | USB_PD_MUX_POLARITY_INVERTED); - setup_ztest_proxy_set(1, 1, EC_SUCCESS, exp_mode); - setup_ztest_proxy_set(2, 2, EC_SUCCESS, - exp_mode | USB_PD_MUX_POLARITY_INVERTED); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 1 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT(proxy_set, NUM_OF_PROXY); + /* usb mux 1 shouldn't be set with polarity mode, because of flag */ + zassert_equal(exp_mode | USB_PD_MUX_POLARITY_INVERTED, + proxy_set_fake.arg1_history[0], NULL); + zassert_equal(exp_mode, proxy_set_fake.arg1_history[1], NULL); + zassert_equal(exp_mode | USB_PD_MUX_POLARITY_INVERTED, + proxy_set_fake.arg1_history[2], NULL); /* Test board set callback */ - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); + reset_proxy_fakes(); proxy_chain_1.board_set = &mock_board_set; - ztest_expect_value(mock_board_set, i, 1); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); + /* Check if board_set was called for proxy 1 */ + zassert_equal(1, mock_board_set_fake.call_count, NULL); + zassert_equal(&proxy_chain_1, mock_board_set_fake.arg0_history[0], + NULL); + zassert_equal(exp_mode, mock_board_set_fake.arg1_history[0], NULL); /* Test set function with error in usb_mux */ - setup_ztest_proxy_set(0, 0, EC_SUCCESS, exp_mode); - setup_ztest_proxy_set(1, 1, EC_ERROR_UNKNOWN, exp_mode); + reset_proxy_fakes(); + SET_RETURN_SEQ(proxy_set, fail_on_2nd_ret, 2); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, 2, exp_mode); + /* board_set shouldn't be called after fail */ + zassert_equal(0, mock_board_set_fake.call_count, NULL); proxy_chain_1.board_set = NULL; } @@ -385,115 +489,125 @@ static void test_usb_mux_reset_in_g3(void) mux_state_t exp_mode = USB_PD_MUX_USB_ENABLED; /* Test that init is called */ - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); + reset_proxy_fakes(); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Usb muxes of port 1 should stay initialised */ usb_muxes[USBC_PORT_C1].flags = 0; hook_notify(HOOK_CHIPSET_HARD_OFF); /* Test that init is not called */ - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); + reset_proxy_fakes(); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); } /** Test usb_mux getting mux mode */ static void test_usb_mux_get(void) { + int fail_on_2nd_ret[] = {EC_SUCCESS, EC_ERROR_UNKNOWN}; mux_state_t exp_mode, mode; /* Test getting mux mode */ exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_get(0, 2, EC_SUCCESS, exp_mode); + set_proxy_get_mux_state_seq(exp_mode); mode = usb_mux_get(USBC_PORT_C1); zassert_equal(exp_mode, mode, "mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); - /* Test getting mux mode with one inverted polarisation */ + /* Test getting mux mode with inverted polarisation in one mux */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_TBT_COMPAT_ENABLED; - setup_ztest_proxy_get(0, 0, EC_SUCCESS, exp_mode); - setup_ztest_proxy_get(1, 1, EC_SUCCESS, - exp_mode | USB_PD_MUX_POLARITY_INVERTED); - setup_ztest_proxy_get(2, 2, EC_SUCCESS, exp_mode); + set_proxy_get_mux_state_seq(exp_mode); + /* Set polarisation in usb mux 1 state */ + proxy_get_mux_state_seq[1] |= USB_PD_MUX_POLARITY_INVERTED; exp_mode |= USB_PD_MUX_POLARITY_INVERTED; mode = usb_mux_get(USBC_PORT_C1); zassert_equal(exp_mode, mode, "mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); /* Test get function with error in usb_mux */ - setup_ztest_proxy_get(0, 0, EC_SUCCESS, USB_PD_MUX_TBT_COMPAT_ENABLED); - setup_ztest_proxy_get(1, 1, EC_ERROR_UNKNOWN, - USB_PD_MUX_TBT_COMPAT_ENABLED); + reset_proxy_fakes(); + SET_RETURN_SEQ(proxy_get, fail_on_2nd_ret, 2); + set_proxy_get_mux_state_seq(USB_PD_MUX_TBT_COMPAT_ENABLED); exp_mode = USB_PD_MUX_NONE; mode = usb_mux_get(USBC_PORT_C1); zassert_equal(exp_mode, mode, "mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, 2); } /** Test usb_mux entering and exiting low power mode */ static void test_usb_mux_low_power_mode(void) { + int fail_on_2nd_ret[] = {EC_SUCCESS, EC_ERROR_NOT_POWERED}; mux_state_t exp_mode, mode; - /* - * Virtual mux return ack_required in some cases, but this requires to - * run usb_mux_set in TASK_PD_C1 context. Remove virtual mux from chain - * for this test. - * - * TODO: Find way to setup PD stack in such state that notifing PD task - * results in required usb_mux_set call. - */ - org_mux[1] = NULL; - /* Test enter to low power mode */ exp_mode = USB_PD_MUX_NONE; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); - setup_ztest_proxy_enter_lpm(0, 2, EC_SUCCESS); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_DISCONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_enter_low_power_mode, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test that nothing is changed when already in low power mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_NONE; usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_DISCONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_enter_low_power_mode, 0); + CHECK_PROXY_FAKE_CALL_CNT(proxy_set, 0); /* Test that get return USB_PD_MUX_NONE in low power mode */ exp_mode = USB_PD_MUX_NONE; mode = usb_mux_get(USBC_PORT_C1); zassert_equal(exp_mode, mode, "mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, 0); /* Test exiting from low power mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test exiting from lpm, when init end with EC_ERROR_NOT_POWERED */ - setup_ztest_proxy_init(0, 0, EC_SUCCESS); - setup_ztest_proxy_init(1, 1, EC_ERROR_NOT_POWERED); + reset_proxy_fakes(); + SET_RETURN_SEQ(proxy_init, fail_on_2nd_ret, 2); usb_mux_init(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 2); + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test enter to low power mode with polarity */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_NONE; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); - setup_ztest_proxy_enter_lpm(0, 2, EC_SUCCESS); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_DISCONNECT, 1 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_enter_low_power_mode, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test that nothing is changed on lpm exit error */ + reset_proxy_fakes(); + SET_RETURN_SEQ(proxy_init, fail_on_2nd_ret, 2); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 0, EC_SUCCESS); - setup_ztest_proxy_init(1, 1, EC_ERROR_NOT_POWERED); usb_mux_set(USBC_PORT_C1, exp_mode, USB_SWITCH_CONNECT, 0 /* = polarity */); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 2); + CHECK_PROXY_FAKE_CALL_CNT(proxy_set, 0); } /** Test usb_mux flip */ @@ -501,32 +615,34 @@ static void test_usb_mux_flip(void) { mux_state_t exp_mode; - /* usb mux mock 1 shouldn't be set with polarity mode */ + /* Set flag for usb mux 1 to disable polarity setting */ proxy_chain_1.flags = USB_MUX_FLAG_SET_WITHOUT_FLIP; - /* Makes sure that usb muxes of port 1 are not init */ - usb_muxes[USBC_PORT_C1].flags = USB_MUX_FLAG_RESETS_IN_G3; - hook_notify(HOOK_CHIPSET_HARD_OFF); - /* Test flip port without polarity inverted */ exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_get(0, 2, EC_SUCCESS, exp_mode); - exp_mode |= USB_PD_MUX_POLARITY_INVERTED; - setup_ztest_proxy_set(0, 0, EC_SUCCESS, exp_mode); - setup_ztest_proxy_set(1, 1, EC_SUCCESS, - exp_mode & ~USB_PD_MUX_POLARITY_INVERTED); - setup_ztest_proxy_set(2, 2, EC_SUCCESS, exp_mode); + set_proxy_get_mux_state_seq(exp_mode); usb_mux_flip(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT(proxy_set, NUM_OF_PROXY); + /* usb mux 1 shouldn't be set with polarity mode, because of flag */ + zassert_equal(exp_mode | USB_PD_MUX_POLARITY_INVERTED, + proxy_set_fake.arg1_history[0], NULL); + zassert_equal(exp_mode, proxy_set_fake.arg1_history[1], NULL); + zassert_equal(exp_mode | USB_PD_MUX_POLARITY_INVERTED, + proxy_set_fake.arg1_history[2], NULL); /* Test flip port with polarity inverted */ - setup_ztest_proxy_get(0, 0, EC_SUCCESS, exp_mode); - setup_ztest_proxy_get(1, 1, EC_SUCCESS, - exp_mode & ~USB_PD_MUX_POLARITY_INVERTED); - setup_ztest_proxy_get(2, 2, EC_SUCCESS, exp_mode); + reset_proxy_fakes(); + exp_mode |= USB_PD_MUX_POLARITY_INVERTED; + set_proxy_get_mux_state_seq(exp_mode); + /* Clear polarity bit from usb mux 1 */ + proxy_get_mux_state_seq[1] &= ~USB_PD_MUX_POLARITY_INVERTED; exp_mode &= ~USB_PD_MUX_POLARITY_INVERTED; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); usb_mux_flip(USBC_PORT_C1); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); } void test_usb_mux_hpd_update(void) @@ -538,40 +654,50 @@ void test_usb_mux_hpd_update(void) /* Test no hpd level and no irq */ exp_mode = virt_mode; - setup_ztest_proxy_init(0, 2, EC_SUCCESS); - setup_ztest_proxy_hpd_update(0, 2, exp_mode); usb_mux_hpd_update(USBC_PORT_C1, exp_mode); /* Check if virtual usb mux mode is updated correctly */ usbc1_virtual_usb_mux.driver->get(&usbc1_virtual_usb_mux, &mode); zassert_equal(exp_mode, mode, "virtual mux mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_hpd_update, NUM_OF_PROXY, + exp_mode); /* Test hpd level and irq */ + reset_proxy_fakes(); exp_mode = virt_mode | USB_PD_MUX_HPD_LVL | USB_PD_MUX_HPD_IRQ; - setup_ztest_proxy_hpd_update(0, 2, exp_mode); usb_mux_hpd_update(USBC_PORT_C1, exp_mode); /* Check if virtual usb mux mode is updated correctly */ usbc1_virtual_usb_mux.driver->get(&usbc1_virtual_usb_mux, &mode); zassert_equal(exp_mode, mode, "virtual mux mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_hpd_update, NUM_OF_PROXY, + exp_mode); /* Test no hpd level and irq */ + reset_proxy_fakes(); exp_mode = virt_mode | USB_PD_MUX_HPD_IRQ; - setup_ztest_proxy_hpd_update(0, 2, exp_mode); usb_mux_hpd_update(USBC_PORT_C1, exp_mode); /* Check if virtual usb mux mode is updated correctly */ usbc1_virtual_usb_mux.driver->get(&usbc1_virtual_usb_mux, &mode); zassert_equal(exp_mode, mode, "virtual mux mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_hpd_update, NUM_OF_PROXY, + exp_mode); /* Test hpd level and no irq */ + reset_proxy_fakes(); exp_mode = virt_mode | USB_PD_MUX_HPD_LVL; - setup_ztest_proxy_hpd_update(0, 2, exp_mode); usb_mux_hpd_update(USBC_PORT_C1, exp_mode); /* Check if virtual usb mux mode is updated correctly */ usbc1_virtual_usb_mux.driver->get(&usbc1_virtual_usb_mux, &mode); zassert_equal(exp_mode, mode, "virtual mux mode is 0x%x (!= 0x%x)", mode, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, 0); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_hpd_update, NUM_OF_PROXY, + exp_mode); } void test_usb_mux_fw_update_port_info(void) @@ -585,9 +711,9 @@ void test_usb_mux_fw_update_port_info(void) void test_usb_mux_chipset_reset(void) { - setup_ztest_proxy_chipset_reset(0, 2, EC_SUCCESS); /* After this hook chipset reset functions should be called */ hook_notify(HOOK_CHIPSET_RESET); + CHECK_PROXY_FAKE_CALL_CNT(proxy_chipset_reset, NUM_OF_PROXY); } /* Test host command get mux info */ @@ -596,13 +722,9 @@ static void test_usb_mux_hc_mux_info(void) struct ec_response_usb_pd_mux_info response; struct ec_params_usb_pd_mux_info params; struct host_cmd_handler_args args = - BUILD_HOST_COMMAND(EC_CMD_USB_PD_MUX_INFO, 0, response); + BUILD_HOST_COMMAND(EC_CMD_USB_PD_MUX_INFO, 0, response, params); mux_state_t exp_mode; - /* Set up host command parameters */ - args.params = ¶ms; - args.params_size = sizeof(params); - /* Test invalid port parameter */ params.port = 5; zassert_equal(EC_RES_INVALID_PARAM, host_command_process(&args), NULL); @@ -611,27 +733,32 @@ static void test_usb_mux_hc_mux_info(void) params.port = USBC_PORT_C1; /* Test error on getting mux mode */ - setup_ztest_proxy_get(0, 0, EC_ERROR_UNKNOWN, - USB_PD_MUX_TBT_COMPAT_ENABLED); + set_proxy_get_mux_state_seq(USB_PD_MUX_USB_ENABLED); + proxy_get_fake.return_val = EC_ERROR_UNKNOWN; zassert_equal(EC_RES_ERROR, host_command_process(&args), NULL); /* Test getting mux mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_get(0, 2, EC_SUCCESS, exp_mode); + set_proxy_get_mux_state_seq(exp_mode); zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); zassert_equal(args.response_size, sizeof(response), NULL); zassert_equal(exp_mode, response.flags, "mode is 0x%x (!= 0x%x)", response.flags, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); /* Test clearing HPD IRQ */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_HPD_LVL | USB_PD_MUX_HPD_IRQ; - setup_ztest_proxy_get(0, 2, EC_SUCCESS, exp_mode); - setup_ztest_proxy_hpd_update(0, 2, USB_PD_MUX_HPD_LVL); + set_proxy_get_mux_state_seq(exp_mode); zassert_equal(EC_RES_SUCCESS, host_command_process(&args), NULL); zassert_equal(args.response_size, sizeof(response), NULL); zassert_equal(exp_mode, response.flags, "mode is 0x%x (!= 0x%x)", response.flags, exp_mode); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_hpd_update, NUM_OF_PROXY, + USB_PD_MUX_HPD_LVL); } /** Test typec console command */ @@ -667,96 +794,102 @@ static void test_usb_mux_typec_command(void) * Test success on correct port number. Command should print mux state * on console, but it is not possible to check that in unit test. */ - setup_ztest_proxy_get(0, 2, EC_SUCCESS, USB_PD_MUX_TBT_COMPAT_ENABLED); + set_proxy_get_mux_state_seq(USB_PD_MUX_TBT_COMPAT_ENABLED); zassert_equal(EC_SUCCESS, shell_execute_cmd(shell_backend_uart_get_ptr(), "typec 1"), NULL); + CHECK_PROXY_FAKE_CALL_CNT(proxy_get, NUM_OF_PROXY); /* Test setting none mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_NONE; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); - /* Mux will enter low power mode */ - setup_ztest_proxy_enter_lpm(0, 2, EC_SUCCESS); zassert_equal(EC_SUCCESS, shell_execute_cmd(shell_backend_uart_get_ptr(), "typec 1 none"), NULL); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); + /* Mux will enter low power mode */ + CHECK_PROXY_FAKE_CALL_CNT(proxy_enter_low_power_mode, NUM_OF_PROXY); /* Test setting USB mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); - /* Mux will exit low power mode */ - setup_ztest_proxy_init(0, 2, EC_SUCCESS); zassert_equal(EC_SUCCESS, shell_execute_cmd(shell_backend_uart_get_ptr(), "typec 1 usb"), NULL); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); + /* Mux will exit low power mode */ + CHECK_PROXY_FAKE_CALL_CNT(proxy_init, NUM_OF_PROXY); /* Test setting DP mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_DP_ENABLED; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); zassert_equal(EC_SUCCESS, shell_execute_cmd(shell_backend_uart_get_ptr(), "typec 1 dp"), NULL); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); /* Test setting dock mode */ + reset_proxy_fakes(); exp_mode = USB_PD_MUX_USB_ENABLED | USB_PD_MUX_DP_ENABLED; - setup_ztest_proxy_set(0, 2, EC_SUCCESS, exp_mode); zassert_equal(EC_SUCCESS, shell_execute_cmd(shell_backend_uart_get_ptr(), "typec 1 dock"), NULL); + CHECK_PROXY_FAKE_CALL_CNT_MUX_STATE(proxy_set, NUM_OF_PROXY, exp_mode); } /** Setup proxy chain and uninit usb muxes */ void setup_uninit_mux(void) { - suspend_usbc_task(/*suspend=*/ true); setup_usb_mux_proxy_chain(); + set_test_runner_tid(); /* Makes sure that usb muxes of port 1 are not init */ usb_muxes[USBC_PORT_C1].flags = USB_MUX_FLAG_RESETS_IN_G3; hook_notify(HOOK_CHIPSET_HARD_OFF); + reset_proxy_fakes(); } /** Setup proxy chain and init usb muxes */ void setup_init_mux(void) { - suspend_usbc_task(/*suspend=*/ true); setup_usb_mux_proxy_chain(); + set_test_runner_tid(); /* Makes sure that usb muxes of port 1 are init */ - setup_ztest_proxy_init(0, 2, EC_SUCCESS); usb_mux_init(USBC_PORT_C1); + reset_proxy_fakes(); } void test_suite_usb_mux(void) { ztest_test_suite(usb_mux, ztest_unit_test_setup_teardown(test_usb_mux_init, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown(test_usb_mux_set, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_reset_in_g3, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown(test_usb_mux_get, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_low_power_mode, - setup_init_mux, resotre_usb_mux_chain), + setup_init_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown(test_usb_mux_flip, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown(test_usb_mux_hpd_update, - setup_uninit_mux, resotre_usb_mux_chain), + setup_uninit_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_fw_update_port_info, - setup_init_mux, resotre_usb_mux_chain), + setup_init_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_chipset_reset, - setup_init_mux, resotre_usb_mux_chain), + setup_init_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_hc_mux_info, - setup_init_mux, resotre_usb_mux_chain), + setup_init_mux, restore_usb_mux_chain), ztest_unit_test_setup_teardown( test_usb_mux_typec_command, - setup_init_mux, resotre_usb_mux_chain)); + setup_init_mux, restore_usb_mux_chain)); ztest_run_test_suite(usb_mux); } diff --git a/zephyr/test/ec_app/src/main.c b/zephyr/test/ec_app/src/main.c index 6aa2d6c1b9..47aecc7eca 100644 --- a/zephyr/test/ec_app/src/main.c +++ b/zephyr/test/ec_app/src/main.c @@ -45,7 +45,7 @@ static void test_button_init(void) static void test_setup_espi(void) { -#ifdef CONFIG_PLATFORM_EC_ESPI +#ifdef CONFIG_PLATFORM_EC_HOST_INTERFACE_ESPI zassert_unreachable("TODO: Implement this test."); #else ztest_test_skip(); diff --git a/zephyr/test/i2c/overlay.dts b/zephyr/test/i2c/overlay.dts index 2c56ee3b7a..1519bb1cb7 100644 --- a/zephyr/test/i2c/overlay.dts +++ b/zephyr/test/i2c/overlay.dts @@ -9,7 +9,6 @@ accel-0 { i2c-port = <&bmi_i2c>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL_0"; }; }; }; diff --git a/zephyr/test/i2c_dts/overlay.dts b/zephyr/test/i2c_dts/overlay.dts index 2c56ee3b7a..1519bb1cb7 100644 --- a/zephyr/test/i2c_dts/overlay.dts +++ b/zephyr/test/i2c_dts/overlay.dts @@ -9,7 +9,6 @@ accel-0 { i2c-port = <&bmi_i2c>; enum-name = "I2C_PORT_ACCEL"; - label = "ACCEL_0"; }; }; }; diff --git a/zephyr/test/system/overlay.dts b/zephyr/test/system/overlay.dts index 37bac97680..bba99a0b81 100644 --- a/zephyr/test/system/overlay.dts +++ b/zephyr/test/system/overlay.dts @@ -4,6 +4,16 @@ */ / { + chosen { + cros-ec,bbram = &bbram; + }; + + bbram: test-bbram-dev { + compatible = "zephyr,bbram-emul"; + label = "TEST_BBRAM_DEV"; + size = <64>; + }; + named-bbram-regions { compatible = "named-bbram-regions"; pd0 { diff --git a/zephyr/test/system/prj.conf b/zephyr/test/system/prj.conf index 03357fa10f..4b3055b39b 100644 --- a/zephyr/test/system/prj.conf +++ b/zephyr/test/system/prj.conf @@ -1,4 +1,10 @@ +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + CONFIG_ZTEST=y CONFIG_PLATFORM_EC=y CONFIG_CROS_EC=y CONFIG_LOG=y +CONFIG_BBRAM=y +CONFIG_BBRAM_EMUL=y diff --git a/zephyr/test/system/test_system.c b/zephyr/test/system/test_system.c index e8eba44fc8..96befde553 100644 --- a/zephyr/test/system/test_system.c +++ b/zephyr/test/system/test_system.c @@ -8,7 +8,6 @@ #include <logging/log.h> #include <ztest.h> -#include "bbram.h" #include "system.h" LOG_MODULE_REGISTER(test); @@ -21,50 +20,34 @@ LOG_MODULE_REGISTER(test); static char mock_data[64] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@"; -static int mock_bbram_read(const struct device *unused, size_t offset, - size_t size, uint8_t *data) -{ - if (offset < 0 || offset + size >= ARRAY_SIZE(mock_data)) - return -1; - memcpy(data, mock_data + offset, size); - return EC_SUCCESS; -} - -static const struct bbram_driver_api bbram_api = { - .read = mock_bbram_read, -}; - -static const struct device bbram_dev_instance = { - .name = "TEST_BBRAM_DEV", - .config = NULL, - .api = &bbram_api, - .data = NULL, -}; - -const struct device *bbram_dev = &bbram_dev_instance; - static void test_bbram_get(void) { + const struct device *const bbram_dev = + DEVICE_DT_GET(DT_CHOSEN(cros_ec_bbram)); uint8_t output[10]; int rc; + /* Write expected data to read back */ + rc = bbram_write(bbram_dev, 0, ARRAY_SIZE(mock_data), mock_data); + zassert_ok(rc, NULL); + rc = system_get_bbram(SYSTEM_BBRAM_IDX_PD0, output); - zassert_equal(rc, 0, NULL); + zassert_ok(rc, NULL); zassert_mem_equal(output, mock_data + BBRAM_REGION_OFF(pd0), BBRAM_REGION_SIZE(pd0), NULL); rc = system_get_bbram(SYSTEM_BBRAM_IDX_PD1, output); - zassert_equal(rc, 0, NULL); + zassert_ok(rc, NULL); zassert_mem_equal(output, mock_data + BBRAM_REGION_OFF(pd1), BBRAM_REGION_SIZE(pd1), NULL); rc = system_get_bbram(SYSTEM_BBRAM_IDX_PD2, output); - zassert_equal(rc, 0, NULL); + zassert_ok(rc, NULL); zassert_mem_equal(output, mock_data + BBRAM_REGION_OFF(pd2), BBRAM_REGION_SIZE(pd2), NULL); rc = system_get_bbram(SYSTEM_BBRAM_IDX_TRY_SLOT, output); - zassert_equal(rc, 0, NULL); + zassert_ok(rc, NULL); zassert_mem_equal(output, mock_data + BBRAM_REGION_OFF(try_slot), BBRAM_REGION_SIZE(try_slot), NULL); } diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py index 4d9994a108..f7688784e7 100644 --- a/zephyr/zmake/tests/test_project.py +++ b/zephyr/zmake/tests/test_project.py @@ -58,7 +58,6 @@ def test_find_dts_overlays(modules): zephyr_board=board, output_packer=zmake.output_packers.ElfPacker, supported_toolchains=["llvm"], - zephyr_version="v2.7", project_dir=pathlib.Path("/fakebuild"), ) ) @@ -93,7 +92,6 @@ def test_prune_modules(modules): zephyr_board="native_posix", output_packer=zmake.output_packers.ElfPacker, supported_toolchains=["coreboot-sdk"], - zephyr_version="v2.7", project_dir=pathlib.Path("/fake"), modules=modules, ), @@ -116,7 +114,6 @@ def test_prune_modules_unavailable(): zephyr_board="native_posix", output_packer=zmake.output_packers.ElfPacker, supported_toolchains=["coreboot-sdk"], - zephyr_version="v2.7", project_dir=pathlib.Path("/fake"), modules=["hal_stm32", "cmsis"], ), diff --git a/zephyr/zmake/tests/test_toolchains.py b/zephyr/zmake/tests/test_toolchains.py index 09d37c4c4e..fb1953052a 100644 --- a/zephyr/zmake/tests/test_toolchains.py +++ b/zephyr/zmake/tests/test_toolchains.py @@ -66,7 +66,6 @@ def fake_project(tmp_path): project.ProjectConfig( project_name="foo", zephyr_board="foo", - zephyr_version="v2.6", supported_toolchains=[ "coreboot-sdk", "host", diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py index cbc1ceff88..b2c6b43fec 100644 --- a/zephyr/zmake/tests/test_version.py +++ b/zephyr/zmake/tests/test_version.py @@ -57,7 +57,6 @@ def _setup_example_repos(tmp_path): zephyr_board="foo", output_packer=zmake.output_packers.RawBinPacker, supported_toolchains=["coreboot-sdk"], - zephyr_version="v2.6", project_dir=project_path, ), ) diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py index 589ee72c66..83862ce65d 100644 --- a/zephyr/zmake/tests/test_zmake.py +++ b/zephyr/zmake/tests/test_zmake.py @@ -13,6 +13,7 @@ import unittest import unittest.mock as mock from unittest.mock import patch +import pytest from testfixtures import LogCapture import zmake.build_config @@ -39,7 +40,6 @@ class FakeProject: project_name="fakeproject", zephyr_board="fakeboard", supported_toolchains=["llvm"], - zephyr_version="v2.5", output_packer=zmake.output_packers.ElfPacker, project_dir=pathlib.Path("FakeProjectDir"), ) @@ -129,12 +129,10 @@ def do_test_with_log_level(log_level, use_configure=False, fnames=None): re.compile(r".*build-rw"): get_test_filepath("rw"), } zephyr_base = mock.Mock() - zephyr_root = mock.Mock() zmk = zm.Zmake( jobserver=FakeJobserver(fnames), zephyr_base=zephyr_base, - zephyr_root=zephyr_root, ) with LogCapture(level=log_level) as cap: @@ -231,5 +229,71 @@ class TestFilters(unittest.TestCase): assert "devicetree error: 'adc' is marked as required" in list(dt_errs)[0] +@pytest.mark.parametrize( + ["project_names", "format", "search_dir", "expected_output"], + [ + ( + ["link", "samus"], + "{config.project_name}\n", + None, + "link\nsamus\n", + ), + ( + ["link", "samus"], + "{config.project_name}\n", + pathlib.Path("/foo/bar"), + "link\nsamus\n", + ), + ( + [], + "{config.project_name}\n", + None, + "", + ), + ( + ["link"], + "", + None, + "", + ), + ( + ["link"], + "{config.zephyr_board}\n", + None, + "some_board\n", + ), + ( + ["link"], + "{config.project_name} is_test={config.is_test}\n", + None, + "link is_test=False\n", + ), + ], +) +def test_list_projects(project_names, format, search_dir, expected_output, capsys): + """Test listing projects with default directory.""" + fake_projects = { + name: zmake.project.Project( + zmake.project.ProjectConfig( + project_name=name, + zephyr_board="some_board", + supported_toolchains=["coreboot-sdk"], + output_packer=zmake.output_packers.RawBinPacker, + ) + ) + for name in project_names + } + zmk = zm.Zmake() + with mock.patch( + "zmake.project.find_projects", + autospec=True, + return_value=fake_projects, + ): + zmk.list_projects(format=format, search_dir=search_dir) + + captured = capsys.readouterr() + assert captured.out == expected_output + + if __name__ == "__main__": unittest.main() diff --git a/zephyr/zmake/zmake/__main__.py b/zephyr/zmake/zmake/__main__.py index f776c1dbaa..1f9c506ee5 100644 --- a/zephyr/zmake/zmake/__main__.py +++ b/zephyr/zmake/zmake/__main__.py @@ -107,7 +107,10 @@ def main(argv=None): maybe_reexec(argv) - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser( + prog="zmake", + description="Chromium OS's meta-build tool for Zephyr", + ) parser.add_argument( "--checkout", type=pathlib.Path, help="Path to ChromiumOS checkout" ) @@ -161,20 +164,13 @@ def main(argv=None): parser.add_argument( "--zephyr-base", type=pathlib.Path, help="Path to Zephyr OS repository" ) - parser.add_argument( - "--zephyr-root", - type=pathlib.Path, - help="Path to Zephyr OS repos, must contain subdirs like v1.2", - ) sub = parser.add_subparsers(dest="subcommand", help="Subcommand") sub.required = True - configure = sub.add_parser("configure") - configure.add_argument( - "--ignore-unsupported-zephyr-version", - action="store_true", - help="Don't warn about using an unsupported Zephyr version", + configure = sub.add_parser( + "configure", + help="Set up a build directory to be built later by the build subcommand", ) configure.add_argument("-t", "--toolchain", help="Name of toolchain to use") configure.add_argument( @@ -217,7 +213,10 @@ def main(argv=None): help="Enable CONFIG_COVERAGE Kconfig.", ) - build = sub.add_parser("build") + build = sub.add_parser( + "build", + help="Execute the build from a build directory", + ) build.add_argument( "build_dir", type=pathlib.Path, @@ -230,16 +229,44 @@ def main(argv=None): help="Exit with code 2 if warnings are detected", ) - test = sub.add_parser("test") + list_projects = sub.add_parser( + "list-projects", + help="List projects known to zmake.", + ) + list_projects.add_argument( + "--format", + default="{config.project_name}\n", + help=( + "Output format to print projects (str.format(config=project.config) is " + "called on this for each project)." + ), + ) + list_projects.add_argument( + "search_dir", + type=pathlib.Path, + nargs="?", + help="Optional directory to search for BUILD.py files in.", + ) + + test = sub.add_parser( + "test", + help="Execute tests from a build directory", + ) test.add_argument( "build_dir", type=pathlib.Path, help="The build directory used during configuration", ) - sub.add_parser("testall") + sub.add_parser( + "testall", + help="Execute all known builds and tests", + ) - coverage = sub.add_parser("coverage") + coverage = sub.add_parser( + "coverage", + help="Run coverage on a build directory", + ) coverage.add_argument( "build_dir", type=pathlib.Path, diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py index de3bc8413b..8e90372a35 100644 --- a/zephyr/zmake/zmake/project.py +++ b/zephyr/zmake/zmake/project.py @@ -55,10 +55,10 @@ def load_config_file(path): exec(code, config_globals) # Next, load the BUILD.py - logging.info("Loading config file %s", path) + logging.debug("Loading config file %s", path) code = compile(path.read_bytes(), str(path), "exec") exec(code, config_globals) - logging.info("Config file %s defines %s projects", path, len(projects)) + logging.debug("Config file %s defines %s projects", path, len(projects)) return projects @@ -71,7 +71,7 @@ def find_projects(root_dir): Returns: A dictionary mapping project names to Project objects. """ - logging.info("Finding zmake targets under '%s'.", root_dir) + logging.debug("Finding zmake targets under '%s'.", root_dir) found_projects = {} for path in pathlib.Path(root_dir).rglob("BUILD.py"): for project in load_config_file(path): @@ -91,7 +91,6 @@ class ProjectConfig: zephyr_board: str supported_toolchains: "list[str]" output_packer: type - zephyr_version: str = dataclasses.field(default="v2.7") modules: "list[str]" = dataclasses.field( default_factory=lambda: modules.known_modules, ) diff --git a/zephyr/zmake/zmake/toolchains.py b/zephyr/zmake/zmake/toolchains.py index 88b7c16e46..671c539c0f 100644 --- a/zephyr/zmake/zmake/toolchains.py +++ b/zephyr/zmake/zmake/toolchains.py @@ -107,7 +107,7 @@ class ZephyrToolchain(GenericToolchain): if not self.zephyr_sdk_install_dir: raise RuntimeError( "No installed Zephyr SDK was found" - " (see docs/zephyr_build.md for documentation)" + " (see docs/zephyr/zephyr_build.md for documentation)" ) tc_vars = { "ZEPHYR_SDK_INSTALL_DIR": str(self.zephyr_sdk_install_dir), diff --git a/zephyr/zmake/zmake/util.py b/zephyr/zmake/zmake/util.py index ca75f1b55e..ee3b245b78 100644 --- a/zephyr/zmake/zmake/util.py +++ b/zephyr/zmake/zmake/util.py @@ -64,19 +64,6 @@ def locate_cros_checkout(): raise FileNotFoundError("Unable to locate a ChromiumOS checkout") -def locate_zephyr_base(zephyr_root, version): - """Locate the path to the Zephyr RTOS in a ChromiumOS checkout. - - Args: - checkout: The path to the ChromiumOS checkout. - version: The requested zephyr version, as a tuple of integers. - - Returns: - The path to the Zephyr source. - """ - return zephyr_root / "v{}.{}".format(*version[:2]) - - def read_kconfig_file(path): """Parse a Kconfig file. @@ -132,23 +119,6 @@ def write_kconfig_file(path, config, only_if_changed=True): f.write("{}={}\n".format(name, value)) -def parse_zephyr_version(version_string): - """Parse a human-readable version string (e.g., "v2.4") as a tuple. - - Args: - version_string: The human-readable version string. - - Returns: - A 2-tuple or 3-tuple of integers representing the version. - """ - match = re.fullmatch(r"v?(\d+)[._](\d+)(?:[._](\d+))?", version_string) - if not match: - raise ValueError( - "{} does not look like a Zephyr version.".format(version_string) - ) - return tuple(int(x) for x in match.groups() if x is not None) - - def read_zephyr_version(zephyr_base): """Read the Zephyr version from a Zephyr OS checkout. diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py index 8fc9542dca..a906181c47 100644 --- a/zephyr/zmake/zmake/zmake.py +++ b/zephyr/zmake/zmake/zmake.py @@ -153,17 +153,13 @@ class Zmake: jobs=0, modules_dir=None, zephyr_base=None, - zephyr_root=None, ): zmake.multiproc.reset() self._checkout = checkout - self._zephyr_base = zephyr_base - if zephyr_root: - self._zephyr_root = zephyr_root + if zephyr_base: + self.zephyr_base = zephyr_base else: - self._zephyr_root = ( - self.checkout / "src" / "third_party" / "zephyr" / "main" - ) + self.zephyr_base = self.checkout / "src" / "third_party" / "zephyr" / "main" if modules_dir: self.module_paths = zmake.modules.locate_from_directory(modules_dir) @@ -188,28 +184,11 @@ class Zmake: self._checkout = util.locate_cros_checkout() return self._checkout.resolve() - def locate_zephyr_base(self, version): - """Locate the Zephyr OS repository. - - Args: - version: If a Zephyr OS base was not supplied to Zmake, - which version to search for as a tuple of integers. - This argument is ignored if a Zephyr base was supplied - to Zmake. - Returns: - A pathlib.Path to the found Zephyr OS repository. - """ - if self._zephyr_base: - return self._zephyr_base - - return util.locate_zephyr_base(self._zephyr_root, version) - def configure( self, project_name_or_dir, build_dir=None, toolchain=None, - ignore_unsupported_zephyr_version=False, build_after_configure=False, test_after_configure=False, bringup=False, @@ -234,7 +213,6 @@ class Zmake: project=project, build_dir=build_dir, toolchain=toolchain, - ignore_unsupported_zephyr_version=ignore_unsupported_zephyr_version, build_after_configure=build_after_configure, test_after_configure=test_after_configure, bringup=bringup, @@ -247,7 +225,6 @@ class Zmake: project, build_dir=None, toolchain=None, - ignore_unsupported_zephyr_version=False, build_after_configure=False, test_after_configure=False, bringup=False, @@ -255,23 +232,6 @@ class Zmake: allow_warnings=False, ): """Set up a build directory to later be built by "zmake build".""" - supported_version = util.parse_zephyr_version(project.config.zephyr_version) - zephyr_base = self.locate_zephyr_base(supported_version).resolve() - - # Ignore the patchset from the Zephyr version. - zephyr_version = util.read_zephyr_version(zephyr_base)[:2] - - if ( - not ignore_unsupported_zephyr_version - and zephyr_version != supported_version - ): - raise ValueError( - "The Zephyr OS version (v{}.{}) is not supported by the " - "project. You may wish to either configure BUILD.py to " - "support this version, or pass " - "--ignore-unsupported-zephyr-version.".format(*zephyr_version) - ) - # Resolve build_dir if needed. if not build_dir: build_dir = ( @@ -287,7 +247,7 @@ class Zmake: generated_include_dir = (build_dir / "include").resolve() base_config = zmake.build_config.BuildConfig( - environ_defs={"ZEPHYR_BASE": str(zephyr_base), "PATH": "/usr/bin"}, + environ_defs={"ZEPHYR_BASE": str(self.zephyr_base), "PATH": "/usr/bin"}, cmake_defs={ "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "DTS_ROOT": str(self.module_paths["ec"] / "zephyr"), @@ -307,7 +267,7 @@ class Zmake: # Symlink the Zephyr base into the build directory so it can # be used in the build phase. - util.update_symlink(zephyr_base, build_dir / "zephyr_base") + util.update_symlink(self.zephyr_base, build_dir / "zephyr_base") dts_overlay_config = project.find_dts_overlays(module_paths) @@ -397,7 +357,15 @@ class Zmake: is_configured=True, ) elif build_after_configure: - return self.build(build_dir=build_dir) + if coverage: + return self._coverage_compile_only( + project=project, + build_dir=build_dir, + lcov_file=build_dir / "lcov.info", + is_configured=True, + ) + else: + return self.build(build_dir=build_dir) def build(self, build_dir, output_files_out=None, fail_on_warnings=False): """Build a pre-configured build directory.""" @@ -652,17 +620,20 @@ class Zmake: return 0 - def _coverage_compile_only(self, project, build_dir, lcov_file): + def _coverage_compile_only( + self, project, build_dir, lcov_file, is_configured=False + ): self.logger.info("Building %s in %s", project.config.project_name, build_dir) - rv = self._configure( - project=project, - build_dir=build_dir, - build_after_configure=False, - test_after_configure=False, - coverage=True, - ) - if rv: - return rv + if not is_configured: + rv = self._configure( + project=project, + build_dir=build_dir, + build_after_configure=False, + test_after_configure=False, + coverage=True, + ) + if rv: + return rv # Compute the version string. version_string = zmake.version.get_version_string( @@ -760,21 +731,17 @@ class Zmake: lcov_file = pathlib.Path(build_dir) / "{}.info".format( project.config.project_name ) - all_lcov_files.append(lcov_file) if is_test: # Configure and run the test. + all_lcov_files.append(lcov_file) self.executor.append( func=lambda: self._coverage_run_test( project, project_build_dir, lcov_file ) ) else: - # Configure and compile the non-test project. - self.executor.append( - func=lambda: self._coverage_compile_only( - project, project_build_dir, lcov_file - ) - ) + # Don't build non-test projects + self.logger.info("Skipping project %s", project.config.project_name) if self._sequential: rv = self.executor.wait() if rv: @@ -845,3 +812,19 @@ class Zmake: if proc.wait(): raise OSError(get_process_failure_msg(proc)) return 0 + + def list_projects(self, format, search_dir): + """List project names known to zmake on stdout. + + Args: + format: The formatting string to print projects with. + search_dir: Directory to start the search for + BUILD.py files at. + """ + if not search_dir: + search_dir = self.module_paths["ec"] / "zephyr" + + for project in zmake.project.find_projects(search_dir).values(): + print(format.format(config=project.config), end="") + + return 0 |