充电类型如下:
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,此时就会触发高温停充。