Skip to content

Commit ecbc8dd

Browse files
smaeulsre
authored andcommitted
power: supply: axp20x_usb_power: Allow offlining
AXP803/AXP813 have a flag that enables/disables the USB power supply input. Allow control of this flag via the ONLINE property on those variants. It may be necessary to offline the USB power supply input when using the USB port in OTG mode, or to allow userspace to disable charging. When the USB VBUS input is disabled via the PATH_SEL bit, the VBUS_USED bit in PWR_INPUT_STATUS is cleared, so there is no change needed when getting the property. Reviewed-by: Chen-Yu Tsai <[email protected]> Signed-off-by: Samuel Holland <[email protected]> Signed-off-by: Sebastian Reichel <[email protected]>
1 parent 56900d4 commit ecbc8dd

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

drivers/power/supply/axp20x_usb_power.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929

3030
#define AXP20X_USB_STATUS_VBUS_VALID BIT(2)
3131

32+
#define AXP20X_VBUS_PATH_SEL BIT(7)
33+
#define AXP20X_VBUS_PATH_SEL_OFFSET 7
34+
3235
#define AXP20X_VBUS_VHOLD_uV(b) (4000000 + (((b) >> 3) & 7) * 100000)
3336
#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
3437
#define AXP20X_VBUS_VHOLD_OFFSET 3
@@ -263,6 +266,16 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
263266
return 0;
264267
}
265268

269+
static int axp813_usb_power_set_online(struct axp20x_usb_power *power,
270+
int intval)
271+
{
272+
int val = !intval << AXP20X_VBUS_PATH_SEL_OFFSET;
273+
274+
return regmap_update_bits(power->regmap,
275+
AXP20X_VBUS_IPSOUT_MGMT,
276+
AXP20X_VBUS_PATH_SEL, val);
277+
}
278+
266279
static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
267280
int intval)
268281
{
@@ -344,6 +357,11 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
344357
struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
345358

346359
switch (psp) {
360+
case POWER_SUPPLY_PROP_ONLINE:
361+
if (power->axp20x_id != AXP813_ID)
362+
return -EINVAL;
363+
return axp813_usb_power_set_online(power, val->intval);
364+
347365
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
348366
return axp20x_usb_power_set_voltage_min(power, val->intval);
349367

@@ -363,6 +381,18 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
363381
static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
364382
enum power_supply_property psp)
365383
{
384+
struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
385+
386+
/*
387+
* The VBUS path select flag works differently on on AXP288 and newer:
388+
* - On AXP20x and AXP22x, the flag enables VBUS (ignoring N_VBUSEN).
389+
* - On AXP288 and AXP8xx, the flag disables VBUS (ignoring N_VBUSEN).
390+
* We only expose the control on variants where it can be used to force
391+
* the VBUS input offline.
392+
*/
393+
if (psp == POWER_SUPPLY_PROP_ONLINE)
394+
return power->axp20x_id == AXP813_ID;
395+
366396
return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
367397
psp == POWER_SUPPLY_PROP_CURRENT_MAX;
368398
}

0 commit comments

Comments
 (0)