[BATTERY] Switch to using device_attribute, from the hardware driver

David Woodhouse dwmw2 at infradead.org
Tue Nov 7 22:38:26 EST 2006


Commit:     0513b2f5473f1e8bb8880c9dee8e1d63af86336e
Parent:     74e2a48a77347d348e9ed21576863d0d9b51c690
commit 0513b2f5473f1e8bb8880c9dee8e1d63af86336e
Author:     David Woodhouse <dwmw2 at infradead.org>
AuthorDate: Tue Oct 24 09:56:46 2006 +0100
Commit:     David Woodhouse <dwmw2 at infradead.org>
CommitDate: Tue Oct 24 09:56:46 2006 +0100

    [BATTERY] Switch to using device_attribute, from the hardware driver
    
    ... instead of the core battery class. Various other cleanups.
    
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>
---
 drivers/battery/battery-class.c |  287 ++++++++++++---------------------------
 drivers/battery/olpc-battery.c  |  165 +++++++++++++++-------
 include/linux/battery.h         |   88 ++++++------
 3 files changed, 245 insertions(+), 295 deletions(-)

diff --git a/drivers/battery/battery-class.c b/drivers/battery/battery-class.c
index 98d2f62..60325c4 100644
--- a/drivers/battery/battery-class.c
+++ b/drivers/battery/battery-class.c
@@ -19,75 +19,16 @@ #include <linux/device.h>
 #include <linux/battery.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
+#include <linux/idr.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 DEFINE_IDR(battery_idr);
+static DEFINE_SPINLOCK(idr_lock);
 
-static ssize_t battery_attribute_show_int(struct device *dev,
-					  struct device_attribute *dev_attr,
-					  char *buf, int attr)
+ssize_t battery_attribute_show_status(char *buf, unsigned long status)
 {
-	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;
+        ssize_t ret = 0;
 
 	if (status & BAT_STAT_PRESENT)
 		sprintf(buf, "present");
@@ -109,128 +50,92 @@ static ssize_t battery_attribute_show_st
 	if (status & BAT_STAT_OVERTEMP)
 		strcat(buf, ",overtemp");
 
-	if (status & BAT_STAT_FIRE)
-		strcat(buf, ",on-fire");
+	if (status & BAT_STAT_CRITICAL)
+		strcat(buf, ",critical");
 
 	if (status & BAT_STAT_CHARGE_DONE)
 		strcat(buf, ",charge-done");
 
 	strcat(buf, "\n");
-	ret = strlen(buf) + 1;
-	return ret;
+        ret = strlen(buf) + 1;
+        return ret;
 }
+EXPORT_SYMBOL_GPL(battery_attribute_show_status);
+
+ssize_t battery_attribute_show_ac_status(char *buf, unsigned long status)
+{
+	return 1 + sprintf(buf, "o%s-line\n", status?"n":"ff");
+}  
+EXPORT_SYMBOL_GPL(battery_attribute_show_ac_status);
 
