展锐jeita电池保护机制

发布时间 2023-12-09 16:23:01作者: 轻轻的吻

充电类型如下:

dcp-jeita-temp-table = <1000 1030 0 4350000>,
	<1150 1180 700000 4350000>,
	<1450 1420 1150000 4350000>,
	<1600 1570 700000 4100000>;
sdp-jeita-temp-table = <1000 1030 0 4350000>,
	<1150 1180 500000 4350000>,
	<1450 1420 500000 4350000>,
	<1600 1570 500000 4100000>;
cdp-jeita-temp-table = <1000 1030 0 4350000>,
	<1150 1180 700000 4350000>,
	<1450 1420 1150000 4350000>,
	<1600 1570 700000 4100000>;
unknown-jeita-temp-table = <1000 1030 0 4350000>,
	<1150 1180 500000 4350000>,
	<1450 1420 500000 4350000>,
	<1600 1570 500000 4100000>;

每种类型的充电接口都有一个temp table表,表中每一行的值代表温度(temp=(值-1000)/10)、恢复温度(temp=(值-1000)/10)、电流(ua)、截止电压。

用cdp端口来举例说明jeita的保护流程:

1、获取充电状态:

cm_get_target_status调用cm_manager_jeita_current_monitor

static int cm_get_target_status(struct charger_manager *cm)
{
        int ret;

        /*
         * Adjust the charging current according to current battery
         * temperature jeita table.
         */
        ret = cm_manager_jeita_current_monitor(cm);  //通过jeita monitor获取充电状态
        if (ret)
                dev_warn(cm->dev, "Errors orrurs when adjusting charging current\n");

        if (!is_ext_pwr_online(cm) || (!is_batt_present(cm) && !allow_charger_enable))
                return POWER_SUPPLY_STATUS_DISCHARGING;

        if (cm_check_thermal_status(cm))  //通过thermal判断充电状态
                return POWER_SUPPLY_STATUS_NOT_CHARGING;

        if (cm->charging_status & (CM_CHARGE_TEMP_OVERHEAT | CM_CHARGE_TEMP_COLD)) {
                dev_warn(cm->dev, "battery overheat or cold is still abnormal\n");
                return POWER_SUPPLY_STATUS_NOT_CHARGING;
        }

        cm_check_charge_health(cm);  //通过health来判断充电状态
        if (cm->charging_status & CM_CHARGE_HEALTH_ABNORMAL) {
                dev_warn(cm->dev, "Charging health is still abnormal\n");
                return POWER_SUPPLY_STATUS_NOT_CHARGING;
        }

        cm_check_charge_voltage(cm);
        if (cm->charging_status & CM_CHARGE_VOLTAGE_ABNORMAL) {
                dev_warn(cm->dev, "Charging voltage is still abnormal\n");
                return POWER_SUPPLY_STATUS_NOT_CHARGING;
        }

        check_charging_duration(cm);
        if (cm->charging_status & CM_CHARGE_DURATION_ABNORMAL) {
                dev_warn(cm->dev, "Charging duration is still abnormal\n");
                return POWER_SUPPLY_STATUS_NOT_CHARGING;
        }

        if (is_full_charged(cm))
                return POWER_SUPPLY_STATUS_FULL;
        /* Charging is allowed. */
        return POWER_SUPPLY_STATUS_CHARGING;
}

 2、 cm_manager_jeita_current_monitor调用cm_manager_adjust_current

