From: Wu Zhangjin <wuzhangjin@xxxxxxxxx> This patch adds APM_EMULATION based Battery Driver, which provides standard interface for user-space applications to manage the battery. Signed-off-by: Wu Zhangjin <wuzhangjin@xxxxxxxxx> --- .../loongson/lemote-2f/yeeloong_laptop/Kconfig | 9 ++ .../loongson/lemote-2f/yeeloong_laptop/Makefile | 1 + .../loongson/lemote-2f/yeeloong_laptop/battery.c | 127 ++++++++++++++++++++ 3 files changed, 137 insertions(+), 0 deletions(-) create mode 100644 arch/mips/loongson/lemote-2f/yeeloong_laptop/battery.c diff --git a/arch/mips/loongson/lemote-2f/yeeloong_laptop/Kconfig b/arch/mips/loongson/lemote-2f/yeeloong_laptop/Kconfig index 02d36d8..e284c91 100644 --- a/arch/mips/loongson/lemote-2f/yeeloong_laptop/Kconfig +++ b/arch/mips/loongson/lemote-2f/yeeloong_laptop/Kconfig @@ -19,4 +19,13 @@ config YEELOONG_BACKLIGHT interface for user-space applications to control the brightness of the backlight. +config YEELOONG_BATTERY + tristate "Battery Driver" + select SYS_SUPPORTS_APM_EMULATION + select APM_EMULATION + default y + help + This option adds APM emulated Battery Driver, which provides standard + interface for user-space applications to manage the battery. + endif diff --git a/arch/mips/loongson/lemote-2f/yeeloong_laptop/Makefile b/arch/mips/loongson/lemote-2f/yeeloong_laptop/Makefile index 8ad1e9d..20fe0c6 100644 --- a/arch/mips/loongson/lemote-2f/yeeloong_laptop/Makefile +++ b/arch/mips/loongson/lemote-2f/yeeloong_laptop/Makefile @@ -3,3 +3,4 @@ obj-y += ec_kb3310b.o obj-$(CONFIG_YEELOONG_BACKLIGHT) += backlight.o +obj-$(CONFIG_YEELOONG_BATTERY) += battery.o diff --git a/arch/mips/loongson/lemote-2f/yeeloong_laptop/battery.c b/arch/mips/loongson/lemote-2f/yeeloong_laptop/battery.c new file mode 100644 index 0000000..2a94292 --- /dev/null +++ b/arch/mips/loongson/lemote-2f/yeeloong_laptop/battery.c @@ -0,0 +1,127 @@ +/* + * YeeLoong Battery Driver: APM emulated support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Liu Junliang <liujl@xxxxxxxxxx> + * Wu Zhangjin <wuzj@xxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/apm-emulation.h> +#include <linux/err.h> +#include <linux/module.h> + +#include <asm/bootinfo.h> + +#include "ec_kb3310b.h" + +MODULE_AUTHOR("Liu Junliang <liujl@xxxxxxxxxx>; Wu Zhangjin <wuzj@xxxxxxxxxx>"); +MODULE_DESCRIPTION("YeeLoong laptop battery driver"); +MODULE_LICENSE("GPL"); + +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 __init yeeloong_battery_init(void) +{ + if (mips_machtype != MACH_LEMOTE_YL2F89) { + pr_err("This Driver is only for YeeLoong laptop\n"); + return -EFAULT; + } + + get_fixed_battery_info(); + + apm_get_power_status = get_power_status; + + return 0; +} + +static void __exit yeeloong_battery_exit(void) +{ +} + +module_init(yeeloong_battery_init); +module_exit(yeeloong_battery_exit); -- 1.6.2.1