一、bq24735简介

bq24735 是一款高效率同步电池充电器。

当系统供电需求暂时高于适配器最大供电水平的时候, bq24735 使用智能加速技术来允许电池向系统中释放能量,这样的话将保护适配器不被损坏。

bq24735 为满足自动系统电源选择的需要,使用 2 个充电泵来分别驱动 n-通道 MOSFET (ACFET, RBFET 和 BATFET) 。

SMBus(I2C总线) 控制的输入电流, 充电电流, 和充电电压DAC允许非常高的调节精度,此调节精度可通过系统功率管理微控制器很容易地进行编程。

bq24735 使用内部输入电流寄存器或者外部ILIM引脚来减缓PWM调制速度以减小充电电流。

二、Linux内核充电架构

要想理解bq24735驱动,必须首先理解Android供电系统框架,最重要的知识点是power supply。

1. Android供电系统框架

​​

power supply(以下简称psy)是Linux中从供电驱动抽象出来的子系统,是Linux电源管理的重要组成部分。

psy是一个中间层,在kernel中是属于设备驱动的一部分,psy的作用主要是向用户空间汇总各类供电的状态信息。

抽象出来的各类信息称为property,比如供电设备是否连接就对应着POWER_SUPPLY_PROP_ONLINE

2. power supply功能

power_supply的软件架构:

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文件目录

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电路连接图:
当没有电源供电的时候,bq24735会直接将电池传递给降压电路,给系统供电
当有电源供电的时候,bq24735会给电池充电。

2. 引脚说明

在此我们只介绍与驱动相关的引脚

3. 寄存器

bq24735用到的寄存器如下:

  1. 充电选项寄存器Charge Options Register [reset = 0x12H]


其中最重要的两个位bit[4]/bit[0]
bit:[4]

0: AC adapter不在 (ACDET < 2.4 V)
1: AC adapter存在(ACDET > 2.4 V)

bit:[0]

0: 使能充电
1: 抑制充电

该寄存器为可读写,
如果要判断当前是否在充电,则可以读取该寄存器,通过判断bit[0]是否为0来确认
如果要判断当前是否存在,则可以读取该寄存器,通过判断bit[4]是否为1来确认

  1. 充电电流寄存器Charge Current Register (0x14H)

通过该寄存器可以设置充电电流。

比如我们要设置充电电流为3072mA,
该值为2048+1024,将对应的bite[10]/[11]为1,其他位为0

1100 0000 0000

即设置该寄存器值为:0xC00

  1. 充电电压寄存器Charge Voltage Register (0x15H)

    该寄存器设置方法类似于充电电流寄存器

  2. 输入电流Input Current Register (0x3FH)

    该寄存器设置方法类似于充电电流寄存器

  3. 0xfe,0xff
    这两个寄存器分别读取MANUFACTURER_ID和DEVICE_ID

这两个值分别为:0x0040、0x000B

驱动初始化时可以通过读取这两个寄存器的值来判断,驱动是否和硬件匹配。

注意:
通常寄存器0x14、0x15、0x3F值需要询问硬件工程师

4. 设备树

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>;
}

参数说明

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. 驱动文件
    内核代码中已经有该驱动
drivers\power\bq24735-charger.c

但是该驱动往往需要修改以适配实际的方案。

该驱动是基于I2C总线,对应结构体变量定义如下:

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,
};
  1. 主要函数
static bool bq24735_charger_is_present(struct bq24735 *charger)
判断bq24735 是否存在
其实就是读取寄存器0x12的值,判断bit[4]值是否为1
static int bq24735_charger_is_charging(struct bq24735 *charger)
判断bq24735 是否在充电
其实就是读取寄存器0x12的值,判断bit[0]值是否为0
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
static int bq24735_config_charger(struct bq24735 *charger)
配置充电电压(寄存器0x15)、充电电流(寄存器0x14)、输入电流(寄存器0x3f)
static irqreturn_t bq24735_charger_isr(int irq, void *devid)
中断处理函数,
当bq24735充电状态发生变化的时候,会发送中断给cpu
此时可以通过I2C来读取寄存器0x12的内容来获取bq24735当前状态
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,//充满
};
  1. probe流程

此处检测MANUFACTURER_ID和DEVICE_ID流程稍做了修改,只有bq24735 present的时候才会check并配置

此外还有个最重要的机构体

 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;
supply_desc->properties提供给power supply架构可以访问的命令的集合,这些命令需要在函数supply_desc->get_property增加对应的命令代码
supply_desc->get_propertypower supply会定时通过该回调函数获取充电芯片是否在线、是否在充电等状态
  1. 代码架构

    这个架构是一口君根据项目中平台所画的架构,其他平台架构可能会有所不同,
    需要具体问题具体分析。

