diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-02-06 18:46:36 +0100 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-09 10:11:36 +0200 |
commit | 6fecfb05c077586ba85aa6f52f10abf30a4bfb40 (patch) | |
tree | eb08f6192d75ef614a25a8148a99878dc6106057 /drivers/usb/gadget/f_acm.c | |
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/f_acm.c')
-rw-r--r-- | drivers/usb/gadget/f_acm.c | 50 |
1 files changed, 50 insertions, 0 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[] = { NULL, }; +static struct usb_endpoint_descriptor acm_ss_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_endpoint_descriptor acm_ss_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc = { + .bLength = sizeof acm_ss_bulk_comp_desc, + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_descriptor_header *acm_ss_function[] = { + (struct usb_descriptor_header *) &acm_iad_descriptor, + (struct usb_descriptor_header *) &acm_control_interface_desc, + (struct usb_descriptor_header *) &acm_header_desc, + (struct usb_descriptor_header *) &acm_call_mgmt_descriptor, + (struct usb_descriptor_header *) &acm_descriptor, + (struct usb_descriptor_header *) &acm_union_desc, + (struct usb_descriptor_header *) &acm_hs_notify_desc, + (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, + (struct usb_descriptor_header *) &acm_data_interface_desc, + (struct usb_descriptor_header *) &acm_ss_in_desc, + (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, + (struct usb_descriptor_header *) &acm_ss_out_desc, + (struct usb_descriptor_header *) &acm_ss_bulk_comp_desc, + NULL, +}; + /* string descriptors: */ #define ACM_CTRL_IDX 0 @@ -643,9 +679,21 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors */ f->hs_descriptors = usb_copy_descriptors(acm_hs_function); } + if (gadget_is_superspeed(c->cdev->gadget)) { + acm_ss_in_desc.bEndpointAddress = + acm_fs_in_desc.bEndpointAddress; + acm_ss_out_desc.bEndpointAddress = + acm_fs_out_desc.bEndpointAddress; + + /* copy descriptors, and track endpoint copies */ + f->ss_descriptors = usb_copy_descriptors(acm_ss_function); + if (!f->ss_descriptors) + goto fail; + } DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", acm->port_num, + gadget_is_superspeed(c->cdev->gadget) ? "super" : gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", acm->port.in->name, acm->port.out->name, acm->notify->name); @@ -675,6 +723,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) if (gadget_is_dualspeed(c->cdev->gadget)) usb_free_descriptors(f->hs_descriptors); + if (gadget_is_superspeed(c->cdev->gadget)) + usb_free_descriptors(f->ss_descriptors); usb_free_descriptors(f->descriptors); gs_free_req(acm->notify, acm->notify_req); kfree(acm); |