tiny4412 linux-4.2 移植(七)USB 2.0 host框架(2)hcd(ehci主机控制器)
简介
上一节整体介绍了usb host框架,分析了其中的phy层。这一节我们分析usb 框架中的hcd层。Exynos 4412的USB 2.0的 Host Controller包含USB 2.0 EHCI Host Controller和 USB 1.1 OHCI Host Controller,我这里只讲EHCI Host Controller。
框架图
hcd层以stuct usb_hcd为核心。它主要有两个功能,一个是通过ehci_hcd去操作phy层,一个是通过hc_driver去操作上层传递下来的urb数据包。
hcd
先来看下hcd相关的dts
# exynos4.dtsi
exynos_usbphy: exynos-usbphy@125B0000 {compatible = "samsung,exynos4210-usb2-phy";reg = <0x125B0000 0x100>;samsung,pmureg-phandle = <&pmu_system_controller>;clocks = <&clock CLK_USB_DEVICE>, <&clock CLK_XUSBXTI>;clock-names = "phy", "ref";#phy-cells = <1>;status = "disabled";
};
# exynos4412.dtsi
&exynos_usbphy {compatible = "samsung,exynos4x12-usb2-phy";samsung,sysreg-phandle = <&sys_reg>;
};
# exynos4412-tiny4412.dts
&exynos_usbphy {status = "okay";
};
# exynos4.dtsi
ehci: ehci@12580000 {compatible = "samsung,exynos4210-ehci";reg = <0x12580000 0x100>;interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clock CLK_USB_HOST>;clock-names = "usbhost";status = "disabled";#address-cells = <1>;#size-cells = <0>;
//exynos_ehci_get_phy中of_property_read_u32(child, "reg", &phy_number)获取到reg的值,然后作为port@0 {// 通过of_property_read_u32(child, "reg", &phy_number); 解析“reg”属性//在_of_phy_get中解析“phys”属性reg = <0>; //被解析成数组的下标 drv->instances[0].phyphys = <&exynos_usbphy 1>; //1代表 hoststatus = "disabled";};port@1 {reg = <1>; //被解析成数组的下标 drv->instances[1].phyphys = <&exynos_usbphy 2>; //2代表 hsci0status = "disabled";};port@2 {reg = <2>; //被解析成数组的下标 drv->instances[2].phyphys = <&exynos_usbphy 3>; //3代表 hsci1status = "disabled";};
};
# exynos4412-tiny4412.dts
&ehci {status = "okay";port@0 {status = "okay";};port@1 {status = "okay";};port@2 {status = "okay";};
};
相关的驱动会匹配到/drivers/usb/host/ehci-exynos.c,来看下它的probe函数
///drivers/usb/host/ehci-hcd.c
static const struct hc_driver ehci_hc_driver = {.product_desc = "EHCI Host Controller",/* generic hardware linkage */.irq = ehci_irq,....../* managing i/o requests and associated device resources */.urb_enqueue = ehci_urb_enqueue,.urb_dequeue = ehci_urb_dequeue,/* scheduling support*/.get_frame_number = ehci_get_frame,/* root hub support */.hub_status_data = ehci_hub_status_data,.hub_control = ehci_hub_control,
};
///drivers/usb/host/ehci-exynos.c
static struct hc_driver __read_mostly exynos_ehci_hc_driver;//这个就是 struct hc_driver ehci_hc_driver
static int exynos_ehci_get_phy(struct device *dev,struct exynos_ehci_hcd *exynos_ehci)
{struct device_node *child;struct phy *phy;int phy_number;/* Get PHYs for the controller */for_each_available_child_of_node(dev->of_node, child) {ret = of_property_read_u32(child, "reg", &phy_number);//对应dts reg = <0>; reg = <1>;这些属性 phy = devm_of_phy_get(dev, child, NULL);--->//这个函数将间接使用samsung_usb2_phy_xlate来取得上一节初始化的phy---> phy = of_phy_get(np, con_id) --->---> phy = _of_phy_get(np, index) ---->----> struct phy *_of_phy_get(struct device_node *np, int index){//获取到 phys = <&exynos_usbphy 1>; 后面的参数ret = of_parse_phandle_with_args(np, "phys", "#phy-cells",index, &args);//调用samsung_usb2_phy_xlatephy = phy_provider->of_xlate(phy_provider->dev, &args); ---->--->samsung_usb2_phy_xlate(struct device *dev,struct of_phandle_args *args){ //所以dts的phys属性的参数:1代表host,2代表hsic0,3代表hsic1return drv->instances[args->args[0]].phy;}}exynos_ehci->phy[phy_number] = phy;
}
static int exynos_ehci_probe(struct platform_device *pdev)
{struct exynos_ehci_hcd *exynos_ehci;struct usb_hcd *hcd;struct ehci_hcd *ehci;hcd = usb_create_hcd(&exynos_ehci_hc_driver, //把ehci_hc_driver赋值给hcd->driver&pdev->dev, dev_name(&pdev->dev));/* usb_hcd的priv域是ehci_hcd,然后ehci_hcd的piv域是exynos_ehci_hcd 具体关系可以看框架图*/exynos_ehci = to_exynos_ehci(hcd); err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci); //获得在上一节初始化phy到struct exynos_ehci_hcderr = exynos_ehci_phy_enable(&pdev->dev); --->---> static int exynos_ehci_phy_enable(struct device *dev) {phy_power_on(exynos_ehci->phy[i]); ----->---> int phy_power_on(struct phy *phy) { /* /drivers/phy/phy-core.c */phy->ops->power_on(phy) ----> ----> static int samsung_usb2_phy_power_on(struct phy *phy){//到了这里就是上一节phy层的调用了,可以直接看上一节的内容。这里就是去设置寄存器}}}usb_add_hcd(hcd, irq, IRQF_SHARED) ---->---->int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags){retval = usb_register_bus(&hcd->self); //注册总线,因为hcd本身就是总线usb_hcd_request_irqs(hcd, irqnum, irqflags)request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd); //注册中断处理函数register_root_hub --->---> usb_new_device --->----> device_add/* * device_add之后会调用probe函数,由于这个device是个hub,所以会调用hub_probe* hub 1-0:1.0: USB hub found* hub 1-0:1.0: 3 ports detected*/}
}
总结一下,当dts到ehci driver匹配到之后会调用exynos_ehci_probe,probe函数会去创建usb_hcd,ehci_hcd和exynos_ehci_hcd,然后通过exynos_ehci_get_phy获取到在phy层初始化的phy,根据dts的指定,我这里获取到的是host、hsci0、hsci1这三个phy,然后通过phy的相关接口去使能对应的phy链路。最后把hcd添加到总线,注册它的中断处理函数,注册root hub。hub这一块我们下一节再讲。
tiny4412 linux-4.2 移植(七)USB 2.0 host框架(2)hcd(ehci主机控制器)相关推荐
- tiny4412 linux-4.2 移植(七)USB 2.0 host框架(1)phy
简介 本文主要讲述usb 2.0 host 中struct phy.struct usb_hcd.struct usb_hub.struct usb_port以及struct urb之间的关系.hcd ...
- tiny4412 linux-4.2 移植(九)USB 2.0 host框架(4)支持otg
由于前面支持了usb host,这里要支持otg模式就比较简单了. make menuconfig打开支持OTG | Symbol: USB_OTG [=n] || Type : bool || Pr ...
- linux查看usb3.0还是2.0,Linux分辨电脑是否有USB 3.0接口的命令行 怎么看电脑用独立显卡还是集成显卡...
延伸:怎么看电脑用独立显卡还是集成显卡 描述:方法一.通过接口来判断我们在主机箱后面的接口上,看你的链接数据线的接口接上了哪个接口,如果是连接集成显卡的话那就是连接到竖的的接口上,因为集成显卡的VGA ...
- linux添加ax88772b驱动,佳能 USB 2.0 to Fast Ethernet AX88772B 驱动程序下载-更新佳能软件(以太网控制器)...
ASIX USB 2.0 to Fast Ethernet AX88772B 驱动程序下载 如何手动下载和更新: 你可以通过 %%os%% 或通过执行 Windows® 更新获取基本的 USB 2.0 ...
- USB 2.0规范中译本 第二章 术语和缩写
第二章 术语和缩写 本章列出并定义了本规范中使用的术语和缩写 ACK 表示肯定确认的握手数据包. Active Device 已通电但未处于挂起状态的设备. Asynchronous Data 异步数 ...
- USB 2.0 眼图测试
一. USB 2.0 测试内容 USB 信号质量需要测试有:眼图测试.信号速率.包尾宽度. JK 抖动. KJ 抖动.连续抖动.单调性测试.上升下降时间,详细如下图: 二. USB 2.0 测试命令和 ...
- USB | 2. 最新USB 4.0规范解析及一致性测试
Update: 2022 / 10 / 11 USB | 2. 最新USB 4.0规范解析及一致性测试 目录 背景 USB 1.0 - 4.0 Type-C 接口 拓扑结构 USB 4 USB Typ ...
- Linux那些事儿 之 戏说USB(24)设备的生命线(七)
算是进入了HCD的片儿区,这里的老大不是帮派头目也不是巡逻片儿警,而是几个结构.在HCD这个片儿区,这个山头儿,王中之王就是include/linux/usb/hcd.h里定义的struct usb_ ...
- Linux系统移植实验---USB驱动的移植
实验八 USB驱动的移植 [实验目的] USB接口是现在计算机系统中最通用的一种接口, 说明:在本系统移植课程实验中命令行提示符 "$"表示是在主机上执行,"#" ...
最新文章
- Android学习——R文件丢失异常原因汇总
- javacript实现不被浏览器拦截打开新窗口
- csu 1756(数论+去重)
- URAL 1152. False Mirrors(DP)
- 通过 GitHub Actions 自动创建 Github Release
- 浅淡Kubernetes 与容器技术体系的最佳方法
- 容器编排技术 -- Kubernetes 使用Service暴露应用
- 新农大计算机学院照片,【新生指南】小团带你逛校园(内附农大全景图~)
- 計算機二級-java-03
- PostgreSQL 12系统表(11)pg_user
- Atitit freemarker模板总结 D:\workspace\springboothelloword\src\com\attilax\util\TempleteFreemarkerUtil.
- WPF-使用代码创建Grid行与列,并将控件添加到Grid中的指定行指定列
- 数据结构—队列的C语言实现
- R、冗余分析(RDA)、ggplot2、置信椭圆
- 选购家用安防摄像头,考虑室内还是室外,无线还是有线
- 用css动态实现圆环百分比分配——初探css3动画
- Photoshop——矫正变形图像
- 从简历被拒到收割今日头条offer,我花了一年时间
- DNS服务器优化的几种方式
- 爬虫python书籍-python爬虫有哪些书