This patch set up the unused madc request structure members to NULL.
[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.do_avg = 0;
608         req.method = TWL4030_MADC_SW1;
609         req.active = 0;
610         req.func_cb = NULL;
611         twl4030_madc_conversion(&req);
612         temp = (u16)req.rbuf[9];
613
614         return  (temp * BK_VOLT_STEP_SIZE) / BK_VOLT_PSR_R;
615 }
616
617 /*
618  * Returns an integer value, that means,
619  * NO_PW_CONN  no power supply is connected
620  * AC_PW_CONN  if the AC power supply is connected
621  * USB_PW_CONN  if the USB power supply is connected
622  * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected
623  *
624  * Or < 0 on failure.
625  */
626 static int twl4030charger_presence(void)
627 {
628         int ret;
629         u8 hwsts;
630
631         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &hwsts,
632                 REG_STS_HW_CONDITIONS);
633         if (ret) {
634                 pr_err("BATTERY DRIVER: error reading STS_HW_CONDITIONS \n");
635                 return ret;
636         }
637
638         ret = (hwsts & STS_CHG)? AC_PW_CONN: NO_PW_CONN;
639         ret += (hwsts & STS_VBUS)? USB_PW_CONN: NO_PW_CONN;
640
641         if (ret & USB_PW_CONN)
642                 usb_charger_flag = 1;
643         else
644                 usb_charger_flag = 0;
645
646         return ret;
647
648 }
649
650 /*
651  * Returns the main charge FSM status
652  * Or < 0 on failure.
653  */
654 static int twl4030bci_status(void)
655 {
656         int ret;
657         u8 status;
658
659         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
660                 &status, REG_BCIMSTATEC);
661         if (ret) {
662                 pr_err("BATTERY DRIVER: error reading BCIMSTATEC \n");
663                 return ret;
664         }
665
666         return (int) (status & BCIMSTAT_MASK);
667 }
668
669 static int read_bci_val(u8 reg)
670 {
671         int ret, temp;
672         u8 val;
673
674         /* reading MSB */
675         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
676                 reg + 1);
677         if (ret)
678                 return ret;
679
680         temp = ((int)(val & 0x03)) << 8;
681
682         /* reading LSB */
683         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
684                 reg);
685         if (ret)
686                 return ret;
687
688         return temp | val;
689 }
690
691 /*
692  * Settup the twl4030 BCI module to enable backup
693  * battery charging.
694  */
695 static int twl4030backupbatt_voltage_setup(void)
696 {
697         int ret;
698
699         /* Starting backup batery charge */
700         ret = clear_n_set(TWL4030_MODULE_PM_RECEIVER, 0, BBCHEN,
701                 REG_BB_CFG);
702         if (ret)
703                 return ret;
704
705         return 0;
706 }
707
708 /*
709  * Settup the twl4030 BCI module to measure battery
710  * temperature
711  */
712 static int twl4030battery_temp_setup(void)
713 {
714         int ret;
715
716         /* Enabling thermistor current */
717         ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, ITHEN,
718                 REG_BCICTL1);
719         if (ret)
720                 return ret;
721
722         return 0;
723 }
724
725 /*
726  * Sets and clears bits on an given register on a given module
727  */
728 static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg)
729 {
730         int ret;
731         u8 val = 0;
732
733         /* Gets the initial register value */
734         ret = twl4030_i2c_read_u8(mod_no, &val, reg);
735         if (ret)
736                 return ret;
737
738         /* Clearing all those bits to clear */
739         val &= ~(clear);
740
741         /* Setting all those bits to set */
742         val |= set;
743
744         /* Update the register */
745         ret = twl4030_i2c_write_u8(mod_no, val, reg);
746         if (ret)
747                 return ret;
748
749         return 0;
750 }
751
752 static enum power_supply_property twl4030_bci_battery_props[] = {
753         POWER_SUPPLY_PROP_STATUS,
754         POWER_SUPPLY_PROP_ONLINE,
755         POWER_SUPPLY_PROP_VOLTAGE_NOW,
756         POWER_SUPPLY_PROP_CURRENT_NOW,
757         POWER_SUPPLY_PROP_CAPACITY,
758         POWER_SUPPLY_PROP_TEMP,
759 };
760
761 static enum power_supply_property twl4030_bk_bci_battery_props[] = {
762         POWER_SUPPLY_PROP_VOLTAGE_NOW,
763 };
764
765 static void
766 twl4030_bk_bci_battery_read_status(struct twl4030_bci_device_info *di)
767 {
768         di->bk_voltage_uV = twl4030backupbatt_voltage();
769 }
770
771 static void twl4030_bk_bci_battery_work(struct work_struct *work)
772 {
773         struct twl4030_bci_device_info *di = container_of(work,
774                 struct twl4030_bci_device_info,
775                 twl4030_bk_bci_monitor_work.work);
776
777         twl4030_bk_bci_battery_read_status(di);
778         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
779 }
780
781 static void twl4030_bci_battery_read_status(struct twl4030_bci_device_info *di)
782 {
783         di->temp_C = twl4030battery_temperature();
784         di->voltage_uV = twl4030battery_voltage();
785         di->current_uA = twl4030battery_current();
786 }
787
788 static void
789 twl4030_bci_battery_update_status(struct twl4030_bci_device_info *di)
790 {
791         twl4030_bci_battery_read_status(di);
792         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
793
794         if (power_supply_am_i_supplied(&di->bat))
795                 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
796         else
797                 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
798 }
799
800 static void twl4030_bci_battery_work(struct work_struct *work)
801 {
802         struct twl4030_bci_device_info *di = container_of(work,
803                 struct twl4030_bci_device_info, twl4030_bci_monitor_work.work);
804
805         twl4030_bci_battery_update_status(di);
806         schedule_delayed_work(&di->twl4030_bci_monitor_work, 100);
807 }
808
809
810 #define to_twl4030_bci_device_info(x) container_of((x), \
811                         struct twl4030_bci_device_info, bat);
812
813 static void twl4030_bci_battery_external_power_changed(struct power_supply *psy)
814 {
815         struct twl4030_bci_device_info *di = to_twl4030_bci_device_info(psy);
816
817         cancel_delayed_work(&di->twl4030_bci_monitor_work);
818         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
819 }
820
821 #define to_twl4030_bk_bci_device_info(x) container_of((x), \
822                 struct twl4030_bci_device_info, bk_bat);
823
824 static int twl4030_bk_bci_battery_get_property(struct power_supply *psy,
825                                         enum power_supply_property psp,
826                                         union power_supply_propval *val)
827 {
828         struct twl4030_bci_device_info *di = to_twl4030_bk_bci_device_info(psy);
829
830         switch (psp) {
831         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
832                 val->intval = di->bk_voltage_uV;
833                 break;
834         default:
835                 return -EINVAL;
836         }
837
838         return 0;
839 }
840
841 static int twl4030_bci_battery_get_property(struct power_supply *psy,
842                                         enum power_supply_property psp,
843                                         union power_supply_propval *val)
844 {
845         struct twl4030_bci_device_info *di = to_twl4030_bci_device_info(psy);
846         int status = 0;
847
848         switch (psp) {
849         case POWER_SUPPLY_PROP_STATUS:
850                 val->intval = di->charge_status;
851                 return 0;
852         default:
853                 break;
854         }
855
856         switch (psp) {
857         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
858                 val->intval = di->voltage_uV;
859                 break;
860         case POWER_SUPPLY_PROP_CURRENT_NOW:
861                 val->intval = di->current_uA;
862                 break;
863         case POWER_SUPPLY_PROP_TEMP:
864                 val->intval = di->temp_C;
865                 break;
866         case POWER_SUPPLY_PROP_ONLINE:
867                 status = twl4030bci_status();
868                 if ((status & AC_STATEC) == AC_STATEC)
869                         val->intval = POWER_SUPPLY_TYPE_MAINS;
870                 else if (usb_charger_flag)
871                         val->intval = POWER_SUPPLY_TYPE_USB;
872                 else
873                         val->intval = 0;
874                 break;
875         case POWER_SUPPLY_PROP_CAPACITY:
876                 /*
877                  * need to get the correct percentage value per the
878                  * battery characteristics. Approx values for now.
879                  */
880                 if (di->voltage_uV < 2894 || LVL_1) {
881                         val->intval = 5;
882                         LVL_1 = 0;
883                 } else if ((di->voltage_uV < 3451 && di->voltage_uV > 2894)
884                         || LVL_2) {
885                         val->intval = 20;
886                         LVL_2 = 0;
887                 } else if ((di->voltage_uV < 3902 && di->voltage_uV > 3451)
888                         || LVL_3) {
889                         val->intval = 50;
890                         LVL_3 = 0;
891                 } else if ((di->voltage_uV < 3949 && di->voltage_uV > 3902)
892                         || LVL_4) {
893                         val->intval = 75;
894                         LVL_4 = 0;
895                 } else if (di->voltage_uV > 3949)
896                         val->intval = 90;
897                 break;
898         default:
899                 return -EINVAL;
900         }
901         return 0;
902 }
903
904 static char *twl4030_bci_supplied_to[] = {
905         "twl4030_bci_battery",
906 };
907
908 static int twl4030_bci_battery_probe(struct  platform_device *dev)
909 {
910         struct twl4030_bci_device_info *di;
911         int ret;
912         struct twl4030_bci_platform_data *pdata = dev->dev.platform_data;
913
914         therm_tbl = pdata->battery_tmp_tbl;
915
916         di = kzalloc(sizeof(*di), GFP_KERNEL);
917         if (!di)
918                 return -ENOMEM;
919
920         platform_set_drvdata(dev, di);
921
922         di->dev = &dev->dev;
923         di->bat.name = "twl4030_bci_battery";
924         di->bat.supplied_to = twl4030_bci_supplied_to;
925         di->bat.num_supplicants = ARRAY_SIZE(twl4030_bci_supplied_to);
926         di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
927         di->bat.properties = twl4030_bci_battery_props;
928         di->bat.num_properties = ARRAY_SIZE(twl4030_bci_battery_props);
929         di->bat.get_property = twl4030_bci_battery_get_property;
930         di->bat.external_power_changed =
931                         twl4030_bci_battery_external_power_changed;
932
933         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
934
935         di->bk_bat.name = "twl4030_bci_bk_battery";
936         di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY;
937         di->bk_bat.properties = twl4030_bk_bci_battery_props;
938         di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props);
939         di->bk_bat.get_property = twl4030_bk_bci_battery_get_property;
940         di->bk_bat.external_power_changed = NULL;
941
942         twl4030charger_ac_en(ENABLE);
943         twl4030charger_usb_en(ENABLE);
944         twl4030battery_hw_level_en(ENABLE);
945         twl4030battery_hw_presence_en(ENABLE);
946
947         /* settings for temperature sensing */
948         ret = twl4030battery_temp_setup();
949         if (ret)
950                 goto temp_setup_fail;
951
952         /* enabling GPCH09 for read back battery voltage */
953         ret = twl4030backupbatt_voltage_setup();
954         if (ret)
955                 goto voltage_setup_fail;
956
957         /* request BCI interruption */
958         ret = request_irq(TWL4030_MODIRQ_BCI, twl4030battery_interrupt,
959                 IRQF_DISABLED, dev->name, NULL);
960         if (ret) {
961                 pr_err("BATTERY DRIVER: (BCI) IRQ%d is not free.\n",
962                         TWL4030_MODIRQ_PWR);
963                 goto batt_irq_fail;
964         }
965
966         /* request Power interruption */
967         ret = request_irq(TWL4030_PWRIRQ_CHG_PRES, twl4030charger_interrupt,
968                 0, dev->name, di);
969
970         if (ret) {
971                 pr_err("BATTERY DRIVER: (POWER) IRQ%d is not free.\n",
972                         TWL4030_MODIRQ_PWR);
973                 goto chg_irq_fail;
974         }
975
976         ret = power_supply_register(&dev->dev, &di->bat);
977         if (ret) {
978                 pr_err("BATTERY DRIVER: failed to register main battery\n");
979                 goto batt_failed;
980         }
981
982         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bci_monitor_work,
983                                 twl4030_bci_battery_work);
984         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
985
986         ret = power_supply_register(&dev->dev, &di->bk_bat);
987         if (ret) {
988                 pr_err("BATTERY DRIVER: failed to register backup battery\n");
989                 goto bk_batt_failed;
990         }
991
992         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bk_bci_monitor_work,
993                                 twl4030_bk_bci_battery_work);
994         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
995
996         return 0;
997
998 bk_batt_failed:
999         power_supply_unregister(&di->bat);
1000 batt_failed:
1001         free_irq(TWL4030_MODIRQ_PWR, di);
1002 chg_irq_fail:
1003 prev_setup_err:
1004         free_irq(TWL4030_MODIRQ_BCI, NULL);
1005 batt_irq_fail:
1006 voltage_setup_fail:
1007 temp_setup_fail:
1008         twl4030charger_ac_en(DISABLE);
1009         twl4030charger_usb_en(DISABLE);
1010         twl4030battery_hw_level_en(DISABLE);
1011         twl4030battery_hw_presence_en(DISABLE);
1012         kfree(di);
1013
1014         return ret;
1015 }
1016
1017 static int twl4030_bci_battery_remove(struct  platform_device *dev)
1018 {
1019         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1020
1021         twl4030charger_ac_en(DISABLE);
1022         twl4030charger_usb_en(DISABLE);
1023         twl4030battery_hw_level_en(DISABLE);
1024         twl4030battery_hw_presence_en(DISABLE);
1025
1026         free_irq(TWL4030_MODIRQ_BCI, NULL);
1027         free_irq(TWL4030_MODIRQ_PWR, di);
1028
1029         flush_scheduled_work();
1030         power_supply_unregister(&di->bat);
1031         power_supply_unregister(&di->bk_bat);
1032         platform_set_drvdata(dev, NULL);
1033         kfree(di);
1034
1035         return 0;
1036 }
1037
1038 #ifdef CONFIG_PM
1039 static int twl4030_bci_battery_suspend(struct platform_device *dev,
1040         pm_message_t state)
1041 {
1042         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1043
1044         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
1045         cancel_delayed_work(&di->twl4030_bci_monitor_work);
1046         cancel_delayed_work(&di->twl4030_bk_bci_monitor_work);
1047         return 0;
1048 }
1049
1050 static int twl4030_bci_battery_resume(struct platform_device *dev)
1051 {
1052         struct twl4030_bci_device_info *di = platform_get_drvdata(dev);
1053
1054         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
1055         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 50);
1056         return 0;
1057 }
1058 #endif /* CONFIG_PM */
1059
1060 /*
1061  * Battery driver module initializer function
1062  * registers battery driver structure
1063  */
1064 static int __init twl4030_battery_init(void)
1065 {
1066         return platform_driver_register(&twl4030_bci_battery_driver);
1067
1068 }
1069
1070 /*
1071  * Battery driver module exit function
1072  * unregister battery driver structure
1073  */
1074 static void __exit twl4030_battery_exit(void)
1075 {
1076         platform_driver_unregister(&twl4030_bci_battery_driver);
1077 }
1078
1079 module_init(twl4030_battery_init);
1080 module_exit(twl4030_battery_exit);
1081 MODULE_LICENSE("GPL");
1082 MODULE_ALIAS("twl4030_bci_battery");
1083 MODULE_AUTHOR("Texas Instruments Inc");