aboutsummaryrefslogtreecommitdiffstats
path: root/bad
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2006-11-13 15:02:29 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-11-13 15:02:29 -0800
commita130c710da39398d59960b0d7412e4e1acb1fc0d (patch)
treeccdc8f90a1cbfc8a83ec7557f7a62b3cbf456468 /bad
parent1a72111808030ef8596bb78c9d895e374aa4093f (diff)
downloadpatches-a130c710da39398d59960b0d7412e4e1acb1fc0d.tar.gz
fix up sound patch
Diffstat (limited to 'bad')
-rw-r--r--bad/battery-class-driver.patch670
1 files changed, 670 insertions, 0 deletions
diff --git a/bad/battery-class-driver.patch b/bad/battery-class-driver.patch
new file mode 100644
index 00000000000000..56059475bc5687
--- /dev/null
+++ b/bad/battery-class-driver.patch
@@ -0,0 +1,670 @@
+From linux-kernel-owner+greg=40kroah.com-S964915AbWJWSUm@vger.kernel.org Mon Oct 23 11: 22:06 2006
+From: David Woodhouse <dwmw2@infradead.org>
+Date: Mon, 23 Oct 2006 19:20:33 +0100
+Cc: davidz@redhat.com, greg@kroah.com, mjg59@srcf.ucam.org, len.brown@intel.com, sfr@canb.auug.org.au, benh@kernel.crashing.org
+Subject: Battery class driver.
+Content-Type: text/plain; charset=UTF-8
+To: linux-kernel@vger.kernel.org, olpc-dev@laptop.org
+Mime-Version: 1.0
+Message-Id: <1161627633.19446.387.camel@pmac.infradead.org>
+Status: RO
+Content-Length: 21135
+Lines: 691
+
+
+
+[BATTERY] Add initial implementation of battery class
+
+
+I really don't like the sysfs interaction, and I don't much like the
+internal interaction with the battery drivers either. In fact, there
+isn't much I _do_ like, but it's good enough as a straw man.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+
+---
+ drivers/Kconfig | 2
+ drivers/Makefile | 1
+ drivers/battery/Kconfig | 22 +++
+ drivers/battery/Makefile | 4
+ drivers/battery/battery-class.c | 292 ++++++++++++++++++++++++++++++++++++++++
+ drivers/battery/olpc-battery.c | 198 +++++++++++++++++++++++++++
+ include/linux/battery.h | 84 +++++++++++
+ 7 files changed, 603 insertions(+)
+
+--- gregkh-2.6.orig/drivers/Kconfig
++++ gregkh-2.6/drivers/Kconfig
+@@ -34,6 +34,8 @@ source "drivers/ieee1394/Kconfig"
+
+ source "drivers/message/i2o/Kconfig"
+
++source "drivers/battery/Kconfig"
++
+ source "drivers/macintosh/Kconfig"
+
+ source "drivers/net/Kconfig"
+--- gregkh-2.6.orig/drivers/Makefile
++++ gregkh-2.6/drivers/Makefile
+@@ -30,6 +30,7 @@ obj-$(CONFIG_PARPORT) += parport/
+ obj-y += base/ block/ misc/ mfd/ net/ media/
+ obj-$(CONFIG_NUBUS) += nubus/
+ obj-$(CONFIG_ATM) += atm/
++obj-$(CONFIG_BATTERY_CLASS) += battery/
+ obj-$(CONFIG_PPC_PMAC) += macintosh/
+ obj-$(CONFIG_IDE) += ide/
+ obj-$(CONFIG_FC4) += fc4/
+--- /dev/null
++++ gregkh-2.6/drivers/battery/Kconfig
+@@ -0,0 +1,22 @@
++
++menu "Battery support"
++
++config BATTERY_CLASS
++ tristate "Battery support"
++ help
++ Say Y to enable battery class support. This allows a battery
++ information to be presented in a uniform manner for all types
++ of batteries.
++
++ Battery information from APM and ACPI is not yet available by
++ this method, but should soon be. If you use APM or ACPI, say
++ 'N', although saying 'Y' would be harmless.
++
++config OLPC_BATTERY
++ tristate "One Laptop Per Child battery"
++ depends on BATTERY_CLASS && X86_32
++ help
++ Say Y to enable support for the battery on the $100 laptop.
++
++
++endmenu
+--- /dev/null
++++ gregkh-2.6/drivers/battery/Makefile
+@@ -0,0 +1,4 @@
++# Battery code
++obj-$(CONFIG_BATTERY_CLASS) += battery-class.o
++
++obj-$(CONFIG_OLPC_BATTERY) += olpc-battery.o
+--- /dev/null
++++ gregkh-2.6/drivers/battery/battery-class.c
+@@ -0,0 +1,292 @@
++/*
++ * Battery class core
++ *
++ * © 2006 David Woodhouse <dwmw2@infradead.org>
++ *
++ * Based on LED Class support, by John Lenz and Richard Purdie:
++ *
++ * © 2005 John Lenz <lenz@cs.wisc.edu>
++ * © 2005-2006 Richard Purdie <rpurdie@openedhand.com>
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/battery.h>
++#include <linux/spinlock.h>
++#include <linux/err.h>
++
++static struct class *battery_class;
++
++/* OMFG we can't just have a single 'show' routine which is given the
++ 'class_attribute' as an argument -- we have to have 20-odd copies
++ of almost identical routines */
++
++static ssize_t battery_attribute_show_int(struct device *dev,
++ struct device_attribute *dev_attr,
++ char *buf, int attr)
++{
++ struct battery_dev *battery_dev = dev_get_drvdata(dev);
++ ssize_t ret = 0;
++ long value;
++
++ ret = battery_dev->query_long(battery_dev, attr, &value);
++ if (ret)
++ return ret;
++
++ sprintf(buf, "%ld\n", value);
++ ret = strlen(buf) + 1;
++
++ return ret;
++}
++
++static ssize_t battery_attribute_show_milli(struct device *dev,
++ struct device_attribute *dev_attr,
++ char *buf, int attr)
++{
++ struct battery_dev *battery_dev = dev_get_drvdata(dev);
++ ssize_t ret = 0;
++ long value;
++
++ ret = battery_dev->query_long(battery_dev, attr, &value);
++ if (ret)
++ return ret;
++
++ sprintf(buf, "%ld.%03ld\n", value/1000, value % 1000);
++ ret = strlen(buf) + 1;
++ return ret;
++}
++
++static ssize_t battery_attribute_show_string(struct device *dev,
++ struct device_attribute *dev_attr,
++ char *buf, int attr)
++{
++ struct battery_dev *battery_dev = dev_get_drvdata(dev);
++ ssize_t ret = 0;
++
++ ret = battery_dev->query_str(battery_dev, attr, buf, PAGE_SIZE-1);
++ if (ret)
++ return ret;
++
++ strcat(buf, "\n");
++ ret = strlen(buf) + 1;
++ return ret;
++}
++
++static ssize_t battery_attribute_show_status(struct device *dev,
++ struct device_attribute *dev_attr,
++ char *buf)
++{
++ struct battery_dev *battery_dev = dev_get_drvdata(dev);
++ ssize_t ret = 0;
++ unsigned long status;
++
++ status = battery_dev->status(battery_dev, ~BAT_STAT_AC);
++ if (status & BAT_STAT_ERROR)
++ return -EIO;
++
++ if (status & BAT_STAT_PRESENT)
++ sprintf(buf, "present");
++ else
++ sprintf(buf, "absent");
++
++ if (status & BAT_STAT_LOW)
++ strcat(buf, ",low");
++
++ if (status & BAT_STAT_FULL)
++ strcat(buf, ",full");
++
++ if (status & BAT_STAT_CHARGING)
++ strcat(buf, ",charging");
++
++ if (status & BAT_STAT_DISCHARGING)
++ strcat(buf, ",discharging");
++
++ if (status & BAT_STAT_OVERTEMP)
++ strcat(buf, ",overtemp");
++
++ if (status & BAT_STAT_FIRE)
++ strcat(buf, ",on-fire");
++
++ if (status & BAT_STAT_CHARGE_DONE)
++ strcat(buf, ",charge-done");
++
++ strcat(buf, "\n");
++ ret = strlen(buf) + 1;
++ return ret;
++}
++
++static ssize_t battery_attribute_show_ac_status(struct device *dev,
++ struct device_attribute *dev_attr,
++ char *buf)
++{
++ struct battery_dev *battery_dev = dev_get_drvdata(dev);
++ ssize_t ret = 0;
++ unsigned long status;
++
++ status = battery_dev->status(battery_dev, BAT_STAT_AC);
++ if (status & BAT_STAT_ERROR)
++ return -EIO;
++
++ if (status & BAT_STAT_AC)
++ sprintf(buf, "on-line");
++ else
++ sprintf(buf, "off-line");
++
++ strcat(buf, "\n");
++ ret = strlen(buf) + 1;
++ return ret;
++}
++
++/* Ew. We can't even use DEVICE_ATTR() if we want one named 'current' */
++#define BATTERY_DEVICE_ATTR(_name, _attr, _type) \
++static ssize_t battery_attr_show_##_attr(struct device *dev, struct device_attribute *attr, char *buf) \
++{ \
++ return battery_attribute_show_##_type(dev, attr, buf, BAT_INFO_##_attr); \
++} \
++static struct device_attribute dev_attr_##_attr = { \
++ .attr = { .name = _name, .mode = 0444, .owner = THIS_MODULE }, \
++ .show = battery_attr_show_##_attr };
++
++static DEVICE_ATTR(status,0444,battery_attribute_show_status, NULL);
++static DEVICE_ATTR(ac,0444,battery_attribute_show_ac_status, NULL);
++BATTERY_DEVICE_ATTR("temp1",TEMP1,milli);
++BATTERY_DEVICE_ATTR("temp1_name",TEMP1_NAME,string);
++BATTERY_DEVICE_ATTR("temp2",TEMP2,milli);
++BATTERY_DEVICE_ATTR("temp2_name",TEMP2_NAME,string);
++BATTERY_DEVICE_ATTR("voltage",VOLTAGE,milli);
++BATTERY_DEVICE_ATTR("voltage_design",VOLTAGE_DESIGN,milli);
++BATTERY_DEVICE_ATTR("current",CURRENT,milli);
++BATTERY_DEVICE_ATTR("charge_rate",CHARGE_RATE,milli);
++BATTERY_DEVICE_ATTR("charge_max",CHARGE_MAX,milli);
++BATTERY_DEVICE_ATTR("charge_last",CHARGE_LAST,milli);
++BATTERY_DEVICE_ATTR("charge_low",CHARGE_LOW,milli);
++BATTERY_DEVICE_ATTR("charge_warn",CHARGE_WARN,milli);
++BATTERY_DEVICE_ATTR("charge_unit",CHARGE_UNITS,string);
++BATTERY_DEVICE_ATTR("charge_percent",CHARGE_PCT,int);
++BATTERY_DEVICE_ATTR("time_remaining",TIME_REMAINING,int);
++BATTERY_DEVICE_ATTR("manufacturer",MANUFACTURER,string);
++BATTERY_DEVICE_ATTR("technology",TECHNOLOGY,string);
++BATTERY_DEVICE_ATTR("model",MODEL,string);
++BATTERY_DEVICE_ATTR("serial",SERIAL,string);
++BATTERY_DEVICE_ATTR("type",TYPE,string);
++BATTERY_DEVICE_ATTR("oem_info",OEM_INFO,string);
++
++#define REGISTER_ATTR(_attr) \
++ if (battery_dev->capabilities & (1<<BAT_INFO_##_attr)) \
++ device_create_file(battery_dev->dev, &dev_attr_##_attr);
++#define UNREGISTER_ATTR(_attr) \
++ if (battery_dev->capabilities & (1<<BAT_INFO_##_attr)) \
++ device_remove_file(battery_dev->dev, &dev_attr_##_attr);
++/**
++ * battery_dev_register - register a new object of battery_dev class.
++ * @dev: The parent of the device to register.
++ * @battery_dev: the battery_dev structure for this device.
++ */
++int battery_dev_register(struct device *parent,
++ struct battery_dev *battery_dev)
++{
++ battery_dev->dev = device_create(battery_class, parent, 0,
++ "%s", battery_dev->name);
++
++ if (unlikely(IS_ERR(battery_dev->dev)))
++ return PTR_ERR(battery_dev->dev);
++
++ dev_set_drvdata(battery_dev->dev, battery_dev);
++
++ /* register the attributes */
++ device_create_file(battery_dev->dev, &dev_attr_status);
++
++ if (battery_dev->status_cap & (1<<BAT_STAT_AC))
++ device_create_file(battery_dev->dev, &dev_attr_ac);
++
++ REGISTER_ATTR(TEMP1);
++ REGISTER_ATTR(TEMP1_NAME);
++ REGISTER_ATTR(TEMP2);
++ REGISTER_ATTR(TEMP2_NAME);
++ REGISTER_ATTR(VOLTAGE);
++ REGISTER_ATTR(VOLTAGE_DESIGN);
++ REGISTER_ATTR(CHARGE_PCT);
++ REGISTER_ATTR(CURRENT);
++ REGISTER_ATTR(CHARGE_RATE);
++ REGISTER_ATTR(CHARGE_MAX);
++ REGISTER_ATTR(CHARGE_LAST);
++ REGISTER_ATTR(CHARGE_LOW);
++ REGISTER_ATTR(CHARGE_WARN);
++ REGISTER_ATTR(CHARGE_UNITS);
++ REGISTER_ATTR(TIME_REMAINING);
++ REGISTER_ATTR(MANUFACTURER);
++ REGISTER_ATTR(TECHNOLOGY);
++ REGISTER_ATTR(MODEL);
++ REGISTER_ATTR(SERIAL);
++ REGISTER_ATTR(TYPE);
++ REGISTER_ATTR(OEM_INFO);
++
++ dev_info(battery_dev->dev, "Registered battery device\n");
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(battery_dev_register);
++
++/**
++ * battery_dev_unregister - unregisters a object of battery_properties class.
++ * @battery_dev: the battery device to unreigister
++ *
++ * Unregisters a previously registered via battery_dev_register object.
++ */
++void battery_dev_unregister(struct battery_dev *battery_dev)
++{
++ device_remove_file(battery_dev->dev, &dev_attr_status);
++
++ if (battery_dev->status_cap & (1<<BAT_STAT_AC))
++ device_remove_file(battery_dev->dev, &dev_attr_ac);
++
++ UNREGISTER_ATTR(TEMP1);
++ UNREGISTER_ATTR(TEMP1_NAME);
++ UNREGISTER_ATTR(TEMP2);
++ UNREGISTER_ATTR(TEMP2_NAME);
++ UNREGISTER_ATTR(VOLTAGE);
++ UNREGISTER_ATTR(VOLTAGE_DESIGN);
++ UNREGISTER_ATTR(CHARGE_PCT);
++ UNREGISTER_ATTR(CURRENT);
++ UNREGISTER_ATTR(CHARGE_RATE);
++ UNREGISTER_ATTR(CHARGE_MAX);
++ UNREGISTER_ATTR(CHARGE_LAST);
++ UNREGISTER_ATTR(CHARGE_LOW);
++ UNREGISTER_ATTR(CHARGE_WARN);
++ UNREGISTER_ATTR(CHARGE_UNITS);
++ UNREGISTER_ATTR(TIME_REMAINING);
++ UNREGISTER_ATTR(MANUFACTURER);
++ UNREGISTER_ATTR(TECHNOLOGY);
++ UNREGISTER_ATTR(MODEL);
++ UNREGISTER_ATTR(SERIAL);
++ UNREGISTER_ATTR(TYPE);
++ UNREGISTER_ATTR(OEM_INFO);
++
++ device_unregister(battery_dev->dev);
++}
++EXPORT_SYMBOL_GPL(battery_dev_unregister);
++
++static int __init battery_init(void)
++{
++ battery_class = class_create(THIS_MODULE, "battery");
++ if (IS_ERR(battery_class))
++ return PTR_ERR(battery_class);
++ return 0;
++}
++
++static void __exit battery_exit(void)
++{
++ class_destroy(battery_class);
++}
++
++subsys_initcall(battery_init);
++module_exit(battery_exit);
++
++MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Battery class interface");
+--- /dev/null
++++ gregkh-2.6/drivers/battery/olpc-battery.c
+@@ -0,0 +1,198 @@
++/*
++ * Battery driver for One Laptop Per Child ($100 laptop) board.
++ *
++ * © 2006 David Woodhouse <dwmw2@infradead.org>
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/battery.h>
++#include <linux/spinlock.h>
++#include <linux/err.h>
++#include <asm/io.h>
++
++#define wBAT_VOLTAGE 0xf900 /* *9.76/32, mV */
++#define wBAT_CURRENT 0xf902 /* *15.625/120, mA */
++#define wBAT_TEMP 0xf906 /* *256/1000, °C */
++#define wAMB_TEMP 0xf908 /* *256/1000, °C */
++#define SOC 0xf910 /* percentage */
++#define sMBAT_STATUS 0xfaa4
++#define sBAT_PRESENT 1
++#define sBAT_FULL 2
++#define sBAT_DESTROY 4
++#define sBAT_LOW 32
++#define sBAT_DISCHG 64
++#define sMCHARGE_STATUS 0xfaa5
++#define sBAT_CHARGE 1
++#define sBAT_OVERTEMP 4
++#define sBAT_NiMH 8
++#define sPOWER_FLAG 0xfa40
++#define ADAPTER_IN 1
++
++static int lock_ec(void)
++{
++ unsigned long timeo = jiffies + HZ/20;
++
++ while (1) {
++ unsigned char lock = inb(0x6c) & 0x80;
++ if (!lock)
++ return 0;
++ if (time_after(jiffies, timeo))
++ return 1;
++ yield();
++ }
++}
++
++static void unlock_ec(void)
++{
++ outb(0xff, 0x6c);
++}
++
++unsigned char read_ec_byte(unsigned short adr)
++{
++ outb(adr >> 8, 0x381);
++ outb(adr, 0x382);
++ return inb(0x383);
++}
++
++unsigned short read_ec_word(unsigned short adr)
++{
++ return (read_ec_byte(adr) << 8) | read_ec_byte(adr+1);
++}
++
++unsigned long olpc_bat_status(struct battery_dev *dev, unsigned long mask)
++{
++ unsigned long result = 0;
++ unsigned short tmp;
++
++ if (lock_ec()) {
++ printk(KERN_ERR "Failed to lock EC for battery access\n");
++ return BAT_STAT_ERROR;
++ }
++
++ if (mask & BAT_STAT_AC) {
++ if (read_ec_byte(sPOWER_FLAG) & ADAPTER_IN)
++ result |= BAT_STAT_AC;
++ }
++ if (mask & (BAT_STAT_PRESENT|BAT_STAT_FULL|BAT_STAT_FIRE|BAT_STAT_LOW|BAT_STAT_DISCHARGING)) {
++ tmp = read_ec_byte(sMBAT_STATUS);
++
++ if (tmp & sBAT_PRESENT)
++ result |= BAT_STAT_PRESENT;
++ if (tmp & sBAT_FULL)
++ result |= BAT_STAT_FULL;
++ if (tmp & sBAT_DESTROY)
++ result |= BAT_STAT_FIRE;
++ if (tmp & sBAT_LOW)
++ result |= BAT_STAT_LOW;
++ if (tmp & sBAT_DISCHG)
++ result |= BAT_STAT_DISCHARGING;
++ }
++ if (mask & (BAT_STAT_CHARGING|BAT_STAT_OVERTEMP)) {
++ tmp = read_ec_byte(sMCHARGE_STATUS);
++ if (tmp & sBAT_CHARGE)
++ result |= BAT_STAT_CHARGING;
++ if (tmp & sBAT_OVERTEMP)
++ result |= BAT_STAT_OVERTEMP;
++ }
++ unlock_ec();
++ return result;
++}
++
++int olpc_bat_query_long(struct battery_dev *dev, int attr, long *result)
++{
++ int ret = 0;
++
++ if (lock_ec())
++ return -EIO;
++
++ if (!(read_ec_byte(sMBAT_STATUS) & sBAT_PRESENT)) {
++ ret = -ENODEV;
++ } else if (attr == BAT_INFO_VOLTAGE) {
++ *result = read_ec_word(wBAT_VOLTAGE) * 9760 / 32000;
++ } else if (attr == BAT_INFO_CURRENT) {
++ *result = read_ec_word(wBAT_CURRENT) * 15625 / 120000;
++ } else if (attr == BAT_INFO_TEMP1) {
++ *result = read_ec_word(wBAT_TEMP) * 1000 / 256;
++ } else if (attr == BAT_INFO_TEMP2) {
++ *result = read_ec_word(wAMB_TEMP) * 1000 / 256;
++ } else if (attr == BAT_INFO_CHARGE_PCT) {
++ *result = read_ec_byte(SOC);
++ } else
++ ret = -EINVAL;
++
++ unlock_ec();
++ return ret;
++}
++
++int olpc_bat_query_str(struct battery_dev *dev, int attr, char *str, int len)
++{
++ int ret = 0;
++
++ if (attr == BAT_INFO_TYPE) {
++ snprintf(str, len, "OLPC");
++ } else if (attr == BAT_INFO_TEMP1_NAME) {
++ snprintf(str, len, "battery");
++ } else if (attr == BAT_INFO_TEMP2_NAME) {
++ snprintf(str, len, "ambient");
++ } else if (!(read_ec_byte(sMBAT_STATUS) & sBAT_PRESENT)) {
++ ret = -ENODEV;
++ } else if (attr == BAT_INFO_TECHNOLOGY) {
++ if (lock_ec())
++ ret = -EIO;
++ else {
++ unsigned short tmp = read_ec_byte(sMCHARGE_STATUS);
++ if (tmp & sBAT_NiMH)
++ snprintf(str, len, "NiMH");
++ else
++ snprintf(str, len, "unknown");
++ }
++ unlock_ec();
++ } else {
++ ret = -EINVAL;
++ }
++
++ return ret;
++}
++
++static struct battery_dev olpc_bat = {
++ .name = "OLPC",
++ .capabilities = (1<<BAT_INFO_VOLTAGE) |
++ (1<<BAT_INFO_CURRENT) |
++ (1<<BAT_INFO_TEMP1) |
++ (1<<BAT_INFO_TEMP2) |
++ (1<<BAT_INFO_CHARGE_PCT) |
++ (1<<BAT_INFO_TYPE) |
++ (1<<BAT_INFO_TECHNOLOGY) |
++ (1<<BAT_INFO_TEMP1_NAME) |
++ (1<<BAT_INFO_TEMP2_NAME),
++ .status_cap = BAT_STAT_AC | BAT_STAT_PRESENT | BAT_STAT_LOW |
++ BAT_STAT_FULL | BAT_STAT_CHARGING| BAT_STAT_DISCHARGING |
++ BAT_STAT_OVERTEMP | BAT_STAT_FIRE,
++ .status = olpc_bat_status,
++ .query_long = olpc_bat_query_long,
++ .query_str = olpc_bat_query_str,
++};
++
++void __exit olpc_bat_exit(void)
++{
++ battery_dev_unregister(&olpc_bat);
++}
++
++int __init olpc_bat_init(void)
++{
++ battery_dev_register(NULL, &olpc_bat);
++ return 0;
++}
++
++module_init(olpc_bat_init);
++module_exit(olpc_bat_exit);
++
++MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Battery class interface");
+--- /dev/null
++++ gregkh-2.6/include/linux/battery.h
+@@ -0,0 +1,84 @@
++/*
++ * Driver model for batteries
++ *
++ * © 2006 David Woodhouse <dwmw2@infradead.org>
++ *
++ * Based on LED Class support, by John Lenz and Richard Purdie:
++ *
++ * © 2005 John Lenz <lenz@cs.wisc.edu>
++ * © 2005-2006 Richard Purdie <rpurdie@openedhand.com>
++ *
++ * 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.
++ *
++ */
++#ifndef __LINUX_BATTERY_H__
++#define __LINUX_BATTERY_H__
++
++struct device;
++struct class_device;
++
++/*
++ * Battery Core
++ */
++#define BAT_STAT_AC (1<<0)
++#define BAT_STAT_PRESENT (1<<1)
++#define BAT_STAT_LOW (1<<2)
++#define BAT_STAT_FULL (1<<3)
++#define BAT_STAT_CHARGING (1<<4)
++#define BAT_STAT_DISCHARGING (1<<5)
++#define BAT_STAT_OVERTEMP (1<<6)
++#define BAT_STAT_FIRE (1<<7)
++#define BAT_STAT_CHARGE_DONE (1<<8)
++
++#define BAT_STAT_ERROR (1<<31)
++
++#define BAT_INFO_TEMP1 (0) /* °C/1000 */
++#define BAT_INFO_TEMP1_NAME (1) /* string */
++
++#define BAT_INFO_TEMP2 (2) /* °C/1000 */
++#define BAT_INFO_TEMP2_NAME (3) /* string */
++
++#define BAT_INFO_VOLTAGE (4) /* mV */
++#define BAT_INFO_VOLTAGE_DESIGN (5) /* mV */
++
++#define BAT_INFO_CURRENT (6) /* mA */
++
++#define BAT_INFO_CHARGE_RATE (7) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE (8) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE_MAX (9) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE_LAST (10) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE_LOW (11) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE_WARN (12) /* BAT_INFO_CHARGE_UNITS */
++#define BAT_INFO_CHARGE_UNITS (13) /* string */
++#define BAT_INFO_CHARGE_PCT (14) /* % */
++
++#define BAT_INFO_TIME_REMAINING (15) /* seconds */
++
++#define BAT_INFO_MANUFACTURER (16) /* string */
++#define BAT_INFO_TECHNOLOGY (17) /* string */
++#define BAT_INFO_MODEL (18) /* string */
++#define BAT_INFO_SERIAL (19) /* string */
++#define BAT_INFO_TYPE (20) /* string */
++#define BAT_INFO_OEM_INFO (21) /* string */
++
++struct battery_dev {
++ const char *name;
++ /* Capabilities of this battery driver */
++ unsigned long capabilities, status_cap;
++
++ /* Query functions */
++ unsigned long (*status)(struct battery_dev *, unsigned long mask);
++ int (*query_long)(struct battery_dev *, int attr, long *result);
++ int (*query_str)(struct battery_dev *, int attr, char *str, ssize_t len);
++
++ struct device *dev;
++ struct list_head node; /* Battery Device list */
++};
++
++extern int battery_dev_register(struct device *parent,
++ struct battery_dev *battery_dev);
++extern void battery_dev_unregister(struct battery_dev *battery_dev);
++
++#endif /* __LINUX_BATTERY_H__ */