Merge current mainline tree into linux-omap tree
[pandora-kernel.git] / drivers / power / twl4030_bci_battery.c
1 /*
2  * linux/drivers/power/twl4030_bci_battery.c
3  *
4  * OMAP2430/3430 BCI battery driver for Linux
5  *
6  * Copyright (C) 2008 Texas Instruments, Inc.
7  * Author: Texas Instruments, Inc.
8  *
9  * This package 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  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/device.h>
21 #include <linux/interrupt.h>
22 #include <linux/delay.h>
23 #include <linux/platform_device.h>
24 #include <linux/i2c/twl4030.h>
25 #include <linux/power_supply.h>
26 #include <mach/bci.h>
27 #include <linux/i2c/twl4030-madc.h>
28
29 #define T2_BATTERY_VOLT         0x04
30 #define T2_BATTERY_TEMP         0x06
31 #define T2_BATTERY_CUR          0x08
32
33 /* charger constants */
34 #define NO_PW_CONN              0
35 #define AC_PW_CONN              0x01
36 #define USB_PW_CONN             0x02
37
38 /* TWL4030_MODULE_USB */
39 #define REG_POWER_CTRL          0x0AC
40 #define OTG_EN                  0x020
41 #define REG_PHY_CLK_CTRL        0x0FE
42 #define REG_PHY_CLK_CTRL_STS    0x0FF
43 #define PHY_DPLL_CLK            0x01
44
45 #define REG_BCICTL1             0x023
46 #define REG_BCICTL2             0x024
47 #define CGAIN                   0x020
48 #define ITHEN                   0x010
49 #define ITHSENS                 0x007
50
51 /* Boot BCI flag bits */
52 #define BCIAUTOWEN              0x020
53 #define CONFIG_DONE             0x010
54 #define BCIAUTOUSB              0x002
55 #define BCIAUTOAC               0x001
56 #define BCIMSTAT_MASK           0x03F
57
58 /* Boot BCI register */
59 #define REG_BOOT_BCI            0x007
60 #define REG_CTRL1               0x00
61 #define REG_SW1SELECT_MSB       0x07
62 #define SW1_CH9_SEL             0x02
63 #define REG_CTRL_SW1            0x012
64 #define SW1_TRIGGER             0x020
65 #define EOC_SW1                 0x002
66 #define REG_GPCH9               0x049
67 #define REG_STS_HW_CONDITIONS   0x0F
68 #define STS_VBUS                0x080
69 #define STS_CHG                 0x02
70 #define REG_BCIMSTATEC          0x02
71 #define REG_BCIMFSTS4           0x010
72 #define REG_BCIMFSTS2           0x00E
73 #define REG_BCIMFSTS3           0x00F
74 #define REG_BCIMFSTS1           0x001
75 #define USBFASTMCHG             0x004
76 #define BATSTSPCHG              0x004
77 #define BATSTSMCHG              0x040
78 #define VBATOV4                 0x020
79 #define VBATOV3                 0x010
80 #define VBATOV2                 0x008
81 #define VBATOV1                 0x004
82 #define REG_BB_CFG              0x012
83 #define BBCHEN                  0x010
84
85 /* Power supply charge interrupt */
86 #define REG_PWR_ISR1            0x00
87 #define REG_PWR_IMR1            0x01
88 #define REG_PWR_EDR1            0x05
89 #define REG_PWR_SIH_CTRL        0x007
90
91 #define USB_PRES                0x004
92 #define CHG_PRES                0x002
93
94 #define USB_PRES_RISING         0x020
95 #define USB_PRES_FALLING        0x010
96 #define CHG_PRES_RISING         0x008
97 #define CHG_PRES_FALLING        0x004
98 #define AC_STATEC               0x20
99 #define COR                     0x004
100
101 /* interrupt status registers */
102 #define REG_BCIISR1A            0x0
103 #define REG_BCIISR2A            0x01
104
105 /* Interrupt flags bits BCIISR1 */
106 #define BATSTS_ISR1             0x080
107 #define VBATLVL_ISR1            0x001
108
109 /* Interrupt mask registers for int1*/
110 #define REG_BCIIMR1A            0x002
111 #define REG_BCIIMR2A            0x003
112
113  /* Interrupt masks for BCIIMR1 */
114 #define BATSTS_IMR1             0x080
115 #define VBATLVL_IMR1            0x001
116
117 /* Interrupt edge detection register */
118 #define REG_BCIEDR1             0x00A
119 #define REG_BCIEDR2             0x00B
120 #define REG_BCIEDR3             0x00C
121
122 /* BCIEDR2 */
123 #define BATSTS_EDRRISIN         0x080
124 #define BATSTS_EDRFALLING       0x040
125
126 /* BCIEDR3 */
127 #define VBATLVL_EDRRISIN        0x02
128
129 /* Step size and prescaler ratio */
130 #define TEMP_STEP_SIZE          147
131 #define TEMP_PSR_R              100
132
133 #define VOLT_STEP_SIZE          588
134 #define VOLT_PSR_R              100
135
136 #define CURR_STEP_SIZE          147
137 #define CURR_PSR_R1             44
138 #define CURR_PSR_R2             80
139
140 #define BK_VOLT_STEP_SIZE       441
141 #define BK_VOLT_PSR_R           100
142
143 #define ENABLE          1
144 #define DISABLE         1
145
146 /* Ptr to thermistor table */
147 int *therm_tbl;
148
149 static int twl4030_bci_battery_probe(struct platform_device *dev);
150 static int twl4030_bci_battery_remove(struct platform_device *dev);
151 #ifdef CONFIG_PM
152 static int twl4030_bci_battery_suspend(struct platform_device *dev,
153                                         pm_message_t state);
154 static int twl4030_bci_battery_resume(struct platform_device *dev);
155 #endif
156
157 struct twl4030_bci_device_info {
158         struct device           *dev;
159
160         unsigned long           update_time;
161         int                     voltage_uV;
162         int                     bk_voltage_uV;
163         int                     current_uA;
164         int                     temp_C;
165         int                     charge_rsoc;
166         int                     charge_status;
167
168         struct power_supply     bat;
169         struct power_supply     bk_bat;
170         struct delayed_work     twl4030_bci_monitor_work;
171         struct delayed_work     twl4030_bk_bci_monitor_work;
172 };
173
174 static struct platform_driver twl4030_bci_battery_driver = {
175         .probe =        twl4030_bci_battery_probe,
176         .remove =       twl4030_bci_battery_remove,
177 #ifdef CONFIG_PM
178         .suspend =      twl4030_bci_battery_suspend,
179         .resume =       twl4030_bci_battery_resume,
180 #endif
181         .driver = {
182                 .name = "twl4030-bci-battery",
183         },
184 };
185
186 static int usb_charger_flag;
187 static int LVL_1, LVL_2, LVL_3, LVL_4;
188
189 static int read_bci_val(u8 reg_1);
190 static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg);
191 static int twl4030charger_presence(void);
192
193 /*
194  * Report and clear the charger presence event.
195  */
196 static inline int twl4030charger_presence_evt(void)
197 {
198         int ret;
199         u8 chg_sts, set = 0, clear = 0;
200
201         /* read charger power supply status */
202         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &chg_sts,
203                 REG_STS_HW_CONDITIONS);
204         if (ret)
205                 return IRQ_NONE;
206
207         /* If the AC charger have been connected */
208         if (chg_sts & STS_CHG) {
209                 /* configuring falling edge detection for CHG_PRES */
210                 set = CHG_PRES_FALLING;
211                 clear = CHG_PRES_RISING;
212         }
213         /* If the AC charger have been disconnected */
214         else {
215                 /* configuring rising edge detection for CHG_PRES */
216                 set = CHG_PRES_RISING;
217                 clear = CHG_PRES_FALLING;
218         }
219
220         /* Update the interrupt edge detection register */
221         clear_n_set(TWL4030_MODULE_INT, clear, set, REG_PWR_EDR1);
222
223         return 0;
224 }
225
226 /*
227  * Interrupt service routine
228  *
229  * Attends to TWL 4030 power module interruptions events, specifically
230  * USB_PRES (USB charger presence) CHG_PRES (AC charger presence) events
231  *
232  */
233 static irqreturn_t twl4030charger_interrupt(int irq, void *dev_id)
234 {
235         struct twl4030_bci_device_info *di = dev_id;
236
237         twl4030charger_presence_evt();
238         power_supply_changed(&di->bat);
239
240         return IRQ_HANDLED;
241 }
242
243 /*
244  * This function handles the twl4030 battery presence interrupt
245  */
246 static int twl4030battery_presence_evt(void)
247 {
248         int ret;
249         u8 batstsmchg, batstspchg;
250
251         /* check for the battery presence in main charge*/
252         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
253                         &batstsmchg, REG_BCIMFSTS3);
254         if (ret)
255                 return ret;
256
257         /* check for the battery presence in precharge */
258         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PRECHARGE,
259                         &batstspchg, REG_BCIMFSTS1);
260         if (ret)
261                 return ret;
262
263         /*
264          * REVISIT: Physically inserting/removing the batt
265          * does not seem to generate an int on 3430ES2 SDP.
266          */
267
268         /* In case of the battery insertion event */
269         if ((batstspchg & BATSTSPCHG) || (batstsmchg & BATSTSMCHG)) {
270                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_EDRRISIN,
271                         BATSTS_EDRFALLING, REG_BCIEDR2);
272                 if (ret)
273                         return ret;
274         }
275
276         /* In case of the battery removal event */
277         else {
278                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_EDRFALLING,
279                         BATSTS_EDRRISIN, REG_BCIEDR2);
280                 if (ret)
281                         return ret;
282         }
283
284         return 0;
285 }
286
287 /*
288  * This function handles the twl4030 battery voltage level interrupt.
289  */
290 static int twl4030battery_level_evt(void)
291 {
292         int ret;
293         u8 mfst;
294
295         /* checking for threshold event */
296         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
297                         &mfst, REG_BCIMFSTS2);
298         if (ret)
299                 return ret;
300
301         if (mfst & VBATOV4) {
302                 LVL_4 = 1;
303                 LVL_3 = LVL_2 = LVL_1 = 0;
304         } else if (mfst & VBATOV3) {
305                 LVL_3 = 1;
306                 LVL_4 = LVL_2 = LVL_1 = 0;
307         } else if (mfst & VBATOV2) {
308                 LVL_2 = 1;
309                 LVL_4 = LVL_3 = LVL_1 = 0;
310         } else {
311                 LVL_1 = 1;
312                 LVL_4 = LVL_3 = LVL_2 = 0;
313         }
314
315         return 0;
316 }
317
318 /*
319  * Interrupt service routine
320  *
321  * Attends to BCI interruptions events,
322  * specifically BATSTS (battery connection and removal)
323  * VBATOV (main battery voltage threshold) events
324  *
325  */
326 static irqreturn_t twl4030battery_interrupt(int irq, void *dev_id)
327 {
328         int ret;
329         u8 isr1a_val, isr2a_val, clear_2a, clear_1a;
330
331         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr1a_val,
332                                 REG_BCIISR1A);
333         if (ret)
334                 return IRQ_NONE;
335
336         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr2a_val,
337                                 REG_BCIISR2A);
338         if (ret)
339                 return IRQ_NONE;
340
341         clear_2a = (isr2a_val & VBATLVL_ISR1)? (VBATLVL_ISR1): 0;
342         clear_1a = (isr1a_val & BATSTS_ISR1)? (BATSTS_ISR1): 0;
343
344         /* cleaning BCI interrupt status flags */
345         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
346                         clear_1a , REG_BCIISR1A);
347         if (ret)
348                 return IRQ_NONE;
349
350         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
351                         clear_2a , REG_BCIISR2A);
352         if (ret)
353                 return IRQ_NONE;
354
355         /* battery connetion or removal event */
356         if (isr1a_val & BATSTS_ISR1)
357                 twl4030battery_presence_evt();
358         /* battery voltage threshold event*/
359         else if (isr2a_val & VBATLVL_ISR1)
360                 twl4030battery_level_evt();
361         else
362                 return IRQ_NONE;
363
364         return IRQ_HANDLED;
365 }
366
367 /*
368  * Enable/Disable hardware battery level event notifications.
369  */
370 static int twl4030battery_hw_level_en(int enable)
371 {
372         int ret;
373
374         if (enable) {
375                 /* unmask VBATOV interrupt for INT1 */
376                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, VBATLVL_IMR1,
377                         0, REG_BCIIMR2A);
378                 if (ret)
379                         return ret;
380
381                 /* configuring interrupt edge detection for VBATOv */
382                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
383                         VBATLVL_EDRRISIN, REG_BCIEDR3);
384                 if (ret)
385                         return ret;
386         } else {
387                 /* mask VBATOV interrupt for INT1 */
388                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
389                         VBATLVL_IMR1, REG_BCIIMR2A);
390                 if (ret)
391                         return ret;
392         }
393
394         return 0;
395 }
396
397 /*
398  * Enable/disable hardware battery presence event notifications.
399  */
400 static int twl4030battery_hw_presence_en(int enable)
401 {
402         int ret;
403
404         if (enable) {
405                 /* unmask BATSTS interrupt for INT1 */
406                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_IMR1,
407                         0, REG_BCIIMR1A);
408                 if (ret)
409                         return ret;
410
411                 /* configuring interrupt edge for BATSTS */
412                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
413                         BATSTS_EDRRISIN | BATSTS_EDRFALLING, REG_BCIEDR2);
414                 if (ret)
415                         return ret;
416         } else {
417                 /* mask BATSTS interrupt for INT1 */
418                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
419                         BATSTS_IMR1, REG_BCIIMR1A);
420                 if (ret)
421                         return ret;
422         }
423
424         return 0;
425 }
426
427 /*
428  * Enable/Disable AC Charge funtionality.
429  */
430 static int twl4030charger_ac_en(int enable)
431 {
432         int ret;
433
434         if (enable) {
435                 /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 1 */
436                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0,
437                         (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC),
438                         REG_BOOT_BCI);
439                 if (ret)
440                         return ret;
441         } else {
442                 /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 0*/
443                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC,
444                         (CONFIG_DONE | BCIAUTOWEN),
445                         REG_BOOT_BCI);
446                 if (ret)
447                         return ret;
448         }
449         return 0;
450 }
451
452 /*
453  * Enable/Disable USB Charge funtionality.
454  */
455 int twl4030charger_usb_en(int enable)
456 {
457         u8 value;
458         int ret;
459         unsigned long timeout;
460
461         if (enable) {
462                 /* Check for USB charger conneted */
463                 ret = twl4030charger_presence();
464                 if (ret < 0)
465                         return ret;
466
467                 if (!(ret & USB_PW_CONN))
468                         return -ENXIO;
469
470                 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
471                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0,
472                         (CONFIG_DONE | BCIAUTOWEN | BCIAUTOUSB),
473                         REG_BOOT_BCI);
474                 if (ret)
475                         return ret;
476
477                 ret = clear_n_set(TWL4030_MODULE_USB, 0, PHY_DPLL_CLK,
478                         REG_PHY_CLK_CTRL);
479                 if (ret)
480                         return ret;
481
482                 value = 0;
483                 timeout = jiffies + msecs_to_jiffies(50);
484
485                 while ((!(value & PHY_DPLL_CLK)) &&
486                         time_before(jiffies, timeout)) {
487                         udelay(10);
488                         ret = twl4030_i2c_read_u8(TWL4030_MODULE_USB, &value,
489                                 REG_PHY_CLK_CTRL_STS);
490                         if (ret)
491                                 return ret;
492                 }
493
494                 /* OTG_EN (POWER_CTRL[5]) to 1 */
495                 ret = clear_n_set(TWL4030_MODULE_USB, 0, OTG_EN,
496                         REG_POWER_CTRL);
497                 if (ret)
498                         return ret;
499
500                 mdelay(50);
501
502                 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
503                 ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0,
504                         USBFASTMCHG, REG_BCIMFSTS4);
505                 if (ret)
506                         return ret;
507         } else {
508                 twl4030charger_presence();
509                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOUSB,
510                         (CONFIG_DONE | BCIAUTOWEN), REG_BOOT_BCI);
511                 if (ret)
512                         return ret;
513         }
514
515         return 0;
516 }
517
518 /*
519  * Return battery temperature
520  * Or < 0 on failure.
521  */
522 static int twl4030battery_temperature(void)
523 {
524         u8 val;
525         int temp, curr, volt, res, ret;
526
527         /* Getting and calculating the thermistor voltage */
528         ret = read_bci_val(T2_BATTERY_TEMP);
529         if (ret < 0)
530                 return ret;
531
532         volt = (ret * TEMP_STEP_SIZE) / TEMP_PSR_R;
533
534         /* Getting and calculating the supply current in micro ampers */
535         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
536                  REG_BCICTL2);
537         if (ret)
538                 return 0;
539
540         curr = ((val & ITHSENS) + 1) * 10;
541
542         /* Getting and calculating the thermistor resistance in ohms*/
543         res = volt * 1000 / curr;
544
545         /*calculating temperature*/
546         for (temp = 58; temp >= 0; temp--) {
547                 int actual = therm_tbl [temp];
548                 if ((actual - res) >= 0)
549                         break;
550         }
551
552         /* Negative temperature */
553         if (temp < 3) {
554                 if (temp == 2)
555                         temp = -1;
556                 else if (temp == 1)
557                         temp = -2;
558                 else
559                         temp = -3;
560         }
561
562         return temp + 1;
563 }
564
565 /*
566  * Return battery voltage
567  * Or < 0 on failure.
568  */
569 static int twl4030battery_voltage(void)
570 {
571         int volt = read_bci_val(T2_BATTERY_VOLT);
572
573         return (volt * VOLT_STEP_SIZE) / VOLT_PSR_R;
574 }
575
576 /*
577  * Return the battery current
578  * Or < 0 on failure.
579  */
580 static int twl4030battery_current(void)
581 {
582         int ret, curr = read_bci_val(T2_BATTERY_CUR);
583         u8 val;
584
585         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
586                 REG_BCICTL1);
587         if (ret)
588                 return ret;
589
590         if (val & CGAIN) /* slope of 0.44 mV/mA */
591                 return (curr * CURR_STEP_SIZE) / CURR_PSR_R1;
592         else /* slope of 0.88 mV/mA */
593                 return (curr * CURR_STEP_SIZE) / CURR_PSR_R2;
594 }
595
596 /*
597  * Return the battery backup voltage
598  * Or < 0 on failure.
599  */
600 static int twl4030backupbatt_voltage(void)
601 {
602         int ret, temp;
603         u8 volt;
604         struct twl4030_madc_request req;
605
606         req.channels = (1 << 9);
607         req.method = TWL4030_MADC_SW1;
608         req.func_cb = NULL;
609         twl4030_madc_conversion(&req);
610         temp = (u16)req.rbuf[9];
611
612         return  (temp * BK_VOLT_STEP_SIZE) / BK_VOLT_PSR_R;
613 }
614
615 /*
616  * Returns an integer value, that means,
617  * NO_PW_CONN  no power supply is connected
618  * AC_PW_CONN  if the AC power supply is connected
619  * USB_PW_CONN  if the USB power supply is connected
620  * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected
621  *
622  * Or < 0 on failure.
623  */
624 static int twl4030charger_presence(void)
625 {
626         int ret;
627         u8 hwsts;
628
629         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &hwsts,
630                 REG_STS_HW_CONDITIONS);
631         if (ret) {
632                 pr_err("BATTERY DRIVER: error reading STS_HW_CONDITIONS \n");
633                 return ret;
634         }
635
636         ret = (hwsts & STS_CHG)? AC_PW_CONN: NO_PW_CONN;
637         ret += (hwsts & STS_VBUS)? USB_PW_CONN: NO_PW_CONN;
638
639         if (ret & USB_PW_CONN)
640                 usb_charger_flag = 1;
641         else
642                 usb_charger_flag = 0;
643
644         return ret;
645
646 }
647
648 /*
649  * Returns the main charge FSM status
650  * Or < 0 on failure.
651  */
652 static int twl4030bci_status(void)
653 {
654         int ret;
655         u8 status;
656
657         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
658                 &status, REG_BCIMSTATEC);
659         if (ret) {
660                 pr_err("BATTERY DRIVER: error reading BCIMSTATEC \n");
661                 return ret;
662         }
663
664         return (int) (status & BCIMSTAT_MASK);
665 }
666
667 static int read_bci_val(u8 reg)
668 {
669         int ret, temp;
670         u8 val;
671
672         /* reading MSB */
673         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
674                 reg + 1);
675         if (ret)
676                 return ret;
677
678         temp = ((int)(val & 0x03)) << 8;
679
680         /* reading LSB */
681         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
682                 reg);
683         if (ret)
684                 return ret;
685
686         return temp | val;
687 }
688
689 /*
690  * Settup the twl4030 BCI module to enable backup
691  * battery charging.
692  */
693 static int twl4030backupbatt_voltage_setup(void)
694 {
695         int ret;
696
697         /* Starting backup batery charge */
698         ret = clear_n_set(TWL4030_MODULE_PM_RECEIVER, 0, BBCHEN,
699                 REG_BB_CFG);
700         if (ret)
701                 return ret;
702
703         return 0;
704 }
705
706 /*
707  * Settup the twl4030 BCI module to measure battery
708  * temperature
709  */
710 static int twl4030battery_temp_setup(void)
711 {
712         int ret;
713
714         /* Enabling thermistor current */
715         ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, ITHEN,
716                 REG_BCICTL1);
717         if (ret)
718                 return ret;
719
720         return 0;
721 }
722
723 /*
724  * Sets and clears bits on an given register on a given module
725  */
726 static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg)
727 {
728         int ret;
729         u8 val = 0;
730
731         /* Gets the initial register value */
732         ret = twl4030_i2c_read_u8(mod_no, &val, reg);
733         if (ret)
734                 return ret;
735
736         /* Clearing all those bits to clear */
737         val &= ~(clear);
738
739         /* Setting all those bits to set */
740         val |= set;
741
742         /* Update the register */
743         ret = twl4030_i2c_write_u8(mod_no, val, reg);
744         if (ret)
745                 return ret;
746
747         return 0;
748 }
749
750 static enum power_supply_property twl4030_bci_battery_props[] = {
751         POWER_SUPPLY_PROP_STATUS,
752         POWER_SUPPLY_PROP_ONLINE,
753         POWER_SUPPLY_PROP_VOLTAGE_NOW,
754         POWER_SUPPLY_PROP_CURRENT_NOW,
755         POWER_SUPPLY_PROP_CAPACITY,
756         POWER_SUPPLY_PROP_TEMP,
757 };
758
759 static enum power_supply_property twl4030_bk_bci_battery_props[] = {
760         POWER_SUPPLY_PROP_VOLTAGE_NOW,
761 };
762
763 static void
764 twl4030_bk_bci_battery_read_status(struct twl4030_bci_device_info *di)
765 {
766         di->bk_voltage_uV = twl4030backupbatt_voltage();
767 }
768
769 static void twl4030_bk_bci_battery_work(struct work_struct *work)
770 {
771         struct twl4030_bci_device_info *di = container_of(work,
772                 struct twl4030_bci_device_info,
773                 twl4030_bk_bci_monitor_work.work);
774
775         twl4030_bk_bci_battery_read_status(di);
776         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
777 }
778
779 static void twl4030_bci_battery_read_status(struct twl4030_bci_device_info *di)
780 {
781         di->temp_C = twl4030battery_temperature();
782         di->voltage_uV = twl4030battery_voltage();
783         di->current_uA = twl4030battery_current();
784 }
785
786 static void
787 twl4030_bci_battery_update_status(struct twl4030_bci_device_info *di)
788 {
789         twl4030_bci_battery_read_status(di);
790         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
791
792         if (power_supply_am_i_supplied(&di->bat))
793                 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
794         else
795                 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
796 }
797
798 static void twl4030_bci_battery_work(struct work_struct *work)
799 {
800         struct twl4030_bci_device_info *di = container_of(work,
801                 struct twl4030_bci_device_info, twl4030_bci_monitor_work.work);
802
803         twl4030_bci_battery_update_status(di);
804         schedule_delayed_work(&di->twl4030_bci_monitor_work, 100);
805 }
806
807
808 #define to_twl4030_bci_device_info(x) container_of((x), \
809                         struct twl4030_bci_device_info, bat);
810
811 static void twl4030_bci_battery_external_power_changed(struct power_supply *psy)
812 {
813         struct twl4030_bci_device_info *di = to_twl4030_bci_device_info(psy);
814
815         cancel_delayed_work(&di->twl4030_bci_monitor_work);
816         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
817 }
818
819 #define to_twl4030_bk_bci_device_info(x) container_of((x), \
820                 struct twl4030_bci_device_info, bk_bat);
821
822 static int twl4030_bk_bci_battery_get_property(struct power_supply *psy,
823                                         enum power_supply_property psp,
824                                         union power_supply_propval *val)
825 {
826         struct twl4030_bci_device_info *di = to_twl4030_bk_bci_device_info(psy);
827
828         switch (psp) {
829         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
830                 val->intval = di->bk_voltage_uV;
831                 break;
832         default:
833                 return -EINVAL;
834         }
835
836         return 0;
837 }
838
839 static int twl4030_bci_battery_get_property(struct power_supply *psy,
840                                         enum power_supply_property psp,
841                                         union power_supply_propval *val)
842 {
843         struct twl4030_bci_device_info *di = to_twl4030_bci_device_info(psy);
844         int status = 0;
845
846         switch (psp) {
847         case POWER_SUPPLY_PROP_STATUS:
848                 val->intval = di->charge_status;
849                 return 0;
850         default:
851                 break;
852         }
853
854         switch (psp) {
855         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
856                 val->intval = di->voltage_uV;
857                 break;
858         case POWER_SUPPLY_PROP_CURRENT_NOW:
859                 val->intval = di->current_uA;
860                 break;
861         case POWER_SUPPLY_PROP_TEMP:
862                 val->intval = di->temp_C;
863                 break;
864         case POWER_SUPPLY_PROP_ONLINE:
865                 status = twl4030bci_status();
866                 if ((status & AC_STATEC) == AC_STATEC)
867                         val->intval = POWER_SUPPLY_TYPE_MAINS;
868                 else if (usb_charger_flag)
869                         val->intval = POWER_SUPPLY_TYPE_USB;
870                 else
871                         val->intval = 0;
872                 break;
873         case POWER_SUPPLY_PROP_CAPACITY:
874                 /*
875                  * need to get the correct percentage value per the
876                  * battery characteristics. Approx values for now.
877                  */
878                 if (di->voltage_uV < 2894 || LVL_1) {
879                         val->intval = 5;
880                         LVL_1 = 0;
881                 } else if ((di->voltage_uV < 3451 && di->voltage_uV > 2894)
882                         || LVL_2) {
883                         val->intval = 20;
884                         LVL_2 = 0;
885                 } else if ((di->voltage_uV < 3902 && di->voltage_uV > 3451)
886                         || LVL_3) {
887                         val->intval = 50;
888                         LVL_3 = 0;
889                 } else if ((di->voltage_uV < 3949 && di->voltage_uV > 3902)
890                         || LVL_4) {
891                         val->intval = 75;
892                         LVL_4 = 0;
893                 } else if (di->voltage_uV > 3949)
894                         val->intval = 90;
895                 break;
896         default:
897                 return -EINVAL;
898         }
899         return 0;
900 }
901
902 static char *twl4030_bci_supplied_to[] = {
903         "twl4030_bci_battery",
904 };
905
906 static int twl4030_bci_battery_probe(struct  platform_device *dev)
907 {
908         struct twl4030_bci_device_info *di;
909         int ret;
910         struct twl4030_bci_platform_data *pdata = dev->dev.platform_data;
911
912         therm_tbl = pdata->battery_tmp_tbl;
913
914         di = kzalloc(sizeof(*di), GFP_KERNEL);
915         if (!di)
916                 return -ENOMEM;
917
918         platform_set_drvdata(dev, di);
919
920         di->dev = &dev->dev;
921         di->bat.name = "twl4030_bci_battery";
922         di->bat.supplied_to = twl4030_bci_supplied_to;
923         di->bat.num_supplicants = ARRAY_SIZE(twl4030_bci_supplied_to);
924         di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
925         di->bat.properties = twl4030_bci_battery_props;
926         di->bat.num_properties = ARRAY_SIZE(twl4030_bci_battery_props);
927         di->bat.get_property = twl4030_bci_battery_get_property;
928         di->bat.external_power_changed =
929                         twl4030_bci_battery_external_power_changed;
930
931         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
932
933         di->bk_bat.name = "twl4030_bci_bk_battery";
934         di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY;
935         di->bk_bat.properties = twl4030_bk_bci_battery_props;
936         di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props);
937         di->bk_bat.get_property = twl4030_bk_bci_battery_get_property;
938         di->bk_bat.external_power_changed = NULL;
939
940         twl4030charger_ac_en(ENABLE);
941         twl4030charger_usb_en(ENABLE);
942         twl4030battery_hw_level_en(ENABLE);
943         twl4030battery_hw_presence_en(ENABLE);
944
945         /* settings for temperature sensing */
946         ret = twl4030battery_temp_setup();
947         if (ret)
948                 goto temp_setup_fail;
949
950         /* enabling GPCH09 for read back battery voltage */
951         ret = twl4030backupbatt_voltage_setup();
952         if (ret)
953                 goto voltage_setup_fail;
954
955         /* request BCI interruption */
956         ret = request_irq(TWL4030_MODIRQ_BCI, twl4030battery_interrupt,
957                 IRQF_DISABLED, dev->name, NULL);
958         if (ret) {
959                 pr_err("BATTERY DRIVER: (BCI) IRQ%d is not free.\n",
960                         TWL4030_MODIRQ_PWR);
961                 goto batt_irq_fail;
962         }
963
964         /* request Power interruption */
965         ret = request_irq(TWL4030_PWRIRQ_CHG_PRES, twl4030charger_interrupt,
966                 0, dev->name, di);
967
968         if (ret) {
969                 pr_err("BATTERY DRIVER: (POWER) IRQ%d is not free.\n",
970                         TWL4030_MODIRQ_PWR);
971                 goto chg_irq_fail;
972         }
973
974         ret = power_supply_register(&dev->dev, &di->bat);
975         if (ret) {
976                 pr_err("BATTERY DRIVER: failed to register main battery\n");
977                 goto batt_failed;
978         }
979
980         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bci_monitor_work,
981                                 twl4030_bci_battery_work);
982         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
983
984         ret = power_supply_register(&dev->dev, &di->bk_bat);
985         if (ret) {
986                 pr_err("BATTERY DRIVER: failed to register backup battery\n");
987                 goto bk_batt_failed;
988         }
989
990         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bk_bci_monitor_work,
991                                 twl4030_bk_bci_battery_work);
992         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
993
994         return 0;
995
996 bk_batt_failed:
997         power_supply_unregister(&di->bat);
998 batt_failed:
999         free_irq(TWL4030_MODIRQ_PWR, di);
1000 chg_irq_fail:
1001 prev_setup_err:
1002         free_irq(TWL4030_MODIRQ_BCI, NULL);
1003 batt_irq_fail:
1004 voltage_setup_fail:
1005 temp_setup_fail:
1006         twl4030charger_ac_en(DISABLE);
1007         twl4030charger_usb_en(DISABLE);
1008         twl4030battery_hw_level_en(DISABLE);
1009         twl4030battery_hw_presence_en(DISABLE);
1010         kfree(di);
1011
1012         return ret;
1013 }
1014
1015 static int twl4030_bci_battery_remove(struct  platform_device *dev)
1016 {
1017         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1018
1019         twl4030charger_ac_en(DISABLE);
1020         twl4030charger_usb_en(DISABLE);
1021         twl4030battery_hw_level_en(DISABLE);
1022         twl4030battery_hw_presence_en(DISABLE);
1023
1024         free_irq(TWL4030_MODIRQ_BCI, NULL);
1025         free_irq(TWL4030_MODIRQ_PWR, di);
1026
1027         flush_scheduled_work();
1028         power_supply_unregister(&di->bat);
1029         power_supply_unregister(&di->bk_bat);
1030         platform_set_drvdata(dev, NULL);
1031         kfree(di);
1032
1033         return 0;
1034 }
1035
1036 #ifdef CONFIG_PM
1037 static int twl4030_bci_battery_suspend(struct platform_device *dev,
1038         pm_message_t state)
1039 {
1040         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1041
1042         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
1043         cancel_delayed_work(&di->twl4030_bci_monitor_work);
1044         cancel_delayed_work(&di->twl4030_bk_bci_monitor_work);
1045         return 0;
1046 }
1047
1048 static int twl4030_bci_battery_resume(struct platform_device *dev)
1049 {
1050         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1051
1052         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
1053         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 50);
1054         return 0;
1055 }
1056 #endif /* CONFIG_PM */
1057
1058 /*
1059  * Battery driver module initializer function
1060  * registers battery driver structure
1061  */
1062 static int __init twl4030_battery_init(void)
1063 {
1064         return platform_driver_register(&twl4030_bci_battery_driver);
1065
1066 }
1067
1068 /*
1069  * Battery driver module exit function
1070  * unregister battery driver structure
1071  */
1072 static void __exit twl4030_battery_exit(void)
1073 {
1074         platform_driver_unregister(&twl4030_bci_battery_driver);
1075 }
1076
1077 module_init(twl4030_battery_init);
1078 module_exit(twl4030_battery_exit);
1079 MODULE_LICENSE("GPL");
1080 MODULE_ALIAS("twl4030_bci_battery");
1081 MODULE_AUTHOR("Texas Instruments Inc");