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執行緒中
- int bat_thread_kthread(voidvoid *x)
- {
- ktime_t ktime = ktime_set(3, 0);
- #ifdef BATTERY_CDP_WORKAROUND
- if (is_usb_rdy() == KAL_FALSE) {
- battery_log(BAT_LOG_CRTI, "CDP, block\n");
- wait_event(bat_thread_wq, (is_usb_rdy() == KAL_TRUE));
- battery_log(BAT_LOG_CRTI, "CDP, free\n");
- } else{
- battery_log(BAT_LOG_CRTI, "CDP, PASS\n"
- }
- #endif
- /* Run on a process content */
- while (1) {
- mutex_lock(&bat_mutex);
- if (((chargin_hw_init_done == KAL_TRUE) && (battery_suspended == KAL_FALSE)) || ((chargin_hw_init_done == KAL_TRUE) && (fg_wake_up_bat == KAL_TRUE)))
- BAT_thread();
- mutex_unlock(&bat_mutex);
- #ifdef FG_BAT_INT
- if(fg_wake_up_bat==KAL_TRUE)
- {
- wake_unlock(&battery_fg_lock);
- fg_wake_up_bat=KAL_FALSE;
- battery_log(BAT_LOG_CRTI, "unlock battery_fg_lock \n");
- }
- #endif //#ifdef FG_BAT_INT
- battery_log(BAT_LOG_FULL, "wait event\n");
- wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));
- bat_thread_timeout = KAL_FALSE;
- hrtimer_start(&battery_kthread_timer, ktime, HRTIMER_MODE_REL);
- ktime = ktime_set(BAT_TASK_PERIOD, 0); /* 10s, 10* 1000 ms 設定時間為10秒*/
- if (chr_wake_up_bat == KAL_TRUE && g_smartbook_update != 1) /* for charger plug in/ out */
- {
- #if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)
- if (DISO_data.chr_get_diso_state) {
- DISO_data.chr_get_diso_state = KAL_FALSE;
- battery_charging_control(CHARGING_CMD_GET_DISO_STATE, &DISO_data);
- }
- #endif
- g_smartbook_update = 0;
- #if defined(CUST_CAPACITY_OCV2CV_TRANSFORM)
- battery_meter_set_reset_soc(KAL_FALSE);
- #endif
- battery_meter_reset();
- chr_wake_up_bat = KAL_FALSE;
- battery_log(BAT_LOG_CRTI,
- "[BATTERY] Charger plug in/out, Call battery_meter_reset. (%d)\n",
- BMT_status.UI_SOC);
- }
- }
- return0;
BAT_Thread
- void BAT_thread(void)
- {
- static kal_bool battery_meter_initilized = KAL_FALSE;
- if (battery_meter_initilized == KAL_FALSE) {
- battery_meter_initial(); /* move from battery_probe() to decrease booting time 第一次進該函式會進行一些初始化,如設定D0的值(初始電量,構建電池曲線等) table_init, oam_init*/
- BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();
- battery_meter_initilized = KAL_TRUE;
- }
- mt_battery_charger_detect_check();//充電器型號,是否插入等方面的檢測,
- mt_battery_GetBatteryData();//核心函式獲取電池資料
- if (BMT_status.charger_exist == KAL_TRUE) {
- check_battery_exist();
- }
- mt_battery_thermal_check();//電池溫度檢測以及開機mode
- mt_battery_notify_check();//檢測電池電壓,電流等
- if (BMT_status.charger_exist == KAL_TRUE) {
- mt_battery_CheckBatteryStatus();//充電異常檢測
- mt_battery_charging_algorithm();//切換充電模式 Pre_CC->CC->CV->Full
- }
- mt_battery_update_status();//上報電池資料
- mt_kpoc_power_off_check();
- }
- void mt_battery_GetBatteryData(void)
- {
- kal_uint32 bat_vol, charger_vol, Vsense, ZCV;
- kal_int32 ICharging, temperature, temperatureR, temperatureV, SOC;
- static kal_int32 bat_sum, icharging_sum, temperature_sum;
- static kal_int32 batteryVoltageBuffer[BATTERY_AVERAGE_SIZE];
- static kal_int32 batteryCurrentBuffer[BATTERY_AVERAGE_SIZE];
- static kal_int32 batteryTempBuffer[BATTERY_AVERAGE_SIZE];
- static kal_uint8 batteryIndex = 0;
- static kal_int32 previous_SOC = -1;
- bat_vol = battery_meter_get_battery_voltage(KAL_TRUE);
- Vsense = battery_meter_get_VSense();
- if( upmu_is_chr_det() == KAL_TRUE ) {
- ICharging = battery_meter_get_charging_current();
- } else {
- ICharging = 0;
- }
- charger_vol = battery_meter_get_charger_voltage();
- temperature = battery_meter_get_battery_temperature();
- temperatureV = battery_meter_get_tempV();
- temperatureR = battery_meter_get_tempR(temperatureV);
- if (bat_meter_timeout == KAL_TRUE || bat_spm_timeout == TRUE || fg_wake_up_bat== KAL_TRUE)
- {
- SOC = battery_meter_get_battery_percentage();//獲取電池電量
- //if (bat_spm_timeout == true)
- //BMT_status.UI_SOC = battery_meter_get_battery_percentage();
- bat_meter_timeout = KAL_FALSE;
- bat_spm_timeout = FALSE;
- } else {
- if (previous_SOC == -1)
- SOC = battery_meter_get_battery_percentage();
- else
- SOC = previous_SOC;
- }
- ZCV = battery_meter_get_battery_zcv();
- BMT_status.ICharging =
- mt_battery_average_method(BATTERY_AVG_CURRENT, &batteryCurrentBuffer[0], ICharging, &icharging_sum,
- batteryIndex);
- if (previous_SOC == -1 && bat_vol <= batt_cust_data.v_0percent_tracking) {
- battery_log(BAT_LOG_CRTI,
- "battery voltage too low, use ZCV to init average data.\n");