summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2020-03-03 17:00:13 -0800
committerCommit Bot <commit-bot@chromium.org>2020-10-08 10:04:06 +0000
commitafe27c14c5ca06294905dfbf7527a912a076e9b6 (patch)
tree8d7428a26028eb29e7cf4681a8bae16f17b88596
parent84aef8213a04d566d63c2565f8c0434901d03c72 (diff)
downloadchrome-ec-afe27c14c5ca06294905dfbf7527a912a076e9b6.tar.gz
max14637: Modify driver to have chip_enable active by default
The max14637 provides client mode bc1.2 detection, and the driver enables bc1.2 detection or turns off the IC bases on VBUS changes. However, the driver does not current differentiate between VBUS resulting for the port acting as a sink or source. The result is that bc1.2 detection is also tirggered when the port is acting as a source. This can cause interop issues with other devices which aren't expecting bc1.2 detection singaling in this case. This CL modifies the driver so that the max14637 enable is on by default. This results in the bc1.2 driver being mostly a NOP when the port power role is a source. If the port power role is a sink, then the enable line is pulsed low so that bc1.2 client detection is triggered as expected. BUG=b:169292275,b:147833952 BRANCH=firmware-octopus-11297.B TEST=Verfied that the device which previously was not enumerating, does enumerate. Test both legacy chargers to ensure that client bc1.2 works as expected. Signed-off-by: Scott Collyer <scollyer@google.com> Change-Id: I8bfd243e312c7238a6668edcdfcde2ac0ae5d580 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2086731 Reviewed-by: Shelley Chen <shchen@chromium.org> Commit-Queue: Shelley Chen <shchen@chromium.org> Tested-by: Shelley Chen <shchen@chromium.org> (cherry picked from commit e8dc03b3cb24df99f41311e842a5641425cfa871) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2364342 Tested-by: Inno.Park <ih.yoo.park@samsung.corp-partner.google.com> Reviewed-by: Marco Chen <marcochen@chromium.org> Reviewed-by: Bob Moragues <moragues@chromium.org> Commit-Queue: Marco Chen <marcochen@chromium.org>
-rw-r--r--driver/bc12/max14637.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/driver/bc12/max14637.c b/driver/bc12/max14637.c
index 0eb449cacf..f65126cb9c 100644
--- a/driver/bc12/max14637.c
+++ b/driver/bc12/max14637.c
@@ -19,6 +19,7 @@
#include "common.h"
#include "console.h"
#include "gpio.h"
+#include "hooks.h"
#include "power.h"
#include "task.h"
#include "tcpm.h"
@@ -68,8 +69,19 @@ static void bc12_detect(const int port)
struct charge_port_info new_chg;
/*
- * Enable the IC to begin detection and connect switches if necessary.
+ * Enable the IC to begin detection and connect switches if
+ * necessary. This is only necessary if the port power role is a
+ * sink. If the power role is a source then just keep the max14637
+ * powered on so that data switches are close. Note that the gpio enable
+ * for this chip is active by default. In order to trigger bc1.2
+ * detection, the chip enable must be driven low, then high again so the
+ * chip will start bc1.2 client side detection. Add a 100 msec delay to
+ * avoid collision with a device that might be doing bc1.2 client side
+ * detection.
*/
+ msleep(100);
+ activate_chip_enable(cfg, 0);
+ msleep(1);
activate_chip_enable(cfg, 1);
new_chg.voltage = USB_CHARGER_VOLTAGE_MV;
@@ -100,23 +112,11 @@ static void bc12_detect(const int port)
}
/**
- * Turn off the MAX14637 detector.
- *
- * @param port: Which USB Type-C port's BC1.2 detector to turn off.
- */
-static void power_down_ic(const int port)
-{
- const struct max14637_config_t * const cfg = &max14637_config[port];
-
- /* Turn off the IC. */
- activate_chip_enable(cfg, 0);
-
- /* Let charge manager know there's no more charge available. */
- charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, NULL);
-}
-
-/**
- * If VBUS is present, determine the charger type, otherwise power down the IC.
+ * If VBUS is present and port power role is sink, then trigger bc1.2 client
+ * detection. If VBUS is not present then update charge manager. Note that both
+ * chip_enable and VBUS must be active for the IC to be powered up. Chip enable
+ * is kept enabled by default so that bc1.2 client detection is not triggered
+ * when the port power role is source.
*
* @param port: Which USB Type-C port to examine.
*/
@@ -135,9 +135,11 @@ static void detect_or_power_down_ic(const int port)
/* Turn on the 5V rail to allow the chip to be powered. */
power_5v_enable(task_get_current(), 1);
#endif
- bc12_detect(port);
+ if (pd_get_power_role(port) == PD_ROLE_SINK)
+ bc12_detect(port);
} else {
- power_down_ic(port);
+ /* Let charge manager know there's no more charge available. */
+ charge_manager_update_charge(CHARGE_SUPPLIER_OTHER, port, NULL);
#if defined(CONFIG_POWER_PP5000_CONTROL) && defined(HAS_TASK_CHIPSET)
/* Issue a request to turn off the rail. */
power_5v_enable(task_get_current(), 0);
@@ -149,9 +151,16 @@ void usb_charger_task(void *u)
{
const int port = (intptr_t)u;
uint32_t evt;
+ const struct max14637_config_t * const cfg = &max14637_config[port];
ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT);
-
+ /*
+ * Have chip enable active as default state so data switches are closed
+ * and bc1.2 client side detection is not activated when the port power
+ * role is a source.
+ */
+ activate_chip_enable(cfg, 1);
+ /* Check whether bc1.2 client mode detection needs to be triggered */
detect_or_power_down_ic(port);
while (1) {
@@ -189,3 +198,21 @@ int usb_charger_ramp_max(int supplier, int sup_curr)
return 500;
}
#endif /* CONFIG_CHARGE_RAMP_SW || CONFIG_CHARGE_RAMP_HW */
+
+/* Called on AP S5 -> S3 and S3/S0iX -> S0 transition */
+static void bc12_chipset_startup(void)
+{
+ int port;
+
+ /*
+ * For each port, trigger a new USB_CHG_EVENT_VBUS event to handle cases
+ * where there was no change in VBUS following an AP resume/startup
+ * event. If a legacy charger is connected to the port, then VBUS will
+ * not drop even during the USB PD hard reset.
+ */
+ for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++)
+ task_set_event(USB_CHG_PORT_TO_TASK_ID(port),
+ USB_CHG_EVENT_VBUS, 0);
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, bc12_chipset_startup, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, bc12_chipset_startup, HOOK_PRIO_DEFAULT);