fg代码阅读笔记2
2017-09-05 14:48
417 查看
jeita配置
代码路径:
/kernel/msm-3.18/drivers/power/qpnp_smbcharger.c
看一下这个属性是什么作用?
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 ???目前代码里没有设置该属性。
![](http://img.blog.csdn.net/20170905144452570?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVld2VuMjAwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
申请中断
先来看中断处理函数做了哪些事情?
上面的处理函数中调用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的回调函数都做了哪些事情?
上面的分析中最后都调用了rc = chip->batt_psy->set_property(chip->batt_psy,
POWER_SUPPLY_PROP_HEALTH, &val);后面又是如何处理的?
代码路径:
/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, ®val, INT_RT_STS(chip->batt_base), 1);//寄存器1218 batt_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_cb rc = fg_read(chip, ®val, BATT_INFO_STS(chip->batt_base), 1); batt_hot = !!(regval & JEITA_HARD_HOT_RT_STS); //batt_hot=1或者batt_hot=0 batt_cold = !!(regval & JEITA_HARD_COLD_RT_STS);// batt_cold =1或者batt_cold = 0 if (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); }
相关文章推荐
- fg代码阅读笔记1
- Discuz!NT代码阅读笔记(3)--网站安装也能自动化:DNT安装时使用到的几个函数解析 (转)
- 梦断代码阅读笔记02
- 梦断代码--阅读笔记2
- gmf logic example 代码阅读笔记
- 梦断代码阅读笔记之三
- 梦断代码阅读笔记之一
- 第一行代码阅读笔记---AndroidMainfest.xml分析
- 代码大全阅读笔记
- 梦断代码阅读笔记之一
- 《深入理解ES6》阅读笔记 --- 用模块封装代码
- linux蓝牙驱动代码阅读笔记
- 梦断代码阅读笔记02
- Typecho 代码阅读笔记(二) - 数据库访问
- Android代码阅读笔记——智能指针
- 自学笔记-16001-代码阅读方法与实践
- nrf51822代码阅读笔记二
- 梦断代码阅读笔记二。
- 视频编码SVC --- JSVM代码阅读笔记(二)
- Caffe代码阅读笔记(2)