From 675087c355ac85a7a82d20e2244822ff786aa4ae Mon Sep 17 00:00:00 2001 From: Scott Collyer Date: Thu, 16 Aug 2018 11:06:33 -0700 Subject: DragonEgg: Add support for port 2 Type C This CL adds support for Type C port 2 which uses the TI USB422 TCPC and NX20P3481 PPC. BUG=b:111281797 BRANCH=none TEST=Verifed that port 2 works as a sink and source. Change-Id: I7ad200768d81fd95aee625e5871b2350412a4f79 Signed-off-by: Scott Collyer Reviewed-on: https://chromium-review.googlesource.com/1178997 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Scott Collyer Reviewed-by: Furquan Shaikh Reviewed-by: Jett Rink --- baseboard/dragonegg/baseboard.c | 35 +++++++++++++++++++++++++++++++++-- baseboard/dragonegg/baseboard.h | 4 +++- baseboard/dragonegg/usb_pd_policy.c | 18 ++++++++++++++++++ board/dragonegg/board.c | 26 +++++++++++++++++++++++++- board/dragonegg/ec.tasklist | 3 ++- board/dragonegg/gpio.inc | 4 +++- 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/baseboard/dragonegg/baseboard.c b/baseboard/dragonegg/baseboard.c index 14e9dc3923..e3f49ff336 100644 --- a/baseboard/dragonegg/baseboard.c +++ b/baseboard/dragonegg/baseboard.c @@ -8,11 +8,13 @@ #include "charge_state_v2.h" #include "chipset.h" #include "console.h" +#include "driver/ppc/nx20p348x.h" #include "driver/ppc/sn5s330.h" #include "driver/ppc/syv682x.h" #include "driver/tcpm/it83xx_pd.h" #include "driver/tcpm/tcpci.h" #include "driver/tcpm/tcpm.h" +#include "driver/tcpm/tusb422.h" #include "espi.h" #include "gpio.h" #include "hooks.h" @@ -27,6 +29,7 @@ #define USB_PD_PORT_ITE_0 0 #define USB_PD_PORT_ITE_1 1 +#define USB_PD_PORT_TUSB422_2 2 #define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) #define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) @@ -170,6 +173,13 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { .drv = &it83xx_tcpm_drv, .pol = TCPC_ALERT_ACTIVE_LOW, }, + + [USB_PD_PORT_TUSB422_2] = { + .i2c_host_port = I2C_PORT_USBC1C2, + .i2c_slave_addr = TUSB422_I2C_ADDR, + .drv = &tusb422_tcpm_drv, + .pol = TCPC_ALERT_ACTIVE_LOW, + }, }; /******************************************************************************/ @@ -186,6 +196,12 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_COUNT] = { .i2c_addr = SYV682X_ADDR0, .drv = &syv682x_drv }, + + [USB_PD_PORT_TUSB422_2] = { + .i2c_port = I2C_PORT_USBC1C2, + .i2c_addr = NX20P3481_ADDR2, + .drv = &nx20p348x_drv, + }, }; unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); @@ -201,6 +217,12 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = { .driver = &virtual_usb_mux_driver, .hpd_update = &virtual_hpd_update, }, + + [USB_PD_PORT_TUSB422_2] = { + .port_addr = 0, + .driver = &virtual_usb_mux_driver, + .hpd_update = &virtual_hpd_update, + }, }; /* Power Delivery and charging functions */ @@ -209,18 +231,28 @@ void baseboard_tcpc_init(void) { /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_USB_C0_TCPPC_INT_L); + gpio_enable_interrupt(GPIO_USB_C2_TCPPC_INT_ODL); + + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C2_TCPC_INT_ODL); + } DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_I2C + 1); uint16_t tcpc_get_alert_status(void) { + uint16_t status = 0; /* * Since C0/C1 TCPC are embedded within EC, we don't need the PDCMD * tasks.The (embedded) TCPC status since chip driver code will * handles its own interrupts and forward the correct events to * the PD_C0 task. See it83xx/intc.c */ - return 0; + + if (!gpio_get_level(GPIO_USB_C2_TCPC_INT_ODL)) + status = PD_STATUS_TCPC_ALERT_2; + + return status; } /** @@ -256,7 +288,6 @@ int board_set_active_charge_port(int port) if (!is_valid_port && port != CHARGE_PORT_NONE) return EC_ERROR_INVAL; - if (port == CHARGE_PORT_NONE) { CPRINTSUSB("Disabling all charger ports"); diff --git a/baseboard/dragonegg/baseboard.h b/baseboard/dragonegg/baseboard.h index 03f1d8bb91..d9b272b7dd 100644 --- a/baseboard/dragonegg/baseboard.h +++ b/baseboard/dragonegg/baseboard.h @@ -61,13 +61,14 @@ #undef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_VBUS_DETECT_PPC #define CONFIG_USB_PD_TCPM_ITE83XX /* C0 & C1 TCPC: ITE EC */ +#define CONFIG_USB_PD_TCPM_TUSB422 /* C1 TCPC: TUSB422 */ #define CONFIG_USB_POWER_DELIVERY /* * TODO (b/111281797): DragonEgg has 3 ports. Only adding support for the port * on the MLB for now. In addition, this config option will likely move to * board.h as it likely board dependent and not same across all follower boards. */ -#define CONFIG_USB_PD_PORT_COUNT 2 +#define CONFIG_USB_PD_PORT_COUNT 3 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING @@ -85,6 +86,7 @@ #define CONFIG_USB_MUX_VIRTUAL #define CONFIG_USBC_PPC_SN5S330 /* C0 PPC */ #define CONFIG_USBC_PPC_SYV682X /* C1 PPC */ +#define CONFIG_USBC_PPC_NX20P3481 /* C2 PPC */ #define CONFIG_USBC_PPC_VCONN #define CONFIG_USBC_SS_MUX #define CONFIG_USBC_VCONN diff --git a/baseboard/dragonegg/usb_pd_policy.c b/baseboard/dragonegg/usb_pd_policy.c index e7def7fe71..1fe2b928d7 100644 --- a/baseboard/dragonegg/usb_pd_policy.c +++ b/baseboard/dragonegg/usb_pd_policy.c @@ -12,6 +12,8 @@ #include "ec_commands.h" #include "gpio.h" #include "system.h" +#include "tcpci.h" +#include "tcpm.h" #include "usb_mux.h" #include "usb_pd.h" #include "usbc_ppc.h" @@ -172,6 +174,22 @@ void pd_transition_voltage(int idx) #ifdef CONFIG_USB_PD_VBUS_DETECT_PPC int pd_snk_is_vbus_provided(int port) { + /* + * TODO(b/112661747): Until per port VBUS detection methods are + * supported, DragonEgg needs to have CONFIG_USB_PD_VBUS_DETECT_PPC + * defined, but the nx20p3481 PPC on port 2 does not support VBUS + * detection. In the meantime, check specifically for port 2, and rely + * on the TUSB422 TCPC for VBUS status. Note that the tcpm method can't + * be called directly here as it's not supported unless + * CONFIG_USB_PD_VBUS_DETECT_TCPC is defined. + */ + int reg; + + if (port == 2) { + if (tcpc_read(port, TCPC_REG_POWER_STATUS, ®)) + return 0; + return reg & TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; + } return ppc_is_vbus_present(port); } #endif diff --git a/board/dragonegg/board.c b/board/dragonegg/board.c index 6b784a9baa..ccff76debf 100644 --- a/board/dragonegg/board.c +++ b/board/dragonegg/board.c @@ -9,10 +9,13 @@ #include "common.h" #include "charger.h" #include "console.h" +#include "driver/ppc/nx20p348x.h" #include "driver/ppc/sn5s330.h" +#include "ec_commands.h" #include "extpower.h" #include "gpio.h" #include "hooks.h" +#include "host_command.h" #include "intc.h" #include "lid_switch.h" #include "power.h" @@ -26,8 +29,29 @@ static void ppc_interrupt(enum gpio_signal signal) { - if (signal == GPIO_USB_C0_TCPPC_INT_L) + + switch (signal) { + case GPIO_USB_C0_TCPPC_INT_L: sn5s330_interrupt(0); + break; + + case GPIO_USB_C2_TCPPC_INT_ODL: + nx20p348x_interrupt(2); + break; + + default: + break; + } +} + +static void tcpc_alert_event(enum gpio_signal signal) +{ + + +#ifdef HAS_TASK_PDCMD + /* Exchange status with TCPCs */ + host_command_pd_send_status(PD_CHARGE_NO_CHANGE); +#endif } #include "gpio_list.h" /* Must come after other header files. */ diff --git a/board/dragonegg/ec.tasklist b/board/dragonegg/ec.tasklist index 04618aa7e2..cce01989ec 100644 --- a/board/dragonegg/ec.tasklist +++ b/board/dragonegg/ec.tasklist @@ -31,5 +31,6 @@ TASK_ALWAYS(POWERBTN, power_button_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE) \ - TASK_ALWAYS(PD_C1, pd_task, NULL, LARGER_TASK_STACK_SIZE) + TASK_ALWAYS(PD_C1, pd_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C2, pd_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/board/dragonegg/gpio.inc b/board/dragonegg/gpio.inc index 417402d251..ab1c7652be 100644 --- a/board/dragonegg/gpio.inc +++ b/board/dragonegg/gpio.inc @@ -29,7 +29,9 @@ GPIO_INT(PG_EC_RSMRST_ODL,PIN(E, 1), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(PG_EC_DSW_PWROK, PIN(D, 6), GPIO_INT_BOTH, power_signal_interrupt) /* USB-C interrupts */ -GPIO_INT(USB_C0_TCPPC_INT_L, PIN(B, 2), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C0_TCPPC_INT_L, PIN(B, 2), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C2_TCPPC_INT_ODL, PIN(L, 1), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C2_TCPC_INT_ODL, PIN(K, 6), GPIO_INT_FALLING, tcpc_alert_event) /* Misc. interrupts */ /* TODO (b:110880394) Uncomment this when support for buttons is added */ -- cgit v1.2.1