1.bq24735简介bq24735是一款高效同步电池充电器。当系统电源需求暂时高于适配器的最大供电水平时,bq24735使用智能加速技术让电池向系统释放能量,从而保护适配器免受损坏。bq24735使用两个电荷泵来驱动n沟道MOSFET(ACFET、RBFET和BATFET)以实现自动系统电源选择。SMBus(I2C总线)控制的输入电流、充电电流和充电电压DAC可实现非常高的调节精度,系统电源管理微控制器可轻松对其进行编程。bq24735使用内部输入电流寄存器或外部ILIM引脚来减慢PWM调制速度以降低充电电流。2、Linux内核充电架构要想了解bq24735驱动,首先要了解Android供电系统框架。最重要的知识点是电源。1、Android电源系统框架powersupply(以下简称psy)是Linux中电源驱动抽象出来的一个子系统,是Linux电源管理的重要组成部分。Psy是一个中间层,是内核中设备驱动的一部分。ps的主要功能是将各种供电状态信息汇总到用户空间。抽象的信息称为属性。例如供电设备是否连接对应POWER_SUPPLY_PROP_ONLINE。2.电源功能power_supply的软件架构:电源框架的功能包括:抽象PSY设备的共性,为用户空间提供统一的API;提供了一种简单统一的底层PSY驱动的编写方法,同时封装和实现了通用逻辑。电源类位于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,基于Linuxled类,提供PSY设备状态指示的通用实现。位于drivers/power/power_suppply_leds.c。最后,驱动工程师可以根据电源类实现具体的PSY驱动,主要处理平台相关和硬件相关的逻辑。这些驱动程序位于drivers/power/power_supply目录中。3、驱动层的功能在驱动层,主要有两个模块,电池监控相关的驱动(fuelgauge)和充放电管理(charger)相关的驱动(对应图中的battery.c和charger.c)),这两个模块主要处理硬件相关的逻辑。当硬件状态发生变化时,会触发相关的中断,驱动层会调用相应的中断函数,更新修改相应的psy节点值。fuelgaugedriver主要负责向上层android系统提供当前电池电量和健康状态信息。除此之外,它还向充电器驱动程序提供电池相关信息;放电过程管理。对于电池管理,硬件上有电量计IC和充放电IC。当然,有些厂商出于成本考虑,也会将电量计和充放电功能集成到一颗IC中。更重要的是,它们还可能集成PMU功能。在硅表面上。4.其他问题:Android如何知道当前电源是多少,是否在充电?答:uevent机制(本质上是一个net_linksocket)(在hotplugs中广泛使用),当充电插入或断开时,内核发送uevent信息,告诉android。Q:android是如何知道和更新各种参数的?答:通过kobject_uevent向上层发送通知,上层读取sys相关文件属性。下面是某平台的sysfs文件目录:root@********_arm64:/sys/class#pwdsys/class/power_supplyroot@********_arm64:/sys/class/power_supply#lsacbatterybq24735@5-0009usbroot@********_arm64:/sys/class/power_supply#cdbq24735@5-0009cdbq24735@5-0009root@********_arm64:/sys/class/power_supply/bq24735@5-0009#lsdeviceonlinepowerstatussubsystemtypeuevent3.bq24735驱动实现下面以某SoC为例说明如何让我们的产品支持bq24735。1、硬件连接图下面是一个典型的bq24735电路连接图:当没有电源时,bq24735会直接将电池通过降压电路给系统供电。当有电源时,bq24735将为电池充电。2.引脚说明这里只介绍与驱动器相关的引脚:3.寄存器bq24735中使用的寄存器如下:ChargeOptionsRegister[reset=0x12H]。最重要的两个位bit[4]/bit[0]bit:[4]。0:ACadapterisnotpresent(ACDET<2.4V)1:ACadapterpresent(ACDET>2.4V)位:[0]:0:允许充电1:禁止充电判断bit[0]是否为0,如果要判断当前是否存在,可以读这个寄存器,通过判断bit[4]是否为1来确定充电电流寄存器ChargeCurrentRegister(0x14H)充电电流可以通过这个寄存器来设置。比如我们要设置充电电流为3072mA。值为2048+1024,对应bit[10]/[11]为1,其他bit为0。110000000000表示设置寄存器值:0xC00。充电电压寄存器充电电压寄存器(0x15H)。寄存器设置方法与充电电流寄存器类似。输入电流输入电流寄存器(0x3FH)。寄存器设置方法与充电电流寄存器类似。0xfe,0xff这两个寄存器分别读取MANUFACTURER_ID和DEVICE_ID。这两个值分别是:0x0040、0x000B。.在驱动初始化的时候,可以通过读取这两个寄存器的值来判断驱动是否与硬件匹配。.注意:通常寄存器0x14、0x15、0x3F的值需要询问硬件工程师。4.设备树bq24735@9{compatible="ti,bq24735";注册=<0x9>;ti,ac-detect-gpios=<&gpio720x1>;ti,充电电流=<0x600>;ti,充电电压=<0x41a0>;ti,input-current=<0x800>;}参数说明:compatible:用于匹配driver结构体的driver.of_match_table->compatible属性i2c_driverreg:bq24735slavedeviceaddress(I2C)ti,ac-detect-gpios:中断所使用的gpio,第三个参数为引脚ti的默认电平,charge-current:充电电流ti,charge-voltage:充电电压ti,input-current:输入电流5.驱动说明驱动文件已经存在内核代码。drivers\power\bq24735-charger.c但驱动经常需要修改以适应实际的解决方案。该驱动基于I2C总线,对应的结构体变量定义如下:.probe=bq24735,charger_probe.remove=bq24735_charger_remove,.id_table=bq24735_charger_id,};主功能。staticboolbq24735_charger_is_present(structbq24735*charger)判断bq24735是否存在其实就是读寄存器0x12的值,判断bit[4]的值是否为1staticintbq24735_charger_is_charging(structbq24735*charger)判断bq24735是否充电其实就是读寄存器0x12判断bit[0]的值是否为0staticinlineintbq24735_enable_charging(structbq24735*charger)使能充电,设置寄存器0x12的bit[0]为0staticinlineintbq24735_disable_charging(structbq24735*charger)禁止充电,寄存器0x12bit[0]设置为1staticintbq24735_config_charger(structbq24735*charger)配置充电电压(寄存器0x??15)、充电电流(寄存器0x??14)、输入电流(寄存器0x??3f)staticirqreturn_tbq24735_charger_isr(intirq,void*devid)中断处理函数,当bq24735的充电状态发生变化时,会向cpu发送一个中断。此时可以通过I2Cstaticintbq24735_charger_get_property(structpower_supply*psy,enumpower_supply_propertypsp,unionpower_supply_propval*val)读取寄存器0x12的内容得到bq24735的当前状态提供给电源子系统的回调函数。该函数用于获取bq24735的当前状态,包括enum{POWER_SUPPLY_STATUS_UNKNOWN=0,POWER_SUPPLY_STATUS_CHARGING,//正在充电POWER_SUPPLY_STATUS_DISCHARGING,POWER_SUPPLY_STATUS_NOT_CHARGING,//未充电电源POWER_SUPPLY_STATUS_FULL,//full};探测过程这里对探测MANUFACTURER_ID和DEVICE_ID的过程稍作修改。只有当bq24735存在时,才会检查和配置它。此外,还有一个最重要的机制。supply_desc->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;supply_desc->properties提供给电源结构可以访问的命令集合。这些命令需要在函数supply_desc->get_property中加入对应的命令码supply_desc->get_property。电源会定时使用回调函数获取充电芯片是否在线或正在充电等状态码。架构:本架构是基于易口君项目中平台绘制的架构,对于其他平台可能会有所不同,需要具体问题具体分析。4、日志下面的日志是开机过程日志。第一步是从电池供电开始。开机后插上电源充电。插上电源后,bq24735会触发一个中断:然后断开电源停止充电。
