栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Android7.1 RK3288充放电管理

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android7.1 RK3288充放电管理

【环境信息】

CPU:RK3288
Android:7.1
Linux:4.4.143
充放电芯片:bq25703
PD芯片:fusb302
电量计:cw2015

【原理说明】 【软件配置】

dts配置:kernel/arch/arm/boot/dts/rk3288-xxx.dts
&i2c5 {
status = “okay”;
i2c-scl-rising-time-ns = <475>;
i2c-scl-falling-time-ns = <26>;
clock-frequency = <100000>;
bq25700: bq25700@6b {
compatible = “ti,bq25703”;
reg = <0x6b>; —》I2C slave address
extcon = <&fusb0>; —》外部连接器,PD
interrupt-parent = <&gpio3>;
interrupts = ; —》PD到SOC的中断
pinctrl-names = “default”;
pinctrl-0 = <&charger_ok>;
ti,charge-current = <4000000>;
ti,max-charge-voltage = <8400000>;
ti,max-input-voltage = <20000000>;
ti,max-input-current = <6000000>;
ti,input-current-sdp = <2000000>; //关机时,使用该电流
ti,input-current-dcp = <2000000>;
ti,input-current-cdp = <5000000>;
ti,input-current-dc = <7000000>;
ti,minimum-sys-voltage = <6000000>;
ti,otg-voltage = <5000000>;
ti,otg-current = <500000>;
ti,input-current = <500000>;
pd-charge-only = <0>; //将值设置为0即支持普通充电
status = “okay”;
};
fusb0: fusb30x@22 {
compatible = “fairchild,fusb302”;
reg = <0x22>;
pinctrl-names = “default”;
pinctrl-0 = <&fusb0_int>;
//vbus-5v-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
int-n-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
// discharge-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
charge-dev = <&bq25700>;
// support-uboot-charge = <1>;
port-num = <0>; //使用的usb控制器,关机充电时需要
status = “okay”;
};
}

