1. 程式人生 > >高通平臺電池曲線

高通平臺電池曲線

跟電池相關的一些名詞:

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;
}