summaryrefslogtreecommitdiff
path: root/driver/bc12
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-07-28 10:22:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-31 17:08:27 -0700
commite67ca7945678399dffa19beb4bd54f7b935e4a7d (patch)
treeb09cd55dc1a5152c4ea7e93dd6550747dbcd4a32 /driver/bc12
parent043c55026242d0b485a400f0ac4020d373e19673 (diff)
downloadchrome-ec-e67ca7945678399dffa19beb4bd54f7b935e4a7d.tar.gz
driver: Add support for TI BQ24392.
The BQ24932 is a dual single-pole single-throw USB 2.0 high-speed isolation switch with charger detection capabilities. The device's charger detection circuitry can support USB Battery Charging Specification version 1.2 (BC1.2), Apple, TomTom, and other non-standard chargers. BUG=None BRANCH=None TEST=`make -j buildall` TEST=Enable support for the BQ24392 on a board. Verify that it complies. Change-Id: I82f426f1eedabdbb6b951a6ce0252135de3368db Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/592133 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Benson Leung <bleung@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'driver/bc12')
-rw-r--r--driver/bc12/bq24392.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/driver/bc12/bq24392.c b/driver/bc12/bq24392.c
new file mode 100644
index 0000000000..0e7948697e
--- /dev/null
+++ b/driver/bc12/bq24392.c
@@ -0,0 +1,143 @@
+/* Copyright 2017 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.
+ */
+
+/*
+ * BQ24392 USB BC 1.2 Charger Detector driver.
+ *
+ * NOTE: The driver assumes that CHG_AL_N and SW_OPEN are not connected,
+ * therefore the value of CHG_DET indicates whether the source is NOT a
+ * low-power standard downstream port (SDP). In order to use higher currents,
+ * the system will have to charge ramp.
+ */
+
+#include "charge_manager.h"
+#include "common.h"
+#include "gpio.h"
+#include "task.h"
+#include "tcpm.h"
+#include "timer.h"
+#include "usb_charge.h"
+#include "util.h"
+
+struct bq24392_pins {
+ enum gpio_signal chip_enable;
+ enum gpio_signal chg_det;
+};
+
+static const struct bq24392_pins pin_tbl[] = {
+ { GPIO_USB_C0_BC12_VBUS_ON, GPIO_USB_C0_BC12_CHG_DET },
+#ifdef HAS_TASK_USB_CHG_P1
+ { GPIO_USB_C1_BC12_VBUS_ON, GPIO_USB_C1_BC12_CHG_DET },
+#endif
+#ifdef HAS_TASK_USB_CHG_P2
+ { GPIO_USB_C2_BC12_VBUS_ON, GPIO_USB_C2_BC12_CHG_DET },
+#endif
+};
+
+/**
+ * Perform BC1.2 detection and update charge manager.
+ *
+ * @param port: The Type-C port where VBUS is present.
+ */
+static void bc12_detect(const int port)
+{
+ int is_high_power;
+ struct charge_port_info new_chg;
+ enum gpio_signal chip_enable;
+ enum gpio_signal chg_det;
+
+ chip_enable = pin_tbl[port].chip_enable;
+ chg_det = pin_tbl[port].chg_det;
+
+ /* Enable the IC to begin detection. */
+ gpio_set_level(chip_enable, 1);
+
+ /*
+ * Apple or TomTom charger detection can take as long as 600ms. Wait a
+ * little bit longer for margin.
+ */
+ msleep(630);
+
+ /*
+ * The driver assumes that CHG_AL_N and SW_OPEN are not connected,
+ * therefore the value of CHG_DET indicates whether the source is NOT a
+ * low-power standard downstream port (SDP). The system will have to
+ * ramp the current to determine the limit.
+ */
+ is_high_power = gpio_get_level(chg_det);
+
+ new_chg.voltage = USB_CHARGER_VOLTAGE_MV;
+#ifdef CONFIG_CHARGE_RAMP
+ new_chg.current = is_high_power ? 2400 : 500;
+#else
+ /*
+ * If the board doesn't support charge ramping, then assume the lowest
+ * denominator; that is assume the charger detected is a weak dedicated
+ * charging port (DCP) which can only supply 500mA.
+ */
+ new_chg.current = 500;
+#endif /* !defined(CONFIG_CHARGE_RAMP) */
+
+ charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &new_chg);
+}
+
+/**
+ * Turn off the BQ24392 detector.
+ *
+ * @param port: Which USB Type-C port's BC1.2 detector to turn off.
+ */
+static void power_down_ic(const int port)
+{
+ struct charge_port_info no_chg = { 0 };
+ enum gpio_signal chip_enable = pin_tbl[port].chip_enable;
+
+ /* Turn off the IC. */
+ gpio_set_level(chip_enable, 0);
+
+ /* Let charge manager know there's no more charge available. */
+ charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, &no_chg);
+}
+
+/**
+ * If VBUS is present, determine the charger type, otherwise power down the IC.
+ *
+ * @param port: Which USB Type-C port to examine.
+ */
+static void detect_or_power_down_ic(const int port)
+{
+ int vbus_present;
+
+#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
+ vbus_present = tcpm_get_vbus_level(port);
+#else
+ vbus_present = pd_snk_is_vbus_provided(port);
+#endif /* !defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) */
+
+ if (vbus_present)
+ bc12_detect(port);
+ else
+ power_down_ic(port);
+}
+
+void usb_charger_task(const int port)
+{
+ uint32_t evt;
+
+ ASSERT(port >= 0 && port <= 2);
+
+ detect_or_power_down_ic(port);
+
+ while (1) {
+ evt = task_wait_event(-1);
+
+ if (evt & USB_CHG_EVENT_VBUS)
+ detect_or_power_down_ic(port);
+ }
+}
+
+void usb_charger_set_switches(int port, enum usb_switch setting)
+{
+ /* The BQ24392 automatically sets up the USB 2.0 high-speed switches. */
+}