&i2c0 {
clock-frequency = <400000>;
CW2015@62 {
compatible = “cw201x”;
reg = <0x62>;
bat_low_gpio = <&gpio0 7 GPIO_ACTIVE_LOW>;
bat_config_info = <0x15 0x7E 0x79 0x6E 0x6C 0x69 0x66 0x65
0x63 0x62 0x5C 0x58 0x52 0x52 0x49 0x31
0x29 0x23 0x24 0x26 0x29 0x37 0x4B 0x5C
0x62 0x45 0x0B 0x85 0x23 0x43 0x6C 0x81
0x83 0x82 0x83 0x85 0x3A 0x16 0x93 0x1B
0x07 0x45 0x35 0x66 0x8E 0x91 0x92 0x45
0x5B 0x78 0x9A 0xAD 0x80 0x81 0x8B 0xCB
0x2F 0x00 0x64 0xA5 0xB5 0xC1 0x46 0xAE>;
// is_usb_charge = <1>;
monitor_sec = <2>; //电量查询时间间隔,2S
virtual_power = <0>;
divider_res1 = <200>; //分压电阻大小
divider_res2 = <200>;
status = “okay”;
};
配置文档:documentation/devicetree/bindings/power/bq25703.txt:
documentation/devicetree/bindings/mfd/fusb302.txt
documentation/devicetree/bindings/power/cw2015_battery.txt
驱动目录:kernel/drivers/mfd/fusb302.c
kernel/drivers/power/bq25700_charger.c
kernel/drivers/power/cw2015_battery.c

【代码分析】

1、PD芯片模块&驱动加载

static int fusb30x_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
{
...
        chip->fusb30x_wq = create_workqueue("fusb302_wq");
        INIT_WORK(&chip->work, fusb302_work_func);
...
        ret = devm_request_threaded_irq(&client->dev,
                                        chip->gpio_int_irq,
                                        NULL,
                                        cc_interrupt_handler,
                                        IRQF_onESHOT | IRQF_TRIGGER_LOW,
                                        client->name,
                                        chip);

2、充电IC bq25700 模块&驱动加载

bq25700_probe
  i2c_check_functionality //是否支持 SMBUS 通信
  devm_regmap_init_i2c    //采用 regmap api 操作 i2c,初始化 bq25700 的 regmap_config 
  devm_regmap_field_alloc //为 regmap 分配内存空间
  i2c_set_clientdata 
  bq25700_field_read      //读 chip id
  bq25700_fw_probe 
    bq25700_fw_read_u32_props //获取 dts 中的属性,包括 charge-current、max-charge-voltage、input-current-sdp/dcp/cdp、minimum-sys-voltage 、otg-voltage、otg-current
  bq25700_hw_init
    //1. bq25700_chip_reset //芯片重启
    //2. WDTWR_ADJ = 0 //disable watchdog
    //3. 初始化电流电压和其他参数
    //4. 配置 ADC 用以持续转化,禁能
  bq25700_parse_dt //获取 dts 中的属性 pd-charge-only 
  bq25700_init_usb 
    usb_charger_wq = alloc_ordered_workqueue //分配工作队列,用于事件通知链
    extcon_get_edev_by_phandle(dev, 0)       //获取外部连接器 fusb302
    bq25700_register_cg_nb(charger); //注册 charger 通知链。如果 pd_charge_only 为 0 ,表示不仅仅采用 TypeC 充电,则执行。添加等待队列。 
      bq25700_charger_evt_worker     //初始化 charger 等待队列
        bq25700_charger_evt_handel   //判断 charger 类型,并使能 INPUT_CURRENT/CHARGE_CURRENT
      bq25700_charger_evt_notifier   //添加 charger 事件通知链
      bq25700_register_cg_extcon     //注册 charger 外部控制器,以及其事件通知链
    bq25700_register_host_nb(charger); //注册 host 通知链
    bq25700_register_discnt_nb(charger); //注册 disconnect 通知链
    bq25700_register_pd_nb(charger); //注册 pd 通知链
    schedule_delayed_work //提交任务到工作队列
  bq25700_init_sysfs //创建 sysfs 中的属性节点
  //根据 AC_STAT 确定触发条件,设定中断触发条件
  device_init_wakeup 
  devm_request_threaded_irq 
  enable_irq_wake //使能中断唤醒
  bq25700_power_supply_init //注册 power supply 的 desc
    bq25700_power_supply_get_property //获取系统属性的接口
int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
                             struct notifier_block *nb)
{
...
                raw_notifier_chain_register(&edev->nh[idx], nb);
...
}
static int bq25700_register_cg_nb(struct bq25700_device *charger)
{
...
                INIT_DELAYED_WORK(&charger->usb_work, bq25700_charger_evt_worker);
                charger->cable_cg_nb.notifier_call = bq25700_charger_evt_notifier;
                bq25700_register_cg_extcon(charger, charger->cable_edev, &charger->cable_cg_nb);
...
}
static int bq25700_register_host_nb(struct bq25700_device *charger)
{
...
                INIT_DELAYED_WORK(&charger->host_work, bq25700_host_evt_worker);
                charger->cable_host_nb.notifier_call = bq25700_host_evt_notifier;
                // extcon_register_notifier见./kernel/drivers/extcon/extcon.c
                ret = extcon_register_notifier(charger->cable_edev, EXTCON_USB_HOST, &charger->cable_host_nb); 
...
}
static int bq25700_register_discnt_nb(struct bq25700_device *charger)
{
...
                INIT_DELAYED_WORK(&charger->discnt_work, bq25700_discnt_evt_worker);
                charger->cable_discnt_nb.notifier_call = bq25700_discnt_evt_notfier;
                ret = extcon_register_notifier(charger->cable_edev, EXTCON_USB, &charger->cable_discnt_nb);
...
}
static int bq25700_register_pd_nb(struct bq25700_device *charger)
{
...
                INIT_DELAYED_WORK(&charger->pd_work, bq25700_pd_evt_worker);
                charger->cable_pd_nb.notifier_call = bq25700_pd_evt_notifier;
                extcon_register_notifier(charger->cable_edev, EXTCON_CHG_USB_FAST, &charger->cable_pd_nb);
...
}
static int bq25700_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
...
        ret = devm_request_threaded_irq(dev, client->irq, NULL,
                                        bq25700_irq_handler_thread,
                                        irq_flag | IRQF_ONESHOT,
                                        "bq25700_irq", charger);
        enable_irq_wake(client->irq);
...
}

通知实例
otg_mode_store->rockchip_usb2phy_set_mode->   (kernel/drivers/phy/rockchip/phy-rockchip-inno-usb2.c)
extcon_set_state_sync->extcon_sync->raw_notifier_call_chain

