a2589177c23d4b4644ccf9c45010c6da7c1bd937
[firefly-linux-kernel-4.4.55.git] / drivers / power / rk2818_battery.c
1 /* drivers/power/rk2818_battery.c
2  *
3  * battery detect driver for the rk2818 
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/module.h>
17 #include <linux/err.h>
18 #include <linux/platform_device.h>
19 #include <linux/power_supply.h>
20 #include <linux/types.h>
21 #include <linux/pci.h>
22 #include <linux/interrupt.h>
23 #include <asm/io.h>
24 #include <asm/mach-types.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
27 #include <mach/gpio.h>
28 #include <mach/adc.h>
29 #include <mach/iomux.h>
30
31 #if 0
32 #define DBG(x...)   printk(x)
33 #else
34 #define DBG(x...)
35 #endif
36
37 /*******************ÒÔϲÎÊý¿ÉÒÔÐÞ¸Ä******************************/
38 #define TIMER_MS_COUNTS         50              //¶¨Ê±Æ÷µÄ³¤¶Èms
39 #define SLOPE_SECOND_COUNTS     120             //ͳ¼ÆµçѹбÂʵÄʱ¼ä¼ä¸ôs
40 #define TIME_UPDATE_STATUS      5000    //¸üеç³Ø״̬µÄʱ¼ä¼ä¸ôms
41 #define BATT_MAX_VOL_VALUE      4180    //ÂúµçʱµÄµç³Øµçѹ       FOR A7
42 #define BATT_ZERO_VOL_VALUE  3400       //¹Ø»úʱµÄµç³Øµçѹ
43 #define BATT_NOMAL_VOL_VALUE  3800
44 #define THRESHOLD_VOLTAGE_LEVEL0          4050
45 #define THRESHOLD_VOLTAGE_LEVEL1          3950
46 #define THRESHOLD_VOLTAGE_LEVEL2          3850
47 #define THRESHOLD_VOLTAGE_LEVEL3          BATT_ZERO_VOL_VALUE
48 #define THRESHOLD_SLOPE_HIGH            10      //бÂÊÖµ = µçѹ½µµÍµÄËÙ¶È
49 #define THRESHOLD_SLOPE_MID                     5       //<     THRESHOLD_SLOPE_HIGH    
50 #define THRESHOLD_SLOPE_LOW                     0       //< THRESHOLD_SLOPE_MID
51
52 /*************************************************************/
53 #define CHN_BAT_ADC     0
54 #define CHN_USB_ADC     2
55 #define BATT_LEVEL_EMPTY        0
56 #define BATT_PRESENT_TRUE        1
57 #define BATT_PRESENT_FALSE  0
58 #define BAT_1V2_VALUE   1330
59 #define CHARGEOK_PIN    RK2818_PIN_PB1
60
61 #define BAT_LOADER_STATUS               0       //Óõç״̬
62 #define BAT_CHANGE_STATUS               1       //²¨¶¯×´Ì¬
63 #define BAT_CHARGE_STATUS               2       //³äµç״̬
64 #define BAT_RELEASE_STATUS              3       //µç³ØºÄ¾¡×´Ì¬
65
66 #define SLOPE_HIGH_LEVEL                0       //µçѹ±ä»¯Ð±Âʵȼ¶
67 #define SLOPE_MID_LEVEL                 1
68 #define SLOPE_LOW_LEVEL                 2
69
70 #define VOLTAGE_HIGH_LEVEL              0       //µçѹ¸ßµÍµÈ¼¶
71 #define VOLTAGE_MID_LEVEL               1
72 #define VOLTAGE_LOW_LEVEL               2
73 #define VOLTAGE_RELEASE_LEVEL   3
74
75 #define NUM_VOLTAGE_SAMPLE      ((1000*SLOPE_SECOND_COUNTS) / TIMER_MS_COUNTS)  //´æ´¢µÄ²ÉÑùµã¸öÊý
76
77 int gBatLastStatus = 0;
78 int gBatStatus =  POWER_SUPPLY_STATUS_UNKNOWN;
79 int gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
80 int gBatLastPresent = 0;
81 int gBatPresent = BATT_PRESENT_TRUE;
82 int gBatLastVoltage =  0;
83 int gBatVoltage =  BATT_NOMAL_VOL_VALUE;
84 int gBatLastCapacity = 0;
85 int gBatCapacity = ((BATT_NOMAL_VOL_VALUE-BATT_ZERO_VOL_VALUE)*100/(BATT_MAX_VOL_VALUE-BATT_ZERO_VOL_VALUE));
86
87 int gBatVoltageSamples[NUM_VOLTAGE_SAMPLE];
88 int gBatSlopeValue = 0;
89 int gBatVoltageValue[2]={0,0};
90 int *pSamples = &gBatVoltageSamples[0];         //²ÉÑùµãÖ¸Õë
91 int gFlagLoop = 0;              //²ÉÑù×ã¹»±êÖ¾
92 int gNumSamples = 0;
93 int gNumCharge = 0;
94 int gMaxCharge = 0;
95 int gNumLoader = 0;
96 int gMaxLoader = 0;
97
98 int gBatSlopeLevel = SLOPE_LOW_LEVEL;
99 int gBatVoltageLevel = VOLTAGE_MID_LEVEL;
100 int gBatUseStatus = BAT_LOADER_STATUS;  
101
102
103
104 extern int dwc_vbus_status(void);
105 extern int get_msc_connect_flag(void);
106
107 struct rk2818_battery_data {
108         int irq;
109         spinlock_t lock;
110         struct work_struct      timer_work;
111         struct timer_list timer;
112         struct power_supply battery;
113         struct power_supply usb;
114         struct power_supply ac;
115         
116         int adc_bat_divider;
117         int bat_max;
118         int bat_min;
119 };
120
121
122 /* temporary variable used between rk2818_battery_probe() and rk2818_battery_open() */
123 static struct rk2818_battery_data *gBatteryData;
124
125 enum {
126         BATTERY_STATUS          = 0,
127         BATTERY_HEALTH          = 1,
128         BATTERY_PRESENT         = 2,
129         BATTERY_CAPACITY        = 3,
130         BATTERY_AC_ONLINE       = 4,
131         BATTERY_STATUS_CHANGED  = 5,
132         AC_STATUS_CHANGED       = 6,
133         BATTERY_INT_STATUS          = 7,
134         BATTERY_INT_ENABLE          = 8,
135 };
136
137 typedef enum {
138         CHARGER_BATTERY = 0,
139         CHARGER_USB,
140         CHARGER_AC
141 } charger_type_t;
142
143 static int rk2818_get_charge_status(void)
144 {
145         //DBG("gAdcValue[CHN_USB_ADC]=%d\n",gAdcValue[CHN_USB_ADC]);
146         if(gAdcValue[CHN_USB_ADC] > 250)        //about 0.5V
147         return 1;               
148         else if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag()))
149         return 1;
150         else
151         return 0;
152 }
153
154 static void rk2818_get_bat_status(struct rk2818_battery_data *bat)
155 {
156         if(rk2818_get_charge_status() == 1)
157         {
158                 if(gpio_get_value (CHARGEOK_PIN) == 1) //CHG_OK ==0 
159                 {
160                         gBatStatus = POWER_SUPPLY_STATUS_FULL;
161                         DBG("Battery is Full!\n");
162                 }
163                 else
164                 gBatStatus = POWER_SUPPLY_STATUS_CHARGING;              
165         }
166         else
167         gBatStatus = POWER_SUPPLY_STATUS_NOT_CHARGING;  
168 }
169
170 static void rk2818_get_bat_health(struct rk2818_battery_data *bat)
171 {
172         gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
173 }
174
175 static void rk2818_get_bat_present(struct rk2818_battery_data *bat)
176 {
177         if(gBatVoltage < bat->bat_min)
178         gBatPresent = 0;
179         else
180         gBatPresent = 1;
181 }
182
183 static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat)
184 {
185         unsigned long value;
186         int i,*pSamp,*pStart = &gBatVoltageSamples[0],num = 0;
187         int temp[2] = {0,0};
188         value = gAdcValue[CHN_BAT_ADC];
189         if(0 != gAdcValue[3])
190         gBatVoltage = (value * BAT_1V2_VALUE * 2)/gAdcValue[3]; // channel 3 is about 1.42v,need modified
191         /*Ïû³ýë´Ìµçѹ*/
192         if(gBatVoltage >= BATT_MAX_VOL_VALUE + 10)
193                 gBatVoltage = BATT_MAX_VOL_VALUE + 10;
194         else if(gBatVoltage <= BATT_ZERO_VOL_VALUE - 10)
195                 gBatVoltage = BATT_ZERO_VOL_VALUE - 10;
196         
197         *pSamples = gBatVoltage;
198         num = ++pSamples - pStart;
199         if(num > NUM_VOLTAGE_SAMPLE)
200         {
201                 pSamples = pStart;
202                 gFlagLoop = 1;
203         }
204         
205         if(gFlagLoop != 1)              //δ²É¼¯µ½ NUM_VOLTAGE_SAMPLE¸öµçѹֵ
206         {
207                 for(i=(num>>1); i<num; i++)
208                 {
209                         temp[0] += gBatVoltageSamples[i];
210                 }
211
212                 if(num != 0)
213                 {
214                         gBatVoltage = temp[0] / ((num+1)>>1);
215                         gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
216                         if(gBatCapacity >= 100)
217                         gBatCapacity = 100;
218                         else if(gBatCapacity < 0)
219                         gBatCapacity = 0;
220                 }
221                 //DBG("gBatVoltage=%d,gBatCapacity=%d,num=%d\n",gBatVoltage,gBatCapacity,num);
222         }
223         else
224         {
225                 //compute the average voltage after samples-count is larger than NUM_VOLTAGE_SAMPLE
226                 pSamp = pSamples;
227                 for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
228                 {
229                         temp[0] += *pSamp;
230                         if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
231                         pSamp = pStart;
232                 }
233                 
234                 gBatVoltageValue[0] = temp[0] / (NUM_VOLTAGE_SAMPLE >> 1);
235                 for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
236                 {
237                         temp[1] += *pSamp;
238                         if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
239                         pSamp = pStart;
240                 }
241                 
242                 gBatVoltageValue[1] = temp[1] / (NUM_VOLTAGE_SAMPLE >> 1);
243
244                 gBatVoltage = gBatVoltageValue[1];
245
246                 gBatSlopeValue = gBatVoltageValue[0] - gBatVoltageValue[1];
247                 //DBG("gBatSlopeValue=%d,gBatVoltageValue[1]=%d\n",gBatSlopeValue,gBatVoltageValue[1]);
248
249                 if(gBatVoltageValue[1] < BATT_ZERO_VOL_VALUE)
250                 {
251                         gBatUseStatus = BAT_RELEASE_STATUS;             //µç³ØºÄ¾¡×´Ì¬
252                 }
253                 else
254                 {
255                         if(gBatSlopeValue < 0)
256                         {
257                                 gNumLoader = 0;
258                                         
259                                 //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪ¸º±íʾ³äµç״̬
260                                 if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
261                                 gMaxCharge = 2;
262                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
263                                 gMaxCharge = 3;
264                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
265                                 gMaxCharge = 4;         
266                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
267                                 gMaxCharge = 2; 
268                                 if((++gNumCharge >= gMaxCharge) && (gBatStatus != POWER_SUPPLY_STATUS_NOT_CHARGING))
269                                 {
270                                         gBatUseStatus = BAT_CHARGE_STATUS;              //³äµç״̬
271                                         gNumCharge = gMaxCharge ;
272                                 }
273                                 else
274                                 {
275                                         gBatUseStatus = BAT_CHANGE_STATUS;      //²¨¶¯×´Ì¬
276                                 }
277                                 
278                         }
279                         else
280                         {
281                                 gNumCharge = 0;
282                                 //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪÕý±íʾÓõç״̬
283                                 if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
284                                 gMaxCharge = 2;
285                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
286                                 gMaxCharge = 3;
287                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
288                                 gMaxCharge = 4;         
289                                 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
290                                 gMaxLoader = 2; 
291                                 
292                                 if((++gNumLoader >= gMaxLoader) && (gBatStatus == POWER_SUPPLY_STATUS_NOT_CHARGING))
293                                 {               
294                                         gBatUseStatus = BAT_LOADER_STATUS;
295                                         gNumLoader = gMaxLoader;
296                                 }
297                                 else
298                                 {
299                                         gBatUseStatus = BAT_CHANGE_STATUS;      //²¨¶¯×´Ì¬
300                                 }
301
302                         }
303                 }
304         }
305
306         
307 }
308
309 static void rk2818_get_bat_capacity(struct rk2818_battery_data *bat)
310 {
311         if(gFlagLoop)
312         {
313                 if(gBatUseStatus == BAT_LOADER_STATUS)
314                 {
315                         //Óõç״̬ϳöÏÖ¸ºÔرäСÈÝÁ¿±ä´óʱ£¬²»¸üÐÂÈÝÁ¿Öµ
316                         if((gBatLastVoltage == 0) || (gBatVoltage <= gBatLastVoltage))
317                         {
318                                 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
319                                 if(gBatCapacity >= 100)
320                                 gBatCapacity = 100;
321                                 else if(gBatCapacity < 0)
322                                 gBatCapacity = 0;
323                                 gBatLastVoltage = gBatVoltage;
324                         }
325         
326                 }
327                 else if(gBatUseStatus == BAT_CHARGE_STATUS)
328                 {
329                         //³äµç״̬ÏÂÈÝÁ¿½µµÍʱ£¬²»¸üÐÂÈÝÁ¿Öµ
330                         if((gBatLastVoltage == 0) || (gBatVoltage >= gBatLastVoltage))
331                         {
332                                 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
333                                 if(gBatCapacity >= 100)
334                                 gBatCapacity = 100;
335                                 else if(gBatCapacity < 0)
336                                 gBatCapacity = 0;
337                                 gBatLastVoltage = gBatVoltage;
338                                 //DBG("BAT_CHARGE_STATUS\n");
339                         }
340
341                 }
342
343                 //±ä»¯×´Ì¬²»¸üÐÂÈÝÁ¿
344                 //DBG("BAT_CHANGE_STATUS\n");
345         }
346         else
347         {
348                 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
349                 if(gBatCapacity >= 100)
350                         gBatCapacity = 100;
351                 else if(gBatCapacity < 0)
352                         gBatCapacity = 0;
353         }
354 }
355
356
357 static void rk2818_battery_timer_work(struct work_struct *work)
358 {               
359         rk2818_get_bat_status(gBatteryData);
360         rk2818_get_bat_health(gBatteryData);
361         rk2818_get_bat_present(gBatteryData);
362         rk2818_get_bat_voltage(gBatteryData);
363         rk2818_get_bat_capacity(gBatteryData);
364         
365         /*update battery parameter after adc and capacity has been changed*/
366         if((gBatStatus != gBatLastStatus) || (gBatPresent != gBatLastPresent) || (gBatCapacity != gBatLastCapacity))
367         {
368                 //gNumSamples = 0;
369                 gBatLastStatus = gBatStatus;
370                 gBatLastPresent = gBatPresent;
371                 gBatLastCapacity = gBatCapacity;
372                 
373                 if(!( strstr(saved_command_line,"nfsroot=") ) )
374                 {
375                         power_supply_changed(&gBatteryData->battery);
376                 }
377                 else
378                 {
379                         DBG("voltage has changed\n");
380                         DBG("gBatStatus=%d,gBatHealth=%d,gBatPresent=%d\n",gBatStatus,gBatHealth,gBatPresent);
381                         if(gBatVoltageValue[1] == 0)
382                         DBG("gBatVoltage=%d\n",gBatVoltage);
383                         else
384                         DBG("gBatVoltage=%d\n",gBatVoltageValue[1]);
385                         DBG("gBatCapacity=%d%%\n",gBatCapacity);
386                 }
387
388         }
389         
390 }
391
392
393 static void rk2818_batscan_timer(unsigned long data)
394 {
395         gBatteryData->timer.expires  = jiffies + msecs_to_jiffies(TIMER_MS_COUNTS);
396         add_timer(&gBatteryData->timer);
397         schedule_work(&gBatteryData->timer_work);       
398 }
399
400
401 static int rk2818_usb_get_property(struct power_supply *psy, 
402                                     enum power_supply_property psp,
403                                     union power_supply_propval *val)
404 {
405         charger_type_t charger;
406         charger =  CHARGER_USB;
407
408         switch (psp) {
409         case POWER_SUPPLY_PROP_ONLINE:
410                 if (psy->type == POWER_SUPPLY_TYPE_USB)
411                         val->intval = dwc_vbus_status();
412                 DBG("%s:%d\n",__FUNCTION__,val->intval);
413                 break;
414
415         default:
416                 return -EINVAL;
417         }
418         
419         return 0;
420
421 }
422
423
424 static int rk2818_ac_get_property(struct power_supply *psy,
425                         enum power_supply_property psp,
426                         union power_supply_propval *val)
427 {
428 //      struct rk2818_battery_data *data = container_of(psy,
429 //              struct rk2818_battery_data, ac);
430         int ret = 0;
431         charger_type_t charger;
432         charger =  CHARGER_USB;
433         switch (psp) {
434         case POWER_SUPPLY_PROP_ONLINE:
435                 if (psy->type == POWER_SUPPLY_TYPE_MAINS)
436                 {
437                         if(gAdcValue[CHN_USB_ADC] > 250)
438                         val->intval = 1;
439                         else
440                         val->intval = 0;        
441                 }
442                 DBG("%s:%d\n",__FUNCTION__,val->intval);
443                 break;
444                 
445         default:
446                 ret = -EINVAL;
447                 break;
448         }
449         return ret;
450 }
451
452 static int rk2818_battery_get_property(struct power_supply *psy,
453                                  enum power_supply_property psp,
454                                  union power_supply_propval *val)
455 {
456         struct rk2818_battery_data *data = container_of(psy,
457                 struct rk2818_battery_data, battery);
458         int ret = 0;
459
460         switch (psp) {
461         case POWER_SUPPLY_PROP_STATUS:
462                 val->intval = gBatStatus;
463                 DBG("gBatStatus=%d\n",val->intval);
464                 break;
465         case POWER_SUPPLY_PROP_HEALTH:
466                 val->intval = gBatHealth;
467                 DBG("gBatHealth=%d\n",val->intval);
468                 break;
469         case POWER_SUPPLY_PROP_PRESENT:
470                 val->intval = gBatPresent;
471                 DBG("gBatPresent=%d\n",val->intval);
472                 break;
473         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
474                 if(gBatVoltageValue[1] == 0)
475                 val ->intval = gBatVoltage;
476                 else
477                 val ->intval = gBatVoltageValue[1];
478                 DBG("gBatVoltage=%d\n",val->intval);
479                 break;
480         case POWER_SUPPLY_PROP_TECHNOLOGY:
481                 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;     
482                 break;
483         case POWER_SUPPLY_PROP_CAPACITY:
484                 val->intval = gBatCapacity;
485                 DBG("gBatCapacity=%d%%\n",val->intval);
486                 break;
487         case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
488                 val->intval = data->bat_max;
489                 break;
490         case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
491                 val->intval = data->bat_min;
492                 break;
493         default:
494                 ret = -EINVAL;
495                 break;
496         }
497
498         return ret;
499 }
500
501 static enum power_supply_property rk2818_battery_props[] = {
502         POWER_SUPPLY_PROP_STATUS,
503         POWER_SUPPLY_PROP_HEALTH,
504         POWER_SUPPLY_PROP_PRESENT,
505         POWER_SUPPLY_PROP_VOLTAGE_NOW,
506         POWER_SUPPLY_PROP_TECHNOLOGY,
507         POWER_SUPPLY_PROP_CAPACITY,
508         POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
509         POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
510 };
511
512 static enum power_supply_property rk2818_usb_props[] = {
513         POWER_SUPPLY_PROP_ONLINE,
514 };
515
516
517 static enum power_supply_property rk2818_ac_props[] = {
518         POWER_SUPPLY_PROP_ONLINE,
519 };
520
521
522 #ifdef CONFIG_PM
523 static int rk2818_battery_suspend(struct platform_device *dev, pm_message_t state)
524 {
525         /* flush all pending status updates */
526         flush_scheduled_work();
527         return 0;
528 }
529
530 static int rk2818_battery_resume(struct platform_device *dev)
531 {
532         /* things may have changed while we were away */
533         schedule_work(&gBatteryData->timer_work);
534         return 0;
535 }
536 #else
537 #define tosa_bat_suspend NULL
538 #define tosa_bat_resume NULL
539 #endif
540
541
542 static int rk2818_battery_probe(struct platform_device *pdev)
543 {
544         int ret;
545         struct rk2818_battery_data *data;
546
547         ret = gpio_request(CHARGEOK_PIN, NULL);
548         if (ret) {
549                 printk("failed to request charge_ok gpio\n");
550                 goto err_free_gpio1;
551         }
552         
553         gpio_pull_updown(CHARGEOK_PIN, GPIOPullUp);//important
554         ret = gpio_direction_input(CHARGEOK_PIN);
555         if (ret) {
556                 printk("failed to set gpio charge_ok input\n");
557                 goto err_free_gpio1;
558         }
559         
560         data = kzalloc(sizeof(*data), GFP_KERNEL);
561         if (data == NULL) {
562                 ret = -ENOMEM;
563                 goto err_data_alloc_failed;
564         }
565         spin_lock_init(&data->lock);
566         
567         memset(gBatVoltageSamples, 0, sizeof(gBatVoltageSamples));
568         
569         data->battery.properties = rk2818_battery_props;
570         data->battery.num_properties = ARRAY_SIZE(rk2818_battery_props);
571         data->battery.get_property = rk2818_battery_get_property;
572         data->battery.name = "battery";
573         data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
574         data->adc_bat_divider = 414;
575         data->bat_max = BATT_MAX_VOL_VALUE;
576         data->bat_min = BATT_ZERO_VOL_VALUE;
577         DBG("bat_min = %d\n",data->bat_min);
578         
579         data->usb.properties = rk2818_usb_props;
580         data->usb.num_properties = ARRAY_SIZE(rk2818_ac_props);
581         data->usb.get_property = rk2818_usb_get_property;
582         data->usb.name = "usb";
583         data->usb.type = POWER_SUPPLY_TYPE_USB;
584
585         data->ac.properties = rk2818_ac_props;
586         data->ac.num_properties = ARRAY_SIZE(rk2818_ac_props);
587         data->ac.get_property = rk2818_ac_get_property;
588         data->ac.name = "ac";
589         data->ac.type = POWER_SUPPLY_TYPE_MAINS;
590         
591         ret = power_supply_register(&pdev->dev, &data->ac);
592         if (ret)
593         {
594                 printk(KERN_INFO "fail to power_supply_register\n");
595                 goto err_ac_failed;
596         }
597
598         ret = power_supply_register(&pdev->dev, &data->usb);
599         if (ret)
600         {
601                 printk(KERN_INFO "fail to power_supply_register\n");
602                 goto err_usb_failed;
603         }
604
605         ret = power_supply_register(&pdev->dev, &data->battery);
606         if (ret)
607         {
608                 printk(KERN_INFO "fail to power_supply_register\n");
609                 goto err_battery_failed;
610         }
611         platform_set_drvdata(pdev, data);
612
613         INIT_WORK(&data->timer_work, rk2818_battery_timer_work);
614         gBatteryData = data;
615         
616         setup_timer(&data->timer, rk2818_batscan_timer, (unsigned long)data);
617         data->timer.expires  = jiffies+100;
618         add_timer(&data->timer);
619         printk(KERN_INFO "rk2818_battery: driver initialized\n");
620         
621         return 0;
622
623 err_battery_failed:
624         power_supply_unregister(&data->usb);
625 err_usb_failed:
626         power_supply_unregister(&data->ac);
627 err_ac_failed:
628         kfree(data);
629 err_data_alloc_failed:
630
631 err_free_gpio1:
632         gpio_free(CHARGEOK_PIN);
633         return ret;
634 }
635
636 static int rk2818_battery_remove(struct platform_device *pdev)
637 {
638         struct rk2818_battery_data *data = platform_get_drvdata(pdev);
639
640         power_supply_unregister(&data->battery);
641         power_supply_unregister(&data->usb);
642         power_supply_unregister(&data->ac);
643         gpio_free(CHARGEOK_PIN);
644         free_irq(data->irq, data);
645         kfree(data);
646         gBatteryData = NULL;
647         return 0;
648 }
649
650 static struct platform_driver rk2818_battery_device = {
651         .probe          = rk2818_battery_probe,
652         .remove         = rk2818_battery_remove,
653         .suspend        = rk2818_battery_suspend,
654         .resume         = rk2818_battery_resume,
655         .driver = {
656                 .name = "rk2818-battery",
657                 .owner  = THIS_MODULE,
658         }
659 };
660
661 static int __init rk2818_battery_init(void)
662 {
663         return platform_driver_register(&rk2818_battery_device);
664 }
665
666 static void __exit rk2818_battery_exit(void)
667 {
668         platform_driver_unregister(&rk2818_battery_device);
669 }
670
671 module_init(rk2818_battery_init);
672 module_exit(rk2818_battery_exit);
673
674 MODULE_DESCRIPTION("Battery detect driver for the rk2818");
675 MODULE_AUTHOR("luowei lw@rock-chips.com");
676 MODULE_LICENSE("GPL");
677