summaryrefslogtreecommitdiff
path: root/common/usb_charger.c
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-05-12 16:06:05 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-05-13 23:34:51 -0700
commita4ef74039104fb7da4137960c2c023f45dda6924 (patch)
tree2b90444806902e130d41bbfca648ebb0a2afcfbc /common/usb_charger.c
parent7d8964614d85232b56b010853ab7f06f93229f57 (diff)
downloadchrome-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/usb_charger.c')
-rw-r--r--common/usb_charger.c195
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;