2009-07-12 18:28:50

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 01/15] power: bq27x00: rename to bq27200.c

That driver only really works for the i2c-based device
bq27200, so rename the file and all defines.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/Kconfig | 2 +-
drivers/power/Makefile | 2 +-
.../power/{bq27x00_battery.c => bq27200_battery.c} | 99 ++++++++++----------
3 files changed, 52 insertions(+), 51 deletions(-)
rename drivers/power/{bq27x00_battery.c => bq27200_battery.c} (73%)

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 7eda348..6e087a4 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -69,7 +69,7 @@ config BATTERY_WM97XX
help
Say Y to enable support for battery measured by WM97xx aux port.

-config BATTERY_BQ27x00
+config BATTERY_BQ27200
tristate "BQ27200 battery driver"
depends on I2C
help
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index daf3179..5288595 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
-obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
+obj-$(CONFIG_BATTERY_BQ27200) += bq27200_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27200_battery.c
similarity index 73%
rename from drivers/power/bq27x00_battery.c
rename to drivers/power/bq27200_battery.c
index 62bb981..f31f167 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -1,5 +1,5 @@
/*
- * BQ27x00 battery driver
+ * BQ27200 battery driver
*
* Copyright (C) 2008 Rodolfo Giometti <[email protected]>
* Copyright (C) 2008 Eurotech S.p.A. <[email protected]>
@@ -28,11 +28,11 @@

#define DRIVER_VERSION "1.0.0"

-#define BQ27x00_REG_TEMP 0x06
-#define BQ27x00_REG_VOLT 0x08
-#define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */
-#define BQ27x00_REG_AI 0x14
-#define BQ27x00_REG_FLAGS 0x0A
+#define BQ27200_REG_TEMP 0x06
+#define BQ27200_REG_VOLT 0x08
+#define BQ27200_REG_RSOC 0x0B /* Relative State-of-Charge */
+#define BQ27200_REG_AI 0x14
+#define BQ27200_REG_FLAGS 0x0A

/* If the system has several batteries we need a different name for each
* of them...
@@ -40,26 +40,26 @@
static DEFINE_IDR(battery_id);
static DEFINE_MUTEX(battery_mutex);

-struct bq27x00_device_info;
-struct bq27x00_access_methods {
+struct bq27200_device_info;
+struct bq27200_access_methods {
int (*read)(u8 reg, int *rt_value, int b_single,
- struct bq27x00_device_info *di);
+ struct bq27200_device_info *di);
};

-struct bq27x00_device_info {
+struct bq27200_device_info {
struct device *dev;
int id;
int voltage_uV;
int current_uA;
int temp_C;
int charge_rsoc;
- struct bq27x00_access_methods *bus;
+ struct bq27200_access_methods *bus;
struct power_supply bat;

struct i2c_client *client;
};

-static enum power_supply_property bq27x00_battery_props[] = {
+static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -68,11 +68,11 @@ static enum power_supply_property bq27x00_battery_props[] = {
};

/*
- * Common code for BQ27x00 devices
+ * Common code for BQ27200 devices
*/

