aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/power
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq20z75.c810
-rw-r--r--drivers/power/max17048_battery.c579
-rw-r--r--drivers/power/max8907c-charger.c228
-rw-r--r--drivers/power/smb349-charger.c588
-rw-r--r--drivers/power/tegra_bpc_mgmt.c139
-rw-r--r--drivers/power/tps80031-charger.c476
-rw-r--r--drivers/power/tps80031_battery_gauge.c606
7 files changed, 3426 insertions, 0 deletions
diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c
new file mode 100644
index 00000000000..32e5a8c5c3d
--- /dev/null
+++ b/drivers/power/bq20z75.c
@@ -0,0 +1,810 @@
1/*
2 * Gas Gauge driver for TI's BQ20Z75
3 *
4 * Copyright (c) 2010, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/err.h>
25#include <linux/power_supply.h>
26#include <linux/i2c.h>
27#include <linux/slab.h>
28#include <linux/interrupt.h>
29#include <linux/gpio.h>
30
31#include <linux/power/bq20z75.h>
32
33enum {
34 REG_MANUFACTURER_DATA,
35 REG_TEMPERATURE,
36 REG_VOLTAGE,
37 REG_CURRENT,
38 REG_CAPACITY,
39 REG_TIME_TO_EMPTY,
40 REG_TIME_TO_FULL,
41 REG_STATUS,
42 REG_CYCLE_COUNT,
43 REG_SERIAL_NUMBER,
44 REG_REMAINING_CAPACITY,
45 REG_REMAINING_CAPACITY_CHARGE,
46 REG_FULL_CHARGE_CAPACITY,
47 REG_FULL_CHARGE_CAPACITY_CHARGE,
48 REG_DESIGN_CAPACITY,
49 REG_DESIGN_CAPACITY_CHARGE,
50 REG_DESIGN_VOLTAGE,
51};
52
53/* Battery Mode defines */
54#define BATTERY_MODE_OFFSET 0x03
55#define BATTERY_MODE_MASK 0x8000
56enum bq20z75_battery_mode {
57 BATTERY_MODE_AMPS,
58 BATTERY_MODE_WATTS
59};
60
61/* manufacturer access defines */
62#define MANUFACTURER_ACCESS_STATUS 0x0006
63#define MANUFACTURER_ACCESS_SLEEP 0x0011
64
65/* battery status value bits */
66#define BATTERY_DISCHARGING 0x40
67#define BATTERY_FULL_CHARGED 0x20
68#define BATTERY_FULL_DISCHARGED 0x10
69
70#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \
71 .psp = _psp, \
72 .addr = _addr, \
73 .min_value = _min_value, \
74 .max_value = _max_value, \
75}
76
77static const struct bq20z75_device_data {
78 enum power_supply_property psp;
79 u8 addr;
80 int min_value;
81 int max_value;
82} bq20z75_data[] = {
83 [REG_MANUFACTURER_DATA] =
84 BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
85 [REG_TEMPERATURE] =
86 BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
87 [REG_VOLTAGE] =
88 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
89 [REG_CURRENT] =
90 BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768,
91 32767),
92 [REG_CAPACITY] =
93 BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
94 [REG_REMAINING_CAPACITY] =
95 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
96 [REG_REMAINING_CAPACITY_CHARGE] =
97 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
98 [REG_FULL_CHARGE_CAPACITY] =
99 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
100 [REG_FULL_CHARGE_CAPACITY_CHARGE] =
101 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
102 [REG_TIME_TO_EMPTY] =
103 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0,
104 65535),
105 [REG_TIME_TO_FULL] =
106 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0,
107 65535),
108 [REG_STATUS] =
109 BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
110 [REG_CYCLE_COUNT] =
111 BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
112 [REG_DESIGN_CAPACITY] =
113 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0,
114 65535),
115 [REG_DESIGN_CAPACITY_CHARGE] =
116 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0,
117 65535),
118 [REG_DESIGN_VOLTAGE] =
119 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0,
120 65535),
121 [REG_SERIAL_NUMBER] =
122 BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
123};
124
125static enum power_supply_property bq20z75_properties[] = {
126 POWER_SUPPLY_PROP_STATUS,
127 POWER_SUPPLY_PROP_HEALTH,
128 POWER_SUPPLY_PROP_PRESENT,
129 POWER_SUPPLY_PROP_TECHNOLOGY,
130 POWER_SUPPLY_PROP_CYCLE_COUNT,
131 POWER_SUPPLY_PROP_VOLTAGE_NOW,
132 POWER_SUPPLY_PROP_CURRENT_NOW,
133 POWER_SUPPLY_PROP_CAPACITY,
134 POWER_SUPPLY_PROP_TEMP,
135 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
136 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
137 POWER_SUPPLY_PROP_SERIAL_NUMBER,
138 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
139 POWER_SUPPLY_PROP_ENERGY_NOW,
140 POWER_SUPPLY_PROP_ENERGY_FULL,
141 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
142 POWER_SUPPLY_PROP_CHARGE_NOW,
143 POWER_SUPPLY_PROP_CHARGE_FULL,
144 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
145};
146
147struct bq20z75_info {
148 struct i2c_client *client;
149 struct power_supply power_supply;
150 struct bq20z75_platform_data plat_data;
151 bool is_present;
152 bool gpio_detect;
153 bool enable_detection;
154 int irq;
155 int last_state;
156 int poll_time;
157 struct delayed_work work;
158 int ignore_changes;
159};
160
161static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
162{
163 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
164 s32 ret = 0;
165 int retries = 1;
166
167 retries = max(bq20z75_device->plat_data.i2c_retry_count + 1, 1);
168
169 while (retries > 0) {
170 ret = i2c_smbus_read_word_data(client, address);
171 if (ret >= 0)
172 break;
173 retries--;
174 }
175
176 if (ret < 0) {
177 dev_dbg(&client->dev,
178 "%s: i2c read at address 0x%x failed\n",
179 __func__, address);
180 return ret;
181 }
182
183 return le16_to_cpu(ret);
184}
185
186static int bq20z75_write_word_data(struct i2c_client *client, u8 address,
187 u16 value)
188{
189 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
190 s32 ret = 0;
191 int retries = 1;
192
193 retries = max(bq20z75_device->plat_data.i2c_retry_count + 1, 1);
194
195 while (retries > 0) {
196 ret = i2c_smbus_write_word_data(client, address,
197 le16_to_cpu(value));
198 if (ret >= 0)
199 break;
200 retries--;
201 }
202
203 if (ret < 0) {
204 dev_dbg(&client->dev,
205 "%s: i2c write to address 0x%x failed\n",
206 __func__, address);
207 return ret;
208 }
209
210 return 0;
211}
212
213static int bq20z75_get_battery_presence_and_health(
214 struct i2c_client *client, enum power_supply_property psp,
215 union power_supply_propval *val)
216{
217 s32 ret;
218 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
219
220 if (psp == POWER_SUPPLY_PROP_PRESENT &&
221 bq20z75_device->gpio_detect) {
222 ret = gpio_get_value(
223 bq20z75_device->plat_data.battery_detect);
224 if (ret == bq20z75_device->plat_data.battery_detect_present)
225 val->intval = 1;
226 else
227 val->intval = 0;
228 bq20z75_device->is_present = val->intval;
229 return ret;
230 }
231
232 /* Write to ManufacturerAccess with
233 * ManufacturerAccess command and then
234 * read the status */
235 ret = bq20z75_write_word_data(client,
236 bq20z75_data[REG_MANUFACTURER_DATA].addr,
237 MANUFACTURER_ACCESS_STATUS);
238 if (ret < 0) {
239 if (psp == POWER_SUPPLY_PROP_PRESENT)
240 val->intval = 0; /* battery removed */
241 return ret;
242 }
243
244 ret = bq20z75_read_word_data(client,
245 bq20z75_data[REG_MANUFACTURER_DATA].addr);
246 if (ret < 0)
247 return ret;
248
249 if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value ||
250 ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) {
251 val->intval = 0;
252 return 0;
253 }
254
255 /* Mask the upper nibble of 2nd byte and
256 * lower byte of response then
257 * shift the result by 8 to get status*/
258 ret &= 0x0F00;
259 ret >>= 8;
260 if (psp == POWER_SUPPLY_PROP_PRESENT) {
261 if (ret == 0x0F)
262 /* battery removed */
263 val->intval = 0;
264 else
265 val->intval = 1;
266 } else if (psp == POWER_SUPPLY_PROP_HEALTH) {
267 if (ret == 0x09)
268 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
269 else if (ret == 0x0B)
270 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
271 else if (ret == 0x0C)
272 val->intval = POWER_SUPPLY_HEALTH_DEAD;
273 else
274 val->intval = POWER_SUPPLY_HEALTH_GOOD;
275 }
276
277 return 0;
278}
279
280static int bq20z75_get_battery_property(struct i2c_client *client,
281 int reg_offset, enum power_supply_property psp,
282 union power_supply_propval *val)
283{
284 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
285 s32 ret;
286
287 ret = bq20z75_read_word_data(client,
288 bq20z75_data[reg_offset].addr);
289 if (ret < 0)
290 return ret;
291
292 /* returned values are 16 bit */
293 if (bq20z75_data[reg_offset].min_value < 0)
294 ret = (s16)ret;
295
296 if (ret >= bq20z75_data[reg_offset].min_value &&
297 ret <= bq20z75_data[reg_offset].max_value) {
298 val->intval = ret;
299 if (psp != POWER_SUPPLY_PROP_STATUS)
300 return 0;
301
302 if (ret & BATTERY_FULL_CHARGED)
303 val->intval = POWER_SUPPLY_STATUS_FULL;
304 else if (ret & BATTERY_FULL_DISCHARGED)
305 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
306 else if (ret & BATTERY_DISCHARGING)
307 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
308 else
309 val->intval = POWER_SUPPLY_STATUS_CHARGING;
310
311 if (bq20z75_device->poll_time == 0)
312 bq20z75_device->last_state = val->intval;
313 else if (bq20z75_device->last_state != val->intval) {
314 cancel_delayed_work_sync(&bq20z75_device->work);
315 power_supply_changed(&bq20z75_device->power_supply);
316 bq20z75_device->poll_time = 0;
317 }
318 } else {
319 if (psp == POWER_SUPPLY_PROP_STATUS)
320 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
321 else
322 val->intval = 0;
323 }
324
325 return 0;
326}
327
328static void bq20z75_unit_adjustment(struct i2c_client *client,
329 enum power_supply_property psp, union power_supply_propval *val)
330{
331#define BASE_UNIT_CONVERSION 1000
332#define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION)
333#define TIME_UNIT_CONVERSION 60
334#define TEMP_KELVIN_TO_CELSIUS 2731
335 switch (psp) {
336 case POWER_SUPPLY_PROP_ENERGY_NOW:
337 case POWER_SUPPLY_PROP_ENERGY_FULL:
338 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
339 /* bq20z75 provides energy in units of 10mWh.
340 * Convert to µWh
341 */
342 val->intval *= BATTERY_MODE_CAP_MULT_WATT;
343 break;
344
345 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
346 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
347 case POWER_SUPPLY_PROP_CURRENT_NOW:
348 case POWER_SUPPLY_PROP_CHARGE_NOW:
349 case POWER_SUPPLY_PROP_CHARGE_FULL:
350 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
351 val->intval *= BASE_UNIT_CONVERSION;
352 break;
353
354 case POWER_SUPPLY_PROP_TEMP:
355 /* bq20z75 provides battery temperature in 0.1K
356 * so convert it to 0.1°C
357 */
358 val->intval -= TEMP_KELVIN_TO_CELSIUS;
359 break;
360
361 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
362 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
363 /* bq20z75 provides time to empty and time to full in minutes.
364 * Convert to seconds
365 */
366 val->intval *= TIME_UNIT_CONVERSION;
367 break;
368
369 default:
370 dev_dbg(&client->dev,
371 "%s: no need for unit conversion %d\n", __func__, psp);
372 }
373}
374
375static enum bq20z75_battery_mode
376bq20z75_set_battery_mode(struct i2c_client *client,
377 enum bq20z75_battery_mode mode)
378{
379 int ret, original_val;
380
381 original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET);
382 if (original_val < 0)
383 return original_val;
384
385 if ((original_val & BATTERY_MODE_MASK) == mode)
386 return mode;
387
388 if (mode == BATTERY_MODE_AMPS)
389 ret = original_val & ~BATTERY_MODE_MASK;
390 else
391 ret = original_val | BATTERY_MODE_MASK;
392
393 ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret);
394 if (ret < 0)
395 return ret;
396
397 return original_val & BATTERY_MODE_MASK;
398}
399
400static int bq20z75_get_battery_capacity(struct i2c_client *client,
401 int reg_offset, enum power_supply_property psp,
402 union power_supply_propval *val)
403{
404 s32 ret;
405 enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS;
406
407 if (power_supply_is_amp_property(psp))
408 mode = BATTERY_MODE_AMPS;
409
410 mode = bq20z75_set_battery_mode(client, mode);
411 if (mode < 0)
412 return mode;
413
414 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr);
415 if (ret < 0)
416 return ret;
417
418 if (psp == POWER_SUPPLY_PROP_CAPACITY) {
419 /* bq20z75 spec says that this can be >100 %
420 * even if max value is 100 % */
421 val->intval = min(ret, 100);
422 } else
423 val->intval = ret;
424
425 ret = bq20z75_set_battery_mode(client, mode);
426 if (ret < 0)
427 return ret;
428
429 return 0;
430}
431
432static char bq20z75_serial[5];
433static int bq20z75_get_battery_serial_number(struct i2c_client *client,
434 union power_supply_propval *val)
435{
436 int ret;
437
438 ret = bq20z75_read_word_data(client,
439 bq20z75_data[REG_SERIAL_NUMBER].addr);
440 if (ret < 0)
441 return ret;
442
443 ret = sprintf(bq20z75_serial, "%04x", ret);
444 val->strval = bq20z75_serial;
445
446 return 0;
447}
448
449static int bq20z75_get_property_index(struct i2c_client *client,
450 enum power_supply_property psp)
451{
452 int count;
453 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++)
454 if (psp == bq20z75_data[count].psp)
455 return count;
456
457 dev_warn(&client->dev,
458 "%s: Invalid Property - %d\n", __func__, psp);
459
460 return -EINVAL;
461}
462
463static int bq20z75_get_property(struct power_supply *psy,
464 enum power_supply_property psp,
465 union power_supply_propval *val)
466{
467 int ret = 0;
468 struct bq20z75_info *bq20z75_device = container_of(psy,
469 struct bq20z75_info, power_supply);
470 struct i2c_client *client = bq20z75_device->client;
471
472 switch (psp) {
473 case POWER_SUPPLY_PROP_PRESENT:
474 case POWER_SUPPLY_PROP_HEALTH:
475 ret = bq20z75_get_battery_presence_and_health(client, psp, val);
476 if (psp == POWER_SUPPLY_PROP_PRESENT)
477 return 0;
478 break;
479
480 case POWER_SUPPLY_PROP_TECHNOLOGY:
481 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
482 break;
483
484 case POWER_SUPPLY_PROP_ENERGY_NOW:
485 case POWER_SUPPLY_PROP_ENERGY_FULL:
486 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
487 case POWER_SUPPLY_PROP_CHARGE_NOW:
488 case POWER_SUPPLY_PROP_CHARGE_FULL:
489 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
490 case POWER_SUPPLY_PROP_CAPACITY:
491 ret = bq20z75_get_property_index(client, psp);
492 if (ret < 0)
493 break;
494
495 ret = bq20z75_get_battery_capacity(client, ret, psp, val);
496 break;
497
498 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
499 ret = bq20z75_get_battery_serial_number(client, val);
500 break;
501
502 case POWER_SUPPLY_PROP_STATUS:
503 case POWER_SUPPLY_PROP_CYCLE_COUNT:
504 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
505 case POWER_SUPPLY_PROP_CURRENT_NOW:
506 case POWER_SUPPLY_PROP_TEMP:
507 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
508 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
509 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
510 ret = bq20z75_get_property_index(client, psp);
511 if (ret < 0)
512 break;
513
514 ret = bq20z75_get_battery_property(client, ret, psp, val);
515 break;
516
517 default:
518 dev_err(&client->dev,
519 "%s: INVALID property\n", __func__);
520 return -EINVAL;
521 }
522
523 if (!bq20z75_device->enable_detection)
524 goto done;
525
526 if (!bq20z75_device->gpio_detect &&
527 bq20z75_device->is_present != (ret >= 0)) {
528 bq20z75_device->is_present = (ret >= 0);
529 power_supply_changed(&bq20z75_device->power_supply);
530 }
531
532done:
533 if (!ret) {
534 /* Convert units to match requirements for power supply class */
535 bq20z75_unit_adjustment(client, psp, val);
536 }
537
538 dev_dbg(&client->dev,
539 "%s: property = %d, value = %x\n", __func__, psp, val->intval);
540
541 if (ret && bq20z75_device->is_present)
542 return ret;
543
544 /* battery not present, so return NODATA for properties */
545 if (ret)
546 return -ENODATA;
547
548 return 0;
549}
550
551static irqreturn_t bq20z75_irq(int irq, void *devid)
552{
553 struct power_supply *battery = devid;
554
555 power_supply_changed(battery);
556
557 return IRQ_HANDLED;
558}
559
560static void bq20z75_external_power_changed(struct power_supply *psy)
561{
562 struct bq20z75_info *bq20z75_device;
563
564 bq20z75_device = container_of(psy, struct bq20z75_info, power_supply);
565
566 if (bq20z75_device->ignore_changes > 0) {
567 bq20z75_device->ignore_changes--;
568 return;
569 }
570
571 /* cancel outstanding work */
572 cancel_delayed_work_sync(&bq20z75_device->work);
573
574 schedule_delayed_work(&bq20z75_device->work, HZ);
575 bq20z75_device->poll_time = bq20z75_device->plat_data.poll_retry_count;
576}
577
578static void bq20z75_delayed_work(struct work_struct *work)
579{
580 struct bq20z75_info *bq20z75_device;
581 s32 ret;
582
583 bq20z75_device = container_of(work, struct bq20z75_info, work.work);
584
585 ret = bq20z75_read_word_data(bq20z75_device->client,
586 bq20z75_data[REG_STATUS].addr);
587 /* if the read failed, give up on this work */
588 if (ret < 0) {
589 bq20z75_device->poll_time = 0;
590 return;
591 }
592
593 if (ret & BATTERY_FULL_CHARGED)
594 ret = POWER_SUPPLY_STATUS_FULL;
595 else if (ret & BATTERY_FULL_DISCHARGED)
596 ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
597 else if (ret & BATTERY_DISCHARGING)
598 ret = POWER_SUPPLY_STATUS_DISCHARGING;
599 else
600 ret = POWER_SUPPLY_STATUS_CHARGING;
601
602 if (bq20z75_device->last_state != ret) {
603 bq20z75_device->poll_time = 0;
604 power_supply_changed(&bq20z75_device->power_supply);
605 return;
606 }
607 if (bq20z75_device->poll_time > 0) {
608 schedule_delayed_work(&bq20z75_device->work, HZ);
609 bq20z75_device->poll_time--;
610 return;
611 }
612}
613
614static int __devinit bq20z75_probe(struct i2c_client *client,
615 const struct i2c_device_id *id)
616{
617 struct bq20z75_info *bq20z75_device;
618 struct bq20z75_platform_data *pdata = client->dev.platform_data;
619 int rc;
620 int irq;
621
622 bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL);
623 if (!bq20z75_device)
624 return -ENOMEM;
625
626 bq20z75_device->client = client;
627 bq20z75_device->enable_detection = false;
628 bq20z75_device->gpio_detect = false;
629 bq20z75_device->power_supply.name = "battery";
630 bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
631 bq20z75_device->power_supply.properties = bq20z75_properties;
632 bq20z75_device->power_supply.num_properties =
633 ARRAY_SIZE(bq20z75_properties);
634 bq20z75_device->power_supply.get_property = bq20z75_get_property;
635 /* ignore first notification of external change, it is generated
636 * from the power_supply_register call back
637 */
638 bq20z75_device->ignore_changes = 1;
639 bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
640 bq20z75_device->power_supply.external_power_changed =
641 bq20z75_external_power_changed;
642
643 if (pdata) {
644 bq20z75_device->gpio_detect =
645 gpio_is_valid(pdata->battery_detect);
646 memcpy(&bq20z75_device->plat_data, pdata, sizeof(struct bq20z75_platform_data));
647 }
648
649 i2c_set_clientdata(client, bq20z75_device);
650
651 /* Probing for the presence of the bq20z75 */
652 rc = bq20z75_read_word_data(client,
653 bq20z75_data[REG_SERIAL_NUMBER].addr);
654
655 if (rc < 0) {
656 dev_err(&client->dev,
657 "%s: bq20z75 is not responding\n", __func__);
658 rc = -ENODEV;
659 goto exit_mem_free;
660 }
661
662 if (!bq20z75_device->gpio_detect)
663 goto skip_gpio;
664
665 rc = gpio_request(pdata->battery_detect, dev_name(&client->dev));
666 if (rc) {
667 dev_warn(&client->dev, "Failed to request gpio: %d\n", rc);
668 bq20z75_device->gpio_detect = false;
669 goto skip_gpio;
670 }
671
672 rc = gpio_direction_input(pdata->battery_detect);
673 if (rc) {
674 dev_warn(&client->dev, "Failed to get gpio as input: %d\n", rc);
675 gpio_free(pdata->battery_detect);
676 bq20z75_device->gpio_detect = false;
677 goto skip_gpio;
678 }
679
680 irq = gpio_to_irq(pdata->battery_detect);
681 if (irq <= 0) {
682 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
683 gpio_free(pdata->battery_detect);
684 bq20z75_device->gpio_detect = false;
685 goto skip_gpio;
686 }
687
688 rc = request_irq(irq, bq20z75_irq,
689 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
690 dev_name(&client->dev), &bq20z75_device->power_supply);
691 if (rc) {
692 dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
693 gpio_free(pdata->battery_detect);
694 bq20z75_device->gpio_detect = false;
695 goto skip_gpio;
696 }
697
698 bq20z75_device->irq = irq;
699
700skip_gpio:
701 rc = power_supply_register(&client->dev, &bq20z75_device->power_supply);
702 if (rc) {
703 dev_err(&client->dev,
704 "%s: Failed to register power supply\n", __func__);
705 goto exit_psupply;
706 }
707
708 dev_info(&client->dev,
709 "%s: battery gas gauge device registered\n", client->name);
710
711 INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work);
712
713 bq20z75_device->enable_detection = true;
714
715 return 0;
716
717exit_psupply:
718 if (bq20z75_device->irq)
719 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
720 if (bq20z75_device->gpio_detect)
721 gpio_free(pdata->battery_detect);
722
723exit_mem_free:
724 kfree(bq20z75_device);
725
726 return rc;
727}
728
729static int __devexit bq20z75_remove(struct i2c_client *client)
730{
731 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
732
733 if (bq20z75_device->irq)
734 free_irq(bq20z75_device->irq, &bq20z75_device->power_supply);
735 if (bq20z75_device->gpio_detect)
736 gpio_free(bq20z75_device->plat_data.battery_detect);
737
738 power_supply_unregister(&bq20z75_device->power_supply);
739
740 cancel_delayed_work_sync(&bq20z75_device->work);
741
742 kfree(bq20z75_device);
743 bq20z75_device = NULL;
744
745 return 0;
746}
747
748#if defined CONFIG_PM
749static int bq20z75_suspend(struct i2c_client *client,
750 pm_message_t state)
751{
752 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
753 s32 ret;
754
755 if (bq20z75_device->poll_time > 0)
756 cancel_delayed_work_sync(&bq20z75_device->work);
757
758 /* write to manufacturer access with sleep command */
759 ret = bq20z75_write_word_data(client,
760 bq20z75_data[REG_MANUFACTURER_DATA].addr,
761 MANUFACTURER_ACCESS_SLEEP);
762 if (bq20z75_device->is_present && ret < 0)
763 return ret;
764
765 return 0;
766}
767
768static int bq20z75_resume(struct i2c_client *client)
769{
770 struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
771
772 schedule_delayed_work(&bq20z75_device->work, HZ);
773 return 0;
774}
775#else
776#define bq20z75_suspend NULL
777#define bq20z75_resume NULL
778#endif
779
780static const struct i2c_device_id bq20z75_id[] = {
781 { "bq20z75", 0 },
782 {}
783};
784MODULE_DEVICE_TABLE(i2c, bq20z75_id);
785
786static struct i2c_driver bq20z75_battery_driver = {
787 .probe = bq20z75_probe,
788 .remove = __devexit_p(bq20z75_remove),
789 .suspend = bq20z75_suspend,
790 .resume = bq20z75_resume,
791 .id_table = bq20z75_id,
792 .driver = {
793 .name = "bq20z75-battery",
794 },
795};
796
797static int __init bq20z75_battery_init(void)
798{
799 return i2c_add_driver(&bq20z75_battery_driver);
800}
801module_init(bq20z75_battery_init);
802
803static void __exit bq20z75_battery_exit(void)
804{
805 i2c_del_driver(&bq20z75_battery_driver);
806}
807module_exit(bq20z75_battery_exit);
808
809MODULE_DESCRIPTION("BQ20z75 battery monitor driver");
810MODULE_LICENSE("GPL");
diff --git a/drivers/power/max17048_battery.c b/drivers/power/max17048_battery.c
new file mode 100644
index 00000000000..44275e329c5
--- /dev/null
+++ b/drivers/power/max17048_battery.c
@@ -0,0 +1,579 @@
1/*
2 * max17048_battery.c
3 * fuel-gauge systems for lithium-ion (Li+) batteries
4 *
5 * Copyright (C) 2012 Nvidia Cooperation
6 * Chandler Zhang <chazhang@nvidia.com>
7 * Syed Rafiuddin <srafiuddin@nvidia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <asm/unaligned.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/mutex.h>
19#include <linux/err.h>
20#include <linux/i2c.h>
21#include <linux/delay.h>
22#include <linux/power_supply.h>
23#include <linux/slab.h>
24#include <linux/max17048_battery.h>
25
26#define MAX17048_VCELL 0x02
27#define MAX17048_SOC 0x04
28#define MAX17048_VER 0x08
29#define MAX17048_HIBRT 0x0A
30#define MAX17048_CONFIG 0x0C
31#define MAX17048_OCV 0x0E
32#define MAX17048_VLRT 0x14
33#define MAX17048_VRESET 0x18
34#define MAX17048_STATUS 0x1A
35#define MAX17048_UNLOCK 0x3E
36#define MAX17048_TABLE 0x40
37#define MAX17048_RCOMPSEG1 0x80
38#define MAX17048_RCOMPSEG2 0x90
39#define MAX17048_CMD 0xFF
40#define MAX17048_UNLOCK_VALUE 0x4a57
41#define MAX17048_RESET_VALUE 0x5400
42#define MAX17048_DELAY 1000
43#define MAX17048_BATTERY_FULL 95
44#define MAX17048_VERSION_NO 0x11
45
46struct max17048_chip {
47 struct i2c_client *client;
48 struct delayed_work work;
49 struct power_supply battery;
50 struct power_supply ac;
51 struct power_supply usb;
52 struct max17048_battery_model *model_data;
53
54 /* State Of Connect */
55 int ac_online;
56 int usb_online;
57 /* battery voltage */
58 int vcell;
59 /* battery capacity */
60 int soc;
61 /* State Of Charge */
62 int status;
63
64 int lasttime_vcell;
65 int lasttime_soc;
66 int lasttime_status;
67};
68
69uint8_t max17048_custom_data[] = {
70 0xAA, 0x00, 0xB1, 0xF0, 0xB7, 0xE0, 0xB9, 0x60, 0xBB, 0x80,
71 0xBC, 0x40, 0xBD, 0x30, 0xBD, 0x50, 0xBD, 0xF0, 0xBE, 0x40,
72 0xBF, 0xD0, 0xC0, 0x90, 0xC4, 0x30, 0xC7, 0xC0, 0xCA, 0x60,
73 0xCF, 0x30, 0x01, 0x20, 0x09, 0xC0, 0x1F, 0xC0, 0x2B, 0xE0,
74 0x4F, 0xC0, 0x30, 0x00, 0x47, 0x80, 0x4F, 0xE0, 0x77, 0x00,
75 0x15, 0x60, 0x46, 0x20, 0x13, 0x80, 0x1A, 0x60, 0x12, 0x20,
76 0x14, 0xA0, 0x14, 0xA0};
77
78static int max17048_write_word(struct i2c_client *client, int reg, u16 value)
79{
80 int ret;
81
82 ret = i2c_smbus_write_word_data(client, reg, swab16(value));
83
84 if (ret < 0)
85 dev_err(&client->dev, "%s(): Failed in writing register"
86 "0x%02x err %d\n", __func__, reg, ret);
87
88 return ret;
89}
90
91static uint16_t max17048_read_word(struct i2c_client *client, int reg)
92{
93 uint16_t ret;
94
95 ret = i2c_smbus_read_word_data(client, reg);
96
97 if (ret < 0)
98 dev_err(&client->dev, "%s(): Failed in reading register"
99 "0x%02x err %d\n", __func__, reg, ret);
100
101 return swab16(ret);
102}
103
104static int max17048_get_property(struct power_supply *psy,
105 enum power_supply_property psp,
106 union power_supply_propval *val)
107{
108 struct max17048_chip *chip = container_of(psy,
109 struct max17048_chip, battery);
110
111 switch (psp) {
112 case POWER_SUPPLY_PROP_STATUS:
113 val->intval = chip->status;
114 break;
115 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
116 val->intval = chip->vcell;
117 break;
118 case POWER_SUPPLY_PROP_CAPACITY:
119 val->intval = chip->soc;
120 break;
121 default:
122 return -EINVAL;
123 }
124 return 0;
125}
126
127static int max17048_ac_get_property(struct power_supply *psy,
128 enum power_supply_property psp,
129 union power_supply_propval *val)
130{
131 struct max17048_chip *chip = container_of(psy,
132 struct max17048_chip, ac);
133
134 if (psp == POWER_SUPPLY_PROP_ONLINE)
135 val->intval = chip->ac_online;
136 else
137 return -EINVAL;
138
139 return 0;
140}
141
142static int max17048_usb_get_property(struct power_supply *psy,
143 enum power_supply_property psp,
144 union power_supply_propval *val)
145{
146 struct max17048_chip *chip = container_of(psy,
147 struct max17048_chip, usb);
148
149 if (psp == POWER_SUPPLY_PROP_ONLINE)
150 val->intval = chip->usb_online;
151 else
152 return -EINVAL;
153
154 return 0;
155}
156
157static void max17048_get_vcell(struct i2c_client *client)
158{
159 struct max17048_chip *chip = i2c_get_clientdata(client);
160 uint16_t vcell;
161
162 vcell = max17048_read_word(client, MAX17048_VCELL);
163 if (vcell < 0)
164 dev_err(&client->dev, "%s: err %d\n", __func__, vcell);
165
166 chip->vcell = vcell;
167}
168
169static void max17048_get_soc(struct i2c_client *client)
170{
171 struct max17048_chip *chip = i2c_get_clientdata(client);
172 uint16_t soc;
173
174 soc = max17048_read_word(client, MAX17048_SOC);
175 if (soc < 0)
176 dev_err(&client->dev, "%s: err %d\n", __func__, soc);
177
178 chip->soc = soc >> 9;
179}
180
181static uint16_t max17048_get_version(struct i2c_client *client)
182{
183 return swab16(i2c_smbus_read_word_data(client, MAX17048_VER));
184}
185
186static void max17048_work(struct work_struct *work)
187{
188 struct max17048_chip *chip;
189
190 chip = container_of(work, struct max17048_chip, work.work);
191
192 max17048_get_vcell(chip->client);
193 max17048_get_soc(chip->client);
194
195 if (chip->vcell != chip->lasttime_vcell ||
196 chip->soc != chip->lasttime_soc ||
197 chip->status != chip->lasttime_status) {
198
199 chip->lasttime_vcell = chip->vcell;
200 chip->lasttime_soc = chip->soc;
201
202 power_supply_changed(&chip->battery);
203 }
204 schedule_delayed_work(&chip->work, MAX17048_DELAY);
205}
206
207static void max17048_battery_status(enum charging_states status,
208 enum charger_type chrg_type, void *data)
209{
210 struct max17048_chip *chip = data;
211
212 chip->ac_online = 0;
213 chip->usb_online = 0;
214
215 if (chrg_type == AC)
216 chip->ac_online = 1;
217 else if (chrg_type == USB)
218 chip->usb_online = 1;
219
220 if (status == progress)
221 chip->status = POWER_SUPPLY_STATUS_CHARGING;
222 else
223 chip->status = POWER_SUPPLY_STATUS_DISCHARGING;
224
225 if (chip->soc > MAX17048_BATTERY_FULL)
226 chip->status = POWER_SUPPLY_STATUS_FULL;
227
228 power_supply_changed(&chip->battery);
229 power_supply_changed(&chip->usb);
230 power_supply_changed(&chip->ac);
231}
232
233static enum power_supply_property max17048_battery_props[] = {
234 POWER_SUPPLY_PROP_STATUS,
235 POWER_SUPPLY_PROP_VOLTAGE_NOW,
236 POWER_SUPPLY_PROP_CAPACITY,
237};
238
239static enum power_supply_property max17048_ac_props[] = {
240 POWER_SUPPLY_PROP_ONLINE,
241};
242
243static enum power_supply_property max17048_usb_props[] = {
244 POWER_SUPPLY_PROP_ONLINE,
245};
246
247static int max17048_write_rcomp_seg(struct i2c_client *client,
248 uint16_t rcomp_seg)
249{
250 uint8_t rs1, rs2;
251 int ret;
252
253 rs2 = rcomp_seg | 0x00FF;
254 rs1 = rcomp_seg >> 8;
255 uint8_t rcomp_seg_table[16] = { rs1, rs2, rs1, rs2,
256 rs1, rs2, rs1, rs2,
257 rs1, rs2, rs1, rs2,
258 rs1, rs2, rs1, rs2};
259
260 ret = i2c_smbus_write_i2c_block_data(client, MAX17048_RCOMPSEG1,
261 16, (uint8_t *)rcomp_seg_table);
262 if (ret < 0) {
263 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
264 return ret;
265 }
266
267 ret = i2c_smbus_write_i2c_block_data(client, MAX17048_RCOMPSEG2,
268 16, (uint8_t *)rcomp_seg_table);
269 if (ret < 0) {
270 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
271 return ret;
272 }
273
274 return 0;
275}
276
277static int max17048_load_model_data(struct max17048_chip *chip)
278{
279 struct i2c_client *client = chip->client;
280 struct max17048_battery_model *mdata = chip->model_data;
281 uint16_t soc_tst, ocv;
282 int i, ret = 0;
283
284 /* read OCV */
285 ocv = max17048_read_word(client, MAX17048_OCV);
286 if (ocv == 0xffff) {
287 dev_err(&client->dev, "%s: Failed in unlocking"
288 "max17048 err: %d\n", __func__, ocv);
289 return -1;
290 }
291
292 /* write custom model data */
293 for (i = 0; i < 4; i += 1) {
294 if (i2c_smbus_write_i2c_block_data(client,
295 (MAX17048_TABLE+i*16), 16,
296 &max17048_custom_data[i*0x10]) < 0) {
297 dev_err(&client->dev, "%s: error writing model data:\n",
298 __func__);
299 return -1;
300 }
301 }
302
303 /* Write OCV Test value */
304 ret = max17048_write_word(client, MAX17048_OCV, mdata->ocvtest);
305 if (ret < 0)
306 return ret;
307
308 ret = max17048_write_rcomp_seg(client, mdata->rcomp_seg);
309 if (ret < 0)
310 return ret;
311
312 /* Disable hibernate */
313 ret = max17048_write_word(client, MAX17048_HIBRT, 0x0000);
314 if (ret < 0)
315 return ret;
316
317 /* Lock model access */
318 ret = max17048_write_word(client, MAX17048_UNLOCK, 0x0000);
319 if (ret < 0)
320 return ret;
321
322 /* Delay between 150ms to 600ms */
323 mdelay(200);
324
325 /* Read SOC Register and compare to expected result */
326 soc_tst = max17048_read_word(client, MAX17048_SOC);
327 if (!((soc_tst >> 8) >= mdata->soccheck_A &&
328 (soc_tst >> 8) <= mdata->soccheck_B)) {
329 dev_err(&client->dev, "%s: soc comparison failed %d\n",
330 __func__, ret);
331 return ret;
332 } else {
333 dev_info(&client->dev, "MAX17048 Custom data"
334 " loading successfull\n");
335 }
336
337 /* unlock model access */
338 ret = max17048_write_word(client, MAX17048_UNLOCK,
339 MAX17048_UNLOCK_VALUE);
340 if (ret < 0)
341 return ret;
342
343 /* Restore OCV */
344 ret = max17048_write_word(client, MAX17048_OCV, ocv);
345 if (ret < 0)
346 return ret;
347
348 return ret;
349}
350
351static int max17048_initialize(struct max17048_chip *chip)
352{
353 uint8_t ret, config, status;
354 uint16_t wrt_status;
355 struct i2c_client *client = chip->client;
356 struct max17048_battery_model *mdata = chip->model_data;
357
358 /* unlock model access */
359 ret = max17048_write_word(client, MAX17048_UNLOCK,
360 MAX17048_UNLOCK_VALUE);
361 if (ret < 0)
362 return ret;
363
364 /* load model data */
365 ret = max17048_load_model_data(chip);
366 if (ret < 0) {
367 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
368 return ret;
369 }
370
371 if (mdata->bits == 19)
372 config = 32 - (mdata->alert_threshold * 2);
373 else if (mdata->bits == 18)
374 config = 32 - mdata->alert_threshold;
375
376 config = mdata->one_percent_alerts | config;
377
378 ret = max17048_write_word(client, MAX17048_CONFIG,
379 ((mdata->rcomp << 8) | config));
380 if (ret < 0)
381 return ret;
382
383 /* Voltage Alert configuration */
384 ret = max17048_write_word(client, MAX17048_VLRT, mdata->valert);
385 if (ret < 0)
386 return ret;
387
388 /* Hibernate configuration */
389 ret = max17048_write_word(client, MAX17048_HIBRT, mdata->hibernate);
390 if (ret < 0)
391 return ret;
392
393 ret = max17048_write_word(client, MAX17048_VRESET, mdata->vreset);
394 if (ret < 0)
395 return ret;
396
397 /* clears the reset indicator */
398 ret = max17048_read_word(client, MAX17048_STATUS);
399 if (ret < 0)
400 return ret;
401
402 /* Sets the EnVR bit if selected */
403 status = (ret & 0xFE) | mdata->alert_on_reset;
404 wrt_status = status << 8;
405
406 ret = max17048_write_word(client, MAX17048_STATUS, wrt_status);
407 if (ret < 0)
408 return ret;
409
410 /* Lock model access */
411 ret = max17048_write_word(client, MAX17048_UNLOCK, 0x0000);
412 if (ret < 0)
413 return ret;
414
415 /* Add delay */
416 mdelay(200);
417 return 0;
418}
419
420static int __devinit max17048_probe(struct i2c_client *client,
421 const struct i2c_device_id *id)
422{
423 struct max17048_chip *chip;
424 int ret;
425 uint16_t version;
426
427 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
428 if (!chip)
429 return -ENOMEM;
430
431 chip->client = client;
432 chip->model_data = client->dev.platform_data;
433 chip->ac_online = 0;
434 chip->usb_online = 0;
435
436 i2c_set_clientdata(client, chip);
437
438 version = max17048_get_version(client);
439 if (version != MAX17048_VERSION_NO) {
440 ret = -ENODEV;
441 goto error2;
442 }
443 dev_info(&client->dev, "MAX17048 Fuel-Gauge Ver 0x%x\n", version);
444
445 ret = max17048_initialize(chip);
446 if (ret < 0) {
447 dev_err(&client->dev, "Error: Initializing fuel-gauge\n");
448 goto error2;
449 }
450
451 ret = register_callback(max17048_battery_status, chip);
452 if (ret < 0)
453 goto error2;
454
455 chip->battery.name = "battery";
456 chip->battery.type = POWER_SUPPLY_TYPE_BATTERY;
457 chip->battery.get_property = max17048_get_property;
458 chip->battery.properties = max17048_battery_props;
459 chip->battery.num_properties = ARRAY_SIZE(max17048_battery_props);
460
461 ret = power_supply_register(&client->dev, &chip->battery);
462 if (ret) {
463 dev_err(&client->dev, "failed: power supply register\n");
464 goto error2;
465 }
466
467 chip->ac.name = "maxim-ac";
468 chip->ac.type = POWER_SUPPLY_TYPE_MAINS;
469 chip->ac.get_property = max17048_ac_get_property;
470 chip->ac.properties = max17048_ac_props;
471 chip->ac.num_properties = ARRAY_SIZE(max17048_ac_props);
472
473 ret = power_supply_register(&client->dev, &chip->ac);
474 if (ret) {
475 dev_err(&client->dev, "failed: power supply register\n");
476 goto error1;
477 }
478
479 chip->usb.name = "maxim-usb";
480 chip->usb.type = POWER_SUPPLY_TYPE_USB;
481 chip->usb.get_property = max17048_usb_get_property;
482 chip->usb.properties = max17048_usb_props;
483 chip->usb.num_properties = ARRAY_SIZE(max17048_usb_props);
484
485 ret = power_supply_register(&client->dev, &chip->usb);
486 if (ret) {
487 dev_err(&client->dev, "failed: power supply register\n");
488 goto error;
489 }
490
491 INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17048_work);
492 schedule_delayed_work(&chip->work, MAX17048_DELAY);
493
494 ret = update_charger_status();
495 if (ret) {
496 dev_err(&client->dev, "failed: update_charger_status\n");
497 goto error;
498 }
499
500 return 0;
501error:
502 power_supply_unregister(&chip->ac);
503error1:
504 power_supply_unregister(&chip->battery);
505error2:
506 kfree(chip);
507 return ret;
508}
509
510static int __devexit max17048_remove(struct i2c_client *client)
511{
512 struct max17048_chip *chip = i2c_get_clientdata(client);
513
514 power_supply_unregister(&chip->battery);
515 power_supply_unregister(&chip->usb);
516 power_supply_unregister(&chip->ac);
517 cancel_delayed_work(&chip->work);
518 kfree(chip);
519 return 0;
520}
521
522#ifdef CONFIG_PM
523
524static int max17048_suspend(struct i2c_client *client,
525 pm_message_t state)
526{
527 struct max17048_chip *chip = i2c_get_clientdata(client);
528
529 cancel_delayed_work(&chip->work);
530 return 0;
531}
532
533static int max17048_resume(struct i2c_client *client)
534{
535 struct max17048_chip *chip = i2c_get_clientdata(client);
536
537 schedule_delayed_work(&chip->work, MAX17048_DELAY);
538 return 0;
539}
540
541#else
542
543#define max17048_suspend NULL
544#define max17048_resume NULL
545
546#endif /* CONFIG_PM */
547
548static const struct i2c_device_id max17048_id[] = {
549 { "max17048", 0 },
550 { }
551};
552MODULE_DEVICE_TABLE(i2c, max17048_id);
553
554static struct i2c_driver max17048_i2c_driver = {
555 .driver = {
556 .name = "max17048",
557 },
558 .probe = max17048_probe,
559 .remove = __devexit_p(max17048_remove),
560 .suspend = max17048_suspend,
561 .resume = max17048_resume,
562 .id_table = max17048_id,
563};
564
565static int __init max17048_init(void)
566{
567 return i2c_add_driver(&max17048_i2c_driver);
568}
569module_init(max17048_init);
570
571static void __exit max17048_exit(void)
572{
573 i2c_del_driver(&max17048_i2c_driver);
574}
575module_exit(max17048_exit);
576
577MODULE_AUTHOR("Chandler Zhang <chazhang@nvidia.com>");
578MODULE_DESCRIPTION("MAX17048 Fuel Gauge");
579MODULE_LICENSE("GPL");
diff --git a/drivers/power/max8907c-charger.c b/drivers/power/max8907c-charger.c
new file mode 100644
index 00000000000..64855c589b1
--- /dev/null
+++ b/drivers/power/max8907c-charger.c
@@ -0,0 +1,228 @@
1/*
2 * Battery driver for Maxim MAX8907C
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/err.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/power_supply.h>
17#include <linux/mfd/max8907c.h>
18#include <linux/power/max8907c-charger.h>
19#include <linux/slab.h>
20
21struct max8907c_charger {
22 struct max8907c_charger_pdata *pdata;
23 struct max8907c *chip;
24 struct i2c_client *i2c;
25 int online;
26};
27
28static void max8907c_set_charger(struct max8907c_charger *charger)
29{
30 struct max8907c_charger_pdata *pdata = charger->pdata;
31 int ret;
32 if (charger->online) {
33 ret = max8907c_reg_write(charger->i2c, MAX8907C_REG_CHG_CNTL1,
34 (pdata->topoff_threshold << 5) |
35 (pdata->restart_hysteresis << 3) |
36 (pdata->fast_charging_current));
37 if (unlikely(ret != 0))
38 pr_err("Failed to set CHG_CNTL1: %d\n", ret);
39
40 ret = max8907c_set_bits(charger->i2c, MAX8907C_REG_CHG_CNTL2,
41 0x30, pdata->fast_charger_time << 4);
42 if (unlikely(ret != 0))
43 pr_err("Failed to set CHG_CNTL2: %d\n", ret);
44 } else {
45 ret = max8907c_set_bits(charger->i2c, MAX8907C_REG_CHG_CNTL1, 0x80, 0x1);
46 if (unlikely(ret != 0))
47 pr_err("Failed to set CHG_CNTL1: %d\n", ret);
48 }
49}
50
51static irqreturn_t max8907c_charger_isr(int irq, void *dev_id)
52{
53 struct max8907c_charger *charger = dev_id;
54 struct max8907c *chip = charger->chip;
55
56 switch (irq - chip->irq_base) {
57 case MAX8907C_IRQ_VCHG_DC_R:
58 charger->online = 1;
59 max8907c_set_charger(charger);
60 break;
61 case MAX8907C_IRQ_VCHG_DC_F:
62 charger->online = 0;
63 max8907c_set_charger(charger);
64 break;
65 }
66
67 return IRQ_HANDLED;
68}
69
70static int max8907c_charger_get_property(struct power_supply *psy,
71 enum power_supply_property psp,
72 union power_supply_propval *val)
73{
74 const static int types[] = {
75 POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
76 POWER_SUPPLY_CHARGE_TYPE_FAST,
77 POWER_SUPPLY_CHARGE_TYPE_FAST,
78 POWER_SUPPLY_CHARGE_TYPE_NONE,
79 };
80 int ret = -ENODEV;
81 int status;
82
83 struct max8907c_charger *charger = dev_get_drvdata(psy->dev->parent);
84
85 switch (psp) {
86 case POWER_SUPPLY_PROP_ONLINE:
87 val->intval = charger->online;
88 ret = 0;
89 break;
90
91 case POWER_SUPPLY_PROP_STATUS:
92 /* Get charger status from CHG_EN_STAT */
93 status = max8907c_reg_read(charger->i2c, MAX8907C_REG_CHG_STAT);
94 val->intval = ((status & 0x10) == 0x10) ?
95 POWER_SUPPLY_STATUS_CHARGING :
96 POWER_SUPPLY_STATUS_NOT_CHARGING;
97 ret = 0;
98 break;
99
100 case POWER_SUPPLY_PROP_CHARGE_TYPE:
101 /* Get charging type from CHG_MODE */
102 status = max8907c_reg_read(charger->i2c, MAX8907C_REG_CHG_STAT);
103 val->intval = types[(status & 0x0C) >> 2];
104 ret = 0;
105 break;
106
107 default:
108 val->intval = 0;
109 ret = -EINVAL;
110 break;
111 }
112 return ret;
113}
114
115static enum power_supply_property max8907c_charger_props[] = {
116 POWER_SUPPLY_PROP_ONLINE,
117 POWER_SUPPLY_PROP_STATUS,
118 POWER_SUPPLY_PROP_CHARGE_TYPE,
119};
120
121static struct power_supply max8907c_charger_ps = {
122 .name = "charger",
123 .type = POWER_SUPPLY_TYPE_MAINS,
124 .properties = max8907c_charger_props,
125 .num_properties = ARRAY_SIZE(max8907c_charger_props),
126 .get_property = max8907c_charger_get_property,
127};
128
129static __devinit int max8907c_charger_probe(struct platform_device *pdev)
130{
131 struct max8907c_charger_pdata *pdata = pdev->dev.platform_data;
132 struct max8907c_charger *charger = 0;
133 struct max8907c *chip = dev_get_drvdata(pdev->dev.parent);
134 int ret;
135
136 charger = kzalloc(sizeof(*charger), GFP_KERNEL);
137 if (!charger)
138 return -ENOMEM;
139
140 charger->pdata = pdata;
141 charger->online = 0;
142 charger->chip = chip;
143 charger->i2c = chip->i2c_power;
144
145 platform_set_drvdata(pdev, charger);
146
147 ret = max8907c_reg_read(charger->i2c, MAX8907C_REG_CHG_STAT);
148 if (ret & (1 << 7)) {
149 charger->online = 1;
150 max8907c_set_charger(charger);
151 }
152
153 ret = request_threaded_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_F, NULL,
154 max8907c_charger_isr, IRQF_ONESHOT,
155 "power-remove", charger);
156 if (unlikely(ret < 0)) {
157 pr_debug("max8907c: failed to request IRQ %X\n", ret);
158 goto out;
159 }
160
161 ret = request_threaded_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_R, NULL,
162 max8907c_charger_isr, IRQF_ONESHOT,
163 "power-insert", charger);
164 if (unlikely(ret < 0)) {
165 pr_debug("max8907c: failed to request IRQ %X\n", ret);
166 goto out1;
167 }
168
169
170 ret = power_supply_register(&pdev->dev, &max8907c_charger_ps);
171 if (unlikely(ret != 0)) {
172 pr_err("Failed to register max8907c_charger driver: %d\n", ret);
173 goto out2;
174 }
175
176 return 0;
177out2:
178 free_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_R, charger);
179out1:
180 free_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_F, charger);
181out:
182 kfree(charger);
183 return ret;
184}
185
186static __devexit int max8907c_charger_remove(struct platform_device *pdev)
187{
188 struct max8907c_charger *charger = platform_get_drvdata(pdev);
189 struct max8907c *chip = charger->chip;
190 int ret;
191
192 ret = max8907c_reg_write(charger->i2c, MAX8907C_REG_CHG_IRQ1_MASK, 0xFF);
193 if (unlikely(ret != 0)) {
194 pr_err("Failed to set IRQ1_MASK: %d\n", ret);
195 goto out;
196 }
197
198 free_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_R, charger);
199 free_irq(chip->irq_base + MAX8907C_IRQ_VCHG_DC_F, charger);
200 power_supply_unregister(&max8907c_charger_ps);
201out:
202 kfree(charger);
203 return 0;
204}
205
206static struct platform_driver max8907c_charger_driver = {
207 .probe = max8907c_charger_probe,
208 .remove = __devexit_p(max8907c_charger_remove),
209 .driver = {
210 .name = "max8907c-charger",
211 },
212};
213
214static int __init max8907c_charger_init(void)
215{
216 return platform_driver_register(&max8907c_charger_driver);
217}
218module_init(max8907c_charger_init);
219
220static void __exit max8907c_charger_exit(void)
221{
222 platform_driver_unregister(&max8907c_charger_driver);
223}
224module_exit(max8907c_charger_exit);
225
226MODULE_DESCRIPTION("Charger driver for MAX8907C");
227MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
228MODULE_LICENSE("GPL");
diff --git a/drivers/power/smb349-charger.c b/drivers/power/smb349-charger.c
new file mode 100644
index 00000000000..1f230baadcb
--- /dev/null
+++ b/drivers/power/smb349-charger.c
@@ -0,0 +1,588 @@
1/*
2 * drivers/power/smb349-charger.c
3 *
4 * Battery charger driver for smb349 from summit microelectronics
5 *
6 * Copyright (c) 2012, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation;
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/platform_device.h>
25#include <linux/mutex.h>
26#include <linux/err.h>
27#include <linux/i2c.h>
28#include <linux/delay.h>
29#include <linux/power_supply.h>
30#include <linux/platform_device.h>
31#include <linux/regulator/driver.h>
32#include <linux/regulator/machine.h>
33#include <linux/smb349-charger.h>
34#include <linux/slab.h>
35#include <linux/gpio.h>
36#include <linux/interrupt.h>
37#include <linux/irq.h>
38#include <linux/usb/otg.h>
39
40#define SMB349_CHARGE 0x00
41#define SMB349_CHRG_CRNTS 0x01
42#define SMB349_VRS_FUNC 0x02
43#define SMB349_FLOAT_VLTG 0x03
44#define SMB349_CHRG_CTRL 0x04
45#define SMB349_STAT_TIME_CTRL 0x05
46#define SMB349_PIN_CTRL 0x06
47#define SMB349_THERM_CTRL 0x07
48#define SMB349_CTRL_REG 0x09
49
50#define SMB349_OTG_TLIM_REG 0x0A
51#define SMB349_HRD_SFT_TEMP 0x0B
52#define SMB349_FAULT_INTR 0x0C
53#define SMB349_STS_INTR_1 0x0D
54#define SMB349_SYSOK_USB3 0x0E
55#define SMB349_IN_CLTG_DET 0x10
56#define SMB349_STS_INTR_2 0x11
57
58#define SMB349_CMD_REG 0x30
59#define SMB349_CMD_REG_B 0x31
60#define SMB349_CMD_REG_c 0x33
61
62#define SMB349_INTR_STS_A 0x35
63#define SMB349_INTR_STS_B 0x36
64#define SMB349_INTR_STS_C 0x37
65#define SMB349_INTR_STS_D 0x38
66#define SMB349_INTR_STS_E 0x39
67#define SMB349_INTR_STS_F 0x3A
68
69#define SMB349_STS_REG_A 0x3B
70#define SMB349_STS_REG_B 0x3C
71#define SMB349_STS_REG_C 0x3D
72#define SMB349_STS_REG_D 0x3E
73#define SMB349_STS_REG_E 0x3F
74
75#define SMB349_ENABLE_WRITE 1
76#define SMB349_DISABLE_WRITE 0
77#define ENABLE_WRT_ACCESS 0x80
78#define THERM_CTRL 0x10
79#define BATTERY_MISSING 0x10
80#define CHARGING 0x06
81#define DEDICATED_CHARGER 0x04
82#define CHRG_DOWNSTRM_PORT 0x08
83#define ENABLE_CHARGE 0x02
84
85static struct smb349_charger *charger;
86static int smb349_configure_charger(struct i2c_client *client, int value);
87static int smb349_configure_interrupts(struct i2c_client *client);
88
89static int smb349_read(struct i2c_client *client, int reg)
90{
91 int ret;
92
93 ret = i2c_smbus_read_byte_data(client, reg);
94
95 if (ret < 0)
96 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
97
98 return ret;
99}
100
101static int smb349_write(struct i2c_client *client, int reg, u8 value)
102{
103 int ret;
104
105 ret = i2c_smbus_write_byte_data(client, reg, value);
106
107 if (ret < 0)
108 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
109
110 return ret;
111}
112
113static int smb349_update_reg(struct i2c_client *client, int reg, u8 value)
114{
115 int ret, retval;
116
117 retval = smb349_read(client, reg);
118 if (retval < 0) {
119 dev_err(&client->dev, "%s: err %d\n", __func__, retval);
120 return retval;
121 }
122
123 ret = smb349_write(client, reg, retval | value);
124 if (ret < 0) {
125 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
126 return ret;
127 }
128
129 return ret;
130}
131
132int smb349_volatile_writes(struct i2c_client *client, uint8_t value)
133{
134 int ret = 0;
135
136 if (value == SMB349_ENABLE_WRITE) {
137 /* Enable volatile write to config registers */
138 ret = smb349_update_reg(client, SMB349_CMD_REG,
139 ENABLE_WRT_ACCESS);
140 if (ret < 0) {
141 dev_err(&client->dev, "%s(): Failed in writing"
142 "register 0x%02x\n", __func__, SMB349_CMD_REG);
143 return ret;
144 }
145 } else {
146 ret = smb349_read(client, SMB349_CMD_REG);
147 if (ret < 0) {
148 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
149 return ret;
150 }
151
152 ret = smb349_write(client, SMB349_CMD_REG, ret & (~(1<<7)));
153 if (ret < 0) {
154 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
155 return ret;
156 }
157 }
158 return ret;
159}
160
161static void smb349_clear_interrupts(struct i2c_client *client)
162{
163 uint8_t val, buf[6];
164
165 val = i2c_smbus_read_i2c_block_data(client, SMB349_INTR_STS_A, 6, buf);
166 if (val < 0)
167 dev_err(&client->dev, "%s(): Failed in clearing interrupts\n",
168 __func__);
169}
170
171static int smb349_configure_otg(struct i2c_client *client, int enable)
172{
173 int ret = 0;
174
175 /*Enable volatile writes to registers*/
176 ret = smb349_volatile_writes(client, SMB349_ENABLE_WRITE);
177 if (ret < 0) {
178 dev_err(&client->dev, "%s error in configuring otg..\n",
179 __func__);
180 goto error;
181 }
182
183 if (enable) {
184 /* Configure PGOOD to be active low */
185 ret = smb349_read(client, SMB349_SYSOK_USB3);
186 if (ret < 0) {
187 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
188 goto error;
189 }
190
191 ret = smb349_write(client, SMB349_SYSOK_USB3, (ret & (~(1))));
192 if (ret < 0) {
193 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
194 goto error;
195 }
196
197 /* Enable OTG */
198 ret = smb349_update_reg(client, SMB349_CMD_REG, 0x10);
199 if (ret < 0) {
200 dev_err(&client->dev, "%s: Failed in writing register"
201 "0x%02x\n", __func__, SMB349_CMD_REG);
202 goto error;
203 }
204 } else {
205 /* Disable OTG */
206 ret = smb349_read(client, SMB349_CMD_REG);
207 if (ret < 0) {
208 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
209 goto error;
210 }
211
212 ret = smb349_write(client, SMB349_CMD_REG, (ret & (~(1<<4))));
213 if (ret < 0) {
214 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
215 goto error;
216 }
217
218 /* Configure PGOOD to be active high */
219 ret = smb349_update_reg(client, SMB349_SYSOK_USB3, 0x01);
220 if (ret < 0) {
221 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
222 goto error;
223 }
224 }
225
226 /* Disable volatile writes to registers */
227 ret = smb349_volatile_writes(client, SMB349_DISABLE_WRITE);
228 if (ret < 0)
229 dev_err(&client->dev, "%s error in configuring OTG..\n",
230 __func__);
231error:
232 return ret;
233}
234
235static int smb349_configure_charger(struct i2c_client *client, int value)
236{
237 int ret = 0;
238
239 /* Enable volatile writes to registers */
240 ret = smb349_volatile_writes(client, SMB349_ENABLE_WRITE);
241 if (ret < 0) {
242 dev_err(&client->dev, "%s() error in configuring charger..\n",
243 __func__);
244 goto error;
245 }
246
247 if (value) {
248 /* Enable charging */
249 ret = smb349_update_reg(client, SMB349_CMD_REG, ENABLE_CHARGE);
250 if (ret < 0) {
251 dev_err(&client->dev, "%s(): Failed in writing register"
252 "0x%02x\n", __func__, SMB349_CMD_REG);
253 goto error;
254 }
255
256 /* Configure THERM ctrl */
257 ret = smb349_update_reg(client, SMB349_THERM_CTRL, THERM_CTRL);
258 if (ret < 0) {
259 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
260 goto error;
261 }
262 } else {
263 ret = smb349_read(client, SMB349_CMD_REG);
264 if (ret < 0) {
265 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
266 goto error;
267 }
268
269 ret = smb349_write(client, SMB349_CMD_REG, (ret & (~(1<<1))));
270 if (ret < 0) {
271 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
272 goto error;
273 }
274 }
275 /* Disable volatile writes to registers */
276 ret = smb349_volatile_writes(client, SMB349_DISABLE_WRITE);
277 if (ret < 0) {
278 dev_err(&client->dev, "%s() error in configuring charger..\n",
279 __func__);
280 goto error;
281 }
282error:
283 return ret;
284}
285
286static irqreturn_t smb349_status_isr(int irq, void *dev_id)
287{
288 struct i2c_client *client = charger->client;
289 int ret, val;
290
291 val = smb349_read(client, SMB349_STS_REG_D);
292 if (val < 0) {
293 dev_err(&client->dev, "%s(): Failed in reading register"
294 "0x%02x\n", __func__, SMB349_STS_REG_D);
295 goto irq_error;
296 } else if (val != 0) {
297 if (val & DEDICATED_CHARGER)
298 charger->chrg_type = AC;
299 else if (val & CHRG_DOWNSTRM_PORT)
300 charger->chrg_type = USB;
301
302 /* configure charger */
303 ret = smb349_configure_charger(client, 1);
304 if (ret < 0) {
305 dev_err(&client->dev, "%s() error in configuring"
306 "charger..\n", __func__);
307 goto irq_error;
308 }
309
310 charger->state = progress;
311 } else {
312 charger->state = stopped;
313
314 /* Disable charger */
315 ret = smb349_configure_charger(client, 0);
316 if (ret < 0) {
317 dev_err(&client->dev, "%s() error in configuring"
318 "charger..\n", __func__);
319 goto irq_error;
320 }
321
322 ret = smb349_configure_interrupts(client);
323 if (ret < 0) {
324 dev_err(&client->dev, "%s() error in configuring"
325 "charger..\n", __func__);
326 goto irq_error;
327 }
328
329 }
330
331 if (charger->charger_cb)
332 charger->charger_cb(charger->state, charger->chrg_type,
333 charger->charger_cb_data);
334irq_error:
335 smb349_clear_interrupts(client);
336 return IRQ_HANDLED;
337}
338
339int update_charger_status(void)
340{
341 struct i2c_client *client = charger->client;
342 int ret, val;
343
344 val = smb349_read(client, SMB349_STS_REG_D);
345 if (val < 0) {
346 dev_err(&client->dev, "%s(): Failed in reading register"
347 "0x%02x\n", __func__, SMB349_STS_REG_D);
348 goto val_error;
349 } else if (val != 0) {
350 if (val & DEDICATED_CHARGER)
351 charger->chrg_type = AC;
352 else if (val & CHRG_DOWNSTRM_PORT)
353 charger->chrg_type = USB;
354
355 /* configure charger */
356 ret = smb349_configure_charger(client, 1);
357 if (ret < 0) {
358 dev_err(&client->dev, "%s() error in configuring"
359 "charger..\n", __func__);
360 goto ret_error;
361 }
362
363 charger->state = progress;
364 } else {
365 charger->state = stopped;
366
367 /* Disable charger */
368 ret = smb349_configure_charger(client, 0);
369 if (ret < 0) {
370 dev_err(&client->dev, "%s() error in configuring"
371 "charger..\n", __func__);
372 goto ret_error;
373 }
374 }
375
376 if (charger->charger_cb)
377 charger->charger_cb(charger->state, charger->chrg_type,
378 charger->charger_cb_data);
379 return 0;
380val_error:
381 return val;
382ret_error:
383 return ret;
384}
385EXPORT_SYMBOL_GPL(update_charger_status);
386
387int register_callback(charging_callback_t cb, void *args)
388{
389 struct smb349_charger *charger_data = charger;
390 if (!charger_data)
391 return -ENODEV;
392
393 charger_data->charger_cb = cb;
394 charger_data->charger_cb_data = args;
395 return 0;
396}
397EXPORT_SYMBOL_GPL(register_callback);
398
399int smb349_battery_online(void)
400{
401 int val;
402 struct i2c_client *client = charger->client;
403
404 val = smb349_read(charger->client, SMB349_INTR_STS_B);
405 if (val < 0) {
406 dev_err(&client->dev, "%s(): Failed in reading register"
407 "0x%02x\n", __func__, SMB349_INTR_STS_B);
408 return val;
409 }
410 if (val & BATTERY_MISSING)
411 return 0;
412 else
413 return 1;
414}
415
416static int smb349_configure_interrupts(struct i2c_client *client)
417{
418 int ret = 0;
419
420 /* Enable volatile writes to registers */
421 ret = smb349_volatile_writes(client, SMB349_ENABLE_WRITE);
422 if (ret < 0) {
423 dev_err(&client->dev, "%s() error in configuring charger..\n",
424 __func__);
425 goto error;
426 }
427
428 ret = smb349_update_reg(client, SMB349_FAULT_INTR, 0xff);
429 if (ret < 0) {
430 dev_err(&client->dev, "%s(): Failed in writing register"
431 "0x%02x\n", __func__, SMB349_CMD_REG);
432 goto error;
433 }
434
435 ret = smb349_update_reg(client, SMB349_STS_INTR_1, 0xff);
436 if (ret < 0) {
437 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
438 goto error;
439 }
440
441 /* Disable volatile writes to registers */
442 ret = smb349_volatile_writes(client, SMB349_DISABLE_WRITE);
443 if (ret < 0) {
444 dev_err(&client->dev, "%s() error in configuring charger..\n",
445 __func__);
446 goto error;
447 }
448
449error:
450 return ret;
451}
452
453static void smb349_otg_status(enum usb_otg_state to, enum usb_otg_state from, void *data)
454{
455 struct i2c_client *client = charger->client;
456 int ret;
457
458 if ((from == OTG_STATE_A_SUSPEND) && (to == OTG_STATE_A_HOST)) {
459
460 /* configure charger */
461 ret = smb349_configure_charger(client, 0);
462 if (ret < 0)
463 dev_err(&client->dev, "%s() error in configuring"
464 "otg..\n", __func__);
465
466 /* ENABLE OTG */
467 ret = smb349_configure_otg(client, 1);
468 if (ret < 0)
469 dev_err(&client->dev, "%s() error in configuring"
470 "otg..\n", __func__);
471
472 } else if ((from == OTG_STATE_A_HOST) && (to == OTG_STATE_A_SUSPEND)) {
473
474 /* Disable OTG */
475 ret = smb349_configure_otg(client, 0);
476 if (ret < 0)
477 dev_err(&client->dev, "%s() error in configuring"
478 "otg..\n", __func__);
479
480 /* configure charger */
481 ret = smb349_configure_charger(client, 1);
482 if (ret < 0)
483 dev_err(&client->dev, "%s() error in configuring"
484 "otg..\n", __func__);
485
486 ret = smb349_configure_interrupts(client);
487 if (ret < 0)
488 dev_err(&client->dev, "%s() error in configuring"
489 "otg..\n", __func__);
490 }
491}
492
493static int __devinit smb349_probe(struct i2c_client *client,
494 const struct i2c_device_id *id)
495{
496 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
497 int ret, irq_num;
498
499 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
500 return -EIO;
501
502 charger = kzalloc(sizeof(*charger), GFP_KERNEL);
503 if (!charger)
504 return -ENOMEM;
505
506 charger->client = client;
507 charger->dev = &client->dev;
508 i2c_set_clientdata(client, charger);
509
510 /* Check battery presence */
511 if (!smb349_battery_online()) {
512 dev_err(&client->dev, "%s() No Battery present, exiting..\n",
513 __func__);
514 ret = -ENODEV;
515 goto error;
516 }
517
518 ret = register_otg_callback(smb349_otg_status, charger);
519 if (ret < 0)
520 goto error;
521
522 ret = smb349_configure_charger(client, 1);
523 if (ret < 0)
524 return ret;
525
526 ret = smb349_configure_interrupts(client);
527 if (ret < 0) {
528 dev_err(&client->dev, "%s() error in configuring charger..\n",
529 __func__);
530 goto error;
531 }
532
533 irq_num = gpio_to_irq(client->irq);
534 ret = request_threaded_irq(irq_num,
535 NULL, smb349_status_isr, IRQ_TYPE_EDGE_FALLING,
536 "smb349", charger);
537 if (ret) {
538 dev_err(&client->dev, "%s(): Failed in requesting isr\n",
539 __func__);
540 goto error;
541 }
542
543 return 0;
544error:
545 kfree(charger);
546 return ret;
547}
548
549static int __devexit smb349_remove(struct i2c_client *client)
550{
551 struct smb349_charger *charger = i2c_get_clientdata(client);
552
553 free_irq(gpio_to_irq(client->irq), charger);
554 kfree(charger);
555
556 return 0;
557}
558
559static const struct i2c_device_id smb349_id[] = {
560 { "smb349", 0 },
561 { }
562};
563MODULE_DEVICE_TABLE(i2c, smb349_id);
564
565static struct i2c_driver smb349_i2c_driver = {
566 .driver = {
567 .name = "smb349",
568 },
569 .probe = smb349_probe,
570 .remove = __devexit_p(smb349_remove),
571 .id_table = smb349_id,
572};
573
574static int __init smb349_init(void)
575{
576 return i2c_add_driver(&smb349_i2c_driver);
577}
578module_init(smb349_init);
579
580static void __exit smb349_exit(void)
581{
582 i2c_del_driver(&smb349_i2c_driver);
583}
584module_exit(smb349_exit);
585
586MODULE_AUTHOR("Syed Rafiuddin <srafiuddin@nvidia.com>");
587MODULE_DESCRIPTION("SMB349 Battery-Charger");
588MODULE_LICENSE("GPL");
diff --git a/drivers/power/tegra_bpc_mgmt.c b/drivers/power/tegra_bpc_mgmt.c
new file mode 100644
index 00000000000..0d9ddeee282
--- /dev/null
+++ b/drivers/power/tegra_bpc_mgmt.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA Corporation
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/gpio.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/irqflags.h>
20#include <linux/slab.h>
21#include <linux/irq.h>
22#include <linux/sched.h>
23#include <linux/jiffies.h>
24#include <linux/platform_data/tegra_bpc_mgmt.h>
25
26#include <mach/edp.h>
27
28static irqreturn_t tegra_bpc_mgmt_bh(int irq, void *data)
29{
30 int gpio_val = 0;
31 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
32 bpc_platform_data = (struct tegra_bpc_mgmt_platform_data *)data;
33
34 tegra_system_edp_alarm(true);
35 /**
36 * Keep on checking whether event has passed or not.
37 */
38 while (!gpio_val) {
39 set_current_state(TASK_INTERRUPTIBLE);
40 schedule_timeout(msecs_to_jiffies(
41 bpc_platform_data->bpc_mgmt_timeout));
42
43 gpio_val = gpio_get_value(bpc_platform_data->gpio_trigger);
44 }
45
46 tegra_system_edp_alarm(false);
47
48 return IRQ_HANDLED;
49}
50
51static irqreturn_t tegra_bpc_mgmt_isr(int irq, void *data)
52{
53 tegra_edp_throttle_cpu_now(2);
54 return IRQ_WAKE_THREAD;
55}
56
57static __devinit int tegra_bpc_mgmt_probe(struct platform_device *pdev)
58{
59 u32 ret;
60 struct task_struct *bh_thread;
61 struct irq_desc *bat_desc;
62 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
63 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
64
65 bpc_platform_data = pdev->dev.platform_data;
66 if (!bpc_platform_data)
67 return -ENODEV;
68
69 if (gpio_is_valid(bpc_platform_data->gpio_trigger)) {
70 ret = gpio_request(bpc_platform_data->gpio_trigger,
71 "tegra-bpc-mgmt");
72
73 if (ret < 0) {
74 pr_err("BPC: GPIO request failed");
75 return -ENODEV;
76 }
77 } else {
78 pr_err("BPC: GPIO check failed, gpio %d",
79 bpc_platform_data->gpio_trigger);
80 return -ENODEV;
81 }
82
83 gpio_direction_input(bpc_platform_data->gpio_trigger);
84
85 ret = request_threaded_irq(
86 gpio_to_irq(bpc_platform_data->gpio_trigger),
87 tegra_bpc_mgmt_isr,
88 tegra_bpc_mgmt_bh, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
89 "tegra-bpc-mgmt", bpc_platform_data);
90 if (ret < 0) {
91 pr_err("BPC:IRQ Installation failed\n");
92 return -ENODEV;
93 }
94 bat_desc = irq_to_desc(
95 gpio_to_irq(bpc_platform_data->gpio_trigger));
96
97 if (bat_desc) {
98 bh_thread = bat_desc->action->thread;
99 if (bh_thread)
100 sched_setscheduler_nocheck(bh_thread,
101 SCHED_FIFO, &param);
102 }
103
104 return 0;
105}
106
107static __devexit int tegra_bpc_mgmt_remove(struct platform_device *pdev)
108{
109 struct tegra_bpc_mgmt_platform_data *bpc_platform_data;
110 bpc_platform_data = pdev->dev.platform_data;
111 free_irq(gpio_to_irq(bpc_platform_data->gpio_trigger), NULL);
112 return 0;
113}
114
115static struct platform_driver tegra_bpc_mgmt_driver = {
116 .probe = tegra_bpc_mgmt_probe,
117 .remove = tegra_bpc_mgmt_remove,
118 .driver = {
119 .name = "tegra-bpc-mgmt",
120 .owner = THIS_MODULE,
121 },
122};
123
124static int __init tegra_bpc_mgmt_init(void)
125{
126 return platform_driver_register(&tegra_bpc_mgmt_driver);
127}
128
129static void __exit tegra_bpc_mgmt_exit(void)
130{
131 platform_driver_unregister(&tegra_bpc_mgmt_driver);
132}
133
134module_init(tegra_bpc_mgmt_init);
135module_exit(tegra_bpc_mgmt_exit);
136
137MODULE_DESCRIPTION("TEGRA Battery Peak current Management");
138MODULE_AUTHOR("NVIDIA");
139MODULE_LICENSE("GPL");
diff --git a/drivers/power/tps80031-charger.c b/drivers/power/tps80031-charger.c
new file mode 100644
index 00000000000..93b283e0b04
--- /dev/null
+++ b/drivers/power/tps80031-charger.c
@@ -0,0 +1,476 @@
1/*
2 * drivers/power/tps80031_charger.c
3 *
4 * Battery charger driver for TI's tps80031
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22#include <linux/kernel.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/err.h>
26#include <linux/slab.h>
27#include <linux/platform_device.h>
28#include <linux/regulator/driver.h>
29#include <linux/regulator/machine.h>
30#include <linux/mfd/tps80031.h>
31#include <linux/tps80031-charger.h>
32
33#define CONTROLLER_CTRL1 0xe1
34#define CONTROLLER_STAT1 0xe3
35#define CHARGERUSB_CTRL2 0xe9
36#define CHARGERUSB_CTRL3 0xea
37#define CHARGERUSB_VOREG 0xec
38#define CHARGERUSB_VICHRG 0xed
39#define CHARGERUSB_CINLIMIT 0xee
40#define CHARGERUSB_CTRLLIMIT2 0xf0
41#define CHARGERUSB_CTRLLIMIT1 0xef
42#define CHARGERUSB_VICHRG_PC 0xdd
43#define CONTROLLER_WDG 0xe2
44#define LINEAR_CHRG_STS 0xde
45
46#define TPS80031_VBUS_DET BIT(2)
47#define TPS80031_VAC_DET BIT(3)
48
49struct tps80031_charger {
50 int max_charge_current_mA;
51 int max_charge_volt_mV;
52 struct device *dev;
53 struct regulator_dev *rdev;
54 struct regulator_desc reg_desc;
55 struct regulator_init_data reg_init_data;
56 struct tps80031_charger_platform_data *pdata;
57 int (*board_init)(void *board_data);
58 void *board_data;
59 int irq_base;
60 int watch_time_sec;
61 enum charging_states state;
62 int charging_term_current_mA;
63 charging_callback_t charger_cb;
64 void *charger_cb_data;
65};
66
67static struct tps80031_charger *charger_data;
68static uint8_t charging_current_val_code[] = {
69 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x27,
70 0x37, 0x28, 0x38, 0x29, 0x39, 0x2A, 0x3A, 0x2B, 0x3B, 0x2C,
71 0x3C, 0x2D, 0x3D, 0x2E,
72};
73
74static int set_charge_current_limit(struct regulator_dev *rdev,
75 int min_uA, int max_uA)
76{
77 struct tps80031_charger *charger = rdev_get_drvdata(rdev);
78 int max_vbus_current = 1500;
79 int max_charge_current = 1500;
80 int ret;
81
82 dev_info(charger->dev, "%s(): Min curr %dmA and max current %dmA\n",
83 __func__, min_uA/1000, max_uA/1000);
84
85 if (!max_uA) {
86 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
87 CONTROLLER_CTRL1, 0x0);
88 if (ret < 0)
89 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
90 __func__, CONTROLLER_CTRL1);
91
92 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
93 CONTROLLER_WDG, 0x0);
94 if (ret < 0)
95 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
96 __func__, CONTROLLER_WDG);
97 charger->state = charging_state_charging_stopped;
98 if (charger->charger_cb)
99 charger->charger_cb(charger->state,
100 charger->charger_cb_data);
101 return ret;
102 }
103
104 max_vbus_current = min(max_uA/1000, max_vbus_current);
105 max_vbus_current = max_vbus_current/50;
106 if (max_vbus_current)
107 max_vbus_current--;
108 ret = tps80031_update(charger->dev->parent, SLAVE_ID2,
109 CHARGERUSB_CINLIMIT,
110 charging_current_val_code[max_vbus_current], 0x3F);
111 if (ret < 0) {
112 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
113 __func__, CHARGERUSB_CINLIMIT);
114 return ret;
115 }
116
117 max_charge_current = min(max_uA/1000, max_charge_current);
118 if (max_charge_current <= 300)
119 max_charge_current = 0;
120 else if ((max_charge_current > 300) && (max_charge_current <= 500))
121 max_charge_current = (max_charge_current - 300)/50;
122 else
123 max_charge_current = (max_charge_current - 500) / 100 + 4;
124 ret = tps80031_update(charger->dev->parent, SLAVE_ID2,
125 CHARGERUSB_VICHRG, (uint8_t)max_charge_current, 0xF);
126 if (ret < 0) {
127 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
128 __func__, CHARGERUSB_VICHRG);
129 return ret;
130 }
131
132 /* Enable watchdog timer */
133 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
134 CONTROLLER_WDG, charger->watch_time_sec);
135 if (ret < 0) {
136 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
137 __func__, CONTROLLER_WDG);
138 return ret;
139 }
140
141 /* Enable the charging */
142 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
143 CONTROLLER_CTRL1, 0x30);
144 if (ret < 0) {
145 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
146 __func__, CONTROLLER_CTRL1);
147 return ret;
148 }
149 charger->state = charging_state_charging_in_progress;
150 if (charger->charger_cb)
151 charger->charger_cb(charger->state,
152 charger->charger_cb_data);
153 return 0;
154}
155
156static struct regulator_ops tegra_regulator_ops = {
157 .set_current_limit = set_charge_current_limit,
158};
159
160int register_charging_state_callback(charging_callback_t cb, void *args)
161{
162 struct tps80031_charger *charger = charger_data;
163 if (!charger_data)
164 return -ENODEV;
165
166 charger->charger_cb = cb;
167 charger->charger_cb_data = args;
168 return 0;
169}
170EXPORT_SYMBOL_GPL(register_charging_state_callback);
171
172static int configure_charging_parameter(struct tps80031_charger *charger)
173{
174 int ret;
175 int max_charge_current;
176 int max_charge_volt;
177 int term_current;
178
179 /* Disable watchdog timer */
180 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
181 CONTROLLER_WDG, 0x0);
182 if (ret < 0) {
183 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
184 __func__, CONTROLLER_WDG);
185 return ret;
186 }
187
188 /* Disable the charging if any */
189 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
190 CONTROLLER_CTRL1, 0x0);
191 if (ret < 0) {
192 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
193 __func__, CONTROLLER_CTRL1);
194 return ret;
195 }
196
197 if (charger->board_init) {
198 ret = charger->board_init(charger->board_data);
199 if (ret < 0) {
200 dev_err(charger->dev, "%s(): Failed in board init\n",
201 __func__);
202 return ret;
203 }
204 }
205
206 /* Unlock value */
207 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
208 CHARGERUSB_CTRLLIMIT2, 0);
209 if (ret < 0) {
210 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
211 __func__, CHARGERUSB_CTRLLIMIT2);
212 return ret;
213 }
214
215 /* Set max current limit */
216 max_charge_current = min(1500, charger->max_charge_current_mA);
217 if (max_charge_current < 100)
218 max_charge_current = 0;
219 else
220 max_charge_current = (max_charge_current - 100)/100;
221 max_charge_current &= 0xF;
222 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
223 CHARGERUSB_CTRLLIMIT2, (uint8_t)max_charge_current);
224 if (ret < 0) {
225 dev_err(charger->dev, "%s(): Failed in writing register "
226 "0x%02x\n", __func__, CHARGERUSB_CTRLLIMIT2);
227 return ret;
228 }
229
230 /* Set max voltage limit */
231 max_charge_volt = min(4760, charger->max_charge_volt_mV);
232 max_charge_volt = max(3500, max_charge_volt);
233 max_charge_volt -= 3500;
234 max_charge_volt = max_charge_volt/20;
235 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
236 CHARGERUSB_CTRLLIMIT1, (uint8_t)max_charge_volt);
237 if (ret < 0) {
238 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
239 __func__, CHARGERUSB_CTRLLIMIT1);
240 return ret;
241 }
242
243 /* Lock value */
244 ret = tps80031_set_bits(charger->dev->parent, SLAVE_ID2,
245 CHARGERUSB_CTRLLIMIT2, (1 << 4));
246 if (ret < 0) {
247 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
248 __func__, CHARGERUSB_CTRLLIMIT2);
249 return ret;
250 }
251
252 /* set Pre Charge current to 400mA */
253 ret = tps80031_write(charger->dev->parent, SLAVE_ID2, 0xDE, 0x3);
254 if (ret < 0) {
255 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
256 __func__, 0xDD);
257 return ret;
258 }
259
260 /* set charging termination current*/
261 if (charger->charging_term_current_mA > 400)
262 term_current = 7;
263 else
264 term_current = (charger->charging_term_current_mA - 50)/50;
265 term_current = term_current << 5;
266 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
267 CHARGERUSB_CTRL2, term_current);
268 if (ret < 0) {
269 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
270 __func__, CHARGERUSB_CTRL2);
271 return ret;
272 }
273
274 return 0;
275}
276
277static irqreturn_t linch_status_isr(int irq, void *dev_id)
278{
279 struct tps80031_charger *charger = dev_id;
280 uint8_t linch_status;
281 int ret;
282 dev_info(charger->dev, "%s() got called\n", __func__);
283
284 ret = tps80031_read(charger->dev->parent, SLAVE_ID2,
285 LINEAR_CHRG_STS, &linch_status);
286 if (ret < 0) {
287 dev_err(charger->dev, "%s(): Failed in reading register 0x%02x\n",
288 __func__, LINEAR_CHRG_STS);
289 } else {
290 dev_info(charger->dev, "%s():The status of LINEAR_CHRG_STS is 0x%02x\n",
291 __func__, linch_status);
292 if (linch_status & 0x20) {
293 charger->state = charging_state_charging_completed;
294 if (charger->charger_cb)
295 charger->charger_cb(charger->state,
296 charger->charger_cb_data);
297 }
298 }
299
300 return IRQ_HANDLED;
301}
302
303static irqreturn_t watchdog_expire_isr(int irq, void *dev_id)
304{
305 struct tps80031_charger *charger = dev_id;
306 int ret;
307
308 dev_info(charger->dev, "%s()\n", __func__);
309 if (charger->state != charging_state_charging_in_progress)
310 return IRQ_HANDLED;
311
312 /* Enable watchdog timer again*/
313 ret = tps80031_write(charger->dev->parent, SLAVE_ID2, CONTROLLER_WDG,
314 charger->watch_time_sec);
315 if (ret < 0)
316 dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
317 __func__, CONTROLLER_WDG);
318
319 /* Rewrite to enable the charging */
320 if (!ret) {
321 ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
322 CONTROLLER_CTRL1, 0x30);
323 if (ret < 0)
324 dev_err(charger->dev, "%s(): Failed in writing "
325 "register 0x%02x\n",
326 __func__, CONTROLLER_CTRL1);
327 }
328 return IRQ_HANDLED;
329}
330
331static int tps80031_charger_probe(struct platform_device *pdev)
332{
333 int ret = 0;
334 struct device *dev = &pdev->dev;
335 struct tps80031_charger *charger;
336 struct tps80031_charger_platform_data *pdata = pdev->dev.platform_data;
337
338 dev_info(dev, "%s()\n", __func__);
339
340 if (!pdata) {
341 dev_err(dev, "%s() No platform data, exiting..\n", __func__);
342 return -ENODEV;
343 }
344
345 if (!pdata->num_consumer_supplies) {
346 dev_err(dev, "%s() No consumer supply list, exiting..\n",
347 __func__);
348 return -ENODEV;
349 }
350
351 charger = kzalloc(sizeof(*charger), GFP_KERNEL);
352 if (!charger) {
353 dev_err(dev, "failed to allocate memory status\n");
354 return -ENOMEM;
355 }
356
357 charger->dev = &pdev->dev;
358
359 charger->max_charge_current_mA = (pdata->max_charge_current_mA) ?
360 pdata->max_charge_current_mA : 1000;
361 charger->max_charge_volt_mV = (pdata->max_charge_volt_mV) ?
362 pdata->max_charge_volt_mV : 4200;
363 charger->irq_base = pdata->irq_base;
364 charger->watch_time_sec = min(pdata->watch_time_sec, 127);
365 if (!charger->watch_time_sec)
366 charger->watch_time_sec = 127;
367 charger->charging_term_current_mA =
368 min(50, pdata->charging_term_current_mA);
369 if (charger->charging_term_current_mA < 50)
370 charger->charging_term_current_mA = 50;
371
372 charger->reg_desc.name = "vbus_charger";
373 charger->reg_desc.id = pdata->regulator_id;
374 charger->reg_desc.ops = &tegra_regulator_ops;
375 charger->reg_desc.type = REGULATOR_CURRENT;
376 charger->reg_desc.owner = THIS_MODULE;
377
378 charger->reg_init_data.supply_regulator = NULL;
379 charger->reg_init_data.num_consumer_supplies =
380 pdata->num_consumer_supplies;
381 charger->reg_init_data.consumer_supplies = pdata->consumer_supplies;
382 charger->reg_init_data.regulator_init = NULL;
383 charger->reg_init_data.driver_data = charger;
384 charger->reg_init_data.constraints.name = "vbus_charger";
385 charger->reg_init_data.constraints.min_uA = 0;
386 charger->reg_init_data.constraints.max_uA =
387 pdata->max_charge_current_mA * 1000;
388 charger->reg_init_data.constraints.valid_modes_mask =
389 REGULATOR_MODE_NORMAL |
390 REGULATOR_MODE_STANDBY;
391 charger->reg_init_data.constraints.valid_ops_mask =
392 REGULATOR_CHANGE_MODE |
393 REGULATOR_CHANGE_STATUS |
394 REGULATOR_CHANGE_CURRENT;
395
396 charger->board_init = pdata->board_init;
397 charger->board_data = pdata->board_data;
398 charger->state = charging_state_idle;
399
400 charger->rdev = regulator_register(&charger->reg_desc, &pdev->dev,
401 &charger->reg_init_data, charger);
402 if (IS_ERR(charger->rdev)) {
403 dev_err(&pdev->dev, "failed to register %s\n",
404 charger->reg_desc.name);
405 ret = PTR_ERR(charger->rdev);
406 goto regulator_fail;
407 }
408
409 ret = request_threaded_irq(charger->irq_base + TPS80031_INT_LINCH_GATED,
410 NULL, linch_status_isr, 0, "tps80031-linch", charger);
411 if (ret) {
412 dev_err(&pdev->dev, "Unable to register irq %d; error %d\n",
413 charger->irq_base + TPS80031_INT_LINCH_GATED, ret);
414 goto irq_linch_fail;
415 }
416
417 ret = request_threaded_irq(charger->irq_base + TPS80031_INT_FAULT_WDG,
418 NULL, watchdog_expire_isr, 0, "tps80031-wdg", charger);
419 if (ret) {
420 dev_err(&pdev->dev, "Unable to register irq %d; error %d\n",
421 charger->irq_base + TPS80031_INT_FAULT_WDG, ret);
422 goto irq_wdg_fail;
423 }
424
425 ret = configure_charging_parameter(charger);
426 if (ret)
427 goto config_fail;
428
429 dev_set_drvdata(&pdev->dev, charger);
430 charger_data = charger;
431 return ret;
432
433config_fail:
434 free_irq(charger->irq_base + TPS80031_INT_FAULT_WDG, charger);
435irq_wdg_fail:
436 free_irq(charger->irq_base + TPS80031_INT_LINCH_GATED, charger);
437irq_linch_fail:
438 regulator_unregister(charger->rdev);
439regulator_fail:
440 kfree(charger);
441 return ret;
442}
443
444static int tps80031_charger_remove(struct platform_device *pdev)
445{
446 struct tps80031_charger *charger = dev_get_drvdata(&pdev->dev);
447
448 regulator_unregister(charger->rdev);
449 kfree(charger);
450 return 0;
451}
452
453static struct platform_driver tps80031_charger_driver = {
454 .driver = {
455 .name = "tps80031-charger",
456 .owner = THIS_MODULE,
457 },
458 .probe = tps80031_charger_probe,
459 .remove = tps80031_charger_remove,
460};
461
462static int __init tps80031_charger_init(void)
463{
464 return platform_driver_register(&tps80031_charger_driver);
465}
466
467static void __exit tps80031_charger_exit(void)
468{
469 platform_driver_unregister(&tps80031_charger_driver);
470}
471
472subsys_initcall(tps80031_charger_init);
473module_exit(tps80031_charger_exit);
474
475MODULE_LICENSE("GPL");
476MODULE_DESCRIPTION("tps80031 battery charger driver");
diff --git a/drivers/power/tps80031_battery_gauge.c b/drivers/power/tps80031_battery_gauge.c
new file mode 100644
index 00000000000..9ccfaad4144
--- /dev/null
+++ b/drivers/power/tps80031_battery_gauge.c
@@ -0,0 +1,606 @@
1/*
2 * drivers/power/tps80031_battery_gauge.c
3 *
4 * Gas Gauge driver for TI's tps80031
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22#include <linux/kernel.h>
23#include <linux/platform_device.h>
24#include <linux/regulator/driver.h>
25#include <linux/err.h>
26#include <linux/regulator/machine.h>
27#include <linux/mutex.h>
28
29#include <linux/module.h>
30#include <linux/param.h>
31#include <linux/jiffies.h>
32#include <linux/workqueue.h>
33#include <linux/pm.h>
34#include <linux/i2c.h>
35#include <linux/slab.h>
36#include <linux/platform_device.h>
37#include <linux/power_supply.h>
38
39#include <linux/mfd/core.h>
40#include <linux/mfd/tps80031.h>
41#include <linux/tps80031-charger.h>
42
43#define CHARGERUSB_CINLIMIT 0xee
44#define CONTROLLER_STAT1 0xe3
45#define LINEAR_CHARGE_STS 0xde
46#define STS_HW_CONDITIONS 0x21
47#define TOGGLE1 0x90
48#define TOGGLE1_FGS BIT(5)
49#define TOGGLE1_GPADCR BIT(1)
50#define GPCH0_LSB 0x3b
51#define GPCH0_MSB 0x3c
52#define GPCH0_MSB_COLLISION_GP BIT(4)
53#define GPSELECT_ISB 0x35
54#define GPADC_CTRL 0x2e
55#define MISC1 0xe4
56#define CTRL_P1 0x36
57#define CTRL_P1_SP1 BIT(3)
58#define CTRL_P1_EOCRT BIT(2)
59#define CTRL_P1_EOCP1 BIT(1)
60#define CTRL_P1_BUSY BIT(0)
61#define FG_REG_00 0xc0
62#define FG_REG_00_CC_CAL_EN BIT(1)
63#define FG_REG_00_CC_AUTOCLEAR BIT(2)
64#define FG_REG_01 0xc1 /* CONV_NR (unsigned) 0 - 7 */
65#define FG_REG_02 0xc2 /* CONV_NR (unsigned) 8 - 15 */
66#define FG_REG_03 0xc3 /* CONV_NR (unsigned) 16 - 23 */
67#define FG_REG_04 0xc4 /* ACCM (signed) 0 - 7 */
68#define FG_REG_05 0xc5 /* ACCM (signed) 8 - 15 */
69#define FG_REG_06 0xc6 /* ACCM (signed) 16 - 23 */
70#define FG_REG_07 0xc7 /* ACCM (signed) 24 - 31 */
71#define FG_REG_08 0xc8 /* OFFSET (signed) 0 - 7 */
72#define FG_REG_09 0xc9 /* OFFSET (signed) 8 - 9 */
73#define FG_REG_10 0xca /* LAST_READ (signed) 0 - 7 */
74#define FG_REG_11 0xcb /* LAST_READ (signed) 8 - 13 */
75
76#define TPS80031_VBUS_DET BIT(2)
77#define TPS80031_VAC_DET BIT(3)
78#define TPS80031_STS_VYSMIN_HI BIT(4)
79#define END_OF_CHARGE BIT(5)
80
81#define DRIVER_VERSION "1.1.0"
82#define BATTERY_POLL_PERIOD 30000
83
84static int tps80031_temp_table[] = {
85 /* adc code for temperature in degree C */
86 929, 925, /* -2, -1 */
87 920, 917, 912, 908, 904, 899, 895, 890, 885, 880, /* 00 - 09 */
88 875, 869, 864, 858, 853, 847, 841, 835, 829, 823, /* 10 - 19 */
89 816, 810, 804, 797, 790, 783, 776, 769, 762, 755, /* 20 - 29 */
90 748, 740, 732, 725, 718, 710, 703, 695, 687, 679, /* 30 - 39 */
91 671, 663, 655, 647, 639, 631, 623, 615, 607, 599, /* 40 - 49 */
92 591, 583, 575, 567, 559, 551, 543, 535, 527, 519, /* 50 - 59 */
93 511, 504, 496 /* 60 - 62 */
94};
95
96struct tps80031_device_info {
97 struct device *dev;
98 struct i2c_client *client;
99 struct power_supply bat;
100 struct power_supply ac;
101 struct power_supply usb;
102 struct timer_list battery_poll_timer;
103 uint32_t vsys;
104 uint8_t usb_online;
105 uint8_t ac_online;
106 uint8_t usb_status;
107 uint8_t capacity_sts;
108 uint8_t health;
109 uint8_t sys_vlow_intr;
110 uint8_t fg_calib_intr;
111 int16_t fg_offset;
112 struct mutex adc_lock;
113};
114
115static enum power_supply_property tps80031_bat_props[] = {
116 POWER_SUPPLY_PROP_TECHNOLOGY,
117 POWER_SUPPLY_PROP_VOLTAGE_NOW,
118 POWER_SUPPLY_PROP_TEMP,
119 POWER_SUPPLY_PROP_CAPACITY,
120 POWER_SUPPLY_PROP_HEALTH,
121 POWER_SUPPLY_PROP_STATUS,
122 POWER_SUPPLY_PROP_CHARGE_NOW,
123 POWER_SUPPLY_PROP_CHARGE_COUNTER,
124};
125
126static enum power_supply_property tps80031_usb_props[] = {
127 POWER_SUPPLY_PROP_ONLINE,
128};
129
130static enum power_supply_property tps80031_ac_props[] = {
131 POWER_SUPPLY_PROP_ONLINE,
132};
133
134static int tps80031_reg_read(struct tps80031_device_info *di, int sid, int reg,
135 uint8_t *val)
136{
137 int ret;
138
139 ret = tps80031_read(di->dev->parent, sid, reg, val);
140 if (ret < 0)
141 dev_err(di->dev, "Failed read register 0x%02x\n",
142 reg);
143 return ret;
144}
145
146static int tps80031_reg_write(struct tps80031_device_info *di, int sid, int reg,
147 uint8_t val)
148{
149 int ret;
150
151 ret = tps80031_write(di->dev->parent, sid, reg, val);
152 if (ret < 0)
153 dev_err(di->dev, "Failed write register 0x%02x\n",
154 reg);
155 return ret;
156}
157
158static int tps80031_battery_capacity(struct tps80031_device_info *di,
159 union power_supply_propval *val)
160{
161 uint8_t hwsts;
162 int ret;
163
164 ret = tps80031_reg_read(di, SLAVE_ID2, LINEAR_CHARGE_STS, &hwsts);
165 if (ret < 0)
166 return ret;
167
168 di->capacity_sts = di->vsys;
169 if (hwsts & END_OF_CHARGE)
170 di->capacity_sts = 100;
171
172 if (di->sys_vlow_intr) {
173 di->capacity_sts = 10;
174 di->sys_vlow_intr = 0;
175 }
176
177 if (di->capacity_sts <= 10)
178 di->health = POWER_SUPPLY_HEALTH_DEAD;
179 else
180 di->health = POWER_SUPPLY_HEALTH_GOOD;
181
182 return di->capacity_sts;
183}
184
185static int tps80031_battery_voltage(struct tps80031_device_info *di,
186 union power_supply_propval *val)
187{
188 int voltage;
189
190 voltage = tps80031_gpadc_conversion(SYSTEM_SUPPLY);
191 if (voltage < 0)
192 return voltage;
193 voltage = ((voltage * 1000) / 4) * 5;
194
195 if (voltage < 3700000)
196 di->vsys = 10;
197 else if (voltage > 3700000 && voltage <= 3800000)
198 di->vsys = 20;
199 else if (voltage > 3800000 && voltage <= 3900000)
200 di->vsys = 50;
201 else if (voltage > 3900000 && voltage <= 4000000)
202 di->vsys = 75;
203 else if (voltage >= 4000000)
204 di->vsys = 90;
205
206 return voltage;
207}
208
209static int tps80031_battery_charge_now(struct tps80031_device_info *di,
210 union power_supply_propval *val)
211{
212 int charge;
213
214 charge = tps80031_gpadc_conversion(BATTERY_CHARGING_CURRENT);
215 if (charge < 0)
216 return charge;
217 charge = charge * 78125 / 40;
218
219 return charge;
220}
221
222static int tps80031_battery_charge_counter(struct tps80031_device_info *di,
223 union power_supply_propval *val)
224{
225 int retval, ret;
226 uint32_t cnt_byte;
227 uint32_t acc_byte;
228
229 /* check if calibrated */
230 if (di->fg_calib_intr == 0)
231 return 0;
232
233 /* get current accumlator */
234 ret = tps80031_reads(di->dev->parent, SLAVE_ID2, FG_REG_04, 4,
235 (uint8_t *) &acc_byte);
236 if (ret < 0)
237 return ret;
238 /* counter value is mAs, need report uAh */
239 retval = (int32_t) acc_byte / 18 * 5;
240
241 /* get counter */
242 ret = tps80031_reads(di->dev->parent, SLAVE_ID2, FG_REG_01, 3,
243 (uint8_t *) &cnt_byte);
244 if (ret < 0)
245 return ret;
246 /* we need calibrate the offset current in uAh*/
247 retval = retval - (di->fg_offset / 4 * cnt_byte);
248
249 /* @todo, counter value will overflow if battery get continuously
250 * charged discharged for more than 108Ah using 250mS integration
251 * period althrough it is hightly impossible.
252 */
253
254 return retval;
255}
256
257static int tps80031_battery_temp(struct tps80031_device_info *di,
258 union power_supply_propval *val)
259{
260 int adc_code, temp;
261
262 adc_code = tps80031_gpadc_conversion(BATTERY_TEMPERATURE);
263 if (adc_code < 0)
264 return adc_code;
265
266 for (temp = 0; temp < ARRAY_SIZE(tps80031_temp_table); temp++) {
267 if (adc_code >= tps80031_temp_table[temp])
268 break;
269 }
270 /* first 2 values are for negative temperature */
271 val->intval = (temp - 2) * 10; /* in tenths of degree Celsius */
272
273 return val->intval;
274}
275
276#define to_tps80031_device_info_bat(x) container_of((x), \
277 struct tps80031_device_info, bat);
278
279static int tps80031_bat_get_property(struct power_supply *psy,
280 enum power_supply_property psp, union power_supply_propval *val)
281{
282 struct tps80031_device_info *di = to_tps80031_device_info_bat(psy);
283
284 switch (psp) {
285
286 case POWER_SUPPLY_PROP_TECHNOLOGY:
287 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
288 break;
289
290 case POWER_SUPPLY_PROP_HEALTH:
291 val->intval = di->health;
292 break;
293
294 case POWER_SUPPLY_PROP_CAPACITY:
295 val->intval = tps80031_battery_capacity(di, val);
296 break;
297
298 case POWER_SUPPLY_PROP_CHARGE_NOW:
299 val->intval = tps80031_battery_charge_now(di, val);
300 break;
301
302 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
303 val->intval = tps80031_battery_voltage(di, val);
304 break;
305
306 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
307 val->intval = tps80031_battery_charge_counter(di, val);
308 break;
309
310 case POWER_SUPPLY_PROP_STATUS:
311 val->intval = di->usb_status;
312 break;
313
314 case POWER_SUPPLY_PROP_TEMP:
315 val->intval = tps80031_battery_temp(di, val);
316 break;
317
318 default:
319 return -EINVAL;
320 }
321 return 0;
322}
323
324#define to_tps80031_device_info_usb(x) container_of((x), \
325 struct tps80031_device_info, usb);
326
327static int tps80031_usb_get_property(struct power_supply *psy,
328 enum power_supply_property psp, union power_supply_propval *val)
329{
330 struct tps80031_device_info *di = to_tps80031_device_info_usb(psy);
331
332 switch (psp) {
333 case POWER_SUPPLY_PROP_ONLINE:
334 val->intval = di->usb_online;
335 break;
336 default:
337 return -EINVAL;
338 }
339 return 0;
340}
341
342#define to_tps80031_device_info_ac(x) container_of((x), \
343 struct tps80031_device_info, ac);
344
345static int tps80031_ac_get_property(struct power_supply *psy,
346 enum power_supply_property psp, union power_supply_propval *val)
347{
348 struct tps80031_device_info *di = to_tps80031_device_info_ac(psy);
349
350 switch (psp) {
351 case POWER_SUPPLY_PROP_ONLINE:
352 val->intval = di->ac_online;
353 break;
354 default:
355 return -EINVAL;
356 }
357 return 0;
358}
359
360static irqreturn_t tps80031_sys_vlow(int irq, void *data)
361{
362 struct tps80031_device_info *di = data;
363
364 di->sys_vlow_intr = 1;
365 power_supply_changed(&di->bat);
366 return IRQ_HANDLED;
367}
368
369static irqreturn_t tps80031_fg_calibrated(int irq, void *data)
370{
371 struct tps80031_device_info *di = data;
372 uint8_t acc_byte0;
373 uint8_t acc_byte1;
374 int ret;
375
376 ret = tps80031_reg_read(di, SLAVE_ID2, FG_REG_08, &acc_byte0);
377 if (ret < 0)
378 return IRQ_HANDLED;
379 ret = tps80031_reg_read(di, SLAVE_ID2, FG_REG_09, &acc_byte1);
380 if (ret < 0)
381 return IRQ_HANDLED;
382 /* sign extension */
383 if (acc_byte1 & 0x02)
384 acc_byte1 = acc_byte1 | 0xFC;
385 else
386 acc_byte1 = acc_byte1 & 0x03;
387
388 di->fg_offset = (int16_t) ((acc_byte1 << 8) | acc_byte0);
389 /* fuel gauge auto calibration finished */
390 di->fg_calib_intr = 1;
391 return IRQ_HANDLED;
392}
393
394static int tps80031_fg_start_gas_gauge(struct tps80031_device_info *di)
395{
396 int ret = 0;
397 di->fg_calib_intr = 0;
398
399 /* start gas gauge */
400 ret = tps80031_reg_write(di, SLAVE_ID2, TOGGLE1, 0x20);
401 if (ret < 0)
402 return ret;
403 /* set ADC update time to 3.9ms and start calibration */
404 ret = tps80031_reg_write(di, SLAVE_ID2, FG_REG_00, FG_REG_00_CC_CAL_EN);
405 if (ret < 0)
406 return ret;
407 return ret;
408}
409
410void tps80031_battery_status(enum charging_states status, void *data)
411{
412 struct tps80031_device_info *di = data;
413 int ret;
414 uint8_t retval;
415
416 if ((status == charging_state_charging_in_progress)) {
417 di->usb_status = POWER_SUPPLY_STATUS_CHARGING;
418 di->health = POWER_SUPPLY_HEALTH_GOOD;
419 ret = tps80031_reg_read(di, SLAVE_ID2,
420 CHARGERUSB_CINLIMIT, &retval);
421 if (ret < 0) {
422 di->ac_online = 0;
423 di->usb_online = 0;
424 }
425 if (retval == 0x9) {
426 di->ac_online = 0;
427 di->usb_online = 1;
428 } else {
429 di->usb_online = 0;
430 di->ac_online = 1;
431 }
432 } else if (status == charging_state_charging_stopped) {
433 di->usb_status = POWER_SUPPLY_STATUS_DISCHARGING;
434 di->ac_online = 0;
435 di->usb_online = 0;
436 }
437 power_supply_changed(&di->usb);
438 power_supply_changed(&di->bat);
439 power_supply_changed(&di->ac);
440}
441
442static void battery_poll_timer_func(unsigned long pdi)
443{
444 struct tps80031_device_info *di = (void *)pdi;
445 power_supply_changed(&di->bat);
446 mod_timer(&di->battery_poll_timer,
447 jiffies + msecs_to_jiffies(BATTERY_POLL_PERIOD));
448}
449
450static int tps80031_battery_probe(struct platform_device *pdev)
451{
452 int ret;
453 uint8_t retval;
454 struct device *dev = &pdev->dev;
455 struct tps80031_device_info *di;
456 struct tps80031_bg_platform_data *pdata = pdev->dev.platform_data;
457
458 di = devm_kzalloc(&pdev->dev, sizeof *di, GFP_KERNEL);
459 if (!di) {
460 dev_err(dev->parent, "failed to allocate device info data\n");
461 return -ENOMEM;
462 }
463
464 if (!pdata->battery_present) {
465 dev_err(dev, "%s() No battery detected, exiting..\n",
466 __func__);
467 return -ENODEV;
468 }
469
470 di->dev = &pdev->dev;
471
472 ret = tps80031_reg_read(di, SLAVE_ID2, CONTROLLER_STAT1, &retval);
473 if (ret < 0)
474 return ret;
475
476 if ((retval & TPS80031_VAC_DET) | (retval & TPS80031_VBUS_DET)) {
477 di->usb_status = POWER_SUPPLY_STATUS_CHARGING;
478 di->usb_online = 1;
479 } else {
480 di->usb_status = POWER_SUPPLY_STATUS_DISCHARGING;
481 di->usb_online = 0;
482 }
483
484 di->capacity_sts = 50;
485 di->health = POWER_SUPPLY_HEALTH_GOOD;
486
487 di->bat.name = "tps80031-bat";
488 di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
489 di->bat.properties = tps80031_bat_props;
490 di->bat.num_properties = ARRAY_SIZE(tps80031_bat_props);
491 di->bat.get_property = tps80031_bat_get_property;
492
493 ret = power_supply_register(dev->parent, &di->bat);
494 if (ret) {
495 dev_err(dev->parent, "failed to register bat power supply\n");
496 return ret;
497 }
498
499 di->usb.name = "tps80031-usb";
500 di->usb.type = POWER_SUPPLY_TYPE_USB;
501 di->usb.properties = tps80031_usb_props;
502 di->usb.num_properties = ARRAY_SIZE(tps80031_usb_props);
503 di->usb.get_property = tps80031_usb_get_property;
504
505 ret = power_supply_register(dev->parent, &di->usb);
506 if (ret) {
507 dev_err(dev->parent, "failed to register ac power supply\n");
508 goto power_supply_fail2;
509 }
510
511 di->ac.name = "tps80031-ac";
512 di->ac.type = POWER_SUPPLY_TYPE_MAINS;
513 di->ac.properties = tps80031_ac_props;
514 di->ac.num_properties = ARRAY_SIZE(tps80031_ac_props);
515 di->ac.get_property = tps80031_ac_get_property;
516
517 ret = power_supply_register(dev->parent, &di->ac);
518 if (ret) {
519 dev_err(dev->parent, "failed to register ac power supply\n");
520 goto power_supply_fail1;
521 }
522
523 dev_set_drvdata(&pdev->dev, di);
524
525 ret = register_charging_state_callback(tps80031_battery_status, di);
526 if (ret < 0)
527 goto power_supply_fail0;
528
529 ret = request_threaded_irq(pdata->irq_base + TPS80031_INT_SYS_VLOW,
530 NULL, tps80031_sys_vlow,
531 IRQF_ONESHOT, "tps80031_sys_vlow", di);
532 if (ret < 0) {
533 dev_err(dev->parent, "request IRQ %d fail\n", pdata->irq_base);
534 goto power_supply_fail0;
535 }
536
537 ret = request_threaded_irq(pdata->irq_base + TPS80031_INT_CC_AUTOCAL,
538 NULL, tps80031_fg_calibrated, IRQF_ONESHOT,
539 "tps80031_fuel_gauge_calibration", di);
540 if (ret < 0) {
541 dev_err(dev->parent, "request IRQ %d fail\n", pdata->irq_base);
542 goto irq_fail2;
543 }
544 setup_timer(&di->battery_poll_timer,
545 battery_poll_timer_func, (unsigned long) di);
546 mod_timer(&di->battery_poll_timer,
547 jiffies + msecs_to_jiffies(BATTERY_POLL_PERIOD));
548
549 ret = tps80031_fg_start_gas_gauge(di);
550 if (ret < 0) {
551 dev_err(dev->parent, "failed to start fuel-gauge\n");
552 goto irq_fail1;
553 }
554 dev_info(dev->parent, "support ver. %s enabled\n", DRIVER_VERSION);
555
556 return ret;
557
558irq_fail1:
559 free_irq(pdata->irq_base + TPS80031_INT_CC_AUTOCAL, di);
560irq_fail2:
561 free_irq(pdata->irq_base + TPS80031_INT_SYS_VLOW, di);
562power_supply_fail0:
563 power_supply_unregister(&di->ac);
564power_supply_fail1:
565 power_supply_unregister(&di->usb);
566power_supply_fail2:
567 power_supply_unregister(&di->bat);
568 return ret;
569}
570
571static int tps80031_battery_remove(struct platform_device *pdev)
572{
573 struct tps80031_device_info *di = dev_get_drvdata(&pdev->dev);
574
575 power_supply_unregister(&di->bat);
576 power_supply_unregister(&di->usb);
577 power_supply_unregister(&di->ac);
578
579 return 0;
580}
581
582static struct platform_driver tps80031_battery_driver = {
583 .driver = {
584 .name = "tps80031-battery-gauge",
585 .owner = THIS_MODULE,
586 },
587 .probe = tps80031_battery_probe,
588 .remove = tps80031_battery_remove,
589};
590
591static int __init tps80031_battery_init(void)
592{
593 return platform_driver_register(&tps80031_battery_driver);
594}
595
596static void __exit tps80031_battery_exit(void)
597{
598 platform_driver_unregister(&tps80031_battery_driver);
599}
600
601module_init(tps80031_battery_init);
602module_exit(tps80031_battery_exit);
603
604MODULE_LICENSE("GPL");
605MODULE_AUTHOR("Syed Rafiuddin <srafiuddin@nvidia.com> ");
606MODULE_DESCRIPTION("tps80031 battery gauge driver");