diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-05-12 16:06:05 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-05-13 23:34:51 -0700 |
commit | a4ef74039104fb7da4137960c2c023f45dda6924 (patch) | |
tree | 2b90444806902e130d41bbfca648ebb0a2afcfbc /common | |
parent | 7d8964614d85232b56b010853ab7f06f93229f57 (diff) | |
download | chrome-ec-a4ef74039104fb7da4137960c2c023f45dda6924.tar.gz |
usb_charger: Move part-specific code to usb_switch driver
Previously usb_charger.c supported only pi3usb9281, but now support for
additional parts is required. Move pericom-specific code (including the
usb_charger tasks that handles various quirks of that part) to the
pi3usb9281 usb_switch driver.
Going forward, usb_switch drivers must implement
usb_charger_set_switches() and must have some method (such as a task or
interrupt handler) to update charge_manager with information about
attached chargers.
BUG=chrome-os-partner:53363
BRANCH=None
TEST=`make buildall -j`
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Change-Id: I4df74e043d8cf2e532d48c39c73b7dc2930f7d3b
Reviewed-on: https://chromium-review.googlesource.com/344289
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_charger.c | 195 |
1 files changed, 6 insertions, 189 deletions
diff --git a/common/usb_charger.c b/common/usb_charger.c index c56e0f4d0f..8e938233a3 100644 --- a/common/usb_charger.c +++ b/common/usb_charger.c @@ -4,40 +4,23 @@ */ /* - * USB charger / BC1.2 task. This code assumes that CONFIG_CHARGE_MANAGER - * is defined and implemented. PI3USB9281 is the only charger detector - * currently supported. + * USB charger interface routines. This code assumes that CONFIG_CHARGE_MANAGER + * is defined and implemented. + * usb_charger_set_switches() must be implemented by a companion + * usb_switch driver. + * In addition, USB switch-specific usb_charger task or interrupt routine + * is necessary to update charge_manager with detected charger attributes. */ #include "charge_manager.h" #include "common.h" #include "console.h" -#include "ec_commands.h" #include "gpio.h" #include "hooks.h" -#include "pi3usb9281.h" #include "task.h" -#include "timer.h" #include "usb_charge.h" #include "usb_pd.h" -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) - -/* Wait after a charger is detected to debounce pin contact order */ -#define USB_CHG_DEBOUNCE_DELAY_MS 1000 -/* - * Wait after reset, before re-enabling attach interrupt, so that the - * spurious attach interrupt from certain ports is ignored. - */ -#define USB_CHG_RESET_DELAY_MS 100 - -/* - * Store the state of our USB data switches so that they can be restored - * after pericom reset. - */ -static int usb_switch_state[CONFIG_USB_PD_PORT_COUNT]; -static struct mutex usb_switch_lock[CONFIG_USB_PD_PORT_COUNT]; - static void update_vbus_supplier(int port, int vbus_level) { struct charge_port_info charge; @@ -67,19 +50,6 @@ int usb_charger_port_is_sourcing_vbus(int port) return 0; } -void usb_charger_set_switches(int port, enum usb_switch setting) -{ - /* If switch is not changing then return */ - if (setting == usb_switch_state[port]) - return; - - mutex_lock(&usb_switch_lock[port]); - if (setting != USB_SWITCH_RESTORE) - usb_switch_state[port] = setting; - pi3usb9281_set_switches(port, usb_switch_state[port]); - mutex_unlock(&usb_switch_lock[port]); -} - void usb_charger_vbus_change(int port, int vbus_level) { /* If VBUS has transitioned low, notify PD module directly */ @@ -94,159 +64,6 @@ void usb_charger_vbus_change(int port, int vbus_level) #endif } -static void usb_charger_bc12_detect(int port) -{ - int device_type, charger_status; - struct charge_port_info charge; - int type; - - charge.voltage = USB_CHARGER_VOLTAGE_MV; - - if (usb_charger_port_is_sourcing_vbus(port)) { - /* If we're sourcing VBUS then we're not charging */ - device_type = charger_status = 0; - } else { - /* Set device type */ - device_type = pi3usb9281_get_device_type(port); - charger_status = pi3usb9281_get_charger_status(port); - } - - /* Debounce pin plug order if we detect a charger */ - if (device_type || PI3USB9281_CHG_STATUS_ANY(charger_status)) { - /* next operation might trigger a detach interrupt */ - pi3usb9281_disable_interrupts(port); - /* - * Ensure D+/D- are open before resetting - * Note: we can't simply call pi3usb9281_set_switches() because - * another task might override it and set the switches closed. - */ - pi3usb9281_set_switch_manual(port, 1); - pi3usb9281_set_pins(port, 0); - - /* Delay to debounce pin attach order */ - msleep(USB_CHG_DEBOUNCE_DELAY_MS); - - /* - * Trigger chip reset to refresh detection registers. - * WARNING: This reset is acceptable for samus_pd, - * but may not be acceptable for devices that have - * an OTG / device mode, as we may be interrupting - * the connection. - */ - pi3usb9281_reset(port); - /* - * Restore data switch settings - switches return to - * closed on reset until restored. - */ - usb_charger_set_switches(port, USB_SWITCH_RESTORE); - /* Clear possible disconnect interrupt */ - pi3usb9281_get_interrupts(port); - /* Mask attach interrupt */ - pi3usb9281_set_interrupt_mask(port, - 0xff & - ~PI3USB9281_INT_ATTACH); - /* Re-enable interrupts */ - pi3usb9281_enable_interrupts(port); - msleep(USB_CHG_RESET_DELAY_MS); - - /* Clear possible attach interrupt */ - pi3usb9281_get_interrupts(port); - /* Re-enable attach interrupt */ - pi3usb9281_set_interrupt_mask(port, 0xff); - - /* Re-read ID registers */ - device_type = pi3usb9281_get_device_type(port); - charger_status = pi3usb9281_get_charger_status(port); - } - - /* Attachment: decode + update available charge */ - if (device_type || PI3USB9281_CHG_STATUS_ANY(charger_status)) { - if (PI3USB9281_CHG_STATUS_ANY(charger_status)) - type = CHARGE_SUPPLIER_PROPRIETARY; - else if (device_type & PI3USB9281_TYPE_CDP) - type = CHARGE_SUPPLIER_BC12_CDP; - else if (device_type & PI3USB9281_TYPE_DCP) - type = CHARGE_SUPPLIER_BC12_DCP; - else if (device_type & PI3USB9281_TYPE_SDP) - type = CHARGE_SUPPLIER_BC12_SDP; - else - type = CHARGE_SUPPLIER_OTHER; - - charge.current = pi3usb9281_get_ilim(device_type, - charger_status); - charge_manager_update_charge(type, port, &charge); - } else { /* Detachment: update available charge to 0 */ - charge.current = 0; - charge_manager_update_charge( - CHARGE_SUPPLIER_PROPRIETARY, - port, - &charge); - charge_manager_update_charge( - CHARGE_SUPPLIER_BC12_CDP, - port, - &charge); - charge_manager_update_charge( - CHARGE_SUPPLIER_BC12_DCP, - port, - &charge); - charge_manager_update_charge( - CHARGE_SUPPLIER_BC12_SDP, - port, - &charge); - charge_manager_update_charge( - CHARGE_SUPPLIER_OTHER, - port, - &charge); - } - - /* notify host of power info change */ - pd_send_host_event(PD_EVENT_POWER_CHANGE); -} - -void usb_charger_task(void) -{ - const int attach_mask = PI3USB9281_INT_ATTACH | PI3USB9281_INT_DETACH; - int port = (task_get_current() == TASK_ID_USB_CHG_P0 ? 0 : 1); - int interrupt; - uint32_t evt; - - /* Initialize chip and enable interrupts */ - pi3usb9281_init(port); - - usb_charger_bc12_detect(port); - - while (1) { - /* Wait for interrupt */ - evt = task_wait_event(-1); - - /* Interrupt from the Pericom chip, determine charger type */ - if (evt & USB_CHG_EVENT_BC12) { - /* Read interrupt register to clear on chip */ - pi3usb9281_get_interrupts(port); - usb_charger_bc12_detect(port); - } else if (evt & USB_CHG_EVENT_INTR) { - /* Check the interrupt register, and clear on chip */ - interrupt = pi3usb9281_get_interrupts(port); - if (interrupt & attach_mask) - usb_charger_bc12_detect(port); - } - - /* - * Re-enable interrupts on pericom charger detector since the - * chip may periodically reset itself, and come back up with - * registers in default state. TODO(crosbug.com/p/33823): Fix - * these unwanted resets. - */ - if (evt & USB_CHG_EVENT_VBUS) { - pi3usb9281_enable_interrupts(port); -#ifndef CONFIG_USB_PD_TCPM_VBUS - CPRINTS("VBUS p%d %d", port, - pd_snk_is_vbus_provided(port)); -#endif - } - } -} - static void usb_charger_init(void) { int i; |