diff options
-rw-r--r-- | board/amenia/board.c | 24 | ||||
-rw-r--r-- | board/amenia/board.h | 2 | ||||
-rw-r--r-- | board/amenia/gpio.inc | 8 | ||||
-rw-r--r-- | board/amenia/usb_pd_policy.c | 3 | ||||
-rw-r--r-- | common/usb_charger.c | 12 | ||||
-rw-r--r-- | driver/charger/bd99955.c | 106 | ||||
-rw-r--r-- | driver/charger/bd99955.h | 14 | ||||
-rw-r--r-- | include/usb_charge.h | 13 |
8 files changed, 144 insertions, 38 deletions
diff --git a/board/amenia/board.c b/board/amenia/board.c index 63d53fdcc2..6895c868f3 100644 --- a/board/amenia/board.c +++ b/board/amenia/board.c @@ -80,26 +80,6 @@ static void tcpc_alert_event(enum gpio_signal signal) #endif } -void vbus0_evt(enum gpio_signal signal) -{ - if (!gpio_get_level(GPIO_USB_C0_RST_L)) - return; - - /* VBUS present GPIO is inverted */ - usb_charger_vbus_change(0, !gpio_get_level(signal)); - task_wake(TASK_ID_PD_C0); -} - -void vbus1_evt(enum gpio_signal signal) -{ - if (!gpio_get_level(GPIO_USB_C1_RST_L)) - return; - - /* VBUS present GPIO is inverted */ - usb_charger_vbus_change(1, !gpio_get_level(signal)); - task_wake(TASK_ID_PD_C1); -} - void board_set_tcpc_power_mode(int port, int normal_mode) { } @@ -216,11 +196,9 @@ void board_tcpc_init(void) /* Enable TCPC0 interrupt */ gpio_enable_interrupt(GPIO_USB_C0_PD_INT); - gpio_enable_interrupt(GPIO_USB_C0_VBUS_WAKE_L); /* Enable TCPC1 interrupt */ gpio_enable_interrupt(GPIO_USB_C1_PD_INT_L); - gpio_enable_interrupt(GPIO_USB_C1_VBUS_WAKE_L); } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1); @@ -284,10 +262,8 @@ void chipset_do_shutdown(void) /* Initialize board. */ static void board_init(void) { -#if 0 /* TODO: CHARGER */ /* Enable charger interrupt */ gpio_enable_interrupt(GPIO_CHARGER_INT_L); -#endif /* Enable tablet mode interrupt for input device enable */ gpio_enable_interrupt(GPIO_TABLET_MODE_L); diff --git a/board/amenia/board.h b/board/amenia/board.h index d4dfd2b705..d8e417ea7e 100644 --- a/board/amenia/board.h +++ b/board/amenia/board.h @@ -86,7 +86,7 @@ #define TCPC1_I2C_ADDR 0x16 #define CONFIG_USB_PD_TCPM_MUX #define CONFIG_USB_PD_TRY_SRC -#define CONFIG_USB_PD_VBUS_DETECT_GPIO +#define CONFIG_USB_PD_VBUS_DETECT_CHARGER #define CONFIG_USB_PORT_POWER_SMART #define GPIO_USB1_CTL1 GPIO_USB_CTL1 #define GPIO_USB1_CTL2 GPIO_UNIMPLEMENTED diff --git a/board/amenia/gpio.inc b/board/amenia/gpio.inc index 3a32f511a2..8e0dc6c98a 100644 --- a/board/amenia/gpio.inc +++ b/board/amenia/gpio.inc @@ -26,14 +26,12 @@ GPIO_INT(PCH_SUSPWRDNACK, PIN(B, 1), GPIO_INT_BOTH, power_ GPIO_INT(ALL_SYS_PGOOD, PIN(6, 2), GPIO_INT_BOTH, power_signal_interrupt) /* A31 - PS2_CLK1 for ALL_SYS_PWRGD */ GPIO_INT(RSMRST_L_PGOOD, PIN(9, 3), GPIO_INT_BOTH, power_signal_interrupt) /* A46 - TA1/F_DIO2 for PMIC_RSMRST_N */ -GPIO_INT(USB_C0_VBUS_WAKE_L, PIN(A, 7), GPIO_INT_BOTH | GPIO_PULL_UP, vbus0_evt) /* B56 - PS2_DAT3/TB2/F_DIO3 for USB_C0_VBUS_DET_N */ GPIO_INT(USB_C0_PD_INT, PIN(8, 5), GPIO_INT_RISING, tcpc_alert_event) /* A43 - RXD for USB_C0_PHY_INT */ - -GPIO_INT(USB_C1_VBUS_WAKE_L, PIN(6, 1), GPIO_INT_BOTH | GPIO_PULL_UP, vbus1_evt) /* B32 - GPIO61 for USB_C1_VBUS_DET_N */ GPIO_INT(USB_C1_PD_INT_L, PIN(9, 4), GPIO_INT_FALLING, tcpc_alert_event) /* B49 - GPIO94 for USB_C1_PHY_INT_N */ +GPIO_INT(CHARGER_INT_L, PIN(0, 2), GPIO_INT_FALLING | GPIO_PULL_UP, bd99955_vbus_interrupt) /* A01 - GPIO02 for CHRGR_INT_N */ -/* TODO: CHARGER */ -GPIO(CHARGER_INT_L, PIN(0, 2), GPIO_INT_FALLING | GPIO_PULL_UP ) /* A01 - GPIO02 for CHRGR_INT_N */ +GPIO(NC_USB_C0_VBUS_WAKE_L, PIN(A, 7), GPIO_INPUT | GPIO_PULL_UP) /* B56 - PS2_DAT3/TB2/F_DIO3 for USB_C0_VBUS_DET_N */ +GPIO(NC_USB_C1_VBUS_WAKE_L, PIN(6, 1), GPIO_INPUT | GPIO_PULL_UP) /* B32 - GPIO61 for USB_C1_VBUS_DET_N */ /* Board ID */ GPIO(BOARD_VERSION1, PIN(0, 4), GPIO_INPUT) /* A02 - KSO13 for EC_BRD_ID1 */ diff --git a/board/amenia/usb_pd_policy.c b/board/amenia/usb_pd_policy.c index e2355d93d2..821272beb0 100644 --- a/board/amenia/usb_pd_policy.c +++ b/board/amenia/usb_pd_policy.c @@ -105,8 +105,7 @@ void typec_set_input_current_limit(int port, uint32_t max_ma, int pd_snk_is_vbus_provided(int port) { - return !gpio_get_level(port ? GPIO_USB_C1_VBUS_WAKE_L : - GPIO_USB_C0_VBUS_WAKE_L); + return bd99955_is_vbus_provided(port); } int pd_board_checks(void) diff --git a/common/usb_charger.c b/common/usb_charger.c index a6b580072b..9888dac199 100644 --- a/common/usb_charger.c +++ b/common/usb_charger.c @@ -62,11 +62,13 @@ void usb_charger_vbus_change(int port, int vbus_level) pd_vbus_low(port); /* Update VBUS supplier and signal VBUS change to USB_CHG task */ update_vbus_supplier(port, vbus_level); -#if CONFIG_USB_PD_PORT_COUNT == 2 - task_set_event(port ? TASK_ID_USB_CHG_P1 : TASK_ID_USB_CHG_P0, - USB_CHG_EVENT_VBUS, 0); -#else - task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_VBUS, 0); + + /* USB Charger task */ + task_set_event(USB_CHG_PORT_TO_TASK_ID(port), USB_CHG_EVENT_VBUS, 0); + +#ifdef CONFIG_USB_PD_VBUS_DETECT_CHARGER + /* USB PD task */ + task_wake(PD_PORT_TO_TASK_ID(port)); #endif } diff --git a/driver/charger/bd99955.c b/driver/charger/bd99955.c index cd3e446fba..6f3ce6c90f 100644 --- a/driver/charger/bd99955.c +++ b/driver/charger/bd99955.c @@ -306,8 +306,70 @@ static void bd99955_bc12_detach(int port, int type) /* notify host of power info change */ pd_send_host_event(PD_EVENT_POWER_CHANGE); } -#endif /* defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1) */ +#ifdef CONFIG_USB_PD_VBUS_DETECT_CHARGER +static int bd99955_enable_vbus_detect_interrupts(int port, int enable) +{ + int reg; + int rv; + int port_reg; + int mask_val; + + /* 1st Level Interrupt Setting */ + rv = ch_raw_read16(BD99955_CMD_INT0_SET, ®, + BD99955_EXTENDED_COMMAND); + if (rv) + return rv; + + mask_val = ((port == BD99955_CHARGE_PORT_VBUS) ? + BD99955_CMD_INT0_SET_INT1_EN : + BD99955_CMD_INT0_SET_INT2_EN) | + BD99955_CMD_INT0_SET_INT0_EN; + if (enable) + reg |= mask_val; + else + reg &= ~mask_val; + + rv = ch_raw_write16(BD99955_CMD_INT0_SET, reg, + BD99955_EXTENDED_COMMAND); + if (rv) + return rv; + + /* 2nd Level Interrupt Setting */ + port_reg = (port == BD99955_CHARGE_PORT_VBUS) ? + BD99955_CMD_INT1_SET : BD99955_CMD_INT2_SET; + rv = ch_raw_read16(port_reg, ®, BD99955_EXTENDED_COMMAND); + if (rv) + return rv; + + if (enable) + reg |= (BD99955_CMD_INT_SET_RES | BD99955_CMD_INT_SET_DET); + else + reg &= ~(BD99955_CMD_INT_SET_RES | BD99955_CMD_INT_SET_DET); + + return ch_raw_write16(port_reg, reg, BD99955_EXTENDED_COMMAND); +} + +static int bd99955_get_vbus_detect_interrupts(int port, int get) +{ + int rv; + int reg; + int port_reg; + + port_reg = (port == BD99955_CHARGE_PORT_VBUS) ? + BD99955_CMD_INT1_STATUS : BD99955_CMD_INT2_STATUS; + if (get) { + rv = ch_raw_read16(port_reg, ®, BD99955_EXTENDED_COMMAND); + + return rv ? 0 : reg & + (BD99955_CMD_INT_SET_RES | BD99955_CMD_INT_SET_DET); + } else + return ch_raw_write16(port_reg, + (BD99955_CMD_INT_SET_RES | BD99955_CMD_INT_SET_DET), + BD99955_EXTENDED_COMMAND); +} +#endif /* CONFIG_USB_PD_VBUS_DETECT_CHARGER */ +#endif /* defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1) */ /* chip specific interfaces */ @@ -570,6 +632,12 @@ static void bd99995_init(void) reg &= ~BD99955_CMD_VM_CTRL_SET_EXTIADPEN; ch_raw_write16(BD99955_CMD_VM_CTRL_SET, reg, BD99955_EXTENDED_COMMAND); + +#if (defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1)) && \ + defined(CONFIG_USB_PD_VBUS_DETECT_CHARGER) + bd99955_enable_vbus_detect_interrupts(BD99955_CHARGE_PORT_VBUS, 1); + bd99955_enable_vbus_detect_interrupts(BD99955_CHARGE_PORT_VCC, 1); +#endif } DECLARE_HOOK(HOOK_INIT, bd99995_init, HOOK_PRIO_INIT_EXTPOWER); @@ -697,12 +765,48 @@ void usb_charger_set_switches(int port, enum usb_switch setting) bd99955_enable_usb_switch(port, usb_switch_state[port]); } +#ifdef CONFIG_USB_PD_VBUS_DETECT_CHARGER +/* TODO: Use only one usb_charger_task for both the ports */ +void bd99955_vbus_interrupt_deferred(void) +{ + int port; + int intr; + + for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) { + /* Get the VBUS interrupt */ + intr = bd99955_get_vbus_detect_interrupts(port, 1); + if (!intr) + continue; + + if (intr & BD99955_CMD_INT_SET_RES) + usb_charger_vbus_change(port, 0); + + if (intr & BD99955_CMD_INT_SET_DET) + usb_charger_vbus_change(port, 1); + + /* Clear the VBUS interrupt */ + bd99955_get_vbus_detect_interrupts(port, 0); + } +} +DECLARE_DEFERRED(bd99955_vbus_interrupt_deferred); + +void bd99955_vbus_interrupt(enum gpio_signal signal) +{ + hook_call_deferred(&bd99955_vbus_interrupt_deferred_data, 0); +} +#endif /* CONFIG_USB_PD_VBUS_DETECT_CHARGER */ + void usb_charger_task(void) { int port = (task_get_current() == TASK_ID_USB_CHG_P0 ? 0 : 1); int bc12_type = CHARGE_SUPPLIER_NONE; int vbus_provided; +#ifdef CONFIG_USB_PD_VBUS_DETECT_CHARGER + /* Clear any pending VBUS interrupts */ + bd99955_get_vbus_detect_interrupts(port, 0); +#endif + while (1) { vbus_provided = pd_snk_is_vbus_provided(port); diff --git a/driver/charger/bd99955.h b/driver/charger/bd99955.h index 6b508611f5..87a1e7bc67 100644 --- a/driver/charger/bd99955.h +++ b/driver/charger/bd99955.h @@ -218,7 +218,15 @@ enum bd99955_charge_port { #define BD99955_CMD_EXTIADP_AVE_VAL 0x63 #define BD99955_CMD_VACPCLPS_TH_SET 0x64 #define BD99955_CMD_INT0_SET 0x68 +#define BD99955_CMD_INT0_SET_INT2_EN (1 << 2) +#define BD99955_CMD_INT0_SET_INT1_EN (1 << 1) +#define BD99955_CMD_INT0_SET_INT0_EN (1 << 0) + #define BD99955_CMD_INT1_SET 0x69 +/* Bits for both INT1 & INT2 reg */ +#define BD99955_CMD_INT_SET_DET (1 << 1) +#define BD99955_CMD_INT_SET_RES (1 << 0) + #define BD99955_CMD_INT2_SET 0x6A #define BD99955_CMD_INT3_SET 0x6B #define BD99955_CMD_INT4_SET 0x6C @@ -227,6 +235,10 @@ enum bd99955_charge_port { #define BD99955_CMD_INT7_SET 0x6F #define BD99955_CMD_INT0_STATUS 0x70 #define BD99955_CMD_INT1_STATUS 0x71 +/* Bits for both INT1_STATUS & INT2_STATUS reg */ +#define BD99955_CMD_INT_STATUS_DET (1 << 1) +#define BD99955_CMD_INT_STATUS_RES (1 << 0) + #define BD99955_CMD_INT2_STATUS 0x72 #define BD99955_CMD_INT3_STATUS 0x73 #define BD99955_CMD_INT4_STATUS 0x74 @@ -251,5 +263,7 @@ int bd99955_is_vbus_provided(int port); int bd99955_select_input_port(enum bd99955_charge_port port); /* Enable/Disable charging triggered by BC1.2 */ int bd99955_bc12_enable_charging(enum bd99955_charge_port port, int enable); +/* Interrupt handler for USB charger VBUS */ +void bd99955_vbus_interrupt(enum gpio_signal signal); #endif /* __CROS_EC_BD99955_H */ diff --git a/include/usb_charge.h b/include/usb_charge.h index 5d21a6aab9..5de334583d 100644 --- a/include/usb_charge.h +++ b/include/usb_charge.h @@ -52,6 +52,19 @@ int usb_charge_ports_enabled(void); #define USB_CHG_EVENT_VBUS TASK_EVENT_CUSTOM(2) #define USB_CHG_EVENT_INTR TASK_EVENT_CUSTOM(4) +/* + * Define USB_CHG_PORT_TO_TASK_ID() and TASK_ID_TO_USB_CHG__PORT() macros to + * go between USB_CHG port number and task ID. Assume that TASK_ID_USB_CHG_P0, + * is the lowest task ID and IDs are on a continuous range. + */ +#ifdef HAS_TASK_USB_CHG_P0 +#define USB_CHG_PORT_TO_TASK_ID(port) (TASK_ID_USB_CHG_P0 + (port)) +#define TASK_ID_TO_USB_CHG_PORT(id) ((id) - TASK_ID_USB_CHG_P0) +#else +#define USB_CHG_PORT_TO_TASK_ID(port) -1 /* dummy task ID */ +#define TASK_ID_TO_USB_CHG_PORT(id) 0 +#endif /* HAS_TASK_USB_CHG_P0 */ + /** * Returns true if the passed port is a power source. * |