diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-02-06 12:46:36 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-09 03:11:36 -0500 |
commit | 6fecfb05c077586ba85aa6f52f10abf30a4bfb40 (patch) | |
tree | eb08f6192d75ef614a25a8148a99878dc6106057 /drivers/usb/gadget | |
parent | 609ca228073ae06c5513474d2cdf0af7ee5766ec (diff) |
usb: gadget: add usb3.0 descriptors to serial gadgets
This patch adds SS descriptors to the ACM & generic serial gadget. The
ACM part was tested with minicom + dummy + send / receive files over
ttyACM <=> ttyGS0.
The generic serial part (f_serial) was not tested (haven't found a
driver on the host side).
The nokia & multi gadget use HS at most.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/f_acm.c | 50 | ||||
-rw-r--r-- | drivers/usb/gadget/f_serial.c | 42 | ||||
-rw-r--r-- | drivers/usb/gadget/serial.c | 2 |
3 files changed, 93 insertions, 1 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index e48212195466..d672250a61fa 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -237,6 +237,42 @@ static struct usb_descriptor_header *acm_hs_function[] = { | |||
237 | NULL, | 237 | NULL, |
238 | }; | 238 | }; |
239 | 239 | ||
240 | static struct usb_endpoint_descriptor acm_ss_in_desc = { | ||
241 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
242 | .bDescriptorType = USB_DT_ENDPOINT, | ||
243 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
244 | .wMaxPacketSize = cpu_to_le16(1024), | ||
245 | }; | ||
246 | |||
247 | static struct usb_endpoint_descriptor acm_ss_out_desc = { | ||
248 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
249 | .bDescriptorType = USB_DT_ENDPOINT, | ||
250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
251 | .wMaxPacketSize = cpu_to_le16(1024), | ||
252 | }; | ||
253 | |||
254 | static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc = { | ||
255 | .bLength = sizeof acm_ss_bulk_comp_desc, | ||
256 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
257 | }; | ||
258 | |||
259 | static struct usb_descriptor_header *acm_ss_function[] = { | ||
260 | (struct usb_descriptor_header *) &acm_iad_descriptor, | ||
261 | (struct usb_descriptor_header *) &acm_control_interface_desc, | ||
262 | (struct usb_descriptor_header *) &acm_header_desc, | ||
263 | (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, | ||
264 | (struct usb_descriptor_header *) &acm_descriptor, | ||
265 | (struct usb_descriptor_header *) &acm_union_desc, | ||
266 | (struct usb_descriptor_header *) &acm_hs_notify_desc, | ||
267 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
268 | (struct usb_descriptor_header *) &acm_data_interface_desc, | ||
269 | (struct usb_descriptor_header *) &acm_ss_in_desc, | ||
270 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
271 | (struct usb_descriptor_header *) &acm_ss_out_desc, | ||
272 | (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, | ||
273 | NULL, | ||
274 | }; | ||
275 | |||
240 | /* string descriptors: */ | 276 | /* string descriptors: */ |
241 | 277 | ||
242 | #define ACM_CTRL_IDX 0 | 278 | #define ACM_CTRL_IDX 0 |
@@ -643,9 +679,21 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) | |||
643 | /* copy descriptors */ | 679 | /* copy descriptors */ |
644 | f->hs_descriptors = usb_copy_descriptors(acm_hs_function); | 680 | f->hs_descriptors = usb_copy_descriptors(acm_hs_function); |
645 | } | 681 | } |
682 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
683 | acm_ss_in_desc.bEndpointAddress = | ||
684 | acm_fs_in_desc.bEndpointAddress; | ||
685 | acm_ss_out_desc.bEndpointAddress = | ||
686 | acm_fs_out_desc.bEndpointAddress; | ||
687 | |||
688 | /* copy descriptors, and track endpoint copies */ | ||
689 | f->ss_descriptors = usb_copy_descriptors(acm_ss_function); | ||
690 | if (!f->ss_descriptors) | ||
691 | goto fail; | ||
692 | } | ||
646 | 693 | ||
647 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 694 | DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
648 | acm->port_num, | 695 | acm->port_num, |
696 | gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||
649 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 697 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
650 | acm->port.in->name, acm->port.out->name, | 698 | acm->port.in->name, acm->port.out->name, |
651 | acm->notify->name); | 699 | acm->notify->name); |
@@ -675,6 +723,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) | |||
675 | 723 | ||
676 | if (gadget_is_dualspeed(c->cdev->gadget)) | 724 | if (gadget_is_dualspeed(c->cdev->gadget)) |
677 | usb_free_descriptors(f->hs_descriptors); | 725 | usb_free_descriptors(f->hs_descriptors); |
726 | if (gadget_is_superspeed(c->cdev->gadget)) | ||
727 | usb_free_descriptors(f->ss_descriptors); | ||
678 | usb_free_descriptors(f->descriptors); | 728 | usb_free_descriptors(f->descriptors); |
679 | gs_free_req(acm->notify, acm->notify_req); | 729 | gs_free_req(acm->notify, acm->notify_req); |
680 | kfree(acm); | 730 | kfree(acm); |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index cf33a8d0fd5d..07197d63d9b1 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
@@ -99,6 +99,34 @@ static struct usb_descriptor_header *gser_hs_function[] __initdata = { | |||
99 | NULL, | 99 | NULL, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct usb_endpoint_descriptor gser_ss_in_desc __initdata = { | ||
103 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
104 | .bDescriptorType = USB_DT_ENDPOINT, | ||
105 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
106 | .wMaxPacketSize = cpu_to_le16(1024), | ||
107 | }; | ||
108 | |||
109 | static struct usb_endpoint_descriptor gser_ss_out_desc __initdata = { | ||
110 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
111 | .bDescriptorType = USB_DT_ENDPOINT, | ||
112 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
113 | .wMaxPacketSize = cpu_to_le16(1024), | ||
114 | }; | ||
115 | |||
116 | static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc __initdata = { | ||
117 | .bLength = sizeof gser_ss_bulk_comp_desc, | ||
118 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
119 | }; | ||
120 | |||
121 | static struct usb_descriptor_header *gser_ss_function[] __initdata = { | ||
122 | (struct usb_descriptor_header *) &gser_interface_desc, | ||
123 | (struct usb_descriptor_header *) &gser_ss_in_desc, | ||
124 | (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, | ||
125 | (struct usb_descriptor_header *) &gser_ss_out_desc, | ||
126 | (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, | ||
127 | NULL, | ||
128 | }; | ||
129 | |||
102 | /* string descriptors: */ | 130 | /* string descriptors: */ |
103 | 131 | ||
104 | static struct usb_string gser_string_defs[] = { | 132 | static struct usb_string gser_string_defs[] = { |
@@ -201,9 +229,21 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) | |||
201 | /* copy descriptors, and track endpoint copies */ | 229 | /* copy descriptors, and track endpoint copies */ |
202 | f->hs_descriptors = usb_copy_descriptors(gser_hs_function); | 230 | f->hs_descriptors = usb_copy_descriptors(gser_hs_function); |
203 | } | 231 | } |
232 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
233 | gser_ss_in_desc.bEndpointAddress = | ||
234 | gser_fs_in_desc.bEndpointAddress; | ||
235 | gser_ss_out_desc.bEndpointAddress = | ||
236 | gser_fs_out_desc.bEndpointAddress; | ||
237 | |||
238 | /* copy descriptors, and track endpoint copies */ | ||
239 | f->ss_descriptors = usb_copy_descriptors(gser_ss_function); | ||
240 | if (!f->ss_descriptors) | ||
241 | goto fail; | ||
242 | } | ||
204 | 243 | ||
205 | DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", | 244 | DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", |
206 | gser->port_num, | 245 | gser->port_num, |
246 | gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||
207 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 247 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
208 | gser->port.in->name, gser->port.out->name); | 248 | gser->port.in->name, gser->port.out->name); |
209 | return 0; | 249 | return 0; |
@@ -225,6 +265,8 @@ gser_unbind(struct usb_configuration *c, struct usb_function *f) | |||
225 | { | 265 | { |
226 | if (gadget_is_dualspeed(c->cdev->gadget)) | 266 | if (gadget_is_dualspeed(c->cdev->gadget)) |
227 | usb_free_descriptors(f->hs_descriptors); | 267 | usb_free_descriptors(f->hs_descriptors); |
268 | if (gadget_is_superspeed(c->cdev->gadget)) | ||
269 | usb_free_descriptors(f->ss_descriptors); | ||
228 | usb_free_descriptors(f->descriptors); | 270 | usb_free_descriptors(f->descriptors); |
229 | kfree(func_to_gser(f)); | 271 | kfree(func_to_gser(f)); |
230 | } | 272 | } |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ad9e5b2df642..665c07422c26 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -242,7 +242,7 @@ static struct usb_composite_driver gserial_driver = { | |||
242 | .name = "g_serial", | 242 | .name = "g_serial", |
243 | .dev = &device_desc, | 243 | .dev = &device_desc, |
244 | .strings = dev_strings, | 244 | .strings = dev_strings, |
245 | .max_speed = USB_SPEED_HIGH, | 245 | .max_speed = USB_SPEED_SUPER, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static int __init init(void) | 248 | static int __init init(void) |