-static ssize_t battery_attribute_show_ac_status(struct device *dev,
-						struct device_attribute *dev_attr,
-						char *buf)
+static ssize_t battery_attribute_show_name(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
 {
 	struct battery_dev *battery_dev = dev_get_drvdata(dev);
-	ssize_t ret = 0;
-	unsigned long status;
+	return 1 + sprintf(buf, "%s\n", battery_dev->name);
+}
 
-	status = battery_dev->status(battery_dev, BAT_STAT_AC);
-	if (status & BAT_STAT_ERROR)
-		return -EIO;
+static const char *dev_types[] = { "battery", "ac" };
 
-	if (status & BAT_STAT_AC)
-		sprintf(buf, "on-line");
-	else
-		sprintf(buf, "off-line");
+static ssize_t battery_attribute_show_type(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct battery_dev *battery_dev = dev_get_drvdata(dev);
 
-	strcat(buf, "\n");
-	ret = strlen(buf) + 1;
-	return ret;
+	return 1 + sprintf(buf, "%s\n", dev_types[battery_dev->type]);
 }
 
-/* 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);
+static DEVICE_ATTR(name, 0444, battery_attribute_show_name, NULL);
+static DEVICE_ATTR(type, 0444, battery_attribute_show_type, NULL);
+
 /**
  * battery_dev_register - register a new object of battery_dev class.
- * @dev: The parent of the device to register.
+ * @dev: 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)
+int battery_device_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;
+	int err;
+
+	if (battery_dev->type < PWRDEV_TYPE_BATTERY ||
+	    battery_dev->type > PWRDEV_TYPE_AC)
+		return -EINVAL;
+
+	do {
+		if (unlikely(!idr_pre_get(&battery_idr, GFP_KERNEL)))
+			return -ENOMEM;
+		
+		spin_lock(&idr_lock);
+		err = idr_get_new(&battery_idr, NULL, &battery_dev->id);
+		spin_unlock(&idr_lock);
+	} while(err == -EAGAIN);
+
+	if (unlikely(err))
+		return err;
+
+        battery_dev->dev = device_create(battery_class, parent, 0,
+					 "%d", battery_dev->id);
+
+        if (unlikely(IS_ERR(battery_dev->dev))) {
+		spin_lock(&idr_lock);
+		idr_remove(&battery_idr, battery_dev->id);
+		spin_unlock(&idr_lock);
+                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_type);
+        device_create_file(battery_dev->dev, &dev_attr_name);
+
+        dev_info(battery_dev->dev, "Registered power source\n");
+
+        return 0;
 }
-EXPORT_SYMBOL_GPL(battery_dev_register);
+EXPORT_SYMBOL_GPL(battery_device_register);
 
 /**
  * battery_dev_unregister - unregisters a object of battery_properties class.
@@ -238,50 +143,30 @@ EXPORT_SYMBOL_GPL(battery_dev_register);
  *
  * Unregisters a previously registered via battery_dev_register object.
  */
-void battery_dev_unregister(struct battery_dev *battery_dev)
+void battery_device_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);
+        device_remove_file(battery_dev->dev, &dev_attr_type);
+        device_remove_file(battery_dev->dev, &dev_attr_name);
+
+        device_unregister(battery_dev->dev);
+
+	spin_lock(&idr_lock);
+	idr_remove(&battery_idr, battery_dev->id);
+	spin_unlock(&idr_lock);
 }
-EXPORT_SYMBOL_GPL(battery_dev_unregister);
+EXPORT_SYMBOL_GPL(battery_device_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;
+        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);
+        class_destroy(battery_class);
 }
 
 subsys_initcall(battery_init);
diff --git a/drivers/battery/olpc-battery.c b/drivers/battery/olpc-battery.c
index c1f4fa6..09ea57a 100644
--- a/drivers/battery/olpc-battery.c
+++ b/drivers/battery/olpc-battery.c
@@ -34,38 +34,60 @@ #define		sBAT_NiMH		8
 #define sPOWER_FLAG		0xfa40
 #define		ADAPTER_IN		1
 
+struct olpc_bat_attr_int {
+	struct device_attribute dev_attr;
+	unsigned short adr1, adr2;
+	int mul, div;
+};
+
+#define ATTR_INT(_name, _adr1, _adr2, _mul, _div) {		\
+	.dev_attr.attr.name = _name,				\
+	.dev_attr.attr.mode = 0444,				\
+	.dev_attr.show = olpc_bat_attr_int_show,		\
+	.adr1 = _adr1,						\
+	.adr2 = _adr2,						\
+	.mul = _mul,						\
+	.div = _div,						\
+}
+
+#define ATTR_BYTE(_name, _adr, _mul, _div) \
+	ATTR_INT(_name, _adr, _adr+1, _mul, _div)
+#define ATTR_WORD(_name, _adr, _mul, _div) \
+	ATTR_INT(_name, _adr, _adr+1, _mul, _div)
+
+
 static int lock_ec(void)
 {
 	unsigned long timeo = jiffies + HZ/20;
 
 	while (1) {
-		unsigned char lock = inb(0x6c) & 0x80;
-		if (!lock)
-			return 0;
+                unsigned char lock = inb(0x6c) & 0x80;
+                if (!lock)
+                        return 0;
 		if (time_after(jiffies, timeo))
 			return 1;
-		yield();
-	}
+                yield();
+        }
 }
 
 static void unlock_ec(void)
 {
-	outb(0xff, 0x6c);
+        outb(0xff, 0x6c);
 }
 
 unsigned char read_ec_byte(unsigned short adr)
 {
-	outb(adr >> 8, 0x381);
-	outb(adr, 0x382);
-	return inb(0x383);
+        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);
+        return (read_ec_byte(adr) << 8) | read_ec_byte(adr+1);
 }
