手机里的电池cw2015电量计芯片片到底有多重要

linux(135)
Battery(1)
电池电量计,库仑计,用max17040这颗电量IC去计量电池电量,这种方法比较合理。想起比较遥远的年代,做samsung&s5pc110/sp5v210的时候,计量电量用一个AD口加两个分压电阻就做了,低电量的时候系统一直判断不准确,“低电关机”提示一会有,一会没有,客户那个郁闷呀,“到底是有电还是没电?”。
如下图,通过两个分压电阻,和一个脚去侦测(电池)电压。
一、MAX17040的工作原理
电量计MAX17040,他通过芯片去测量电池电量,芯片本身集成的电路比较复杂,同时可以通过软件上的一些算法去实现一些处理,是测量出的电量更加准确。还有一个好处,就是他 直接 输出数字量,通过IIC直接读取,我们在电路设计、程序处理上更加的统一化。
如下图所示,MAX17040和电池盒主控的关系,一个脚接到电池,检测到的电量信息,通过传到主控。
下面是电路图,电路接口比较简单,,接到的,接到主控的接口,这个我们在程序中要配置。看这个器件比较简单吧。
看下的内部结构,其实这也是一个转换的过程,单独一颗芯片去实现,这样看起来比较专业些。CELL接口,其实就是一个转换的引脚,我们可以看到芯片内部有自己的时钟()控制器之类的,通过采集到的模拟量,转换成数字量,传输给主控。
通过上面的介绍Max17040的硬件、原理我们基本上都了解了,比较简单,下面我们就重点去分析下驱动程序。
二、MAX17040&总体流程
电量计的工作流程比较简单,max17040通过CELL&ADC转换引脚,把电池的相关信息,实时读取,存入max17040相应的寄存器,驱动里 首先 申请一个定时器,记时结束,通过IIC去读取电池状态信息,和老的电池信息对比,如果 有变化,那么上报信息,然后重新计时;这样循环操作,流程如下所示:
三、MAX17040这个电量计驱动,我们主要用到以下知识点
1、IIC的注册(这个在TP、CAMERA中都有分析);
2、linux&中定时器的使用;
3、任务初始化宏;
4、linux定时器调度队列;
5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);
6、AC、USB充电状态的上报,这个和电池电量是一种方法。
7、电池曲线的测量与加入;
1、IIC的注册
IIC这个总线,在工作中用的比较多,TP、CAMERA、电量计、充电IC、音频芯片、电源管理芯片、基本所有的传感器,所以这大家要仔细看下,后面有时间的话单独列一片介绍下IIC,从单片机时代都用的比较多,看来条总线的生命力很强,像C语言一样,很难被同类的东西替代到,至少现在应该是这样的。
看下他结构体的初始化与驱动的申请,这个比较统一,这里就不想想解释了。
()、驱动的注册:
static&const&struct&i2c_device_id&max17040_id[]&=&{&&&&&&{&&max17040&,&0&},&&&&&&{&}&&};&&MODULE_DEVICE_TABLE(i2c,&max17040_id);&&&&static&struct&i2c_driver&max17040_i2c_driver&=&{&&&&&&.driver&=&{&&&&&&&&&&.name&&&=&&max17040&,&&&&&&},&&&&&&.probe&&&&&&=&max17040_probe,&&&&&&.remove&&&&&=&__devexit_p(max17040_remove),&&&&&&.suspend&&&&=&max17040_suspend,&&&&&&.resume&&&&&=&max17040_resume,&&&&&&.id_table&&&=&max17040_id,&&};&&&&static&int&__init&max17040_init(void)&&{&&&&&&printk(&MAX17040&max17040_init&!!\n&);&&&&&&wake_lock_init(&vbus_wake_lock,&WAKE_LOCK_SUSPEND,&&vbus_present&);&&&&&&return&i2c_add_driver(&max17040_i2c_driver);&&}&&module_init(max17040_init);&&
()在中,平台驱动的注册:
static&struct&i2c_board_info&i2c_devs2[]&__initdata&=&{&&#if&defined(CONFIG_BATTERY_MAX17040)&&&&&&{&&&&&&&&&&I2C_BOARD_INFO(&max17040&,&0x36),&&&&&&&&&&.platform_data&=&&max17040_platform_data,&&&&&&},&&#endif&&……………………&&};&&
下图就是我们驱动注册生成的文件;
2、linux&中定时器的使用
定时器,就是定一个时间,&比如:申请一个10秒定时器,linux系统开始计时,到10秒,定时器 清零重新计时并发出信号告知系统计时完成,系统接到这个信号,做相应的处理;
#include&&linux/delay.h&&&#define&MAX17040_DELAY&&&&&&&&&&msecs_to_jiffies(5000)&&
3、任务初始化宏
INIT_WORK(work,func);&&INTI_DELAYED_WORK(work,func);&&INIT_DELAYED_WORK_DEFERRABLE(work,func);&&
任务结构体的初始化完成后,接下来要将任务安排进工作队列。&可采用多种方法来完成这一操作。&首先,利用&queue_work&queue_work_on&work_struct
INIT_DELAYED_WORK_DEFERRABLE(&chip-&work,&max17040_work);&&调度函数&max17040_work加入chip-&work队列;&&
4、linux定时器调度队列
INIT_DELAYED_WORK_DEFERRABLE(&chip-&work,&max17040_work);&&schedule_delayed_work(&chip-&work,&MAX17040_DELAY);&&通过定时器调度队列;&
5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);
&&&&&&&4中的定时器记时完成,就可以调度队列,chip-&work执行:max17040_work函数,把改读取的信息上传,我们看下max17040_work函数的实现:
static&void&max17040_work(struct&work_struct&*work)&&{&&&&&&struct&max17040_chip&*&&&&&&int&old_usb_online,&old_online,&old_vcell,&old_&&&&&&chip&=&container_of(work,&struct&max17040_chip,&work.work);&&&#ifdef&MAX17040_SUPPORT_CURVE&&&&&&&&&&&&if&(g_TimeCount&&=&1200)&{&&&&&&&&&&handle_model(0);&&&&&&&&&&g_TimeCount&=&0;&&&&&&}&&&&&&g_TimeCount++;&&#endif&&&&&&&&old_online&=&chip-&&&&&&&old_usb_online&=&chip-&usb_&&&&&&old_vcell&=&chip-&&&&&&&old_soc&=&chip-&&&&&&&max17040_get_online(chip-&client);&&&&&&max17040_get_vcell(chip-&client);&&&&&&max17040_get_soc(chip-&client);&&&&&&max17040_get_status(chip-&client);&&&&&&&&if&((old_vcell&!=&chip-&vcell)&||&(old_soc&!=&chip-&soc))&{&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&battery);&&&&&&}&&&#if&!defined(CONFIG_CHARGER_PM2301)//(4)、如果用PM2301充电IC,USB充电功能不用;&&&&&&if&(old_usb_online&!=&chip-&usb_online)&{&&&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&usb);&&&&&&}&&#endif&&&&&&&&if&(old_online&!=&chip-&online)&{&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&ac);&&&&&&}&&&&&&&&schedule_delayed_work(&chip-&work,&MAX17040_DELAY);&&}&
()、保存老的电池信息,如电量、AC、USB是否插入
old_online&=&chip-&&&old_usb_online&=&chip-&usb_&&old_vcell&=&chip-&&&old_soc&=&chip-&&&
()、读取电池新的状态信息
max17040_get_online(chip-&client);&&max17040_get_vcell(chip-&client);&&max17040_get_soc(chip-&client);&&max17040_get_status(chip-&client);&&
()、如果电池信息有变化,就上报系统
if&((old_vcell&!=&chip-&vcell)&||&(old_soc&!=&chip-&soc))&{&&&&&&&&&&&&power_supply_changed(&chip-&battery);&&}&&
power_supply_changed这个函数比较重要,&我们后面分析;
()、如果用PM2301充电IC,USB充电功能不用
这个是由于我们的系统耗电比较大,用USB充电时,电流过小,所以出现越充越少的现象,所以这个功能给去掉了。
()、如果有DC插入,则跟新充电状态
power_supply_changed(&chip-&ac);&
6、AC、USB充电状态怎么更新到应用
如上面所说,通过power_supply_changed上报;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2605026次
积分:22222
积分:22222
排名:第246名
原创:370篇
转载:104篇
评论:292条
(2)(6)(1)(2)(1)(1)(3)(1)(1)(3)(5)(4)(4)(5)(1)(4)(10)(5)(3)(8)(2)(2)(6)(4)(9)(5)(5)(16)(6)(20)(24)(18)(6)(8)(5)(1)(15)(4)(19)(35)(35)(21)(18)(21)(7)(2)(21)(31)(38)iPhone6S意外关机换电池有用?是芯片“乱套了”-中商情报网
iPhone6S意外关机换电池有用?是芯片“乱套了”
中关村在线
前段时间闹得沸沸扬扬的iPhone6S意外关机事件,苹果官方虽然承诺免费更换但是对于意外关机的真正原因却始终含糊其辞。近日有爆料称导致iPhone意外关机的罪魁祸首竟是德州仪器。 根据微信公众号摩卡公社透漏的消息,iPhone6S所采用由德州仪器供应的SN27546芯片是前段时间iPhone无故关机的真正原因。该芯片主要为iPhone计算并显示电池电量的使用情况。一般情况下,iPhone电量到达1%的情况时会自动关闭机器,但日前网友反应自己的iPhone在电量到达10%甚至20%时手机就会关机,原因就是由于这块芯片“乱套了”。 对于苹果手机关机门,苹果日前公开表示:“少数于月期间生产的iPhone6S设备中,Ti电量计装进电池包之前在受控环境空气中暴露时间过长,使电池电量消耗速度快于正常水平,导致意外关机,这并不是安全问题。”但是如果消息属实,苹果关机是由于计电芯片导致,那么更换电池则没有任何用处。
【版权提示】中商情报网倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请联系、4,我们将及时沟通与处理。
【数据平台合作】我们的数据自媒体平台“”、数据交易所“”正式上线了!欢迎各位数据自媒体们合作入驻。免费入驻类型:各行业数据自媒体、数据企业。咨询QQ :
中商情报网扫一扫、与您一起发现数据的价值
中商产业研究院扫一扫、每天阅读免费高价值报告
中商情报网始终聚焦科技、互联网+、创业、财经、产经大数据等,目前在全国财经网站中排名居前,旗下中商产业研究院专注产业经济细分市场研究,中商可以为用您提供一手的市场数据和高价值的商业资讯,欢迎沟通交流合作!
广告、内容合作请点这里:
askci Corporation, All Rights Reserved 中商情报网版权所有
增值电信业务经营许可证:粤B2-热门搜索:
当前位置:
芯传科技推出全新锂电池电量计芯片EG2801
芯传科技(EPI)推出一款锂电池电量计芯片,EG2801可精准读取电池电压、电流、温度等讯息,并透过精确的积分及演算作库伦计量。EG2801并提供一组I2C接口与主系统进行通信,广泛适用于便携式装置中。
  芯传科技(EPI)推出一款电量计芯片,EG2801可精准读取电池电压、电流、温度等讯息,并透过精确的积分及演算作库伦计量。EG2801并提供一组I2C接口与主系统进行通信,广泛适用于便携式装置中。  EG2801主要特点 :  I2C 界面  电压/电流精度1%  Time Base 精度 1.5%  温度量测  DFN-12(2.5*4mm))Package  EG2801优势:  提供高精度的电池状态及电量监测。  计算各种条件下的剩余电量。  针对充放状态,时间,电压,电流及温度进行报告。  提供电池温度状况, 有效安全管理电池运行。  无需微处理器及复杂电子电路设计。  EG2801相关应用包括:  平板电脑  智能手机  可携式3C产品  行动电源和电池管理系统
