aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGrazvydas Ignotas <notasas@gmail.com>2010-02-12 16:57:23 -0500
committerAnton Vorontsov <cbouatmailru@gmail.com>2010-02-16 13:26:52 -0500
commite20908d95e89d04b9537aefecc0734d2e4f7faed (patch)
tree77edc6d7755ab0b0abf611dc9f3068ad66b2a6a5 /drivers
parentb4de3608156311b615da4bcc4c095913abc44825 (diff)
power_supply: bq27x00: add BQ27500 support
BQ27500 is newer fuel gauge chip from TI with slightly changed register layout and some different register semantics. Add new i2c ID for it and handle differences where needed. Also rename bq27200 functions to bq27x00, as they are no longer bq27200 specific. Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> Acked-by: Rodolfo Giometti <giometti@linux.it> Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/Kconfig4
-rw-r--r--drivers/power/bq27x00_battery.c77
2 files changed, 51 insertions, 30 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index d4b3d67f0548..bf1467213954 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -98,10 +98,10 @@ config BATTERY_WM97XX
98 Say Y to enable support for battery measured by WM97xx aux port. 98 Say Y to enable support for battery measured by WM97xx aux port.
99 99
100config BATTERY_BQ27x00 100config BATTERY_BQ27x00
101 tristate "BQ27200 battery driver" 101 tristate "BQ27x00 battery driver"
102 depends on I2C 102 depends on I2C
103 help 103 help
104 Say Y here to enable support for batteries with BQ27200(I2C) chip. 104 Say Y here to enable support for batteries with BQ27x00 (I2C) chips.
105 105
106config BATTERY_DA9030 106config BATTERY_DA9030
107 tristate "DA9030 battery driver" 107 tristate "DA9030 battery driver"
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 3da9e0aa705a..1526d020cbc6 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -26,14 +26,17 @@
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <asm/unaligned.h> 27#include <asm/unaligned.h>
28 28
29#define DRIVER_VERSION "1.0.0" 29#define DRIVER_VERSION "1.1.0"
30 30
31#define BQ27x00_REG_TEMP 0x06 31#define BQ27x00_REG_TEMP 0x06
32#define BQ27x00_REG_VOLT 0x08 32#define BQ27x00_REG_VOLT 0x08
33#define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */
34#define BQ27x00_REG_AI 0x14 33#define BQ27x00_REG_AI 0x14
35#define BQ27x00_REG_FLAGS 0x0A 34#define BQ27x00_REG_FLAGS 0x0A
36 35
36#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
37
38#define BQ27500_REG_SOC 0x2c
39
37/* If the system has several batteries we need a different name for each 40/* If the system has several batteries we need a different name for each
38 * of them... 41 * of them...
39 */ 42 */
@@ -46,11 +49,14 @@ struct bq27x00_access_methods {
46 struct bq27x00_device_info *di); 49 struct bq27x00_device_info *di);
47}; 50};
48 51
52enum bq27x00_chip { BQ27000, BQ27500 };
53
49struct bq27x00_device_info { 54struct bq27x00_device_info {
50 struct device *dev; 55 struct device *dev;
51 int id; 56 int id;
52 struct bq27x00_access_methods *bus; 57 struct bq27x00_access_methods *bus;
53 struct power_supply bat; 58 struct power_supply bat;
59 enum bq27x00_chip chip;
54 60
55 struct i2c_client *client; 61 struct i2c_client *client;
56}; 62};
@@ -88,7 +94,10 @@ static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
88 return ret; 94 return ret;
89 } 95 }
90 96
91 return ((temp >> 2) - 273) * 10; 97 if (di->chip == BQ27500)
98 return temp - 2731;
99 else
100 return ((temp >> 2) - 273) * 10;
92} 101}
93 102
94/* 103/*
@@ -125,15 +134,22 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di)
125 dev_err(di->dev, "error reading current\n"); 134 dev_err(di->dev, "error reading current\n");
126 return 0; 135 return 0;
127 } 136 }
128 ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di); 137
129 if (ret < 0) { 138 if (di->chip == BQ27500) {
130 dev_err(di->dev, "error reading flags\n"); 139 /* bq27500 returns signed value */
131 return 0; 140 curr = (int)(s16)curr;
132 } 141 } else {
133 if ((flags & (1 << 7)) != 0) { 142 ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
134 dev_dbg(di->dev, "negative current!\n"); 143 if (ret < 0) {
135 return -curr; 144 dev_err(di->dev, "error reading flags\n");
145 return 0;
146 }
147 if ((flags & (1 << 7)) != 0) {
148 dev_dbg(di->dev, "negative current!\n");
149 return -curr;
150 }
136 } 151 }
152
137 return curr; 153 return curr;
138} 154}
139 155
@@ -146,7 +162,10 @@ static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
146 int ret; 162 int ret;
147 int rsoc = 0; 163 int rsoc = 0;
148 164
149 ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di); 165 if (di->chip == BQ27500)
166 ret = bq27x00_read(BQ27500_REG_SOC, &rsoc, 0, di);
167 else
168 ret = bq27x00_read(BQ27000_REG_RSOC, &rsoc, 1, di);
150 if (ret) { 169 if (ret) {
151 dev_err(di->dev, "error reading relative State-of-Charge\n"); 170 dev_err(di->dev, "error reading relative State-of-Charge\n");
152 return ret; 171 return ret;
@@ -197,10 +216,10 @@ static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
197} 216}
198 217
199/* 218/*
200 * BQ27200 specific code 219 * i2c specific code
201 */ 220 */
202 221
203static int bq27200_read(u8 reg, int *rt_value, int b_single, 222static int bq27x00_read_i2c(u8 reg, int *rt_value, int b_single,
204 struct bq27x00_device_info *di) 223 struct bq27x00_device_info *di)
205{ 224{
206 struct i2c_client *client = di->client; 225 struct i2c_client *client = di->client;
@@ -239,7 +258,7 @@ static int bq27200_read(u8 reg, int *rt_value, int b_single,
239 return err; 258 return err;
240} 259}
241 260
242static int bq27200_battery_probe(struct i2c_client *client, 261static int bq27x00_battery_probe(struct i2c_client *client,
243 const struct i2c_device_id *id) 262 const struct i2c_device_id *id)
244{ 263{
245 char *name; 264 char *name;
@@ -258,7 +277,7 @@ static int bq27200_battery_probe(struct i2c_client *client,
258 if (retval < 0) 277 if (retval < 0)
259 return retval; 278 return retval;
260 279
261 name = kasprintf(GFP_KERNEL, "bq27200-%d", num); 280 name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
262 if (!name) { 281 if (!name) {
263 dev_err(&client->dev, "failed to allocate device name\n"); 282 dev_err(&client->dev, "failed to allocate device name\n");
264 retval = -ENOMEM; 283 retval = -ENOMEM;
@@ -272,6 +291,7 @@ static int bq27200_battery_probe(struct i2c_client *client,
272 goto batt_failed_2; 291 goto batt_failed_2;
273 } 292 }
274 di->id = num; 293 di->id = num;
294 di->chip = id->driver_data;
275 295
276 bus = kzalloc(sizeof(*bus), GFP_KERNEL); 296 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
277 if (!bus) { 297 if (!bus) {
@@ -284,7 +304,7 @@ static int bq27200_battery_probe(struct i2c_client *client,
284 i2c_set_clientdata(client, di); 304 i2c_set_clientdata(client, di);
285 di->dev = &client->dev; 305 di->dev = &client->dev;
286 di->bat.name = name; 306 di->bat.name = name;
287 bus->read = &bq27200_read; 307 bus->read = &bq27x00_read_i2c;
288 di->bus = bus; 308 di->bus = bus;
289 di->client = client; 309 di->client = client;
290 310
@@ -314,7 +334,7 @@ batt_failed_1:
314 return retval; 334 return retval;
315} 335}
316 336
317static int bq27200_battery_remove(struct i2c_client *client) 337static int bq27x00_battery_remove(struct i2c_client *client)
318{ 338{
319 struct bq27x00_device_info *di = i2c_get_clientdata(client); 339 struct bq27x00_device_info *di = i2c_get_clientdata(client);
320 340
@@ -335,27 +355,28 @@ static int bq27200_battery_remove(struct i2c_client *client)
335 * Module stuff 355 * Module stuff
336 */ 356 */
337 357
338static const struct i2c_device_id bq27200_id[] = { 358static const struct i2c_device_id bq27x00_id[] = {
339 { "bq27200", 0 }, 359 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */
360 { "bq27500", BQ27500 },
340 {}, 361 {},
341}; 362};
342 363
343static struct i2c_driver bq27200_battery_driver = { 364static struct i2c_driver bq27x00_battery_driver = {
344 .driver = { 365 .driver = {
345 .name = "bq27200-battery", 366 .name = "bq27x00-battery",
346 }, 367 },
347 .probe = bq27200_battery_probe, 368 .probe = bq27x00_battery_probe,
348 .remove = bq27200_battery_remove, 369 .remove = bq27x00_battery_remove,
349 .id_table = bq27200_id, 370 .id_table = bq27x00_id,
350}; 371};
351 372
352static int __init bq27x00_battery_init(void) 373static int __init bq27x00_battery_init(void)
353{ 374{
354 int ret; 375 int ret;
355 376
356 ret = i2c_add_driver(&bq27200_battery_driver); 377 ret = i2c_add_driver(&bq27x00_battery_driver);
357 if (ret) 378 if (ret)
358 printk(KERN_ERR "Unable to register BQ27200 driver\n"); 379 printk(KERN_ERR "Unable to register BQ27x00 driver\n");
359 380
360 return ret; 381 return ret;
361} 382}
@@ -363,7 +384,7 @@ module_init(bq27x00_battery_init);
363 384
364static void __exit bq27x00_battery_exit(void) 385static void __exit bq27x00_battery_exit(void)
365{ 386{
366 i2c_del_driver(&bq27200_battery_driver); 387 i2c_del_driver(&bq27x00_battery_driver);
367} 388}
368module_exit(bq27x00_battery_exit); 389module_exit(bq27x00_battery_exit);
369 390