summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 65132f920459..69cbc57c2d1c 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery)
static int acpi_battery_get_state(struct acpi_battery *battery);
+static int acpi_battery_is_charged(struct acpi_battery *battery)
+{
+ /* either charging or discharging */
+ if (battery->state != 0)
+ return 0;
+
+ /* battery not reporting charge */
+ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+ battery->capacity_now == 0)
+ return 0;
+
+ /* good batteries update full_charge as the batteries degrade */
+ if (battery->full_charge_capacity == battery->capacity_now)
+ return 1;
+
+ /* fallback to using design values for broken batteries */
+ if (battery->design_capacity == battery->capacity_now)
+ return 1;
+
+ /* we don't do any sort of metric based on percentages */
+ return 0;
+}
+
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (battery->state & 0x02)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else if (battery->state == 0)
+ else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;