diff options
| author | Paul Zimmerman <Paul.Zimmerman@synopsys.com> | 2012-04-16 17:19:06 -0400 |
|---|---|---|
| committer | Felipe Balbi <balbi@ti.com> | 2012-05-04 08:53:08 -0400 |
| commit | b4036ccdd2ce5ec0c4f29b91312dd3cf19fc9152 (patch) | |
| tree | b48719669536a489f842b1a8d55fd73a69055066 | |
| parent | 20c5e74c7b47cefaf2cd0f84bdb4830b66452384 (diff) | |
usb: gadget: add isochronous support to gadget zero
Add two isochronous endpoints to the gadget zero source/sink
function. They are enabled by selecting alternate interface 1, so
by default they are not enabled. Module parameters for setting all
the isoc endpoint characteristics are also provided.
Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
| -rw-r--r-- | drivers/usb/gadget/f_loopback.c | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_sourcesink.c | 424 | ||||
| -rw-r--r-- | drivers/usb/gadget/g_zero.h | 5 | ||||
| -rw-r--r-- | drivers/usb/gadget/zero.c | 19 |
4 files changed, 387 insertions, 65 deletions
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 2c0cd824c66..7275706caeb 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c | |||
| @@ -286,7 +286,7 @@ static void disable_loopback(struct f_loopback *loop) | |||
| 286 | struct usb_composite_dev *cdev; | 286 | struct usb_composite_dev *cdev; |
| 287 | 287 | ||
| 288 | cdev = loop->function.config->cdev; | 288 | cdev = loop->function.config->cdev; |
| 289 | disable_endpoints(cdev, loop->in_ep, loop->out_ep); | 289 | disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL); |
| 290 | VDBG(cdev, "%s disabled\n", loop->function.name); | 290 | VDBG(cdev, "%s disabled\n", loop->function.name); |
| 291 | } | 291 | } |
| 292 | 292 | ||
| @@ -329,7 +329,7 @@ fail0: | |||
| 329 | * than 'buflen' bytes each. | 329 | * than 'buflen' bytes each. |
| 330 | */ | 330 | */ |
| 331 | for (i = 0; i < qlen && result == 0; i++) { | 331 | for (i = 0; i < qlen && result == 0; i++) { |
| 332 | req = alloc_ep_req(ep); | 332 | req = alloc_ep_req(ep, 0); |
| 333 | if (req) { | 333 | if (req) { |
| 334 | req->complete = loopback_complete; | 334 | req->complete = loopback_complete; |
| 335 | result = usb_ep_queue(ep, req, GFP_ATOMIC); | 335 | result = usb_ep_queue(ep, req, GFP_ATOMIC); |
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 7aa7ac82c02..5c1b68b63c9 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
| @@ -51,6 +51,9 @@ struct f_sourcesink { | |||
| 51 | 51 | ||
| 52 | struct usb_ep *in_ep; | 52 | struct usb_ep *in_ep; |
| 53 | struct usb_ep *out_ep; | 53 | struct usb_ep *out_ep; |
| 54 | struct usb_ep *iso_in_ep; | ||
| 55 | struct usb_ep *iso_out_ep; | ||
| 56 | int cur_alt; | ||
| 54 | }; | 57 | }; |
| 55 | 58 | ||
| 56 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | 59 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) |
| @@ -59,18 +62,45 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | |||
| 59 | } | 62 | } |
| 60 | 63 | ||
| 61 | static unsigned pattern; | 64 | static unsigned pattern; |
| 62 | module_param(pattern, uint, 0); | 65 | module_param(pattern, uint, S_IRUGO|S_IWUSR); |
| 63 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 "); | 66 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none"); |
| 67 | |||
| 68 | static unsigned isoc_interval = 4; | ||
| 69 | module_param(isoc_interval, uint, S_IRUGO|S_IWUSR); | ||
| 70 | MODULE_PARM_DESC(isoc_interval, "1 - 16"); | ||
| 71 | |||
| 72 | static unsigned isoc_maxpacket = 1024; | ||
| 73 | module_param(isoc_maxpacket, uint, S_IRUGO|S_IWUSR); | ||
| 74 | MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); | ||
| 75 | |||
| 76 | static unsigned isoc_mult; | ||
| 77 | module_param(isoc_mult, uint, S_IRUGO|S_IWUSR); | ||
| 78 | MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)"); | ||
| 79 | |||
| 80 | static unsigned isoc_maxburst; | ||
| 81 | module_param(isoc_maxburst, uint, S_IRUGO|S_IWUSR); | ||
| 82 | MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)"); | ||
| 64 | 83 | ||
| 65 | /*-------------------------------------------------------------------------*/ | 84 | /*-------------------------------------------------------------------------*/ |
| 66 | 85 | ||
| 67 | static struct usb_interface_descriptor source_sink_intf = { | 86 | static struct usb_interface_descriptor source_sink_intf_alt0 = { |
| 68 | .bLength = sizeof source_sink_intf, | 87 | .bLength = USB_DT_INTERFACE_SIZE, |
| 69 | .bDescriptorType = USB_DT_INTERFACE, | 88 | .bDescriptorType = USB_DT_INTERFACE, |
| 70 | 89 | ||
| 90 | .bAlternateSetting = 0, | ||
| 71 | .bNumEndpoints = 2, | 91 | .bNumEndpoints = 2, |
| 72 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 92 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
| 73 | /* .iInterface = DYNAMIC */ | 93 | /* .iInterface = DYNAMIC */ |
| 94 | }; | ||
| 95 | |||
| 96 | static struct usb_interface_descriptor source_sink_intf_alt1 = { | ||
| 97 | .bLength = USB_DT_INTERFACE_SIZE, | ||
| 98 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 99 | |||
| 100 | .bAlternateSetting = 1, | ||
| 101 | .bNumEndpoints = 4, | ||
| 102 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
| 103 | /* .iInterface = DYNAMIC */ | ||
| 74 | }; | 104 | }; |
| 75 | 105 | ||
| 76 | /* full speed support: */ | 106 | /* full speed support: */ |
| @@ -91,10 +121,36 @@ static struct usb_endpoint_descriptor fs_sink_desc = { | |||
| 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 121 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 92 | }; | 122 | }; |
| 93 | 123 | ||
| 124 | static struct usb_endpoint_descriptor fs_iso_source_desc = { | ||
| 125 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 126 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 127 | |||
| 128 | .bEndpointAddress = USB_DIR_IN, | ||
| 129 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
| 130 | .wMaxPacketSize = cpu_to_le16(1023), | ||
| 131 | .bInterval = 4, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static struct usb_endpoint_descriptor fs_iso_sink_desc = { | ||
| 135 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 136 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 137 | |||
| 138 | .bEndpointAddress = USB_DIR_OUT, | ||
| 139 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
| 140 | .wMaxPacketSize = cpu_to_le16(1023), | ||
| 141 | .bInterval = 4, | ||
| 142 | }; | ||
| 143 | |||
| 94 | static struct usb_descriptor_header *fs_source_sink_descs[] = { | 144 | static struct usb_descriptor_header *fs_source_sink_descs[] = { |
| 95 | (struct usb_descriptor_header *) &source_sink_intf, | 145 | (struct usb_descriptor_header *) &source_sink_intf_alt0, |
| 96 | (struct usb_descriptor_header *) &fs_sink_desc, | 146 | (struct usb_descriptor_header *) &fs_sink_desc, |
| 97 | (struct usb_descriptor_header *) &fs_source_desc, | 147 | (struct usb_descriptor_header *) &fs_source_desc, |
| 148 | (struct usb_descriptor_header *) &source_sink_intf_alt1, | ||
| 149 | #define FS_ALT_IFC_1_OFFSET 3 | ||
| 150 | (struct usb_descriptor_header *) &fs_sink_desc, | ||
| 151 | (struct usb_descriptor_header *) &fs_source_desc, | ||
| 152 | (struct usb_descriptor_header *) &fs_iso_sink_desc, | ||
| 153 | (struct usb_descriptor_header *) &fs_iso_source_desc, | ||
| 98 | NULL, | 154 | NULL, |
| 99 | }; | 155 | }; |
| 100 | 156 | ||
| @@ -116,10 +172,34 @@ static struct usb_endpoint_descriptor hs_sink_desc = { | |||
| 116 | .wMaxPacketSize = cpu_to_le16(512), | 172 | .wMaxPacketSize = cpu_to_le16(512), |
| 117 | }; | 173 | }; |
| 118 | 174 | ||
| 175 | static struct usb_endpoint_descriptor hs_iso_source_desc = { | ||
| 176 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 177 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 178 | |||
| 179 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
| 180 | .wMaxPacketSize = cpu_to_le16(1024), | ||
| 181 | .bInterval = 4, | ||
| 182 | }; | ||
| 183 | |||
| 184 | static struct usb_endpoint_descriptor hs_iso_sink_desc = { | ||
| 185 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 186 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 187 | |||
| 188 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
| 189 | .wMaxPacketSize = cpu_to_le16(1024), | ||
| 190 | .bInterval = 4, | ||
| 191 | }; | ||
| 192 | |||
| 119 | static struct usb_descriptor_header *hs_source_sink_descs[] = { | 193 | static struct usb_descriptor_header *hs_source_sink_descs[] = { |
| 120 | (struct usb_descriptor_header *) &source_sink_intf, | 194 | (struct usb_descriptor_header *) &source_sink_intf_alt0, |
| 121 | (struct usb_descriptor_header *) &hs_source_desc, | 195 | (struct usb_descriptor_header *) &hs_source_desc, |
| 122 | (struct usb_descriptor_header *) &hs_sink_desc, | 196 | (struct usb_descriptor_header *) &hs_sink_desc, |
| 197 | (struct usb_descriptor_header *) &source_sink_intf_alt1, | ||
| 198 | #define HS_ALT_IFC_1_OFFSET 3 | ||
| 199 | (struct usb_descriptor_header *) &hs_source_desc, | ||
| 200 | (struct usb_descriptor_header *) &hs_sink_desc, | ||
| 201 | (struct usb_descriptor_header *) &hs_iso_source_desc, | ||
| 202 | (struct usb_descriptor_header *) &hs_iso_sink_desc, | ||
| 123 | NULL, | 203 | NULL, |
| 124 | }; | 204 | }; |
| 125 | 205 | ||
| @@ -136,6 +216,7 @@ static struct usb_endpoint_descriptor ss_source_desc = { | |||
| 136 | struct usb_ss_ep_comp_descriptor ss_source_comp_desc = { | 216 | struct usb_ss_ep_comp_descriptor ss_source_comp_desc = { |
| 137 | .bLength = USB_DT_SS_EP_COMP_SIZE, | 217 | .bLength = USB_DT_SS_EP_COMP_SIZE, |
| 138 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | 218 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, |
| 219 | |||
| 139 | .bMaxBurst = 0, | 220 | .bMaxBurst = 0, |
| 140 | .bmAttributes = 0, | 221 | .bmAttributes = 0, |
| 141 | .wBytesPerInterval = 0, | 222 | .wBytesPerInterval = 0, |
| @@ -152,17 +233,64 @@ static struct usb_endpoint_descriptor ss_sink_desc = { | |||
| 152 | struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = { | 233 | struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = { |
| 153 | .bLength = USB_DT_SS_EP_COMP_SIZE, | 234 | .bLength = USB_DT_SS_EP_COMP_SIZE, |
| 154 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | 235 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, |
| 236 | |||
| 155 | .bMaxBurst = 0, | 237 | .bMaxBurst = 0, |
| 156 | .bmAttributes = 0, | 238 | .bmAttributes = 0, |
| 157 | .wBytesPerInterval = 0, | 239 | .wBytesPerInterval = 0, |
| 158 | }; | ||