-static int bq27x00_read(u8 reg, int *rt_value, int b_single,
- struct bq27x00_device_info *di)
+static int bq27200_read(u8 reg, int *rt_value, int b_single,
+ struct bq27200_device_info *di)
{
int ret;

@@ -86,12 +86,12 @@ static int bq27x00_read(u8 reg, int *rt_value, int b_single,
* Return the battery temperature in Celsius degrees
* Or < 0 if something fails.
*/
-static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
+static int bq27200_temperature(struct bq27200_device_info *di)
{
int ret;
int temp = 0;

- ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di);
+ ret = bq27200_read(BQ27200_REG_TEMP, &temp, 0, di);
if (ret) {
dev_err(di->dev, "error reading temperature\n");
return ret;
@@ -104,12 +104,12 @@ static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
* Return the battery Voltage in milivolts
* Or < 0 if something fails.
*/
-static int bq27x00_battery_voltage(struct bq27x00_device_info *di)
+static int bq27200_voltage(struct bq27200_device_info *di)
{
int ret;
int volt = 0;

- ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di);
+ ret = bq27200_read(BQ27200_REG_VOLT, &volt, 0, di);
if (ret) {
dev_err(di->dev, "error reading voltage\n");
return ret;
@@ -123,18 +123,18 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di)
* Note that current can be negative signed as well
* Or 0 if something fails.
*/
-static int bq27x00_battery_current(struct bq27x00_device_info *di)
+static int bq27200_current(struct bq27200_device_info *di)
{
int ret;
int curr = 0;
int flags = 0;

- ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di);
+ ret = bq27200_read(BQ27200_REG_AI, &curr, 0, di);
if (ret) {
dev_err(di->dev, "error reading current\n");
return 0;
}
- ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
+ ret = bq27200_read(BQ27200_REG_FLAGS, &flags, 0, di);
if (ret < 0) {
dev_err(di->dev, "error reading flags\n");
return 0;
@@ -150,12 +150,12 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di)
* Return the battery Relative State-of-Charge
* Or < 0 if something fails.
*/
-static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
+static int bq27200_rsoc(struct bq27200_device_info *di)
{
int ret;
int rsoc = 0;

- ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di);
+ ret = bq27200_read(BQ27200_REG_RSOC, &rsoc, 1, di);
if (ret) {
dev_err(di->dev, "error reading relative State-of-Charge\n");
return ret;
@@ -164,30 +164,30 @@ static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
return rsoc >> 8;
}

-#define to_bq27x00_device_info(x) container_of((x), \
- struct bq27x00_device_info, bat);
+#define to_bq27200_device_info(x) container_of((x), \
+ struct bq27200_device_info, bat);

-static int bq27x00_battery_get_property(struct power_supply *psy,
+static int bq27200_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct bq27x00_device_info *di = to_bq27x00_device_info(psy);
+ struct bq27200_device_info *di = to_bq27200_device_info(psy);

switch (psp) {
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = bq27x00_battery_voltage(di);
+ val->intval = bq27200_voltage(di);
if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = val->intval <= 0 ? 0 : 1;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = bq27x00_battery_current(di);
+ val->intval = bq27200_current(di);
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = bq27x00_battery_rsoc(di);
+ val->intval = bq27200_rsoc(di);
break;
case POWER_SUPPLY_PROP_TEMP:
- val->intval = bq27x00_battery_temperature(di);
+ val->intval = bq27200_temperature(di);
break;
default:
return -EINVAL;
@@ -196,12 +196,12 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
return 0;
}

-static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
+static void bq27200_powersupply_init(struct bq27200_device_info *di)
{
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- di->bat.properties = bq27x00_battery_props;
- di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
- di->bat.get_property = bq27x00_battery_get_property;
+ di->bat.properties = bq27200_props;
+ di->bat.num_properties = ARRAY_SIZE(bq27200_props);
+ di->bat.get_property = bq27200_get_property;
di->bat.external_power_changed = NULL;
}

@@ -209,8 +209,8 @@ static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
* BQ27200 specific code
*/

-static int bq27200_read(u8 reg, int *rt_value, int b_single,
- struct bq27x00_device_info *di)
+static int _bq27200_read(u8 reg, int *rt_value, int b_single,
+ struct bq27200_device_info *di)
{
struct i2c_client *client = di->client;
struct i2c_msg msg[1];
@@ -252,8 +252,8 @@ static int bq27200_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
char *name;
- struct bq27x00_device_info *di;
- struct bq27x00_access_methods *bus;
+ struct bq27200_device_info *di;
+ struct bq27200_access_methods *bus;
int num;
int retval = 0;

@@ -293,11 +293,11 @@ static int bq27200_battery_probe(struct i2c_client *client,
i2c_set_clientdata(client, di);
di->dev = &client->dev;
di->bat.name = name;
- bus->read = &bq27200_read;
+ bus->read = &_bq27200_read;
di->bus = bus;
di->client = client;

- bq27x00_powersupply_init(di);
+ bq27200_powersupply_init(di);

retval = power_supply_register(&client->dev, &di->bat);
if (retval) {
@@ -325,7 +325,7 @@ batt_failed_1:

static int bq27200_battery_remove(struct i2c_client *client)
{
- struct bq27x00_device_info *di = i2c_get_clientdata(client);
+ struct bq27200_device_info *di = i2c_get_clientdata(client);

power_supply_unregister(&di->bat);

@@ -351,14 +351,14 @@ static const struct i2c_device_id bq27200_id[] = {

static struct i2c_driver bq27200_battery_driver = {
.driver = {
- .name = "bq27200-battery",
+ .name = "bq27200",
},
.probe = bq27200_battery_probe,
.remove = bq27200_battery_remove,
.id_table = bq27200_id,
};

-static int __init bq27x00_battery_init(void)
+static int __init bq27200_init(void)
{
int ret;

@@ -368,14 +368,15 @@ static int __init bq27x00_battery_init(void)

return ret;
}
-module_init(bq27x00_battery_init);
+module_init(bq27200_init);

-static void __exit bq27x00_battery_exit(void)
+static void __exit bq27200_exit(void)
{
i2c_del_driver(&bq27200_battery_driver);
}
-module_exit(bq27x00_battery_exit);
+module_exit(bq27200_exit);

MODULE_AUTHOR("Rodolfo Giometti <[email protected]>");
-MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
+MODULE_DESCRIPTION("BQ27200 battery monitor driver");
MODULE_LICENSE("GPL");
+
--
1.6.1.3


2009-07-12 18:29:01

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 07/15] power: bq27200: add missing suplicants

add the missing suplicants to bq27200 driver.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 44375d6..385a505 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -164,6 +164,10 @@ static int bq27200_get_property(struct power_supply *psy,
return 0;
}

+static char *bq27200_supplied_to[] = {
+ "main-battery",
+};
+
static int bq27200_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -186,6 +190,8 @@ static int bq27200_battery_probe(struct i2c_client *client,
bq->bat.properties = bq27200_props;
bq->bat.num_properties = ARRAY_SIZE(bq27200_props);
bq->bat.get_property = bq27200_get_property;
+ bq->bat.supplied_to = bq27200_supplied_to;
+ bq->bat.num_supplicants = ARRAY_SIZE(bq27200_supplied_to);

retval = power_supply_register(&client->dev, &bq->bat);
if (retval) {
--
1.6.1.3

2009-07-12 18:29:24

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 08/15] power: bq27200: define all register space

... and also add accessors for 8-bit wide registers

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 52 ++++++++++++++++++++++++++++++--------
1 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 385a505..f36633c 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -26,11 +26,31 @@

#define DRIVER_VERSION "1.0.0"

-#define BQ27200_REG_TEMP 0x06
-#define BQ27200_REG_VOLT 0x08
-#define BQ27200_REG_RSOC 0x0B /* Relative State-of-Charge */
-#define BQ27200_REG_AI 0x14
-#define BQ27200_REG_FLAGS 0x0A
+#define BQ27200_REG_CTRL 0x00 /* device control */
+#define BQ27200_REG_MODE 0x01 /* device mode */
+#define BQ27200_REG_AR 0x02 /* at-rate */
+#define BQ27200_REG_ARTTE 0x04 /* at-rate time-to-empty */
+#define BQ27200_REG_TEMP 0x06 /* temperature */
+#define BQ27200_REG_VOLT 0x08 /* voltage */
+#define BQ27200_REG_FLAGS 0x0a /* status flags */
+#define BQ27200_REG_RSOC 0x0b /* relative state-of-charge */
+#define BQ27200_REG_NAC 0x0c /* nominal available capacity */
+#define BQ27200_REG_CACD 0x0e /* discharge compensated NAC */
+#define BQ27200_REG_CACT 0x10 /* temperature compensated CACD */
+#define BQ27200_REG_LMD 0x12 /* last measured discharge */
+#define BQ27200_REG_AI 0x14 /* average current */
+#define BQ27200_REG_TTE 0x16 /* time-to-empty */
+#define BQ27200_REG_TTF 0x18 /* time-to-full */
+#define BQ27200_REG_SI 0x1a /* standby current */
+#define BQ27200_REG_STTE 0x1c /* standby time-to-empty */
+#define BQ27200_REG_MLI 0x1e /* max load current */
+#define BQ27200_REG_MLTTE 0x20 /* max load time-to-empty */
+#define BQ27200_REG_SAE 0x22 /* available energy */
+#define BQ27200_REG_AP 0x24 /* average power */
+#define BQ27200_REG_TTECP 0x26 /* time-to-empty at constant power */
+#define BQ27200_REG_CYCL 0x28 /* cycle-count since learning cycle */
+#define BQ27200_REG_CYCT 0x2a /* cycle-count total */
+#define BQ27200_REG_CSOC 0x2c /* compensated state-of-charge */

struct bq27200 {
struct power_supply bat;
@@ -56,12 +76,22 @@ static enum power_supply_property bq27200_props[] = {
* Common code for BQ27200 devices
*/

-static inline int bq27200_read(struct bq27200 *bq, u8 reg)
+static inline int bq27200_readb(struct bq27200 *bq, u8 reg)
+{
+ return i2c_smbus_read_byte_data(bq->client, reg);
+}
+
+static inline int bq27200_writeb(struct bq27200 *bq, u8 reg, u8 data)
+{
+ return i2c_smbus_write_byte_data(bq->client, reg, data);
+}
+
+static inline int bq27200_readw(struct bq27200 *bq, u8 reg)
{
return i2c_smbus_read_word_data(bq->client, reg);
}

-static inline int bq27200_write(struct bq27200 *bq, u8 reg, u8 data)
+static inline int bq27200_writew(struct bq27200 *bq, u8 reg, u16 data)
{
return i2c_smbus_write_word_data(bq->client, reg, data);
}
@@ -74,7 +104,7 @@ static int bq27200_temperature(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(bq, BQ27200_REG_TEMP);
+ ret = bq27200_readw(bq, BQ27200_REG_TEMP);
if (ret < 0) {
dev_err(&bq->client->dev, "error reading temperature\n");
return ret;
@@ -91,7 +121,7 @@ static int bq27200_voltage(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(bq, BQ27200_REG_VOLT);
+ ret = bq27200_readw(bq, BQ27200_REG_VOLT);
if (ret < 0)
dev_err(&bq->client->dev, "error reading voltage\n");

@@ -107,7 +137,7 @@ static int bq27200_current(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(bq, BQ27200_REG_AI);
+ ret = bq27200_readw(bq, BQ27200_REG_AI);
if (ret < 0) {
dev_err(&bq->client->dev, "error reading current\n");
return 0;
@@ -124,7 +154,7 @@ static int bq27200_rsoc(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(bq, BQ27200_REG_RSOC);
+ ret = bq27200_readw(bq, BQ27200_REG_RSOC);
if (ret < 0) {
dev_err(&bq->client->dev, "error reading relative State-of-Charge\n");
return ret;
--
1.6.1.3

2009-07-12 18:29:36

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 06/15] power: bq27200: rename structure to something smaller

the previous name was quite big, rename to something smaller.

Trivial patch.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 91 +++++++++++++++++++--------------------
1 files changed, 45 insertions(+), 46 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index deef1b5..44375d6 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -32,7 +32,7 @@
#define BQ27200_REG_AI 0x14
#define BQ27200_REG_FLAGS 0x0A

-struct bq27200_device_info {
+struct bq27200 {
struct power_supply bat;
struct i2c_client *client;

@@ -42,8 +42,7 @@ struct bq27200_device_info {
int temp_C;
};

-#define to_bq27200_device_info(x) container_of((x), \
- struct bq27200_device_info, bat);
+#define to_bq27200(x) container_of((x), struct bq27200, bat);

static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_PRESENT,
@@ -57,28 +56,27 @@ static enum power_supply_property bq27200_props[] = {
* Common code for BQ27200 devices
*/

-static inline int bq27200_read(struct bq27200_device_info *di, u8 reg)
+static inline int bq27200_read(struct bq27200 *bq, u8 reg)
{
- return i2c_smbus_read_word_data(di->client, reg);
+ return i2c_smbus_read_word_data(bq->client, reg);
}

-static inline int bq27200_write(struct bq27200_device_info *di,
- u8 reg, u8 data)
+static inline int bq27200_write(struct bq27200 *bq, u8 reg, u8 data)
{
- return i2c_smbus_write_word_data(di->client, reg, data);
+ return i2c_smbus_write_word_data(bq->client, reg, data);
}

/*
* Return the battery temperature in Celsius degrees
* Or < 0 if something fails.
*/
-static int bq27200_temperature(struct bq27200_device_info *di)
+static int bq27200_temperature(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(di, BQ27200_REG_TEMP);
+ ret = bq27200_read(bq, BQ27200_REG_TEMP);
if (ret < 0) {
- dev_err(&di->client->dev, "error reading temperature\n");
+ dev_err(&bq->client->dev, "error reading temperature\n");
return ret;
}

@@ -89,13 +87,13 @@ static int bq27200_temperature(struct bq27200_device_info *di)
* Return the battery Voltage in milivolts
* Or < 0 if something fails.
*/
-static int bq27200_voltage(struct bq27200_device_info *di)
+static int bq27200_voltage(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(di, BQ27200_REG_VOLT);
+ ret = bq27200_read(bq, BQ27200_REG_VOLT);
if (ret < 0)
- dev_err(&di->client->dev, "error reading voltage\n");
+ dev_err(&bq->client->dev, "error reading voltage\n");

return ret;
}
@@ -105,13 +103,13 @@ static int bq27200_voltage(struct bq27200_device_info *di)
* Note that current can be negative signed as well
* Or 0 if something fails.
*/
-static int bq27200_current(struct bq27200_device_info *di)
+static int bq27200_current(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(di, BQ27200_REG_AI);
+ ret = bq27200_read(bq, BQ27200_REG_AI);
if (ret < 0) {
- dev_err(&di->client->dev, "error reading current\n");
+ dev_err(&bq->client->dev, "error reading current\n");
return 0;
}

@@ -122,13 +120,13 @@ static int bq27200_current(struct bq27200_device_info *di)
* Return the battery Relative State-of-Charge
* Or < 0 if something fails.
*/
-static int bq27200_rsoc(struct bq27200_device_info *di)
+static int bq27200_rsoc(struct bq27200 *bq)
{
int ret;

- ret = bq27200_read(di, BQ27200_REG_RSOC);
+ ret = bq27200_read(bq, BQ27200_REG_RSOC);
if (ret < 0) {
- dev_err(&di->client->dev, "error reading relative State-of-Charge\n");
+ dev_err(&bq->client->dev, "error reading relative State-of-Charge\n");
return ret;
}

@@ -136,26 +134,28 @@ static int bq27200_rsoc(struct bq27200_device_info *di)
}

static int bq27200_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
+ enum power_supply_property psp, union power_supply_propval *val)
{
- struct bq27200_device_info *di = to_bq27200_device_info(psy);
+ struct bq27200 *bq = to_bq27200(psy);

switch (psp) {
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = bq27200_voltage(di);
+ val->intval = bq27200_voltage(bq);
+ if (val->intval < 0)
+ return val->intval;
+
if (psp == POWER_SUPPLY_PROP_PRESENT)
- val->intval = val->intval <= 0 ? 0 : 1;
+ val->intval = !!val->intval;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = bq27200_current(di);
+ val->intval = bq27200_current(bq);
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = bq27200_rsoc(di);
+ val->intval = bq27200_rsoc(bq);
break;
case POWER_SUPPLY_PROP_TEMP:
- val->intval = bq27200_temperature(di);
+ val->intval = bq27200_temperature(bq);
break;
default:
return -EINVAL;
@@ -165,30 +165,29 @@ static int bq27200_get_property(struct power_supply *psy,
}

static int bq27200_battery_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
- struct bq27200_device_info *di;
+ struct bq27200 *bq;
int retval = 0;

- di = kzalloc(sizeof(*di), GFP_KERNEL);
- if (!di) {
+ bq = kzalloc(sizeof(*bq), GFP_KERNEL);
+ if (!bq) {
dev_err(&client->dev, "failed to allocate device info data\n");
retval = -ENOMEM;
goto batt_failed_1;
}

- i2c_set_clientdata(client, di);
- di->client = client;
- di->bat.name = client->name;
- di->client = client;
+ i2c_set_clientdata(client, bq);
+ bq->client = client;
+ bq->bat.name = client->name;
+ bq->client = client;

- di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- di->bat.properties = bq27200_props;
- di->bat.num_properties = ARRAY_SIZE(bq27200_props);
- di->bat.get_property = bq27200_get_property;
- di->bat.external_power_changed = NULL;
+ bq->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ bq->bat.properties = bq27200_props;
+ bq->bat.num_properties = ARRAY_SIZE(bq27200_props);
+ bq->bat.get_property = bq27200_get_property;

- retval = power_supply_register(&client->dev, &di->bat);
+ retval = power_supply_register(&client->dev, &bq->bat);
if (retval) {
dev_err(&client->dev, "failed to register battery\n");
goto batt_failed_2;
@@ -197,7 +196,7 @@ static int bq27200_battery_probe(struct i2c_client *client,
return 0;

batt_failed_2:
- kfree(di);
+ kfree(bq);

batt_failed_1:
return retval;
@@ -205,10 +204,10 @@ batt_failed_1:

static int bq27200_battery_remove(struct i2c_client *client)
{
- struct bq27200_device_info *di = i2c_get_clientdata(client);
+ struct bq27200 *bq = i2c_get_clientdata(client);

- power_supply_unregister(&di->bat);
- kfree(di);
+ power_supply_unregister(&bq->bat);
+ kfree(bq);

return 0;
}
--
1.6.1.3

2009-07-12 18:29:48

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 12/15] power: bq27200: add power property

report power average to userland.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 658c2c5..dd1b2f2 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -54,6 +54,7 @@

#define BQ27200_SENSING_RESISTOR (20) /* 20 mOhms */
#define BQ27200_CURRENT_CONSTANT (256 * 3570 / 1000) /* 256 * 3.57 uV */
+#define BQ27200_POWER_CONSTANT (256 * 29200 / 1000) /* 256 * 29.2 uVVh */

struct bq27200 {
struct power_supply bat;
@@ -73,6 +74,7 @@ static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_POWER_AVG,
};

/*
@@ -166,6 +168,19 @@ static int bq27200_rsoc(struct bq27200 *bq)
return ret >> 8;
}

+static int bq27200_power(struct bq27200 *bq)
+{
+ int ret;
+
+ ret = bq27200_readw(bq, BQ27200_REG_AP);
+ if (ret < 0) {
+ dev_err(&bq->client->dev, "error reading average power\n");
+ return ret;
+ }
+
+ return (ret * BQ27200_POWER_CONSTANT) / BQ27200_SENSING_RESISTOR;
+}
+
static int bq27200_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val)
{
@@ -190,6 +205,8 @@ static int bq27200_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_TEMP:
val->intval = bq27200_temperature(bq);
break;
+ case POWER_SUPPLY_PROP_POWER_AVG:
+ val->intval = bq27200_power(bq);
default:
return -EINVAL;
}
--
1.6.1.3

2009-07-12 18:29:59

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 11/15] power: bq27200: temperature in tenths of degrees

temperature should be reported in tenths of degrees celsius.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index a359761..658c2c5 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -113,7 +113,7 @@ static int bq27200_temperature(struct bq27200 *bq)
return ret;
}

- return (ret >> 2) - 273;
+ return ((ret >> 2) - 273) * 10;
}

/*
--
1.6.1.3

2009-07-12 18:30:16

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 13/15] power: bq27200: RSOC is 8-bit wide

no need for shifting, just read 8-bits.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index dd1b2f2..85e824a 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -159,13 +159,13 @@ static int bq27200_rsoc(struct bq27200 *bq)
{
int ret;

- ret = bq27200_readw(bq, BQ27200_REG_RSOC);
+ ret = bq27200_readb(bq, BQ27200_REG_RSOC);
if (ret < 0) {
dev_err(&bq->client->dev, "error reading relative State-of-Charge\n");
return ret;
}

- return ret >> 8;
+ return ret;
}

static int bq27200_power(struct bq27200 *bq)
--
1.6.1.3

2009-07-12 18:30:36

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 15/15] power: bq27200: add energy average

report energy average to userland.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 26ef2be..2fbe7a4 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -77,6 +77,7 @@ static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ POWER_SUPPLY_PROP_ENERGY_AVG,
};

/*
@@ -183,6 +184,19 @@ static int bq27200_power(struct bq27200 *bq)
return (ret * BQ27200_POWER_CONSTANT) / BQ27200_SENSING_RESISTOR;
}

+static int bq27200_energy(struct bq27200 *bq)
+{
+ int ret;
+
+ ret = bq27200_readw(bq, BQ27200_REG_SAE);
+ if (ret < 0) {
+ dev_err(&bq->client->dev, "error reading average energy\n");
+ return ret;
+ }
+
+ return (ret * BQ27200_POWER_CONSTANT) / BQ27200_SENSING_RESISTOR;
+}
+
static int bq27200_time_to_empty(struct bq27200 *bq)
{
int ret;
@@ -242,6 +256,9 @@ static int bq27200_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
val->intval = bq27200_time_to_full(bq);
break;
+ case POWER_SUPPLY_PROP_ENERGY_AVG:
+ val->intval = bq27200_energy(bq);
+ break;
default:
return -EINVAL;
}
--
1.6.1.3

2009-07-12 18:30:50

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 04/15] power: bq27200: simplify read by using smbus

the chip supports smbus protocol, so let's use it and simply
register read/write.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 135 ++++++++-------------------------------
1 files changed, 28 insertions(+), 107 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 3eb0f5a..eddb731 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -32,22 +32,14 @@
#define BQ27200_REG_AI 0x14
#define BQ27200_REG_FLAGS 0x0A

-struct bq27200_device_info;
-struct bq27200_access_methods {
- int (*read)(u8 reg, int *rt_value, int b_single,
- struct bq27200_device_info *di);
-};
-
struct bq27200_device_info {
- struct device *dev;
+ struct power_supply bat;
+ struct i2c_client *client;
+
+ int charge_rsoc;
int voltage_uV;
int current_uA;
int temp_C;
- int charge_rsoc;
- struct bq27200_access_methods *bus;
- struct power_supply bat;
-
- struct i2c_client *client;
};

#define to_bq27200_device_info(x) container_of((x), \
@@ -65,15 +57,15 @@ static enum power_supply_property bq27200_props[] = {
* Common code for BQ27200 devices
*/

-static int bq27200_read(u8 reg, int *rt_value, int b_single,
- struct bq27200_device_info *di)
+static inline int bq27200_read(struct bq27200_device_info *di, u8 reg)
{
- int ret;
-
- ret = di->bus->read(reg, rt_value, b_single, di);
- *rt_value = be16_to_cpu(*rt_value);
+ return i2c_smbus_read_word_data(di->client, reg);
+}

- return ret;
+static inline int bq27200_write(struct bq27200_device_info *di,
+ u8 reg, u8 data)
+{
+ return i2c_smbus_write_word_data(di->client, reg, data);
}

/*
@@ -83,15 +75,14 @@ static int bq27200_read(u8 reg, int *rt_value, int b_single,
static int bq27200_temperature(struct bq27200_device_info *di)
{
int ret;
- int temp = 0;

- ret = bq27200_read(BQ27200_REG_TEMP, &temp, 0, di);
- if (ret) {
- dev_err(di->dev, "error reading temperature\n");
+ ret = bq27200_read(di, BQ27200_REG_TEMP);
+ if (ret < 0) {
+ dev_err(&di->client->dev, "error reading temperature\n");
return ret;
}

- return (temp >> 2) - 273;
+ return (ret >> 2) - 273;
}

/*
@@ -101,15 +92,12 @@ static int bq27200_temperature(struct bq27200_device_info *di)
static int bq27200_voltage(struct bq27200_device_info *di)
{
int ret;
- int volt = 0;

- ret = bq27200_read(BQ27200_REG_VOLT, &volt, 0, di);
- if (ret) {
- dev_err(di->dev, "error reading voltage\n");
- return ret;
- }
+ ret = bq27200_read(di, BQ27200_REG_VOLT);
+ if (ret < 0)
+ dev_err(&di->client->dev, "error reading voltage\n");

- return volt;
+ return ret;
}

/*
@@ -120,25 +108,14 @@ static int bq27200_voltage(struct bq27200_device_info *di)
static int bq27200_current(struct bq27200_device_info *di)
{
int ret;
- int curr = 0;
- int flags = 0;

- ret = bq27200_read(BQ27200_REG_AI, &curr, 0, di);
- if (ret) {
- dev_err(di->dev, "error reading current\n");
- return 0;
- }
- ret = bq27200_read(BQ27200_REG_FLAGS, &flags, 0, di);
+ ret = bq27200_read(di, BQ27200_REG_AI);
if (ret < 0) {
- dev_err(di->dev, "error reading flags\n");
+ dev_err(&di->client->dev, "error reading current\n");
return 0;
}
- if ((flags & (1 << 7)) != 0) {
- dev_dbg(di->dev, "negative current!\n");
- return -curr;
- }

- return curr;
+ return ret;
}

/*
@@ -148,15 +125,14 @@ static int bq27200_current(struct bq27200_device_info *di)
static int bq27200_rsoc(struct bq27200_device_info *di)
{
int ret;
- int rsoc = 0;

- ret = bq27200_read(BQ27200_REG_RSOC, &rsoc, 1, di);
- if (ret) {
- dev_err(di->dev, "error reading relative State-of-Charge\n");
+ ret = bq27200_read(di, BQ27200_REG_RSOC);
+ if (ret < 0) {
+ dev_err(&di->client->dev, "error reading relative State-of-Charge\n");
return ret;
}

- return rsoc >> 8;
+ return ret >> 8;
}

static int bq27200_get_property(struct power_supply *psy,
@@ -197,51 +173,10 @@ static void bq27200_powersupply_init(struct bq27200_device_info *di)
di->bat.external_power_changed = NULL;
}

-static int _bq27200_read(u8 reg, int *rt_value, int b_single,
- struct bq27200_device_info *di)
-{
- struct i2c_client *client = di->client;
- struct i2c_msg msg[1];
- unsigned char data[2];
- int err;
-
- if (!client->adapter)
- return -ENODEV;
-
- msg->addr = client->addr;
- msg->flags = 0;
- msg->len = 1;
- msg->buf = data;
-
- data[0] = reg;
- err = i2c_transfer(client->adapter, msg, 1);
-
- if (err >= 0) {
- if (!b_single)
- msg->len = 2;
- else
- msg->len = 1;
-
- msg->flags = I2C_M_RD;
- err = i2c_transfer(client->adapter, msg, 1);
- if (err >= 0) {
- if (!b_single)
- *rt_value = get_unaligned_be16(data);
- else
- *rt_value = data[0];
-
- return 0;
- }
- }
-
- return err;
-}
-
static int bq27200_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bq27200_device_info *di;
- struct bq27200_access_methods *bus;
int retval = 0;

di = kzalloc(sizeof(*di), GFP_KERNEL);
@@ -251,19 +186,9 @@ static int bq27200_battery_probe(struct i2c_client *client,
goto batt_failed_1;
}

- bus = kzalloc(sizeof(*bus), GFP_KERNEL);
- if (!bus) {
- dev_err(&client->dev, "failed to allocate access method "
- "data\n");
- retval = -ENOMEM;
- goto batt_failed_2;
- }
-
i2c_set_clientdata(client, di);
- di->dev = &client->dev;
+ di->client = client;
di->bat.name = client->name;
- bus->read = _bq27200_read;
- di->bus = bus;
di->client = client;

bq27200_powersupply_init(di);
@@ -271,14 +196,11 @@ static int bq27200_battery_probe(struct i2c_client *client,
retval = power_supply_register(&client->dev, &di->bat);
if (retval) {
dev_err(&client->dev, "failed to register battery\n");
- goto batt_failed_3;
+ goto batt_failed_2;
}

return 0;

-batt_failed_3:
- kfree(bus);
-
batt_failed_2:
kfree(di);

@@ -291,7 +213,6 @@ static int bq27200_battery_remove(struct i2c_client *client)
struct bq27200_device_info *di = i2c_get_clientdata(client);

power_supply_unregister(&di->bat);
- kfree(di->bat.name);
kfree(di);

return 0;
--
1.6.1.3

2009-07-12 18:31:03

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 05/15] power: bq27200: remove unnecessary function

that init function was completely unnecessary.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 15 +++++----------
1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index eddb731..deef1b5 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -164,15 +164,6 @@ static int bq27200_get_property(struct power_supply *psy,
return 0;
}

-static void bq27200_powersupply_init(struct bq27200_device_info *di)
-{
- di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- di->bat.properties = bq27200_props;
- di->bat.num_properties = ARRAY_SIZE(bq27200_props);
- di->bat.get_property = bq27200_get_property;
- di->bat.external_power_changed = NULL;
-}
-
static int bq27200_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -191,7 +182,11 @@ static int bq27200_battery_probe(struct i2c_client *client,
di->bat.name = client->name;
di->client = client;

- bq27200_powersupply_init(di);
+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ di->bat.properties = bq27200_props;
+ di->bat.num_properties = ARRAY_SIZE(bq27200_props);
+ di->bat.get_property = bq27200_get_property;
+ di->bat.external_power_changed = NULL;

retval = power_supply_register(&client->dev, &di->bat);
if (retval) {
--
1.6.1.3

2009-07-12 18:31:23

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 10/15] power: bq27200: voltage should be expressed in uV

... and not mV as the chip reports.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 869761e..a359761 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -128,7 +128,7 @@ static int bq27200_voltage(struct bq27200 *bq)
if (ret < 0)
dev_err(&bq->client->dev, "error reading voltage\n");

- return ret;
+ return ret * 1000;
}

/*
--
1.6.1.3

2009-07-12 18:31:35

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 09/15] power: bq27200: fix up current reporting

according to bq27200 datasheet, avarage current is calculated
with the following equation:

current = (256 * AI) * 3.57 / Rs

where Rs = 20mOhms

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index f36633c..869761e 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -52,6 +52,9 @@
#define BQ27200_REG_CYCT 0x2a /* cycle-count total */
#define BQ27200_REG_CSOC 0x2c /* compensated state-of-charge */

+#define BQ27200_SENSING_RESISTOR (20) /* 20 mOhms */
+#define BQ27200_CURRENT_CONSTANT (256 * 3570 / 1000) /* 256 * 3.57 uV */
+
struct bq27200 {
struct power_supply bat;
struct i2c_client *client;
@@ -143,7 +146,7 @@ static int bq27200_current(struct bq27200 *bq)
return 0;
}

- return ret;
+ return (ret * BQ27200_CURRENT_CONSTANT) / BQ27200_SENSING_RESISTOR;
}

/*
--
1.6.1.3

2009-07-12 18:31:47

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 14/15] power: bq27200: add time to empty/full

the chip reports time to empty and time to full
in minutes, so we multiply the result by 60 to get
it in seconds as requested by power_supply interface.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 85e824a..26ef2be 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -75,6 +75,8 @@ static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_POWER_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
};

/*
@@ -181,6 +183,32 @@ static int bq27200_power(struct bq27200 *bq)
return (ret * BQ27200_POWER_CONSTANT) / BQ27200_SENSING_RESISTOR;
}

+static int bq27200_time_to_empty(struct bq27200 *bq)
+{
+ int ret;
+
+ ret = bq27200_readw(bq, BQ27200_REG_TTE);
+ if (ret < 0) {
+ dev_err(&bq->client->dev, "error reading time to empty\n");
+ return ret;
+ }
+
+ return ret * 60;
+}
+
+static int bq27200_time_to_full(struct bq27200 *bq)
+{
+ int ret;
+
+ ret = bq27200_readw(bq, BQ27200_REG_TTF);
+ if (ret < 0) {
+ dev_err(&bq->client->dev, "error reading time to full\n");
+ return ret;
+ }
+
+ return ret * 60;
+}
+
static int bq27200_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val)
{
@@ -207,6 +235,13 @@ static int bq27200_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_POWER_AVG:
val->intval = bq27200_power(bq);
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ val->intval = bq27200_time_to_empty(bq);
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ val->intval = bq27200_time_to_full(bq);
+ break;
default:
return -EINVAL;
}
--
1.6.1.3

2009-07-12 18:31:59

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 03/15] power: bq27200: misc cleanup

whitespaces, tabs, unnecessary prints... the usual.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 40 ++++++++++++--------------------------
1 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index 1978cd9..3eb0f5a 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -39,7 +39,7 @@ struct bq27200_access_methods {
};

struct bq27200_device_info {
- struct device *dev;
+ struct device *dev;
int voltage_uV;
int current_uA;
int temp_C;
@@ -50,6 +50,9 @@ struct bq27200_device_info {
struct i2c_client *client;
};

+#define to_bq27200_device_info(x) container_of((x), \
+ struct bq27200_device_info, bat);
+
static enum power_supply_property bq27200_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -134,6 +137,7 @@ static int bq27200_current(struct bq27200_device_info *di)
dev_dbg(di->dev, "negative current!\n");
return -curr;
}
+
return curr;
}

@@ -155,9 +159,6 @@ static int bq27200_rsoc(struct bq27200_device_info *di)
return rsoc >> 8;
}

-#define to_bq27200_device_info(x) container_of((x), \
- struct bq27200_device_info, bat);
-
static int bq27200_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -196,10 +197,6 @@ static void bq27200_powersupply_init(struct bq27200_device_info *di)
di->bat.external_power_changed = NULL;
}

-/*
- * BQ27200 specific code
- */
-
static int _bq27200_read(u8 reg, int *rt_value, int b_single,
struct bq27200_device_info *di)
{
@@ -236,6 +233,7 @@ static int _bq27200_read(u8 reg, int *rt_value, int b_single,
return 0;
}
}
+
return err;
}

@@ -264,7 +262,7 @@ static int bq27200_battery_probe(struct i2c_client *client,
i2c_set_clientdata(client, di);
di->dev = &client->dev;
di->bat.name = client->name;
- bus->read = &_bq27200_read;
+ bus->read = _bq27200_read;
di->bus = bus;
di->client = client;

@@ -276,8 +274,6 @@ static int bq27200_battery_probe(struct i2c_client *client,
goto batt_failed_3;
}

- dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
-
return 0;

batt_failed_3:
@@ -301,33 +297,23 @@ static int bq27200_battery_remove(struct i2c_client *client)
return 0;
}

-/*
- * Module stuff
- */
-
static const struct i2c_device_id bq27200_id[] = {
{ "bq27200", 0 },
{},
};

static struct i2c_driver bq27200_battery_driver = {
- .driver = {
- .name = "bq27200",
+ .driver = {
+ .name = "bq27200",
},
- .probe = bq27200_battery_probe,
- .remove = bq27200_battery_remove,
- .id_table = bq27200_id,
+ .probe = bq27200_battery_probe,
+ .remove = bq27200_battery_remove,
+ .id_table = bq27200_id,
};

static int __init bq27200_init(void)
{
- int ret;
-
- ret = i2c_add_driver(&bq27200_battery_driver);
- if (ret)
- printk(KERN_ERR "Unable to register BQ27200 driver\n");
-
- return ret;
+ return i2c_add_driver(&bq27200_battery_driver);
}
module_init(bq27200_init);

--
1.6.1.3

2009-07-12 18:32:20

by Felipe Balbi

[permalink] [raw]
Subject: [rfc/patch 02/15] power: bq27200: this is an i2c device

... with hardcoded device address so i2c subsystem won't
talk to more than one of those.

Signed-off-by: Felipe Balbi <[email protected]>
---
drivers/power/bq27200_battery.c | 55 +++++---------------------------------
1 files changed, 8 insertions(+), 47 deletions(-)

diff --git a/drivers/power/bq27200_battery.c b/drivers/power/bq27200_battery.c
index f31f167..1978cd9 100644
--- a/drivers/power/bq27200_battery.c
+++ b/drivers/power/bq27200_battery.c
@@ -22,9 +22,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
-#include <linux/idr.h>
#include <linux/i2c.h>
-#include <asm/unaligned.h>

#define DRIVER_VERSION "1.0.0"

@@ -34,12 +32,6 @@
#define BQ27200_REG_AI 0x14
#define BQ27200_REG_FLAGS 0x0A

-/* If the system has several batteries we need a different name for each
- * of them...
- */
-static DEFINE_IDR(battery_id);
-static DEFINE_MUTEX(battery_mutex);
-
struct bq27200_device_info;
struct bq27200_access_methods {
int (*read)(u8 reg, int *rt_value, int b_single,
@@ -48,7 +40,6 @@ struct bq27200_access_methods {

struct bq27200_device_info {
struct device *dev;
- int id;
int voltage_uV;
int current_uA;
int temp_C;
@@ -251,48 +242,28 @@ static int _bq27200_read(u8 reg, int *rt_value, int b_single,
static int bq27200_battery_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- char *name;
struct bq27200_device_info *di;
struct bq27200_access_methods *bus;
- int num;
int retval = 0;

- /* Get new ID for the new battery device */
- retval = idr_pre_get(&battery_id, GFP_KERNEL);
- if (retval == 0)
- return -ENOMEM;
- mutex_lock(&battery_mutex);
- retval = idr_get_new(&battery_id, client, &num);
- mutex_unlock(&battery_mutex);
- if (retval < 0)
- return retval;
-
- name = kasprintf(GFP_KERNEL, "bq27200-%d", num);
- if (!name) {
- dev_err(&client->dev, "failed to allocate device name\n");
- retval = -ENOMEM;
- goto batt_failed_1;
- }
-
di = kzalloc(sizeof(*di), GFP_KERNEL);
if (!di) {
dev_err(&client->dev, "failed to allocate device info data\n");
retval = -ENOMEM;
- goto batt_failed_2;
+ goto batt_failed_1;
}
- di->id = num;

bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (!bus) {
dev_err(&client->dev, "failed to allocate access method "
"data\n");
retval = -ENOMEM;
- goto batt_failed_3;
+ goto batt_failed_2;
}

i2c_set_clientdata(client, di);
di->dev = &client->dev;
- di->bat.name = name;
+ di->bat.name = client->name;
bus->read = &_bq27200_read;
di->bus = bus;
di->client = client;
@@ -302,24 +273,20 @@ static int bq27200_battery_probe(struct i2c_client *client,
retval = power_supply_register(&client->dev, &di->bat);
if (retval) {
dev_err(&client->dev, "failed to register battery\n");
- goto batt_failed_4;
+ goto batt_failed_3;
}

dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);

return 0;

-batt_failed_4:
- kfree(bus);
batt_failed_3:
- kfree(di);
+ kfree(bus);
+
batt_failed_2:
- kfree(name);
-batt_failed_1:
- mutex_lock(&battery_mutex);
- idr_remove(&battery_id, num);
- mutex_unlock(&battery_mutex);
+ kfree(di);

+batt_failed_1:
return retval;
}

@@ -328,13 +295,7 @@ static int bq27200_battery_remove(struct i2c_client *client)
struct bq27200_device_info *di = i2c_get_clientdata(client);

power_supply_unregister(&di->bat);
-
kfree(di->bat.name);
-
- mutex_lock(&battery_mutex);
- idr_remove(&battery_id, di->id);
- mutex_unlock(&battery_mutex);
-
kfree(di);

return 0;
--
1.6.1.3

2009-07-12 18:48:10

by Linus Walleij

[permalink] [raw]
Subject: Re: [rfc/patch 02/15] power: bq27200: this is an i2c device

2009/7/12 Felipe Balbi <[email protected]>:

> ... with hardcoded device address so i2c subsystem won't
> talk to more than one of those.

So you remove support for multiple instances of this driver, OK.

But theoretically, what happens if you have two different I2C busses
on your system with a battery driver on each?

Can you confirm that that will never happen?

Linus Walleij

2009-07-12 19:50:19

by Felipe Balbi

[permalink] [raw]
Subject: Re: [rfc/patch 02/15] power: bq27200: this is an i2c device

On Sun, Jul 12, 2009 at 08:47:53PM +0200, ext Linus Walleij wrote:
> 2009/7/12 Felipe Balbi <[email protected]>:
>
> > ... with hardcoded device address so i2c subsystem won't
> > talk to more than one of those.
>
> So you remove support for multiple instances of this driver, OK.
>
> But theoretically, what happens if you have two different I2C busses
> on your system with a battery driver on each?
>
> Can you confirm that that will never happen?

If they are on different buses, there shouldn't be any problems.
Unfortunately I don't have a hw suitable for this kind of test.

Let's hear from Ben Dooks on this.

--
balbi

2009-07-12 20:11:59

by Felipe Balbi

[permalink] [raw]
Subject: Re: [rfc/patch 12/15] power: bq27200: add power property

Hi,

On Sun, Jul 12, 2009 at 09:09:34PM +0300, Felipe Balbi wrote:
> @@ -190,6 +205,8 @@ static int bq27200_get_property(struct power_supply *psy,
> case POWER_SUPPLY_PROP_TEMP:
> val->intval = bq27200_temperature(bq);
> break;
> + case POWER_SUPPLY_PROP_POWER_AVG:
> + val->intval = bq27200_power(bq);

missing break here. Updated patch attached.

--
balbi


Attachments:
(No filename) (368.00 B)
0012-power-bq27200-add-power-property.diff (1.82 kB)
Download all attachments

2009-07-12 20:13:13

by Felipe Balbi

[permalink] [raw]
Subject: Re: [rfc/patch 14/15] power: bq27200: add time to empty/full

Hi,

On Sun, Jul 12, 2009 at 09:09:36PM +0300, Felipe Balbi wrote:
> @@ -207,6 +235,13 @@ static int bq27200_get_property(struct power_supply *psy,
> break;
> case POWER_SUPPLY_PROP_POWER_AVG:
> val->intval = bq27200_power(bq);
> + break;

this break doesn't belong here. Updated patch attached.

--
balbi


Attachments:
(No filename) (316.00 B)
0014-power-bq27200-add-time-to-empty-full.diff (2.09 kB)
Download all attachments