mtk 电池管理hw_ocv的更新和获取方法

mtk 电池管理hw_ocv的更新和获取方法

[DESCRIPTION]
电量计算过程中,旧gauge算法和GM2.0都会经常用到hw_ocv的值,那到底hw_ocv如何获取?hw_ocv又是何时更新?

[SOLUTION]
1.hw_ocv何时更新:
hw_ocv表示电池的开路电压,我们的做法是让硬件在合适的时间点通过ADC获取电池电压的值保存到对应的寄存器,
在需要用到hw_ocv的值时才会通过软件读寄存器的值,并不会像去读电池CV电压一样通过一个ADC通道实时读取和更新,

hw_ocv对应寄存器的值在如下两个时间点会得到更新:
(1)手机第一次上电时会更新一次,即 AV(LDO)信号起来后2~3mS内会更新一次;
(2)手机休眠唤醒过程会更新一次,即SRCLKEN(26MHz时钟)信号从0->1时更新一次。 
 
2.旧gauge算法获取hw_ocv的方法:
直接通过下面这个回调函数接口,调到battery_meter_hal.c里面对应接口读取寄存器的值
1388 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);

3.GM2.0获取hw_ocv的方法:
从battery_meter_hal.c对应接口读取到寄存器的值后,通过netlink将hw_ocv的值传到GM2.0上层daemon。
/kernel-3.10/drivers/power/mediatek/battery_meter_fg_20.c
       void bmd_ctrl_cmd_from_user(void *nl_data, struct fgd_nl_msg_t *ret_msg)
       {
       
			        switch (msg->fgd_cmd) {
			       
			        case FG_DAEMON_CMD_GET_HW_OCV:
			        {
			        kal_int32 voltage = 0;
			       
			        battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &voltage);
			       
			        ret_msg->fgd_data_len += sizeof(voltage);
			        memcpy(ret_msg->fgd_data, &voltage, sizeof(voltage));
			        //bm_print(BM_LOG_CRTI, " ret_msg->fgd_data_len %d\n",ret_msg->fgd_data_len);
			        bm_print(BM_LOG_CRTI, "[fg_res] voltage = %d\n",voltage);
			        gFG_hwocv = voltage;
        }
       		 break;

 
 4.battery_meter_hal.c里面对应的接口函数如下:
定义宏值SWCHR_POWER_PATH选择不同的通道,分别对应硬件BATSENS & ISENSE两个PIN的电压。
/kernel-3.10/drivers/misc/mediatek/power/mt6735/battery_meter_hal.c

       int get_hw_ocv(void)
       {
			       #if defined(CONFIG_POWER_EXT)
			        return 4001;
			        bm_print(BM_LOG_CRTI, "[get_hw_ocv] TBD\n");
			       #else
			        kal_int32 adc_result_reg=0;
			        kal_int32 adc_result=0;
			        kal_int32 r_val_temp=3; //MT6325 use 2, old chip use 4
			       
			        #if defined(SWCHR_POWER_PATH)
			        adc_result_reg = pmic_get_register_value(PMIC_AUXADC_ADC_OUT_WAKEUP_SWCHR);//mt6325_upmu_get_rg_adc_out_wakeup_swchr();
			        adc_result = (adc_result_reg*r_val_temp*VOLTAGE_FULL_RANGE)/ADC_PRECISE;
			        bm_print(BM_LOG_CRTI, "[oam] get_hw_ocv (swchr) : adc_result_reg=%d, adc_result=%d\n",
			        adc_result_reg, adc_result);
			        #else
			        adc_result_reg = pmic_get_register_value(PMIC_AUXADC_ADC_OUT_WAKEUP_PCHR);//mt6325_upmu_get_rg_adc_out_wakeup_pchr();
			        adc_result = (adc_result_reg*r_val_temp*VOLTAGE_FULL_RANGE)/ADC_PRECISE;
			        bm_print(BM_LOG_CRTI, "[oam] get_hw_ocv (pchr) : adc_result_reg=%d, adc_result=%d\n",
			        adc_result_reg, adc_result);
			        #endif
			       
			        adc_result += g_hw_ocv_tune_value;
			        return adc_result;
			       #endif
       }

猜你喜欢

转载自blog.csdn.net/MrDongShiYi/article/details/85113006
MTK
今日推荐