The original submission of the charge_behaviour property did not
implement proper formatting in the default formatting handler in
power_supply_sysfs.c.
At that time it was not a problem because the only provider of the UAPI,
thinkpad_acpi, did its own formatting.
Now there is an in-tree driver, mm8013, and out-of-tree driver which use
the normal power-supply properties and are affected by the wrong
formatting.
In this revision the handling of CHARGE_BEHAVIOUR in mm8013 is dropped
as it is not the correct API for it to use.
That change was not tested by me as I don't have the hardware.
Signed-off-by: Thomas Weißschuh <[email protected]>
---
Changes in v2:
- Simplify the backwards-compatibility logic (adds a preparatory patch)
- Extend test-power to also handle writing of charge_behaviour
- Drop incorrect CHARGE_BEHAVIOUR from mm8013 driver
- Replace special CHARGE_BEHAVIOUR_AVAILABLE property with bitmask in
struct power_supply_desc
- Link to v1: https://lore.kernel.org/r/20240204-power_supply-charge_behaviour_prop-v1-0-06a20c958f96@weissschuh.net
---
Thomas Weißschuh (4):
power: supply: mm8013: fix "not charging" detection
power: supply: core: ease special formatting implementations
power: supply: core: fix charge_behaviour formatting
power: supply: test-power: implement charge_behaviour property
drivers/power/supply/mm8013.c | 13 ++-----------
drivers/power/supply/power_supply_sysfs.c | 32 +++++++++++++++++++++++++------
drivers/power/supply/test_power.c | 31 ++++++++++++++++++++++++++++++
include/linux/power_supply.h | 1 +
4 files changed, 60 insertions(+), 17 deletions(-)
---
base-commit: 04b8076df2534f08bb4190f90a24e0f7f8930aca
change-id: 20230929-power_supply-charge_behaviour_prop-10ccfd96a666
Best regards,
--
Thomas Weißschuh <[email protected]>
By moving the conditional into the default-branch of the switch new
additions to the switch won't have to bypass the conditional.
This makes it easier to implement those special cases like the upcoming
change to the formatting of "charge_behaviour".
Suggested-by: Hans de Goede <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Thomas Weißschuh <[email protected]>
---
drivers/power/supply/power_supply_sysfs.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 977611e16373..10fec411794b 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -298,11 +298,6 @@ static ssize_t power_supply_show_property(struct device *dev,
}
}
- if (ps_attr->text_values_len > 0 &&
- value.intval < ps_attr->text_values_len && value.intval >= 0) {
- return sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
- }
-
switch (psp) {
case POWER_SUPPLY_PROP_USB_TYPE:
ret = power_supply_show_usb_type(dev, psy->desc,
@@ -312,7 +307,12 @@ static ssize_t power_supply_show_property(struct device *dev,
ret = sysfs_emit(buf, "%s\n", value.strval);
break;
default:
- ret = sysfs_emit(buf, "%d\n", value.intval);
+ if (ps_attr->text_values_len > 0 &&
+ value.intval < ps_attr->text_values_len && value.intval >= 0) {
+ ret = sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
+ } else {
+ ret = sysfs_emit(buf, "%d\n", value.intval);
+ }
}
return ret;
--
2.44.0
The charge_behaviours property is meant as a control-knob that can be
changed by the user.
Page 23 of [0] which documents the flag CHG_INH as follows:
CHG_INH : Charge Inhibit When the current is more than or equal to charge
threshold current,
charge inhibit temperature (upper/lower limit) :1
charge permission temperature or the current is
less than charge threshold current :0
So this is pure read-only information which is better represented as
POWER_SUPPLY_STATUS_NOT_CHARGING.
[0] https://product.minebeamitsumi.com/en/product/category/ics/battery/fuel_gauge/parts/download/__icsFiles/afieldfile/2023/07/12/1_download_01_12.pdf
Signed-off-by: Thomas Weißschuh <[email protected]>
---
drivers/power/supply/mm8013.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/drivers/power/supply/mm8013.c b/drivers/power/supply/mm8013.c
index caa272b03564..20c1651ca38e 100644
--- a/drivers/power/supply/mm8013.c
+++ b/drivers/power/supply/mm8013.c
@@ -71,7 +71,6 @@ static int mm8013_checkdevice(struct mm8013_chip *chip)
static enum power_supply_property mm8013_battery_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_CHARGE_NOW,
@@ -103,16 +102,6 @@ static int mm8013_get_property(struct power_supply *psy,
val->intval = regval;
break;
- case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
- ret = regmap_read(chip->regmap, REG_FLAGS, ®val);
- if (ret < 0)
- return ret;
-
- if (regval & MM8013_FLAG_CHG_INH)
- val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
- else
- val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
- break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
ret = regmap_read(chip->regmap, REG_FULL_CHARGE_CAPACITY, ®val);
if (ret < 0)
@@ -187,6 +176,8 @@ static int mm8013_get_property(struct power_supply *psy,
if (regval & MM8013_FLAG_DSG)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else if (regval & MM8013_FLAG_CHG_INH)
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
else if (regval & MM8013_FLAG_CHG)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (regval & MM8013_FLAG_FC)
--
2.44.0
This property is documented to have a special format which exposes all
available behaviours and the currently active one at the same time.
For this special format some helpers are provided.
However the default property logic in power_supply_sysfs.c is not using
the helper and the default logic only prints the currently active
behaviour.
Adjust power_supply_sysfs.c to follow the documented format.
There are currently two in-tree drivers exposing charge behaviours:
thinkpad_acpi and mm8013.
thinkpad_acpi is not affected by the change, as it directly uses the
helpers and does not use the power_supply_sysfs.c logic.
As mm8013 does not set implement desc->charge_behaviours.
the new logic will preserve the simple output format in this case.
Fixes: 1b0b6cc8030d ("power: supply: add charge_behaviour attributes")
Signed-off-by: Thomas Weißschuh <[email protected]>
---
drivers/power/supply/power_supply_sysfs.c | 20 ++++++++++++++++++++
include/linux/power_supply.h | 1 +
2 files changed, 21 insertions(+)
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 10fec411794b..a20aa0156b0a 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -271,6 +271,23 @@ static ssize_t power_supply_show_usb_type(struct device *dev,
return count;
}
+static ssize_t power_supply_show_charge_behaviour(struct device *dev,
+ struct power_supply *psy,
+ union power_supply_propval *value,
+ char *buf)
+{
+ int ret;
+
+ ret = power_supply_get_property(psy,
+ POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
+ value);
+ if (ret < 0)
+ return ret;
+
+ return power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours,
+ value->intval, buf);
+}
+
static ssize_t power_supply_show_property(struct device *dev,
struct device_attribute *attr,
char *buf) {
@@ -303,6 +320,9 @@ static ssize_t power_supply_show_property(struct device *dev,
ret = power_supply_show_usb_type(dev, psy->desc,
&value, buf);
break;
+ case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+ ret = power_supply_show_charge_behaviour(dev, psy, &value, buf);
+ break;
case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
ret = sysfs_emit(buf, "%s\n", value.strval);
break;
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index c0992a77feea..a50ee69503bf 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -242,6 +242,7 @@ struct power_supply_config {
struct power_supply_desc {
const char *name;
enum power_supply_type type;
+ u8 charge_behaviours;
const enum power_supply_usb_type *usb_types;
size_t num_usb_types;
const enum power_supply_property *properties;
--
2.44.0
To validate the special formatting of the "charge_behaviour" sysfs
property add it to the example driver.
Signed-off-by: Thomas Weißschuh <[email protected]>
---
drivers/power/supply/test_power.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/power/supply/test_power.c b/drivers/power/supply/test_power.c
index 0d0a77584c5d..1dfbaabb8086 100644
--- a/drivers/power/supply/test_power.c
+++ b/drivers/power/supply/test_power.c
@@ -35,6 +35,8 @@ static int battery_capacity = 50;
static int battery_voltage = 3300;
static int battery_charge_counter = -1000;
static int battery_current = -1600;
+static enum power_supply_charge_behaviour battery_charge_behaviour =
+ POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
static bool module_initialized;
@@ -123,6 +125,9 @@ static int test_power_get_battery_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = battery_current;
break;
+ case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+ val->intval = battery_charge_behaviour;
+ break;
default:
pr_info("%s: some properties deliberately report errors.\n",
__func__);
@@ -131,6 +136,26 @@ static int test_power_get_battery_property(struct power_supply *psy,
return 0;
}
+static int test_power_battery_property_is_writeable(struct power_supply *psy,
+ enum power_supply_property psp)
+{
+ return psp == POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR;
+}
+
+static int test_power_set_battery_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+ battery_charge_behaviour = val->intval;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
static enum power_supply_property test_power_ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
@@ -156,6 +181,7 @@ static enum power_supply_property test_power_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
};
static char *test_power_ac_supplied_to[] = {
@@ -178,6 +204,11 @@ static const struct power_supply_desc test_power_desc[] = {
.properties = test_power_battery_props,
.num_properties = ARRAY_SIZE(test_power_battery_props),
.get_property = test_power_get_battery_property,
+ .set_property = test_power_set_battery_property,
+ .property_is_writeable = test_power_battery_property_is_writeable,
+ .charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO)
+ | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE)
+ | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE),
},
[TEST_USB] = {
.name = "test_usb",
--
2.44.0
Hi,
On Sun, Mar 03, 2024 at 04:31:13PM +0100, Thomas Weißschuh wrote:
> The charge_behaviours property is meant as a control-knob that can be
> changed by the user.
>
> Page 23 of [0] which documents the flag CHG_INH as follows:
>
> CHG_INH : Charge Inhibit When the current is more than or equal to charge
> threshold current,
> charge inhibit temperature (upper/lower limit) :1
> charge permission temperature or the current is
> less than charge threshold current :0
>
> So this is pure read-only information which is better represented as
> POWER_SUPPLY_STATUS_NOT_CHARGING.
>
> [0] https://product.minebeamitsumi.com/en/product/category/ics/battery/fuel_gauge/parts/download/__icsFiles/afieldfile/2023/07/12/1_download_01_12.pdf
>
> Signed-off-by: Thomas Weißschuh <[email protected]>
> ---
I queued this with
Fixes: e39257cde7e8 ("power: supply: mm8013: Add more properties")
-- Sebastian
> drivers/power/supply/mm8013.c | 13 ++-----------
> 1 file changed, 2 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/power/supply/mm8013.c b/drivers/power/supply/mm8013.c
> index caa272b03564..20c1651ca38e 100644
> --- a/drivers/power/supply/mm8013.c
> +++ b/drivers/power/supply/mm8013.c
> @@ -71,7 +71,6 @@ static int mm8013_checkdevice(struct mm8013_chip *chip)
>
> static enum power_supply_property mm8013_battery_props[] = {
> POWER_SUPPLY_PROP_CAPACITY,
> - POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
> POWER_SUPPLY_PROP_CHARGE_FULL,
> POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> POWER_SUPPLY_PROP_CHARGE_NOW,
> @@ -103,16 +102,6 @@ static int mm8013_get_property(struct power_supply *psy,
>
> val->intval = regval;
> break;
> - case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> - ret = regmap_read(chip->regmap, REG_FLAGS, ®val);
> - if (ret < 0)
> - return ret;
> -
> - if (regval & MM8013_FLAG_CHG_INH)
> - val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
> - else
> - val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
> - break;
> case POWER_SUPPLY_PROP_CHARGE_FULL:
> ret = regmap_read(chip->regmap, REG_FULL_CHARGE_CAPACITY, ®val);
> if (ret < 0)
> @@ -187,6 +176,8 @@ static int mm8013_get_property(struct power_supply *psy,
>
> if (regval & MM8013_FLAG_DSG)
> val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> + else if (regval & MM8013_FLAG_CHG_INH)
> + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> else if (regval & MM8013_FLAG_CHG)
> val->intval = POWER_SUPPLY_STATUS_CHARGING;
> else if (regval & MM8013_FLAG_FC)
>
> --
> 2.44.0
>
Hi,
On Sun, Mar 03, 2024 at 04:31:14PM +0100, Thomas Wei?schuh wrote:
> By moving the conditional into the default-branch of the switch new
> additions to the switch won't have to bypass the conditional.
>
> This makes it easier to implement those special cases like the upcoming
> change to the formatting of "charge_behaviour".
>
> Suggested-by: Hans de Goede <[email protected]>
> Link: https://lore.kernel.org/lkml/[email protected]/
> Signed-off-by: Thomas Wei?schuh <[email protected]>
> ---
Thanks, queued.
-- Sebastian
> drivers/power/supply/power_supply_sysfs.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
> index 977611e16373..10fec411794b 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -298,11 +298,6 @@ static ssize_t power_supply_show_property(struct device *dev,
> }
> }
>
> - if (ps_attr->text_values_len > 0 &&
> - value.intval < ps_attr->text_values_len && value.intval >= 0) {
> - return sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
> - }
> -
> switch (psp) {
> case POWER_SUPPLY_PROP_USB_TYPE:
> ret = power_supply_show_usb_type(dev, psy->desc,
> @@ -312,7 +307,12 @@ static ssize_t power_supply_show_property(struct device *dev,
> ret = sysfs_emit(buf, "%s\n", value.strval);
> break;
> default:
> - ret = sysfs_emit(buf, "%d\n", value.intval);
> + if (ps_attr->text_values_len > 0 &&
> + value.intval < ps_attr->text_values_len && value.intval >= 0) {
> + ret = sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
> + } else {
> + ret = sysfs_emit(buf, "%d\n", value.intval);
> + }
> }
>
> return ret;
>
> --
> 2.44.0
>
>
Hi,
On Sun, Mar 03, 2024 at 04:31:15PM +0100, Thomas Wei?schuh wrote:
> This property is documented to have a special format which exposes all
> available behaviours and the currently active one at the same time.
> For this special format some helpers are provided.
>
> However the default property logic in power_supply_sysfs.c is not using
> the helper and the default logic only prints the currently active
> behaviour.
>
> Adjust power_supply_sysfs.c to follow the documented format.
>
> There are currently two in-tree drivers exposing charge behaviours:
> thinkpad_acpi and mm8013.
> thinkpad_acpi is not affected by the change, as it directly uses the
> helpers and does not use the power_supply_sysfs.c logic.
>
> As mm8013 does not set implement desc->charge_behaviours.
> the new logic will preserve the simple output format in this case.
>
> Fixes: 1b0b6cc8030d ("power: supply: add charge_behaviour attributes")
> Signed-off-by: Thomas Wei?schuh <[email protected]>
> ---
Thanks, I also queued this one, but reworked the commit message and
removed the Fixes tag considering we have only thinkpad_acpi using
this feature in-tree.
-- Sebastian
> drivers/power/supply/power_supply_sysfs.c | 20 ++++++++++++++++++++
> include/linux/power_supply.h | 1 +
> 2 files changed, 21 insertions(+)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
> index 10fec411794b..a20aa0156b0a 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -271,6 +271,23 @@ static ssize_t power_supply_show_usb_type(struct device *dev,
> return count;
> }
>
> +static ssize_t power_supply_show_charge_behaviour(struct device *dev,
> + struct power_supply *psy,
> + union power_supply_propval *value,
> + char *buf)
> +{
> + int ret;
> +
> + ret = power_supply_get_property(psy,
> + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
> + value);
> + if (ret < 0)
> + return ret;
> +
> + return power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours,
> + value->intval, buf);
> +}
> +
> static ssize_t power_supply_show_property(struct device *dev,
> struct device_attribute *attr,
> char *buf) {
> @@ -303,6 +320,9 @@ static ssize_t power_supply_show_property(struct device *dev,
> ret = power_supply_show_usb_type(dev, psy->desc,
> &value, buf);
> break;
> + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> + ret = power_supply_show_charge_behaviour(dev, psy, &value, buf);
> + break;
> case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
> ret = sysfs_emit(buf, "%s\n", value.strval);
> break;
> diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
> index c0992a77feea..a50ee69503bf 100644
> --- a/include/linux/power_supply.h
> +++ b/include/linux/power_supply.h
> @@ -242,6 +242,7 @@ struct power_supply_config {
> struct power_supply_desc {
> const char *name;
> enum power_supply_type type;
> + u8 charge_behaviours;
> const enum power_supply_usb_type *usb_types;
> size_t num_usb_types;
> const enum power_supply_property *properties;
>
> --
> 2.44.0
>
>
Hi,
On Sun, Mar 03, 2024 at 04:31:16PM +0100, Thomas Wei?schuh wrote:
> To validate the special formatting of the "charge_behaviour" sysfs
> property add it to the example driver.
>
> Signed-off-by: Thomas Wei?schuh <[email protected]>
> ---
Thanks for your patch.
> drivers/power/supply/test_power.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
[...]
> +static int test_power_set_battery_property(struct power_supply *psy,
> + enum power_supply_property psp,
> + const union power_supply_propval *val)
> +{
> + switch (psp) {
> + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> + battery_charge_behaviour = val->intval;
> + break;
This should check if user supplied val->intval is valid, otherwise
LGTM.
-- Sebastian
Hi,
On 3/3/24 4:31 PM, Thomas Weißschuh wrote:
> The charge_behaviours property is meant as a control-knob that can be
> changed by the user.
>
> Page 23 of [0] which documents the flag CHG_INH as follows:
>
> CHG_INH : Charge Inhibit When the current is more than or equal to charge
> threshold current,
> charge inhibit temperature (upper/lower limit) :1
> charge permission temperature or the current is
> less than charge threshold current :0
>
> So this is pure read-only information which is better represented as
> POWER_SUPPLY_STATUS_NOT_CHARGING.
>
> [0] https://product.minebeamitsumi.com/en/product/category/ics/battery/fuel_gauge/parts/download/__icsFiles/afieldfile/2023/07/12/1_download_01_12.pdf
>
> Signed-off-by: Thomas Weißschuh <[email protected]>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <[email protected]>
Regards,
Hans
> ---
> drivers/power/supply/mm8013.c | 13 ++-----------
> 1 file changed, 2 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/power/supply/mm8013.c b/drivers/power/supply/mm8013.c
> index caa272b03564..20c1651ca38e 100644
> --- a/drivers/power/supply/mm8013.c
> +++ b/drivers/power/supply/mm8013.c
> @@ -71,7 +71,6 @@ static int mm8013_checkdevice(struct mm8013_chip *chip)
>
> static enum power_supply_property mm8013_battery_props[] = {
> POWER_SUPPLY_PROP_CAPACITY,
> - POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
> POWER_SUPPLY_PROP_CHARGE_FULL,
> POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> POWER_SUPPLY_PROP_CHARGE_NOW,
> @@ -103,16 +102,6 @@ static int mm8013_get_property(struct power_supply *psy,
>
> val->intval = regval;
> break;
> - case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> - ret = regmap_read(chip->regmap, REG_FLAGS, ®val);
> - if (ret < 0)
> - return ret;
> -
> - if (regval & MM8013_FLAG_CHG_INH)
> - val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
> - else
> - val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
> - break;
> case POWER_SUPPLY_PROP_CHARGE_FULL:
> ret = regmap_read(chip->regmap, REG_FULL_CHARGE_CAPACITY, ®val);
> if (ret < 0)
> @@ -187,6 +176,8 @@ static int mm8013_get_property(struct power_supply *psy,
>
> if (regval & MM8013_FLAG_DSG)
> val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> + else if (regval & MM8013_FLAG_CHG_INH)
> + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> else if (regval & MM8013_FLAG_CHG)
> val->intval = POWER_SUPPLY_STATUS_CHARGING;
> else if (regval & MM8013_FLAG_FC)
>
Hi Thomas,
On 3/3/24 4:31 PM, Thomas Weißschuh wrote:
> This property is documented to have a special format which exposes all
> available behaviours and the currently active one at the same time.
> For this special format some helpers are provided.
>
> However the default property logic in power_supply_sysfs.c is not using
> the helper and the default logic only prints the currently active
> behaviour.
>
> Adjust power_supply_sysfs.c to follow the documented format.
>
> There are currently two in-tree drivers exposing charge behaviours:
> thinkpad_acpi and mm8013.
> thinkpad_acpi is not affected by the change, as it directly uses the
> helpers and does not use the power_supply_sysfs.c logic.
>
> As mm8013 does not set implement desc->charge_behaviours.
> the new logic will preserve the simple output format in this case.
Since patch 1/3 now drops the charge behaviours from mm8013 I believe
these 2 paragraphs should be replaced with:
"""
thinkpad_acpi. is the only in-tree drivers currently exposing charge
behaviours. thinkpad_acpi is not affected by the change, as it directly
uses the helpers and does not use the power_supply_sysfs.c logic.
"""
> Fixes: 1b0b6cc8030d ("power: supply: add charge_behaviour attributes")
> Signed-off-by: Thomas Weißschuh <[email protected]>
> ---
> drivers/power/supply/power_supply_sysfs.c | 20 ++++++++++++++++++++
> include/linux/power_supply.h | 1 +
> 2 files changed, 21 insertions(+)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
> index 10fec411794b..a20aa0156b0a 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -271,6 +271,23 @@ static ssize_t power_supply_show_usb_type(struct device *dev,
> return count;
> }
>
> +static ssize_t power_supply_show_charge_behaviour(struct device *dev,
> + struct power_supply *psy,
> + union power_supply_propval *value,
> + char *buf)
> +{
> + int ret;
> +
> + ret = power_supply_get_property(psy,
> + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
> + value);
> + if (ret < 0)
> + return ret;
power_supply_show_property() has already called power_supply_get_property()
before calling this, so this call can be dropped. At which point
power_supply_show_charge_behaviour() becomes just a wrapper around
power_supply_charge_behaviour_show() and thus can be dropped itself.
And then ... (continued below).
> +
> + return power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours,
> + value->intval, buf);
> +}
> +
> static ssize_t power_supply_show_property(struct device *dev,
> struct device_attribute *attr,
> char *buf) {
> @@ -303,6 +320,9 @@ static ssize_t power_supply_show_property(struct device *dev,
> ret = power_supply_show_usb_type(dev, psy->desc,
> &value, buf);
> break;
> + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> + ret = power_supply_show_charge_behaviour(dev, psy, &value, buf);
replace this line with:
ret = power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours,
value.intval, buf);
Making this patch a nice simple patch :)
Regards,
Hans
> + break;
> case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
> ret = sysfs_emit(buf, "%s\n", value.strval);
> break;
> diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
> index c0992a77feea..a50ee69503bf 100644
> --- a/include/linux/power_supply.h
> +++ b/include/linux/power_supply.h
> @@ -242,6 +242,7 @@ struct power_supply_config {
> struct power_supply_desc {
> const char *name;
> enum power_supply_type type;
> + u8 charge_behaviours;
> const enum power_supply_usb_type *usb_types;
> size_t num_usb_types;
> const enum power_supply_property *properties;
>
Hi,
On 3/3/24 4:31 PM, Thomas Weißschuh wrote:
> By moving the conditional into the default-branch of the switch new
> additions to the switch won't have to bypass the conditional.
>
> This makes it easier to implement those special cases like the upcoming
> change to the formatting of "charge_behaviour".
>
> Suggested-by: Hans de Goede <[email protected]>
> Link: https://lore.kernel.org/lkml/[email protected]/
> Signed-off-by: Thomas Weißschuh <[email protected]>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <[email protected]>
Regards,
Hans
> ---
> drivers/power/supply/power_supply_sysfs.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
> index 977611e16373..10fec411794b 100644
> --- a/drivers/power/supply/power_supply_sysfs.c
> +++ b/drivers/power/supply/power_supply_sysfs.c
> @@ -298,11 +298,6 @@ static ssize_t power_supply_show_property(struct device *dev,
> }
> }
>
> - if (ps_attr->text_values_len > 0 &&
> - value.intval < ps_attr->text_values_len && value.intval >= 0) {
> - return sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
> - }
> -
> switch (psp) {
> case POWER_SUPPLY_PROP_USB_TYPE:
> ret = power_supply_show_usb_type(dev, psy->desc,
> @@ -312,7 +307,12 @@ static ssize_t power_supply_show_property(struct device *dev,
> ret = sysfs_emit(buf, "%s\n", value.strval);
> break;
> default:
> - ret = sysfs_emit(buf, "%d\n", value.intval);
> + if (ps_attr->text_values_len > 0 &&
> + value.intval < ps_attr->text_values_len && value.intval >= 0) {
> + ret = sysfs_emit(buf, "%s\n", ps_attr->text_values[value.intval]);
> + } else {
> + ret = sysfs_emit(buf, "%d\n", value.intval);
> + }
> }
>
> return ret;
>
On 3.03.2024 4:31 PM, Thomas Weißschuh wrote:
> The charge_behaviours property is meant as a control-knob that can be
> changed by the user.
>
> Page 23 of [0] which documents the flag CHG_INH as follows:
>
> CHG_INH : Charge Inhibit When the current is more than or equal to charge
> threshold current,
> charge inhibit temperature (upper/lower limit) :1
> charge permission temperature or the current is
> less than charge threshold current :0
>
> So this is pure read-only information which is better represented as
> POWER_SUPPLY_STATUS_NOT_CHARGING.
>
> [0] https://product.minebeamitsumi.com/en/product/category/ics/battery/fuel_gauge/parts/download/__icsFiles/afieldfile/2023/07/12/1_download_01_12.pdf
>
> Signed-off-by: Thomas Weißschuh <[email protected]>
> ---
The patch is now queued, so I won't leave any additional tags,
but thanks for taking care of this, Thomas!
Konrad