#define NUM_CHARGE_FULL_DELAY_TIMES ((CHARGE_FULL_DELAY_TIMES * 1000) / TIMER_MS_COUNTS) //³äµçÂú״̬³ÖÐøʱ¼ä³¤¶È
#define NUM_USBCHARGE_IDENTIFY_TIMES ((USBCHARGE_IDENTIFY_TIMES * 1000) / TIMER_MS_COUNTS) //³äµçÂú״̬³ÖÐøʱ¼ä³¤¶È
+#define CHARGE_IS_OK 1
+#define INVALID_CHARGE_CHECK -1
+
#if defined(CONFIG_ARCH_RK3066B)
#define BAT_DEFINE_VALUE 1800
+#elif defined(CONFIG_ARCH_RK2928)
+#define BAT_DEFINE_VALUE 3300
#else
#define BAT_DEFINE_VALUE 2500
charge_on = 1;
}
}
+ else{
+ if(pdata->is_dc_charging)
+ charge_on =pdata->is_dc_charging();
+ }
+
+
#endif
+#if 1
+ if (pdata->spport_usb_charging) //is usb charging
+ if(pdata->is_usb_charging)
+ charge_on = pdata->is_usb_charging();
-#if defined (CONFIG_BATTERY_RK30_USB_CHARGE)
- if (charge_on == 0){
- if (suspend_flag)
- return;
- if (1 == dwc_vbus_status()) { //¼ì²âµ½USB²åÈ룬µ«ÊÇÎÞ·¨Ê¶±ðÊÇ·ñÊdzäµçÆ÷
- //ͨ¹ýÑÓʱ¼ì²âPCʶ±ð±êÖ¾£¬Èç¹û³¬Ê±¼ì²â²»µ½£¬ËµÃ÷Êdzäµç
- if (0 == get_msc_connect_flag()){ //²åÈë³äµçÆ÷ʱ¼ä´óÓÚÒ»¶¨Ê±¼äÖ®ºó£¬¿ªÊ¼½øÈë³äµç״̬
- if (++gBatUsbChargeCnt >= NUM_USBCHARGE_IDENTIFY_TIMES){
- gBatUsbChargeCnt = NUM_USBCHARGE_IDENTIFY_TIMES + 1;
- charge_on = 1;
- }
- } //·ñÔò£¬²»½øÈë³äµçģʽ
- }
- else{
- gBatUsbChargeCnt = 0;
- if (2 == dwc_vbus_status()) {
- charge_on = 1;
- }
- }
- }
#endif
return charge_on;
}
+static int is_charge_ok(struct rk30_adc_battery_data *bat)
+{
+ int charge_is_ok = 0;
+ struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+
+ if((pdata->charge_ok_pin == INVALID_GPIO)&& ( pdata->charging_ok == NULL))
+ return -1;
+
+ if (pdata->charge_ok_pin != INVALID_GPIO){
+ if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level)
+ {
+ charge_is_ok =1;
+ }
+ }else if( pdata->charging_ok)
+ {
+ charge_is_ok = pdata->charging_ok();
+ }
+ return charge_is_ok;
+
+
+}
//int old_charge_level;
static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat)
{
int charge_level;
-
- struct rk30_adc_battery_platform_data *pdata = bat->pdata;
-
+// struct rk30_adc_battery_platform_data *pdata = bat->pdata;
charge_level = rk30_adc_battery_get_charge_level(bat);
//¼ì²â³äµç״̬±ä»¯Çé¿ö
bat->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
}
else{
- //CHARGE
- if (pdata->charge_ok_pin == INVALID_GPIO){ //no charge_ok_pin
+ //CHARGE
+ if( is_charge_ok(bat) == INVALID_CHARGE_CHECK){
+ //if (pdata->charge_ok_pin == INVALID_GPIO){ //no charge_ok_pin
if (bat->bat_capacity == 100){
if (bat->bat_status != POWER_SUPPLY_STATUS_FULL){
}
}
else{ // pin of charge_ok_pin
- if (gpio_get_value(pdata->charge_ok_pin) != pdata->charge_ok_level){
+ if (is_charge_ok(bat) != CHARGE_IS_OK ){
bat->full_times = 0;
bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
bat->full_times = NUM_CHARGE_FULL_DELAY_TIMES + 1;
}
- if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) && (bat->bat_capacity >= 99)){
+ if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) && (bat->bat_capacity >= 95)){
if (bat->bat_status != POWER_SUPPLY_STATUS_FULL){
bat->bat_status = POWER_SUPPLY_STATUS_FULL;
bat->bat_capacity = 100;
return charge_level;
}
+//#define adc_to_voltage(adc_val) ((adc_val * BAT_DEFINE_VALUE * (BAT_PULL_UP_R + BAT_PULL_DOWN_R)) / (1024 * BAT_PULL_DOWN_R))
+
+static int rk_adc_voltage(int value)
+{
+ int voltage;
+
+ int ref_voltage; //reference_voltage
+ int pullup_res;
+ int pulldown_res;
+
+ ref_voltage = gBatteryData ->pdata->reference_voltage;
+ pullup_res = gBatteryData ->pdata->pull_up_res;
+ pulldown_res = gBatteryData ->pdata->pull_down_res;
+
+ if(ref_voltage && pullup_res && pulldown_res){
+
+ voltage = ((value * ref_voltage * (pullup_res + pulldown_res)) / (1024 * pulldown_res));
+
+ }else{
+ voltage = adc_to_voltage(value);
+ }
+
+
+ return voltage;
+
+}
static int *pSamples;
static void rk30_adc_battery_voltage_samples(struct rk30_adc_battery_data *bat)
value = bat->adc_val;
adc_async_read(bat->client);
- *pSamples++ = adc_to_voltage(value);
+ *pSamples++ = rk_adc_voltage(value);
bat->bat_status_cnt++;
if (bat->bat_status_cnt > NUM_VOLTAGE_SAMPLE) bat->bat_status_cnt = NUM_VOLTAGE_SAMPLE + 1;
if (rk30_adc_battery_get_charge_level(bat)){ //charge
if(BatVoltage >= (p[BATT_NUM - 1].charge_vol)){
- capacity = 100;
+ capacity = 99;
}
else{
if(BatVoltage <= (p[0].charge_vol)){
}
return capacity;
-}
+ }
+
static void rk30_adc_battery_capacity_samples(struct rk30_adc_battery_data *bat)
{
int capacity = 0;
- struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+// struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+ int timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE;
+ int timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE;
//³ä·Åµç״̬±ä»¯ºó£¬BufferÌîÂú֮ǰ£¬²»¸üÐÂ
if (bat->bat_status_cnt < NUM_VOLTAGE_SAMPLE) {
if (rk30_adc_battery_get_charge_level(bat)){
if (capacity > bat->bat_capacity){
+ if(capacity > bat->bat_capacity + 10 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -10; //5s
+ else if(capacity > bat->bat_capacity + 7 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -5; //10s
+ else if(capacity > bat->bat_capacity + 3 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE - 2; // 13
//ʵ¼Ê²ÉÑùµ½µÄÈÝÁ¿±ÈÏÔʾµÄÈÝÁ¿´ó£¬Öð¼¶ÉÏÉý
- if (++(bat->gBatCapacityDisChargeCnt) >= NUM_CHARGE_MIN_SAMPLE){
+ if (++(bat->gBatCapacityDisChargeCnt) >= timer_of_charge_sample){
bat->gBatCapacityDisChargeCnt = 0;
if (bat->bat_capacity < 99){
bat->bat_capacity++;
else{ // ʵ¼ÊµÄÈÝÁ¿±È²ÉÑù±È ÏÔʾµÄÈÝÁ¿Ð¡
bat->gBatCapacityDisChargeCnt = 0;
(bat->gBatCapacityChargeCnt)++;
-
- if (pdata->charge_ok_pin != INVALID_GPIO){
- if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level){
+ pr_bat("------------- is_charge_ok(bat)=%d\n", is_charge_ok(bat));
+ if( is_charge_ok(bat) != INVALID_CHARGE_CHECK){
+ //if (pdata->charge_ok_pin != INVALID_GPIO){
+ //if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level){
+ if( is_charge_ok(bat) == CHARGE_IS_OK){
+ if(capacity > bat->bat_capacity + 10 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -13; // 2s
+ else if(capacity > bat->bat_capacity + 7 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -10; //10s
+ else if(capacity > bat->bat_capacity + 2 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -8; //7s
//¼ì²âµ½µç³Ø³äÂú±êÖ¾£¬Í¬Ê±³¤Ê±¼äÄÚ³äµçµçѹÎޱ仯£¬¿ªÊ¼Æô¶¯¼Æʱ³äµç£¬¿ìËÙÉÏÉýÈÝÁ¿
- if (bat->gBatCapacityChargeCnt >= NUM_CHARGE_MIN_SAMPLE){
+ if (bat->gBatCapacityChargeCnt >= timer_of_charge_sample){
bat->gBatCapacityChargeCnt = 0;
if (bat->bat_capacity < 99){
bat->bat_capacity++;
if ((bat->bat_capacity >= 85) &&(bat->gBatCapacityChargeCnt > NUM_CHARGE_MAX_SAMPLE)){
bat->gBatCapacityChargeCnt = (NUM_CHARGE_MAX_SAMPLE - NUM_CHARGE_MID_SAMPLE);
- if (bat->bat_capacity < 99){
+ if (bat->bat_capacity <= 99){
bat->bat_capacity++;
bat->bat_change = 1;
}
else{
//·Åµçʱ,Ö»ÔÊÐíµçѹϽµ
if (capacity < bat->bat_capacity){
- if (++(bat->gBatCapacityDisChargeCnt) >= NUM_DISCHARGE_MIN_SAMPLE){
+ if(capacity + 10 > bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE -10; //5s
+ else if(capacity + 7 > bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE -5; //10s
+ else if(capacity + 3> bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE - 2; // 13
+
+ if (++(bat->gBatCapacityDisChargeCnt) >= timer_of_discharge_sample){
bat->gBatCapacityDisChargeCnt = 0;
if (bat->bat_capacity > 0){
bat->bat_capacity-- ;
new_capacity = gBatteryData->bat_capacity;
old_capacity = rk30_adc_battery_load_capacity();
+
+ pr_bat("------------old_capacity---%d\n",old_capacity);
if ((old_capacity <= 0) || (old_capacity >= 100)){
old_capacity = new_capacity;
}
}
- //printk("capacity = %d, new_capacity = %d, old_capacity = %d\n",gBatteryData->bat_capacity, new_capacity, old_capacity);
+ pr_bat("capacity = %d, new_capacity = %d, old_capacity = %d\n",gBatteryData->bat_capacity, new_capacity, old_capacity);
gBatteryData->bat_change = 1;
}
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
if (psy->type == POWER_SUPPLY_TYPE_USB)
- val->intval = get_msc_connect_flag();
+ // val->intval = get_msc_connect_flag();
+ if (gBatteryData->pdata->spport_usb_charging) //is usb charging
+ if(gBatteryData->pdata->is_usb_charging)
+ val->intval = gBatteryData ->pdata->is_usb_charging();
+
printk("%s:%d\n",__FUNCTION__,val->intval);
break;
gBatteryData->resume = false;
}
#endif
-
-
+
rk30_adc_battery_status_samples(gBatteryData);
if (gBatteryData->poweron_check){
rk30_adc_battery_voltage_samples(gBatteryData);
rk30_adc_battery_capacity_samples(gBatteryData);
- if( 1 == rk30_adc_battery_get_charge_level(gBatteryData)){ // charge
- if(0 == gBatteryData->status_lock ){
- wake_lock(&batt_wake_lock); //lock
- gBatteryData->status_lock = 1;
- }
- }
- else{
- if(1 == gBatteryData->status_lock ){
- wake_unlock(&batt_wake_lock); //unlock
- gBatteryData->status_lock = 0;
+ if( 0 == gBatteryData ->pdata ->charging_sleep){
+ if( 1 == rk30_adc_battery_get_charge_level(gBatteryData)){ // charge
+ if(0 == gBatteryData->status_lock ){
+ wake_lock(&batt_wake_lock); //lock
+ gBatteryData->status_lock = 1;
+ }
}
+ else{
+ if(1 == gBatteryData->status_lock ){
+ wake_unlock(&batt_wake_lock); //unlock
+ gBatteryData->status_lock = 0;
+ }
+ }
}
gBatteryData->bat_change = 0;
rk30_adc_battery_put_capacity(gBatteryData->bat_capacity);
power_supply_changed(&rk30_battery_supply);
+#if defined (CONFIG_BATTERY_RK30_AC_CHARGE)
+ if (gBatteryData->pdata->dc_det_pin == INVALID_GPIO){
+ power_supply_changed(&rk30_ac_supply);
+ }
+#endif
}
if (rk30_battery_dbg_level){
{
AdcTestCnt = 0;
- printk("Status = %d, RealAdcVal = %d, RealVol = %d,gBatVol = %d, gBatCap = %d, RealCapacity = %d, dischargecnt = %d, chargecnt = %d\n",
- gBatteryData->bat_status, gBatteryData->adc_val, adc_to_voltage(gBatteryData->adc_val),
+ pr_bat("Status = %d, RealAdcVal = %d, RealVol = %d,gBatVol = %d, gBatCap = %d, RealCapacity = %d, dischargecnt = %d, chargecnt = %d\n",
+ gBatteryData->bat_status, gBatteryData->adc_val, rk_adc_voltage(gBatteryData->adc_val),
gBatteryData->bat_voltage, gBatteryData->bat_capacity, gBatteryData->capacitytmp, gBatteryData->gBatCapacityDisChargeCnt,gBatteryData-> gBatCapacityChargeCnt);
}
if (pdata->io_init) {
pdata->io_init();
+ return 0;
}
//charge control pin
return -1;
}
-//extern void kernel_power_off(void);
+extern void kernel_power_off(void);
static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat)
{
int i;
}
-
+#if 0
#if 1
rk30_adc_battery_poweron_capacity_check();
#else
gBatteryData->poweron_check = 1;
#endif
gBatteryData->poweron_check = 0;
-
+#endif
/*******************************************
//¿ª»ú²ÉÑùµ½µÄµçѹºÍÉϴιػú±£´æµçѹÏà²î½Ï´ó£¬Ôõô´¦Àí£¿
if (bat->bat_capacity > old_capacity)
if (bat->bat_capacity == 0) bat->bat_capacity = 1;
-#if 0
- if ((bat->bat_voltage <= batt_table[0].dis_charge_vol+ 50)&&(bat->bat_status != POWER_SUPPLY_STATUS_CHARGING)){
- kernel_power_off();
- }
-#endif
+ if(1==gBatteryData -> pdata->low_voltage_protection)
+
+ if ((bat->bat_voltage <= batt_table[0].dis_charge_vol+ 50)&&(bat->bat_status != POWER_SUPPLY_STATUS_CHARGING)){
+ kernel_power_off();
+ }
+
}
static void rk30_adc_battery_callback(struct adc_client *client, void *param, int result)
ret = -ENOMEM;
goto err_data_alloc_failed;
}
+
+ memset(data, 0, sizeof(struct rk30_adc_battery_data));
gBatteryData = data;
-
platform_set_drvdata(pdev, data);
data->pdata = pdata;
memset(data->adc_samples, 0, sizeof(int)*(NUM_VOLTAGE_SAMPLE + 2));
//register adc for battery sample
- client = adc_register(0, rk30_adc_battery_callback, NULL); //pdata->adc_channel = ani0
+ if(0 == pdata->adc_channel)
+ client = adc_register(0, rk30_adc_battery_callback, NULL); //pdata->adc_channel = ani0
+ else
+ client = adc_register(pdata->adc_channel, rk30_adc_battery_callback, NULL);
if(!client)
goto err_adc_register_failed;
data->wq = create_singlethread_workqueue("adc_battd");
INIT_DELAYED_WORK(&data->delay_work, rk30_adc_battery_timer_work);
+
//Power on Battery detect
rk30_adc_battery_check(data);
- queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+ if(1 == pdata->save_capacity ){
+ queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS*10));
+ gBatteryData->poweron_check = 1;
+ }else{
+ queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+ gBatteryData->poweron_check = 0;
+ }
#if defined (CONFIG_BATTERY_RK30_AC_CHARGE)
ret = power_supply_register(&pdev->dev, &rk30_ac_supply);
platform_driver_unregister(&rk30_adc_battery_driver);
}
-subsys_initcall(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+//subsys_initcall(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+module_init(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+
module_exit(rk30_adc_battery_exit);
MODULE_DESCRIPTION("Battery detect driver for the rk30");