Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756481AbZLDNed (ORCPT ); Fri, 4 Dec 2009 08:34:33 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756226AbZLDNeb (ORCPT ); Fri, 4 Dec 2009 08:34:31 -0500 Received: from mail-pw0-f42.google.com ([209.85.160.42]:57254 "EHLO mail-pw0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756034AbZLDNea (ORCPT ); Fri, 4 Dec 2009 08:34:30 -0500 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=hP+xl3Xff6KIqs14vroKQAhnpXDFIjxQHoLRGhZ7Ir7JZlkNIIYEupHrm4JZchrXO0 CJqQ4sEeLKAsZ7LAG9VR0Hk9KZmXZpyHHzCsPOgzHO9tN70+l/p4gC3XoRw/QUc2K+Ne LM9kMYwScdyB+UZaxH7ntrydARbWRLuLTkxro= From: Wu Zhangjin To: Ralf Baechle , akpm@linux-foundation.org, linux-mips@linux-mips.org, linux-kernel@vger.kernel.org Cc: Dmitry Torokhov , Pavel Machek , "Rafael J. Wysocki" , zhangfx@lemote.com, Stephen Rothwell , linux-laptop@vger.kernel.org, Wu Zhangjin Subject: [PATCH v7 4/8] Loongson: YeeLoong: add battery driver Date: Fri, 4 Dec 2009 21:34:17 +0800 Message-Id: <059fa216d70771a6341edb2db4cc559e958273e9.1259932036.git.wuzhangjin@gmail.com> X-Mailer: git-send-email 1.6.2.1 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5029 Lines: 167 From: Wu Zhangjin This patch adds APM emulated Battery Driver, it provides standard interface(/proc/apm) for user-space applications(e.g. kpowersave, gnome-power-manager) to manage the battery. Signed-off-by: Wu Zhangjin --- drivers/platform/mips/Kconfig | 2 + drivers/platform/mips/yeeloong_laptop.c | 104 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 0 deletions(-) diff --git a/drivers/platform/mips/Kconfig b/drivers/platform/mips/Kconfig index f7a3705..0c6b5ad 100644 --- a/drivers/platform/mips/Kconfig +++ b/drivers/platform/mips/Kconfig @@ -18,6 +18,8 @@ config LEMOTE_YEELOONG2F tristate "Lemote YeeLoong Laptop" depends on LEMOTE_MACH2F select BACKLIGHT_CLASS_DEVICE + select SYS_SUPPORTS_APM_EMULATION + select APM_EMULATION default m help YeeLoong netbook is a mini laptop made by Lemote, which is basically diff --git a/drivers/platform/mips/yeeloong_laptop.c b/drivers/platform/mips/yeeloong_laptop.c index fbc4ebb..729e368 100644 --- a/drivers/platform/mips/yeeloong_laptop.c +++ b/drivers/platform/mips/yeeloong_laptop.c @@ -13,6 +13,7 @@ #include #include /* for backlight subdriver */ #include +#include /* for battery subdriver */ #include @@ -83,6 +84,106 @@ static void yeeloong_backlight_exit(void) } } +/* battery subdriver */ + +static void get_fixed_battery_info(void) +{ + int design_cap, full_charged_cap, design_vol, vendor, cell_count; + + design_cap = (ec_read(REG_BAT_DESIGN_CAP_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_CAP_LOW); + full_charged_cap = (ec_read(REG_BAT_FULLCHG_CAP_HIGH) << 8) + | ec_read(REG_BAT_FULLCHG_CAP_LOW); + design_vol = (ec_read(REG_BAT_DESIGN_VOL_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_VOL_LOW); + vendor = ec_read(REG_BAT_VENDOR); + cell_count = ec_read(REG_BAT_CELL_COUNT); + + if (vendor != 0) { + pr_info("battery vendor(%s), cells count(%d), " + "with designed capacity(%d),designed voltage(%d)," + " full charged capacity(%d)\n", + (vendor == + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO", + (cell_count == FLAG_BAT_CELL_3S1P) ? 3 : 6, + design_cap, design_vol, + full_charged_cap); + } +} + +#define APM_CRITICAL 5 + +static void get_power_status(struct apm_power_info *info) +{ + unsigned char bat_status; + + info->battery_status = APM_BATTERY_STATUS_UNKNOWN; + info->battery_flag = APM_BATTERY_FLAG_UNKNOWN; + info->units = APM_UNITS_MINS; + + info->battery_life = (ec_read(REG_BAT_RELATIVE_CAP_HIGH) << 8) | + (ec_read(REG_BAT_RELATIVE_CAP_LOW)); + + info->ac_line_status = (ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN) ? + APM_AC_ONLINE : APM_AC_OFFLINE; + + bat_status = ec_read(REG_BAT_STATUS); + + if (!(bat_status & BIT_BAT_STATUS_IN)) { + /* no battery inserted */ + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT; + info->time = 0x00; + return; + } + + /* adapter inserted */ + if (info->ac_line_status == APM_AC_ONLINE) { + if (!(bat_status & BIT_BAT_STATUS_FULL)) { + /* battery is not fully charged */ + info->battery_status = APM_BATTERY_STATUS_CHARGING; + info->battery_flag = APM_BATTERY_FLAG_CHARGING; + } else { + /* battery is fully charged */ + info->battery_status = APM_BATTERY_STATUS_HIGH; + info->battery_flag = APM_BATTERY_FLAG_HIGH; + info->battery_life = 100; + } + } else { + /* battery is too low */ + if (bat_status & BIT_BAT_STATUS_LOW) { + info->battery_status = APM_BATTERY_STATUS_LOW; + info->battery_flag = APM_BATTERY_FLAG_LOW; + if (info->battery_life <= APM_CRITICAL) { + /* we should power off the system now */ + info->battery_status = + APM_BATTERY_STATUS_CRITICAL; + info->battery_flag = APM_BATTERY_FLAG_CRITICAL; + } + } else { + /* assume the battery is high enough. */ + info->battery_status = APM_BATTERY_STATUS_HIGH; + info->battery_flag = APM_BATTERY_FLAG_HIGH; + } + } + info->time = ((info->battery_life - 3) * 54 + 142) / 60; +} + +static int yeeloong_battery_init(void) +{ + get_fixed_battery_info(); + + apm_get_power_status = get_power_status; + + return 0; +} + +static void yeeloong_battery_exit(void) +{ + if (apm_get_power_status == get_power_status) + apm_get_power_status = NULL; +} + static struct platform_device_id platform_device_ids[] = { { .name = "yeeloong_laptop", @@ -120,11 +221,14 @@ static int __init yeeloong_init(void) return ret; } + yeeloong_battery_init(); + return 0; } static void __exit yeeloong_exit(void) { + yeeloong_battery_exit(); yeeloong_backlight_exit(); platform_driver_unregister(&platform_driver); -- 1.6.2.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/