aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/supply/cpcap-charger.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/supply/cpcap-charger.c')
-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 @@
#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe)
#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 {
CPCAP_CHARGER_IIO_BATTDET,
CPCAP_CHARGER_IIO_VOLTAGE,
@@ -130,7 +133,8 @@ struct cpcap_charger_ddata {
struct power_supply *usb;
struct phy_companion comparator; /* For USB VBUS */
- bool vbus_enabled;
+ unsigned int vbus_enabled:1;
+ unsigned int feeding_vbus:1;
atomic_t active;
int status;
@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
}
/* VBUS control functions for the USB PHY companion */
-
static void cpcap_charger_vbus_work(struct work_struct *work)
{
struct cpcap_charger_ddata *ddata;
@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
return;
}
+ ddata->feeding_vbus = true;
cpcap_charger_set_cable_path(ddata, false);
cpcap_charger_set_inductive_path(ddata, false);
@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
if (error)
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,
CPCAP_REG_CRM_RVRSMODE,
CPCAP_REG_CRM_RVRSMODE);
if (error)
goto out_err;
} 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,
CPCAP_REG_CRM_RVRSMODE, 0);
if (error)
@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
cpcap_charger_set_cable_path(ddata, true);
cpcap_charger_set_inductive_path(ddata, true);
+ ddata->feeding_vbus = false;
}
return;
@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work)
if (error)
return;
- if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) {
+ if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
+ s.chrgcurr1) {
int max_current;
if (cpcap_charger_battery_found(ddata))