四、 log

下面log是开机启动流程log,
第一步
用电池供电启动


启动后再插入电源充电,
插入电源后,bq24735会触发中断:

然后再断开电源停止充电

【Linux驱动】安卓充电芯片bq24735调试详解相关推荐

  1. Linux Bash命令关于程序调试详解

    转载:http://os.51cto.com/art/201006/207230.htm 参考:<Linux shell 脚本攻略>Page22-23 Linux bash程序在程序员的使 ...

  2. 嵌入式linux mtd,嵌入式Linux驱动设备之MTD技术详解

    原标题:嵌入式Linux驱动设备之MTD技术详解 MTD(memory technology device内存技术设备)是用于访问memory设备(ROM.flash)的Linux的子系统. MTD的 ...

  3. 【Linux驱动开发】设备树详解(二)设备树语法详解

    ​ 活动地址:CSDN21天学习挑战赛 [Linux驱动开发]设备树详解(一)设备树基础介绍 [Linux驱动开发]设备树详解(二)设备树语法详解 [Linux驱动开发]设备树详解(三)设备树Kern ...

  4. Linux驱动开发_设备文件系统详解

    目录 何为设备管理器? Linux下dev的作用 Devfs sysfs kobject udev proc 何为设备管理器? 设备管理器就是负责管理这台电脑上的外设,当我们通过电脑提供的USB口插入 ...

  5. linux platform匹配机制,Linux驱动中的platform总线详解

    platform总线是学习linux驱动必须要掌握的一个知识点. 一.概念 嵌入式系统中有很多的物理总线:I2c.SPI.USB.uart.PCIE.APB.AHB linux从2.6起就加入了一套新 ...

  6. 【genius_platform软件平台开发】第五十八讲:Linux系统之V4L2视频驱动-VIDIOC_REQBUFS向驱动申请帧缓冲代码详解

    VIDIOC_REQBUFS向驱动申请帧缓冲代码详解 1. 概述 2. 应用层 3. 内核驱动 3.1 vb2_ioctl_reqbufs函数 3.2 vb2_core_reqbufs函数 3.3 _ ...

  7. Linux中/proc目录下文件详解

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

  8. linux mount命令参数及用法详解

    linux mount命令参数及用法详解 非原创,主要来自 http://www.360doc.com/content/13/0608/14/12600778_291501907.shtml. htt ...

  9. Linux中/proc目录下文件详解(二)

    Linux中/proc目录下文件详解(二) /proc/mdstat文件 这个文件包含了由md设备驱动程序控制的RAID设备信息. 示例: [root@localhost ~]# cat /proc/ ...

最新文章

  1. 自定义Counter使用
  2. 『浅入浅出』MySQL 和 InnoDB
  3. Android中使用AlarmManager设置闹钟
  4. 互联网1分钟 |1119
  5. Symmetric multiprocessing(SMP)下的spinlock
  6. linux 安装tomcat遇到的问题
  7. java编程代写有哪些平台,学习路线+知识点梳理
  8. 【英语学习】【WOTD】resuscitate 释义/词源/示例
  9. Java中获取文件大小的正确方法
  10. 电子科大计算机操作系统ppt,电子科大计算机操作系统实验报告级.docx
  11. 【leetcode】链表题(python)
  12. Sentinel 哨兵 实现redis高可用
  13. Tyvj - 1305 单调队列优化dp
  14. 使用dom和jaxen实现一个增删改查的功能;
  15. 会议论文集出版地总结_codestorm_新浪博客
  16. 模数转换 A/D 与数模转换 D/A介绍
  17. c语言日期计算器程序代码,用C语言写一个日期计算器
  18. 【直播笔记】在临床研究中,如何利用SAS做更好的统计报表输出
  19. 手持云台 1.前期准备
  20. expects parameter 1 to be resource, array given 错误解析

热门文章

  1. 云呐|事业单位资产管理、事业单位资产管理信息系统操作
  2. html页面如果想要字体比12px还小
  3. Python经纬度转换地理坐标(逆地理编码)
  4. 关于手机号码、邮箱的在JavaScript中的正则表达式和其简单用法
  5. 树形数据库查询优化方案
  6. 关于游戏测试岗位的一些理解和建议
  7. 分页插件 ajax请求,jquery ajax分页插件的简单实现
  8. vue 选中列表去重
  9. Lichee_RV学习系列---认识Lichee Rv Dock、环境搭建和编译第一个程序
  10. Unity粒子系统(5.x)基础(二)