]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/power/bq27x00_battery.c
Merge current mainline tree into linux-omap tree
[linux-2.6-omap-h63xx.git] / drivers / power / bq27x00_battery.c
1 /*
2  * linux/drivers/power/bq27x00_battery.c
3  *
4  * BQ27000/BQ27200 battery driver
5  *
6  * Copyright (C) 2008 Texas Instruments, Inc.
7  *
8  * Author: Texas Instruments
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  */
19 #include <linux/module.h>
20 #include <linux/param.h>
21 #include <linux/jiffies.h>
22 #include <linux/workqueue.h>
23 #include <linux/delay.h>
24 #include <linux/platform_device.h>
25 #include <linux/power_supply.h>
26
27 #ifdef CONFIG_BATTERY_BQ27000
28 #include "../w1/w1.h"
29 #endif
30 #ifdef CONFIG_BATTERY_BQ27200
31 #include <linux/i2c.h>
32 #endif
33
34 #define BQ27x00_REG_TEMP                0x06
35 #define BQ27x00_REG_VOLT                0x08
36 #define BQ27x00_REG_RSOC                0x0B /* Relative State-of-Charge */
37 #define BQ27x00_REG_AI                  0x14
38 #define BQ27x00_REG_FLAGS               0x0A
39 #define HIGH_BYTE(A)                    ((A) << 8)
40
41 #ifdef CONFIG_BATTERY_BQ27000
42 extern int w1_bq27000_read(struct device *dev, u8 reg);
43 #endif
44
45 struct bq27x00_device_info;
46 struct bq27x00_access_methods {
47         int (*read)(u8 reg, int *rt_value, int b_single,
48                 struct bq27x00_device_info *di);
49 };
50
51 struct bq27x00_device_info {
52         struct device           *dev;
53 #ifdef CONFIG_BATTERY_BQ27000
54         struct device           *w1_dev;
55 #endif
56 #ifdef CONFIG_BATTERY_BQ27200
57         struct i2c_client *client;
58 #endif
59         unsigned long           update_time;
60         int                     voltage_uV;
61         int                     current_uA;
62         int                     temp_C;
63         int                     charge_rsoc;
64         struct bq27x00_access_methods   *bus;
65         struct power_supply     bat;
66         struct delayed_work     monitor_work;
67 };
68
69 static unsigned int cache_time = 60000;
70 module_param(cache_time, uint, 0644);
71 MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
72
73 static enum power_supply_property bq27x00_battery_props[] = {
74         POWER_SUPPLY_PROP_PRESENT,
75         POWER_SUPPLY_PROP_VOLTAGE_NOW,
76         POWER_SUPPLY_PROP_CURRENT_NOW,
77         POWER_SUPPLY_PROP_CHARGE_NOW,
78         POWER_SUPPLY_PROP_CAPACITY,
79         POWER_SUPPLY_PROP_TEMP,
80 };
81
82 static int bq27x00_read(u8 reg, int *rt_value, int b_single,
83         struct bq27x00_device_info *di);
84
85 #ifdef CONFIG_BATTERY_BQ27000
86 static int bq27000_battery_probe(struct platform_device *dev);
87 static int bq27000_battery_remove(struct platform_device *dev);
88 #ifdef CONFIG_PM
89 static int bq27000_battery_suspend(struct platform_device *dev,
90         pm_message_t state);
91 static int bq27000_battery_resume(struct platform_device *dev);
92 #endif /* CONFIG_PM */
93
94 static struct platform_driver bq27000_battery_driver = {
95         .probe = bq27000_battery_probe,
96         .remove = bq27000_battery_remove,
97 #ifdef CONFIG_PM
98         .suspend = bq27000_battery_suspend,
99         .resume = bq27000_battery_resume,
100 #endif /* CONFIG_PM */
101         .driver = {
102                 .name = "bq27000-battery",
103         },
104 };
105 #endif /* CONFIG_BATTERY_BQ27000 */
106
107 #ifdef CONFIG_BATTERY_BQ27200
108 static int bq27200_battery_probe(struct i2c_client *client);
109 static int bq27200_battery_remove(struct i2c_client *client);
110 #ifdef CONFIG_PM
111 static int bq27200_battery_suspend(struct i2c_client *client,
112                 pm_message_t mesg);
113 static int bq27200_battery_resume(struct i2c_client *client);
114 #endif /* CONFIG_PM */
115 static struct i2c_driver bq27200_battery_driver = {
116         .driver = {
117                 .name   = "bq27200-bat",
118         },
119         .probe  = bq27200_battery_probe,
120         .remove = bq27200_battery_remove,
121 #ifdef CONFIG_PM
122         .suspend = bq27200_battery_suspend,
123         .resume = bq27200_battery_resume,
124 #endif /* CONFIG_PM */
125 };
126 #endif /* CONFIG_BATTERY_BQ27200 */
127
128 /*
129  * Return the battery temperature in Celcius degrees
130  * Or < 0 if something fails.
131  */
132 static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
133 {
134         int ret, temp = 0;
135
136         ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di);
137         if (ret) {
138                 pr_err("BQ27x00 battery driver:"
139                         "Error reading temperature from the battery\n");
140                 return ret;
141         }
142
143         return (temp >> 2) - 273;
144 }
145
146 /*
147  * Return the battery Voltage in milivolts
148  * Or < 0 if something fails.
149  */
150 static int bq27x00_battery_voltage(struct bq27x00_device_info *di)
151 {
152         int ret, volt = 0;
153
154         ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di);
155         if (ret) {
156                 pr_err("BQ27x00 battery driver:"
157                         "Error reading battery voltage from the battery\n");
158                 return ret;
159         }
160
161         return volt;
162 }
163
164 /*
165  * Return the battery average current
166  * Note that current can be negative signed as well
167  * Or 0 if something fails.
168  */
169 static int bq27x00_battery_current(struct bq27x00_device_info *di)
170 {
171         int ret, curr = 0, flags = 0;
172
173         ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di);
174         if (ret) {
175                 pr_err("BQ27x00 battery driver:"
176                         "Error reading current from the battery\n");
177                 return 0;
178         }
179         ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
180         if (ret < 0) {
181                 pr_err("BQ27x00 battery driver:"
182                         "Error reading battery flags\n");
183                 return 0;
184         }
185         if ((flags & (1 << 7)) != 0) {
186                 pr_debug("Negative current\n");
187                 return -curr;
188         } else {
189                 return curr;
190         }
191 }
192
193 /*
194  * Return the battery Relative State-of-Charge
195  * Or < 0 if something fails.
196  */
197 static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
198 {
199         int ret, rsoc = 0;
200
201         ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di);
202         if (ret) {
203                 pr_err("BQ27x00 battery driver:"
204                         "Error reading battery Relative"
205                         "State-of-Charge\n");
206                 return ret;
207         }
208         return rsoc;
209 }
210
211 #ifdef CONFIG_BATTERY_BQ27000
212 static inline int bq27000_read(u8 reg, int *rt_value, int b_single,
213         struct bq27x00_device_info *di)
214 {
215         u8 val;
216
217         val = w1_bq27000_read(di->w1_dev, reg);
218         *rt_value = val;
219
220         if (!b_single) {
221                 val = 0;
222                 val = w1_bq27000_read(di->w1_dev, reg + 1);
223                 *rt_value +=  HIGH_BYTE((int) val);
224         }
225
226         return 0;
227 }
228 #else
229 static inline int bq27000_read(u8 reg, int *rt_value, int b_single,
230         struct bq27x00_device_info *di)
231 {
232         return 0;
233 }
234 #endif
235
236 #ifdef CONFIG_BATTERY_BQ27200
237 static inline int bq27200_read(u8 reg, int *rt_value, int b_single,
238         struct bq27x00_device_info *di)
239 {
240         struct i2c_client *client = di->client;
241         struct i2c_msg msg[1];
242         unsigned char data[2];
243         int err;
244
245         if (!client->adapter)
246                 return -ENODEV;
247
248         msg->addr = client->addr;
249         msg->flags = 0;
250         msg->len = 1;
251         msg->buf = data;
252
253         data[0] = reg;
254         err = i2c_transfer(client->adapter, msg, 1);
255
256         if (err >= 0) {
257                 if (!b_single)
258                         msg->len = 2;
259                 else
260                         msg->len = 1;
261
262                 msg->flags = I2C_M_RD;
263                 err = i2c_transfer(client->adapter, msg, 1);
264                 if (err >= 0) {
265                         if (!b_single)
266                                 *rt_value = data[1] | HIGH_BYTE(data[0]);
267                         else
268                                 *rt_value = data[0];
269
270                         return 0;
271                 } else {
272                         pr_err("BQ27200 I2C read failed\n");
273                         return err;
274                 }
275         } else {
276                 pr_err("BQ27200 I2C write failed\n");
277                 return err;
278         }
279 }
280 #else
281 static inline int bq27200_read(u8 reg, int *rt_value, int b_single,
282         struct bq27x00_device_info *di)
283 {
284         return 0;
285 }
286 #endif
287
288 static int bq27x00_read(u8 reg, int *rt_value, int b_single,
289         struct bq27x00_device_info *di)
290 {
291         int ret;
292
293         ret = di->bus->read(reg, rt_value, b_single, di);
294         return ret;
295 }
296
297 /*
298  * Read the battery temp, voltage, current and relative state of charge.
299  */
300 static void bq27x00_battery_read_status(struct bq27x00_device_info *di)
301 {
302         if (di->update_time && time_before(jiffies, di->update_time +
303                                         msecs_to_jiffies(cache_time)))
304                 return;
305
306         di->temp_C = bq27x00_battery_temperature(di);
307         di->voltage_uV = bq27x00_battery_voltage(di);
308         di->current_uA = bq27x00_battery_current(di);
309         di->charge_rsoc = bq27x00_battery_rsoc(di);
310
311         di->update_time = jiffies;
312
313         return;
314 }
315
316 static void bq27x00_battery_work(struct delayed_work *work)
317 {
318         struct bq27x00_device_info *di = container_of(work,
319                 struct bq27x00_device_info, monitor_work);
320
321         bq27x00_battery_read_status(di);
322         schedule_delayed_work(&di->monitor_work, 100);
323         return;
324 }
325
326 #define to_bq27x00_device_info(x) container_of((x), \
327                                 struct bq27x00_device_info, bat);
328
329 static int bq27x00_battery_get_property(struct power_supply *psy,
330                                         enum power_supply_property psp,
331                                         union power_supply_propval *val)
332 {
333         struct bq27x00_device_info *di = to_bq27x00_device_info(psy);
334
335         switch (psp) {
336         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
337                 val->intval = di->voltage_uV;
338                 break;
339         case POWER_SUPPLY_PROP_CURRENT_NOW:
340                 val->intval = di->current_uA;
341                 break;
342         case POWER_SUPPLY_PROP_CHARGE_NOW:
343                 val->intval = di->charge_rsoc;
344                 break;
345         case POWER_SUPPLY_PROP_TEMP:
346                 val->intval = di->temp_C;
347                 break;
348         case POWER_SUPPLY_PROP_CAPACITY:
349                 val->intval = di->charge_rsoc;
350                 break;
351         case POWER_SUPPLY_PROP_PRESENT:
352                 if (di->voltage_uV == 0)
353                         val->intval = 0;
354                 else
355                         val->intval = 1;
356                 break;
357         default:
358                 return -EINVAL;
359         }
360
361         return 0;
362 }
363
364 static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
365 {
366         di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
367         di->bat.properties = bq27x00_battery_props;
368         di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
369         di->bat.get_property = bq27x00_battery_get_property;
370         di->bat.external_power_changed = NULL;
371         return;
372 }
373
374 #ifdef CONFIG_BATTERY_BQ27200
375 static int bq27200_battery_probe(struct i2c_client *client)
376 {
377         struct bq27x00_device_info *di;
378         struct bq27x00_access_methods *bus;
379         int retval = 0;
380
381         di = kzalloc(sizeof(*di), GFP_KERNEL);
382         if (!di) {
383                 pr_err("BQ27000 battery driver:"
384                         "Failed to allocate device info structure\n");
385                 return -ENOMEM;
386         }
387
388         bus = kzalloc(sizeof(*bus), GFP_KERNEL);
389         if (!bus) {
390                 pr_err("BQ27000 battery driver:"
391                         "Failed to allocate access method structure\n");
392                 kfree(di);
393                 return -ENOMEM;
394         }
395
396         i2c_set_clientdata(client, di);
397         di->dev = &client->dev;
398         di->bat.name = "bq27200";
399         bus->read = &bq27200_read;
400         di->bus = bus;
401         di->client = client;
402
403         bq27x00_powersupply_init(di);
404
405         retval = power_supply_register(&client->dev, &di->bat);
406         if (retval) {
407                 pr_err("BQ27200 battery driver: Failed to register battery\n");
408                 goto batt_failed;
409         }
410
411         INIT_DELAYED_WORK(&di->monitor_work, bq27x00_battery_work);
412         schedule_delayed_work(&di->monitor_work, 100);
413
414         return 0;
415
416 batt_failed:
417         kfree(bus);
418         kfree(di);
419         return retval;
420 }
421
422 static int bq27200_battery_remove(struct i2c_client *client)
423 {
424         struct bq27x00_device_info *di  = i2c_get_clientdata(client);
425
426         flush_scheduled_work();
427         power_supply_unregister(&di->bat);
428         kfree(di);
429
430         return 0;
431 }
432
433 #ifdef CONFIG_PM
434 static int bq27200_battery_suspend(struct i2c_client *client, pm_message_t mesg)
435 {
436         struct bq27x00_device_info *di  = i2c_get_clientdata(client);
437
438         cancel_delayed_work(&di->monitor_work);
439         return 0;
440 }
441
442 static int bq27200_battery_resume(struct i2c_client *client)
443 {
444         struct bq27x00_device_info *di  = i2c_get_clientdata(client);
445
446         schedule_delayed_work(&di->monitor_work, 0);
447         return 0;
448 }
449 #endif /* CONFIG_PM */
450 #endif /* CONFIG_BATTERY_BQ27200 */
451
452 #ifdef CONFIG_BATTERY_BQ27000
453 static int bq27000_battery_probe(struct  platform_device *pdev)
454 {
455         struct bq27x00_device_info *di;
456         struct bq27x00_access_methods *bus;
457         int retval = 0;
458
459         di = kzalloc(sizeof(*di), GFP_KERNEL);
460         if (!di) {
461                 pr_err("BQ27000 battery driver:"
462                         "Failed to allocate device info structure\n");
463                 return -ENOMEM;
464         }
465
466         bus = kzalloc(sizeof(*bus), GFP_KERNEL);
467         if (!bus) {
468                 pr_err("BQ27000 battery driver:"
469                         "Failed to allocate access method structure\n");
470                 kfree(di);
471                 return -ENOMEM;
472         }
473
474         platform_set_drvdata(pdev, di);
475
476         di->dev = &pdev->dev;
477         di->w1_dev = pdev->dev.parent;
478         di->bat.name = "bq27000";
479         bus->read = &bq27000_read;
480         di->bus = bus;
481
482         bq27x00_powersupply_init(di);
483
484         retval = power_supply_register(&pdev->dev, &di->bat);
485         if (retval) {
486                 pr_err("BQ27000 battery driver: Failed to register battery\n");
487                 goto batt_failed;
488         }
489
490         INIT_DELAYED_WORK(&di->monitor_work, bq27x00_battery_work);
491         schedule_delayed_work(&di->monitor_work, 50);
492
493         return 0;
494
495 batt_failed:
496         kfree(bus);
497         kfree(di);
498         return retval;
499 }
500
501 static int bq27000_battery_remove(struct  platform_device *pdev)
502 {
503         struct bq27x00_device_info *di = platform_get_drvdata(pdev);
504
505         flush_scheduled_work();
506         power_supply_unregister(&di->bat);
507         platform_set_drvdata(pdev, NULL);
508         kfree(di);
509
510         return 0;
511 }
512
513 #ifdef CONFIG_PM
514 static int bq27000_battery_suspend(struct platform_device *pdev,
515         pm_message_t state)
516 {
517         struct bq27x00_device_info *di = platform_get_drvdata(pdev);
518
519         cancel_delayed_work(&di->monitor_work);
520         return 0;
521 }
522
523 static int bq27000_battery_resume(struct platform_device *pdev)
524 {
525         struct bq27x00_device_info *di = platform_get_drvdata(pdev);
526
527         schedule_delayed_work(&di->monitor_work, 0);
528         return 0;
529 }
530 #endif /* CONFIG_PM */
531 #endif /* CONFIG_BATTERY_BQ27000 */
532
533 static int __init bq27x00_battery_init(void)
534 {
535         int status = 0;
536
537 #ifdef CONFIG_BATTERY_BQ27000
538         status = platform_driver_register(&bq27000_battery_driver);
539         if (status)
540                 printk(KERN_ERR "Unable to register BQ27000 driver\n");
541 #endif
542 #ifdef CONFIG_BATTERY_BQ27200
543         status = i2c_add_driver(&bq27200_battery_driver);
544                 printk(KERN_ERR "Unable to register BQ27200 driver\n");
545 #endif
546         return status;
547 }
548
549 static void __exit bq27x00_battery_exit(void)
550 {
551 #ifdef CONFIG_BATTERY_BQ27000
552         platform_driver_unregister(&bq27000_battery_driver);
553 #endif
554 #ifdef CONFIG_BATTERY_BQ27200
555         i2c_del_driver(&bq27200_battery_driver);
556 #endif
557 }
558
559 module_init(bq27x00_battery_init);
560 module_exit(bq27x00_battery_exit);
561
562 MODULE_AUTHOR("Texas Instruments");
563 MODULE_DESCRIPTION("BQ27x00 battery moniter driver");
564 MODULE_LICENSE("GPL");