summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-06-08 13:58:47 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-10 19:48:08 +0000
commite05ed041cfe60db7d1bff5424d4579a52aea402f (patch)
tree1fd7a6e78c42682b1f9eb331c12084a4b44c3b56 /common
parent5d7c4f0cd6b7b020e70c9f9ec5f60a8457b90f12 (diff)
downloadchrome-ec-e05ed041cfe60db7d1bff5424d4579a52aea402f.tar.gz
charger: Move USB charger / BC1.2 task to common code
Move the task responsible for detection of USB chargers to common code to reduce code duplication. BUG=chrome-os-partner:40920 TEST=Manual on samus_pd. Plug USB charger, verify detection is correct on both charge ports. BRANCH=None Change-Id: I362f8b5b51741509e459c66928131f1f6d2a3b1d Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/276210 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/build.mk1
-rw-r--r--common/charge_manager.c13
-rw-r--r--common/charge_ramp.c4
-rw-r--r--common/usb_charger.c138
-rw-r--r--common/usb_pd_policy.c6
5 files changed, 158 insertions, 4 deletions
diff --git a/common/build.mk b/common/build.mk
index be87443078..3941a40c5f 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -76,6 +76,7 @@ common-$(CONFIG_STREAM)+=in_stream.o out_stream.o stream_adaptor.o
common-$(CONFIG_SWITCH)+=switch.o
common-$(CONFIG_SW_CRC)+=crc.o
common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o thermal.o throttle_ap.o
+common-$(CONFIG_USB_CHARGER)+=usb_charger.o
common-$(CONFIG_USB_PORT_POWER_DUMB)+=usb_port_power_dumb.o
common-$(CONFIG_USB_PORT_POWER_SMART)+=usb_port_power_smart.o
common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o
diff --git a/common/charge_manager.c b/common/charge_manager.c
index b52f297c45..24fbae2d38 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -23,6 +23,19 @@
#define POWER_SWAP_TIMEOUT (PD_T_SRC_RECOVER_MAX + PD_T_SRC_TURN_ON + \
PD_T_SAFE_0V + 500 * MSEC)
+/* Charge supplier priority: lower number indicates higher priority. */
+test_mockable const int supplier_priority[] = {
+ [CHARGE_SUPPLIER_PD] = 0,
+ [CHARGE_SUPPLIER_TYPEC] = 1,
+ [CHARGE_SUPPLIER_PROPRIETARY] = 1,
+ [CHARGE_SUPPLIER_BC12_DCP] = 1,
+ [CHARGE_SUPPLIER_BC12_CDP] = 2,
+ [CHARGE_SUPPLIER_BC12_SDP] = 3,
+ [CHARGE_SUPPLIER_OTHER] = 3,
+ [CHARGE_SUPPLIER_VBUS] = 4
+};
+BUILD_ASSERT(ARRAY_SIZE(supplier_priority) == CHARGE_SUPPLIER_COUNT);
+
/* Keep track of available charge for each charge port. */
static struct charge_port_info available_charge[CHARGE_SUPPLIER_COUNT]
[CONFIG_USB_PD_PORT_COUNT];
diff --git a/common/charge_ramp.c b/common/charge_ramp.c
index cc71f987b6..e5f6d99e26 100644
--- a/common/charge_ramp.c
+++ b/common/charge_ramp.c
@@ -197,10 +197,8 @@ void chg_ramp_task(void)
/* Detect delay is over, fall through to next state */
ramp_st_new = CHG_RAMP_OVERCURRENT_DETECT;
-#ifdef CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
-#endif
case CHG_RAMP_OVERCURRENT_DETECT:
/* Check if we should ramp or go straight to stable */
task_wait_time = SECOND;
@@ -297,10 +295,8 @@ void chg_ramp_task(void)
#ifdef CONFIG_USB_PD_LOGGING
charge_manager_save_log(active_port);
#endif
-#ifdef CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
-#endif
}
/* Keep an eye on VBUS and restart ramping if it dips */
diff --git a/common/usb_charger.c b/common/usb_charger.c
new file mode 100644
index 0000000000..bb85fc3c7f
--- /dev/null
+++ b/common/usb_charger.c
@@ -0,0 +1,138 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * USB charger / BC1.2 task. This code assumes that CONFIG_CHARGE_MANAGER
+ * is defined and implemented. PI3USB9281 is the only charger detector
+ * currently supported.
+ */
+
+#include "charge_manager.h"
+#include "common.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "pi3usb9281.h"
+#include "task.h"
+#include "timer.h"
+#include "usb_pd.h"
+
+/* 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
+
+void usb_charger_task(void)
+{
+ int port = (task_get_current() == TASK_ID_USB_CHG_P0 ? 0 : 1);
+#if (CONFIG_USB_PD_PORT_COUNT == 1)
+ int vbus_source = GPIO_USB_C0_5V_EN;
+#else
+ int vbus_source = (port == 0 ? GPIO_USB_C0_5V_EN : GPIO_USB_C1_5V_EN);
+#endif
+ int device_type, charger_status;
+ struct charge_port_info charge;
+ int type;
+ charge.voltage = USB_BC12_CHARGE_VOLTAGE;
+
+ while (1) {
+ /* Read interrupt register to clear on chip */
+ pi3usb9281_get_interrupts(port);
+
+ if (gpio_get_level(vbus_source)) {
+ /* 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)) {
+ 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.
+ */
+ board_set_usb_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);
+
+ /* Wait for interrupt */
+ task_wait_event(-1);
+ }
+}
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 19c69a7369..3972e2289c 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -914,3 +914,9 @@ int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload)
}
return rsize;
}
+
+static void stub_pd_send_host_event(int mask)
+{
+}
+void pd_send_host_event(int mask)
+ __attribute__((weak, alias("stub_pd_send_host_event")));