tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / power / fan5405.c
1 /*
2  * fan5405.c  --  FAN5405 Switching Charger driver
3  *
4  * Copyright (C) 2012 Fairchild semiconductor Co.Ltd
5  * Author: Bright Yang <bright.yang@fairchildsemi.com>
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  */
13
14 #include <linux/device.h>
15 #include <linux/kernel.h>
16 #include <linux/i2c.h>
17 #include <linux/interrupt.h>
18 #include <linux/slab.h>
19 #include <linux/delay.h>
20 #include <linux/gpio.h>
21 #include <linux/timer.h>
22 #include <linux/param.h>
23 #include <linux/stat.h>
24
25 #include "fan5405.h"
26
27 #define FAN5405_DEBUG_FS
28
29
30 /******************************************************************************
31 * Register addresses    
32 ******************************************************************************/
33 #define FAN5405_REG_CONTROL0                  0
34 #define FAN5405_REG_CONTROL1                  1
35 #define FAN5405_REG_OREG                      2
36 #define FAN5405_REG_IC_INFO                   3
37 #define FAN5405_REG_IBAT                      4
38 #define FAN5405_REG_SP_CHARGER                5
39 #define FAN5405_REG_SAFETY                    6
40 #define FAN5405_REG_MONITOR                  16
41
42 /******************************************************************************
43 * Register bits 
44 ******************************************************************************/
45 /* FAN5405_REG_CONTROL0 (0x00) */
46 #define FAN5405_FAULT                   (0x07)
47 #define FAN5405_FAULT_SHIFT                  0  
48 #define FAN5405_BOOST              (0x01 << 3) 
49 #define FAN5405_BOOST_SHIFT                  3
50 #define FAN5405_STAT               (0x3 <<  4) 
51 #define FAN5405_STAT_SHIFT                   4
52 #define FAN5405_EN_STAT            (0x01 << 6)
53 #define FAN5405_EN_STAT_SHIFT                6
54 #define FAN5405_TMR_RST_OTG        (0x01 << 7)  // writing a 1 resets the t32s timer, writing a 0 has no effect
55 #define FAN5405_TMR_RST_OTG_SHIFT            7
56
57 /* FAN5405_REG_CONTROL1 (0x01) */
58 #define FAN5405_OPA_MODE                (0x01)
59 #define FAN5405_OPA_MODE_SHIFT               0
60 #define FAN5405_HZ_MODE            (0x01 << 1)
61 #define FAN5405_HZ_MODE_SHIFT                1  
62 #define FAN5405_CE_N               (0x01 << 2)
63 #define FAN5405_CE_N_SHIFT                   2 
64 #define FAN5405_TE                 (0x01 << 3)
65 #define FAN5405_TE_SHIFT                     3
66 #define FAN5405_VLOWV              (0x03 << 4)
67 #define FAN5405_VLOWV_SHIFT                  4
68 #define FAN5405_IINLIM             (0x03 << 6)
69 #define FAN5405_IINLIM_SHIFT                 6
70
71 /* FAN5405_REG_OREG (0x02) */
72 #define FAN5405_OTG_EN                  (0x01)
73 #define FAN5405_OTG_EN_SHIFT                 0
74 #define FAN5405_OTG_PL             (0x01 << 1)
75 #define FAN5405_OTG_PL_SHIFT                 1
76 #define FAN5405_OREG               (0x3f << 2)
77 #define FAN5405_OREG_SHIFT                   2
78
79 /* FAN5405_REG_IC_INFO (0x03) */
80 #define FAN5405_REV                     (0x03)
81 #define FAN5405_REV_SHIFT                    0
82 #define FAN5405_PN                 (0x07 << 2)
83 #define FAN5405_PN_SHIFT                     2
84 #define FAN5405_VENDOR_CODE        (0x07 << 5)
85 #define FAN5405_VENDOR_CODE_SHIFT            5
86
87 /* FAN5405_REG_IBAT (0x04) */
88 #define FAN5405_ITERM                   (0x07)
89 #define FAN5405_ITERM_SHIFT                  0
90 #define FAN5405_IOCHARGE           (0x07 << 4)
91 #define FAN5405_IOCHARGE_SHIFT               4
92 #define FAN5405_RESET              (0x01 << 7)
93 #define FAN5405_RESET_SHIFT                  7
94
95 /* FAN5405_REG_SP_CHARGER (0x05) */
96 #define FAN5405_VSP                     (0x07)
97 #define FAN5405_VSP_SHIFT                    0
98 #define FAN5405_EN_LEVEL           (0x01 << 3)
99 #define FAN5405_EN_LEVEL_SHIFT               3
100 #define FAN5405_SP                 (0x01 << 4)
101 #define FAN5405_SP_SHIFT                     4
102 #define FAN5405_IO_LEVEL           (0x01 << 5)
103 #define FAN5405_IO_LEVEL_SHIFT               5
104 #define FAN5405_DIS_VREG           (0x01 << 6)
105 #define FAN5405_DIS_VREG_SHIFT               6
106
107 /* FAN5405_REG_SAFETY (0x06) */
108 #define FAN5405_VSAFE                   (0x0f)
109 #define FAN5405_VSAFE_SHIFT                  0
110 #define FAN5405_ISAFE              (0x07 << 4)
111 #define FAN5405_ISAFE_SHIFT                  4
112
113 /* FAN5405_REG_MONITOR (0x10) */
114 #define FAN5405_CV                      (0x01)
115 #define FAN5405_CV_SHIFT                     0
116 #define FAN5405_VBUS_VALID         (0x01 << 1)
117 #define FAN5405_VBUS_VALID_SHIFT             1
118 #define FAN5405_IBUS               (0x01 << 2)
119 #define FAN5405_IBUS_SHIFT                   2
120 #define FAN5405_ICHG               (0x01 << 3)
121 #define FAN5405_ICHG_SHIFT                   3
122 #define FAN5405_T_120              (0x01 << 4)
123 #define FAN5405_T_120_SHIFT                  4
124 #define FAN5405_LINCHG             (0x01 << 5)
125 #define FAN5405_LINCHG_SHIFT                 5
126 #define FAN5405_VBAT_CMP           (0x01 << 6)
127 #define FAN5405_VBAT_CMP_SHIFT               6
128 #define FAN5405_ITERM_CMP          (0x01 << 7)
129 #define FAN5405_ITERM_CMP_SHIFT              7
130
131 /******************************************************************************
132 * bit definitions
133 ******************************************************************************/
134 /********** FAN5405_REG_CONTROL0 (0x00) **********/
135 // EN_STAT [6]
136 #define ENSTAT 1
137 #define DISSTAT 0
138 // TMR_RST [7]
139 #define RESET32S 1
140
141 /********** FAN5405_REG_CONTROL1 (0x01) **********/
142 // OPA_MODE [0]
143 #define CHARGEMODE 0
144 #define BOOSTMODE 1
145 //HZ_MODE [1]
146 #define NOTHIGHIMP 0
147 #define HIGHIMP 1
148 // CE/ [2]
149 #define ENCHARGER 0
150 #define DISCHARGER 1
151 // TE [3]
152 #define DISTE 0
153 #define ENTE 1
154 // VLOWV [5:4]
155 #define VLOWV3P4 0
156 #define VLOWV3P5 1
157 #define VLOWV3P6 2
158 #define VLOWV3P7 3
159 // IINLIM [7:6]
160 #define IINLIM100 0
161 #define IINLIM500 1
162 #define IINLIM800 2
163 #define NOLIMIT 3
164
165 /********** FAN5405_REG_OREG (0x02) **********/
166 // OTG_EN [0]
167 #define DISOTG 0
168 #define ENOTG 1
169 // OTG_PL [1]
170 #define OTGACTIVELOW 0
171 #define OTGACTIVEHIGH 1
172 // OREG [7:2]
173 #define VOREG4P2 35  // refer to table 3
174
175 /********** FAN5405_REG_IC_INFO (0x03) **********/
176
177 /********** FAN5405_REG_IBAT (0x04) **********/
178 // ITERM [2:0] - 68mOhm
179 #define ITERM49 0
180 #define ITERM97 1
181 #define ITERM146 2
182 #define ITERM194 3
183 #define ITERM243 4
184 #define ITERM291 5
185 #define ITERM340 6
186 #define ITERM388 7
187 // IOCHARGE [6:4] - 68mOhm
188 #define IOCHARGE550 0
189 #define IOCHARGE650 1
190 #define IOCHARGE750 2
191 #define IOCHARGE850 3
192 #define IOCHARGE1050 4
193 #define IOCHARGE1150 5
194 #define IOCHARGE1350 6
195 #define IOCHARGE1450 7
196
197 /********** FAN5405_REG_SP_CHARGER (0x05) **********/
198 // VSP [2:0] 
199 #define VSP4P213 0
200 #define VSP4P293 1
201 #define VSP4P373 2
202 #define VSP4P453 3
203 #define VSP4P533 4
204 #define VSP4P613 5
205 #define VSP4P693 6
206 #define VSP4P773 7
207 // IO_LEVEL [5]
208 #define ENIOLEVEL 0
209 #define DISIOLEVEL 1
210 // DIS_VREG [6]
211 #define VREGON 0
212 #define VREGOFF 1
213
214 /********** FAN5405_REG_SAFETY (0x06) **********/
215 // VSAFE [3:0]
216 #define VSAFE4P20 0
217 #define VSAFE4P22 1
218 #define VSAFE4P24 2
219 #define VSAFE4P26 3
220 #define VSAFE4P28 4
221 #define VSAFE4P30 5
222 #define VSAFE4P32 6
223 #define VSAFE4P34 7
224 #define VSAFE4P36 8
225 #define VSAFE4P38 9
226 #define VSAFE4P40 10
227 #define VSAFE4P42 11
228 #define VSAFE4P44 12
229 // ISAFE [6:4] - 68mOhm
230 #define ISAFE550 0
231 #define ISAFE650 1
232 #define ISAFE750 2
233 #define ISAFE850 3
234 #define ISAFE1050 4
235 #define ISAFE1150 5
236 #define ISAFE1350 6
237 #define ISAFE1450 7
238
239 /* reset the T32s timer every 10 seconds   */
240 #define T32S_RESET_INTERVAL     10
241
242 static struct timer_list t32s_timer;
243 static struct delayed_work fan_t32s_timer_work;
244
245
246 static const BYTE fan5405_def_reg[17] = {
247     0x40,    // #0x00(CONTROL0)
248     0x30,    // #0x01(CONTROL1)
249     0x0a,    // #0x02(OREG)
250     0x84,    // #0x03(IC_INFO)
251     0x09,    // #0x04(IBAT) default is 0x89 but writing 1 to IBAT[7] resets charge parameters, except the safety reg, so 
252     0x24,    // #0x05(SP_CHARGER)
253     0x40,    // #0x06(SAFETY)
254     0x00,    // #0x07 - unused
255     0x00,    // #0x08 - unused
256     0x00,    // #0x09 - unused
257     0x00,    // #0x0a - unused
258     0x00,    // #0x0b - unused
259     0x00,    // #0x0c - unused
260     0x00,    // #0x0d - unused
261     0x00,    // #0x0e - unused
262     0x00,    // #0x0f - unused    
263     0x00,    // #0x10(MONITOR)
264 };
265
266 static BYTE fan5405_curr_reg[17];
267
268 static struct i2c_client *this_client;
269 static struct fan5405_platform_data *pdata; 
270
271
272 static int reset_flag = 0;      // use when assert reset
273 static int write_error_count = 0;
274
275 static int fan5405_WriteReg(int reg, int val)
276 {
277     int ret;
278         printk("####pengwei writereg reg = %d val = %d\n",reg,val);
279         ret = i2c_smbus_write_byte_data(this_client, reg, val);
280                 
281         if (ret < 0)
282                 {
283                 write_error_count ++;
284                 pr_debug("%s: error = %d", __func__, ret);
285                 }
286
287         if((reset_flag == 1) ||  
288                 ((reg == FAN5405_REG_IBAT) && (val & FAN5405_RESET)))  
289         {
290             memcpy(fan5405_curr_reg,fan5405_def_reg,6);  // resets charge paremeters, except the safety register(#6)
291             reset_flag = 0;
292         }
293         else
294         {
295             fan5405_curr_reg[reg] = val;
296         }
297
298     return ret;
299 }
300
301 //pengwei added for i2c read error
302 static int read_err_flag = 0;
303 static int read_err_count = 0;
304 static int fan5405_ReadReg(int reg)
305 {
306     int ret;
307         
308         printk("######fan5405_readreg reg  = %d value =%d\n",reg,ret);
309         
310         ret = i2c_smbus_read_byte_data(this_client, reg);
311                 
312         if (ret < 0)
313                 {
314                 read_err_flag = 1;
315                 read_err_count ++;
316                 pr_debug("%s: error = %d", __func__, ret);
317                 }
318
319
320     return ret;
321 }
322
323 static void fan5405_SetValue(BYTE reg, BYTE reg_bit,BYTE reg_shift, BYTE val)
324 {
325         BYTE tmp;
326
327         tmp = fan5405_curr_reg[reg] & (~reg_bit);
328         printk("test value of i2c fan5405_curr_reg[%d] = 0x%x , temp = %d\n",reg,fan5405_curr_reg[reg],tmp);
329         tmp |= (val << reg_shift);
330         printk("continue test tmp =0x%x\n",tmp);
331         if(reg_bit == FAN5405_RESET)
332         {
333             reset_flag = 1;
334         }
335         
336         fan5405_WriteReg(reg,tmp);
337 }
338
339 static BYTE fan5405_GetValue(BYTE reg, BYTE reg_bit, BYTE reg_shift)
340 {
341         BYTE tmp,ret;
342
343         tmp = (BYTE)fan5405_ReadReg(reg);
344         ret = (tmp & reg_bit) >> reg_shift;
345
346         return ret;
347 }
348
349
350
351
352 /******************************************************************************
353 * Function:     
354 * Parameters: None
355 * Return: None
356 *
357 * Description:  if VBUS present(charging & boost),write 1 every 10 seconds
358 *
359 ******************************************************************************/
360 static void fan5405_Reset32sTimer(unsigned long data)
361 {
362         printk("fan 5405 reset timer\n");
363         printk("#####################################read error times is %d\n,writ error times is %d\n",read_err_count,write_error_count);
364         fan5405_SetValue(FAN5405_REG_CONTROL0, FAN5405_TMR_RST_OTG,FAN5405_TMR_RST_OTG_SHIFT, RESET32S);
365         schedule_delayed_work(&fan_t32s_timer_work, HZ*10);
366
367 }
368
369
370 /******************************************************************************
371 * Function:     
372 * Parameters: None
373 * Return: None
374 *
375 * Description:  if VBUS present(charging & boost),write 1 every 10 seconds
376 *
377 ******************************************************************************/
378
379 void fan5405_Reset32sTimer_ap(void)
380 {
381         printk("fan 5405 reset rimer for ap\n");
382         printk("#####################################read error times is %d\n,writ error times is %d\n",read_err_count,write_error_count);
383         fan5405_SetValue(FAN5405_REG_CONTROL0, FAN5405_TMR_RST_OTG,FAN5405_TMR_RST_OTG_SHIFT, RESET32S);
384         schedule_delayed_work(&fan_t32s_timer_work, HZ*10);
385 }
386
387
388 /******************************************************************************
389 * Function: FAN5405_Initialization      
390 * Parameters: None
391 * Return: None
392 *
393 * Description:  
394 *
395 ******************************************************************************/
396 static void fan5405_Initialization(void)
397 {
398     memcpy(fan5405_curr_reg,fan5405_def_reg,sizeof(fan5405_curr_reg));
399         printk("pengwei test fan5405init\n");
400     /* Initialize timer */
401         /* start the timer */
402         /*
403         init_timer(&t32s_timer);
404         t32s_timer.function = fan5405_Reset32sTimer;
405         t32s_timer.data = 0;
406         mod_timer(&t32s_timer, jiffies + (T32S_RESET_INTERVAL * HZ));
407         */
408 //reg 6
409         fan5405_SetValue(FAN5405_REG_SAFETY, FAN5405_VSAFE,FAN5405_VSAFE_SHIFT, VSAFE4P20);  // VSAFE = 4.20V
410         fan5405_SetValue(FAN5405_REG_SAFETY, FAN5405_ISAFE, FAN5405_ISAFE_SHIFT, ISAFE1450);  // ISAFE = 1050mA (68mOhm)
411 //reg 1
412         fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_VLOWV, FAN5405_VLOWV_SHIFT,VLOWV3P4);  // VLOWV = 3.4V
413         fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_IINLIM, FAN5405_IINLIM_SHIFT,IINLIM500);  // INLIM = 500mA
414 //reg 2 
415         fan5405_SetValue(FAN5405_REG_OREG, FAN5405_OREG,FAN5405_OREG_SHIFT, VOREG4P2);  //OREG = 4.20V
416 //reg 5
417         fan5405_SetValue(FAN5405_REG_SP_CHARGER, FAN5405_IO_LEVEL,FAN5405_IO_LEVEL_SHIFT, ENIOLEVEL);  //IO_LEVEL is 0. Output current is controlled by IOCHARGE bits.
418 //reg 5
419         fan5405_SetValue(FAN5405_REG_SP_CHARGER, FAN5405_VSP,FAN5405_VSP_SHIFT, VSP4P213);
420
421 }
422
423 void fan5405_init(void)
424 {
425         //reg 6
426                 fan5405_SetValue(FAN5405_REG_SAFETY, FAN5405_VSAFE,FAN5405_VSAFE_SHIFT, VSAFE4P20);  // VSAFE = 4.20V
427                 fan5405_SetValue(FAN5405_REG_SAFETY, FAN5405_ISAFE, FAN5405_ISAFE_SHIFT, ISAFE1450);  // ISAFE = 1050mA (68mOhm)
428         //reg 1
429                 fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_VLOWV, FAN5405_VLOWV_SHIFT,VLOWV3P4);  // VLOWV = 3.4V
430                 fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_IINLIM, FAN5405_IINLIM_SHIFT,IINLIM500);  // INLIM = 500mA
431         //reg 2 
432                 fan5405_SetValue(FAN5405_REG_OREG, FAN5405_OREG,FAN5405_OREG_SHIFT, VOREG4P2);  //OREG = 4.20V
433         //reg 5
434                 fan5405_SetValue(FAN5405_REG_SP_CHARGER, FAN5405_IO_LEVEL,FAN5405_IO_LEVEL_SHIFT, ENIOLEVEL);  //IO_LEVEL is 0. Output current is controlled by IOCHARGE bits.
435
436         //reg 5
437                 fan5405_SetValue(FAN5405_REG_SP_CHARGER, FAN5405_VSP,FAN5405_VSP_SHIFT, VSP4P213);
438 }
439
440
441 /******************************************************************************
442 * Function: fan5405_OTG_Enable  
443 * Parameters: None
444 * Return: None
445 *
446 * Description:  
447 *
448 ******************************************************************************/
449 void fan5405_OTG_Enable(int enable)
450 {
451         printk("#######pengwei  OTG enable\n");
452     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_OPA_MODE,FAN5405_OPA_MODE_SHIFT, enable); 
453
454         if(enable){
455         fan5405_SetValue(FAN5405_REG_OREG, FAN5405_OTG_EN,FAN5405_OTG_EN_SHIFT, enable);
456         }else{
457         fan5405_init();
458         }
459 }
460
461
462 EXPORT_SYMBOL_GPL(fan5405_OTG_Enable);
463
464
465
466 /******************************************************************************
467 * Function: FAN5405_TA_StartCharging    
468 * Parameters: None
469 * Return: None
470 *
471 * Description:  
472 *
473 ******************************************************************************/
474 void fan5405_TA_StartCharging(void)
475 {
476         printk("pengwei enter TA charging fan5405\n");
477
478     fan5405_SetValue(FAN5405_REG_IBAT, FAN5405_IOCHARGE,FAN5405_IOCHARGE_SHIFT, IOCHARGE1450);  //1050mA
479     fan5405_SetValue(FAN5405_REG_IBAT, FAN5405_ITERM,FAN5405_ITERM_SHIFT, ITERM146);  //146ma
480     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_IINLIM, FAN5405_IINLIM_SHIFT,NOLIMIT);  // no limit
481     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_TE,FAN5405_TE_SHIFT, ENTE);
482     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_CE_N,FAN5405_CE_N_SHIFT, ENCHARGER);
483 }
484 EXPORT_SYMBOL_GPL(fan5405_TA_StartCharging);
485
486 /******************************************************************************
487 * Function: FAN5405_USB_StartCharging   
488 * Parameters: None
489 * Return: None
490 *
491 * Description:  
492 *
493 ******************************************************************************/
494 void fan5405_USB_StartCharging(void)
495 {
496         printk("pengwei enter USB charging fan5405\n");
497     fan5405_SetValue(FAN5405_REG_IBAT, FAN5405_IOCHARGE,FAN5405_IOCHARGE_SHIFT, IOCHARGE550);  //550mA
498         fan5405_SetValue(FAN5405_REG_IBAT, FAN5405_ITERM, FAN5405_ITERM_SHIFT,ITERM146);  //146ma
499     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_IINLIM,FAN5405_IINLIM_SHIFT, IINLIM500);  // limit 500mA (default)   
500     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_TE,FAN5405_TE_SHIFT, ENTE);
501     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_CE_N,FAN5405_CE_N_SHIFT, ENCHARGER);
502 }
503 EXPORT_SYMBOL_GPL(fan5405_USB_StartCharging);
504
505 /******************************************************************************
506 * Function:     
507 * Parameters: None
508 * Return: None
509 *
510 * Description:  
511 *
512 ******************************************************************************/
513 void fan5405_StopCharging(void)
514 {
515         printk("pengwei STOP charging fan5405\n");
516
517     fan5405_SetValue(FAN5405_REG_CONTROL1, FAN5405_CE_N,FAN5405_CE_N_SHIFT, DISCHARGER);
518 }
519 EXPORT_SYMBOL_GPL(fan5405_StopCharging);
520
521 /******************************************************************************
522 * Function: FAN5405_Monitor     
523 * Parameters: None
524 * Return: status 
525 *
526 * Description:  enable the host procdessor to monitor the status of the IC.
527 *
528 ******************************************************************************/
529 fan5405_monitor_status fan5405_Monitor(void)
530 {
531     fan5405_monitor_status status;
532         
533     status = (fan5405_monitor_status)fan5405_ReadReg(FAN5405_REG_MONITOR);
534
535         switch(status){
536                 case FAN5405_MONITOR_NONE:
537                         break;
538                 case FAN5405_MONITOR_CV:
539                         // if need something to do, add
540                         break;
541                 case FAN5405_MONITOR_VBUS_VALID:
542                         // if need something to do, add
543                         break;
544                 case FAN5405_MONITOR_IBUS:
545                         // if need something to do, add
546                         break;
547                 case FAN5405_MONITOR_ICHG:
548                         // if need something to do, add
549                         break;
550                 case FAN5405_MONITOR_T_120:
551                         // if need something to do, add
552                         break;
553                 case FAN5405_MONITOR_LINCHG:
554                         // if need something to do, add
555                         break;
556                 case FAN5405_MONITOR_VBAT_CMP:
557                         // if need something to do, add
558                         break;
559                 case FAN5405_MONITOR_ITERM_CMP:
560                         // if need something to do, add
561                         break;
562                 default :
563                         break;
564                         
565                 }
566
567         return status;
568 }
569 EXPORT_SYMBOL_GPL(fan5405_Monitor);
570
571 static int stat_last = 0;
572 int fan5405_GetCharge_Stat(void)
573 {
574         int stat;
575         int num ;
576         for(num=6;num>=0;num--)
577                 {
578                 printk("###### pengwei test getcharge stat fan5405_ReadReg(%d) = 0x%x\n",num,fan5405_ReadReg(num));
579                 }
580         printk("###### pengwei test getcharge stat value 0x10 = 0x%x\n",fan5405_ReadReg(0x10));
581         stat = fan5405_GetValue(FAN5405_REG_CONTROL0, FAN5405_STAT, FAN5405_STAT_SHIFT);
582 //pengwei added for i2c read err
583         if (read_err_flag == 1)
584                 {
585                 read_err_flag = 0;
586                 }
587         else
588                 {
589                 stat_last = stat;
590                 }
591                 return stat_last;
592 }
593
594 EXPORT_SYMBOL_GPL(fan5405_GetCharge_Stat);
595
596 #ifdef FAN5405_DEBUG_FS
597
598 static ssize_t set_regs_store(struct device *dev,
599                 struct device_attribute *attr,
600                 const char *buf, size_t count)
601 {
602         unsigned long set_value;
603         int reg;  // bit 16:8
604         int val;  //bit7:0
605         int ret;
606         set_value = simple_strtoul(buf, NULL, 16);
607
608         reg = (set_value & 0xff00) >> 8;
609         val = set_value & 0xff;
610         printk("fan54015 set reg = %d value = %d\n",reg, val);
611         ret = fan5405_WriteReg(reg, val);
612         
613         if (ret < 0){
614                 printk("set_regs_store error\n");
615                 return -EINVAL;
616                 }
617
618         return count;
619 }
620
621
622 static ssize_t dump_regs_show(struct device *dev, struct device_attribute *attr,
623                 char *buf)
624 {
625         const int regaddrs[] = {0x00, 0x01, 0x02, 0x03, 0x4, 0x05, 0x06, 0x10 };
626         const char str[] = "0123456789abcdef";
627         BYTE fan5405_regs[0x60];
628
629         int i = 0, index;
630         char val = 0;
631
632         for (i=0; i<0x60; i++) {
633                 if ((i%3)==2)
634                         buf[i]=' ';
635                 else
636                         buf[i] = 'x';
637         }
638         buf[0x5d] = '\n';
639         buf[0x5e] = 0;
640         buf[0x5f] = 0;
641 #if 0
642
643         for ( i = 0; i<0x07; i++) {
644                 fan5405_read_reg(usb_fan5405_chg->client, i, &fan5405_regs[i]);
645         }
646         fan5405_read_reg(usb_fan5405_chg->client, 0x10, &fan5405_regs[0x10]);
647
648 #else
649         for ( i = 0; i<0x07; i++) {
650                 fan5405_regs[i] = fan5405_ReadReg(i);
651         }
652 //      fan5405_ReadReg(fan5405_regs[0x10]);
653 #endif
654         
655
656         for (i=0; i<ARRAY_SIZE(regaddrs); i++) {
657                 index = regaddrs[i];
658                 val = fan5405_regs[index];
659                 buf[3*index] = str[(val&0xf0)>>4];
660                 buf[3*index+1] = str[val&0x0f];
661                 buf[3*index+1] = str[val&0x0f];
662         }
663         
664         return 0x60;
665 }
666
667
668 static DEVICE_ATTR(dump_regs, S_IRUGO | S_IWUSR, dump_regs_show, NULL);
669 static DEVICE_ATTR(set_regs, S_IRUGO | S_IWUSR, NULL, set_regs_store);
670 #endif
671
672 static void fan54015_start_type(int type)
673 {
674         if(type){
675                 fan5405_TA_StartCharging();
676                 }
677         else{
678                 fan5405_USB_StartCharging();
679                 }
680 }
681
682 struct sprd_ext_ic_operations sprd_extic_op ={
683         .ic_init = fan5405_init,
684         .charge_start_ext = fan54015_start_type,
685         .charge_stop_ext = fan5405_StopCharging,
686         .get_charging_status = fan5405_GetCharge_Stat,
687         .timer_callback_ext = fan5405_Reset32sTimer_ap,
688         .otg_charge_ext = fan5405_OTG_Enable,
689 };
690
691 const struct sprd_ext_ic_operations *sprd_get_ext_ic_ops(void){
692         return &sprd_extic_op;
693 }
694
695 extern int sprd_otg_enable_power_on(void);
696
697
698 #ifdef CONFIG_OF
699 static struct fan5405_platform_data *fan5405_parse_dt(struct device *dev)
700 {
701 //      struct fan5405_platform_data *pdata;
702         struct device_node *np = dev->of_node;
703         int ret;
704         pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
705         if (!pdata) {
706                 dev_err(dev, "Could not allocate struct fan5405_platform_data");
707                 return NULL;
708         }
709         return pdata;
710 fail:
711         kfree(pdata);
712         return NULL;
713 }
714 #endif
715
716 static int fan5405_probe(
717         struct i2c_client *client, const struct i2c_device_id *id)
718 {
719
720         int rc = 0;
721         int err = -1;
722         printk("@@@@@@@fan5405_probe\n");
723         pdata = client->dev.platform_data;
724
725 #ifdef CONFIG_OF
726                 struct device_node *np = client->dev.of_node;
727                 if (np && !pdata){
728                         fan5405_parse_dt(&client->dev);
729                         if(!pdata){
730                                 err = -ENOMEM;
731                                 goto exit_alloc_platform_data_failed;
732                         }
733                         client->dev.platform_data = pdata;
734                 }
735 #else
736
737         if (pdata == NULL) {
738                 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
739                 if (pdata == NULL) {
740                         rc = -ENOMEM;
741                         pr_err("%s: platform data is NULL\n", __func__);
742                         goto err_alloc_data_failed;
743                 }
744         }
745 #endif
746
747         this_client = client;   
748
749         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
750                 pr_err("%s: i2c check functionality error\n", __func__);
751                 rc = -ENODEV;
752                 goto check_funcionality_failed;
753         }
754
755         INIT_DELAYED_WORK(&fan_t32s_timer_work, fan5405_Reset32sTimer);
756         schedule_work(&fan_t32s_timer_work);
757
758         fan5405_Initialization();
759         if(sprd_otg_enable_power_on()){
760                 printk("enable OTG mode when power on\n");
761                 fan5405_OTG_Enable(1);
762         }
763
764 #ifdef FAN5405_DEBUG_FS 
765         device_create_file(&client->dev, &dev_attr_dump_regs);
766         device_create_file(&client->dev, &dev_attr_set_regs);
767 #endif
768         printk("@@@@@@@fan5405_probe ok\n");
769         return rc;
770
771 check_funcionality_failed:
772
773 err_alloc_data_failed:
774         return rc;      
775 #ifdef CONFIG_OF
776 exit_alloc_platform_data_failed:
777         return err;
778 #endif
779 }
780 static int fan5405_remove(struct i2c_client *client)
781 {
782         struct fan5405_platform_data *p54013data = i2c_get_clientdata(client);
783         kfree(p54013data);
784         del_timer(&t32s_timer);
785
786         return 0;
787 }
788
789 static int  fan5405_suspend(struct i2c_client *client, pm_message_t message)
790 {
791         return 0;
792 }
793
794 static int  fan5405_resume(struct i2c_client *client)
795 {
796         return 0;
797 }
798
799 static const struct i2c_device_id fan5405_i2c_id[] = {
800         { "fairchild_fan5405", 0 },
801         { }
802 };
803
804 #ifdef CONFIG_OF
805 static const struct of_device_id fan5405_of_match[] = {
806         {.compatible = "fairchild,fairchild_fan5405",},
807         {}
808 };
809 #endif
810
811 static struct i2c_driver fan5405_i2c_driver = {
812         .driver = {
813                 .name = "fairchild_fan5405",
814                 .owner = THIS_MODULE,
815 #ifdef CONFIG_OF
816                 .of_match_table = of_match_ptr(fan5405_of_match),
817 #endif
818         },
819         .probe    = fan5405_probe,
820 //      .remove   = __devexit_p(fan5405_remove),
821         .remove   = fan5405_remove,
822         .suspend  = fan5405_suspend,
823         .resume   = fan5405_resume,
824         .id_table = fan5405_i2c_id,
825 };
826
827 static __init int fan5405_i2c_init(void)
828 {
829         return i2c_add_driver(&fan5405_i2c_driver);
830 }
831
832 static __exit void fan5405_i2c_exit(void)
833 {
834         i2c_del_driver(&fan5405_i2c_driver);
835 }
836
837 module_init(fan5405_i2c_init);
838 module_exit(fan5405_i2c_exit);
839
840 //MODULE_AUTHOR("Bright Yang<bright.yang@fairchildsemi.com>");
841 //MODULE_DESCRIPTION("I2C bus driver for FAN5405 Switching Charger");
842 //MODULE_LICENSE("GPL v2");
843