责任编辑:Arunme
免责声明:
本文仅代表作者个人观点,与
OFweek锂电网
无关。其原创性以及文中陈述文字和内容未经本站证实,
对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅
作参考,并请自行核实相关内容。
邮箱/用户名:
忘记密码?
用其他账号登录: QQ
请输入评论
临近年关,锂电行业的企业资本并购渐歇,但是受新版规范条件影响,动力电池企业疯狂扩产。据专家介绍,就目...
广东省/深圳市
四川省/成都市
广东省/深圳市
广东省/深圳市
广东省/深圳市
广东省/深圳市
北京市/海淀区
广东省/深圳市
广东省/深圳市
广东省/惠州市
*文字标题:
*纠错内容:
联系邮箱:
*验 证 码:Android 模块-power(15)
电池电量计,库仑计,用max17040这颗电量IC去计量电池电量,这种方法比较合理。想起比较遥远的年代,做samsung&s5pc110/sp5v210的时候,计量电量用一个AD口加两个分压电阻就做了,低电量的时候系统一直判断不准确,“低电关机”提示一会有,一会没有,客户那个郁闷呀,“到底是有电还是没电?”。
如下图,通过两个分压电阻,和一个脚去侦测(电池)电压。
一、MAX17040的工作原理
电量计MAX17040,他通过芯片去测量电池电量,芯片本身集成的电路比较复杂,同时可以通过软件上的一些算法去实现一些处理,是测量出的电量更加准确。还有一个好处,就是他之接输出数字量,通过IIC直接读取,我们在电路设计、程序处理上更加的统一化。
如下图所示,MAX17040和电池盒主控的关系,一个脚接到电池,检测到的电量信息,通过传到主控。
下面是电路图,电路接口比较简单,,接到的,接到主控的接口,这个我们在程序中要配置。看这个器件比较简单吧。
看下的内部结构,其实这也是一个转换的过程,单独一颗芯片去实现,这样看起来比较专业些。CELL接口,其实就是一个转换的引脚,我们可以看到芯片内部有自己的时钟()控制器之类的,通过采集到的模拟量,转换成数字量,传输给主控。
通过上面的介绍Max17040的硬件、原理我们基本上都了解了,比较简单,下面我们就重点去分析下驱动程序。
二、MAX17040&总体流程
电量计的工作流程比较简单,max17040通过CELL&ADC转换引脚,把电池的相关信息,实时读取,存入max17040相应的寄存器,驱动申请一个定时器,记时结束,通过IIC去读取电池状态信息,和老的电池信息对比,如果用变化上报,然后重新计时;这样循环操作,流程如下所示:
三、MAX17040这个电量计驱动,我们主要用到以下知识点
1、IIC的注册(这个在TP、CAMERA中都有分析);
2、linux&中定时器的使用;
3、任务初始化宏;
4、linux定时器调度队列;
5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);
6、AC、USB充电状态的上报,这个和电池电量是一种方法。
7、电池曲线的测量与加入;
1、IIC的注册
IIC这个总线,在工作中用的比较多,TP、CAMERA、电量计、充电IC、音频芯片、电源管理芯片、基本所有的传感器,所以这大家要仔细看下,后面有时间的话单独列一片介绍下IIC,从单片机时代都用的比较多,看来条总线的生命力很强,像C语言一样,很难被同类的东西替代到,至少现在应该是这样的。
看下他结构体的初始化与驱动的申请,这个比较统一,这里就不想想解释了。
()、驱动的注册:
static&const&struct&i2c_device_id&max17040_id[]&=&{&&&&&&{&&max17040&,&0&},&&&&&&{&}&&};&&MODULE_DEVICE_TABLE(i2c,&max17040_id);&&&&static&struct&i2c_driver&max17040_i2c_driver&=&{&&&&&&.driver&=&{&&&&&&&&&&.name&&&=&&max17040&,&&&&&&},&&&&&&.probe&&&&&&=&max17040_probe,&&&&&&.remove&&&&&=&__devexit_p(max17040_remove),&&&&&&.suspend&&&&=&max17040_suspend,&&&&&&.resume&&&&&=&max17040_resume,&&&&&&.id_table&&&=&max17040_id,&&};&&&&static&int&__init&max17040_init(void)&&{&&&&&&printk(&MAX17040&max17040_init&!!\n&);&&&&&&wake_lock_init(&vbus_wake_lock,&WAKE_LOCK_SUSPEND,&&vbus_present&);&&&&&&return&i2c_add_driver(&max17040_i2c_driver);&&}&&module_init(max17040_init);&&
()在中,平台驱动的注册:
static&struct&i2c_board_info&i2c_devs2[]&__initdata&=&{&&#if&defined(CONFIG_BATTERY_MAX17040)&&&&&&{&&&&&&&&&&I2C_BOARD_INFO(&max17040&,&0x36),&&&&&&&&&&.platform_data&=&&max17040_platform_data,&&&&&&},&&#endif&&……………………&&};&&
下图就是我们驱动注册生成的文件;
2、linux&中定时器的使用
定时器,就是定一个时间,&比如:申请一个10秒定时器,linux系统开始计时,到10秒,请示器清零重新计时并发出信号告知系统计时完成,系统接到这个信号,做相应的处理;
#include&&linux/delay.h&&&#define&MAX17040_DELAY&&&&&&&&&&msecs_to_jiffies(5000)&&
3、任务初始化宏
INIT_WORK(work,func);&&INTI_DELAYED_WORK(work,func);&&INIT_DELAYED_WORK_DEFERRABLE(work,func);&&
任务结构体的初始化完成后,接下来要将任务安排进工作队列。&可采用多种方法来完成这一操作。&首先,利用&queue_work&queue_work_on&work_struct
INIT_DELAYED_WORK_DEFERRABLE(&chip-&work,&max17040_work);&&调度函数&max17040_work加入chip-&work队列;&&
4、linux定时器调度队列
INIT_DELAYED_WORK_DEFERRABLE(&chip-&work,&max17040_work);&&schedule_delayed_work(&chip-&work,&MAX17040_DELAY);&&通过定时器调度队列;&&
5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);
&&&&&&&4中的定时器记时完成,就可以调度队列,chip-&work执行:max17040_work函数,把改读取的信息上传,我们看下max17040_work函数的实现:
static&void&max17040_work(struct&work_struct&*work)&&{&&&&&&struct&max17040_chip&*&&&&&&int&old_usb_online,&old_online,&old_vcell,&old_&&&&&&chip&=&container_of(work,&struct&max17040_chip,&work.work);&&&#ifdef&MAX17040_SUPPORT_CURVE&&&&&&&&&&&&if&(g_TimeCount&&=&1200)&{&&&&&&&&&&handle_model(0);&&&&&&&&&&g_TimeCount&=&0;&&&&&&}&&&&&&g_TimeCount++;&&#endif&&&&&&&&old_online&=&chip-&&&&&&&old_usb_online&=&chip-&usb_&&&&&&old_vcell&=&chip-&&&&&&&old_soc&=&chip-&&&&&&&max17040_get_online(chip-&client);&&&&&&max17040_get_vcell(chip-&client);&&&&&&max17040_get_soc(chip-&client);&&&&&&max17040_get_status(chip-&client);&&&&&&&&if&((old_vcell&!=&chip-&vcell)&||&(old_soc&!=&chip-&soc))&{&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&battery);&&&&&&}&&&#if&!defined(CONFIG_CHARGER_PM2301)//(4)、如果用PM2301充电IC,USB充电功能不用;&&&&&&if&(old_usb_online&!=&chip-&usb_online)&{&&&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&usb);&&&&&&}&&#endif&&&&&&&&if&(old_online&!=&chip-&online)&{&&&&&&&&&&&&&&&&&&&&power_supply_changed(&chip-&ac);&&&&&&}&&&&&&&&schedule_delayed_work(&chip-&work,&MAX17040_DELAY);&&}&&
()、保存老的电池信息,如电量、AC、USB是否插入
old_online&=&chip-&&&old_usb_online&=&chip-&usb_&&old_vcell&=&chip-&&&old_soc&=&chip-&&&
()、读取电池新的状态信息
max17040_get_online(chip-&client);&&max17040_get_vcell(chip-&client);&&max17040_get_soc(chip-&client);&&max17040_get_status(chip-&client);&&
()、如果电池信息有变化,就上报系统
if&((old_vcell&!=&chip-&vcell)&||&(old_soc&!=&chip-&soc))&{&&&&&&&&&&&&power_supply_changed(&chip-&battery);&&}&&
power_supply_changed这个函数比较重要,&我们后面分析;
()、如果用PM2301充电IC,USB充电功能不用
这个是由于我们的系统耗电比较大,用USB充电时,电流过小,所以出现越充越少的现象,所以这个功能给去掉了。
()、如果有DC插入,则跟新充电状态
power_supply_changed(&chip-&ac);&&
6、AC、USB充电状态怎么更新到应用
如上面所说,通过power_supply_changed上报;
7、电池曲线的测量与加入
电池曲线,就是电池的冲放电信息,就是用专业的设备,对电池连续充放电几天,测出一个比较平均的值。然后转换成针对电量IC(如我们用的max17040)的数字量,填入一个数组中,如下图所示:
下面数据时针对电池曲线的数字量,和相关参数。如上图所示,为小时的电池信息,包括:不同颜色分别代表不同的曲线:如
数据表格如下:
Device=MAX17040&&Title&=&012&&EmptyAdjustment&=&0&&FullAdjustment=&100&&RCOMP0=161&&TempCoUp&=0&&TempCoDown&=&-2&&OCVTest&=&56224&&SOCCheckA&=&113&&SOCCheckB&=&115&&bits=&18&&0xC2&0xE8&0x0D&0x37&0x51&0x5B&0x5E&0x62&&&0x6A&0x88&0xA6&0xCB&0xF1&0x3C&0x99&0x1A&&&0x60&0x0D&0x80&0x0D&0xA0&0x01&0xC0&0x0C&&&0xF0&0x0F&0x30&0x0F&0x90&0x06&0x10&0x06&&&&&0xAC&0x20&0xAE&0x80&0xB0&0xD0&0xB3&0x70&&0xB5&0x10&0xB5&0xB0&0xB5&0xE0&0xB6&0x20&&&0xB6&0xA0&0xB8&0x80&0xBA&0x60&0xBC&0xB0&&&0xBF&0x10&0xC3&0xC0&0xC9&0x90&0xD1&0xA0&&&0x02&0x90&0x0E&0x00&0x0C&0x10&0x0E&0x20&&&0x2C&0x60&0x4C&0xB0&0x39&0x80&0x39&0x80&&&0x0C&0xD0&0x0C&0xD0&0x0A&0x10&0x09&0xC0&&&0x08&0xF0&0x07&0xF0&0x05&0x60&0x05&0x60&&&&&0xC0&0x09&0xE0&0x00&0x00&0x01&0x30&0x02&&&0x52&0x06&0x54&0x0B&0x53&0x080x63&&0x08&&&0x29&0xE0&0xC1&0xE2&0xC6&0xCB&0x98&0x98&&&0xCD&0xCD&0xA1&0x9C&0x8F&0x7F&0x56&0x56&&
加入驱动中的值:
unsigned&char&model_data[65]&=&{&&&&&&0x40,&&&&&&&&&0xAC,&0x20,0xAE,&0x80,&0xB0,&0xD0,&0xB3,&0x70,&&&&&&0xB5,&0x10,&0xB5,&0xB0,&0xB5,&0xE0,0xB6,&0x20,&&&&&&0xB6,&0xA0,&0xB8,&0x80,&0xBA,&0x60,&0xBC,&0xB0,&&&&&&0xBF,&0x10,&0xC3,&0xC0,&0xC9,&0x90,&0xD1,&0xA0,&&&&&&0x02,&0x90,&0x0E,&0x00,&0x0C,&0x10,0x0E,&0x20,&&&&&&0x2C,&0x60,0x4C,&0xB0,&0x39,&0x80,&0x39,&0x80,&&&&&&0x0C,&0xD0,0x0C,&0xD0,&&0x0A,&0x10,0x09,&0xC0,&&&&&&0x08,&0xF0,&0x07,&0xF0,&0x05,&0x60,&0x05,&0x60,&&};&&&&unsigned&char&INI_OCVTest_High_Byte&=&0xDB;&&&unsigned&char&INI_OCVTest_Low_Byte&=&0xA0;&&unsigned&char&INI_SOCCheckA&=&0x71;&&unsigned&char&INI_SOCCheckB&=&0x73;&&unsigned&char&INI_RCOMP&=&0xa1;&&unsigned&char&INI_bits&=&18;&&unsigned&char&original_OCV_1;&&unsigned&char&original_OCV_2;&&#elseunsigned&char&INI_RCOMP&=&0x64;&&unsigned&char&INI_bits&=&19;&&unsigned&char&original_OCV_1;&&&strong&unsigned&char&original_OCV_2;&/strong&&&
四、驱动分析
1、函数分析
上面我们简单了解驱动中用到的主要知识点,后面我们把这些点串起来,驱动还是从probe说起;
static&int&__devinit&max17040_probe(struct&i2c_client&*client,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&const&struct&i2c_device_id&*id)&&{&&&&&&struct&i2c_adapter&*adapter&=&to_i2c_adapter(client-&dev.parent);&&&&&&struct&max17040_chip&*&&&&&&int&&&&&&&printk(&MAX17040&probe&!!\n&);&&&&&&&&if&(!i2c_check_functionality(adapter,&I2C_FUNC_SMBUS_BYTE))&&&&&&&&&&return&-EIO;&&&&&&&&chip&=&kzalloc(sizeof(*chip),&GFP_KERNEL);&&&&&&&&if&(!chip)&&&&&&&&&&return&-ENOMEM;&&&&&&&&g_chip&=&&&&&&&g_i2c_client&=&&&&&&&&&chip-&client&=&&&&&&&chip-&pdata&=&client-&dev.platform_&&&&&&i2c_set_clientdata(client,&chip);&&&&&&chip-&battery.name&&&&&&&=&&battery&;&&&&&&chip-&battery.type&&&&&&&=&POWER_SUPPLY_TYPE_BATTERY;&&&&&&chip-&battery.get_property&&&=&max17040_get_&&&&&&chip-&battery.properties&=&max17040_battery_&&&&&&chip-&battery.num_properties&=&ARRAY_SIZE(max17040_battery_props);&&&&&&chip-&battery.external_power_changed&=&NULL;&&&&&&ret&=&power_supply_register(&client-&dev,&&chip-&battery);&&&&&&if&(ret)&&&&&&&&&&goto&err_battery_&&&&&&&&&&chip-&ac.name&&&&&&&&=&&ac&&&&&&&chip-&ac.type&&&&&&&&=&POWER_SUPPLY_TYPE_MAINS;&&&&&&chip-&ac.get_property&&&&=&adapter_get_&&&&&&chip-&ac.properties&&=&adapter_get_&&&&&&chip-&ac.num_properties&&=&ARRAY_SIZE(adapter_get_props);&&&&&&chip-&ac.external_power_changed&=&NULL;&&&&&&ret&=&power_supply_register(&client-&dev,&&chip-&ac);&&&&&&if&(ret)&&&&&&&&&&goto&err_ac_&&&&#if&!defined(CONFIG_CHARGER_PM2301)&&&&&&chip-&usb.name&&&&&&&=&&usb&;&&&&&&chip-&usb.type&&&&&&&=&POWER_SUPPLY_TYPE_USB;&&&&&&chip-&usb.get_property&&&=&usb_get_&&&&&&chip-&usb.properties&=&usb_get_&&&&&&chip-&usb.num_properties&=&ARRAY_SIZE(usb_get_props);&&&&&&chip-&usb.external_power_changed&=&NULL;&&&&&&ret&=&power_supply_register(&client-&dev,&&chip-&usb);&&&&&&if&(ret)&&&&&&&&&&goto&err_usb_&&&&&&&&if&(chip-&pdata-&hw_init&&&&!(chip-&pdata-&hw_init()))&{&&&&&&&&&&dev_err(&client-&dev,&&hardware&initial&failed.\n&);&&&&&&&&&&goto&err_hw_init_&&&&&&}&&#endif&&&#ifdef&MAX17040_SUPPORT_CURVE&&&&&&&g_TimeCount&=&0;&&&&&&&handle_model(0);&&#endif&&&&&&max17040_get_version(client);&&&&&&battery_initial&=&1;&&&&&&&&INIT_DELAYED_WORK_DEFERRABLE(&chip-&work,&max17040_work);&&&&&&schedule_delayed_work(&chip-&work,&MAX17040_DELAY);&&&&&&&&&&printk(&MAX17040&probe&success!!\n&);&&&&&&return&0;&&&&err_hw_init_failed:&&&&&&power_supply_unregister(&chip-&usb);&&err_usb_failed:&&&&&&power_supply_unregister(&chip-&ac);&&err_ac_failed:&&&&&&power_supply_unregister(&chip-&battery);&&err_battery_failed:&&&&&&dev_err(&client-&dev,&&failed:&power&supply&register\n&);&&&&&&i2c_set_clientdata(client,&NULL);&&&&&&kfree(chip);&&&&&&return&&&}&&
(1)、驱动部分申请;
(3)、获取电池信息;
通过传递下来的参数,来读取结构体中相应的状态,这个函数实现比较简单。
static&int&max17040_get_property(struct&power_supply&*psy,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&enum&power_supply_property&psp,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&union&power_supply_propval&*val)&&{&&&&&&struct&max17040_chip&*chip&=&container_of(psy,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&struct&max17040_chip,&battery);&&&&&&&&switch&(psp)&{&&&&&&case&POWER_SUPPLY_PROP_STATUS:&&&&&&&&&&val-&intval&=&chip-&&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_ONLINE:&&&&&&&&&&val-&intval&=&chip-&&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_VOLTAGE_NOW:&&&&&&case&POWER_SUPPLY_PROP_PRESENT:&&&&&&&&&&val-&intval&=&chip-&&&&&&&&&&&&&if&(psp&&==&POWER_SUPPLY_PROP_PRESENT)&&&&&&&&&&&&&&val-&intval&=&1;&&&&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_CAPACITY:&&&&&&&&&&val-&intval&=&chip-&&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_TECHNOLOGY:&&&&&&&&&&val-&intval&=&POWER_SUPPLY_TECHNOLOGY_LION;&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_HEALTH:&&&&&&&&&&if&(chip-&vcell&&&&2850)&&&&&&&&&&&&&&val-&intval&=&POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;&&&&&&&&&&else&&&&&&&&&&&&&&val-&intval&=&POWER_SUPPLY_HEALTH_GOOD;&&&&&&&&&&&&break;&&&&&&&&case&POWER_SUPPLY_PROP_TEMP:&&&&&&&&&&val-&intval&=&365;&&&&&&&&&&break;&&&&&&&&default:&&&&&&&&&&return&-EINVAL;&&&&&&}&&&&&&&&return&0;&&}&&
(4)电池各种信息
static&enum&power_supply_property&max17040_battery_props[]&=&{&&&&&&&&&&&&&&POWER_SUPPLY_PROP_PRESENT,&&&&&&&&&&&&&&POWER_SUPPLY_PROP_STATUS,&&&&&&&&&&&&&&&&&&&&&&&&&&&&POWER_SUPPLY_PROP_VOLTAGE_NOW,&&&&&&&&&&&&&&POWER_SUPPLY_PROP_CAPACITY,&&&&&&&&&&&&&&POWER_SUPPLY_PROP_TECHNOLOGY,&&&&&&&&&&&&&&POWER_SUPPLY_PROP_HEALTH,&&&&&&&&&&&&&&POWER_SUPPLY_PROP_TEMP,&&&&&&&&&&};&&
(5)、加入;
(6)、和battery相似,把ac加入power_supply;
(7)、和battery相似,把usb加入power_supply;
(8)、max17040加入chip-&work队列;
前面已经分析;
(9)、通过定时器调度队列;
前面已经分析;
2、power_supply_changed简要分析
如:把电池电量信息上报:我们在max17040_work队列调度函数中,&如果有电池信息、状态变化,则上用power_supply_changed上报。
power_supply_changed(&chip-&battery);&&
Kernel/drivers/power/power_supply_core.c中:
void&power_supply_changed(struct&power_supply&*psy)&&{&&&&&&unsigned&long&&&&&&&&&dev_dbg(psy-&dev,&&%s\n&,&__func__);&&&&&&&&spin_lock_irqsave(&psy-&changed_lock,&flags);&&&&&&psy-&changed&=&true;&&&&&&wake_lock(&psy-&work_wake_lock);&&&&&&spin_unlock_irqrestore(&psy-&changed_lock,&flags);&&&&&&schedule_work(&psy-&changed_work);&&}&&Psy-&changed_work的执行函数:&&static&void&power_supply_changed_work(struct&work_struct&*work)&&{&&&&&&unsigned&long&&&&&&&struct&power_supply&*psy&=&container_of(work,&struct&power_supply,&&&&&&&&&&&&&&&&&&&&&&&&&&changed_work);&&&&&&&&dev_dbg(psy-&dev,&&%s\n&,&__func__);&&&&&&&&spin_lock_irqsave(&psy-&changed_lock,&flags);&&&&&&if&(psy-&changed)&{&&&&&&&&&&psy-&changed&=&false;&&&&&&&&&&spin_unlock_irqrestore(&psy-&changed_lock,&flags);&&&&&&&&&&&&class_for_each_device(power_supply_class,&NULL,&psy,&&&&&&&&&&&&&&&&&&&&&&&&__power_supply_changed_work);&&&&&&&&&&&&power_supply_update_leds(psy);&&&&&&&&&&&&kobject_uevent(&psy-&dev-&kobj,&KOBJ_CHANGE);&&&&&&&&&&spin_lock_irqsave(&psy-&changed_lock,&flags);&&&&&&}&&&&&&if&(!psy-&changed)&&&&&&&&&&wake_unlock(&psy-&work_wake_lock);&&&&&&spin_unlock_irqrestore(&psy-&changed_lock,&flags);&&}&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:221822次
积分:2694
积分:2694
排名:第10815名
原创:39篇
转载:66篇
评论:18条
(1)(1)(1)(10)(4)(27)(1)(1)(1)(2)(4)(4)(1)(1)(1)(3)(9)(22)(11)

我要回帖

更多关于 电池电量计芯片 的文章

 

随机推荐