fg代码阅读笔记2

来源:互联网 发布:网络3无internet访问 编辑:程序博客网 时间:2024/05/19 15:44

jeita配置

代码路径:
/kernel/msm-3.18/drivers/power/qpnp_smbcharger.c

smbchg_hw_init(struct smbchg_chip *chip)/* configure jeita temperature hard limit */    if (chip->jeita_temp_hard_limit >= 0) {        rc = smbchg_sec_masked_write(chip,chip->chgr_base + CHGR_CCMP_CFG,            JEITA_TEMP_HARD_LIMIT_BIT,chip->jeita_temp_hard_limit            ? 0 : JEITA_TEMP_HARD_LIMIT_BIT);    }smb_parse_dt(struct smbchg_chip *chip)OF_PROP_READ(chip, chip->jeita_temp_hard_limit,"jeita-temp-hard-limit", rc, 1);

看一下这个属性是什么作用?
qcom,jeita-temp-hard-limit property when present will enable or disable the jeita temperature hard limit based on the value 1 or 0. Specify 0 if the jeita temp hard limit needs to be disabled. If it is not present,jeita temperature hard limit will be based on what the bootloader had set earlier.
写1打开jeita hard temp limit写0关闭jieta hard temp limit ???目前代码里没有设置该属性。

这里写图片描述

fg_probe   rc = fg_of_init(chip);    OF_READ_SETTING(FG_MEM_SOFT_HOT, "warm-bat-decidegc", rc, 1);    OF_READ_SETTING(FG_MEM_SOFT_COLD, "cool-bat-decidegc", rc, 1);    OF_READ_SETTING(FG_MEM_HARD_HOT, "hot-bat-decidegc", rc, 1);    OF_READ_SETTING(FG_MEM_HARD_COLD, "cold-bat-decidegc", rc, 1);    //以上会将dtsi中配置的温度信息写入到setings中    if (of_find_property(node, "qcom,cold-hot-jeita-hysteresis", NULL)) {//dtsi中是否配置了高低温迟滞属性        int hard_hot = 0, soft_hot = 0, hard_cold = 0, soft_cold = 0;        rc = of_property_read_u32_array(node,"qcom,cold-hot-jeita-hysteresis", temp, 2);        if (rc) {//将设置的迟滞温度读到temp中            pr_err("Error reading cold-hot-jeita-hysteresis rc=%d\n",rc);            return rc;        }        chip->jeita_hysteresis_support = true;//支持高低温迟滞属性        chip->cold_hysteresis = temp[0];//低温迟滞        chip->hot_hysteresis = temp[1];//高温迟滞        hard_hot = settings[FG_MEM_HARD_HOT].value;        soft_hot = settings[FG_MEM_SOFT_HOT].value;        hard_cold = settings[FG_MEM_HARD_COLD].value;        soft_cold = settings[FG_MEM_SOFT_COLD].value;        if (((hard_hot - chip->hot_hysteresis) < soft_hot) ||((hard_cold + chip->cold_hysteresis) > soft_cold)) {            chip->jeita_hysteresis_support = false;//判断迟滞温度是否合法            pr_err("invalid hysteresis: hot_hysterresis = %d cold_hysteresis = %d\n",chip->hot_hysteresis, chip->cold_hysteresis);        } else {            pr_debug("cold_hysteresis = %d, hot_hysteresis = %d\n",chip->cold_hysteresis, chip->hot_hysteresis);        }    }

申请中断