开机初始化打印
[ 1.013590] chip id is 78 --》bq25700芯片ID
[ 1.042547] bq25700-charger 5-006b: GPIO lookup for consumer typec0-enable
[ 1.042561] bq25700-charger 5-006b: using device tree for GPIO lookup
[ 1.042575] of_get_named_gpiod_flags: can’t parse ‘typec0-enable-gpios’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042587] of_get_named_gpiod_flags: can’t parse ‘typec0-enable-gpio’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042597] bq25700-charger 5-006b: using lookup tables for GPIO lookup
[ 1.042608] bq25700-charger 5-006b: lookup for GPIO typec0-enable failed
[ 1.042619] bq25700-charger 5-006b: GPIO lookup for consumer typec1-enable
[ 1.042628] bq25700-charger 5-006b: using device tree for GPIO lookup
[ 1.042639] of_get_named_gpiod_flags: can’t parse ‘typec1-enable-gpios’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042649] of_get_named_gpiod_flags: can’t parse ‘typec1-enable-gpio’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042658] bq25700-charger 5-006b: using lookup tables for GPIO lookup
[ 1.042668] bq25700-charger 5-006b: lookup for GPIO typec1-enable failed
[ 1.042678] bq25700-charger 5-006b: GPIO lookup for consumer typec0-discharge
[ 1.042688] bq25700-charger 5-006b: using device tree for GPIO lookup
[ 1.042698] of_get_named_gpiod_flags: can’t parse ‘typec0-discharge-gpios’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042709] of_get_named_gpiod_flags: can’t parse ‘typec0-discharge-gpio’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042719] bq25700-charger 5-006b: using lookup tables for GPIO lookup
[ 1.042728] bq25700-charger 5-006b: lookup for GPIO typec0-discharge failed
[ 1.042738] bq25700-charger 5-006b: GPIO lookup for consumer typec1-discharge
[ 1.042747] bq25700-charger 5-006b: using device tree for GPIO lookup
[ 1.042758] of_get_named_gpiod_flags: can’t parse ‘typec1-discharge-gpios’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042768] of_get_named_gpiod_flags: can’t parse ‘typec1-discharge-gpio’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042778] bq25700-charger 5-006b: using lookup tables for GPIO lookup
[ 1.042787] bq25700-charger 5-006b: lookup for GPIO typec1-discharge failed
[ 1.042797] bq25700-charger 5-006b: GPIO lookup for consumer otg-mode-en
[ 1.042806] bq25700-charger 5-006b: using device tree for GPIO lookup
[ 1.042816] of_get_named_gpiod_flags: can’t parse ‘otg-mode-en-gpios’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042826] of_get_named_gpiod_flags: can’t parse ‘otg-mode-en-gpio’ property of node ‘/i2c@ff170000/bq25700@6b[0]’
[ 1.042836] bq25700-charger 5-006b: using lookup tables for GPIO lookup
[ 1.042846] bq25700-charger 5-006b: lookup for GPIO otg-mode-en failed
[ 1.043209] bq25700-charger 5-006b: Invalid or missing extcon dev1

2、插拔typec适配器充电日志打印
日志打印信息:
[ 681.428862] fusb302 5-0022: CC connected in CC2 as UFP —》fusb_state_attached_sink-》force_usb_mode_store
[ 681.428949] jon debug:::usb_mode:30
[ 681.429051] force_usb_mode_store 0->2
[ 681.429144] jon debug:::usb_mode set 2
[ 681.472246] healthd: battery l=25 v=7142 t=18.8 h=2 st=3 chg=u
[ 681.478031] type=1400 audit(1634649279.583:44): avc: denied { search } for pid=227 comm=“Binder:227_1” name=“416” dev=“proc” ino=13324 scontext=u:r:mediaserver:s0 tcontext=u:r:system_server:s0 tclass=dir permissive=1
[ 681.512553] rk_battery_charger_detect_cb , battery_charger_detect 2
[ 681.534022] healthd: battery l=25 v=7142 t=18.8 h=2 st=3 chg=u
[ 681.746237] fusb302 5-0022: PD connected as UFP, fetching 5V
[ 681.779401] jon SET vol_idx: 164mv
[ 681.779417] jon SET cur_idx: 60mA
[ 681.779423] jon SET harger->init_data.ichg: 62mA
[ 681.811527] healthd: battery l=25 v=7142 t=18.8 h=2 st=3 chg=u

