Commit 7f737861 authored by Tony Lindgren's avatar Tony Lindgren Committed by Sebastian Reichel

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: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent 7cfd33d9
...@@ -231,8 +231,9 @@ static void cpcap_usb_detect(struct work_struct *work) ...@@ -231,8 +231,9 @@ static void cpcap_usb_detect(struct work_struct *work)
goto out_err; goto out_err;
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_VBUSSTBY_EN, CPCAP_BIT_VBUSSTBY_EN |
CPCAP_BIT_VBUSSTBY_EN); CPCAP_BIT_VBUSEN_SPI,
CPCAP_BIT_VBUSEN_SPI);
if (error) if (error)
goto out_err; goto out_err;
...@@ -240,7 +241,8 @@ static void cpcap_usb_detect(struct work_struct *work) ...@@ -240,7 +241,8 @@ static void cpcap_usb_detect(struct work_struct *work)
} }
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_VBUSSTBY_EN, 0); CPCAP_BIT_VBUSSTBY_EN |
CPCAP_BIT_VBUSEN_SPI, 0);
if (error) if (error)
goto out_err; goto out_err;
......
...@@ -108,6 +108,9 @@ ...@@ -108,6 +108,9 @@
#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) #define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe)
#define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) #define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf)
/* CPCAP_REG_VUSBC register bits needed for VBUS */
#define CPCAP_BIT_VBUS_SWITCH BIT(0) /* VBUS boost to 5V */
enum { enum {
CPCAP_CHARGER_IIO_BATTDET, CPCAP_CHARGER_IIO_BATTDET,
CPCAP_CHARGER_IIO_VOLTAGE, CPCAP_CHARGER_IIO_VOLTAGE,
...@@ -130,7 +133,8 @@ struct cpcap_charger_ddata { ...@@ -130,7 +133,8 @@ struct cpcap_charger_ddata {
struct power_supply *usb; struct power_supply *usb;
struct phy_companion comparator; /* For USB VBUS */ struct phy_companion comparator; /* For USB VBUS */
bool vbus_enabled; unsigned int vbus_enabled:1;
unsigned int feeding_vbus:1;
atomic_t active; atomic_t active;
int status; int status;
...@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata) ...@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
} }
/* VBUS control functions for the USB PHY companion */ /* VBUS control functions for the USB PHY companion */
static void cpcap_charger_vbus_work(struct work_struct *work) static void cpcap_charger_vbus_work(struct work_struct *work)
{ {
struct cpcap_charger_ddata *ddata; struct cpcap_charger_ddata *ddata;
...@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work) ...@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
return; return;
} }
ddata->feeding_vbus = true;
cpcap_charger_set_cable_path(ddata, false); cpcap_charger_set_cable_path(ddata, false);
cpcap_charger_set_inductive_path(ddata, false); cpcap_charger_set_inductive_path(ddata, false);
...@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work) ...@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
if (error) if (error)
goto out_err; goto out_err;
error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
CPCAP_BIT_VBUS_SWITCH,
CPCAP_BIT_VBUS_SWITCH);
if (error)
goto out_err;
error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
CPCAP_REG_CRM_RVRSMODE, CPCAP_REG_CRM_RVRSMODE,
CPCAP_REG_CRM_RVRSMODE); CPCAP_REG_CRM_RVRSMODE);
if (error) if (error)
goto out_err; goto out_err;
} else { } else {
error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
CPCAP_BIT_VBUS_SWITCH, 0);
if (error)
goto out_err;
error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
CPCAP_REG_CRM_RVRSMODE, 0); CPCAP_REG_CRM_RVRSMODE, 0);
if (error) if (error)
...@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work) ...@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
cpcap_charger_set_cable_path(ddata, true); cpcap_charger_set_cable_path(ddata, true);
cpcap_charger_set_inductive_path(ddata, true); cpcap_charger_set_inductive_path(ddata, true);
ddata->feeding_vbus = false;
} }
return; return;
...@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work) ...@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work)
if (error) if (error)
return; return;
if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) { if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
s.chrgcurr1) {
int max_current; int max_current;
if (cpcap_charger_battery_found(ddata)) if (cpcap_charger_battery_found(ddata))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment