当前位置:嗨网首页>书籍在线阅读

16-实例_S3C6410 USB 2.0的UDC驱动

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

20.4.2 实例:S3C6410 USB 2.0的UDC驱动

S3C6410除了一个USB1.1主机接口以外,还包括一个USB 2.0支持OTG的控制器。它既支持主机,又支持外设功能。当使能USB_S3C_OTG_HOST选项(即“S3C USB OTG Host support”菜单时),drivers/usb/host/s3c-otg目录中的源码被选中,实现主机控制器驱动;当使能USB_GADGET_S3C_OTGD(即“S3C HS USB OTG Device”)时,drivers/usb/gadget/s3c_udc_otg.c被编译,成为一个UDC。

drivers/usb/gadget/s3c_udc.h中定义了一个s3c_udc结构体,将S3C6410 UDC的gadget、usb_gadget_driver、endpoint等封装在一起,而drivers/usb/gadget/s3c_udc_otg.c则定义了一个它的实例,如代码清单20.32所示。

代码清单20.32 S3C6410 UDC驱动的s3c_udc结构体以及实例

1 struct s3c_udc {

2 struct usb_gadget gadget;

3 struct usb_gadget_driver *driver;

4 struct platform_device *dev;

5 spinlock_t lock;

6

7 int ep0state;

8 struct s3c_ep ep[S3C_MAX_ENDPOINTS];

9

10 unsigned char usb_address;

11

12 unsigned req_pending:1, req_std:1, req_config:1;

13 };

14

15 static struct s3c_udc memory = {

16 .usb_address = 0,

17

18 .gadget = {

19 .ops = &s3c_udc_ops,

20 .ep0 = &memory.ep[0].ep,

21 .name = driver_name,

22 .dev = {

23 .bus_id = "gadget",

24 .release = nop_release,

25 },

26 },

27

28 / 控制器endpoint /

29 .ep[0] = {

30 .ep = {

31 .name = ep0name,

32 .ops = &s3c_ep_ops,

33 .maxpacket = EP0_FIFO_SIZE,

34 },

35 .dev = &memory,

36

37 .bEndpointAddress = 0,

38 .bmAttributes = 0,

39

40 .ep_type = ep_control,

41 .fifo = (unsigned int) S3C_UDC_OTG_EP0_FIFO,

42 },

43

44 / endpoints /

45 .ep[1] = {

46 .ep = {

47 .name = "ep1-bulk",

48 .ops = &s3c_ep_ops,

49 .maxpacket = EP_FIFO_SIZE,

50 },

51 .dev = &memory,

52

53 .bEndpointAddress = USB_DIR_OUT | 1,

54 .bmAttributes = USB_ENDPOINT_XFER_BULK,

55

56 .ep_type = ep_bulk_out,

57 .fifo = (unsigned int) S3C_UDC_OTG_EP1_FIFO,

58 },

59

60 .ep[2] = {

61 ...

62 .bEndpointAddress = USB_DIR_IN | 2,

63 .bmAttributes = USB_ENDPOINT_XFER_BULK,

64

65 .ep_type = ep_bulk_in,

66 },

67

68 .ep[3] = {

69 ...

70 .bEndpointAddress = USB_DIR_IN | 3,

71 .bmAttributes = USB_ENDPOINT_XFER_INT,

72 ...

73 },

74 .ep[4] = {

75 ...

76 .bEndpointAddress = USB_DIR_OUT | 4,

77 .bmAttributes = USB_ENDPOINT_XFER_BULK,

78 ...

79 },

80 .ep[5] = {

81 ...

82 .bEndpointAddress = USB_DIR_IN | 5,

83 .bmAttributes = USB_ENDPOINT_XFER_BULK,

84

85 .ep_type = ep_bulk_in,

86 },

87 .ep[6] = {

88 ...

89 .bEndpointAddress = USB_DIR_IN | 6,

90 .bmAttributes = USB_ENDPOINT_XFER_INT,

91

92 .ep_type = ep_interrupt,

93 },

94 .ep[7] = {

95 ...

96 .bEndpointAddress = USB_DIR_OUT | 7,

97 .bmAttributes = USB_ENDPOINT_XFER_BULK,

98

99 .ep_type = ep_bulk_out,

100 },

101 ...

102 };

上述代码的第18~26行是对UDC整体的描述以及操作,从第29行起,描述的就是S3C6410 UDC的各个端点的类型、地址和操作。s3c_udc类型的memory是一个全局变量,实际上,在drivers/usb/gadget/s3c_udc_otg.c是一个基于platform的设备驱动的probe()过程中,还会进一步初始化memory中的各成员,例如通过list_add_tail()将各endpoint添加到ep_list等。

drivers/usb/gadget/s3c_udc_otg.c其他主要工作是根据endpoint的列表配置硬件和完成usb_request数据发送和接收请求,实现s3c_udc_ops和s3c_ep_ops这两个结构体的成员函数,实现usb_gadget_register_driver()、usb_gadget_unregister_driver()这两个API等。