【流程梳理】

1、插入AC流程
硬件连接:fusb302芯片INT#管脚连到SOC(RK3288 GPIO0 A6,见dts配置: int-n-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>)
插入AC-》产生硬件中断-》
cc_interrupt_handler-》queue_work (kernel/drivers/mfd/fusb302.c, fusb30x_probe->devm_request_threaded_irq注册)
fusb302_work_func-》
state_machine_typec-》
fusb_state_attached_sink-》
force_usb_mode_store-》

2、拔出AC流程

3、正常充电流程

【环境操作】

1、查看电池文件系统
rk3288:/ # ls -l ./sys/devices/platform/ff170000.i2c/i2c-5/5-006b/power_supply/bq25700-charger
-r–r--r-- 1 root root 4096 2021-10-22 20:42 charge_control_limit_max
-r–r--r-- 1 root root 4096 2021-10-22 20:42 constant_charge_current
-r–r--r-- 1 root root 4096 2021-10-22 20:42 constant_charge_current_max
-r–r--r-- 1 root root 4096 2021-10-22 20:42 constant_charge_voltage
-r–r--r-- 1 root root 4096 2021-10-22 20:42 constant_charge_voltage_max
-r–r--r-- 1 root root 4096 2021-10-22 20:35 current_max
lrwxrwxrwx 1 root root 0 2021-10-22 20:42 device -> …/…/…/5-006b
-r–r--r-- 1 root root 4096 2021-10-22 20:42 health
-r–r--r-- 1 root root 4096 2021-10-22 20:42 input_current_limit
-r–r--r-- 1 root root 4096 2021-10-22 20:42 manufacturer
-rwxrwxrwx 1 root root 4096 2021-10-22 20:47 online
drwxr-xr-x 2 root root 0 2021-10-22 20:35 power
-r–r--r-- 1 root root 4096 2021-10-22 20:42 status
lrwxrwxrwx 1 root root 0 2021-10-22 20:42 subsystem -> …/…/…/…/…/…/…/class/power_supply
-r–r--r-- 1 root root 4096 2021-10-22 20:35 type
-rw-r–r-- 1 root root 4096 2021-10-22 20:35 uevent
-r–r--r-- 1 root root 4096 2021-10-22 20:35 voltage_max

rk3288:/ # ls -l ./sys/bus/i2c/drivers/bq25700-charger
total 0
lrwxrwxrwx 1 root root 0 2021-10-22 20:42 5-006b -> …/…/…/…/devices/platform/ff170000.i2c/i2c-5/5-006b
–w------- 1 root root 4096 2021-10-22 20:42 bind
–w------- 1 root root 4096 2021-10-22 20:42 uevent
–w------- 1 root root 4096 2021-10-22 20:42 unbind

【参考接口】

1、delay_work延时工作

INIT_DELAYED_WORK(dwork, work);    
//参数1是个delayed_work结构体,参数2是个函数名

schedule_delayed_work (struct delayed_work *dwork, unsigned long delay);
//将当前dwork变量进入到等待队列中,在后续的delay时间后,将会调用dwork变量对应的work函数

bool cancel_delayed_work(struct delayed_work *dwork);
//如果当前dwork在等待队列中,则将取消掉

2、notifier通知机制

static RAW_NOTIFIER_HEAD(test_chain);

raw_notifier_chain_register(&test_chain, nb); // nb为struct notifier_block

raw_notifier_call_chain(&test_chain, val, NULL);
【参考资料】

RK3399充电管理
https://blog.csdn.net/m0_37631324/article/details/105956187?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163462546616780255278368%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163462546616780255278368&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-105956187.pc_search_result_hbase_insert&utm_term=rk3399+%E5%85%85%E7%94%B5%E7%AE%A1%E7%90%86&spm=1018.2226.3001.4187

BQ25700 IC 驱动分析
https://blog.csdn.net/dearsq/article/details/72335905

内核通知链 notifier_block
http://bbs.chinaunix.net/thread-2011776-1-1.html

Android电池管理体系(一)
https://blog.csdn.net/zhou12314/article/details/79379276?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163490557516780271563114%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163490557516780271563114&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-14-79379276.pc_search_result_hbase_insert&utm_term=bq27500&spm=1018.2226.3001.4187

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342189.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号