分类: LINUX
2013-01-16 16:41:25
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 调用