summaryrefslogtreecommitdiffstats
path: root/drivers/power/supply
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2019-08-30 19:23:16 -0400
committerSebastian Reichel <sebastian.reichel@collabora.com>2019-09-02 17:08:07 -0400
commit7f7378618b4103c083db7de5017df958f8ada070 (patch)
tree0ac9a70b8263996326b9634e6713f67b251b295b /drivers/power/supply
parent7cfd33d997a4c320b6bbce5e9592230dae1e73d2 (diff)
power: supply: cpcap-charger: Enable vbus boost voltage
We are currently not enabling VBUS boost for cpcap when in host mode. This means the VBUS is fed at the battery voltage level, which can cause flakeyness enumerating devices. Looks like the boost control for VBUS is CPCAP_BIT_VBUS_SWITCH that we must enable in the charger for nice 4.92 V VBUS output. And looks like we must not use the STBY pin enabling but must instead use manual VBUS control in phy-cpcap-usb. We want to do this in cpcap_charger_vbus_work() and also set a flag for feeding_vbus to avoid races between USB detection and charger detection, and disable charging if feeding_vbus is set. Cc: Jacopo Mondi <jacopo@jmondi.org> Cc: Kishon Vijay Abraham I <kishon@ti.com> Cc: Marcel Partap <mpartap@gmx.net> Cc: Merlijn Wajer <merlijn@wizzup.org> Cc: Michael Scott <hashcode0f@gmail.com> Cc: NeKit <nekit1000@gmail.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Sebastian Reichel <sre@kernel.org> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power/supply')
-rw-r--r--drivers/power/supply/cpcap-charger.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
index cc546bc40a78..74258c7fe17d 100644
--- a/drivers/power/supply/cpcap-charger.c
+++ b/drivers/power/supply/cpcap-charger.c
@@ -108,6 +108,9 @@
108#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) 108#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe)
109#define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) 109#define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf)
110 110
111/* CPCAP_REG_VUSBC register bits needed for VBUS */
112#define CPCAP_BIT_VBUS_SWITCH BIT(0) /* VBUS boost to 5V */
113
111enum { 114enum {
112 CPCAP_CHARGER_IIO_BATTDET, 115 CPCAP_CHARGER_IIO_BATTDET,
113 CPCAP_CHARGER_IIO_VOLTAGE, 116 CPCAP_CHARGER_IIO_VOLTAGE,
@@ -130,7 +133,8 @@ struct cpcap_charger_ddata {
130 struct power_supply *usb; 133 struct power_supply *usb;
131 134
132 struct phy_companion comparator; /* For USB VBUS */ 135 struct phy_companion comparator; /* For USB VBUS */
133 bool vbus_enabled; 136 unsigned int vbus_enabled:1;
137 unsigned int feeding_vbus:1;
134 atomic_t active; 138 atomic_t active;
135 139
136 int status; 140 int status;
@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
325} 329}
326 330
327/* VBUS control functions for the USB PHY companion */ 331/* VBUS control functions for the USB PHY companion */
328
329static void cpcap_charger_vbus_work(struct work_struct *work) 332static void cpcap_charger_vbus_work(struct work_struct *work)
330{ 333{
331 struct cpcap_charger_ddata *ddata; 334 struct cpcap_charger_ddata *ddata;
@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
343 return; 346 return;
344 } 347 }
345 348
349 ddata->feeding_vbus = true;
346 cpcap_charger_set_cable_path(ddata, false); 350 cpcap_charger_set_cable_path(ddata, false);
347 cpcap_charger_set_inductive_path(ddata, false); 351 cpcap_charger_set_inductive_path(ddata, false);
348 352
@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
350 if (error) 354 if (error)
351 goto out_err; 355 goto out_err;
352 356
357 error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
358 CPCAP_BIT_VBUS_SWITCH,
359 CPCAP_BIT_VBUS_SWITCH);
360 if (error)
361 goto out_err;
362
353 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, 363 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
354 CPCAP_REG_CRM_RVRSMODE, 364 CPCAP_REG_CRM_RVRSMODE,
355 CPCAP_REG_CRM_RVRSMODE); 365 CPCAP_REG_CRM_RVRSMODE);
356 if (error) 366 if (error)
357 goto out_err; 367 goto out_err;
358 } else { 368 } else {
369 error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
370 CPCAP_BIT_VBUS_SWITCH, 0);
371 if (error)
372 goto out_err;
373
359 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, 374 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
360 CPCAP_REG_CRM_RVRSMODE, 0); 375 CPCAP_REG_CRM_RVRSMODE, 0);
361 if (error) 376 if (error)
@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
363 378
364 cpcap_charger_set_cable_path(ddata, true); 379 cpcap_charger_set_cable_path(ddata, true);
365 cpcap_charger_set_inductive_path(ddata, true); 380 cpcap_charger_set_inductive_path(ddata, true);
381 ddata->feeding_vbus = false;
366 } 382 }
367 383
368 return; 384 return;
@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work)
431 if (error) 447 if (error)
432 return; 448 return;
433 449
434 if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) { 450 if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
451 s.chrgcurr1) {
435 int max_current; 452 int max_current;
436 453
437 if (cpcap_charger_battery_found(ddata)) 454 if (cpcap_charger_battery_found(ddata))