fg_probe rc = fg_init_irqs(chip);  case FG_BATT:    chip->batt_irq[JEITA_SOFT_COLD].irq =spmi_get_irq_byname(chip->spmi, spmi_resource,    "soft-cold");//通过中断名soft-cold获得中断号    if (chip->batt_irq[JEITA_SOFT_COLD].irq < 0) {        pr_err("Unable to get soft-cold irq\n");        rc = -EINVAL;        return rc;}    rc = devm_request_threaded_irq(chip->dev,chip->batt_irq[JEITA_SOFT_COLD].irq,NULL,    fg_jeita_soft_cold_irq_handler,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT,"soft-cold", chip);//注册申请soft cold中断,中断处理函数fg_jeita_soft_cold_irq_handler,上升沿或下降沿触发    if (rc < 0) {pr_err("Can't request %d soft-cold: %d\n",    chip->batt_irq[JEITA_SOFT_COLD].irq,rc);    return rc;    }        disable_irq(chip->batt_irq[JEITA_SOFT_COLD].irq);//关闭中断        chip->batt_irq[JEITA_SOFT_COLD].disabled = true;//设置关闭中断后变量的状态        chip->batt_irq[JEITA_SOFT_HOT].irq =spmi_get_irq_byname(chip->spmi, spmi_resource,        "soft-hot");//通过中断名soft-hot获得中断号        if (chip->batt_irq[JEITA_SOFT_HOT].irq < 0) {            pr_err("Unable to get soft-hot irq\n");            rc = -EINVAL;            return rc;        }        rc = devm_request_threaded_irq(chip->dev,chip->batt_irq[JEITA_SOFT_HOT].irq,NULL,        fg_jeita_soft_hot_irq_handler,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |        IRQF_ONESHOT,"soft-hot", chip); //注册申请soft hot中断,中断处理函数fg_jeita_soft_cold_irq_handler,上升沿或下降沿触发        if (rc < 0) {            pr_err("Can't request %d soft-hot: %d\n",            chip->batt_irq[JEITA_SOFT_HOT].irq, rc);            return rc;        }        disable_irq(chip->batt_irq[JEITA_SOFT_HOT].irq); //关闭中断        chip->batt_irq[JEITA_SOFT_HOT].disabled = true; //设置关闭中断后变量的状态

先来看中断处理函数做了哪些事情?

fg_jeita_soft_hot_irq_handlerrc = fg_read(chip, &regval, INT_RT_STS(chip->batt_base), 1);//寄存器1218batt_warm = !!(regval & BATT_SOFT_HOT_STS);//电池高温warm状态if (chip->batt_warm == batt_warm) {        pr_debug("warm state not change, ignore!\n");//之前的状态就是warm中断不做处理        return IRQ_HANDLED;    }    chip->batt_warm = batt_warm;if (batt_warm) {        val.intval = POWER_SUPPLY_HEALTH_WARM;        chip->batt_psy->set_property(chip->batt_psy,            POWER_SUPPLY_PROP_HEALTH, &val);//设置health property为POWER_SUPPLY_HEALTH_WARM        /* kick the alarm timer for hard hot polling */        rc = alarm_start_relative(&chip->hard_jeita_alarm,//启动定时器检测电池hot状态                ns_to_ktime(HARD_JEITA_ALARM_CHECK_NS));        if (rc)            pr_err("start alarm for hard HOT detection failed, rc=%d\n",                                    rc);    } else {        val.intval = POWER_SUPPLY_HEALTH_GOOD;        chip->batt_psy->set_property(chip->batt_psy,POWER_SUPPLY_PROP_HEALTH, &val);        /* cancel the alarm timer */        alarm_try_to_cancel(&chip->hard_jeita_alarm);    }    return IRQ_HANDLED;

上面的处理函数中调用alarm_start_relative启动了一个10秒的定时器HARD_JEITA_ALARM_CHECK_NS = 10000000000ns=10000000us=10000ms =10s,这个定时器是在哪里初始化的?
fg_probe
alarm_init(&chip->hard_jeita_alarm, ALARM_BOOTTIME,fg_hard_jeita_alarm_cb);初始化一个定时器hard_jeita_alarm,定时时间到后执行回调函数fg_hard_jeita_alarm_cb
从上面的中断处理程序分析可以知道到soft_hot中断到来后会读状态寄存器1218查看是否是电池高温了,如果是电池warm则设置HEALTH属性,然后启动10s的定时器去检测这时候电池温度有没有达到hard hot的状态。现在就来看10s的回调函数都做了哪些事情?

