1. 程式人生 > >MTK平臺下Battery驅動分析及充電流程

MTK平臺下Battery驅動分析及充電流程

轉自:http://blog.csdn.net/baidu_34021173/article/details/51105223

主要涉及程式碼:

Kernel:

kernel-3.10\drivers\power\mediatek\

kernel-3.10\drivers\misc\mediatek\mach\mt6580\<project_name>\power\

MTK Battery框架結構圖


通過上層通過讀取建立一系列的裝置節點獲取電池相關的狀態資訊


Android電源管理系統
/sys/class/power_supply/ac/online //AC 電源連線狀態 交流電 即電源插座


/sys/class/power_supply/usb/online //USB電源連線狀態


/sys/class/power_supply/battery/status //充電狀態


/sys/class/power_supply/battery/health //電池狀態


/sys/class/power_supply/battery/present //使用狀態


/sys/class/power_supply/battery/capacity //電池 level


/sys/class/power_supply/battery/batt_vol //電池電壓


/sys/class/power_supply/battery/batt_temp //電池溫度


/sys/class/power_supply/battery/technology //電池技術

程式碼框架:


battery_common.c

在Battery驅動模組中,battery_probe函式中會建立一些裝置節點,並且執行一個執行緒bat_thread_kthread獲取電池相關的資料資訊

battery_kthread_hrtimer_init();//檢測電池插入/拔出

kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");

在bat_thread_kthread執行緒中

  1. int bat_thread_kthread(voidvoid *x)  
  2. {  
  3.     ktime_t ktime = ktime_set(30);    
    /* 10s, 10* 1000 ms */
  4. #ifdef BATTERY_CDP_WORKAROUND
  5.     if (is_usb_rdy() == KAL_FALSE) {  
  6.         battery_log(BAT_LOG_CRTI, "CDP, block\n");  
  7.         wait_event(bat_thread_wq, (is_usb_rdy() == KAL_TRUE));  
  8.         battery_log(BAT_LOG_CRTI, "CDP, free\n");  
  9.     } else{  
  10.         battery_log(BAT_LOG_CRTI, "CDP, PASS\n"
    );  
  11.     }  
  12. #endif
  13.     /* Run on a process content */
  14.     while (1) {  
  15.         mutex_lock(&bat_mutex);  
  16.         if (((chargin_hw_init_done == KAL_TRUE) && (battery_suspended == KAL_FALSE)) || ((chargin_hw_init_done == KAL_TRUE) && (fg_wake_up_bat == KAL_TRUE)))  
  17.             BAT_thread();  
  18.         mutex_unlock(&bat_mutex);  
  19. #ifdef FG_BAT_INT
  20.         if(fg_wake_up_bat==KAL_TRUE)  
  21.         {  
  22.             wake_unlock(&battery_fg_lock);  
  23.             fg_wake_up_bat=KAL_FALSE;  
  24.             battery_log(BAT_LOG_CRTI, "unlock battery_fg_lock \n");  
  25.         }  
  26. #endif //#ifdef FG_BAT_INT
  27.         battery_log(BAT_LOG_FULL, "wait event\n");  
  28.         wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));  
  29.         bat_thread_timeout = KAL_FALSE;  
  30.         hrtimer_start(&battery_kthread_timer, ktime, HRTIMER_MODE_REL);  
  31.         ktime = ktime_set(BAT_TASK_PERIOD, 0);  /* 10s, 10* 1000 ms 設定時間為10秒*/
  32.         if (chr_wake_up_bat == KAL_TRUE && g_smartbook_update != 1/* for charger plug in/ out */
  33.         {  
  34.             #if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
  35.             if (DISO_data.chr_get_diso_state) {  
  36.                 DISO_data.chr_get_diso_state = KAL_FALSE;  
  37.                 battery_charging_control(CHARGING_CMD_GET_DISO_STATE, &DISO_data);  
  38.             }  
  39.             #endif
  40.             g_smartbook_update = 0;  
  41.             #if defined(CUST_CAPACITY_OCV2CV_TRANSFORM)
  42.             battery_meter_set_reset_soc(KAL_FALSE);  
  43.             #endif
  44.             battery_meter_reset();  
  45.             chr_wake_up_bat = KAL_FALSE;  
  46.             battery_log(BAT_LOG_CRTI,  
  47.                         "[BATTERY] Charger plug in/out, Call battery_meter_reset. (%d)\n",  
  48.                         BMT_status.UI_SOC);  
  49.         }  
  50.     }  
  51.     return0;  
