diff options
Diffstat (limited to 'drivers/usb/gadget/function/f_hid.c')
| -rw-r--r-- | drivers/usb/gadget/function/f_hid.c | 75 | 
1 files changed, 70 insertions, 5 deletions
| diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index e2966f87c860..5f8139b8e601 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -98,6 +98,60 @@ static struct hid_descriptor hidg_desc = {  	/*.desc[0].wDescriptorLenght	= DYNAMIC */  }; +/* Super-Speed Support */ + +static struct usb_endpoint_descriptor hidg_ss_in_ep_desc = { +	.bLength		= USB_DT_ENDPOINT_SIZE, +	.bDescriptorType	= USB_DT_ENDPOINT, +	.bEndpointAddress	= USB_DIR_IN, +	.bmAttributes		= USB_ENDPOINT_XFER_INT, +	/*.wMaxPacketSize	= DYNAMIC */ +	.bInterval		= 4, /* FIXME: Add this field in the +				      * HID gadget configuration? +				      * (struct hidg_func_descriptor) +				      */ +}; + +static struct usb_ss_ep_comp_descriptor hidg_ss_in_comp_desc = { +	.bLength                = sizeof(hidg_ss_in_comp_desc), +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP, + +	/* .bMaxBurst           = 0, */ +	/* .bmAttributes        = 0, */ +	/* .wBytesPerInterval   = DYNAMIC */ +}; + +static struct usb_endpoint_descriptor hidg_ss_out_ep_desc = { +	.bLength		= USB_DT_ENDPOINT_SIZE, +	.bDescriptorType	= USB_DT_ENDPOINT, +	.bEndpointAddress	= USB_DIR_OUT, +	.bmAttributes		= USB_ENDPOINT_XFER_INT, +	/*.wMaxPacketSize	= DYNAMIC */ +	.bInterval		= 4, /* FIXME: Add this field in the +				      * HID gadget configuration? +				      * (struct hidg_func_descriptor) +				      */ +}; + +static struct usb_ss_ep_comp_descriptor hidg_ss_out_comp_desc = { +	.bLength                = sizeof(hidg_ss_out_comp_desc), +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP, + +	/* .bMaxBurst           = 0, */ +	/* .bmAttributes        = 0, */ +	/* .wBytesPerInterval   = DYNAMIC */ +}; + +static struct usb_descriptor_header *hidg_ss_descriptors[] = { +	(struct usb_descriptor_header *)&hidg_interface_desc, +	(struct usb_descriptor_header *)&hidg_desc, +	(struct usb_descriptor_header *)&hidg_ss_in_ep_desc, +	(struct usb_descriptor_header *)&hidg_ss_in_comp_desc, +	(struct usb_descriptor_header *)&hidg_ss_out_ep_desc, +	(struct usb_descriptor_header *)&hidg_ss_out_comp_desc, +	NULL, +}; +  /* High-Speed Support */  static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = { @@ -539,7 +593,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)  		}  		status = usb_ep_enable(hidg->out_ep);  		if (status < 0) { -			ERROR(cdev, "Enable IN endpoint FAILED!\n"); +			ERROR(cdev, "Enable OUT endpoint FAILED!\n");  			goto fail;  		}  		hidg->out_ep->driver_data = hidg; @@ -624,8 +678,14 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)  	/* set descriptor dynamic values */  	hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;  	hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; +	hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); +	hidg_ss_in_comp_desc.wBytesPerInterval = +				cpu_to_le16(hidg->report_length);  	hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);  	hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); +	hidg_ss_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); +	hidg_ss_out_comp_desc.wBytesPerInterval = +				cpu_to_le16(hidg->report_length);  	hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);  	hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);  	/* @@ -641,8 +701,13 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)  	hidg_hs_out_ep_desc.bEndpointAddress =  		hidg_fs_out_ep_desc.bEndpointAddress; +	hidg_ss_in_ep_desc.bEndpointAddress = +		hidg_fs_in_ep_desc.bEndpointAddress; +	hidg_ss_out_ep_desc.bEndpointAddress = +		hidg_fs_out_ep_desc.bEndpointAddress; +  	status = usb_assign_descriptors(f, hidg_fs_descriptors, -			hidg_hs_descriptors, NULL, NULL); +			hidg_hs_descriptors, hidg_ss_descriptors, NULL);  	if (status)  		goto fail; @@ -840,7 +905,7 @@ static void hidg_free_inst(struct usb_function_instance *f)  	mutex_lock(&hidg_ida_lock);  	hidg_put_minor(opts->minor); -	if (idr_is_empty(&hidg_ida.idr)) +	if (ida_is_empty(&hidg_ida))  		ghid_cleanup();  	mutex_unlock(&hidg_ida_lock); @@ -866,7 +931,7 @@ static struct usb_function_instance *hidg_alloc_inst(void)  	mutex_lock(&hidg_ida_lock); -	if (idr_is_empty(&hidg_ida.idr)) { +	if (ida_is_empty(&hidg_ida)) {  		status = ghid_setup(NULL, HIDG_MINORS);  		if (status)  {  			ret = ERR_PTR(status); @@ -879,7 +944,7 @@ static struct usb_function_instance *hidg_alloc_inst(void)  	if (opts->minor < 0) {  		ret = ERR_PTR(opts->minor);  		kfree(opts); -		if (idr_is_empty(&hidg_ida.idr)) +		if (ida_is_empty(&hidg_ida))  			ghid_cleanup();  		goto unlock;  	} |