您的位置:首页 > 运维架构 > 网站架构

Linux USB "On-The-Go"(OTG) on OMAP H2 软件架构分析(三)

2013-07-22 17:50 603 查看
原帖地址:/article/8995434.html

USB控制器驱动 (USB Controller Drivers)

在linux 2.6 kernel中定义了一些抽象的接口,用于在不同驱动程序间(如:OHCI driver与UDC
driver)通信.omap_usb_config是与处理器OMAP相关的接口(定义在include/asm-arm/arch-omap/board.h中的struct
omap_usb_config),用来定义板级的引脚引用和控制模式.其他通用的接口有struct otg_transceiver用来不同drivers间的工作.

OMAP USB 初始化

当前linux 2.6中通过板级相关的MACHINE_INIT hooks来建立正确的引脚关系和初始化控制器。在2.4 kernel中这些板级相关的逻辑是放在控制器的驱动程序中。而2.6
kernel把这些初始化部分从driver中移出,并连同其他板级初始化信息放在一起。Omap usb初始化工作是在arch/arm/mach-omap/usb.c中完成的。将板级相关的struct
omap_usb_info传递给初始化逻辑,它会通过struct platform_data来告诉driver。

OTG控制器(OTG Controller)

H2的OTG Controller集成了两个主要的逻辑部件:一个外部的Philips ISP1301 OTG tansceiver和OMAP
chip内的OTG Controller. 通过otg_transceiver接口来和OTG controller交互。

Struct otg_transceiver

该结构提供给开发者与USB硬件直接进行交互。Linu/usb_otg.h

Struct otg_transceiver{

Struct device *dev;

Const char *label;

U8 default_a;

Enum usb_otg_state state;

Struct usb_bus *host;

Struct usb_gadget *gadget;

/*to pass extra port status to the root hub*/

U16 port_status;

U16 port_change;

/*bind/unbind the host controller*/

Int (*set_host) (struct otg_transceiver *otg, struct usb_bus *host);

/*bind/unbind the peripheral controller*/

Int (*set_ peripheral) (struct otg_transceiver *otg, struct usb_gadget *gadget);

/*effective for B devices, ignored for A-peripheral */

Int (*set_power) (struct otg_transceiver *otg, unsigned mA);

/*for B devices only: start session with A-Host*/

Int (* start_srp) (struct otg_transceiver *otg);

/*start or continue HNP role switch*/

Int (*start_hnp) (struct otg_transceiver *otg);

}

Enum usb_otg_state是OTG spec中定义的诸多状态(linux/usb_otg.h),这些状态是在USB
reset之前的枚举状态。因此这些状态对于USB device或Gadget driver是不可见的。

当A-Host配置好OTG设备后,设备出于某种用途可能需要一定的电流。此时,B设备利用set_power将请求通过gadget
driver传递给OTG transceiver driver

这个OTG driver需要知道他将要和哪个usb controller (host, gadget)工作,并在某时刻激活这个controller.它同时还负责初始化struct
usb_bus.is_b_host和struct usb_gadget.is_a_peripheral标志。使driver层可以知道发生HNP角色转变。

Isp1301_omap

Drivers/i2c/chips/isp1301_omap.c实现了otg_transceiver API,用来支持大部分的OTG协议核心,同时也支持简单的host-only和peripheral-only模式。在H2和相关平台isp1301_omap
driver不但实现了otg_transceiver的部分接口,还能与TPS65010 chip的driver交互以控制USB
VBUS上的电流(0 – 500mA)。

为了支持OTG特性,isp1301 driver需要与OMAP OTG controller紧密结合。isp1301
driver中最主要的结构是一个工作队列(当前用kevent实现),isp1301 driver从isp1301得到信号比较器状态(signal
comparatot state),并告诉给OMAP controller.或者把OMAP OTG controller的控制命令返回给isp1301。

isp1301 driver由每个控制器通过中断方式驱动,查看isp1301发出和接收的信息,探测OTG状态机的转变并采取相应对策行为而有的对策行为要求是实时的。

OHCI 端口重启

为了满足HNP协议的时序要求,OTG controller driver在HNP过程中切换到host模式需要在设备连接的1ms内reset
OTG port。这意味着他开始一个中断服务;khubd将在几十ms内处理剩下的枚举工作。Driver可以用以下函数来传递bus->otg_port。

int usb_bus_start_enum(struct usb_bus *root, unsigned port_num);

OHCI已经有一个比较通用的实现办法,重发reset信号来确定reset持续了足够长的时间。

Omap_udc

Drivers/usb/gadget/omap_udc.c可以支持多个full speed端点,及在所有传输类型的方式下工作。Omap udc driver和其他的基于gadget框架的UDC
driver大体类似,只是包含了一些OTG相关的新特性。

Probe/release

通过is_otg告诉gadget driver是否支持OTG,如果用了外部OTG收发器,probe要找到OTG
controller的driver并注册他。

OTG设备特征标志位 (OTG Device Feature Flags)

由硬件负责更新。

远程唤醒调用 (Remote Wakeup calls)

必须与OTG controller driver会话来初始化SRP。

VBUS connect/disconnect 调用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