-
-unsigned long olpc_bat_status(struct battery_dev *dev, unsigned long mask)
+#if 0
+unsigned long olpc_bat_status(struct battery_dev *cdev, unsigned long mask)
 {
 	unsigned long result = 0;
 	unsigned short tmp;
@@ -81,7 +103,7 @@ unsigned long olpc_bat_status(struct bat
 	}
 	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)
@@ -103,35 +125,42 @@ unsigned long olpc_bat_status(struct bat
 	unlock_ec();
 	return result;
 }
-
-int olpc_bat_query_long(struct battery_dev *dev, int attr, long *result)
+#endif
+static int olpc_bat_attr_int_show(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
 {
-	int ret = 0;
+	struct olpc_bat_attr_int *battr = (void *)attr;
+	long value;
 
 	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;
+	value = read_ec_byte(battr->adr1);
+	if (battr->adr2)
+		value |= read_ec_byte(battr->adr2) << 8;
 
 	unlock_ec();
-	return ret;
+
+	value *= battr->mul;
+	value /= battr->div;
+
+	return 1 + sprintf(buf, "%ld\n", value);
 }
 
-int olpc_bat_query_str(struct battery_dev *dev, int attr, char *str, int len)
+static struct olpc_bat_attr_int attrs_int[] = {
+	ATTR_WORD(BAT_INFO_VOLTAGE, wBAT_VOLTAGE, 9760,  32000),
+	ATTR_WORD(BAT_INFO_CURRENT, wBAT_CURRENT, 15625, 120000),
+	ATTR_WORD(BAT_INFO_TEMP1,   wBAT_TEMP,    1000,  256),
+	ATTR_WORD(BAT_INFO_TEMP2,   wAMB_TEMP,    1000,  256),
+	ATTR_BYTE(BAT_INFO_CHARGE_PCT, SOC,       1,     1)
+};
+#if 0
+static int olpc_bat_attr_str_show(struct battery_dev *dev,
+				  struct device_attribute *attr,
+				  char *buf)
 {
+	struct olpc_bat_attr_int *battr = (void *)attr;
 	int ret = 0;
 
 	if (attr == BAT_INFO_TYPE) {
@@ -159,37 +188,67 @@ int olpc_bat_query_str(struct battery_de
 
 	return ret;
 }
+#endif
 
 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,
+	.name = "OLPC battery",
+	.type = PWRDEV_TYPE_BATTERY,
 };
 
-void __exit olpc_bat_exit(void)
+static struct battery_dev olpc_ac = {
+	.name = "OLPC AC",
+	.type = PWRDEV_TYPE_AC,
+};
+
+int __init olpc_bat_init(void)
 {
-	battery_dev_unregister(&olpc_bat);
+	int ret = -ENODEV;
+	unsigned short tmp;
+	int i;
+
+	if (!request_region(0x380, 4, "battery"))
+		return -EIO;
+
+	if (lock_ec())
+		goto out_rel;
+
+	tmp = read_ec_word(0xfe92);
+	unlock_ec();
+
+	if (tmp != 0x380) {
+		/* Doesn't look like OLPC EC, but unlock anyway */
+		return -ENODEV;
+	}
+
+	ret = battery_device_register(NULL, &olpc_bat);
+	if (ret)
+		goto out_rel;
+
+	ret = battery_device_register(NULL, &olpc_ac);
+	if (ret) {
+		battery_device_unregister(&olpc_bat);
+	out_rel:
+		release_region(0x380, 4);
+		return ret;
+	}
+	for (i=0; i < ARRAY_SIZE(attrs_int); i++)
+		device_create_file(olpc_bat.dev, &attrs_int[i].dev_attr);
+	
+	return ret;
 }
 
-int __init olpc_bat_init(void)
+void __exit olpc_bat_exit(void)
 {
-	battery_dev_register(NULL, &olpc_bat);
-	return 0;
+	int i;
+
+	for (i=0; i < ARRAY_SIZE(attrs_int); i++)
+		device_remove_file(olpc_bat.dev, &attrs_int[i].dev_attr);
+	battery_device_unregister(&olpc_ac);
+	battery_device_unregister(&olpc_bat);
+	release_region(0x380, 4);
 }
 
+
 module_init(olpc_bat_init);
 module_exit(olpc_bat_exit);
 
diff --git a/include/linux/battery.h b/include/linux/battery.h
index 93a5a81..1688d07 100644
--- a/include/linux/battery.h
+++ b/include/linux/battery.h
@@ -22,63 +22,69 @@ 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 PWRDEV_TYPE_BATTERY	1
+#define PWRDEV_TYPE_AC		2
+
+#define BAT_STAT_PRESENT	(1<<0)
+#define BAT_STAT_LOW		(1<<1)
+#define BAT_STAT_FULL		(1<<2)
+#define BAT_STAT_CHARGING	(1<<3)
+#define BAT_STAT_DISCHARGING	(1<<4)
+#define BAT_STAT_OVERTEMP	(1<<5)
+#define BAT_STAT_CRITICAL	(1<<6)
 #define BAT_STAT_FIRE		(1<<7)
 #define BAT_STAT_CHARGE_DONE	(1<<8)
 
-#define BAT_STAT_ERROR		(1<<31)
+/* Thou shalt not export any attributes in sysfs except these, and
+   with these units: */
+#define BAT_INFO_TEMP1		"temp1"			/* °C/1000 */
+#define BAT_INFO_TEMP1_NAME	"temp1_name"		/* string */
+
+#define BAT_INFO_TEMP2		"temp2"			/* °C/1000 */
+#define BAT_INFO_TEMP2_NAME	"temp2_name"		/* string */
 
-#define BAT_INFO_TEMP1		(0) /* °C/1000 */
-#define BAT_INFO_TEMP1_NAME	(1) /* string */
+#define BAT_INFO_VOLTAGE	"voltage"		/* mV */
+#define BAT_INFO_VOLTAGE_DESIGN	"design_voltage"	/* mV */
 
-#define BAT_INFO_TEMP2		(2) /* °C/1000 */
-#define BAT_INFO_TEMP2_NAME	(3) /* string */
+#define BAT_INFO_CURRENT	"current"		/* mA */
+#define BAT_INFO_AVG_CURRENT	"current_avg"		/* mA */
 
-#define BAT_INFO_VOLTAGE	(4) /* mV */
-#define BAT_INFO_VOLTAGE_DESIGN	(5) /* mV */
+#define BAT_INFO_CHARGE_RATE	"charge_rate"		/* CHARGE_UNITS */
+#define BAT_INFO_CHARGE		"charge"		/* CHARGE_UNITS*h */
+#define BAT_INFO_CHARGE_MAX	"design_charge"		/* CHARGE_UNITS*h */
+#define BAT_INFO_CHARGE_LAST	"charge_last"		/* CHARGE_UNITS*h */
+#define BAT_INFO_CHARGE_LOW	"charge_low_thresh"	/* CHARGE_UNITS*h */
+#define BAT_INFO_CHARGE_WARN	"charge_warn_thresh"	/* CHARGE_UNITS*h */
+#define BAT_INFO_CHARGE_UNITS	"charge_units"		/* string */
 
-#define BAT_INFO_CURRENT	(6) /* mA */
+#define BAT_INFO_CHARGE_PCT	"charge_percentage"	/* integer */
 
-#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	"time_remaining"	/* seconds */
 
-#define BAT_INFO_TIME_REMAINING	(15) /* seconds */
+#define BAT_INFO_MANUFACTURER	"manufacturer"		/* string */
+#define BAT_INFO_TECHNOLOGY	"technology"		/* string */
+#define BAT_INFO_MODEL		"model"			/* string */
+#define BAT_INFO_SERIAL		"serial"		/* string */
+#define BAT_INFO_OEM_INFO	"oem_info"		/* string */
 
-#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 */
+#define BAT_INFO_CHARGE_COUNT	"charge_count"		/* integer */
+#define BAT_INFO_MFR_DATE	"manufacture_date"	/* YYYY[-MM[-DD]] */
+#define BAT_INFO_FIRST_USE	"first_use"		/* YYYY[-MM[-DD]] */
 
 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);
+	int			id;
+	int			type;
+	const char		*name;
 
 	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);
+int battery_device_register(struct device *parent,
+			    struct battery_dev *battery_cdev);
+void battery_device_unregister(struct battery_dev *battery_cdev);
+
 
+ssize_t battery_attribute_show_status(char *buf, unsigned long status);
+ssize_t battery_attribute_show_ac_status(char *buf, unsigned long status);
 #endif /* __LINUX_BATTERY_H__ */


More information about the Commits-kernel mailing list