在這個執行緒中,每隔10s會去呼叫函式BAT_Thread去獲取電池資料

BAT_Thread

  1. void BAT_thread(void)  
  2. {  
  3.     static kal_bool battery_meter_initilized = KAL_FALSE;  
  4.     if (battery_meter_initilized == KAL_FALSE) {  
  5.         battery_meter_initial();    /* move from battery_probe() to decrease booting time 第一次進該函式會進行一些初始化,如設定D0的值(初始電量,構建電池曲線等) table_init, oam_init*/
  6.         BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();  
  7.         battery_meter_initilized = KAL_TRUE;  
  8.     }  
  9.     mt_battery_charger_detect_check();//充電器型號,是否插入等方面的檢測,
  10.     mt_battery_GetBatteryData();//核心函式獲取電池資料
  11.     if (BMT_status.charger_exist == KAL_TRUE) {  
  12.         check_battery_exist();  
  13.     }  
  14.     mt_battery_thermal_check();//電池溫度檢測以及開機mode
  15.     mt_battery_notify_check();//檢測電池電壓,電流等
  16.     if (BMT_status.charger_exist == KAL_TRUE) {  
  17.         mt_battery_CheckBatteryStatus();//充電異常檢測
  18.         mt_battery_charging_algorithm();//切換充電模式 Pre_CC->CC->CV->Full
  19.     }  
  20.     mt_battery_update_status();//上報電池資料
  21.     mt_kpoc_power_off_check();  
  22. }  
mt_battery_GetBatteryData:
  1. void mt_battery_GetBatteryData(void)  
  2. {  
  3.     kal_uint32 bat_vol, charger_vol, Vsense, ZCV;  
  4.     kal_int32 ICharging, temperature, temperatureR, temperatureV, SOC;  
  5.     static kal_int32 bat_sum, icharging_sum, temperature_sum;  
  6.     static kal_int32 batteryVoltageBuffer[BATTERY_AVERAGE_SIZE];  
  7.     static kal_int32 batteryCurrentBuffer[BATTERY_AVERAGE_SIZE];  
  8.     static kal_int32 batteryTempBuffer[BATTERY_AVERAGE_SIZE];  
  9.     static kal_uint8 batteryIndex = 0;  
  10.     static kal_int32 previous_SOC = -1;  
  11.     bat_vol = battery_meter_get_battery_voltage(KAL_TRUE);  
  12.     Vsense = battery_meter_get_VSense();  
  13.     if( upmu_is_chr_det() == KAL_TRUE ) {  
  14.     ICharging = battery_meter_get_charging_current();  
  15.     } else {  
  16.         ICharging = 0;  
  17.     }  
  18.     charger_vol = battery_meter_get_charger_voltage();  
  19.     temperature = battery_meter_get_battery_temperature();  
  20.     temperatureV = battery_meter_get_tempV();  
  21.     temperatureR = battery_meter_get_tempR(temperatureV);  
  22.     if (bat_meter_timeout == KAL_TRUE || bat_spm_timeout == TRUE || fg_wake_up_bat== KAL_TRUE)   
  23.     {  
  24.         SOC = battery_meter_get_battery_percentage();//獲取電池電量
  25.         //if (bat_spm_timeout == true)
  26.             //BMT_status.UI_SOC = battery_meter_get_battery_percentage();
  27.         bat_meter_timeout = KAL_FALSE;  
  28.         bat_spm_timeout = FALSE;  
  29.     } else {  
  30.         if (previous_SOC == -1)  
  31.             SOC = battery_meter_get_battery_percentage();  
  32.         else
  33.             SOC = previous_SOC;  
  34.     }  
  35.     ZCV = battery_meter_get_battery_zcv();  
  36.     BMT_status.ICharging =  
  37.         mt_battery_average_method(BATTERY_AVG_CURRENT, &batteryCurrentBuffer[0], ICharging, &icharging_sum,  
  38.                       batteryIndex);  
  39.     if (previous_SOC == -1 && bat_vol <= batt_cust_data.v_0percent_tracking) {  
  40.         battery_log(BAT_LOG_CRTI,  
  41.                     "battery voltage too low, use ZCV to init average data.\n");  
  42.