From patchwork Wed Jan 28 13:20:11 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Hughes X-Patchwork-Id: 4230 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n0SDKu0n004280 for ; Wed, 28 Jan 2009 13:20:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750740AbZA1NUz (ORCPT ); Wed, 28 Jan 2009 08:20:55 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751123AbZA1NUy (ORCPT ); Wed, 28 Jan 2009 08:20:54 -0500 Received: from mail-qy0-f11.google.com ([209.85.221.11]:54020 "EHLO mail-qy0-f11.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750740AbZA1NUy (ORCPT ); Wed, 28 Jan 2009 08:20:54 -0500 Received: by qyk4 with SMTP id 4so7894517qyk.13 for ; Wed, 28 Jan 2009 05:20:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:subject:from:to:cc :in-reply-to:references:content-type:date:message-id:mime-version :x-mailer; bh=5CW1CbjT7L5AaPp5jYENfzfDHe3I41Xg5rpkhgqi2Lw=; b=Z4xqTkD1VDVpNh7J850ooWBi39r6IkuWgWLYb6EiklWG7iI5PVTbjMAAqlhlbMaAcZ 3jyWik7+cfOkEsVphE40GuQfmKZM5831QoGsl2ouRpNcCNtsLuiv1pZLyX1jnxF10GPU KqAfzN1Mbm4o35TP2/e90e8TYpA4Zdwux48lE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version:x-mailer; b=CCfm82AeWC80c0UarfY9Wqr1eqE6SQNhTjmSehgew/m1ZAa3hVlK5bZyIDBWlqQdaA LaJWhTsTSB9ylKFeOxfFGW81ApCr+ADF5Gur0/fqQnUx+8wRputexwkyg8CjoiRW1YV2 dcel7ASLo1kQ4JTXn/4KU86J+X1tTWotB7srA= Received: by 10.214.215.19 with SMTP id n19mr6535739qag.59.1233148852682; Wed, 28 Jan 2009 05:20:52 -0800 (PST) Received: from ?192.168.1.64? ([78.86.247.183]) by mx.google.com with ESMTPS id 6sm5718199ywn.17.2009.01.28.05.20.50 (version=SSLv3 cipher=RC4-MD5); Wed, 28 Jan 2009 05:20:51 -0800 (PST) Subject: Re: [patch] ACPI battery driver emits POWER_SUPPLY_STATUS_FULL when power lead plugged in (resend) From: Richard Hughes To: Henrique de Moraes Holschuh Cc: Alexey Starikovskiy , linux-acpi , mjg , Matthias Clasen , Len Brown In-Reply-To: <20090125134203.GA12776@khazad-dum.debian.net> References: <1232729843.3504.6.camel@hughsie-work.lan> <497A13C0.5020604@suse.de> <20090123220243.GB26701@khazad-dum.debian.net> <1232753981.3504.10.camel@hughsie-work.lan> <497A5D49.6070706@suse.de> <20090124124158.GC5325@khazad-dum.debian.net> <497B43D3.80703@suse.de> <1232879297.3518.26.camel@hughsie-work.lan> <20090125134203.GA12776@khazad-dum.debian.net> Date: Wed, 28 Jan 2009 13:20:11 +0000 Message-Id: <1233148811.4231.0.camel@hughsie-work.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.24.3 (2.24.3-1.fc10) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org On Sun, 2009-01-25 at 11:42 -0200, Henrique de Moraes Holschuh wrote: > So, the above test will still break on any proper battery subsystem with the > high watermark set below 100%, as those systems update full_charge_capacity > *only* when the cells really are full (and not because the EC decided to > stop the charging before they were full). This is what I observed when testing my patch. The attached patch checks the last full and design charge, as this seems to work in all cases I have here. In the case of broken batteries or broken hardware, we just return UNKNOWN in this "settling" state, which is much better for userspace than falling back to full. With the attached patch userspace gets the right states. In the future, maybe we can do some sort of metric over time (watching to see if the present charge changes) but for the most part the patch fixes things up for userspace. Please review, Richard. >From 3b0fb1239e5bc064766ffa3d7a45265e722fb9eb Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Sun, 25 Jan 2009 15:05:50 +0000 Subject: [PATCH] battery: don't assume we are fully charged when not charging or discharging On hardware like the T61 it can take a couple of seconds for the battery to start charging after the power is connected, and we incorrectly tell userspace that we are fully charged, and then go back to charging. Only mark a battery as fully charged when the preset charge matches either the last full charge, or the design charge. Signed-off-by: Richard Hughes --- drivers/acpi/battery.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 65132f9..69cbc57 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; -- 1.6.0.6