1 /* drivers/power/rk2818_battery.c
3 * battery detect driver for the rk2818
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.
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.
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/regulator/consumer.h>
21 #include <linux/types.h>
22 #include <linux/pci.h>
23 #include <linux/interrupt.h>
25 #include <asm/mach-types.h>
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <mach/gpio.h>
30 #include <mach/iomux.h>
31 #include <mach/board.h>
33 #define DBG(x...) printk(x)
38 /*******************ÒÔϲÎÊý¿ÉÒÔÐÞ¸Ä******************************/
39 #define TIMER_MS_COUNTS 50 //¶¨Ê±Æ÷µÄ³¤¶Èms
40 #define SLOPE_SECOND_COUNTS 120 //ͳ¼ÆµçѹбÂʵÄʱ¼ä¼ä¸ôs
41 #define TIME_UPDATE_STATUS 5000 //¸üеç³Ø״̬µÄʱ¼ä¼ä¸ôms
42 #define BATT_MAX_VOL_VALUE 4180 //ÂúµçʱµÄµç³Øµçѹ FOR A7
43 #define BATT_ZERO_VOL_VALUE 3500 //¹Ø»úʱµÄµç³Øµçѹ
44 #define BATT_NOMAL_VOL_VALUE 3800
45 #define THRESHOLD_VOLTAGE_LEVEL0 4050
46 #define THRESHOLD_VOLTAGE_LEVEL1 3950
47 #define THRESHOLD_VOLTAGE_LEVEL2 3850
48 #define THRESHOLD_VOLTAGE_LEVEL3 BATT_ZERO_VOL_VALUE
49 #define THRESHOLD_SLOPE_HIGH 10 //бÂÊÖµ = µçѹ½µµÍµÄËÙ¶È
50 #define THRESHOLD_SLOPE_MID 5 //< THRESHOLD_SLOPE_HIGH
51 #define THRESHOLD_SLOPE_LOW 0 //< THRESHOLD_SLOPE_MID
53 /*************************************************************/
56 #define BATT_LEVEL_EMPTY 0
57 #define BATT_PRESENT_TRUE 1
58 #define BATT_PRESENT_FALSE 0
59 #define BAT_1V2_VALUE 1270
61 #define BAT_LOADER_STATUS 0 //Óõç״̬
62 #define BAT_CHANGE_STATUS 1 //²¨¶¯×´Ì¬
63 #define BAT_CHARGE_STATUS 2 //³äµç״̬
64 #define BAT_RELEASE_STATUS 3 //µç³ØºÄ¾¡×´Ì¬
66 #define SLOPE_HIGH_LEVEL 0 //µçѹ±ä»¯Ð±Âʵȼ¶
67 #define SLOPE_MID_LEVEL 1
68 #define SLOPE_LOW_LEVEL 2
70 #define VOLTAGE_HIGH_LEVEL 0 //µçѹ¸ßµÍµÈ¼¶
71 #define VOLTAGE_MID_LEVEL 1
72 #define VOLTAGE_LOW_LEVEL 2
73 #define VOLTAGE_RELEASE_LEVEL 3
75 #define NUM_VOLTAGE_SAMPLE ((1000*SLOPE_SECOND_COUNTS) / TIMER_MS_COUNTS) //´æ´¢µÄ²ÉÑùµã¸öÊý
77 static int gBatFullFlag = 0;
79 static int gBatLastStatus = 0;
80 static int gBatStatus = POWER_SUPPLY_STATUS_UNKNOWN;
81 static int gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
82 static int gBatLastPresent = 0;
83 static int gBatPresent = BATT_PRESENT_TRUE;
84 static int gBatLastVoltage = 0;
85 static int gBatVoltage = BATT_NOMAL_VOL_VALUE;
86 static int gBatLastCapacity = 0;
87 static int gBatCapacity = ((BATT_NOMAL_VOL_VALUE-BATT_ZERO_VOL_VALUE)*100/(BATT_MAX_VOL_VALUE-BATT_ZERO_VOL_VALUE));
89 static int gBatVoltageSamples[NUM_VOLTAGE_SAMPLE+2]; //add 2 to handle one bug
90 static int gBatSlopeValue = 0;
91 static int gBatVoltageValue[2]={0,0};
92 static int *pSamples = &gBatVoltageSamples[0]; //²ÉÑùµãÖ¸Õë
93 static int gFlagLoop = 0; //²ÉÑù×ã¹»±êÖ¾
94 static int gNumSamples = 0;
95 static int gNumCharge = 0;
96 static int gMaxCharge = 0;
97 static int gNumLoader = 0;
98 static int gMaxLoader = 0;
100 static int gBatSlopeLevel = SLOPE_LOW_LEVEL;
101 static int gBatVoltageLevel = VOLTAGE_MID_LEVEL;
102 static int gBatUseStatus = BAT_LOADER_STATUS;
104 static struct regulator *pChargeregulator;
105 static int gVbuscharge = 0;
107 extern int dwc_vbus_status(void);
108 extern int get_msc_connect_flag(void);
110 struct rk2818_battery_data {
113 struct work_struct timer_work;
114 struct timer_list timer;
115 struct power_supply battery;
116 struct power_supply usb;
117 struct power_supply ac;
128 /* temporary variable used between rk2818_battery_probe() and rk2818_battery_open() */
129 static struct rk2818_battery_data *gBatteryData;
135 BATTERY_CAPACITY = 3,
136 BATTERY_AC_ONLINE = 4,
137 BATTERY_STATUS_CHANGED = 5,
138 AC_STATUS_CHANGED = 6,
139 BATTERY_INT_STATUS = 7,
140 BATTERY_INT_ENABLE = 8,
149 static int rk2818_get_charge_status(void)
151 struct regulator * rdev = pChargeregulator;
152 //DBG("gAdcValue[CHN_USB_ADC]=%d\n",gAdcValue[CHN_USB_ADC]);
153 /*if(gAdcValue[CHN_USB_ADC] > 250)
158 if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag()))
161 if(gVbuscharge !=1) {
163 regulator_set_current_limit(rdev,0,1200000);
170 DBG("NOT CHARGING!\n");
171 if(gVbuscharge !=0 ) {
173 regulator_set_current_limit(rdev,0,475000);
181 static void rk2818_get_bat_status(struct rk2818_battery_data *bat)
183 if(rk2818_get_charge_status() == 1)
185 //local_irq_disable();
186 if (gBatFullFlag == 0) {
187 gBatStatus = POWER_SUPPLY_STATUS_CHARGING;
189 gBatStatus = POWER_SUPPLY_STATUS_FULL;
191 //local_irq_enable();
192 DBG("Battery is Charging!\n");
196 gBatStatus = POWER_SUPPLY_STATUS_NOT_CHARGING;
197 DBG("Battery is Not Charging!\n");
201 static void rk2818_get_bat_health(struct rk2818_battery_data *bat)
203 gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
206 static void rk2818_get_bat_present(struct rk2818_battery_data *bat)
208 if(gBatVoltage < bat->bat_min)
214 static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat)
217 int i,*pSamp,*pStart = &gBatVoltageSamples[0],num = 0;
219 value = gAdcValue[CHN_BAT_ADC];
220 if(0 != gAdcValue[3])
221 #ifdef CONFIG_MACH_RAHO
222 gBatVoltage = (value * BAT_1V2_VALUE * 3)/(gAdcValue[3]*2);
224 gBatVoltage = (value * BAT_1V2_VALUE * 2)/gAdcValue[3]; // channel 3 is about 1.42v,need modified
228 if(gBatVoltage >= BATT_MAX_VOL_VALUE + 10)
229 gBatVoltage = BATT_MAX_VOL_VALUE + 10;
230 else if(gBatVoltage <= BATT_ZERO_VOL_VALUE - 10)
231 gBatVoltage = BATT_ZERO_VOL_VALUE - 10;
233 *pSamples = gBatVoltage;
234 num = ++pSamples - pStart;
235 if(num > NUM_VOLTAGE_SAMPLE)
241 if(gFlagLoop != 1) //δ²É¼¯µ½ NUM_VOLTAGE_SAMPLE¸öµçѹֵ
243 for(i=(num>>1); i<num; i++)
245 temp[0] += gBatVoltageSamples[i];
250 gBatVoltage = temp[0] / ((num+1)>>1);
251 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
252 if(gBatCapacity >= 100)
254 else if(gBatCapacity < 0)
257 //DBG("gBatVoltage=%d,gBatCapacity=%d,num=%d\n",gBatVoltage,gBatCapacity,num);
261 //compute the average voltage after samples-count is larger than NUM_VOLTAGE_SAMPLE
263 for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
266 if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
270 gBatVoltageValue[0] = temp[0] / (NUM_VOLTAGE_SAMPLE >> 1);
271 for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
274 if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
278 gBatVoltageValue[1] = temp[1] / (NUM_VOLTAGE_SAMPLE >> 1);
280 gBatVoltage = gBatVoltageValue[1];
282 gBatSlopeValue = gBatVoltageValue[0] - gBatVoltageValue[1];
283 //DBG("gBatSlopeValue=%d,gBatVoltageValue[1]=%d\n",gBatSlopeValue,gBatVoltageValue[1]);
285 if(gBatVoltageValue[1] < BATT_ZERO_VOL_VALUE)
287 gBatUseStatus = BAT_RELEASE_STATUS; //µç³ØºÄ¾¡×´Ì¬
291 if(gBatSlopeValue < 0)
295 //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪ¸º±íʾ³äµç״̬
296 if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
298 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
300 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
302 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
304 if((++gNumCharge >= gMaxCharge) && (gBatStatus != POWER_SUPPLY_STATUS_NOT_CHARGING))
306 gBatUseStatus = BAT_CHARGE_STATUS; //³äµç״̬
307 gNumCharge = gMaxCharge ;
311 gBatUseStatus = BAT_CHANGE_STATUS; //²¨¶¯×´Ì¬
318 //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪÕý±íʾÓõç״̬
319 if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
321 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
323 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
325 else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
328 if((++gNumLoader >= gMaxLoader) && (gBatStatus == POWER_SUPPLY_STATUS_NOT_CHARGING))
330 gBatUseStatus = BAT_LOADER_STATUS;
331 gNumLoader = gMaxLoader;
335 gBatUseStatus = BAT_CHANGE_STATUS; //²¨¶¯×´Ì¬
345 static void rk2818_get_bat_capacity(struct rk2818_battery_data *bat)
349 if(gBatUseStatus == BAT_LOADER_STATUS)
351 //Óõç״̬ϳöÏÖ¸ºÔرäСÈÝÁ¿±ä´óʱ£¬²»¸üÐÂÈÝÁ¿Öµ
352 if((gBatLastVoltage == 0) || (gBatVoltage <= gBatLastVoltage))
354 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
355 if(gBatCapacity >= 100)
357 else if(gBatCapacity < 0)
359 gBatLastVoltage = gBatVoltage;
363 else if(gBatUseStatus == BAT_CHARGE_STATUS)
365 //³äµç״̬ÏÂÈÝÁ¿½µµÍʱ£¬²»¸üÐÂÈÝÁ¿Öµ
366 if((gBatLastVoltage == 0) || (gBatVoltage >= gBatLastVoltage))
368 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
369 if(gBatCapacity >= 100)
371 else if(gBatCapacity < 0)
373 gBatLastVoltage = gBatVoltage;
374 //DBG("BAT_CHARGE_STATUS\n");
380 //DBG("BAT_CHANGE_STATUS\n");
384 gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
385 if(gBatCapacity >= 100)
387 else if(gBatCapacity < 0)
393 static void rk2818_battery_timer_work(struct work_struct *work)
395 rk2818_get_bat_status(gBatteryData);
396 rk2818_get_bat_health(gBatteryData);
397 rk2818_get_bat_present(gBatteryData);
398 rk2818_get_bat_voltage(gBatteryData);
399 rk2818_get_bat_capacity(gBatteryData);
401 /*update battery parameter after adc and capacity has been changed*/
402 if((gBatStatus != gBatLastStatus) || (gBatPresent != gBatLastPresent) || (gBatCapacity != gBatLastCapacity))
405 gBatLastStatus = gBatStatus;
406 gBatLastPresent = gBatPresent;
407 gBatLastCapacity = gBatCapacity;
408 power_supply_changed(&gBatteryData->battery);
415 static void rk2818_batscan_timer(unsigned long data)
417 gBatteryData->timer.expires = jiffies + msecs_to_jiffies(TIMER_MS_COUNTS);
418 add_timer(&gBatteryData->timer);
419 schedule_work(&gBatteryData->timer_work);
423 static int rk2818_usb_get_property(struct power_supply *psy,
424 enum power_supply_property psp,
425 union power_supply_propval *val)
427 charger_type_t charger;
428 charger = CHARGER_USB;
431 case POWER_SUPPLY_PROP_ONLINE:
432 if (psy->type == POWER_SUPPLY_TYPE_USB)
433 val->intval = dwc_vbus_status();
434 DBG("%s:%d\n",__FUNCTION__,val->intval);
446 static int rk2818_ac_get_property(struct power_supply *psy,
447 enum power_supply_property psp,
448 union power_supply_propval *val)
450 // struct rk2818_battery_data *data = container_of(psy,
451 // struct rk2818_battery_data, ac);
453 charger_type_t charger;
454 charger = CHARGER_USB;
456 case POWER_SUPPLY_PROP_ONLINE:
457 if (psy->type == POWER_SUPPLY_TYPE_MAINS)
459 if(gAdcValue[CHN_USB_ADC] > 250)
464 DBG("%s:%d\n",__FUNCTION__,val->intval);
474 static int rk2818_battery_get_property(struct power_supply *psy,
475 enum power_supply_property psp,
476 union power_supply_propval *val)
478 struct rk2818_battery_data *data = container_of(psy,
479 struct rk2818_battery_data, battery);
483 case POWER_SUPPLY_PROP_STATUS:
484 val->intval = gBatStatus;
485 DBG("gBatStatus=%d\n",val->intval);
487 case POWER_SUPPLY_PROP_HEALTH:
488 val->intval = gBatHealth;
489 DBG("gBatHealth=%d\n",val->intval);
491 case POWER_SUPPLY_PROP_PRESENT:
492 val->intval = gBatPresent;
493 DBG("gBatPresent=%d\n",val->intval);
495 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
496 if(gBatVoltageValue[1] == 0)
497 val ->intval = gBatVoltage;
499 val ->intval = gBatVoltageValue[1];
500 DBG("gBatVoltage=%d\n",val->intval);
502 case POWER_SUPPLY_PROP_TECHNOLOGY:
503 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
505 case POWER_SUPPLY_PROP_CAPACITY:
506 val->intval = gBatCapacity;
507 DBG("gBatCapacity=%d%%\n",val->intval);
509 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
510 val->intval = data->bat_max;
512 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
513 val->intval = data->bat_min;
523 static enum power_supply_property rk2818_battery_props[] = {
524 POWER_SUPPLY_PROP_STATUS,
525 POWER_SUPPLY_PROP_HEALTH,
526 POWER_SUPPLY_PROP_PRESENT,
527 POWER_SUPPLY_PROP_VOLTAGE_NOW,
528 POWER_SUPPLY_PROP_TECHNOLOGY,
529 POWER_SUPPLY_PROP_CAPACITY,
530 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
531 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
534 static enum power_supply_property rk2818_usb_props[] = {
535 POWER_SUPPLY_PROP_ONLINE,
539 static enum power_supply_property rk2818_ac_props[] = {
540 POWER_SUPPLY_PROP_ONLINE,
545 static int rk2818_battery_suspend(struct platform_device *dev, pm_message_t state)
547 /* flush all pending status updates */
548 flush_scheduled_work();
552 static int rk2818_battery_resume(struct platform_device *dev)
554 /* things may have changed while we were away */
555 schedule_work(&gBatteryData->timer_work);
559 #define rk2818_battery_suspend NULL
560 #define rk2818_battery_resume NULL
563 static irqreturn_t rk2818_battery_interrupt(int irq, void *dev_id)
565 if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag())) {//detech when charging
569 DBG(KERN_INFO "-----battery is full-----\n");
574 static int rk2818_battery_probe(struct platform_device *pdev)
577 struct rk2818_battery_data *data;
578 struct rk2818_battery_platform_data *pdata = pdev->dev.platform_data;
581 if (pdata && pdata->io_init) {
582 ret = pdata->io_init();
587 ret = gpio_request(pdata->charge_ok_pin, NULL);
589 printk("failed to request charge_ok gpio\n");
593 gpio_pull_updown(pdata->charge_ok_pin, GPIOPullUp);//important
594 ret = gpio_direction_input(pdata->charge_ok_pin);
596 printk("failed to set gpio charge_ok input\n");
600 data = kzalloc(sizeof(*data), GFP_KERNEL);
603 goto err_data_alloc_failed;
605 spin_lock_init(&data->lock);
607 memset(gBatVoltageSamples, 0, sizeof(gBatVoltageSamples));
609 data->battery.properties = rk2818_battery_props;
610 data->battery.num_properties = ARRAY_SIZE(rk2818_battery_props);
611 data->battery.get_property = rk2818_battery_get_property;
612 data->battery.name = "battery";
613 data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
614 data->adc_bat_divider = 414;
615 data->bat_max = BATT_MAX_VOL_VALUE;
616 data->bat_min = BATT_ZERO_VOL_VALUE;
617 DBG("bat_min = %d\n",data->bat_min);
619 data->usb.properties = rk2818_usb_props;
620 data->usb.num_properties = ARRAY_SIZE(rk2818_ac_props);
621 data->usb.get_property = rk2818_usb_get_property;
622 data->usb.name = "usb";
623 data->usb.type = POWER_SUPPLY_TYPE_USB;
625 data->ac.properties = rk2818_ac_props;
626 data->ac.num_properties = ARRAY_SIZE(rk2818_ac_props);
627 data->ac.get_property = rk2818_ac_get_property;
628 data->ac.name = "ac";
629 data->ac.type = POWER_SUPPLY_TYPE_MAINS;
631 data->charge_ok_pin = pdata->charge_ok_pin;
632 data->charge_ok_level = pdata->charge_ok_level;
634 irq_flag = (!pdata->charge_ok_level) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
635 ret = request_irq(gpio_to_irq(pdata->charge_ok_pin), rk2818_battery_interrupt, irq_flag, "rk2818_battery", data);
637 printk("failed to request irq\n");
641 ret = power_supply_register(&pdev->dev, &data->ac);
644 printk(KERN_INFO "fail to power_supply_register\n");
648 ret = power_supply_register(&pdev->dev, &data->usb);
651 printk(KERN_INFO "fail to power_supply_register\n");
655 ret = power_supply_register(&pdev->dev, &data->battery);
658 printk(KERN_INFO "fail to power_supply_register\n");
659 goto err_battery_failed;
661 platform_set_drvdata(pdev, data);
664 pChargeregulator = regulator_get(&pdev->dev, "battery");
665 if(IS_ERR(pChargeregulator))
666 printk(KERN_ERR"fail to get regulator battery\n");
668 regulator_set_current_limit(pChargeregulator,0,475000);
670 INIT_WORK(&data->timer_work, rk2818_battery_timer_work);
673 setup_timer(&data->timer, rk2818_batscan_timer, (unsigned long)data);
674 data->timer.expires = jiffies+100;
675 add_timer(&data->timer);
676 printk(KERN_INFO "rk2818_battery: driver initialized\n");
681 power_supply_unregister(&data->usb);
683 power_supply_unregister(&data->ac);
685 free_irq(gpio_to_irq(pdata->charge_ok_pin), data);
688 err_data_alloc_failed:
691 gpio_free(pdata->charge_ok_pin);
695 static int rk2818_battery_remove(struct platform_device *pdev)
697 struct rk2818_battery_data *data = platform_get_drvdata(pdev);
698 struct rk2818_battery_platform_data *pdata = pdev->dev.platform_data;
700 power_supply_unregister(&data->battery);
701 power_supply_unregister(&data->usb);
702 power_supply_unregister(&data->ac);
703 free_irq(data->irq, data);
704 gpio_free(pdata->charge_ok_pin);
710 static struct platform_driver rk2818_battery_device = {
711 .probe = rk2818_battery_probe,
712 .remove = rk2818_battery_remove,
713 .suspend = rk2818_battery_suspend,
714 .resume = rk2818_battery_resume,
716 .name = "rk2818-battery",
717 .owner = THIS_MODULE,
721 static int __init rk2818_battery_init(void)
723 return platform_driver_register(&rk2818_battery_device);
726 static void __exit rk2818_battery_exit(void)
728 platform_driver_unregister(&rk2818_battery_device);
731 module_init(rk2818_battery_init);
732 module_exit(rk2818_battery_exit);
734 MODULE_DESCRIPTION("Battery detect driver for the rk2818");
735 MODULE_AUTHOR("luowei lw@rock-chips.com");
736 MODULE_LICENSE("GPL");