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