mt6737电池状态监测

   这里分析下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");
#endif

	mtk_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_DETECT
	if (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(); */
#endif
	g_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();
#endif

	return 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_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);
		/* 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);
			}
#endif

			g_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();
	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");
		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显示的电量百分比



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值