mt6735电池状态监测

来源:互联网 发布:stc单片机isp原理 编辑:程序博客网 时间:2024/04/30 03:17

   这里分析下mt6735平台下的电池驱动,使用的bq24296芯片(开关模式的充电方式)。

kernel-3.18/drivers/power/mediatek/battery_common.c

static int battery_probe(struct platform_device *dev){struct class_device *class_dev = NULL;int ret = 0;battery_log(BAT_LOG_CRTI, "******** battery driver probe!! ********\n");/* Integrate with NVRAM */ret = alloc_chrdev_region(&adc_cali_devno, 0, 1, ADC_CALI_DEVNAME);if (ret)battery_log(BAT_LOG_CRTI, "Error: Can't Get Major number for adc_cali\n");adc_cali_cdev = cdev_alloc();adc_cali_cdev->owner = THIS_MODULE;adc_cali_cdev->ops = &adc_cali_fops;ret = cdev_add(adc_cali_cdev, adc_cali_devno, 1);if (ret)battery_log(BAT_LOG_CRTI, "adc_cali Error: cdev_add\n");adc_cali_major = MAJOR(adc_cali_devno);adc_cali_class = class_create(THIS_MODULE, ADC_CALI_DEVNAME);class_dev = (struct class_device *)device_create(adc_cali_class, NULL, adc_cali_devno, NULL, ADC_CALI_DEVNAME);battery_log(BAT_LOG_CRTI, "[BAT_probe] adc_cali prepare : done !!\n ");get_charging_control();batt_init_cust_data();battery_charging_control(CHARGING_CMD_GET_PLATFORM_BOOT_MODE, &g_platform_boot_mode);battery_log(BAT_LOG_CRTI, "[BAT_probe] g_platform_boot_mode = %d\n ", g_platform_boot_mode);wake_lock_init(&battery_fg_lock, WAKE_LOCK_SUSPEND, "battery fg wakelock");wake_lock_init(&battery_suspend_lock, WAKE_LOCK_SUSPEND, "battery suspend wakelock");#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)wake_lock_init(&TA_charger_suspend_lock, WAKE_LOCK_SUSPEND, "TA charger suspend wakelock");#endifmtk_pep_init();mtk_pep20_init();/* Integrate with Android Battery Service */ret = power_supply_register(&(dev->dev), &ac_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register AC Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register AC Success !!\n");ret = power_supply_register(&(dev->dev), &usb_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register USB Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register USB Success !!\n");ret = power_supply_register(&(dev->dev), &wireless_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register WIRELESS Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register WIRELESS Success !!\n");ret = power_supply_register(&(dev->dev), &battery_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register Battery Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register Battery Success !!\n");#if !defined(CONFIG_POWER_EXT)#ifdef CONFIG_MTK_POWER_EXT_DETECTif (KAL_TRUE == bat_is_ext_power()) {battery_main.BAT_STATUS = POWER_SUPPLY_STATUS_FULL;battery_main.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD;battery_main.BAT_PRESENT = 1;battery_main.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION;battery_main.BAT_CAPACITY = 100;battery_main.BAT_batt_vol = 4200;battery_main.BAT_batt_temp = 220;g_bat_init_flag = KAL_TRUE;return 0;}#endif/* For EM */{int ret_device_file = 0;ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Charger_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_0_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_1_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_2_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_3_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_4_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_5_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_6_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_7_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_8_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_9_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_10_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_11_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_12_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_13_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_0_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_1_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_2_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_3_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_4_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_5_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_6_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_7_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_8_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_9_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_10_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_11_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_12_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_13_Offset);ret_device_file =device_create_file(&(dev->dev), &dev_attr_ADC_Channel_Is_Calibration);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Power_On_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Power_Off_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charger_TopOff_Value);ret_device_file =device_create_file(&(dev->dev), &dev_attr_FG_Battery_CurrentConsumption);ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_SW_CoulombCounter);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charging_CallState);ret_device_file = device_create_file(&(dev->dev), &dev_attr_V_0Percent_Tracking);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charger_Type);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Pump_Express);}/* battery_meter_initial();      //move to mt_battery_GetBatteryData() to decrease booting time *//* Initialization BMT Struct */BMT_status.bat_exist = KAL_TRUE;/* phone must have battery */BMT_status.charger_exist = KAL_FALSE;/* for default, no charger */BMT_status.bat_vol = 0;BMT_status.ICharging = 0;BMT_status.temperature = 0;BMT_status.charger_vol = 0;BMT_status.total_charging_time = 0;BMT_status.PRE_charging_time = 0;BMT_status.CC_charging_time = 0;BMT_status.TOPOFF_charging_time = 0;BMT_status.POSTFULL_charging_time = 0;BMT_status.SOC = 0;BMT_status.UI_SOC = 0;BMT_status.bat_charging_state = CHR_PRE;BMT_status.bat_in_recharging_state = KAL_FALSE;BMT_status.bat_full = KAL_FALSE;BMT_status.nPercent_ZCV = 0;BMT_status.nPrecent_UI_SOC_check_point = battery_meter_get_battery_nPercent_UI_SOC();#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)dual_input_init();#endif/* battery kernel thread for 10s check and charger in/out event *//* Replace GPT timer by hrtime */battery_kthread_hrtimer_init();kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");battery_log(BAT_LOG_CRTI, "[battery_probe] bat_thread_kthread Done\n");charger_hv_detect_sw_workaround_init();/*LOG System Set */init_proc_log();#else/* keep HW alive *//* charger_hv_detect_sw_workaround_init(); */#endifg_bat_init_flag = KAL_TRUE;#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)if ((g_vcdt_irq_delay_flag == KAL_TRUE) || (upmu_is_chr_det() == KAL_TRUE))do_chrdet_int_task();#endifreturn 0;}

get_charging_control();//获取bq24296的接口

batt_init_cust_data();//获取dts中配置的电池数据

battery_kthread_hrtimer_init();//初始化高精度定时器,每10s唤醒bat_thread_kthread

kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");//创建内核线程

ret = power_supply_register(&(dev->dev), &battery_main.psy);//注册电池电源


get_charging_control();指针数组初始化

typedef signed int(*CHARGING_CONTROL) (CHARGING_CTRL_CMD cmd, void *data);CHARGING_CONTROL battery_charging_control;static void get_charging_control(void){battery_charging_control = chr_control_interface;}signed int chr_control_interface(CHARGING_CTRL_CMD cmd, void *data){    static signed int init = -1;    if (init == -1) {        init = 0;        charging_func[CHARGING_CMD_INIT] = charging_hw_init;        charging_func[CHARGING_CMD_DUMP_REGISTER] = charging_dump_register;        charging_func[CHARGING_CMD_ENABLE] = charging_enable;        charging_func[CHARGING_CMD_SET_CV_VOLTAGE] = charging_set_cv_voltage;        charging_func[CHARGING_CMD_GET_CURRENT] = charging_get_current;        charging_func[CHARGING_CMD_SET_CURRENT] = charging_set_current;        charging_func[CHARGING_CMD_SET_INPUT_CURRENT] = charging_set_input_current;        charging_func[CHARGING_CMD_GET_CHARGING_STATUS] =  charging_get_charging_status;        charging_func[CHARGING_CMD_RESET_WATCH_DOG_TIMER] = charging_reset_watch_dog_timer;        charging_func[CHARGING_CMD_SET_HV_THRESHOLD] = charging_set_hv_threshold;        charging_func[CHARGING_CMD_GET_HV_STATUS] = charging_get_hv_status;        charging_func[CHARGING_CMD_GET_BATTERY_STATUS] = charging_get_battery_status;        charging_func[CHARGING_CMD_GET_CHARGER_DET_STATUS] = charging_get_charger_det_status;        charging_func[CHARGING_CMD_GET_CHARGER_TYPE] = charging_get_charger_type;        charging_func[CHARGING_CMD_SET_PLATFORM_RESET] = charging_set_platform_reset;        charging_func[CHARGING_CMD_GET_PLATFORM_BOOT_MODE] = charging_get_platform_boot_mode;        charging_func[CHARGING_CMD_SET_POWER_OFF] = charging_set_power_off;        charging_func[CHARGING_CMD_SET_TA_CURRENT_PATTERN] = charging_set_ta_current_pattern;        charging_func[CHARGING_CMD_SET_ERROR_STATE] = charging_set_error_state;        charging_func[CHARGING_CMD_DISO_INIT] = charging_diso_init;        charging_func[CHARGING_CMD_GET_DISO_STATE] = charging_get_diso_state;        charging_func[CHARGING_CMD_SET_VBUS_OVP_EN] = charging_set_vbus_ovp_en;        charging_func[CHARGING_CMD_SET_VINDPM] = charging_set_vindpm;    }    if (cmd < CHARGING_CMD_NUMBER) {        if (charging_func[cmd] != NULL)            return charging_func[cmd](data);    }    pr_debug("[%s]UNSUPPORT Function: %d\n", __func__, cmd);    return STATUS_UNSUPPORTED;}

power_supply_register(&(dev->dev), &battery_main.psy);

上层要获取电池属性,相当于直接获取全局结构体battery_data的值。

struct battery_data {    struct power_supply psy;    int BAT_STATUS;    int BAT_HEALTH;    int BAT_PRESENT;    int BAT_TECHNOLOGY;    int BAT_CAPACITY;    /* Add for Battery Service */    int BAT_batt_vol;    int BAT_batt_temp;    /* Add for EM */    int BAT_TemperatureR;    int BAT_TempBattVoltage;    int BAT_InstatVolt;    int BAT_BatteryAverageCurrent;    int BAT_BatterySenseVoltage;    int BAT_ISenseVoltage;    int BAT_ChargerVoltage;    /* Dual battery */    int status_smb;    int capacity_smb;    int present_smb;    int adjust_power;};static enum power_supply_property battery_props[] = {    POWER_SUPPLY_PROP_STATUS,    POWER_SUPPLY_PROP_HEALTH,    POWER_SUPPLY_PROP_PRESENT,    POWER_SUPPLY_PROP_TECHNOLOGY,    POWER_SUPPLY_PROP_CAPACITY,    /* Add for Battery Service */    POWER_SUPPLY_PROP_batt_vol,    POWER_SUPPLY_PROP_batt_temp,    /* Add for EM */    POWER_SUPPLY_PROP_TemperatureR,    POWER_SUPPLY_PROP_TempBattVoltage,    POWER_SUPPLY_PROP_InstatVolt,    POWER_SUPPLY_PROP_BatteryAverageCurrent,    POWER_SUPPLY_PROP_BatterySenseVoltage,    POWER_SUPPLY_PROP_ISenseVoltage,    POWER_SUPPLY_PROP_ChargerVoltage,    /* Dual battery */    POWER_SUPPLY_PROP_status_smb,    POWER_SUPPLY_PROP_capacity_smb,    POWER_SUPPLY_PROP_present_smb,    /* ADB CMD Discharging */    POWER_SUPPLY_PROP_adjust_power,}; static int battery_get_property(struct power_supply *psy,                enum power_supply_property psp, union power_supply_propval *val){    int ret = 0;    struct battery_data *data = container_of(psy, struct battery_data, psy);    switch (psp) {    case POWER_SUPPLY_PROP_STATUS:        val->intval = data->BAT_STATUS;        break;    case POWER_SUPPLY_PROP_HEALTH:        val->intval = data->BAT_HEALTH;        break;    case POWER_SUPPLY_PROP_PRESENT:        val->intval = data->BAT_PRESENT;        break;    case POWER_SUPPLY_PROP_TECHNOLOGY:        val->intval = data->BAT_TECHNOLOGY;        break;    case POWER_SUPPLY_PROP_CAPACITY:        val->intval = data->BAT_CAPACITY;        break;    case POWER_SUPPLY_PROP_batt_vol:        val->intval = data->BAT_batt_vol;        break;    case POWER_SUPPLY_PROP_batt_temp:        val->intval = data->BAT_batt_temp;        break;    case POWER_SUPPLY_PROP_TemperatureR:        val->intval = data->BAT_TemperatureR;        break;    case POWER_SUPPLY_PROP_TempBattVoltage:        val->intval = data->BAT_TempBattVoltage;        break;    case POWER_SUPPLY_PROP_InstatVolt:        val->intval = data->BAT_InstatVolt;        break;    case POWER_SUPPLY_PROP_BatteryAverageCurrent:        val->intval = data->BAT_BatteryAverageCurrent;        break;    case POWER_SUPPLY_PROP_BatterySenseVoltage:        val->intval = data->BAT_BatterySenseVoltage;        break;    case POWER_SUPPLY_PROP_ISenseVoltage:        val->intval = data->BAT_ISenseVoltage;        break;    case POWER_SUPPLY_PROP_ChargerVoltage:        val->intval = data->BAT_ChargerVoltage;        break;        /* Dual battery */    case POWER_SUPPLY_PROP_status_smb:        val->intval = data->status_smb;        break;    case POWER_SUPPLY_PROP_capacity_smb:        val->intval = data->capacity_smb;        break;    case POWER_SUPPLY_PROP_present_smb:        val->intval = data->present_smb;        break;    case POWER_SUPPLY_PROP_adjust_power:        val->intval = data->adjust_power;        break;    default:        ret = -EINVAL;        break;    }    return ret;}/* battery_data initialization */static struct battery_data battery_main = {.psy = {.name = "battery",.type = POWER_SUPPLY_TYPE_BATTERY,.properties = battery_props,.num_properties = ARRAY_SIZE(battery_props),.get_property = battery_get_property,},/* CC: modify to have a full power supply status */#if defined(CONFIG_POWER_EXT).BAT_STATUS = POWER_SUPPLY_STATUS_FULL,.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD,.BAT_PRESENT = 1,.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION,.BAT_CAPACITY = 100,.BAT_batt_vol = 4200,.BAT_batt_temp = 22,/* Dual battery */.status_smb = POWER_SUPPLY_STATUS_NOT_CHARGING,.capacity_smb = 50,.present_smb = 0,/* ADB CMD discharging */.adjust_power = -1,#else.BAT_STATUS = POWER_SUPPLY_STATUS_NOT_CHARGING,.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD,.BAT_PRESENT = 1,.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION,#if defined(PUMP_EXPRESS_SERIES).BAT_CAPACITY = -1,#else.BAT_CAPACITY = 50,#endif.BAT_batt_vol = 0,.BAT_batt_temp = 0,/* Dual battery */.status_smb = POWER_SUPPLY_STATUS_NOT_CHARGING,.capacity_smb = 50,.present_smb = 0,/* ADB CMD discharging */.adjust_power = -1,#endif};


下面看下电池线程函数

void BAT_thread(void){    static kal_bool battery_meter_initilized = KAL_FALSE;    static int first_time_update;    if (battery_meter_initilized == KAL_FALSE) {        battery_meter_initial();    /* move from battery_probe() to decrease booting time */        BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();        battery_meter_initilized = KAL_TRUE;    }    mt_battery_charger_detect_check();    if (fg_battery_shutdown)        return;    mt_battery_GetBatteryData();    if (fg_battery_shutdown)        return;    if (BMT_status.charger_exist == KAL_TRUE)        check_battery_exist();    mt_battery_thermal_check();    mt_battery_notify_check();    if (first_time_update == 0) {        mt_battery_update_status();        if (BMT_status.charger_exist == KAL_TRUE) {            mt_battery_CheckBatteryStatus();            mt_battery_charging_algorithm();        }        first_time_update = 1;    } else {        if (BMT_status.charger_exist == KAL_TRUE && !fg_battery_shutdown) {            mt_battery_CheckBatteryStatus();            mt_battery_charging_algorithm();        }        mt_battery_update_status();    }    mt_kpoc_power_off_check();}int bat_thread_kthread(void *x){ktime_t ktime = ktime_set(3, 0);/* 10s, 10* 1000 ms *//* Run on a process content */while (!fg_battery_shutdown) {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_INTif (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);/* 10s, 10* 1000 ms */if (!fg_battery_shutdown)ktime = ktime_set(BAT_TASK_PERIOD, 0);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);}#endifg_smartbook_update = 0;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);}}mutex_lock(&bat_mutex);fg_bat_thread = KAL_TRUE;mutex_unlock(&bat_mutex);return 0;}

mt_battery_charger_detect_check//检测充电器的类型
mt_battery_GetBatteryData()//获取电池数据
mt_battery_thermal_check()/电池温度检查
mt_battery_notify_check();//电池其他参数检查
mt_battery_charging_algorithm();充电算法(充电硬件初始化,选择充电电流)
mt_battery_update_status()//更新电池数据


mt_battery_GetBatteryData

void mt_battery_GetBatteryData(void){unsigned int bat_vol, charger_vol, Vsense, ZCV;signed int ICharging, temperature, temperatureR, temperatureV, SOC;static signed int bat_sum, icharging_sum, temperature_sum;static signed int batteryVoltageBuffer[BATTERY_AVERAGE_SIZE];static signed int batteryCurrentBuffer[BATTERY_AVERAGE_SIZE];static signed int batteryTempBuffer[BATTERY_AVERAGE_SIZE];static unsigned char batteryIndex;static signed int previous_SOC = -1;kal_bool current_sign;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();elseICharging = 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();elseSOC = 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");BMT_status.bat_vol =    mt_battery_average_method(BATTERY_AVG_VOLT, &batteryVoltageBuffer[0], ZCV,      &bat_sum, batteryIndex);} else {BMT_status.bat_vol =    mt_battery_average_method(BATTERY_AVG_VOLT, &batteryVoltageBuffer[0], bat_vol,      &bat_sum, batteryIndex);}if (battery_cmd_thermal_test_mode == 1) {battery_log(BAT_LOG_CRTI, "test mode , battery temperature is fixed.\n");} else {BMT_status.temperature =    mt_battery_average_method(BATTERY_AVG_TEMP, &batteryTempBuffer[0], temperature,      &temperature_sum, batteryIndex);}BMT_status.Vsense = Vsense;BMT_status.charger_vol = charger_vol;BMT_status.temperatureV = temperatureV;BMT_status.temperatureR = temperatureR;BMT_status.SOC = SOC;BMT_status.ZCV = ZCV;BMT_status.IBattery = battery_meter_get_battery_current();current_sign = battery_meter_get_battery_current_sign();BMT_status.IBattery *= (current_sign ? 1 : (-1));if (BMT_status.charger_exist == KAL_FALSE) {if (BMT_status.SOC > previous_SOC && previous_SOC >= 0)BMT_status.SOC = previous_SOC;}previous_SOC = BMT_status.SOC;batteryIndex++;if (batteryIndex >= BATTERY_AVERAGE_SIZE)batteryIndex = 0;if (g_battery_soc_ready == KAL_FALSE)g_battery_soc_ready = KAL_TRUE;battery_log(BAT_LOG_CRTI,"AvgVbat=(%d,%d),AvgI=(%d,%d),VChr=%d,AvgT=(%d,%d),SOC=(%d,%d),UI_SOC=%d,ZCV=%d,CHR_Type=%d bcct:%d:%d I:%d Ibat:%d\n",    BMT_status.bat_vol, bat_vol, BMT_status.ICharging, ICharging,    BMT_status.charger_vol, BMT_status.temperature, temperature,    previous_SOC, BMT_status.SOC, BMT_status.UI_SOC, BMT_status.ZCV,    BMT_status.charger_type, g_bcct_flag, get_usb_current_unlimited(),    get_bat_charging_current_level(), BMT_status.IBattery / 10);battery_log(BAT_LOG_CRTI, "v=%d,i=%d,t=%d,soc=%d,bcct:%d:%d I:%d Ibat:%d\n",    bat_vol, ICharging, temperature, BMT_status.UI_SOC, g_bcct_flag,    get_usb_current_unlimited(), get_bat_charging_current_level(),    BMT_status.IBattery / 10);}
battery_meter_get_battery_percentage //获取电池电量(方式1通过开路电压与容量的关系 方式2根据开路电压算出初始电量,然后通过库伦积分算出消耗的电量)
BMT_status.bat_vol, bat_vol,     //该段时间的平均电池电压  //电池电压(直接读寄存器)
BMT_status.ICharging        //电流(平台硬件差异这里是0,这里通过的是库仑计获取电流)
BMT_status.charger_vol        //充电器电压  根据pmic6328vcdt脚获取到的电压,根据分压原理算出vbus的电压 其中vcdt还有一个功能,
作为充电器的中断检测,来判断充电器的插拔
BMT_status.temperature, temperature, //电池温度
BMT_status.SOC, BMT_status.UI_SOC //电池容量  电池ui容量
BMT_status.ZCV//电路开路电压
BMT_status.charger_type//充电器类型
g_bcct_flag//充电是否被限流(高温或者其他情况)  
get_bat_charging_current_level(), //获取充电电流等级(bq24296对应的值)


mt_battery_update_status//更新全局结构体battery_data的值,上层便能及时获取到电池的数据

static void mt_battery_update_status(void){#if defined(CONFIG_POWER_EXT)battery_log(BAT_LOG_CRTI, "[BATTERY] CONFIG_POWER_EXT, no update Android.\n");#else{if (skip_battery_update == KAL_FALSE) {battery_log(BAT_LOG_FULL, "mt_battery_update_status.\n");usb_update(&usb_main);ac_update(&ac_main);wireless_update(&wireless_main);battery_update(&battery_main);} else {battery_log(BAT_LOG_CRTI, "skip mt_battery_update_status.\n");skip_battery_update = KAL_FALSE;}}#endif}static void battery_update(struct battery_data *bat_data){    struct power_supply *bat_psy = &bat_data->psy;    kal_bool resetBatteryMeter = KAL_FALSE;    static unsigned int update_cnt = 3;    static unsigned int pre_uisoc;    static unsigned int pre_chr_state;    bat_data->BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION;    bat_data->BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD;    bat_data->BAT_batt_vol = BMT_status.bat_vol;    bat_data->BAT_batt_temp = BMT_status.temperature * 10;    bat_data->BAT_PRESENT = BMT_status.bat_exist;    if ((BMT_status.charger_exist == KAL_TRUE) && (BMT_status.bat_charging_state != CHR_ERROR)) {        if (BMT_status.bat_exist) {    /* charging */            if (BMT_status.bat_vol <= batt_cust_data.v_0percent_tracking)                resetBatteryMeter = mt_battery_0Percent_tracking_check();            else                resetBatteryMeter = mt_battery_100Percent_tracking_check();            bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_CHARGING;        } else {    /* No Battery, Only Charger */            bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_UNKNOWN;            BMT_status.UI_SOC = 0;        }    } else {        /* Only Battery */        bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_NOT_CHARGING;        if (BMT_status.bat_vol <= batt_cust_data.v_0percent_tracking)            resetBatteryMeter = mt_battery_0Percent_tracking_check();        else            resetBatteryMeter = mt_battery_nPercent_tracking_check();    }    if (resetBatteryMeter == KAL_TRUE) {        battery_meter_reset();    } else {        if (BMT_status.bat_full == KAL_TRUE && is_uisoc_ever_100 == KAL_TRUE) {            BMT_status.UI_SOC = 100;            battery_log(BAT_LOG_CRTI, "[recharging] UI_SOC=%d, SOC=%d\n",                    BMT_status.UI_SOC, BMT_status.SOC);        } else {            mt_battery_Sync_UI_Percentage_to_Real();        }    }    battery_log(BAT_LOG_CRTI, "UI_SOC=(%d), resetBatteryMeter=(%d)\n",            BMT_status.UI_SOC, resetBatteryMeter);    /* set RTC SOC to 1 to avoid SOC jump in charger boot.*/    if (BMT_status.UI_SOC <= 1)        set_rtc_spare_fg_value(1);    else        set_rtc_spare_fg_value(BMT_status.UI_SOC);    mt_battery_update_EM(bat_data);    if (cmd_discharging == 1)        bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_CMD_DISCHARGING;    if (adjust_power != -1) {        bat_data->adjust_power = adjust_power;        battery_log(BAT_LOG_CRTI, "adjust_power=(%d)\n", adjust_power);    }#ifdef DLPT_POWER_OFF_EN    /*extern int dlpt_check_power_off(void);*/    if (bat_data->BAT_CAPACITY <= DLPT_POWER_OFF_THD) {        static signed char cnt;        battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] run\n");        if (dlpt_check_power_off() == 1) {            bat_data->BAT_CAPACITY = 0;            cnt++;            battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] SOC=%d to power off\n",                    bat_data->BAT_CAPACITY);            if (cnt >= 2)                kernel_restart("DLPT reboot system");        } else            cnt = 0;    } else {        battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] disable(%d)\n",                bat_data->BAT_CAPACITY);    }#endif    if (update_cnt >= 3) {        /* Update per 60 seconds */        power_supply_changed(bat_psy);        pre_uisoc = BMT_status.UI_SOC;        update_cnt = 0;        pre_chr_state = BMT_status.bat_charging_state;        if (cable_in_uevent == 1)            cable_in_uevent = 0;    } else if ((pre_uisoc != BMT_status.UI_SOC) || (BMT_status.UI_SOC == 0)) {        /* Update when soc change */        power_supply_changed(bat_psy);        pre_uisoc = BMT_status.UI_SOC;        update_cnt = 0;    } else if ((BMT_status.charger_exist == KAL_TRUE) &&            ((pre_chr_state != BMT_status.bat_charging_state) ||            (BMT_status.bat_charging_state == CHR_ERROR))) {        /* Update when changer status change */        power_supply_changed(bat_psy);        pre_chr_state = BMT_status.bat_charging_state;        update_cnt = 0;    } else if (cable_in_uevent == 1) {        /*To prevent interrupt-trigger update from being filtered*/        power_supply_changed(bat_psy);        cable_in_uevent = 0;    } else {        /* No update */        update_cnt++;    }}
mt_battery_0Percent_tracking_check//低于关机电压监测,让ui电池容量减少到0,这时framework层会让系统关机
mt_battery_nPercent_tracking_check//n可自行定制,库仑积分计算的电量跟ocv(开路电压)计算的电量进行同步,保证电量计算的可靠性。
mt_battery_Sync_UI_Percentage_to_Real();//同步ui显示的电量百分比