高通平台电池曲线

跟电池相关的一些名词:

FCC Full-Charge Capacity 满电荷电量
UC Remaining Capacity RC 剩余电量
CC Coulumb Counter 电量计
UUC Unusable Capacity 不可用电量
PC Percentage Charge 剩余电荷占FCC百分比
SoC State of Charge 电量百分比
OCV Open Circuit Voltage 开路电压,电池在开路状态下的端电压称为开路电压
RUC Remaining Usable Capacity RUC=RC-CC-UUC,剩余可用电量

电池dts节点信息   (kernel\Documentation\devicetree\bindings\batterydata)

qcom,battery-type:指明电池类型的字符串; 如qrd-skua-4v35-6500mAh
qcom,batt-id-kohm:电池ID电阻:当一些电池模型的ID电阻在一定范围内浮动时,电池ID电阻可以作为单电池模型数组以支持多ID;
qcom,chg-term-ua= <100000>;:电池的结束充电电流,这里为100mA;就是电池满电的时候的电流;
qcom,default-rbatt-mohm:标称电池电阻值;正常温度下的电池电阻值(取中值)
qcom,fcc-mah=<3200>;电池完全充满的电池容量3200mAh;能放电多少的电流
qcom,max-voltage-uv =<4200000>; 电池最大的额定电压;
qcom,rbatt-capacitive-mohm=<50>;电池的电容电阻; 跟着修改;
qcom,v-cutoff-uv = <3400000>;电池的截止电压,当电池电压低于此值时设备会自动关机;
qcom,flat-ocv-threshold-uv = <3800000>;可以被认为处于平坦放电后的开始下降的阈值;在表格中查找那个电流下降的很快的那个值;

qcom,palladium-batterydata {
        qcom,fcc-mah = <1500>; //电池完全充满的电池容量1500MA;能放多少电流
        qcom,default-rbatt-mohm = <210>; //电池的电阻值
        qcom,rbatt-capacitive-mohm = <50>; //电池的电容电阻
        qcom,flat-ocv-threshold-uv = <3800000>; //表示电池电压开始平坦放电的阈值,当大于这个值时,电池电压下降的快,电池电压下降的慢
        qcom,max-voltage-uv = <4200000>;// 电池最大额定电压
        qcom,v-cutoff-uv = <3400000>;// 电池的截止电压,当电池电压低于此值时设备会自动关机
        qcom,chg-term-ua = <100000>;//电池结束充电时候的电流为 100mA, 电池满电后的充电电流
        qcom,batt-id-kohm = <75>;//电池ID电阻:当一些电池模型的ID电阻在一定范围内浮动时,电池ID电阻可以作为单电池模型数组以支持多ID;
        qcom,battery-type = "palladium_1500mah"; //指明电池类型的字符串;

        //一维查找表节点会将温度编码成fcc查找。该方法的单位摄氏度映射成毫安时。
        qcom,fcc-temp-lut {
                qcom,lut-col-legend = <(-20) 0 25 40 60>;
                qcom,lut-data = <1467 1470 1473 1473 1470>;
        };
        //一个包含温度和百分比的开路电压2维查找表,查找表的单位是百分比和电压的关系 
        qcom,pc-temp-ocv-lut {
                qcom,lut-col-legend = <(-20) 0 25 40 60>;
                qcom,lut-row-legend = <100 95 90 85 80>,
                                <75 70 65 60 55>,
                                <50 45 40 35 30>,
                                <25 20 16 13 11>,  
                                <10 9 8 7 6>,
                                <5 4 3 2 1>,
                                <0>;
                qcom,lut-data = <4175 4173 4167 4162 4157>,
                                <4097 4111 4112 4110 4107>,
                                <4039 4075 4072 4068 4064>,
                                <3963 4017 4025 4026 4025>,
                                <3920 3969 3984 3989 3988>,
                                <3887 3932 3957 3958 3955>,
                                <3856 3898 3929 3928 3925>,
                                <3830 3868 3900 3901 3898>,
                                <3808 3843 3858 3863 3862>,
                                <3793 3821 3827 3827 3827>,
                                <3779 3803 3807 3808 3807>,
                                <3768 3788 3792 3793 3792>,
                                <3757 3779 3780 3780 3779>,
                                <3746 3771 3772 3768 3768>,
                                <3734 3762 3765 3759 3749>,
                                <3722 3747 3753 3744 3730>,
                                <3707 3721 3731 3722 3709>,
                                <3693 3705 3704 3696 3683>,
                                <3678 3698 3687 3678 3667>,
                                <3664 3693 3683 3676 3665>,
                                <3656 3690 3682 3675 3664>,
                                <3646 3687 3681 3674 3662>,
                                <3634 3683 3680 3672 3661>,
                                <3618 3677 3676 3668 3656>,
                                <3599 3667 3667 3655 3639>,
                                <3573 3645 3638 3623 3603>,
                                <3541 3607 3591 3575 3554>,
                                <3496 3550 3528 3511 3490>,
                                <3428 3469 3445 3423 3400>,
                                <3312 3342 3308 3280 3250>,
                                <3000 3000 3000 3000 3000>;
        };
       //一个二维查找表对应于电池充电的内部温度和内部电阻
        qcom,rbatt-sf-lut {
                qcom,lut-col-legend = <(-20) 0 25 40 60>;
                qcom,lut-row-legend = <100 95 90 85 80>,
                                <75 70 65 60 55>,
                                <50 45 40 35 30>,
                                <25 20 16 13 11>,
                                <10 9 8 7 6>,
                                <5 4 3 2 1>,
};

 

static int qpnp_vm_bms_probe(struct spmi_device *spmi)
{

    ......

	/* read battery-id and select the battery profile */
	rc = set_battery_data(chip);
	if (rc) {
		pr_err("Unable to read battery data %d\n", rc);
		goto fail_init;
	}

	/* set the battery profile */
	rc = config_battery_data(chip->batt_data);
	if (rc) {
		pr_err("Unable to config battery data %d\n", rc);
		goto fail_init;
	}

    ...........

}
static int set_battery_data(struct qpnp_bms_chip *chip)
{
	int64_t battery_id;
	int rc = 0;
	struct bms_battery_data *batt_data;
	struct device_node *node;

	battery_id = read_battery_id(chip);
	if (battery_id < 0) {
		pr_err("cannot read battery id err = %lld\n", battery_id);
		return battery_id;
	}
	node = of_find_node_by_name(chip->spmi->dev.of_node,
					"qcom,battery-data");
	if (!node) {
			pr_err("No available batterydata\n");
			return -EINVAL;
	}

	batt_data = devm_kzalloc(chip->dev,
			sizeof(struct bms_battery_data), GFP_KERNEL);
	if (!batt_data) {
		pr_err("Could not alloc battery data\n");
		return -EINVAL;
	}

	batt_data->fcc_temp_lut = devm_kzalloc(chip->dev,
		sizeof(struct single_row_lut), GFP_KERNEL);
	batt_data->pc_temp_ocv_lut = devm_kzalloc(chip->dev,
			sizeof(struct pc_temp_ocv_lut), GFP_KERNEL);
	batt_data->rbatt_sf_lut = devm_kzalloc(chip->dev,
				sizeof(struct sf_lut), GFP_KERNEL);
	batt_data->ibat_acc_lut = devm_kzalloc(chip->dev,
				sizeof(struct ibat_temp_acc_lut), GFP_KERNEL);

	batt_data->max_voltage_uv = -1;
	batt_data->cutoff_uv = -1;
	batt_data->iterm_ua = -1;

	/*
	 * if the alloced luts are 0s, of_batterydata_read_data ignores
	 * them.
	 */
	rc = of_batterydata_read_data(node, batt_data, battery_id);
	if (rc || !batt_data->pc_temp_ocv_lut
		|| !batt_data->fcc_temp_lut
		|| !batt_data->rbatt_sf_lut
		|| !batt_data->ibat_acc_lut) {
		pr_err("battery data load failed\n");
		devm_kfree(chip->dev, batt_data->fcc_temp_lut);
		devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut);
		devm_kfree(chip->dev, batt_data->rbatt_sf_lut);
		devm_kfree(chip->dev, batt_data->ibat_acc_lut);
		devm_kfree(chip->dev, batt_data);
		return rc;
	}

	if (batt_data->pc_temp_ocv_lut == NULL) {
		pr_err("temp ocv lut table has not been loaded\n");
		devm_kfree(chip->dev, batt_data->fcc_temp_lut);
		devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut);
		devm_kfree(chip->dev, batt_data->rbatt_sf_lut);
		devm_kfree(chip->dev, batt_data->ibat_acc_lut);
		devm_kfree(chip->dev, batt_data);

		return -EINVAL;
	}

	/* check if ibat_acc_lut is valid */
	if (!batt_data->ibat_acc_lut->rows) {
		pr_info("ibat_acc_lut not present\n");
		devm_kfree(chip->dev, batt_data->ibat_acc_lut);
		batt_data->ibat_acc_lut = NULL;
	}

	/* Override battery properties if specified in the battery profile */
	if (batt_data->max_voltage_uv >= 0)
		chip->dt.cfg_max_voltage_uv = batt_data->max_voltage_uv;
	if (batt_data->cutoff_uv >= 0)
		chip->dt.cfg_v_cutoff_uv = batt_data->cutoff_uv;

	chip->batt_data = batt_data;

	return 0;
}

  LINUX\android\kernel\drivers\power\batterydata-interface.c

int config_battery_data(struct bms_battery_data *profile)
{
	if (!the_battery) {
		pr_err("Battery data not intialized\n");
		return -ENODEV;
	}

	the_battery->profile = profile;

	pr_debug("Battery profile set - %s\n",
			the_battery->profile->battery_type);

	return 0;
}

 

你可能感兴趣的:(高通)