fg_hard_jeita_alarm_cbrc = fg_read(chip, &regval, BATT_INFO_STS(chip->batt_base), 1);batt_hot = !!(regval & JEITA_HARD_HOT_RT_STS); //batt_hot=1或者batt_hot=0batt_cold = !!(regval & JEITA_HARD_COLD_RT_STS);// batt_cold =1或者batt_cold = 0if (batt_cold != chip->batt_cold) {         /* cool --> cold */        if (chip->batt_cool) {            chip->batt_cool = false;            chip->batt_cold = true;            health = POWER_SUPPLY_HEALTH_COLD;//电池由cool到了cold状态        } else if (chip->batt_cold) { /* cold --> cool */            chip->batt_cool = true;            chip->batt_cold = false;            health = POWER_SUPPLY_HEALTH_COOL; //电池由cold到了cool状态        }    }    if (batt_hot != chip->batt_hot) {        /* warm --> hot */        if (chip->batt_warm) {            chip->batt_warm = false;            chip->batt_hot = true;            health = POWER_SUPPLY_HEALTH_OVERHEAT; //电池由warm到了hot状态        } else if (chip->batt_hot) { /* hot --> warm */            chip->batt_hot = false;            chip->batt_warm = true;            health = POWER_SUPPLY_HEALTH_WARM; //电池由hot到了warm状态        }    }if (health != POWER_SUPPLY_HEALTH_UNKNOWN) {        pr_debug("FG report battery health: %d\n", health);        val.intval = health;        rc = chip->batt_psy->set_property(chip->batt_psy,                POWER_SUPPLY_PROP_HEALTH, &val);再次设置health的属性为cold或者hot        if (rc)            pr_err("Set batt_psy health: %d failed\n", health);    }

上面的分析中最后都调用了rc = chip->batt_psy->set_property(chip->batt_psy,
POWER_SUPPLY_PROP_HEALTH, &val);后面又是如何处理的?

fg_power_set_property    case POWER_SUPPLY_PROP_HEALTH:        chip->health = val->intval;        if (chip->health == POWER_SUPPLY_HEALTH_GOOD) {            fg_stay_awake(&chip->resume_soc_wakeup_source);            schedule_work(&chip->set_resume_soc_work);        }        if (chip->jeita_hysteresis_support)            fg_hysteresis_config(chip);        break;fg_hysteresis_config    hard_hot = get_prop_jeita_temp(chip, FG_MEM_HARD_HOT);    hard_cold = get_prop_jeita_temp(chip, FG_MEM_HARD_COLD);    if (chip->health == POWER_SUPPLY_HEALTH_OVERHEAT && !chip->batt_hot) {        /* turn down the hard hot threshold */        chip->batt_hot = true;        set_prop_jeita_temp(chip, FG_MEM_HARD_HOT,            hard_hot - chip->hot_hysteresis);        if (fg_debug_mask & FG_STATUS)            pr_info("hard hot hysteresis: old hot=%d, new hot=%d\n",                hard_hot, hard_hot - chip->hot_hysteresis);    } else if (chip->health == POWER_SUPPLY_HEALTH_COLD &&        !chip->batt_cold) {        /* turn up the hard cold threshold */        chip->batt_cold = true;        set_prop_jeita_temp(chip, FG_MEM_HARD_COLD,            hard_cold + chip->cold_hysteresis);        if (fg_debug_mask & FG_STATUS)            pr_info("hard cold hysteresis: old cold=%d, new cold=%d\n",                hard_cold, hard_cold + chip->hot_hysteresis);    } else if (chip->health != POWER_SUPPLY_HEALTH_OVERHEAT &&        chip->batt_hot) {        /* restore the hard hot threshold */        set_prop_jeita_temp(chip, FG_MEM_HARD_HOT,            hard_hot + chip->hot_hysteresis);        chip->batt_hot = !chip->batt_hot;        if (fg_debug_mask & FG_STATUS)            pr_info("restore hard hot threshold: old hot=%d, new hot=%d\n",                hard_hot,hard_hot + chip->hot_hysteresis);    } else if (chip->health != POWER_SUPPLY_HEALTH_COLD &&        chip->batt_cold) {        /* restore the hard cold threshold */        set_prop_jeita_temp(chip, FG_MEM_HARD_COLD,            hard_cold - chip->cold_hysteresis);        chip->batt_cold = !chip->batt_cold;        if (fg_debug_mask & FG_STATUS)            pr_info("restore hard cold threshold: old cold=%d, new cold=%d\n",                hard_cold,hard_cold - chip->cold_hysteresis);    }
原创粉丝点击