mtk充电器插拔检测
以mt6357 pmic为例,充电器插拔检测和类型检测在mt6357-charger-type.c下完成:
一、首先从pmic的probe开始分析:
static int mt6357_charger_type_probe(struct platform_device *pdev)
{struct mtk_charger_type *info;struct iio_channel *chan_vbus;struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;int ret = 0;pr_notice("%s: starts\n", __func__);chan_vbus = devm_iio_channel_get(&pdev->dev, "pmic_vbus"); //dts中pmic_vbus设备节点读取,通过adc读取vcdt引脚上的分压电压(充电器电压)来识别并触发中断,if (IS_ERR(chan_vbus)) {pr_notice("mt6357 charger type requests probe deferral ret:%d\n",chan_vbus);return -EPROBE_DEFER;}info = devm_kzalloc(&pdev->dev, sizeof(*info),GFP_KERNEL);if (!info)return -ENOMEM;info->chip = (struct mt6397_chip *)dev_get_drvdata( //pmic私有数据获取pdev->dev.parent);info->regmap = info->chip->regmap;dev_set_drvdata(&pdev->dev, info);info->pdev = pdev;mutex_init(&info->ops_lock);check_boot_mode(info, &pdev->dev);info->psy_desc.name = "mtk_charger_type"; //一些私有数据赋值info->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;info->psy_desc.properties = chr_type_properties;info->psy_desc.num_properties = ARRAY_SIZE(chr_type_properties);info->psy_desc.get_property = psy_chr_type_get_property;info->psy_desc.set_property = psy_chr_type_set_property;info->psy_desc.property_is_writeable =psy_charger_type_property_is_writeable;info->psy_desc.usb_types = mt6357_charger_usb_types,info->psy_desc.num_usb_types = ARRAY_SIZE(mt6357_charger_usb_types),info->psy_cfg.drv_data = info;info->psy_cfg.of_node = np;info->psy_cfg.supplied_to = mt6357_charger_supplied_to;info->psy_cfg.num_supplicants = ARRAY_SIZE(mt6357_charger_supplied_to);info->ac_desc.name = "ac";info->ac_desc.type = POWER_SUPPLY_TYPE_MAINS;info->ac_desc.properties = mt_ac_properties;info->ac_desc.num_properties = ARRAY_SIZE(mt_ac_properties);info->ac_desc.get_property = mt_ac_get_property;info->ac_cfg.drv_data = info;info->usb_desc.name = "usb";info->usb_desc.type = POWER_SUPPLY_TYPE_USB;info->usb_desc.properties = mt_usb_properties;info->usb_desc.num_properties = ARRAY_SIZE(mt_usb_properties);info->usb_desc.get_property = mt_usb_get_property;info->usb_cfg.drv_data = info;info->psy = power_supply_register(&pdev->dev, &info->psy_desc, //注册此pmic设备为psy设备&info->psy_cfg);if (IS_ERR(info->psy)) {pr_notice("%s Failed to register power supply: %ld\n",__func__, PTR_ERR(info->psy));return PTR_ERR(info->psy);}pr_notice("%s register psy success\n", __func__);info->chan_vbus = devm_iio_channel_get( //再次读取该psy设备信息&pdev->dev, "pmic_vbus");if (IS_ERR_OR_NULL(info->chan_vbus)) {pr_notice("chan_vbus auxadc get fail, ret=%d\n",PTR_ERR(info->chan_vbus));}if (of_property_read_u32(np, "bc12_active", &info->bc12_active) < 0) //bc1.2使能,bc检测使能pr_notice("%s: no bc12_active\n", __func__);pr_notice("%s: bc12_active:%d\n", __func__, info->bc12_active);if (info->bc12_active) {info->ac_psy = power_supply_register(&pdev->dev, //注册ac psy设备&info->ac_desc, &info->ac_cfg);if (IS_ERR(info->ac_psy)) {pr_notice("%s Failed to register power supply: %ld\n",__func__, PTR_ERR(info->ac_psy));return PTR_ERR(info->ac_psy);}info->usb_psy = power_supply_register(&pdev->dev, //注册usb psy设备&info->usb_desc, &info->usb_cfg);if (IS_ERR(info->usb_psy)) {pr_notice("%s Failed to register power supply: %ld\n",__func__, PTR_ERR(info->usb_psy));return PTR_ERR(info->usb_psy);}INIT_WORK(&info->chr_work, do_charger_detection_work); //这里初始化了一个do_charger_detection_work任务,做插拔检测schedule_work(&info->chr_work);ret = devm_request_threaded_irq(&pdev->dev, //这里注册了一个chrdet_int_handler中断,触发方式是边沿触发,插入充电器和拔出,首先会执行这个中断函数platform_get_irq_byname(pdev, "chrdet"), NULL,chrdet_int_handler, IRQF_TRIGGER_HIGH, "chrdet", info);if (ret < 0)pr_notice("%s request chrdet irq fail\n", __func__);}info->first_connect = true;pr_notice("%s: done\n", __func__);return 0;
}
下面分解看它的中断函数和检测函数:
二、chrdet_int_handler函数:
irqreturn_t chrdet_int_handler(int irq, void *data)
{struct mtk_charger_type *info = data;unsigned int chrdet = 0;chrdet = bc11_get_register_value(info->regmap, //bc1.2读取pmic CHRDET寄存器值,来判断是否使能检测充电器PMIC_RGS_CHRDET_ADDR,PMIC_RGS_CHRDET_MASK,PMIC_RGS_CHRDET_SHIFT);if (!chrdet) {hw_bc11_done(info); //pmic寄存器操作/* 8 = KERNEL_POWER_OFF_CHARGING_BOOT *//* 9 = LOW_POWER_OFF_CHARGING_BOOT */if (info->bootmode == 8 || info->bootmode == 9) { //boot mode判断,关机充电或者低压充电pr_info("%s: Unplug Charger/USB\n", __func__);#ifndef CONFIG_TCPC_CLASSpr_info("%s: system_state=%d\n", __func__,system_state);if (system_state != SYSTEM_POWER_OFF)kernel_power_off(); //系统下点
#endif}}pr_notice("%s: chrdet:%d\n", __func__, chrdet);do_charger_detect(info, chrdet); //这里会去做充电器是否在位和类型判断return IRQ_HANDLED;
}
三、do_charger_detection_work:
static void do_charger_detection_work(struct work_struct *data)
{//container_of: 通过已知的一个数据结构成员指针data,数据结构类型mtk_charger_type,以及这个成员指针在这个数据结构中的成员名chr_work,来获取指向这个数据结构的指针mtk_charger_type *struct mtk_charger_type *info = (struct mtk_charger_type *)container_of( data, struct mtk_charger_type, chr_work);unsigned int chrdet = 0;chrdet = bc11_get_register_value(info->regmap, //bc1.2读取pmic CHRDET寄存器值,来判断是否使能检测充电器PMIC_RGS_CHRDET_ADDR,PMIC_RGS_CHRDET_MASK,PMIC_RGS_CHRDET_SHIFT);pr_notice("%s: chrdet:%d\n", __func__, chrdet);if (chrdet)do_charger_detect(info, chrdet); //这里会去做充电器是否在位和类型判断else {hw_bc11_done(info);/* 8 = KERNEL_POWER_OFF_CHARGING_BOOT *//* 9 = LOW_POWER_OFF_CHARGING_BOOT */if (info->bootmode == 8 || info->bootmode == 9) {pr_info("%s: Unplug Charger/USB\n", __func__);#ifndef CONFIG_TCPC_CLASSpr_info("%s: system_state=%d\n", __func__,system_state);if (system_state != SYSTEM_POWER_OFF)kernel_power_off();
#endif}}
}
四、do_charger_detect:
这个函数会在do_charger_detection_work和chrdet_int_handler都去调用,主要是做psy设备状态改变之后的通知动作
;
void do_charger_detect(struct mtk_charger_type *info, bool en)
{union power_supply_propval prop, prop2, prop3;int ret = 0;#ifndef CONFIG_TCPC_CLASSif (!mt_usb_is_device()) { //通过usb phy识别和确认是usb设备pr_info("charger type: UNKNOWN, Now is usb host mode. Skip detection\n");return;}
#endifprop.intval = en;if (en) {ret = power_supply_set_property(info->psy, //spy设备online属性设置POWER_SUPPLY_PROP_ONLINE, &prop);ret = power_supply_get_property(info->psy, //psy类型获取POWER_SUPPLY_PROP_TYPE, &prop2);ret = power_supply_get_property(info->psy, //usb类型获取POWER_SUPPLY_PROP_USB_TYPE, &prop3);} else {prop2.intval = POWER_SUPPLY_TYPE_UNKNOWN;prop3.intval = POWER_SUPPLY_USB_TYPE_UNKNOWN;info->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;info->type = POWER_SUPPLY_USB_TYPE_UNKNOWN;}pr_notice("%s type:%d usb_type:%d\n", __func__, prop2.intval, prop3.intval);if(en &&(prop3.intval ==1 || prop3.intval ==3)) { //usb类型mt_usb_connect();} else {mt_usb_disconnect();}power_supply_changed(info->psy); //这里做psy设备状态更新
}
mtk充电器插拔检测相关推荐
- 耳机驱动调试(插拔检测与按键检测)
耳机驱动调试(插拔检测与按键检测) 小白一枚,欢各位大佬指出错误 耳机类型判断 三段和四段.欧标和美标 现在许多设备的耳机接口都采用3.5mm的耳机接口,其中终端就是,终端可以兼容三段和四段耳机:三段 ...
- linux U盘插拔检测
因为最终要在tiny210上实现此功能,最终选择了hotplug. http://hi.baidu.com/hdy5200075/item/7751f48647f3d12a100ef3f6这里是hot ...
- MFC使用Windows API实现U盘插拔检测,获取U盘容量,U盘内容移动删除,开启和关闭U盘以及获取盘符
文章目录 前言 一.利用OS API实现对U盘的管理 二.项目到底长啥样 三.实例代码 1.实时判断U盘插入与拔出 2.能够显示U盘的总容量.使用容量和剩余容量 3.能够将某个目录上的文件或整个目录复 ...
- 教程一:windows api(c mfc vs2017)实现U盘插拔检测,获取U盘容量,U盘内容移动,开启和关闭U盘以及获取盘符等
c++是大二下学期的专业课,大家可能都学过,这里主要介绍U盘这个小项目要用到没学过的知识.(踩坑合集) U盘完整项目源代码下载地址:https://download.csdn.net/download ...
- 使用libusb检测USB设备插拔状态
libusb是一个提供USB设备访问的跨平台用户模式程序库.该项目最新网址:http://www.libusb.info, 支持主流的操作系统:Linux.Mac OS X. Windows.Open ...
- 高通平台耳机插拔检测
https://blog.csdn.net/u012899335/article/details/82312766 高通耳机的插拔检测需要配置NC或NO,并且使用匹配的耳机(欧标,美标). 欧标,美标 ...
- sim插拔识别时间_特斯拉+树莓派实现车牌识别检测系统
转自机器之心 | 作者:Robert Lucian Chiriac | 参与:王子嘉.思.一鸣 怎样在不换车的前提下打造一个智能车系统呢?一段时间以来,本文作者 Robert Lucian Chiri ...
- [转]VB:如何检测到U盘的插拔(源代码)
听说现在网络上流传着一些能实时检测到U盘插拔消息并能在其插入后伺机拷贝其中文档资料的恶意程序,而日前在CSDN论坛也看到有网友询问这类程序的实现原理,为此我想通过一个简单的VB程序演示一下核心操作过程 ...
- shell 判断网线插拔_linux检测网线插拔状态
Shell查看网线插拔状态: 使用ifconfig命令,如果含有"RUNNING",说明网线接入,否则就没有. 例: ifconfig ifconfig eth0 ifconfig ...
最新文章
- ArcBruTile 0.2.2
- eclipse创建了java web项目后怎么连接mysql
- redis反杀面试官之10问
- java 物理内存_聊聊Java中的内存
- php session缓存,扫盲:php session缓存至memcached中的方法
- 关于二维数组取地址加以或减一解引用问题
- [蓝桥杯][2018年第九届真题]约瑟夫环
- oracle的aud文件,oracle asm实例的aud文件有关问题
- [转]Qt 之 QFileSystemWatcher
- 使用php-amqplib连接rabbitMQ 学习笔记及总结
- iOS底层探索之多线程(十七)——通过 Swift的Foundation源码分析锁(NSLock、NSCondition、NSRecursiveLock)
- HDU 3333-Turing Tree(BIT好题)
- Atitit 提升稳定性 数据库死锁 目录 1.1. 配置数据库死锁检测超时时间从默认50s到10s	1 1.2. 调整隔离级别到read commit	1 1.3. mysql数据库连接使用完毕
- 联想电脑 Windows10 20H2 32位64位 专业版 V2021【OEM原版镜像】
- python安装openpyxl库_Python openpyxl 库
- Java--集合框架--Map集合、 HashMap和Hashtable的区别、 Collections(集合工具类)
- 高级语言程序设计(c语言描述) 陆黎明 朱媛媛 练习答案,高级语言程序设计(c语言描述) 陆黎明 朱媛媛 练习答案...
- 实时渲染3D动画创作大赛
- 使用R进行VENN_维恩图或韦恩图_的绘制_2020-11-08
- 在windows下使用docker做本机linux环境系统测试