电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【Linux驱动】充电芯片bq24735调试详解
分 享
扫描二维码分享
【Linux驱动】充电芯片bq24735调试详解
linux
bq24735
充电芯片
一口Linux
关注
发布时间: 2022-04-14
丨
阅读: 627
## 一、bq24735简介 bq24735 是一款高效率同步电池充电器。 当系统供电需求暂时高于适配器最大供电水平的时候, bq24735 使用智能加速技术来允许电池向系统中释放能量,这样的话将保护适配器不被损坏。 ![ ](https://img-blog.csdnimg.cn/2b10ec37c21140bdae7b869ae4c9ab9a.png?) bq24735 为满足自动系统电源选择的需要,使用 2 个充电泵来分别驱动 n-通道 MOSFET (ACFET, RBFET 和 BATFET) 。 SMBus(I2C总线) 控制的输入电流, 充电电流, 和充电电压DAC允许非常高的调节精度,此调节精度可通过系统功率管理微控制器很容易地进行编程。 bq24735 使用内部输入电流寄存器或者外部ILIM引脚来减缓PWM调制速度以减小充电电流。 ## 二、Linux内核充电架构 要想理解bq24735驱动,必须首先理解Android供电系统框架,最重要的知识点是power supply。 ### 1. Android供电系统框架 ![](https://img-blog.csdnimg.cn/img_convert/1421c8429429ab1a0165e9d359708de2.png#pic_center) power supply(以下简称psy)是Linux中从供电驱动抽象出来的子系统,是Linux电源管理的重要组成部分。 psy是一个中间层,在kernel中是属于设备驱动的一部分,psy的作用主要是向用户空间汇总各类供电的状态信息。 抽象出来的各类信息称为property,比如供电设备是否连接就对应着**POWER_SUPPLY_PROP_ONLINE**。 ### 2. power supply功能 power_supply的软件架构: ![ ](https://img-blog.csdnimg.cn/695f9be6061a4408853690f630651830.png?) power supply framework功能包括: 1. 抽象PSY设备的共性,向用户空间提供统一的API; 2. 为底层PSY驱动的编写,提供简单、统一的方式,同时封装并实现公共逻辑。 power supply class位于drivers/power/目录中,主要由3部分组成(可参考下图的软件架构): * 1)power_supply_core,用于抽象核心数据结构、实现公共逻辑。位于drivers/power/power_supply_core.c中。 * 2)power_supply_sysfs,实现sysfs以及uevent功能。位于drivers/power/power_supply_sysfs.c中。 * 3)power_supply_leds,基于Linux led class,提供PSY设备状态指示的通用实现。位于drivers/power/power_suppply_leds.c中。 最后,驱动工程师可以基于power supply class,实现具体的PSY drivers,主要处理平台相关、硬件相关的逻辑。这些drivers都位于drivers/power/power_supply目录下。 ### 3. 驱动层功能 在驱动层,主要是两大模块,与电池监控(fuelgauge)和与充放电管理(charger)相关的驱动(对应图中的battery.c和charger.c),这两大模块主要处理硬件相关的逻辑,在硬件状态发生变化时,会触发相关的中断,驱动层会调用相应的中断函数,并更新修改相应的psy节点值。 fuelgauge驱动主要是负责向上层android系统提供当前电池的电量以及健康状态信息等等,另外除了这个以外,它也向charger驱动提供电池的相关信息;charger驱动主要负责电源线的插拔检测,以及充放电的过程管理。 对于battery管理,硬件上有电量计IC和充放电IC,当然有些厂家为了成本的考虑,也会把电量计和充放电功能集成到一个IC上,更有甚者,可能会把PMU功能也集成在一块硅面上。 ### 4. 其他问题 问:android怎么知道当前是什么供电,充电中与否? 答:uevent机制(实质是net_link方式的socket)(广泛应用于hotplug),充电插入与断开时,内核通过发送uevent信息,告诉android。 问:android如何知道各种参数并更新的? 答:通过kobject_uevent发送通知给上层,上层读取sys相关文件属性 以下是某平台sysfs文件目录 ```bash root@********_arm64:/sys/class # pwd sys/class/power_supply root@********_arm64:/sys/class/power_supply # ls ac battery bq24735@5-0009 usb root@********_arm64:/sys/class/power_supply # cd bq24735@5-0009 cd bq24735@5-0009 root@*********_arm64:/sys/class/power_supply/bq24735@5-0009 # ls device online power status subsystem type uevent ``` ## 三、bq24735驱动实现 下面基于某款soc来讲解如何让我们的产品支持bq24735。 ### 1. 硬件连接图图 下面是一个典型的bq24735电路连接图: ![ ](https://img-blog.csdnimg.cn/ecf1cb0e132d47168af271471a640c37.png?)当没有电源供电的时候,bq24735会直接将电池传递给降压电路,给系统供电 当有电源供电的时候,bq24735会给电池充电。 ### 2. 引脚说明 ![](https://img-blog.csdnimg.cn/63ca7d99440845eabfe64b33f37e482a.png?)在此我们只介绍与驱动相关的引脚 ![ ](https://img-blog.csdnimg.cn/6730cb5a86cb4306ace5b605e19bb653.png?) ### 3. 寄存器 bq24735用到的寄存器如下: ![ ](https://img-blog.csdnimg.cn/f467c3015e084d2e8256ae82669d1c6a.png?) 1. 充电选项寄存器Charge Options Register [reset = 0x12H] ![ ](https://img-blog.csdnimg.cn/86fbd74a06a74ebf8204d39698a6a84c.png?) 其中最重要的两个位bit[4]/bit[0] bit:[4] ```bash 0: AC adapter不在 (ACDET < 2.4 V) 1: AC adapter存在(ACDET > 2.4 V) ``` bit:[0] ```bash 0: 使能充电 1: 抑制充电 ``` 该寄存器为可读写, 如果要判断当前是否在充电,则可以读取该寄存器,通过判断bit[0]是否为0来确认 如果要判断当前是否存在,则可以读取该寄存器,通过判断bit[4]是否为1来确认 2. 充电电流寄存器Charge Current Register (0x14H) 通过该寄存器可以设置充电电流。 ![ ](https://img-blog.csdnimg.cn/94a5406f27ce4e1788e8f6b58bc853e1.png?) 比如我们要设置充电电流为3072mA, 该值为2048+1024,将对应的bite[10]/[11]为1,其他位为0 ```bash 1100 0000 0000 ``` 即设置该寄存器值为:`0xC00` 3. 充电电压寄存器Charge Voltage Register (0x15H) ![ ](https://img-blog.csdnimg.cn/9538c673fb154965923361b784058227.png?) 该寄存器设置方法类似于`充电电流寄存器` 4. 输入电流Input Current Register (0x3FH) ![ ](https://img-blog.csdnimg.cn/490b18f94a34486aaceb272b11649169.png?6) 该寄存器设置方法类似于`充电电流寄存器` 5. 0xfe,0xff 这两个寄存器分别读取MANUFACTURER_ID和DEVICE_ID 这两个值分别为:0x0040、0x000B 驱动初始化时可以通过读取这两个寄存器的值来判断,驱动是否和硬件匹配。 >注意: 通常寄存器0x14、0x15、0x3F值需要询问硬件工程师 ### 4. 设备树 ```bash bq24735@9 { compatible = "ti,bq24735"; reg = <0x9>; ti,ac-detect-gpios = <&gpio 72 0x1>; ti,charge-current =<0x600>; ti,charge-voltage=<0x41a0>; ti,input-current =<0x800>; } ``` 参数说明 ```bash compatible :用于和驱动的结构体i2c_driver的driver.of_match_table->compatible属性进行匹配 reg:bq24735从设备地址(I2C) ti,ac-detect-gpios:中断使用的gpio,第三个参数是该pin默认电平 ti,charge-current :充电电流 ti,charge-voltage :充电电压 ti,input-current :输入电流 ``` ### 5. 驱动讲解 1. 驱动文件 内核代码中已经有该驱动 ```bash drivers\power\bq24735-charger.c ``` 但是该驱动往往需要修改以适配实际的方案。 该驱动是基于I2C总线,对应结构体变量定义如下: ```c static struct i2c_driver bq24735_charger_driver = { .driver = { .name = "bq24735-charger", .owner = THIS_MODULE, .of_match_table = bq24735_match_ids, }, .probe = bq24735_charger_probe, .remove = bq24735_charger_remove, .id_table = bq24735_charger_id, }; ``` 2. 主要函数 ```c static bool bq24735_charger_is_present(struct bq24735 *charger) 判断bq24735 是否存在 其实就是读取寄存器0x12的值,判断bit[4]值是否为1 ``` ```c static int bq24735_charger_is_charging(struct bq24735 *charger) 判断bq24735 是否在充电 其实就是读取寄存器0x12的值,判断bit[0]值是否为0 ``` ```c static inline int bq24735_enable_charging(struct bq24735 *charger) 使能充电 将寄存器寄存器0x12的bit[0]置0 static inline int bq24735_disable_charging(struct bq24735 *charger) 禁止充电 将寄存器寄存器0x12的bit[0]置1 ``` ```c static int bq24735_config_charger(struct bq24735 *charger) 配置充电电压(寄存器0x15)、充电电流(寄存器0x14)、输入电流(寄存器0x3f) ``` ```c static irqreturn_t bq24735_charger_isr(int irq, void *devid) 中断处理函数, 当bq24735充电状态发生变化的时候,会发送中断给cpu 此时可以通过I2C来读取寄存器0x12的内容来获取bq24735当前状态 ``` ```c static int bq24735_charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) 提供给power supply子系统的回调函数 该函数用于获取bq24735当前状态 状态包括 enum { POWER_SUPPLY_STATUS_UNKNOWN = 0, POWER_SUPPLY_STATUS_CHARGING, //正在充电 POWER_SUPPLY_STATUS_DISCHARGING, POWER_SUPPLY_STATUS_NOT_CHARGING,//没有充电 POWER_SUPPLY_STATUS_FULL,//充满 }; ``` 3. probe流程 ![ ](https://img-blog.csdnimg.cn/a504f41be58940fc86d01741e4eafe84.png?) 此处检测MANUFACTURER_ID和DEVICE_ID流程稍做了修改,只有bq24735 present的时候才会check并配置 此外还有个最重要的机构体 ```c supply_desc->name = name; supply_desc->type = POWER_SUPPLY_TYPE_MAINS; supply_desc->properties = bq24735_charger_properties; supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); supply_desc->get_property = bq24735_charger_get_property; ``` ```c supply_desc->properties 提供给power supply架构可以访问的命令的集合, 这些命令需要在函数supply_desc->get_property增加对应的命令代码 ``` ```c supply_desc->get_property power supply会定时通过该回调函数获取充电芯片是否在线、是否在充电等状态 ``` 4. 代码架构 ![ ](https://img-blog.csdnimg.cn/25cf458dc14b4bdfa1691f03760eb248.png?) 这个架构是一口君根据项目中平台所画的架构,其他平台架构可能会有所不同, 需要具体问题具体分析。 ## 四、 log 下面log是开机启动流程log, 第一步 用电池供电启动 ![ ](https://img-blog.csdnimg.cn/0eff47027f644234aeb92c3cf4e08fe6.png?) 启动后再插入电源充电, 插入电源后,bq24735会触发中断: ![ ](https://img-blog.csdnimg.cn/7b78be2d9f644d2396c870744231e653.png?) 然后再断开电源停止充电 ![](https://img-blog.csdnimg.cn/5b6e554edd8b4aceb99e2a6ca5097dcb.png?)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
一口Linux
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交