From f1ba420de66fdb8b2a827bf60e228e64521dd12a Mon Sep 17 00:00:00 2001 From: Eric Yilun Lin Date: Fri, 26 Nov 2021 14:05:08 +0800 Subject: zephyr: krabby: refactor usbc_config Move non-share code into krabby/usbc_config.c: 1. charger configs 2. bc12 configs 3. ppc configs 4. tcpc configs 5. VBUS ADC getter BUG=b:207802869 TEST=zmake testall BRANCH=none Change-Id: I134c843826dcce536d5fa8b1d52e41ff786175a7 Signed-off-by: Eric Yilun Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3303264 Tested-by: Eric Yilun Lin Commit-Queue: Eric Yilun Lin Reviewed-by: Ting Shen --- zephyr/projects/corsola/CMakeLists.txt | 2 + .../corsola/include/baseboard_usbc_config.h | 15 ++ zephyr/projects/corsola/src/krabby/usbc_config.c | 255 +++++++++++++++++++++ zephyr/projects/corsola/src/usb_pd_policy.c | 1 + zephyr/projects/corsola/src/usbc_config.c | 239 +------------------ 5 files changed, 275 insertions(+), 237 deletions(-) create mode 100644 zephyr/projects/corsola/include/baseboard_usbc_config.h diff --git a/zephyr/projects/corsola/CMakeLists.txt b/zephyr/projects/corsola/CMakeLists.txt index 3856119707..79ac32d915 100644 --- a/zephyr/projects/corsola/CMakeLists.txt +++ b/zephyr/projects/corsola/CMakeLists.txt @@ -25,6 +25,8 @@ if(DEFINED CONFIG_BOARD_KRABBY) 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/usbc_config.c") elseif(DEFINED CONFIG_BOARD_KINGLER) project(kingler) endif() 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/src/krabby/usbc_config.c b/zephyr/projects/corsola/src/krabby/usbc_config.c index 8a942ed8c4..2b5ec7204a 100644 --- a/zephyr/projects/corsola/src/krabby/usbc_config.c +++ b/zephyr/projects/corsola/src/krabby/usbc_config.c @@ -5,12 +5,106 @@ /* Krabby board-specific USB-C configuration */ +#include "adc.h" +#include "baseboard_usbc_config.h" +#include "bc12/pi3usb9201_public.h" +#include "charge_manager.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" #include "driver/tcpm/it83xx_pd.h" #include "driver/usb_mux/ps8743.h" #include "hooks.h" +#include "ppc/syv682x_public.h" +#include "usb_mux/it5205_public.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, + }, +}; + +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, + } +}; +/* PPC */ +struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .i2c_port = I2C_PORT_PPC0, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .drv = &syv682x_drv, + .frs_en = GPIO_USB_C0_PPC_FRSINFO, + }, + { + .i2c_port = I2C_PORT_PPC1, + .i2c_addr_flags = SYV682X_ADDR0_FLAGS, + .drv = &syv682x_drv, + .frs_en = GPIO_USB_C1_FRS_EN, + }, +}; +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +struct bc12_config bc12_ports[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { .drv = NULL }, + { .drv = &pi3usb9201_drv }, +}; + +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 (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. */ + task_disable_task(TASK_ID_USB_CHG_P1); +} +/* Must be done after I2C and subboard */ +DECLARE_HOOK(HOOK_INIT, board_sub_bc12_init, HOOK_PRIO_INIT_I2C + 1); + +static void board_usbc_init(void) +{ + 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] = { + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + /* TCPC is embedded within EC so no i2c config needed */ + .drv = &it8xxx2_tcpm_drv, + /* Alert is active-low, push-pull */ + .flags = 0, + }, + { + .bus_type = EC_BUS_TYPE_EMBEDDED, + /* TCPC is embedded within EC so no i2c config needed */ + .drv = &it8xxx2_tcpm_drv, + /* Alert is active-low, push-pull */ + .flags = 0, + }, +}; + void board_usb_mux_init(void) { if (corsola_get_db_type() == CORSOLA_DB_TYPEC) { @@ -24,6 +118,22 @@ void board_usb_mux_init(void) } 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 @@ -40,3 +150,148 @@ const struct cc_para_t *board_get_cc_tuning_parameter(enum usbpd_port port) 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) +{ + /* + * C0 & C1: TCPC is embedded in the EC and processes interrupts in the + * chip code (it83xx/intc.c) + */ + return 0; +} + +void board_reset_pd_mcu(void) +{ + /* + * C0 & C1: TCPC is embedded in the EC and processes interrupts in the + * chip code (it83xx/intc.c) + */ +} + +int board_set_active_charge_port(int port) +{ + int i; + int is_valid_port = (port >= 0 && port < board_get_usb_pd_port_count()); + + if (!is_valid_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + if (port == CHARGE_PORT_NONE) { + CPRINTS("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)) + CPRINTS("Disabling C%d as sink failed.", i); + } + + return EC_SUCCESS; + } + + /* Check if the port is sourcing VBUS. */ + if (ppc_is_sourcing_vbus(port)) { + CPRINTS("Skip enable C%d", port); + return EC_ERROR_INVAL; + } + + CPRINTS("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)) + CPRINTS("C%d: sink path disable failed.", i); + } + + /* Enable requested charge port. */ + if (ppc_vbus_sink_enable(port, 1)) { + CPRINTS("C%d: sink path enable failed.", port); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +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, +}; + +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 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) +{ + if (port == 0) + return ADC_VBUS_C0; + if (port == 1) + return ADC_VBUS_C1; + CPRINTSUSB("Unknown vbus adc port id: %d", port); + return ADC_VBUS_C0; +} +#endif /* CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT */ diff --git a/zephyr/projects/corsola/src/usb_pd_policy.c b/zephyr/projects/corsola/src/usb_pd_policy.c index 3769f189ae..a30c5e2fe3 100644 --- a/zephyr/projects/corsola/src/usb_pd_policy.c +++ b/zephyr/projects/corsola/src/usb_pd_policy.c @@ -2,6 +2,7 @@ * 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 "charge_manager.h" diff --git a/zephyr/projects/corsola/src/usbc_config.c b/zephyr/projects/corsola/src/usbc_config.c index f71fd65cc8..c4917b252d 100644 --- a/zephyr/projects/corsola/src/usbc_config.c +++ b/zephyr/projects/corsola/src/usbc_config.c @@ -6,11 +6,10 @@ /* Corsola baseboard-specific USB-C configuration */ #include "adc.h" -#include "bc12/pi3usb9201_public.h" +#include "baseboard_usbc_config.h" #include "button.h" #include "charger.h" #include "charge_state_v2.h" -#include "charger/isl923x_public.h" #include "console.h" #include "ec_commands.h" #include "extpower.h" @@ -25,34 +24,20 @@ #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) -const struct charger_config_t chg_chips[] = { - { - .i2c_port = I2C_PORT_CHARGER, - .i2c_addr_flags = ISL923X_ADDR_FLAGS, - .drv = &isl923x_drv, - }, -}; - /* 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); @@ -69,53 +54,6 @@ static void board_tcpc_init(void) /* 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] = { - { - .i2c_port = I2C_PORT_PPC0, - .i2c_addr_flags = SYV682X_ADDR0_FLAGS, - .drv = &syv682x_drv, - .frs_en = GPIO_USB_C0_PPC_FRSINFO, - }, - { - .i2c_port = I2C_PORT_PPC1, - .i2c_addr_flags = SYV682X_ADDR0_FLAGS, - .drv = &syv682x_drv, - .frs_en = GPIO_USB_C1_FRS_EN, - }, -}; -unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); - -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 = NULL }, - { .drv = &pi3usb9201_drv }, -}; - -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 (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. */ - task_disable_task(TASK_ID_USB_CHG_P1); -} -/* Must be done after I2C and subboard */ -DECLARE_HOOK(HOOK_INIT, board_sub_bc12_init, HOOK_PRIO_INIT_I2C + 1); - __override uint8_t board_get_usb_pd_port_count(void) { if (corsola_get_db_type() == CORSOLA_DB_TYPEC) @@ -139,104 +77,6 @@ void usb_a0_interrupt(enum gpio_signal signal) 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) -{ - /* TODO: check correct operation for Corsola */ -} - -/* TCPC */ -const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { - { - .bus_type = EC_BUS_TYPE_EMBEDDED, - /* TCPC is embedded within EC so no i2c config needed */ - .drv = &it8xxx2_tcpm_drv, - /* Alert is active-low, push-pull */ - .flags = 0, - }, - { - .bus_type = EC_BUS_TYPE_EMBEDDED, - /* TCPC is embedded within EC so no i2c config needed */ - .drv = &it8xxx2_tcpm_drv, - /* Alert is active-low, push-pull */ - .flags = 0, - }, -}; - -uint16_t tcpc_get_alert_status(void) -{ - /* - * C0 & C1: TCPC is embedded in the EC and processes interrupts in the - * chip code (it83xx/intc.c) - */ - return 0; -} - -void board_reset_pd_mcu(void) -{ - /* - * C0 & C1: TCPC is embedded in the EC and processes interrupts in the - * chip code (it83xx/intc.c) - */ -} - void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, int charge_mv) { @@ -253,59 +93,6 @@ void board_pd_vconn_ctrl(int port, enum usbpd_cc_pin cc_pin, int enabled) */ } -int board_set_active_charge_port(int port) -{ - int i; - int is_valid_port = (port >= 0 && port < board_get_usb_pd_port_count()); - - if (!is_valid_port && port != CHARGE_PORT_NONE) - return EC_ERROR_INVAL; - - if (port == CHARGE_PORT_NONE) { - CPRINTS("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)) - CPRINTS("Disabling C%d as sink failed.", i); - } - - return EC_SUCCESS; - } - - /* Check if the port is sourcing VBUS. */ - if (ppc_is_sourcing_vbus(port)) { - CPRINTS("Skip enable C%d", port); - return EC_ERROR_INVAL; - } - - CPRINTS("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)) - CPRINTS("C%d: sink path disable failed.", i); - } - - /* Enable requested charge port. */ - if (ppc_vbus_sink_enable(port, 1)) { - CPRINTS("C%d: sink path enable failed.", port); - return EC_ERROR_UNKNOWN; - } - - return EC_SUCCESS; -} - /** * Handle PS185 HPD changing state. */ @@ -340,31 +127,9 @@ void x_ec_interrupt(enum gpio_signal signal) if (sub == CORSOLA_DB_TYPEC) /* C1: PPC interrupt */ - syv682x_interrupt(1); + ppc_interrupt(signal); else if (sub == CORSOLA_DB_HDMI) hdmi_hpd_interrupt(signal); else CPRINTS("Undetected subboard interrupt."); } - -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; -} - -#ifdef CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT -enum adc_channel board_get_vbus_adc(int port) -{ - if (port == 0) - return ADC_VBUS_C0; - if (port == 1) - return ADC_VBUS_C1; - CPRINTSUSB("Unknown vbus adc port id: %d", port); - return ADC_VBUS_C0; -} -#endif /* CONFIG_USB_PD_VBUS_MEASURE_ADC_EACH_PORT */ -- cgit v1.2.1