static int cm_manager_jeita_current_monitor(struct charger_manager *cm)
{
        struct charger_desc *desc = cm->desc;
        static int last_jeita_status = -1, temp_up_trigger, temp_down_trigger;
        int cur_jeita_status;
        static bool is_normal = true;

        if (!desc->jeita_tab_size)
                return 0;
//判断是否为外部充电
        if (!is_ext_pwr_online(cm)) {  
                if (last_jeita_status != -1)
                        last_jeita_status = -1;

                return 0;
        }
//判断是否关闭jeita功能
//通过/sys/devices/platform/charger-manager/power_supply/battery/charger.0/jeita_control节点 可以关闭jeita功能。
        if (desc->jeita_disabled) {
                if (last_jeita_status != cm->desc->force_jeita_status) {
                        dev_info(cm->dev, "Disable jeita and force jeita state to force_jeita_status\n");
                        last_jeita_status = cm->desc->force_jeita_status;
                        desc->thm_info.thm_adjust_cur = -EINVAL;
                        cm_manager_adjust_current(cm, last_jeita_status);
                }

                return 0;
        }
 //获取jeita状态
        cur_jeita_status = cm_manager_get_jeita_status(cm, desc->temperature);

        dev_info(cm->dev, "current-last jeita status: %d-%d, current temperature: %d\n",
                 cur_jeita_status, last_jeita_status, desc->temperature);

        /*
         * We should give a initial jeita status with adjusting the charging
         * current when pluging in the cabel.
         */
        if (last_jeita_status == -1) {
//调整电流
                is_normal = cm_manager_adjust_current(cm, cur_jeita_status);
                last_jeita_status = cur_jeita_status;
                goto out;
        }

        if (cur_jeita_status > last_jeita_status) {
                temp_down_trigger = 0;

                if (++temp_up_trigger > 2) {
                        is_normal = cm_manager_adjust_current(cm,
                                                              cur_jeita_status);
                        last_jeita_status = cur_jeita_status;
                }
        } else if (cur_jeita_status < last_jeita_status) {
                temp_up_trigger = 0;

                if (++temp_down_trigger > 2) {
                        is_normal = cm_manager_adjust_current(cm,
                                                              cur_jeita_status);
                        last_jeita_status = cur_jeita_status;

 3、

static bool cm_manager_adjust_current(struct charger_manager *cm, int jeita_status)
{
        struct charger_desc *desc = cm->desc;
        int term_volt, target_cur;

        if (jeita_status > desc->jeita_tab_size)
                jeita_status = desc->jeita_tab_size;
//如果jeita_status=0代表电池温度过低,jeita_status=4(table_size)代表电池过热
        if (jeita_status == 0 || jeita_status == desc->jeita_tab_size) {
                dev_warn(cm->dev,
                         "stop charging due to battery overheat or cold\n");

                if (jeita_status == 0) {
                        cm->charging_status &= ~CM_CHARGE_TEMP_OVERHEAT;
                        cm->charging_status |= CM_CHARGE_TEMP_COLD;
                } else {
                        cm->charging_status &= ~CM_CHARGE_TEMP_COLD;
                        cm->charging_status |= CM_CHARGE_TEMP_OVERHEAT;
                }
                return false;
        }

        term_volt = desc->jeita_tab[jeita_status].term_volt;
        target_cur = desc->jeita_tab[jeita_status].current_ua;

        cm->desc->ir_comp.us = term_volt;
        cm->desc->ir_comp.us_lower_limit = term_volt;

        if (cm->desc->cp.cp_running && !cm_check_primary_charger_enabled(cm)) {
                dev_info(cm->dev, "cp target terminate voltage = %d, target current = %d\n",
                         term_volt, target_cur);
                cm->desc->cp.cp_target_ibat = target_cur;
                goto exit;
        }

        dev_info(cm->dev, "target terminate voltage = %d, target current = %d\n",
                 term_volt, target_cur);

        cm->cm_charge_vote->vote(cm->cm_charge_vote, true,
                                 SPRD_VOTE_TYPE_IBAT,
                                 SPRD_VOTE_TYPE_IBAT_ID_JEITA,
                                 SPRD_VOTE_CMD_MIN,
                                 target_cur, cm);
        cm->cm_charge_vote->vote(cm->cm_charge_vote, true,
                                 SPRD_VOTE_TYPE_CCCV,
                                 SPRD_VOTE_TYPE_CCCV_ID_JEITA,
                                 SPRD_VOTE_CMD_MIN,
                                 term_volt, cm);

exit:
        cm->charging_status &= ~(CM_CHARGE_TEMP_OVERHEAT | CM_CHARGE_TEMP_COLD);
        return true;
}

  从cdp-jeita-temp-table表来看当电池温度超过60度时,jeita_status=4,此时就会触发高温停充。