Add sysfs entry for system load control
v2 cover Add sysfs entry for system load control
During discussions of the development of a new driver [1], it was concluded that a new sysfs ABI for controlling the connection from power to system load is wanted. This patchset introduces this.
There are already several drivers that are controlling this, but with their own custom sysfs entries. The drivers in this patchset were find with a simple grep for bat\s?fet (there might be more?), and then converted to use this new sysfs ABI. The old custom ABIs are left untouched of course, for backward compatibility.
[1] https://lore.kernel.org/lkml/[email protected]/
Changes in v2:
* Drop already merged patches (picked up by Sebastian in v1).
* Pack struct power_supply_desc so that an extra member doesn't increase the size unnecessarily too much.
* Use power_supply_show_enum_with_available() for POWER_SUPPLY_LOAD_SWITCH.
* Drop commit for selftest since properties using power_supply_show_enum_with_available() don't have any helper test functions. Should we add this (in a separate patch set)? I'll others decide if it's worth the churn...
* Add implementation for bq25630.
Link to v1: https://lore.kernel.org/lkml/[email protected]/
Waqar Hameed (8):
power: supply: Pack power_supply_desc to eliminate holes
power: supply: Add sysfs entry for system load control
power: supply: ltc4162-l: Use POWER_SUPPLY_PROP_LOAD_SWITCH
power: supply: rt9471: Use POWER_SUPPLY_PROP_LOAD_SWITCH
power: supply: rt9467: Use POWER_SUPPLY_PROP_LOAD_SWITCH
power: supply: bq24257: Use POWER_SUPPLY_PROP_LOAD_SWITCH
power: supply: bq24190: Use POWER_SUPPLY_PROP_LOAD_SWITCH
power: supply: bq25630: Add support for BATFET control
Documentation/ABI/testing/sysfs-class-power | 25 ++++++ .../ABI/testing/sysfs-class-power-ltc4162l | 2 + .../ABI/testing/sysfs-class-power-rt9467 | 2 + .../ABI/testing/sysfs-class-power-rt9471 | 2 + drivers/power/supply/bq24190_charger.c | 62 ++++++++++++++ drivers/power/supply/bq24257_charger.c | 43 +++++++++- drivers/power/supply/bq25630_charger.c | 84 +++++++++++++++++++ drivers/power/supply/ltc4162-l-charger.c | 56 +++++++++++-- drivers/power/supply/power_supply_sysfs.c | 17 ++++ drivers/power/supply/rt9467-charger.c | 54 ++++++++++-- drivers/power/supply/rt9471.c | 54 ++++++++++-- include/linux/power_supply.h | 18 +++- 12 files changed, 397 insertions(+), 22 deletions(-)
base-commit: 73e3f0710014fe6d4ed98cfc02292f6121db7558
Signature · 1 line
2.43.0
PATCH v2 1/8 power: supply: Pack power_supply_desc to eliminate holes
pahole reports that there are two holes in struct power_supply_desc:
struct power_supply_desc {
const char * name; /* 0 4 */
enum power_supply_type type; /* 4 4 */
u8 charge_behaviours; /* 8 1 *//* XXX 3 bytes hole, try to pack */
u32 charge_types; /* 12 4 */
u32 usb_types; /* 16 4 */
const enum power_supply_property * properties; /* 20 4 */
size_t num_properties; /* 24 4 */
int (*get_property)(...); /* 28 4 */
int (*set_property)(...); /* 32 4 */
int (*property_is_writeable)(...); /* 36 4 */
void (*external_power_changed)(...); /* 40 4 */
int (*init)(struct power_supply *); /* 44 4 */
bool no_thermal; /* 48 1 */
/* XXX 3 bytes hole, try to pack */
int use_for_apm; /* 52 4 */
/* size: 56, cachelines: 1, members: 14 */ /* sum members: 50, holes: 2, sum holes: 6 */ /* last cacheline: 56 bytes */
};
This can be optimized by moving u8 charge_behaviours to the end and swapping int use_for_apm with bool no_thermal:
struct power_supply_desc {
const char * name; /* 0 4 */
enum power_supply_type type; /* 4 4 */
u32 charge_types; /* 8 4 */
u32 usb_types; /* 12 4 */
const enum power_supply_property * properties; /* 16 4 */
size_t num_properties; /* 20 4 */
int (*get_property)(...); /* 24 4 */
int (*set_property)(...); /* 28 4 */
int (*property_is_writeable)(...); /* 32 4 */
void (*external_power_changed)(...); /* 36 4 */
int (*init)(struct power_supply *); /* 40 4 */
int use_for_apm; /* 44 4 */
bool no_thermal; /* 48 1 */
u8 charge_behaviours; /* 49 1 */ /* size: 52, cachelines: 1, members: 14 */
/* padding: 2 */
/* last cacheline: 52 bytes */};
Do this in order to save 4 bytes. This will also help when adding new members in the future to this struct.
--- include/linux/power_supply.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
include/linux/power_supply.h +5 -3
@@ -259,7 +259,6 @@ struct power_supply_config {struct power_supply_desc {const char *name;enum power_supply_type type; -u8 charge_behaviours;u32 charge_types;u32 usb_types;const enum power_supply_property *properties;
@@ -295,14 +294,17 @@ struct power_supply_desc {*/ int (*init)(struct power_supply *psy); +/* For APM emulation, think legacy userspace. */ +int use_for_apm; +/* * Set if thermal zone should not be created for this power supply. * For example for virtual supplies forwarding calls to actual * sensors or other supplies. */ bool no_thermal; -/* For APM emulation, think legacy userspace. */ -int use_for_apm; + +u8 charge_behaviours; };struct power_supply_ext {
Signature · 1 line
2.43.0
PATCH v2 2/8 power: supply: Add sysfs entry for system load control
In reply to Waqar HameedThere are devices that can control the connection from power to system load. For example, with a field-effect transistor between a battery and the system load (BATFET). Drivers for these devices are currently enrolling their own custom sysfs property to control this.
In order to unify this, add a new sysfs entry for controlling such switch and corresponding power_supply_property with enum values. The obvious states are "on" and "off", i.e. there is a connection or not, respectively. However, many devices can also enter special modes such as "low-power", "shipping" or "deep sleep".
Since the members in struct power_supply_desc already are ordered, adding load_switches only increases the size with 4 bytes, as can be seen from pahole:
struct power_supply_desc {
const char * name; /* 0 4 */
enum power_supply_type type; /* 4 4 */
u32 charge_types; /* 8 4 */
u32 usb_types; /* 12 4 */
u32 load_switches; /* 16 4 */
const enum power_supply_property * properties; /* 20 4 */
size_t num_properties; /* 24 4 */
int (*get_property)(...); /* 28 4 */
int (*set_property)(...); /* 32 4 */
int (*property_is_writeable)(...); /* 36 4 */
void (*external_power_changed)(...); /* 40 4 */
int (*init)(struct power_supply *); /* 44 4 */
int use_for_apm; /* 48 4 */
bool no_thermal; /* 52 1 */
u8 charge_behaviours; /* 53 1 */ /* size: 56, cachelines: 1, members: 15 */
/* padding: 2 */
/* last cacheline: 56 bytes */};
--- Documentation/ABI/testing/sysfs-class-power | 25 +++++++++++++++++++++ drivers/power/supply/power_supply_sysfs.c | 17 ++++++++++++++ include/linux/power_supply.h | 10 +++++++++ 3 files changed, 52 insertions(+)
Documentation/ABI/testing/sysfs-class-power +25 -0
@@ -590,6 +590,31 @@ Description: Valid values: 0 - 100 (percent) +What: /sys/class/power_supply/<supply_name>/load_switch +Date: June 2026 +Contact: [email protected] +Description: + Devices can control the connection from power to system load. + For example, with a field-effect transistor between a battery + and the system load (BATFET). This entry controls such switch. + The obvious states are "on" and "off", i.e. there is a + connection or not, respectively. However, many devices can also + enter special modes such as "low-power", "shipping" or "deep + sleep". In these modes the switch is usually off and the + quiescent current quite low. + + Access: Read, Write + + Valid values: + + ============= ================================== + "Unknown" (0) Unknown mode. + "On" (1) Power is connected to the load. + "Off" (2) Power is disconnected to the load. + "Standby" (3) Low-power mode. + "Ship" (4) Ship mode. + ============= ================================== + **USB Properties** What: /sys/class/power_supply/<supply_name>/input_current_limit
drivers/power/supply/power_supply_sysfs.c +17 -0
@@ -152,6 +152,14 @@ static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = { [POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge", }; +static const char *const POWER_SUPPLY_LOAD_SWITCH_TEXT [] = { + [POWER_SUPPLY_LOAD_SWITCH_UNKNOWN ] ="Unknown" , + [POWER_SUPPLY_LOAD_SWITCH_ON ] ="On" , + [POWER_SUPPLY_LOAD_SWITCH_OFF ] ="Off" , + [POWER_SUPPLY_LOAD_SWITCH_STANDBY ] ="Standby" , + [POWER_SUPPLY_LOAD_SWITCH_SHIP ] ="Ship" , +}; +static struct power_supply_attr power_supply_attrs[]__ro_after_init = {/* Properties of type `int' */ POWER_SUPPLY_ENUM_ATTR (STATUS ),
@@ -231,6 +239,7 @@ static struct power_supply_attr power_supply_attrs[] __ro_after_init = {POWER_SUPPLY_ATTR (MANUFACTURE_DAY ),POWER_SUPPLY_ATTR (INTERNAL_RESISTANCE ),POWER_SUPPLY_ATTR (STATE_OF_HEALTH ), +POWER_SUPPLY_ENUM_ATTR (LOAD_SWITCH ),/* Properties of type `const char *' */ POWER_SUPPLY_ATTR (MODEL_NAME ), POWER_SUPPLY_ATTR(MANUFACTURER),
@@ -400,6 +409,14 @@ static ssize_t power_supply_format_property(struct device *dev, ret =power_supply_show_charge_types (dev, psy, value.intval, buf);break ; +case POWER_SUPPLY_PROP_LOAD_SWITCH : +if (uevent)/* no possible values in uevents */ + goto default_format; + ret =power_supply_show_enum_with_available ( + dev,POWER_SUPPLY_LOAD_SWITCH_TEXT , +ARRAY_SIZE (POWER_SUPPLY_LOAD_SWITCH_TEXT ), + psy->desc->load_switches, value.intval, buf); +break ; case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER: ret =sysfs_emit (buf,"%s\n" , value.strval);break ;
include/linux/power_supply.h +10 -0
@@ -104,6 +104,14 @@ enum { POWER_SUPPLY_SCOPE_DEVICE, }; +enum { +POWER_SUPPLY_LOAD_SWITCH_UNKNOWN =0 , +POWER_SUPPLY_LOAD_SWITCH_ON , +POWER_SUPPLY_LOAD_SWITCH_OFF , +POWER_SUPPLY_LOAD_SWITCH_STANDBY , +POWER_SUPPLY_LOAD_SWITCH_SHIP , +}; +enum power_supply_property {/* Properties of type `int' */ POWER_SUPPLY_PROP_STATUS =0 ,
@@ -182,6 +190,7 @@ enum power_supply_property {POWER_SUPPLY_PROP_MANUFACTURE_DAY ,POWER_SUPPLY_PROP_INTERNAL_RESISTANCE ,POWER_SUPPLY_PROP_STATE_OF_HEALTH , +POWER_SUPPLY_PROP_LOAD_SWITCH ,/* Properties of type `const char *' */ POWER_SUPPLY_PROP_MODEL_NAME , POWER_SUPPLY_PROP_MANUFACTURER,
@@ -261,6 +270,7 @@ struct power_supply_desc {enum power_supply_type type;u32 charge_types;u32 usb_types; +u32 load_switches;const enum power_supply_property *properties;size_t num_properties;
Signature · 1 line
2.43.0
PATCH v2 3/8 power: supply: ltc4162-l: Use POWER_SUPPLY_PROP_LOAD_SWITCH
In reply to Waqar HameedThe framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to select ship mode, but keep old custom sysfs ABI for backward compatibility. However, add a note in ABI documentation that one should prefer the property load_switch instead.
--- .../ABI/testing/sysfs-class-power-ltc4162l | 2 + drivers/power/supply/ltc4162-l-charger.c | 56 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-)
Documentation/ABI/testing/sysfs-class-power-ltc4162l +2 -0
@@ -77,6 +77,8 @@ Description: The ship mode, when armed, activates once the input voltage drops below 1V. + Note: use /sys/class/power_supply/ltc4162-l/load_switch instead. + Access: Read, Write Valid values: 0 (disable) or 1 (enable)
drivers/power/supply/ltc4162-l-charger.c +50 -6
107 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v2 4/8 power: supply: rt9471: Use POWER_SUPPLY_PROP_LOAD_SWITCH
In reply to Waqar HameedThe framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to control the BATFET, but keep old custom sysfs ABI for backward compatibility. However, add a note in ABI documentation that one should prefer the property load_switch instead.
--- .../ABI/testing/sysfs-class-power-rt9471 | 2 + drivers/power/supply/rt9471.c | 54 ++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-)
Documentation/ABI/testing/sysfs-class-power-rt9471 +2 -0
@@ -11,6 +11,8 @@ Description: mode. 'Disable' also can help to leave it, but it's more like to abort the action before the device really enter shipping mode. + Note: use /sys/class/power_supply/rt9471-*/load_switch instead. + Access: Read, Write Valid values: - 1: enabled
drivers/power/supply/rt9471.c +48 -6
106 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v2 5/8 power: supply: rt9467: Use POWER_SUPPLY_PROP_LOAD_SWITCH
In reply to Waqar HameedThe framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to control the BATFET, but keep old custom sysfs ABI for backward compatibility. However, add a note in ABI documentation that one should prefer the property load_switch instead.
--- .../ABI/testing/sysfs-class-power-rt9467 | 2 + drivers/power/supply/rt9467-charger.c | 54 ++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-)
Documentation/ABI/testing/sysfs-class-power-rt9467 +2 -0
@@ -13,6 +13,8 @@ Description: 'Disable' also can help to leave it, but it's more like to abort the action before the device really enter shipping mode. + Note: use /sys/class/power_supply/rt9467-*/load_switch instead. + Access: Read, Write Valid values: - 1: enabled
drivers/power/supply/rt9467-charger.c +48 -6
106 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v2 6/8 power: supply: bq24257: Use POWER_SUPPLY_PROP_LOAD_SWITCH
In reply to Waqar HameedThe framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to control SYSOFF, but keep old custom sysfs ABI for backward compatibility.
--- drivers/power/supply/bq24257_charger.c | 43 +++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)
drivers/power/supply/bq24257_charger.c +42 -1
@@ -295,6 +295,40 @@ static int bq24257_set_input_current_limit(struct bq24257_device *bq, BQ24257_IILIMIT_MAP_SIZE)); } +static int bq24257_get_sys_switch (struct bq24257_device *bq, +union power_supply_propval *val) +{ +int ret; + + ret =bq24257_field_read (bq,F_SYSOFF ); +if (ret <0 ) +return ret; + + val->intval = ret ?POWER_SUPPLY_LOAD_SWITCH_OFF : +POWER_SUPPLY_LOAD_SWITCH_ON ; + +return 0 ; +} + +static int bq24257_set_sys_switch (struct bq24257_device *bq, +const union power_supply_propval *val) +{ +u8 regval; + +switch (val->intval) { +case POWER_SUPPLY_LOAD_SWITCH_ON : + regval =0 ; +break ; +case POWER_SUPPLY_LOAD_SWITCH_OFF : + regval =1 ; +break ; +default : +return -EINVAL ; + } + +return bq24257_field_write (bq,F_SYSOFF , regval); +} +static int bq24257_power_supply_get_property (struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
@@ -381,7 +415,8 @@ static int bq24257_power_supply_get_property(struct power_supply *psy,case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :return bq24257_get_input_current_limit (bq, val); - +case POWER_SUPPLY_PROP_LOAD_SWITCH : +return bq24257_get_sys_switch (bq, val);default :return -EINVAL ; }
@@ -398,6 +433,8 @@ static int bq24257_power_supply_set_property(struct power_supply *psy,switch (prop) {case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :return bq24257_set_input_current_limit (bq, val); +case POWER_SUPPLY_PROP_LOAD_SWITCH : +return bq24257_set_sys_switch (bq, val);default :return -EINVAL ; }
@@ -408,6 +445,7 @@ static int bq24257_power_supply_property_is_writeable(struct power_supply *psy, {switch (psp) {case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : +case POWER_SUPPLY_PROP_LOAD_SWITCH :return true;default :return false;
@@ -740,6 +778,7 @@ static enum power_supply_property bq24257_power_supply_props[] = {POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX ,POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT ,POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT , + POWER_SUPPLY_PROP_LOAD_SWITCH, }; static char *bq24257_charger_supplied_to[] = {
@@ -749,6 +788,8 @@ static char *bq24257_charger_supplied_to[] = {static const struct power_supply_desc bq24257_power_supply_desc = { .name ="bq24257-charger" , .type =POWER_SUPPLY_TYPE_USB , + .load_switches =BIT (POWER_SUPPLY_LOAD_SWITCH_ON ) | +BIT (POWER_SUPPLY_LOAD_SWITCH_OFF ), .properties = bq24257_power_supply_props, .num_properties =ARRAY_SIZE (bq24257_power_supply_props), .get_property = bq24257_power_supply_get_property,
Signature · 1 line
2.43.0
PATCH v2 7/8 power: supply: bq24190: Use POWER_SUPPLY_PROP_LOAD_SWITCH
In reply to Waqar HameedThe online-property has historically been (ab)used for controlling the BATFET in this driver. The framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to control the BATFET, but keep the support for online in order to have ABI backward compatibility.
Moreover, don't bother with converting the online-functions to use the new charger_get/set_batfet_ctrl() to keep the code more readable. It's already quite messy, e.g. charge_set_online() calls battery_set_online().
--- drivers/power/supply/bq24190_charger.c | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
drivers/power/supply/bq24190_charger.c +62 -0
@@ -1294,6 +1294,58 @@ static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi, ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval); } +static int bq24190_charger_get_batfet_ctrl (struct bq24190_dev_info *bdi, +union power_supply_propval *val) +{ +u8 regval; +int ret; + + ret =bq24190_read_mask (bdi,BQ24190_REG_MOC , +BQ24190_REG_MOC_BATFET_DISABLE_MASK , +BQ24190_REG_MOC_BATFET_DISABLE_SHIFT , + ®val); +if (ret <0 ) +return ret; + +/* +* Datasheet defines shipping mode as BATFET off _and_ the watchdog +* disabled. Since the watchdog is disabled during the whole lifetime +* (from probe), shipping mode is the only "off" state that can be +* achievable. +*/ + val->intval = regval ?POWER_SUPPLY_LOAD_SWITCH_SHIP : +POWER_SUPPLY_LOAD_SWITCH_ON ; +return 0 ; +} + +static int +bq24190_charger_set_batfet_ctrl (struct bq24190_dev_info *bdi, +const union power_supply_propval *val) +{ +u8 regval; + +/* +* Datasheet defines shipping mode as BATFET off _and_ the watchdog +* disabled. Since the watchdog is disabled during the whole lifetime +* (from probe), shipping mode is the only "off" state that can be +* achievable. +*/ +switch (val->intval) { +case POWER_SUPPLY_LOAD_SWITCH_ON : + regval =0 ; +break ; +case POWER_SUPPLY_LOAD_SWITCH_SHIP : + regval =1 ; +break ; +default : +return -EINVAL ; + } + +return bq24190_write_mask (bdi,BQ24190_REG_MOC , +BQ24190_REG_MOC_BATFET_DISABLE_MASK , +BQ24190_REG_MOC_BATFET_DISABLE_SHIFT , regval); +} +static int bq24190_charger_get_property (struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val) {
@@ -1350,6 +1402,9 @@ static int bq24190_charger_get_property(struct power_supply *psy, val->intval =POWER_SUPPLY_SCOPE_SYSTEM ; ret =0 ;break ; +case POWER_SUPPLY_PROP_LOAD_SWITCH : + ret =bq24190_charger_get_batfet_ctrl (bdi, val); +break ;case POWER_SUPPLY_PROP_MODEL_NAME : val->strval = bdi->model_name; ret =0 ;
@@ -1400,6 +1455,9 @@ static int bq24190_charger_set_property(struct power_supply *psy,case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : ret =bq24190_charger_set_iinlimit (bdi, val);break ; +case POWER_SUPPLY_PROP_LOAD_SWITCH : + ret =bq24190_charger_set_batfet_ctrl (bdi, val); +break ;default : ret = -EINVAL ; }
@@ -1420,6 +1478,7 @@ static int bq24190_charger_property_is_writeable(struct power_supply *psy,case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT :case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE :case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : +case POWER_SUPPLY_PROP_LOAD_SWITCH :return 1 ;default :return 0 ;
@@ -1480,6 +1539,7 @@ static enum power_supply_property bq24190_charger_properties[] = {POWER_SUPPLY_PROP_SCOPE ,POWER_SUPPLY_PROP_MODEL_NAME ,POWER_SUPPLY_PROP_MANUFACTURER , + POWER_SUPPLY_PROP_LOAD_SWITCH, }; static char *bq24190_charger_supplied_to[] = {
@@ -1498,6 +1558,8 @@ static const struct power_supply_desc bq24190_charger_desc = { .charge_types = BIT(POWER_SUPPLY_CHARGE_TYPE_NONE) |BIT (POWER_SUPPLY_CHARGE_TYPE_TRICKLE ) | BIT(POWER_SUPPLY_CHARGE_TYPE_FAST), + .load_switches =BIT (POWER_SUPPLY_LOAD_SWITCH_ON ) | + BIT(POWER_SUPPLY_LOAD_SWITCH_SHIP), };/* Battery power supply property routines */
Signature · 1 line
2.43.0
PATCH v2 8/8 power: supply: bq25630: Add support for BATFET control
In reply to Waqar HameedThe framework supports controlling system load with POWER_SUPPLY_PROP_LOAD_SWITCH. Use this to select between the different supported BATFET control modes.
--- drivers/power/supply/bq25630_charger.c | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
drivers/power/supply/bq25630_charger.c +84 -0
@@ -112,6 +112,12 @@#define BQ25630_ITERM_MAX 1000000#define BQ25630_ITERM_STEP 10000 +/* BATFET control modes. */ +#define BQ25630_BATFET_CTRL_IDLE 0x00 +#define BQ25630_BATFET_CTRL_SHUTDOWN 0x01 +#define BQ25630_BATFET_CTRL_SHIP 0x02 +#define BQ25630_BATFET_CTRL_STANDBY 0x03 +/* Charge types. */ #define BQ25630_CHG_STAT_NOT_CHARGING 0x00#define BQ25630_CHG_STAT_TRICKLE_CHARGE 0x01
@@ -587,6 +593,71 @@ static int bq25630_read_vbus(struct bq25630_data *data, int *val)return 0 ; } +static int bq25630_read_batfet_ctrl (struct bq25630_data *data,int *val) +{ +unsigned int regval; +int ret; + + ret =regmap_field_read (data->regfields[BQ25630_REGF_BATFET_CTRL ], + ®val); +if (ret) { +dev_err (data->dev,"Could not read BATFET control (%d)\n" , ret); +return ret; + } + +switch (regval) { +case BQ25630_BATFET_CTRL_IDLE : + *val =POWER_SUPPLY_LOAD_SWITCH_ON ; +break ; +case BQ25630_BATFET_CTRL_SHUTDOWN : + *val =POWER_SUPPLY_LOAD_SWITCH_OFF ; +break ; +case BQ25630_BATFET_CTRL_SHIP : + *val =POWER_SUPPLY_LOAD_SWITCH_SHIP ; +break ; +case BQ25630_BATFET_CTRL_STANDBY : + *val =POWER_SUPPLY_LOAD_SWITCH_STANDBY ; +break ; +default : + *val =POWER_SUPPLY_LOAD_SWITCH_UNKNOWN ; + } + +return 0 ; +} + +static int bq25630_write_batfet_ctrl (struct bq25630_data *data,int val) +{ +unsigned int regval; +int ret; + +switch (val) { +case POWER_SUPPLY_LOAD_SWITCH_ON : + regval =BQ25630_BATFET_CTRL_IDLE ; +break ; +case POWER_SUPPLY_LOAD_SWITCH_OFF : + regval =BQ25630_BATFET_CTRL_SHUTDOWN ; +break ; +case POWER_SUPPLY_LOAD_SWITCH_SHIP : + regval =BQ25630_BATFET_CTRL_SHIP ; +break ; +case POWER_SUPPLY_LOAD_SWITCH_STANDBY : + regval =BQ25630_BATFET_CTRL_STANDBY ; +break ; +default : +return -EINVAL ; + } + + ret =regmap_field_write (data->regfields[BQ25630_REGF_BATFET_CTRL ], + regval); +if (ret) { +dev_err (data->dev,"Could not write BATFET control (%d)\n" , + ret); +return ret; + } + +return 0 ; +} +static int bq25630_get_status (struct bq25630_data *data,int *val) {unsigned int regval;
@@ -845,6 +916,9 @@ static int bq25630_charger_get_property(struct power_supply *psy,BQ25630_ITERM_MIN_REGVAL , &val->intval);break ; +case POWER_SUPPLY_PROP_LOAD_SWITCH : + ret =bq25630_read_batfet_ctrl (data, &val->intval); +break ;case POWER_SUPPLY_PROP_MODEL_NAME : val->strval ="BQ25630" ;break ;
@@ -913,6 +987,9 @@ static int bq25630_charger_set_property(struct power_supply *psy,BQ25630_ITERM_MIN_REGVAL , val->intval);break ; +case POWER_SUPPLY_PROP_LOAD_SWITCH : + ret =bq25630_write_batfet_ctrl (data, val->intval); +break ;default :return -EINVAL ; }
@@ -932,6 +1009,7 @@ static int bq25630_charger_property_is_writeable(struct power_supply *psy,case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT :case POWER_SUPPLY_PROP_PRECHARGE_CURRENT :case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT : +case POWER_SUPPLY_PROP_LOAD_SWITCH :return true;default :return false;
@@ -954,6 +1032,7 @@ static const enum power_supply_property bq25630_charger_properties[] = {POWER_SUPPLY_PROP_USB_TYPE ,POWER_SUPPLY_PROP_PRECHARGE_CURRENT ,POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT , +POWER_SUPPLY_PROP_LOAD_SWITCH ,POWER_SUPPLY_PROP_MODEL_NAME , POWER_SUPPLY_PROP_MANUFACTURER, };
@@ -972,6 +1051,11 @@ static const struct power_supply_desc bq25630_charger_psy_desc = {BIT (POWER_SUPPLY_USB_TYPE_DCP ) |BIT (POWER_SUPPLY_USB_TYPE_CDP ) | BIT(POWER_SUPPLY_USB_TYPE_C), + .load_switches =BIT (POWER_SUPPLY_LOAD_SWITCH_UNKNOWN ) | +BIT (POWER_SUPPLY_LOAD_SWITCH_ON ) | +BIT (POWER_SUPPLY_LOAD_SWITCH_OFF ) | +BIT (POWER_SUPPLY_LOAD_SWITCH_STANDBY ) | + BIT(POWER_SUPPLY_LOAD_SWITCH_SHIP), .properties = bq25630_charger_properties, .num_properties = ARRAY_SIZE(bq25630_charger_properties), .get_property = bq25630_charger_get_property,
Signature · 1 line
2.43.0
Sebastian Reichel
AppliedQuoted 11 lines · Waqar Hameed
During discussions of the development of a new driver [1], it was concluded that a new
sysfsABI for controlling the connection from power to system load is wanted. This patchset introduces this.There are already several drivers that are controlling this, but with their own custom
sysfsentries. The drivers in this patchset were find with a simplegrepforbat\s?fet(there might be more?), and then converted to use this newsysfsABI. The old custom ABIs are left untouched of course, for backward compatibility.[...]
Applied, thanks!
[1/8] power: supply: Pack power_supply_desc to eliminate holes
commit: 1948a667e2b9e2628a73f7b594bc2461b3062471
[2/8] power: supply: Add sysfs entry for system load control
commit: eb16583b98416ea8472a48356e5eeeecbd7ab2e2
[3/8] power: supply: ltc4162-l: Use POWER_SUPPLY_PROP_LOAD_SWITCH
commit: 63ca332b361df73d0f69ebf20a325e8f014d8982
[4/8] power: supply: rt9471: Use POWER_SUPPLY_PROP_LOAD_SWITCH
commit: 63c85b1ae2f602d7865964e078b35b24196409f7
[5/8] power: supply: rt9467: Use POWER_SUPPLY_PROP_LOAD_SWITCH
commit: 22baf7437615b94a4dad8288b14ae8815761d70d
[6/8] power: supply: bq24257: Use POWER_SUPPLY_PROP_LOAD_SWITCH
commit: f7259dbf1e73f759c4a0c972a402bec3f6756b28
[7/8] power: supply: bq24190: Use POWER_SUPPLY_PROP_LOAD_SWITCH
commit: 22d3111d524958c849e8105a8201ef40bd86c1ff
[8/8] power: supply: bq25630: Add support for BATFET control
commit: 800ab4aa3ebc56333d65d158aa61bae56f9b79ecBest regards,
Signature · 1 line
Sebastian Reichel <[email protected]>