8fc87119555a9f3daa5c4df1e5626d96a4214610
[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 /* Boot with automatic charge */
19 #define CHARGE_MODE 1
20
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/device.h>
24 #include <linux/interrupt.h>
25 #include <linux/delay.h>
26 #include <linux/platform_device.h>
27 #include <linux/i2c/twl4030.h>
28 #include <linux/power_supply.h>
29 #include <linux/i2c/twl4030-madc.h>
30
31 #define T2_BATTERY_VOLT         0x04
32 #define T2_BATTERY_TEMP         0x06
33 #define T2_BATTERY_CUR          0x08
34
35 /* charger constants */
36 #define NO_PW_CONN              0
37 #define AC_PW_CONN              0x01
38 #define USB_PW_CONN             0x02
39
40 /* TWL4030_MODULE_USB */
41 #define REG_POWER_CTRL          0x0AC
42 #define OTG_EN                  0x020
43 #define REG_PHY_CLK_CTRL        0x0FE
44 #define REG_PHY_CLK_CTRL_STS    0x0FF
45 #define PHY_DPLL_CLK            0x01
46
47 #define REG_BCICTL1             0x023
48 #define REG_BCICTL2             0x024
49 #define CGAIN                   0x020
50 #define ITHEN                   0x010
51 #define ITHSENS                 0x007
52
53 /* Boot BCI flag bits */
54 #define BCIAUTOWEN              0x020
55 #define CONFIG_DONE             0x010
56 #define CVENAC                  0x004
57 #define BCIAUTOUSB              0x002
58 #define BCIAUTOAC               0x001
59 #define BCIMSTAT_MASK           0x03F
60
61 /* Boot BCI register */
62 #define REG_BOOT_BCI            0x007
63 #define REG_CTRL1               0x00
64 #define REG_SW1SELECT_MSB       0x07
65 #define SW1_CH9_SEL             0x02
66 #define REG_CTRL_SW1            0x012
67 #define SW1_TRIGGER             0x020
68 #define EOC_SW1                 0x002
69 #define REG_GPCH9               0x049
70 #define REG_STS_HW_CONDITIONS   0x0F
71 #define STS_VBUS                0x080
72 #define STS_CHG                 0x02
73 #define REG_BCIMSTATEC          0x02
74 #define REG_BCIMFSTS4           0x010
75 #define REG_BCIMFSTS2           0x00E
76 #define REG_BCIMFSTS3           0x00F
77 #define REG_BCIMFSTS1           0x001
78 #define USBFASTMCHG             0x004
79 #define BATSTSPCHG              0x004
80 #define BATSTSMCHG              0x040
81 #define VBATOV4                 0x020
82 #define VBATOV3                 0x010
83 #define VBATOV2                 0x008
84 #define VBATOV1                 0x004
85 #define REG_BB_CFG              0x012
86 #define BBCHEN                  0x010
87
88 /* GPBR */
89 #define REG_GPBR1               0x0c
90 #define MADC_HFCLK_EN           0x80
91 #define DEFAULT_MADC_CLK_EN     0x10
92
93 /* Power supply charge interrupt */
94 #define REG_PWR_ISR1            0x00
95 #define REG_PWR_IMR1            0x01
96 #define REG_PWR_EDR1            0x05
97 #define REG_PWR_SIH_CTRL        0x007
98
99 #define USB_PRES                0x004
100 #define CHG_PRES                0x002
101
102 #define USB_PRES_RISING         0x020
103 #define USB_PRES_FALLING        0x010
104 #define CHG_PRES_RISING         0x008
105 #define CHG_PRES_FALLING        0x004
106 #define AC_STATEC               0x20
107 #define COR                     0x004
108
109 /* interrupt status registers */
110 #define REG_BCIISR1A            0x0
111 #define REG_BCIISR2A            0x01
112
113 /* Interrupt flags bits BCIISR1 */
114 #define BATSTS_ISR1             0x080
115 #define VBATLVL_ISR1            0x001
116
117 /* Interrupt mask registers for int1*/
118 #define REG_BCIIMR1A            0x002
119 #define REG_BCIIMR2A            0x003
120
121  /* Interrupt masks for BCIIMR1 */
122 #define BATSTS_IMR1             0x080
123 #define VBATLVL_IMR1            0x001
124
125 /* Interrupt edge detection register */
126 #define REG_BCIEDR1             0x00A
127 #define REG_BCIEDR2             0x00B
128 #define REG_BCIEDR3             0x00C
129
130 /* BCIEDR2 */
131 #define BATSTS_EDRRISIN         0x080
132 #define BATSTS_EDRFALLING       0x040
133
134 /* BCIEDR3 */
135 #define VBATLVL_EDRRISIN        0x02
136
137 /* BCIIREF1 */
138 #define REG_BCIIREF1            0x027
139 #define REG_BCIIREF2            0x028
140
141 /* BCIMFTH1 */
142 #define REG_BCIMFTH1            0x016
143
144 /* Key */
145 #define KEY_IIREF               0xE7
146 #define KEY_FTH1                0xD2
147 #define REG_BCIMFKEY            0x011
148
149 /* Step size and prescaler ratio */
150 #define TEMP_STEP_SIZE          147
151 #define TEMP_PSR_R              100
152
153 #define VOLT_STEP_SIZE          588
154 #define VOLT_PSR_R              100
155
156 #define BK_VOLT_STEP_SIZE       441
157 #define BK_VOLT_PSR_R           100
158
159 #define ENABLE          1
160 #define DISABLE         1
161
162 struct twl4030_bci_device_info {
163         struct device           *dev;
164
165         unsigned long           update_time;
166         int                     voltage_uV;
167         int                     bk_voltage_uV;
168         int                     current_uA;
169         int                     temp_C;
170         int                     charge_rsoc;
171         int                     charge_status;
172
173         struct power_supply     bat;
174         struct power_supply     bk_bat;
175         struct delayed_work     twl4030_bci_monitor_work;
176         struct delayed_work     twl4030_bk_bci_monitor_work;
177
178         struct twl4030_bci_platform_data *pdata;
179 };
180
181 static int usb_charger_flag;
182 static int LVL_1, LVL_2, LVL_3, LVL_4;
183
184 static int read_bci_val(u8 reg_1);
185 static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg);
186 static int twl4030charger_presence(void);
187
188 /*
189  * Report and clear the charger presence event.
190  */
191 static inline int twl4030charger_presence_evt(void)
192 {
193         int ret;
194         u8 chg_sts, set = 0, clear = 0;
195
196         /* read charger power supply status */
197         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &chg_sts,
198                 REG_STS_HW_CONDITIONS);
199         if (ret)
200                 return IRQ_NONE;
201
202         if (chg_sts & STS_CHG) { /* If the AC charger have been connected */
203                 /* configuring falling edge detection for CHG_PRES */
204                 set = CHG_PRES_FALLING;
205                 clear = CHG_PRES_RISING;
206         } else { /* If the AC charger have been disconnected */
207                 /* configuring rising edge detection for CHG_PRES */
208                 set = CHG_PRES_RISING;
209                 clear = CHG_PRES_FALLING;
210         }
211
212         /* Update the interrupt edge detection register */
213         clear_n_set(TWL4030_MODULE_INT, clear, set, REG_PWR_EDR1);
214
215         return 0;
216 }
217
218 /*
219  * Interrupt service routine
220  *
221  * Attends to TWL 4030 power module interruptions events, specifically
222  * USB_PRES (USB charger presence) CHG_PRES (AC charger presence) events
223  *
224  */
225 static irqreturn_t twl4030charger_interrupt(int irq, void *_di)
226 {
227         struct twl4030_bci_device_info *di = _di;
228
229 #ifdef CONFIG_LOCKDEP
230         /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
231          * we don't want and can't tolerate.  Although it might be
232          * friendlier not to borrow this thread context...
233          */
234         local_irq_enable();
235 #endif
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         if ((batstspchg & BATSTSPCHG) || (batstsmchg & BATSTSMCHG)) {
268                 /* In case of the battery insertion event */
269                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_EDRRISIN,
270                         BATSTS_EDRFALLING, REG_BCIEDR2);
271                 if (ret)
272                         return ret;
273         } else {
274                 /* In case of the battery removal event */
275                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_EDRFALLING,
276                         BATSTS_EDRRISIN, REG_BCIEDR2);
277                 if (ret)
278                         return ret;
279         }
280
281         return 0;
282 }
283
284 /*
285  * This function handles the twl4030 battery voltage level interrupt.
286  */
287 static int twl4030battery_level_evt(void)
288 {
289         int ret;
290         u8 mfst;
291
292         /* checking for threshold event */
293         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
294                         &mfst, REG_BCIMFSTS2);
295         if (ret)
296                 return ret;
297
298         /* REVISIT could use a bitmap */
299         if (mfst & VBATOV4) {
300                 LVL_4 = 1;
301                 LVL_3 = 0;
302                 LVL_2 = 0;
303                 LVL_1 = 0;
304         } else if (mfst & VBATOV3) {
305                 LVL_4 = 0;
306                 LVL_3 = 1;
307                 LVL_2 = 0;
308                 LVL_1 = 0;
309         } else if (mfst & VBATOV2) {
310                 LVL_4 = 0;
311                 LVL_3 = 0;
312                 LVL_2 = 1;
313                 LVL_1 = 0;
314         } else {
315                 LVL_4 = 0;
316                 LVL_3 = 0;
317                 LVL_2 = 0;
318                 LVL_1 = 1;
319         }
320
321         return 0;
322 }
323
324 /*
325  * Interrupt service routine
326  *
327  * Attends to BCI interruptions events,
328  * specifically BATSTS (battery connection and removal)
329  * VBATOV (main battery voltage threshold) events
330  *
331  */
332 static irqreturn_t twl4030battery_interrupt(int irq, void *_di)
333 {
334         u8 isr1a_val, isr2a_val, clear_2a, clear_1a;
335         int ret;
336
337 #ifdef CONFIG_LOCKDEP
338         /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
339          * we don't want and can't tolerate.  Although it might be
340          * friendlier not to borrow this thread context...
341          */
342         local_irq_enable();
343 #endif
344
345         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr1a_val,
346                                 REG_BCIISR1A);
347         if (ret)
348                 return IRQ_NONE;
349
350         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr2a_val,
351                                 REG_BCIISR2A);
352         if (ret)
353                 return IRQ_NONE;
354
355         clear_2a = (isr2a_val & VBATLVL_ISR1) ? (VBATLVL_ISR1) : 0;
356         clear_1a = (isr1a_val & BATSTS_ISR1) ? (BATSTS_ISR1) : 0;
357
358         /* cleaning BCI interrupt status flags */
359         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
360                         clear_1a , REG_BCIISR1A);
361         if (ret)
362                 return IRQ_NONE;
363
364         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
365                         clear_2a , REG_BCIISR2A);
366         if (ret)
367                 return IRQ_NONE;
368
369         /* battery connetion or removal event */
370         if (isr1a_val & BATSTS_ISR1)
371                 twl4030battery_presence_evt();
372         /* battery voltage threshold event*/
373         else if (isr2a_val & VBATLVL_ISR1)
374                 twl4030battery_level_evt();
375         else
376                 return IRQ_NONE;
377
378         return IRQ_HANDLED;
379 }
380
381 /*
382  * Enable/Disable hardware battery level event notifications.
383  */
384 static int twl4030battery_hw_level_en(int enable)
385 {
386         int ret;
387
388         if (enable) {
389                 /* unmask VBATOV interrupt for INT1 */
390                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, VBATLVL_IMR1,
391                         0, REG_BCIIMR2A);
392                 if (ret)
393                         return ret;
394
395                 /* configuring interrupt edge detection for VBATOv */
396                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
397                         VBATLVL_EDRRISIN, REG_BCIEDR3);
398                 if (ret)
399                         return ret;
400         } else {
401                 /* mask VBATOV interrupt for INT1 */
402                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
403                         VBATLVL_IMR1, REG_BCIIMR2A);
404                 if (ret)
405                         return ret;
406         }
407
408         return 0;
409 }
410
411 /*
412  * Enable/disable hardware battery presence event notifications.
413  */
414 static int twl4030battery_hw_presence_en(int enable)
415 {
416         int ret;
417
418         if (enable) {
419                 /* unmask BATSTS interrupt for INT1 */
420                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, BATSTS_IMR1,
421                         0, REG_BCIIMR1A);
422                 if (ret)
423                         return ret;
424
425                 /* configuring interrupt edge for BATSTS */
426                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
427                         BATSTS_EDRRISIN | BATSTS_EDRFALLING, REG_BCIEDR2);
428                 if (ret)
429                         return ret;
430         } else {
431                 /* mask BATSTS interrupt for INT1 */
432                 ret = clear_n_set(TWL4030_MODULE_INTERRUPTS, 0,
433                         BATSTS_IMR1, REG_BCIIMR1A);
434                 if (ret)
435                         return ret;
436         }
437
438         return 0;
439 }
440
441 /*
442  * Enable/Disable AC Charge funtionality.
443  */
444 static int twl4030charger_ac_en(int enable, int automatic)
445 {
446         int ret;
447
448         if (enable) {
449                 /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 1 */
450                 if(!automatic) {
451                         ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC | CVENAC,
452                                 (CONFIG_DONE | BCIAUTOWEN),
453                                 REG_BOOT_BCI);
454                 } else {
455                         ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0,
456                                 (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC | CVENAC),
457                                 REG_BOOT_BCI);
458                 }
459                 if (ret)
460                         return ret;
461         } else {
462                 /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 0*/
463                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC,
464                         (CONFIG_DONE | BCIAUTOWEN),
465                         REG_BOOT_BCI);
466                 if (ret)
467                         return ret;
468         }
469
470         return 0;
471 }
472
473 /*
474  * Enable/Disable USB Charge funtionality.
475  */
476 int twl4030charger_usb_en(int enable)
477 {
478         u8 value;
479         int ret;
480         unsigned long timeout;
481
482         if (enable) {
483                 /* Check for USB charger conneted */
484                 ret = twl4030charger_presence();
485                 if (ret < 0)
486                         return ret;
487
488                 if (!(ret & USB_PW_CONN))
489                         return -ENXIO;
490
491                 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
492                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0,
493                         (CONFIG_DONE | BCIAUTOWEN | BCIAUTOUSB),
494                         REG_BOOT_BCI);
495                 if (ret)
496                         return ret;
497
498                 ret = clear_n_set(TWL4030_MODULE_USB, 0, PHY_DPLL_CLK,
499                         REG_PHY_CLK_CTRL);
500                 if (ret)
501                         return ret;
502
503                 value = 0;
504                 timeout = jiffies + msecs_to_jiffies(50);
505
506                 while ((!(value & PHY_DPLL_CLK)) &&
507                         time_before(jiffies, timeout)) {
508                         udelay(10);
509                         ret = twl4030_i2c_read_u8(TWL4030_MODULE_USB, &value,
510                                 REG_PHY_CLK_CTRL_STS);
511                         if (ret)
512                                 return ret;
513                 }
514
515                 /* OTG_EN (POWER_CTRL[5]) to 1 */
516                 ret = clear_n_set(TWL4030_MODULE_USB, 0, OTG_EN,
517                         REG_POWER_CTRL);
518                 if (ret)
519                         return ret;
520
521                 mdelay(50);
522
523                 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
524                 ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0,
525                         USBFASTMCHG, REG_BCIMFSTS4);
526                 if (ret)
527                         return ret;
528         } else {
529                 twl4030charger_presence();
530                 ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOUSB,
531                         (CONFIG_DONE | BCIAUTOWEN), REG_BOOT_BCI);
532                 if (ret)
533                         return ret;
534         }
535
536         return 0;
537 }
538
539 /*
540  * Return battery temperature
541  * Or < 0 on failure.
542  */
543 static int twl4030battery_temperature(struct twl4030_bci_device_info *di)
544 {
545         u8 val;
546         int temp, curr, volt, res, ret;
547
548         /* Is a temperature table specified? */
549         if (!di->pdata->tblsize)
550                 return 0;
551
552         /* Getting and calculating the thermistor voltage */
553         ret = read_bci_val(T2_BATTERY_TEMP);
554         if (ret < 0)
555                 return ret;
556
557         volt = (ret * TEMP_STEP_SIZE) / TEMP_PSR_R;
558
559         /* Getting and calculating the supply current in micro ampers */
560         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
561                  REG_BCICTL2);
562         if (ret)
563                 return 0;
564
565         curr = ((val & ITHSENS) + 1) * 10;
566
567         /* Getting and calculating the thermistor resistance in ohms*/
568         res = volt * 1000 / curr;
569
570         /*calculating temperature*/
571         for (temp = 58; temp >= 0; temp--) {
572                 int actual = di->pdata->battery_tmp_tbl[temp];
573                 if ((actual - res) >= 0)
574                         break;
575         }
576
577         /* Negative temperature */
578         if (temp < 3) {
579                 if (temp == 2)
580                         temp = -1;
581                 else if (temp == 1)
582                         temp = -2;
583                 else
584                         temp = -3;
585         }
586
587         return temp + 1;
588 }
589
590 /*
591  * Return battery voltage
592  * Or < 0 on failure.
593  */
594 static int twl4030battery_voltage(void)
595 {
596         int volt = read_bci_val(T2_BATTERY_VOLT);
597
598         return (volt * VOLT_STEP_SIZE) / VOLT_PSR_R;
599 }
600
601 /*
602  * Return the battery current
603  * Or < 0 on failure.
604  */
605 static int twl4030battery_current(void)
606 {
607         int ret, curr = read_bci_val(T2_BATTERY_CUR);
608         u8 val;
609
610         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
611                 REG_BCICTL1);
612         if (ret)
613                 return ret;
614
615         if (val & CGAIN)
616                 //ret = (int)((float)curr * 1.6617790811339199f * 2.0f - 1.7f);
617                 ret = curr * 16618 * 2 - 1700 * 10000;
618         else
619                 //ret = (int)((float)curr * 1.6617790811339199f - 0.85f);
620                 ret = curr * 16618 - 850 * 10000;
621         ret /= 10000;
622         return ret;
623 }
624
625 /*
626  * Return the battery backup voltage
627  * Or < 0 on failure.
628  */
629 static int twl4030backupbatt_voltage(void)
630 {
631         struct twl4030_madc_request req;
632         int temp;
633
634         req.channels = (1 << 9);
635         req.do_avg = 0;
636         req.method = TWL4030_MADC_SW1;
637         req.active = 0;
638         req.func_cb = NULL;
639         twl4030_madc_conversion(&req);
640         temp = (u16)req.rbuf[9];
641
642         return  (temp * BK_VOLT_STEP_SIZE) / BK_VOLT_PSR_R;
643 }
644
645 /*
646  * Returns an integer value, that means,
647  * NO_PW_CONN  no power supply is connected
648  * AC_PW_CONN  if the AC power supply is connected
649  * USB_PW_CONN  if the USB power supply is connected
650  * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected
651  *
652  * Or < 0 on failure.
653  */
654 static int twl4030charger_presence(void)
655 {
656         int ret;
657         u8 hwsts;
658
659         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &hwsts,
660                 REG_STS_HW_CONDITIONS);
661         if (ret) {
662                 pr_err("twl4030_bci: error reading STS_HW_CONDITIONS\n");
663                 return ret;
664         }
665
666         ret = (hwsts & STS_CHG) ? AC_PW_CONN : NO_PW_CONN;
667         ret += (hwsts & STS_VBUS) ? USB_PW_CONN : NO_PW_CONN;
668
669         if (ret & USB_PW_CONN)
670                 usb_charger_flag = 1;
671         else
672                 usb_charger_flag = 0;
673
674         return ret;
675
676 }
677
678 /*
679  * Returns the main charge FSM status
680  * Or < 0 on failure.
681  */
682 static int twl4030bci_status(void)
683 {
684         int ret;
685         u8 status;
686
687         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
688                 &status, REG_BCIMSTATEC);
689         if (ret) {
690                 pr_err("twl4030_bci: error reading BCIMSTATEC\n");
691                 return ret;
692         }
693
694 #ifdef DEBUG
695         printk("BCI DEBUG: BCIMSTATEC Charge state is 0x%x\n", status);
696 #endif
697         return (int) (status & BCIMSTAT_MASK);
698 }
699
700 static int read_bci_val(u8 reg)
701 {
702         int ret, temp;
703         u8 val;
704
705         /* reading MSB */
706         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
707                 reg + 1);
708         if (ret)
709                 return ret;
710
711         temp = ((int)(val & 0x03)) << 8;
712
713         /* reading LSB */
714         ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
715                 reg);
716         if (ret)
717                 return ret;
718
719         return temp | val;
720 }
721
722 /*
723  * Settup the twl4030 BCI module to enable backup
724  * battery charging.
725  */
726 static int twl4030backupbatt_voltage_setup(void)
727 {
728         int ret;
729
730         /* Starting backup batery charge */
731         ret = clear_n_set(TWL4030_MODULE_PM_RECEIVER, 0, BBCHEN,
732                 REG_BB_CFG);
733         if (ret)
734                 return ret;
735
736         return 0;
737 }
738
739 /*
740  * Settup the twl4030 BCI module to measure battery
741  * temperature
742  */
743 static int twl4030battery_temp_setup(void)
744 {
745 #ifdef DEBUG
746         u8 i;
747 #endif
748         u8 ret;
749
750         /* Enabling thermistor current */
751         ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, 0x1B,
752                 REG_BCICTL1);
753         if (ret)
754                 return ret;
755
756 #ifdef DEBUG
757         twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_BOOT_BCI);
758         printk("BCI DEBUG: BOOT_BCI Value is 0x%x\n", ret);
759
760         twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_STS_HW_CONDITIONS);
761         printk("BCI DEBUG: STS_HW_CONDITIONS Value is 0x%x\n", ret);
762
763         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL1);
764         printk("BCI DEBUG: BCICTL1 Value is 0x%x\n", ret);
765
766         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL2);
767         printk("BCI DEBUG: BCICTL2 Value is 0x%x\n", ret);
768
769         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, 0x0);
770         printk("BCI DEBUG: BCIMDEN Value is 0x%x\n", ret);
771
772         twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &ret, REG_GPBR1);
773         printk("BCI DEBUG: GPBR1 Value is 0x%x\n", ret);
774
775         for(i = 0x0; i <= 0x32; i++)
776         {
777                 twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, i);
778                 printk("BCI DEBUG: BCI 0x%x Value is 0x%x\n", i, ret);
779         }
780 #endif
781
782         return 0;
783 }
784
785 /*
786  * Sets and clears bits on an given register on a given module
787  */
788 static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg)
789 {
790         int ret;
791         u8 val = 0;
792
793         /* Gets the initial register value */
794         ret = twl4030_i2c_read_u8(mod_no, &val, reg);
795         if (ret)
796                 return ret;
797         /* Clearing all those bits to clear */
798         val &= ~(clear);
799
800         /* Setting all those bits to set */
801         val |= set;
802
803         /* Update the register */
804         ret = twl4030_i2c_write_u8(mod_no, val, reg);
805         if (ret)
806                 return ret;
807
808         return 0;
809 }
810
811 static enum power_supply_property twl4030_bci_battery_props[] = {
812         POWER_SUPPLY_PROP_STATUS,
813         POWER_SUPPLY_PROP_ONLINE,
814         POWER_SUPPLY_PROP_VOLTAGE_NOW,
815         POWER_SUPPLY_PROP_CURRENT_NOW,
816         POWER_SUPPLY_PROP_CAPACITY,
817         POWER_SUPPLY_PROP_TEMP,
818 };
819
820 static enum power_supply_property twl4030_bk_bci_battery_props[] = {
821         POWER_SUPPLY_PROP_VOLTAGE_NOW,
822 };
823
824 static void
825 twl4030_bk_bci_battery_read_status(struct twl4030_bci_device_info *di)
826 {
827         di->bk_voltage_uV = twl4030backupbatt_voltage();
828 }
829
830 static void twl4030_bk_bci_battery_work(struct work_struct *work)
831 {
832         struct twl4030_bci_device_info *di = container_of(work,
833                 struct twl4030_bci_device_info,
834                 twl4030_bk_bci_monitor_work.work);
835
836         if(!di->pdata->no_backup_battery)
837                 twl4030_bk_bci_battery_read_status(di);
838         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
839 }
840
841 static void twl4030_bci_battery_read_status(struct twl4030_bci_device_info *di)
842 {
843         di->temp_C = twl4030battery_temperature(di);
844         di->voltage_uV = twl4030battery_voltage();
845         di->current_uA = twl4030battery_current();
846 }
847
848 static void
849 twl4030_bci_battery_update_status(struct twl4030_bci_device_info *di)
850 {
851         twl4030_bci_battery_read_status(di);
852         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
853
854         if (power_supply_am_i_supplied(&di->bat))
855                 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
856         else
857                 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
858 }
859
860 static void twl4030_bci_battery_work(struct work_struct *work)
861 {
862         struct twl4030_bci_device_info *di = container_of(work,
863                 struct twl4030_bci_device_info, twl4030_bci_monitor_work.work);
864
865         twl4030_bci_battery_update_status(di);
866         schedule_delayed_work(&di->twl4030_bci_monitor_work, 100);
867 }
868
869
870 #define to_twl4030_bci_device_info(x) container_of((x), \
871                         struct twl4030_bci_device_info, bat);
872
873 static void twl4030_bci_battery_external_power_changed(struct power_supply *psy)
874 {
875         struct twl4030_bci_device_info *di = to_twl4030_bci_device_info(psy);
876
877         cancel_delayed_work(&di->twl4030_bci_monitor_work);
878         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
879 }
880
881 #define to_twl4030_bk_bci_device_info(x) container_of((x), \
882                 struct twl4030_bci_device_info, bk_bat);
883
884 static ssize_t
885 show_charge_current(struct device *dev, struct device_attribute *attr, char *buf)
886 {
887         u8  ctl;
888         int ret = read_bci_val(REG_BCIIREF1) & 0x1FF;
889         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ctl, REG_BCICTL1);
890
891         if (ctl & CGAIN)
892                 ret |= 0x200;
893
894 #ifdef DEBUG
895         /* Dump debug */
896         twl4030battery_temp_setup();
897 #endif
898
899         return sprintf(buf, "%d\n", ret);
900 }
901
902 static ssize_t
903 set_charge_current(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
904 {
905         unsigned long newCurrent;
906         u8 tmp, boot_bci_prev;
907         int i, ret;
908
909         ret = strict_strtoul(buf, 10, &newCurrent);
910         if (ret)
911                 return -EINVAL;
912
913         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &boot_bci_prev, REG_BOOT_BCI);
914         if (ret)
915                 return ret;
916
917         /* Leave automatic mode as some things cannot be changed there. */
918         ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC | BCIAUTOUSB | CVENAC,
919                         (CONFIG_DONE | BCIAUTOWEN), REG_BOOT_BCI);
920         if (ret)
921                 return ret;
922
923         ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY);
924         if (ret)
925                 return ret;
926
927         ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, newCurrent & 0xff, REG_BCIIREF1);
928         if (ret)
929                 return ret;
930
931         ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY);
932         if (ret)
933                 return ret;
934
935         ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x1, REG_BCIIREF2);
936         if (ret)
937                 return ret;
938
939         /* Set CGAIN = 0 or 1 */
940         if (newCurrent > 511) {
941                 /* Set CGAIN = 1 -- need to wait until automatic charge turns off */
942                 for (i = 0; i < 10; i++) {
943                         clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, CGAIN | 0x1B, REG_BCICTL1);
944                         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1);
945
946                         ret = tmp & CGAIN;
947                         if (ret)
948                                 break;
949                         mdelay(50);
950                 }
951         } else {
952                 /* Set CGAIN = 0 -- need to wait until automatic charge turns off */
953                 for (i = 0; i < 10; i++) {
954                         clear_n_set(TWL4030_MODULE_MAIN_CHARGE, CGAIN, 0x1B, REG_BCICTL1);
955                         twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1);
956
957                         ret = !(tmp & CGAIN);
958                         if (ret)
959                                 break;
960                         mdelay(50);
961                 }
962         }
963
964         if (!ret)
965                 dev_err(dev, "CGAIN change failed\n");
966
967         ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, boot_bci_prev, REG_BOOT_BCI);
968         if (ret)
969                 return ret;
970
971         return count;
972 }
973 static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUSR, show_charge_current, set_charge_current);
974
975 static int twl4030_bk_bci_battery_get_property(struct power_supply *psy,
976                                         enum power_supply_property psp,
977                                         union power_supply_propval *val)
978 {
979         struct twl4030_bci_device_info *di = to_twl4030_bk_bci_device_info(psy);
980
981         switch (psp) {
982         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
983                 val->intval = di->bk_voltage_uV;
984                 break;
985         default:
986                 return -EINVAL;
987         }
988
989         return 0;
990 }
991
992 static int twl4030_bci_battery_get_property(struct power_supply *psy,
993                                         enum power_supply_property psp,
994                                         union power_supply_propval *val)
995 {
996         struct twl4030_bci_device_info *di;
997         int status = 0;
998
999         di = to_twl4030_bci_device_info(psy);
1000
1001         switch (psp) {
1002         case POWER_SUPPLY_PROP_STATUS:
1003                 val->intval = di->charge_status;
1004                 return 0;
1005         default:
1006                 break;
1007         }
1008
1009         switch (psp) {
1010         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1011                 val->intval = di->voltage_uV;
1012                 break;
1013         case POWER_SUPPLY_PROP_CURRENT_NOW:
1014                 val->intval = di->current_uA;
1015                 break;
1016         case POWER_SUPPLY_PROP_TEMP:
1017                 val->intval = di->temp_C;
1018                 break;
1019         case POWER_SUPPLY_PROP_ONLINE:
1020                 status = twl4030bci_status();
1021                 if ((status & AC_STATEC) == AC_STATEC)
1022                         val->intval = POWER_SUPPLY_TYPE_MAINS;
1023                 else if (usb_charger_flag)
1024                         val->intval = POWER_SUPPLY_TYPE_USB;
1025                 else
1026                         val->intval = 0;
1027                 break;
1028         case POWER_SUPPLY_PROP_CAPACITY:
1029                 /*
1030                  * need to get the correct percentage value per the
1031                  * battery characteristics. Approx values for now.
1032                  */
1033                 if (di->voltage_uV < 2894 || LVL_1) {
1034                         val->intval = 5;
1035                         LVL_1 = 0;
1036                 } else if ((di->voltage_uV < 3451 && di->voltage_uV > 2894)
1037                         || LVL_2) {
1038                         val->intval = 20;
1039                         LVL_2 = 0;
1040                 } else if ((di->voltage_uV < 3902 && di->voltage_uV > 3451)
1041                         || LVL_3) {
1042                         val->intval = 50;
1043                         LVL_3 = 0;
1044                 } else if ((di->voltage_uV < 3949 && di->voltage_uV > 3902)
1045                         || LVL_4) {
1046                         val->intval = 75;
1047                         LVL_4 = 0;
1048                 } else if (di->voltage_uV > 3949)
1049                         val->intval = 90;
1050                 break;
1051         default:
1052                 return -EINVAL;
1053         }
1054         return 0;
1055 }
1056
1057 static char *twl4030_bci_supplied_to[] = {
1058         "twl4030_bci_battery",
1059 };
1060
1061 static int __init twl4030_bci_battery_probe(struct platform_device *pdev)
1062 {
1063         struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data;
1064         struct twl4030_bci_device_info *di;
1065         int irq;
1066         int ret;
1067
1068         di = kzalloc(sizeof(*di), GFP_KERNEL);
1069         if (!di)
1070                 return -ENOMEM;
1071
1072         di->dev = &pdev->dev;
1073         di->bat.name = "twl4030_bci_battery";
1074         di->bat.supplied_to = twl4030_bci_supplied_to;
1075         di->bat.num_supplicants = ARRAY_SIZE(twl4030_bci_supplied_to);
1076         di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
1077         di->bat.properties = twl4030_bci_battery_props;
1078         di->bat.num_properties = ARRAY_SIZE(twl4030_bci_battery_props);
1079         di->bat.get_property = twl4030_bci_battery_get_property;
1080         di->bat.external_power_changed =
1081                         twl4030_bci_battery_external_power_changed;
1082
1083         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
1084
1085         di->bk_bat.name = "twl4030_bci_bk_battery";
1086         di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY;
1087         di->bk_bat.properties = twl4030_bk_bci_battery_props;
1088         di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props);
1089         di->bk_bat.get_property = twl4030_bk_bci_battery_get_property;
1090         di->bk_bat.external_power_changed = NULL;
1091         di->pdata = pdata;
1092
1093         /* Set up clocks */
1094         clear_n_set(TWL4030_MODULE_INTBR, 0,
1095                         MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, REG_GPBR1);
1096
1097         twl4030charger_ac_en(ENABLE, CHARGE_MODE);
1098         twl4030charger_usb_en(ENABLE);
1099         twl4030battery_hw_level_en(ENABLE);
1100         twl4030battery_hw_presence_en(ENABLE);
1101
1102         platform_set_drvdata(pdev, di);
1103
1104         /* settings for temperature sensing */
1105         ret = twl4030battery_temp_setup();
1106         if (ret)
1107                 goto temp_setup_fail;
1108
1109         /* enabling GPCH09 for read back battery voltage */
1110         if(!di->pdata->no_backup_battery)
1111         {
1112                 ret = twl4030backupbatt_voltage_setup();
1113                 if (ret)
1114                         goto voltage_setup_fail;
1115         }
1116
1117         /* REVISIT do we need to request both IRQs ?? */
1118
1119         /* request BCI interruption */
1120         ret = request_irq(TWL4030_MODIRQ_BCI, twl4030battery_interrupt,
1121                 0, pdev->name, NULL);
1122         if (ret) {
1123                 dev_dbg(&pdev->dev, "could not request irq %d, status %d\n",
1124                         TWL4030_MODIRQ_BCI, ret);
1125                 goto batt_irq_fail;
1126         }
1127
1128         irq = platform_get_irq(pdev, 0);
1129
1130         /* request Power interruption */
1131         ret = request_irq(irq, twl4030charger_interrupt,
1132                 0, pdev->name, di);
1133
1134         if (ret) {
1135                 dev_dbg(&pdev->dev, "could not request irq %d, status %d\n",
1136                         irq, ret);
1137                 goto chg_irq_fail;
1138         }
1139
1140         ret = power_supply_register(&pdev->dev, &di->bat);
1141         if (ret) {
1142                 dev_dbg(&pdev->dev, "failed to register main battery\n");
1143                 goto batt_failed;
1144         }
1145
1146         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bci_monitor_work,
1147                                 twl4030_bci_battery_work);
1148         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
1149
1150         if(!pdata->no_backup_battery)
1151         {
1152                 ret = power_supply_register(&pdev->dev, &di->bk_bat);
1153                 if (ret) {
1154                         dev_dbg(&pdev->dev, "failed to register backup battery\n");
1155                         goto bk_batt_failed;
1156                 }
1157         }
1158
1159         ret = device_create_file(di->bat.dev, &dev_attr_charge_current);
1160         if (ret) {
1161                 dev_err(&pdev->dev, "failed to create sysfs entries\n");
1162                 goto bk_batt_failed;
1163         }
1164
1165         INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bk_bci_monitor_work,
1166                                 twl4030_bk_bci_battery_work);
1167         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500);
1168
1169         return 0;
1170
1171 bk_batt_failed:
1172         if(!pdata->no_backup_battery)
1173                 power_supply_unregister(&di->bat);
1174 batt_failed:
1175         free_irq(irq, di);
1176 chg_irq_fail:
1177         free_irq(TWL4030_MODIRQ_BCI, NULL);
1178 batt_irq_fail:
1179 voltage_setup_fail:
1180 temp_setup_fail:
1181         twl4030charger_ac_en(DISABLE, CHARGE_MODE);
1182         twl4030charger_usb_en(DISABLE);
1183         twl4030battery_hw_level_en(DISABLE);
1184         twl4030battery_hw_presence_en(DISABLE);
1185         kfree(di);
1186
1187         return ret;
1188 }
1189
1190 static int __exit twl4030_bci_battery_remove(struct platform_device *pdev)
1191 {
1192         struct twl4030_bci_device_info *di = platform_get_drvdata(pdev);
1193         int irq = platform_get_irq(pdev, 0);
1194
1195         twl4030charger_ac_en(DISABLE, CHARGE_MODE);
1196         twl4030charger_usb_en(DISABLE);
1197         twl4030battery_hw_level_en(DISABLE);
1198         twl4030battery_hw_presence_en(DISABLE);
1199
1200         free_irq(TWL4030_MODIRQ_BCI, NULL);
1201         free_irq(irq, di);
1202
1203         flush_scheduled_work();
1204         power_supply_unregister(&di->bat);
1205         power_supply_unregister(&di->bk_bat);
1206         platform_set_drvdata(pdev, NULL);
1207         kfree(di);
1208
1209         return 0;
1210 }
1211
1212 #ifdef CONFIG_PM
1213 static int twl4030_bci_battery_suspend(struct platform_device *pdev,
1214         pm_message_t state)
1215 {
1216         struct twl4030_bci_device_info *di = platform_get_drvdata(pdev);
1217
1218         di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
1219         cancel_delayed_work(&di->twl4030_bci_monitor_work);
1220         cancel_delayed_work(&di->twl4030_bk_bci_monitor_work);
1221         return 0;
1222 }
1223
1224 static int twl4030_bci_battery_resume(struct platform_device *pdev)
1225 {
1226         struct twl4030_bci_device_info *di = platform_get_drvdata(pdev);
1227
1228         schedule_delayed_work(&di->twl4030_bci_monitor_work, 0);
1229         schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 50);
1230         return 0;
1231 }
1232 #else
1233 #define twl4030_bci_battery_suspend     NULL
1234 #define twl4030_bci_battery_resume      NULL
1235 #endif /* CONFIG_PM */
1236
1237 static struct platform_driver twl4030_bci_battery_driver = {
1238         .probe          = twl4030_bci_battery_probe,
1239         .remove         = __exit_p(twl4030_bci_battery_remove),
1240         .suspend        = twl4030_bci_battery_suspend,
1241         .resume         = twl4030_bci_battery_resume,
1242         .driver         = {
1243                 .name   = "twl4030_bci",
1244         },
1245 };
1246
1247 MODULE_LICENSE("GPL");
1248 MODULE_ALIAS("platform:twl4030_bci");
1249 MODULE_AUTHOR("Texas Instruments Inc");
1250
1251 static int __init twl4030_battery_init(void)
1252 {
1253         return platform_driver_register(&twl4030_bci_battery_driver);
1254 }
1255 module_init(twl4030_battery_init);
1256
1257 static void __exit twl4030_battery_exit(void)
1258 {
1259         platform_driver_unregister(&twl4030_bci_battery_driver);
1260 }
1261 module_exit(twl4030_battery_exit);
1262