完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
【环境信息】
CPU:RK3288 Android:7.1 Linux:4.4.143 充放电芯片:bq25703 PD芯片:fu***302 电量计:cw2015 【背景信息】 DRP/UFP/DFP/ASS 【原理说明】 To-do 【软件配置】 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 = 《&fu***0》; ---》外部连接器,PD interrupt-parent = 《&gpio3》; interrupts = 《RK_PD1 IRQ_TYPE_LEVEL_LOW》; ---》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”; }; fu***0: fu***30x@22 { compatible = “fairchild,fu***302”; reg = 《0x22》; // I2C slave address pinctrl-names = “default”; pinctrl-0 = 《&fu***0_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》; //使用的u***控制器,关机充电时需要 status = “okay”; }; } &pinctrl { 。.. fu***30x { fu***0_int: fu***0-int { rockchip,pins = 《0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up》; //连接FUSB302 PD芯片的INT#管脚 }; }; 。.. } //电量计配置 &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_u***_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/fu***302.txt Documentation/devicetree/bindings/power/cw2015_battery.txt 驱动目录:kernel/drivers/mfd/fu***302.c kernel/drivers/power/bq25700_charger.c kernel/drivers/power/cw2015_battery.c 【代码分析】 1、PD芯片模块&驱动加载 static int fu***30x_probe(struct i2c_client *client, const struct i2c_device_id *id) { 。.. fu***_initialize_gpio ---》读取dts设备树,初始化gpio fu***_initialize_timer ---》fu***_timer_handler回调 chip-》fu***30x_wq = create_workqueue(“fu***302_wq”); INIT_WORK(&chip-》work, fu***302_work_func); tcpm_init //PD reset、set and enable interrupt、 ret = devm_request_threaded_irq(&client-》dev, chip-》gpio_int_irq, NULL, cc_interrupt_handler, IRQF_ONESHOT | IRQF_TRIGGER_LOW, client-》name, chip); } fu***_timer_handler-》 queue_work(fu***30x_port_info-》fu***30x_wq, &fu***30x_port_info-》work) // 将任务提交到工作队列 fu***302_work_func-》 cc_interrupt_handler-》 queue_work(chip-》fu***30x_wq, &chip-》work)-》 fu***302_work_func-》 state_machine_typec-》 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 中的属性 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_u*** u***_charger_wq = alloc_ordered_workqueue //分配工作队列,用于事件通知链 extcon_get_edev_by_phandle(dev, 0) //获取外部连接器 fu***302 bq25700_register_cg_nb(charger); //注册 charger 通知链。 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(xx,bq25700_irq_handler_thread,xxx) enable_irq_wake //使能中断唤醒 bq25700_power_supply_init //注册 power supply 的 desc,用于上传获取充电状态 -》power_supply_register-》bq25700_power_supply_get_property//获取系统属性的接口 通知实例 otg_mode_store-》rockchip_u***2phy_set_mode-》 (kernel/drivers/phy/rockchip/phy-rockchip-inno-u***2.c) extcon_set_state_sync-》extcon_sync-》raw_notifier_call_chain 3、拔出AC,停止充电 1)注册任务与通知链 static int bq25700_register_discnt_nb(struct bq25700_device *charger) { 。.. INIT_DELAYED_WORK(&charger-》discnt_work, bq25700_discnt_evt_worker); ---》创建discnt_work延时任务 charger-》cable_discnt_nb.notifier_call = bq25700_discnt_evt_notfier; ret = extcon_register_notifier(charger-》cable_edev, EXTCON_USB, &charger-》cable_discnt_nb); 。.. } 2)流程梳理 bq25700_discnt_evt_notfier-》 queue_delayed_work(charger-》u***_charger_wq, &charger-》discnt_work, xxx)-》 bq25700_discnt_evt_worker-》 bq25700_discnt-》 bq25700_disable_charge bq25700_typec0_discharge power_supply_changed 4、PD work处理 1)注册任务与通知链 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); 。.. } 2)收到通知 bq25700_pd_evt_notifier-》 queue_delayed_work(charger-》u***_charger_wq, &charger-》pd_work,xxx)-》 bq25700_pd_evt_worker-》 bq25700_pd_connect-》获取PD协商出的电压和电流,设置charger输入电压和电流和充电电流 bq25700_enable_typec0-》 bq25700_get_chip_state-》 power_supply_changed-》 5、使能或禁止OTG功能 static int bq25700_register_host_nb(struct bq25700_device *charger) { 。.. INIT_DELAYED_WORK(&charger-》host_work, bq25700_host_evt_worker); ---》创建host_work延时任务 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); 。.. } bq25700_host_evt_notifier-》 queue_delayed_work-》 bq25700_host_evt_worker-》 extcon_get_cable_state_-》获取cable/charger状态 bq25700_field_write(charger, EN_OTG, xxx); ---》使能或禁止OTG 6、充电事件处理 static int bq25700_register_cg_nb(struct bq25700_device *charger) { 。.. INIT_DELAYED_WORK(&charger-》u***_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); 。.. } bq25700_charger_evt_notifier-》 queue_delayed_work-》 bq25700_charger_evt_worker-》 bq25700_charger_u***_bc_handel bq25700_enable_charger-》 // SDP/DCP/CDP power_supply_changed-》 |
|
|
|
7、charger中断处理
bq25700_irq_handler_thread 【日志信息】 1、插入充电器打印 [ 1561.796236] state_machine_typec unattached=2 [ 1562.054372] state_machine_typec attach_wait_sink=3 打印35次 [ 1562.059987] state_machine_typec attached_sink=6 [ 1562.060071] allen_debug:fu***_state_attached_sink,1648 [ 1562.060754] fu***302 5-0022: CC connected in CC1 as UFP [ 1562.060858] jon debug:::u***_mode:30 [ 1562.060916] force_u***_mode_store 0-》0 [ 1562.060963] jon debug:::u***_mode set 0 [ 1562.062994] state_machine_typec policy_snk_startup=19 [ 1562.064720] bq25700_discnt_evt_worker line1640 [ 1562.069680] state_machine_typec policy_snk_discovery=20 [ 1562.071540] state_machine_typec policy_snk_wait_caps=21 [ 1562.089561] bq25700_irq_handler_thread line1261 irq=198 00 [ 1562.099482] bq25700_host_evt_worker line1550 [ 1562.104086] healthd: battery l=47 v=7254 t=18.8 h=2 st=3 chg=u [ 1562.141302] rk_battery_charger_detect_cb , battery_charger_detect 2 [ 1562.148692] bq25700_charger_evt_worker line1503 u***_bc=1 [ 1562.162912] healthd: battery l=47 v=7254 t=18.8 h=2 st=3 chg=u [ 1562.182576] state_machine_typec policy_snk_wait_caps=21 [ 1562.184020] state_machine_typec policy_snk_evaluate_caps=22 [ 1562.187441] state_machine_typec policy_snk_select_cap=23 [ 1562.189049] state_machine_typec policy_snk_select_cap=23 [ 1562.195351] state_machine_typec policy_snk_select_cap=23 [ 1562.196795] state_machine_typec policy_snk_transition_sink=24 [ 1562.211321] healthd: battery l=47 v=7256 t=18.8 h=2 st=2 chg=u [ 1562.375627] state_machine_typec policy_snk_transition_sink=24 [ 1562.375649] fu***302 5-0022: PD connected as UFP, fetching 5V ---》协商完成,UFP模式 [ 1562.377014] state_machine_typec policy_snk_ready=25 [ 1562.377050] bq25700_discnt_evt_worker line1640 [ 1562.385335] bq25700_pd_evt_worker line1384 [ 1562.408119] jon SET vol_idx: 164mv [ 1562.408132] jon SET cur_idx: 60mA [ 1562.408138] jon SET harger-》init_data.ichg: 62mA [ 1562.435576] bq25700_host_evt_worker line1550 [ 1562.440200] healthd: battery l=47 v=7256 t=18.8 h=2 st=2 chg=u [ 1562.696760] state_machine_typec policy_snk_ready=25 2、拔出充电器打印 [ 4072.872299] bq25700_irq_handler_thread line1261 irq=198 00 ---》irq_flag = IRQF_TRIGGER_LOW [ 4072.906988] rk_battery_charger_detect_cb , battery_charger_detect 1 [ 4072.912096] state_machine_typec line2882 unattached=2 [ 4072.914829] bq25700_charger_evt_worker line1503 u***_bc=1 ---》bq25700_charger_u***_bc_handel [ 4072.919668] state_machine_typec line2882 attach_wait_sink=3 打印多次 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通知机制 /* * RAW_NOTIFIER_HEAD是定义一个通知链的头部结点, * 通过这个头部结点可以找到这个链中的其它所有的notifier_block */ static RAW_NOTIFIER_HEAD(test_chain); /* * 自定义的注册函数,将notifier_block节点加到刚刚定义的test_chain这个链表中来 * raw_notifier_chain_register会调用notifier_chain_register */ raw_notifier_chain_register(&test_chain, nb); // nb为struct notifier_block /* * 自定义的通知链表的函数,即通知test_chain指向的链表中的所有节点执行相应的函数 */ raw_notifier_call_chain(&test_chain, val, NULL); |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
626 浏览 0 评论
887 浏览 1 评论
784 浏览 1 评论
1997 浏览 1 评论
3242 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 00:34 , Processed in 0.442467 second(s), Total 43, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号