diff options
author | Lu Zhang <lu.zhang@bitland.corp-partner.google.com> | 2020-06-04 19:52:30 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-05 12:13:36 +0000 |
commit | 6c08aba5c3ce54888abcdb2fef6f6b093865a5d6 (patch) | |
tree | e057c536bc0c7a183f0c1b8008e29c9fd04a964e /board/dalboz | |
parent | 8432637e62220c5eeb237f14ae1f7cd4e8a7ce84 (diff) | |
download | chrome-ec-6c08aba5c3ce54888abcdb2fef6f6b093865a5d6.tar.gz |
zork: Move tcpc,ppc,bc12 from baseboard to board
BUG=b:158125500
BRANCH=none
TEST=Build all zork boards
Signed-off-by: Lu Zhang <lu.zhang@bitland.corp-partner.google.com>
Change-Id: I86a21a049f97c42d330be6c1bfbecbda10e1ebb6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2230941
Reviewed-by: Peter Marheine <pmarheine@chromium.org>
Diffstat (limited to 'board/dalboz')
-rw-r--r-- | board/dalboz/board.c | 207 | ||||
-rw-r--r-- | board/dalboz/board.h | 12 |
2 files changed, 219 insertions, 0 deletions
diff --git a/board/dalboz/board.c b/board/dalboz/board.c index 37f1eba31e..edfcdafc77 100644 --- a/board/dalboz/board.c +++ b/board/dalboz/board.c @@ -8,7 +8,10 @@ #include "cros_board_info.h" #include "driver/accel_lis2dw12.h" #include "driver/accelgyro_lsm6dsm.h" +#include "driver/bc12/pi3usb9201.h" #include "driver/ioexpander/pcal6408.h" +#include "driver/ppc/aoz1380.h" +#include "driver/ppc/nx20p348x.h" #include "driver/tcpm/nct38xx.h" #include "driver/usb_mux/ps8740.h" #include "driver/usb_mux/ps8743.h" @@ -28,6 +31,11 @@ #include "tablet_mode.h" #include "task.h" #include "usb_charge.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" + +#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args) /* This I2C moved. Temporarily detect and support the V0 HW. */ int I2C_PORT_BATTERY = I2C_PORT_BATTERY_V1; @@ -190,6 +198,205 @@ static int board_ps8743_mux_set(const struct usb_mux *me, return EC_SUCCESS; } +struct ppc_config_t ppc_chips[] = { + [USBC_PORT_C0] = { + /* Device does not talk I2C */ + .drv = &aoz1380_drv + }, + + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_TCPC1, + .i2c_addr_flags = NX20P3483_ADDR1_FLAGS, + .drv = &nx20p348x_drv + }, +}; +BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT); +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +void ppc_interrupt(enum gpio_signal signal) +{ + switch (signal) { + case GPIO_USB_C0_PPC_FAULT_ODL: + aoz1380_interrupt(USBC_PORT_C0); + break; + + case GPIO_USB_C1_PPC_INT_ODL: + nx20p348x_interrupt(USBC_PORT_C1); + break; + + default: + break; + } +} + +int board_set_active_charge_port(int port) +{ + int is_valid_port = (port >= 0 && + port < CONFIG_USB_PD_PORT_MAX_COUNT); + 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; +} + +const struct tcpc_config_t tcpc_config[] = { + [USBC_PORT_C0] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_TCPC0, + .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_TCPC1, + .addr_flags = NCT38XX_I2C_ADDR1_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); + +const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { + [USBC_PORT_C0] = { + .i2c_port = I2C_PORT_TCPC0, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, + + [USBC_PORT_C1] = { + .i2c_port = I2C_PORT_TCPC1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT); + +static void reset_pd_port(int port, enum gpio_signal reset_gpio_l, + int hold_delay, int finish_delay) +{ + gpio_set_level(reset_gpio_l, 0); + msleep(hold_delay); + gpio_set_level(reset_gpio_l, 1); + if (finish_delay) + msleep(finish_delay); +} + +void board_reset_pd_mcu(void) +{ + /* Reset TCPC0 */ + reset_pd_port(USBC_PORT_C0, GPIO_USB_C0_TCPC_RST_L, + NCT38XX_RESET_HOLD_DELAY_MS, + NCT38XX_RESET_POST_DELAY_MS); + + /* Reset TCPC1 */ + reset_pd_port(USBC_PORT_C1, GPIO_USB_C1_TCPC_RST_L, + NCT38XX_RESET_HOLD_DELAY_MS, + NCT38XX_RESET_POST_DELAY_MS); +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + + /* + * Check which port has the ALERT line set and ignore if that TCPC has + * its reset line active. + */ + if (!gpio_get_level(GPIO_USB_C0_TCPC_INT_ODL)) { + if (gpio_get_level(GPIO_USB_C0_TCPC_RST_L) != 0) + status |= PD_STATUS_TCPC_ALERT_0; + } + + if (!gpio_get_level(GPIO_USB_C1_TCPC_INT_ODL)) { + if (gpio_get_level(GPIO_USB_C1_TCPC_RST_L) != 0) + status |= PD_STATUS_TCPC_ALERT_1; + } + + return status; +} + +void tcpc_alert_event(enum gpio_signal signal) +{ + int port = -1; + + switch (signal) { + case GPIO_USB_C0_TCPC_INT_ODL: + port = 0; + break; + case GPIO_USB_C1_TCPC_INT_ODL: + port = 1; + break; + default: + return; + } + + schedule_deferred_pd_interrupt(port); +} + +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, 0); + break; + + case GPIO_USB_C1_BC12_INT_ODL: + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12, 0); + break; + + default: + break; + } +} + static void setup_fw_config(void) { uint32_t board_version = 0; diff --git a/board/dalboz/board.h b/board/dalboz/board.h index ce492613bf..392a3d1f37 100644 --- a/board/dalboz/board.h +++ b/board/dalboz/board.h @@ -141,6 +141,11 @@ enum ec_cfg_usb_db_type { DALBOZ_DB_D_OPT2_USBA_HDMI = 1, }; +enum usbc_port { + USBC_PORT_C0 = 0, + USBC_PORT_C1, + USBC_PORT_COUNT +}; #define HAS_USBC1 \ (BIT(DALBOZ_DB_D_OPT1_USBAC)) @@ -174,6 +179,13 @@ static inline bool ec_config_has_hdmi_retimer_pi3hdx1204(void) extern enum gpio_signal IOEX_USB_A1_RETIMER_EN; extern enum gpio_signal IOEX_USB_A1_CHARGE_EN_DB_L; +void board_reset_pd_mcu(void); + +/* Common definition for the USB PD interrupt handlers. */ +void tcpc_alert_event(enum gpio_signal signal); +void bc12_interrupt(enum gpio_signal signal); +void ppc_interrupt(enum gpio_signal signal); + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ |