* [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck
@ 2026-09-23 8:29 Umang Jain
2026-09-23 8:29 ` [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method Umang Jain
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Umang Jain @ 2026-09-23 8:29 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown
Cc: linux-acpi, linux-kernel, kernel-dev, Umang Jain
Short series to query Battery charge time ("_BCT") from ACPI tables
(1/2).
Patch 2/2 handles the case where steamdeck devices can report "Charging"
even when low power PSU is connected which is discharging the device.
Changes in v2:
- comment improvements
- split off BCT method handling into separate patch
v1:
https://lore.kernel.org/all/20260918135628.2322188-1-uajain@igalia.com/
Umang Jain (2):
acpi: battery: Query Battery charge time ("_BCT") method
acpi: battery: Handle Valve steamdeck devices quirk
drivers/acpi/battery.c | 45 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method 2026-09-23 8:29 [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain @ 2026-09-23 8:29 ` Umang Jain 2026-10-12 15:15 ` Rafael J. Wysocki (Intel) 2026-09-23 8:29 ` [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk Umang Jain 2026-10-10 16:57 ` [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain 2 siblings, 1 reply; 6+ messages in thread From: Umang Jain @ 2026-09-23 8:29 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown Cc: linux-acpi, linux-kernel, kernel-dev, Umang Jain Add plumbing for querying the Battery Charge Time ("_BCT") method. If present, set ACPI_BATTERY_BCT_PRESENT in battery flags to denote that the method is supported in ACPI. Signed-off-by: Umang Jain <uajain@igalia.com> --- drivers/acpi/battery.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 670853ec3a4d..a1b7a821abaf 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -76,6 +76,7 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); enum { ACPI_BATTERY_ALARM_PRESENT, ACPI_BATTERY_XINFO_PRESENT, + ACPI_BATTERY_BCT_PRESENT, ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, /* On Lenovo Thinkpad models from 2010 and 2011, the power unit * switches between mWh and mAh depending on whether the system @@ -110,6 +111,7 @@ struct acpi_battery { struct mutex property_lock; /* Protects properties below. */ unsigned long update_time; + unsigned long long charge_time; int revision; int rate_now; int capacity_now; @@ -613,6 +615,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) int result = 0; acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list args = { 1, &arg0 }; + + arg0.integer.value = 100; lockdep_assert_held(&battery->property_lock); @@ -638,6 +644,15 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->update_time = jiffies; kfree(buffer.pointer); + if (test_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags)) { + status = acpi_evaluate_integer(battery->device->handle, "_BCT", + &args, &battery->charge_time); + if (ACPI_FAILURE(status)) + acpi_handle_info(battery->device->handle, + "_BCT evaluation failed: %s", + acpi_format_exception(status)); + } + /* For buggy DSDTs that report negative 16-bit values for either * charging or discharging current and/or report 0 as 65536 * due to bad math. @@ -1083,6 +1098,8 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) if (result) return result; acpi_battery_init_alarm(battery); + if (acpi_has_method(battery->device->handle, "_BCT")) + set_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags); } result = acpi_battery_get_state(battery); -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method 2026-09-23 8:29 ` [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method Umang Jain @ 2026-10-12 15:15 ` Rafael J. Wysocki (Intel) 0 siblings, 0 replies; 6+ messages in thread From: Rafael J. Wysocki (Intel) @ 2026-10-12 15:15 UTC (permalink / raw) To: Umang Jain Cc: Rafael J. Wysocki, Len Brown, linux-acpi, linux-kernel, kernel-dev On Wed, Sep 23, 2026 at 10:28 AM Umang Jain <uajain@igalia.com> wrote: > > Add plumbing for querying the Battery Charge Time ("_BCT") method. > If present, set ACPI_BATTERY_BCT_PRESENT in battery flags to denote > that the method is supported in ACPI. > > Signed-off-by: Umang Jain <uajain@igalia.com> > --- > drivers/acpi/battery.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c > index 670853ec3a4d..a1b7a821abaf 100644 > --- a/drivers/acpi/battery.c > +++ b/drivers/acpi/battery.c > @@ -76,6 +76,7 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); > enum { > ACPI_BATTERY_ALARM_PRESENT, > ACPI_BATTERY_XINFO_PRESENT, > + ACPI_BATTERY_BCT_PRESENT, > ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, > /* On Lenovo Thinkpad models from 2010 and 2011, the power unit > * switches between mWh and mAh depending on whether the system > @@ -110,6 +111,7 @@ struct acpi_battery { > > struct mutex property_lock; /* Protects properties below. */ > unsigned long update_time; > + unsigned long long charge_time; This doesn't need to be unsigned long long. As per the spec, unsigned int should be sufficient. > int revision; > int rate_now; > int capacity_now; > @@ -613,6 +615,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) > int result = 0; > acpi_status status = 0; > struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; > + struct acpi_object_list args = { 1, &arg0 }; > + > + arg0.integer.value = 100; Please move the definitions of the variables related to _BCT evaluation to the code block where it gets evaluated. > > lockdep_assert_held(&battery->property_lock); > > @@ -638,6 +644,15 @@ static int acpi_battery_get_state(struct acpi_battery *battery) > battery->update_time = jiffies; > kfree(buffer.pointer); > > + if (test_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags)) { > + status = acpi_evaluate_integer(battery->device->handle, "_BCT", > + &args, &battery->charge_time); Currently, you only need to evaluate _BCT to implement the quirk in the second patch AFAICS, so it is not useful to evaluate _BCT if the quirk is not going to be used. Any chance to rearrange the code to avoid evaluating _BCT when it is not needed? > + if (ACPI_FAILURE(status)) > + acpi_handle_info(battery->device->handle, > + "_BCT evaluation failed: %s", > + acpi_format_exception(status)); Missing indentation. > + } > + > /* For buggy DSDTs that report negative 16-bit values for either > * charging or discharging current and/or report 0 as 65536 > * due to bad math. > @@ -1083,6 +1098,8 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) > if (result) > return result; > acpi_battery_init_alarm(battery); > + if (acpi_has_method(battery->device->handle, "_BCT")) > + set_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags); > } > > result = acpi_battery_get_state(battery); > -- ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk 2026-09-23 8:29 [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain 2026-09-23 8:29 ` [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method Umang Jain @ 2026-09-23 8:29 ` Umang Jain 2026-10-12 15:19 ` Rafael J. Wysocki (Intel) 2026-10-10 16:57 ` [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain 2 siblings, 1 reply; 6+ messages in thread From: Umang Jain @ 2026-09-23 8:29 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown Cc: linux-acpi, linux-kernel, kernel-dev, Umang Jain Valve steamdeck devices can report battery status as charging, even when low-powered power supply is connected to the device. The battery status is reported as charging through sysfs, even though in reality, it is discharging. To handle this case, we introduce a battery quirk for steamdeck devices ACPI_BATTERY_QUIRK_VALVE_STEAMDECK. Additionally, it has been found that on such devices, Battery Charge Time ("_BCT") is reported accurately, hence use that information for report charging vs discharging status. Battery Charge Time("_BCT") with an eligible power supply unit will have valid values whereas with a low-powered supply unit, it shall report ACPI_BATTERY_VALUE_UNKNOWN. Use this as a differentiator to determine, whether the battery of steamdeck devices is really charging or not. Signed-off-by: Umang Jain <uajain@igalia.com> --- drivers/acpi/battery.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index a1b7a821abaf..8defafd2b7c7 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -95,6 +95,14 @@ enum { * on a full charge, but showing degradation in full charge cap. */ ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, + /* + * Valve steamdeck devices can get discharged even when battery status + * is charging. This happens typically when low power supply unit is + * connected. To accurately determine this scenario, we shall read + * battery charge time ("_BCT"). This is the key differentiator to + * determine whether the steamdeck is actually charging or not. + */ + ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, }; struct acpi_battery { @@ -236,7 +244,7 @@ static int acpi_battery_get_property(struct power_supply *psy, : POWER_SUPPLY_STATUS_DISCHARGING; return 0; } - else if (battery->state & ACPI_BATTERY_STATE_CHARGING) + else if (battery->state & ACPI_BATTERY_STATE_CHARGING) { /* Check the rate and capacity to validate the status. */ if (!acpi_battery_is_full(battery) || (battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && @@ -246,6 +254,12 @@ static int acpi_battery_get_property(struct power_supply *psy, /* Full and zero rate. */ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; } + + if (test_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags) && + test_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags) && + battery->charge_time == ACPI_BATTERY_VALUE_UNKNOWN) + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + } else if (battery->state & ACPI_BATTERY_STATE_CHARGE_LIMITING) val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; else if (acpi_battery_is_charged(battery)) @@ -1072,6 +1086,18 @@ static void acpi_battery_quirks(struct acpi_battery *battery) set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags); battery->capacity_now = battery->full_charge_capacity; } + + if (test_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags)) + return; + + if (dmi_name_in_vendors("Valve")) { + const char *name; + + name = dmi_get_system_info(DMI_PRODUCT_NAME); + if ((name && (!strncmp("Jupiter", name, 7))) || + (name && (!strncmp("Galileo", name, 7)))) + set_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags); + } } static int acpi_battery_update(struct acpi_battery *battery, bool resume) -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk 2026-09-23 8:29 ` [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk Umang Jain @ 2026-10-12 15:19 ` Rafael J. Wysocki (Intel) 0 siblings, 0 replies; 6+ messages in thread From: Rafael J. Wysocki (Intel) @ 2026-10-12 15:19 UTC (permalink / raw) To: Umang Jain Cc: Rafael J. Wysocki, Len Brown, linux-acpi, linux-kernel, kernel-dev On Wed, Sep 23, 2026 at 10:28 AM Umang Jain <uajain@igalia.com> wrote: > > Valve steamdeck devices can report battery status as > charging, even when low-powered power supply is connected > to the device. The battery status is reported as charging > through sysfs, even though in reality, it is discharging. > > To handle this case, we introduce a battery quirk for steamdeck > devices ACPI_BATTERY_QUIRK_VALVE_STEAMDECK. Additionally, it has been > found that on such devices, Battery Charge Time ("_BCT") is reported > accurately, hence use that information for report charging vs > discharging status. Battery Charge Time("_BCT") with an eligible power > supply unit will have valid values whereas with a low-powered supply > unit, it shall report ACPI_BATTERY_VALUE_UNKNOWN. Use this as a > differentiator to determine, whether the battery of steamdeck devices > is really charging or not. > > Signed-off-by: Umang Jain <uajain@igalia.com> > --- > drivers/acpi/battery.c | 28 +++++++++++++++++++++++++++- > 1 file changed, 27 insertions(+), 1 deletion(-) > > diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c > index a1b7a821abaf..8defafd2b7c7 100644 > --- a/drivers/acpi/battery.c > +++ b/drivers/acpi/battery.c > @@ -95,6 +95,14 @@ enum { > * on a full charge, but showing degradation in full charge cap. > */ > ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, > + /* > + * Valve steamdeck devices can get discharged even when battery status > + * is charging. This happens typically when low power supply unit is > + * connected. To accurately determine this scenario, we shall read > + * battery charge time ("_BCT"). This is the key differentiator to > + * determine whether the steamdeck is actually charging or not. > + */ > + ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, > }; > > struct acpi_battery { > @@ -236,7 +244,7 @@ static int acpi_battery_get_property(struct power_supply *psy, > : POWER_SUPPLY_STATUS_DISCHARGING; > return 0; > } > - else if (battery->state & ACPI_BATTERY_STATE_CHARGING) > + else if (battery->state & ACPI_BATTERY_STATE_CHARGING) { > /* Check the rate and capacity to validate the status. */ > if (!acpi_battery_is_full(battery) || > (battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && > @@ -246,6 +254,12 @@ static int acpi_battery_get_property(struct power_supply *psy, > /* Full and zero rate. */ > val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; > } > + > + if (test_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags) && > + test_bit(ACPI_BATTERY_BCT_PRESENT, &battery->flags) && > + battery->charge_time == ACPI_BATTERY_VALUE_UNKNOWN) Would it be practical to evaluate _BCT here without storing charge_time in the battery object? > + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > + } > else if (battery->state & ACPI_BATTERY_STATE_CHARGE_LIMITING) > val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; > else if (acpi_battery_is_charged(battery)) > @@ -1072,6 +1086,18 @@ static void acpi_battery_quirks(struct acpi_battery *battery) > set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags); > battery->capacity_now = battery->full_charge_capacity; > } > + > + if (test_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags)) > + return; > + > + if (dmi_name_in_vendors("Valve")) { > + const char *name; > + > + name = dmi_get_system_info(DMI_PRODUCT_NAME); > + if ((name && (!strncmp("Jupiter", name, 7))) || > + (name && (!strncmp("Galileo", name, 7)))) > + set_bit(ACPI_BATTERY_QUIRK_VALVE_STEAMDECK, &battery->flags); > + } > } > > static int acpi_battery_update(struct acpi_battery *battery, bool resume) > -- ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck 2026-09-23 8:29 [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain 2026-09-23 8:29 ` [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method Umang Jain 2026-09-23 8:29 ` [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk Umang Jain @ 2026-10-10 16:57 ` Umang Jain 2 siblings, 0 replies; 6+ messages in thread From: Umang Jain @ 2026-10-10 16:57 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown; +Cc: linux-acpi, linux-kernel Hello, Gentle ping for some review? Thanks, Umang On 2026-09-23 10:29, Umang Jain wrote: > Short series to query Battery charge time ("_BCT") from ACPI tables > (1/2). > > Patch 2/2 handles the case where steamdeck devices can report "Charging" > even when low power PSU is connected which is discharging the device. > > Changes in v2: > - comment improvements > - split off BCT method handling into separate patch > > v1: > https://lore.kernel.org/all/20260918135628.2322188-1-uajain@igalia.com/ > > Umang Jain (2): > acpi: battery: Query Battery charge time ("_BCT") method > acpi: battery: Handle Valve steamdeck devices quirk > > drivers/acpi/battery.c | 45 +++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 44 insertions(+), 1 deletion(-) ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-12 15:21 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 8:29 [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain
2026-09-23 8:29 ` [PATCH v2 1/2] acpi: battery: Query Battery charge time ("_BCT") method Umang Jain
2026-10-12 15:15 ` Rafael J. Wysocki (Intel)
2026-09-23 8:29 ` [PATCH v2 2/2] acpi: battery: Handle Valve steamdeck devices quirk Umang Jain
2026-10-12 15:19 ` Rafael J. Wysocki (Intel)
2026-10-10 16:57 ` [PATCH v2 0/2] acpi: battery: Query BCT method and steamdeck Umang Jain
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox