extcon驱动及其在USB驱动中的应用
extcon,是External Connector的简称,用于抽象外部连接器,比如说Audio Jack、USB MicroB/TypeC接口等。它的原型是Android的switch-class驱动,经过修改后在kernel 3.4.0版本时被引入内核中。
Extcon (external connector): import Android's switch class and modify.
External connector class (extcon) is based on and an extension of Android kernel's switch class located at linux/drivers/switch/.
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/extcon?h=next-20220502&id=de55d8716ac50a356cea736c29bb7db5ac3d0190
extcon驱动的主要功能是识别外部连接器状态变化,并将状态变化通知到与外部连接器相关的其他驱动。
使用extcon驱动,有什么好处呢?之前的内核都没有extcon驱动,又是怎么处理这些外部连接器的?不妨以USB驱动为例,看看使用extcon驱动前后的变化。
USB常见的外部接口有TypeA/B/C三种,其中TypeA/B又有标准A/B、Mini A/B和Micro A/B三种,直接上图:
这三种不同的接口,TypeA/B只是物理信号上的连接,主控芯片内部没有针对TypeA/B的专用控制器,可通过VBUS和ID两个脚的状态来识别是否接入了USB主机或USB外设。接入主机前,VBUS脚上没有电压,接入主机后,主机端会在VBUS脚上提供5V电压;接入外设前,ID脚为高电平,接入外设后,ID脚被拉低。于是软件可以通过主动读取这两个脚的电平或者异步响应这两个脚的中断来获知状态的变化。
TypeC就有点特别,从TypeC规范可以看到,TypeC是有一个状态机的,从Unattached状态走到Attached Sink状态(做从设备)或者Attached Source状态(做主机),主控芯片内部是有相应的控制器的,控制器会通过寄存器汇报状态变化,并产生中断通知主控。TypeC控制器需要软件进行相应的编程来配置和使能它。
截图来自官方规范:USB Type-C 2.1 Release
https://www.usb.org/document-library/usb-type-cr-cable-and-connector-specification-release-21
以上就是USB针对不同外部接口所面临的状况。在extcon驱动出现之前,同一份USB控制器驱动代码,比较常见的做法就是在设备树(dts)中指明是哪种接口,USB控制器驱动代码中会解析设备树中的定义,通过if...else...来走不同的代码逻辑。如果是MicroB接口,就注册VBUS和ID脚的中断、查询IO脚的电平状态;如果是TypeC接口,就注册TypeC的中断,查询TypeC的状态。假设后续又有新的接口出现,工作原理不同于已有的接口,那就又需要在USB控制器驱动中去增加相关代码。
在extcon驱动出现后,USB控制器驱动就能和外部接口驱动解耦。在USB控制器驱动看来,不管外部接口是什么,我只需知道外部接口状态的变化就好了,比如是否接入主机了、是否有设备接入了。使用extcon驱动提供的函数接口来注册notifier,当外部接口状态变化时,extcon驱动负责回调notifier,USB控制器驱动代码无需再针对不同的外部接口改来改去。不同的外部接口,都用extcon来抽象自己的行为。
以上都是原理性的介绍,最后还是要落实到代码上才够清晰。以内核原生代码为例:
drivers\extcon\extcon-usb-gpio.c //extcon驱动示例
drivers\usb\dwc3\dwc3-omap.c //使用extcon示例
extcon-usb-gpio.c实现了通过IO脚(VBUS和ID)检测USB插拔的extcon驱动。整个驱动是以platform driver为框架。
在驱动的probe函数中,会从设备树获取VBUS和ID脚对应的GPIO。设备树中定义了这个extcon设备的相关属性。
接着会分配并注册一个extcon device。usb_extcon_cable数组定义了这个extcon device所支持的状态类型,EXTCON_USB表示USB做Device,EXTCON_USB_HOST表示USB做Host。状态值当然是插入或者拔出。
最后注册ID脚和VBUS脚的中断,注意这里两个脚的中断处理函数都是usb_irq_handler。两个脚的中断处理函数也不是非要是同一个,这里设置为同一个,是为了逻辑处理上的方便,因为VBUS和ID脚要联合判断。
usb_irq_handler函数里会queue work,这个work对应的处理函数如下图。通过extcon_set_state_sync函数通知其他驱动,只要有驱动注册了相应的notifier,就会被通知到。
以上是extcon-usb-gpio.c的实现,类似地,TypeC驱动也可以注册extcon device,通过extcon_set_state_sync函数向其他驱动汇报状态,这里就不再重复地举例。
最后看看dwc3-omap.c如何使用extcon。该驱动的probe函数中会调用下图函数,该函数首先调用extcon_get_edev_by_phandle从设备树获取extcon device,然后注册notifier,当extcon device状态变化时,notifier被回调;也可以通过extcon_get_state主动查询extcon device的状态。
------ END ------
作者:bigfish99
博客:https://www.cnblogs.com/bigfish0506/
公众号:大鱼嵌入式
extcon驱动及其在USB驱动中的应用的更多相关文章
- Linux驱动开发:USB驱动之usb_skel分析
在学习了这么些天的驱动之后,个人觉得驱动就是个架构的问题,只要把架构弄清楚了 然后往里面添砖加瓦就可以了,所以似乎看起来不是太困难,但也许是是我经验不足吧,这只能算是个人浅见了 这两天在学习USB驱动 ...
- USB驱动开发大全【转】
本文转载自:http://www.360doc.com/content/12/0504/19/8363527_208666082.shtml 编写USB驱动程序步骤:1所有usb驱动都必须创建主要结构 ...
- VxWorks下USB驱动总结1
1.USB设备 物理特征:4条电缆,电源线.地线.数据线.脉冲线; 速 度:低速1.5Mbps,全速12Mbps,高速480Mbps; 规范版本:1998年USB1.1,2000年USB2.0; 连 ...
- Linux USB驱动框架分析 【转】
转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...
- Linux USB驱动框架分析【转】
转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...
- usb驱动开发之大结局
从usb总线的那个match函数usb_device_match()开始到现在,遇到了设备,遇到了设备驱动,遇到了接口,也遇到了接口驱动,期间还多次遇到usb_device_match(),又多次与它 ...
- usb驱动开发24之接口驱动
从第一节我们已经知道,usb_generic_driver在自己的生命线里,以一己之力将设备的各个接口送给了linux的设备模型,让usb总线的match函数,也就是usb_device_match, ...
- Linux内核USB驱动【转】
本文转载自:http://www.360doc.com/content/12/0321/14/8363527_196286673.shtml 注意,该文件是2.4的内核的驱动源文件,并不保证在2.6内 ...
- usb驱动开发22之驱动生命线
我们总是很喜欢高潮,不是吗?那就好好对待她哦.我们来看一下linux中的高潮部分设备是怎么从Address进入Configured的. usb_set_configuration函数的代码就不贴了,可 ...
随机推荐
- springboot使用redis实现发布与订阅
配置redis连接地址 # Redis服务器地址 spring.redis.host=youxiu326.xin # Redis服务器连接端口 spring.redis.port=6379 # Red ...
- c++思维导图
转自:https://blog.csdn.net/qq_37941471/article/details/84026920
- 基于mongodb的搜索分页
mongodb模糊查询并分页 1.建立数据库 代码如下: var mongoose = require('mongoose'); var shortid = require('shortid'); v ...
- 一步步搭建物联网系统——无处不在的CSS
无处不在的CSS 或许你觉得CSS一点儿也不重要,而事实上,如果说HTML是建筑的框架,CSS就是房子的装修.那么Javascript呢,我听到的最有趣的说法是小三--还是先让我们回到代码上来吧. C ...
- hive从入门到放弃(四)——分区与分桶
今天讲讲分区表和分桶表,前面的文章还没看的可以点击链接: hive从入门到放弃(一)--初识hive hive从入门到放弃(二)--DDL数据定义 hive从入门到放弃(三)--DML数据操作 分区 ...
- C#编写程序,找一找一个二维数组中的鞍点
编写程序,找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在该列上最小.有可能数组没有鞍点).要求: 1.二维数组的大小.数组元素的值在运行时输入: 2.程序有友好的提示信息. 代码: us ...
- idea 启动微服务 设置 run dashboard
微服务如果很多,启动时如果在run窗口,会不是很方便,所以idea中配置了rundashboard,有时不自动出现时,需要进行配置: 配置操作如下: 我的idea版本2020.2 1.在父工程的.id ...
- 【Android开发】LogcatView,手机中查看logcat神器
先上图 集成: 1, allprojects { repositories { ... maven { url 'https://www.jitpack.io' } } } 2, dependenci ...
- Python简单文件读写
''' 用文件存储账户信息 使用列表存储多个账户信息,每个账户为一个字典对象 ''' users=[] #创建一个空列表 users.append({'id':'admin','pwd':'1235@ ...
- Ubuntu中hyperledger-fabric2.3.0环境搭建
系统环境 hyperledger-fabric在Ubuntu安装过程,fabric版本为2.3.0 首先安装相关软件 1.安装docker 直接参考下面这篇文档安装好docker-ce即可 Ubunt ...