xref: /OK3568_Linux_fs/kernel/drivers/usb/gadget/function/f_uvc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *	uvc_gadget.c  --  USB Video Class Gadget driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *	Copyright (C) 2009-2010
6*4882a593Smuzhiyun  *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/device.h>
10*4882a593Smuzhiyun #include <linux/errno.h>
11*4882a593Smuzhiyun #include <linux/fs.h>
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/list.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/mutex.h>
16*4882a593Smuzhiyun #include <linux/string.h>
17*4882a593Smuzhiyun #include <linux/usb/ch9.h>
18*4882a593Smuzhiyun #include <linux/usb/gadget.h>
19*4882a593Smuzhiyun #include <linux/usb/g_uvc.h>
20*4882a593Smuzhiyun #include <linux/usb/video.h>
21*4882a593Smuzhiyun #include <linux/vmalloc.h>
22*4882a593Smuzhiyun #include <linux/wait.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include <media/v4l2-dev.h>
25*4882a593Smuzhiyun #include <media/v4l2-event.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include "u_uvc.h"
28*4882a593Smuzhiyun #include "uvc.h"
29*4882a593Smuzhiyun #include "uvc_configfs.h"
30*4882a593Smuzhiyun #include "uvc_v4l2.h"
31*4882a593Smuzhiyun #include "uvc_video.h"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun unsigned int uvc_gadget_trace_param;
34*4882a593Smuzhiyun module_param_named(trace, uvc_gadget_trace_param, uint, 0644);
35*4882a593Smuzhiyun MODULE_PARM_DESC(trace, "Trace level bitmask");
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* --------------------------------------------------------------------------
38*4882a593Smuzhiyun  * Function descriptors
39*4882a593Smuzhiyun  */
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* string IDs are assigned dynamically */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define UVC_STRING_CONTROL_IDX			0
44*4882a593Smuzhiyun #define UVC_STRING_STREAMING_IDX		1
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static struct usb_string uvc_en_us_strings[] = {
47*4882a593Smuzhiyun 	/* [UVC_STRING_CONTROL_IDX].s = DYNAMIC, */
48*4882a593Smuzhiyun 	[UVC_STRING_STREAMING_IDX].s = "Video Streaming",
49*4882a593Smuzhiyun 	{  }
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static struct usb_gadget_strings uvc_stringtab = {
53*4882a593Smuzhiyun 	.language = 0x0409,	/* en-us */
54*4882a593Smuzhiyun 	.strings = uvc_en_us_strings,
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static struct usb_gadget_strings *uvc_function_strings[] = {
58*4882a593Smuzhiyun 	&uvc_stringtab,
59*4882a593Smuzhiyun 	NULL,
60*4882a593Smuzhiyun };
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define UVC_INTF_VIDEO_CONTROL			0
63*4882a593Smuzhiyun #define UVC_INTF_VIDEO_STREAMING		1
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define UVC_STATUS_MAX_PACKET_SIZE		16	/* 16 bytes status */
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static struct usb_interface_assoc_descriptor uvc_iad = {
68*4882a593Smuzhiyun 	.bLength		= sizeof(uvc_iad),
69*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_INTERFACE_ASSOCIATION,
70*4882a593Smuzhiyun 	.bFirstInterface	= 0,
71*4882a593Smuzhiyun 	.bInterfaceCount	= 2,
72*4882a593Smuzhiyun 	.bFunctionClass		= USB_CLASS_VIDEO,
73*4882a593Smuzhiyun 	.bFunctionSubClass	= UVC_SC_VIDEO_INTERFACE_COLLECTION,
74*4882a593Smuzhiyun 	.bFunctionProtocol	= 0x00,
75*4882a593Smuzhiyun 	.iFunction		= 0,
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun static struct usb_interface_descriptor uvc_control_intf = {
79*4882a593Smuzhiyun 	.bLength		= USB_DT_INTERFACE_SIZE,
80*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_INTERFACE,
81*4882a593Smuzhiyun 	.bInterfaceNumber	= UVC_INTF_VIDEO_CONTROL,
82*4882a593Smuzhiyun 	.bAlternateSetting	= 0,
83*4882a593Smuzhiyun 	.bNumEndpoints		= 1,
84*4882a593Smuzhiyun 	.bInterfaceClass	= USB_CLASS_VIDEO,
85*4882a593Smuzhiyun 	.bInterfaceSubClass	= UVC_SC_VIDEOCONTROL,
86*4882a593Smuzhiyun 	.bInterfaceProtocol	= 0x00,
87*4882a593Smuzhiyun 	.iInterface		= 0,
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_control_ep = {
91*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
92*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
93*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
94*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_XFER_INT,
95*4882a593Smuzhiyun 	.wMaxPacketSize		= cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
96*4882a593Smuzhiyun 	.bInterval		= 8,
97*4882a593Smuzhiyun };
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp = {
100*4882a593Smuzhiyun 	.bLength		= sizeof(uvc_ss_control_comp),
101*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
102*4882a593Smuzhiyun 	/* The following 3 values can be tweaked if necessary. */
103*4882a593Smuzhiyun 	.bMaxBurst		= 0,
104*4882a593Smuzhiyun 	.bmAttributes		= 0,
105*4882a593Smuzhiyun 	.wBytesPerInterval	= cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun static struct uvc_control_endpoint_descriptor uvc_control_cs_ep = {
109*4882a593Smuzhiyun 	.bLength		= UVC_DT_CONTROL_ENDPOINT_SIZE,
110*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_CS_ENDPOINT,
111*4882a593Smuzhiyun 	.bDescriptorSubType	= UVC_EP_INTERRUPT,
112*4882a593Smuzhiyun 	.wMaxTransferSize	= cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
116*4882a593Smuzhiyun 	.bLength		= USB_DT_INTERFACE_SIZE,
117*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_INTERFACE,
118*4882a593Smuzhiyun 	.bInterfaceNumber	= UVC_INTF_VIDEO_STREAMING,
119*4882a593Smuzhiyun 	.bAlternateSetting	= 0,
120*4882a593Smuzhiyun 	.bNumEndpoints		= 0,
121*4882a593Smuzhiyun 	.bInterfaceClass	= USB_CLASS_VIDEO,
122*4882a593Smuzhiyun 	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
123*4882a593Smuzhiyun 	.bInterfaceProtocol	= 0x00,
124*4882a593Smuzhiyun 	.iInterface		= 0,
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun static struct usb_interface_descriptor uvc_bulk_streaming_intf_alt0 = {
128*4882a593Smuzhiyun 	.bLength		= USB_DT_INTERFACE_SIZE,
129*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_INTERFACE,
130*4882a593Smuzhiyun 	.bInterfaceNumber	= UVC_INTF_VIDEO_STREAMING,
131*4882a593Smuzhiyun 	.bAlternateSetting	= 0,
132*4882a593Smuzhiyun 	.bNumEndpoints		= 1,
133*4882a593Smuzhiyun 	.bInterfaceClass	= USB_CLASS_VIDEO,
134*4882a593Smuzhiyun 	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
135*4882a593Smuzhiyun 	.bInterfaceProtocol	= 0x00,
136*4882a593Smuzhiyun 	.iInterface		= 0,
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun static struct usb_interface_descriptor uvc_streaming_intf_alt1 = {
140*4882a593Smuzhiyun 	.bLength		= USB_DT_INTERFACE_SIZE,
141*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_INTERFACE,
142*4882a593Smuzhiyun 	.bInterfaceNumber	= UVC_INTF_VIDEO_STREAMING,
143*4882a593Smuzhiyun 	.bAlternateSetting	= 1,
144*4882a593Smuzhiyun 	.bNumEndpoints		= 1,
145*4882a593Smuzhiyun 	.bInterfaceClass	= USB_CLASS_VIDEO,
146*4882a593Smuzhiyun 	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
147*4882a593Smuzhiyun 	.bInterfaceProtocol	= 0x00,
148*4882a593Smuzhiyun 	.iInterface		= 0,
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
152*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
153*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
154*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
155*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_SYNC_ASYNC
156*4882a593Smuzhiyun 				| USB_ENDPOINT_XFER_ISOC,
157*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
158*4882a593Smuzhiyun 	 * module parameters.
159*4882a593Smuzhiyun 	 */
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_fs_bulk_streaming_ep = {
163*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
164*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
165*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
166*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
167*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
168*4882a593Smuzhiyun 	 * module parameters.
169*4882a593Smuzhiyun 	 */
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_hs_streaming_ep = {
173*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
174*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
175*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
176*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_SYNC_ASYNC
177*4882a593Smuzhiyun 				| USB_ENDPOINT_XFER_ISOC,
178*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
179*4882a593Smuzhiyun 	 * module parameters.
180*4882a593Smuzhiyun 	 */
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_hs_bulk_streaming_ep = {
184*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
185*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
186*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
187*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
188*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
189*4882a593Smuzhiyun 	 * module parameters.
190*4882a593Smuzhiyun 	 */
191*4882a593Smuzhiyun };
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_ss_streaming_ep = {
194*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
195*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
198*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_SYNC_ASYNC
199*4882a593Smuzhiyun 				| USB_ENDPOINT_XFER_ISOC,
200*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
201*4882a593Smuzhiyun 	 * module parameters.
202*4882a593Smuzhiyun 	 */
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun static struct usb_endpoint_descriptor uvc_ss_bulk_streaming_ep = {
206*4882a593Smuzhiyun 	.bLength		= USB_DT_ENDPOINT_SIZE,
207*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_ENDPOINT,
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	.bEndpointAddress	= USB_DIR_IN,
210*4882a593Smuzhiyun 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
211*4882a593Smuzhiyun 	/* The wMaxPacketSize and bInterval values will be initialized from
212*4882a593Smuzhiyun 	 * module parameters.
213*4882a593Smuzhiyun 	 */
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = {
217*4882a593Smuzhiyun 	.bLength		= sizeof(uvc_ss_streaming_comp),
218*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
219*4882a593Smuzhiyun 	/* The bMaxBurst, bmAttributes and wBytesPerInterval values will be
220*4882a593Smuzhiyun 	 * initialized from module parameters.
221*4882a593Smuzhiyun 	 */
222*4882a593Smuzhiyun };
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun static struct usb_ss_ep_comp_descriptor uvc_ss_bulk_streaming_comp = {
225*4882a593Smuzhiyun 	.bLength		= sizeof(uvc_ss_bulk_streaming_comp),
226*4882a593Smuzhiyun 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
227*4882a593Smuzhiyun 	/* The bMaxBurst, bmAttributes and wBytesPerInterval values will be
228*4882a593Smuzhiyun 	 * initialized from module parameters.
229*4882a593Smuzhiyun 	 */
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_fs_streaming[] = {
233*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
234*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_fs_streaming_ep,
235*4882a593Smuzhiyun 	NULL,
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_fs_bulk_streaming[] = {
239*4882a593Smuzhiyun 	(struct usb_descriptor_header *)&uvc_fs_bulk_streaming_ep,
240*4882a593Smuzhiyun 	NULL,
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_hs_streaming[] = {
244*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
245*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_hs_streaming_ep,
246*4882a593Smuzhiyun 	NULL,
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_hs_bulk_streaming[] = {
250*4882a593Smuzhiyun 	(struct usb_descriptor_header *)&uvc_hs_bulk_streaming_ep,
251*4882a593Smuzhiyun 	NULL,
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_ss_streaming[] = {
255*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
256*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_ss_streaming_ep,
257*4882a593Smuzhiyun 	(struct usb_descriptor_header *) &uvc_ss_streaming_comp,
258*4882a593Smuzhiyun 	NULL,
259*4882a593Smuzhiyun };
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun static const struct usb_descriptor_header * const uvc_ss_bulk_streaming[] = {
262*4882a593Smuzhiyun 	(struct usb_descriptor_header *)&uvc_ss_bulk_streaming_ep,
263*4882a593Smuzhiyun 	(struct usb_descriptor_header *)&uvc_ss_bulk_streaming_comp,
264*4882a593Smuzhiyun 	NULL,
265*4882a593Smuzhiyun };
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /* --------------------------------------------------------------------------
268*4882a593Smuzhiyun  * Control requests
269*4882a593Smuzhiyun  */
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static void
uvc_function_ep0_complete(struct usb_ep * ep,struct usb_request * req)272*4882a593Smuzhiyun uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	struct uvc_device *uvc = req->context;
275*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
276*4882a593Smuzhiyun 	struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	uvc_trace(UVC_TRACE_CONTROL,
279*4882a593Smuzhiyun 		  "event_setup_out %d, data len %d\n",
280*4882a593Smuzhiyun 		  uvc->event_setup_out, req->actual);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	if (uvc->event_setup_out) {
283*4882a593Smuzhiyun 		uvc->event_setup_out = 0;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 		memset(&v4l2_event, 0, sizeof(v4l2_event));
286*4882a593Smuzhiyun 		v4l2_event.type = UVC_EVENT_DATA;
287*4882a593Smuzhiyun 		uvc_event->data.length = min_t(unsigned int, req->actual,
288*4882a593Smuzhiyun 			sizeof(uvc_event->data.data));
289*4882a593Smuzhiyun 		memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length);
290*4882a593Smuzhiyun 		v4l2_event_queue(&uvc->vdev, &v4l2_event);
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun static int
uvc_function_setup(struct usb_function * f,const struct usb_ctrlrequest * ctrl)295*4882a593Smuzhiyun uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
298*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
299*4882a593Smuzhiyun 	struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	uvc_trace(UVC_TRACE_CONTROL,
302*4882a593Smuzhiyun 		  "setup request %02x %02x value %04x index %04x %04x\n",
303*4882a593Smuzhiyun 		  ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue),
304*4882a593Smuzhiyun 		  le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength));
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) {
307*4882a593Smuzhiyun 		uvcg_info(f, "invalid request type\n");
308*4882a593Smuzhiyun 		return -EINVAL;
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	/* Stall too big requests. */
312*4882a593Smuzhiyun 	if (le16_to_cpu(ctrl->wLength) > UVC_MAX_REQUEST_SIZE)
313*4882a593Smuzhiyun 		return -EINVAL;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	/* Tell the complete callback to generate an event for the next request
316*4882a593Smuzhiyun 	 * that will be enqueued by UVCIOC_SEND_RESPONSE.
317*4882a593Smuzhiyun 	 */
318*4882a593Smuzhiyun 	uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN);
319*4882a593Smuzhiyun 	uvc->event_length = le16_to_cpu(ctrl->wLength);
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	memset(&v4l2_event, 0, sizeof(v4l2_event));
322*4882a593Smuzhiyun 	v4l2_event.type = UVC_EVENT_SETUP;
323*4882a593Smuzhiyun 	memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
324*4882a593Smuzhiyun 	v4l2_event_queue(&uvc->vdev, &v4l2_event);
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	return 0;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
uvc_function_setup_continue(struct uvc_device * uvc)329*4882a593Smuzhiyun void uvc_function_setup_continue(struct uvc_device *uvc)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	struct usb_composite_dev *cdev = uvc->func.config->cdev;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	usb_composite_setup_continue(cdev);
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun static int
uvc_function_get_alt(struct usb_function * f,unsigned interface)337*4882a593Smuzhiyun uvc_function_get_alt(struct usb_function *f, unsigned interface)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
340*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	uvcg_info(f, "%s(%u)\n", __func__, interface);
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(f->fi);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	if (interface == uvc->control_intf)
347*4882a593Smuzhiyun 		return 0;
348*4882a593Smuzhiyun 	else if (interface != uvc->streaming_intf)
349*4882a593Smuzhiyun 		return -EINVAL;
350*4882a593Smuzhiyun 	else if (!opts->streaming_bulk)
351*4882a593Smuzhiyun 		return uvc->video.ep->enabled ? 1 : 0;
352*4882a593Smuzhiyun 	else
353*4882a593Smuzhiyun 		/*
354*4882a593Smuzhiyun 		 * Alt settings in an interface are supported only for
355*4882a593Smuzhiyun 		 * ISOC endpoints as there are different alt-settings for
356*4882a593Smuzhiyun 		 * zero-bandwidth and full-bandwidth cases, but the same
357*4882a593Smuzhiyun 		 * is not true for BULK endpoints, as they have a single
358*4882a593Smuzhiyun 		 * alt-setting.
359*4882a593Smuzhiyun 		 */
360*4882a593Smuzhiyun 		return 0;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun static int
uvc_function_set_alt(struct usb_function * f,unsigned interface,unsigned alt)364*4882a593Smuzhiyun uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
367*4882a593Smuzhiyun 	struct usb_composite_dev *cdev = f->config->cdev;
368*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
369*4882a593Smuzhiyun 	struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
370*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
371*4882a593Smuzhiyun 	int ret;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	uvcg_info(f, "%s(%u, %u)\n", __func__, interface, alt);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(f->fi);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	if (interface == uvc->control_intf) {
378*4882a593Smuzhiyun 		if (alt)
379*4882a593Smuzhiyun 			return -EINVAL;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 		uvcg_info(f, "reset UVC Control\n");
382*4882a593Smuzhiyun 		usb_ep_disable(uvc->control_ep);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		if (!uvc->control_ep->desc)
385*4882a593Smuzhiyun 			if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep))
386*4882a593Smuzhiyun 				return -EINVAL;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 		usb_ep_enable(uvc->control_ep);
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		if (uvc->event_suspend) {
391*4882a593Smuzhiyun 			memset(&v4l2_event, 0, sizeof(v4l2_event));
392*4882a593Smuzhiyun 			v4l2_event.type = UVC_EVENT_RESUME;
393*4882a593Smuzhiyun 			v4l2_event_queue(&uvc->vdev, &v4l2_event);
394*4882a593Smuzhiyun 			uvc->event_suspend = 0;
395*4882a593Smuzhiyun 			uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_RESUME\n");
396*4882a593Smuzhiyun 		}
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 		if (uvc->state == UVC_STATE_DISCONNECTED) {
399*4882a593Smuzhiyun 			memset(&v4l2_event, 0, sizeof(v4l2_event));
400*4882a593Smuzhiyun 			v4l2_event.type = UVC_EVENT_CONNECT;
401*4882a593Smuzhiyun 			uvc_event->speed = cdev->gadget->speed;
402*4882a593Smuzhiyun 			v4l2_event_queue(&uvc->vdev, &v4l2_event);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 			uvc->state = UVC_STATE_CONNECTED;
405*4882a593Smuzhiyun 		}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 		return 0;
408*4882a593Smuzhiyun 	}
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	if (interface != uvc->streaming_intf)
411*4882a593Smuzhiyun 		return -EINVAL;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
414*4882a593Smuzhiyun 		switch (alt) {
415*4882a593Smuzhiyun 		case 0:
416*4882a593Smuzhiyun 			if (uvc->state != UVC_STATE_STREAMING)
417*4882a593Smuzhiyun 				return 0;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 			if (uvc->video.ep)
420*4882a593Smuzhiyun 				usb_ep_disable(uvc->video.ep);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 			memset(&v4l2_event, 0, sizeof(v4l2_event));
423*4882a593Smuzhiyun 			v4l2_event.type = UVC_EVENT_STREAMOFF;
424*4882a593Smuzhiyun 			v4l2_event_queue(&uvc->vdev, &v4l2_event);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 			uvc->state = UVC_STATE_CONNECTED;
427*4882a593Smuzhiyun 			return 0;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 		case 1:
430*4882a593Smuzhiyun 			if (uvc->state != UVC_STATE_CONNECTED)
431*4882a593Smuzhiyun 				return 0;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 			if (!uvc->video.ep)
434*4882a593Smuzhiyun 				return -EINVAL;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 			INFO(cdev, "reset UVC\n");
437*4882a593Smuzhiyun 			usb_ep_disable(uvc->video.ep);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 			ret = config_ep_by_speed(f->config->cdev->gadget,
440*4882a593Smuzhiyun 						 &uvc->func, uvc->video.ep);
441*4882a593Smuzhiyun 			if (ret)
442*4882a593Smuzhiyun 				return ret;
443*4882a593Smuzhiyun 			usb_ep_enable(uvc->video.ep);
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 			memset(&v4l2_event, 0, sizeof(v4l2_event));
446*4882a593Smuzhiyun 			v4l2_event.type = UVC_EVENT_STREAMON;
447*4882a593Smuzhiyun 			v4l2_event_queue(&uvc->vdev, &v4l2_event);
448*4882a593Smuzhiyun 			return USB_GADGET_DELAYED_STATUS;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 		default:
451*4882a593Smuzhiyun 			return -EINVAL;
452*4882a593Smuzhiyun 		}
453*4882a593Smuzhiyun 	} else {
454*4882a593Smuzhiyun 		switch (uvc->state) {
455*4882a593Smuzhiyun 		case UVC_STATE_CONNECTED:
456*4882a593Smuzhiyun 			if (uvc->video.ep &&
457*4882a593Smuzhiyun 			    !uvc->video.ep->enabled) {
458*4882a593Smuzhiyun 				/*
459*4882a593Smuzhiyun 				 * Enable the video streaming endpoint,
460*4882a593Smuzhiyun 				 * but don't change the 'uvc->state'.
461*4882a593Smuzhiyun 				 */
462*4882a593Smuzhiyun 				ret = config_ep_by_speed(cdev->gadget,
463*4882a593Smuzhiyun 							 &uvc->func,
464*4882a593Smuzhiyun 							 uvc->video.ep);
465*4882a593Smuzhiyun 				if (ret)
466*4882a593Smuzhiyun 					return ret;
467*4882a593Smuzhiyun 				ret = usb_ep_enable(uvc->video.ep);
468*4882a593Smuzhiyun 				if (ret)
469*4882a593Smuzhiyun 					return ret;
470*4882a593Smuzhiyun 			} else {
471*4882a593Smuzhiyun 				memset(&v4l2_event, 0, sizeof(v4l2_event));
472*4882a593Smuzhiyun 				v4l2_event.type = UVC_EVENT_STREAMON;
473*4882a593Smuzhiyun 				v4l2_event_queue(&uvc->vdev, &v4l2_event);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 				uvc->state = UVC_STATE_STREAMING;
476*4882a593Smuzhiyun 			}
477*4882a593Smuzhiyun 			return 0;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 		case UVC_STATE_STREAMING:
480*4882a593Smuzhiyun 			if (!alt) {
481*4882a593Smuzhiyun 				INFO(cdev, "bulk streaming intf not support alt 0\n");
482*4882a593Smuzhiyun 				return 0;
483*4882a593Smuzhiyun 			}
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 			if (uvc->video.ep &&
486*4882a593Smuzhiyun 			    uvc->video.ep->enabled) {
487*4882a593Smuzhiyun 				ret = usb_ep_disable(uvc->video.ep);
488*4882a593Smuzhiyun 				if (ret)
489*4882a593Smuzhiyun 					return ret;
490*4882a593Smuzhiyun 			}
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 			memset(&v4l2_event, 0, sizeof(v4l2_event));
493*4882a593Smuzhiyun 			v4l2_event.type = UVC_EVENT_STREAMOFF;
494*4882a593Smuzhiyun 			v4l2_event_queue(&uvc->vdev, &v4l2_event);
495*4882a593Smuzhiyun 			uvc->state = UVC_STATE_CONNECTED;
496*4882a593Smuzhiyun 			return 0;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 		default:
499*4882a593Smuzhiyun 			return -EINVAL;
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 	}
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun static void
uvc_function_disable(struct usb_function * f)505*4882a593Smuzhiyun uvc_function_disable(struct usb_function *f)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
508*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	uvcg_info(f, "%s()\n", __func__);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	memset(&v4l2_event, 0, sizeof(v4l2_event));
513*4882a593Smuzhiyun 	v4l2_event.type = UVC_EVENT_DISCONNECT;
514*4882a593Smuzhiyun 	v4l2_event_queue(&uvc->vdev, &v4l2_event);
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	uvc->state = UVC_STATE_DISCONNECTED;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	usb_ep_disable(uvc->video.ep);
519*4882a593Smuzhiyun 	usb_ep_disable(uvc->control_ep);
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun 
uvc_function_suspend(struct usb_function * f)522*4882a593Smuzhiyun static void uvc_function_suspend(struct usb_function *f)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
525*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	memset(&v4l2_event, 0, sizeof(v4l2_event));
528*4882a593Smuzhiyun 	v4l2_event.type = UVC_EVENT_SUSPEND;
529*4882a593Smuzhiyun 	v4l2_event_queue(&uvc->vdev, &v4l2_event);
530*4882a593Smuzhiyun 	uvc->event_suspend = 1;
531*4882a593Smuzhiyun 	uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_SUSPEND\n");
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
uvc_function_resume(struct usb_function * f)534*4882a593Smuzhiyun static void uvc_function_resume(struct usb_function *f)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
537*4882a593Smuzhiyun 	struct v4l2_event v4l2_event;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	memset(&v4l2_event, 0, sizeof(v4l2_event));
540*4882a593Smuzhiyun 	v4l2_event.type = UVC_EVENT_RESUME;
541*4882a593Smuzhiyun 	v4l2_event_queue(&uvc->vdev, &v4l2_event);
542*4882a593Smuzhiyun 	uvc->event_suspend = 0;
543*4882a593Smuzhiyun 	uvc_trace(UVC_TRACE_SUSPEND, "send UVC_EVENT_RESUME\n");
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /* --------------------------------------------------------------------------
547*4882a593Smuzhiyun  * Connection / disconnection
548*4882a593Smuzhiyun  */
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun void
uvc_function_connect(struct uvc_device * uvc)551*4882a593Smuzhiyun uvc_function_connect(struct uvc_device *uvc)
552*4882a593Smuzhiyun {
553*4882a593Smuzhiyun 	int ret;
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	if ((ret = usb_function_activate(&uvc->func)) < 0)
556*4882a593Smuzhiyun 		uvcg_info(&uvc->func, "UVC connect failed with %d\n", ret);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun void
uvc_function_disconnect(struct uvc_device * uvc)560*4882a593Smuzhiyun uvc_function_disconnect(struct uvc_device *uvc)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	int ret;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	if ((ret = usb_function_deactivate(&uvc->func)) < 0)
565*4882a593Smuzhiyun 		uvcg_info(&uvc->func, "UVC disconnect failed with %d\n", ret);
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun /* --------------------------------------------------------------------------
569*4882a593Smuzhiyun  * USB probe and disconnect
570*4882a593Smuzhiyun  */
571*4882a593Smuzhiyun 
function_name_show(struct device * dev,struct device_attribute * attr,char * buf)572*4882a593Smuzhiyun static ssize_t function_name_show(struct device *dev,
573*4882a593Smuzhiyun 				  struct device_attribute *attr, char *buf)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	struct uvc_device *uvc = dev_get_drvdata(dev);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", uvc->func.fi->group.cg_item.ci_name);
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun static DEVICE_ATTR_RO(function_name);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun static int
uvc_register_video(struct uvc_device * uvc)583*4882a593Smuzhiyun uvc_register_video(struct uvc_device *uvc)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	struct usb_composite_dev *cdev = uvc->func.config->cdev;
586*4882a593Smuzhiyun 	int ret;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	/* TODO reference counting. */
589*4882a593Smuzhiyun 	uvc->vdev.v4l2_dev = &uvc->v4l2_dev;
590*4882a593Smuzhiyun 	uvc->vdev.fops = &uvc_v4l2_fops;
591*4882a593Smuzhiyun 	uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops;
592*4882a593Smuzhiyun 	uvc->vdev.release = video_device_release_empty;
593*4882a593Smuzhiyun 	uvc->vdev.vfl_dir = VFL_DIR_TX;
594*4882a593Smuzhiyun 	uvc->vdev.lock = &uvc->video.mutex;
595*4882a593Smuzhiyun 	uvc->vdev.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
596*4882a593Smuzhiyun 	strlcpy(uvc->vdev.name, cdev->gadget->name, sizeof(uvc->vdev.name));
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	video_set_drvdata(&uvc->vdev, uvc);
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	ret = video_register_device(&uvc->vdev, VFL_TYPE_VIDEO, -1);
601*4882a593Smuzhiyun 	if (ret < 0)
602*4882a593Smuzhiyun 		return ret;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	ret = device_create_file(&uvc->vdev.dev, &dev_attr_function_name);
605*4882a593Smuzhiyun 	if (ret < 0) {
606*4882a593Smuzhiyun 		video_unregister_device(&uvc->vdev);
607*4882a593Smuzhiyun 		return ret;
608*4882a593Smuzhiyun 	}
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	return 0;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun #define UVC_COPY_DESCRIPTOR(mem, dst, desc) \
614*4882a593Smuzhiyun 	do { \
615*4882a593Smuzhiyun 		memcpy(mem, desc, (desc)->bLength); \
616*4882a593Smuzhiyun 		*(dst)++ = mem; \
617*4882a593Smuzhiyun 		mem += (desc)->bLength; \
618*4882a593Smuzhiyun 	} while (0);
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun #define UVC_COPY_DESCRIPTORS(mem, dst, src) \
621*4882a593Smuzhiyun 	do { \
622*4882a593Smuzhiyun 		const struct usb_descriptor_header * const *__src; \
623*4882a593Smuzhiyun 		for (__src = src; *__src; ++__src) { \
624*4882a593Smuzhiyun 			memcpy(mem, *__src, (*__src)->bLength); \
625*4882a593Smuzhiyun 			*dst++ = mem; \
626*4882a593Smuzhiyun 			mem += (*__src)->bLength; \
627*4882a593Smuzhiyun 		} \
628*4882a593Smuzhiyun 	} while (0)
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun static struct usb_descriptor_header **
uvc_copy_descriptors(struct uvc_device * uvc,enum usb_device_speed speed)631*4882a593Smuzhiyun uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun 	struct uvc_input_header_descriptor *uvc_streaming_header;
634*4882a593Smuzhiyun 	struct uvc_header_descriptor *uvc_control_header;
635*4882a593Smuzhiyun 	const struct uvc_descriptor_header * const *uvc_control_desc;
636*4882a593Smuzhiyun 	const struct uvc_descriptor_header * const *uvc_streaming_cls;
637*4882a593Smuzhiyun 	const struct usb_descriptor_header * const *uvc_streaming_std;
638*4882a593Smuzhiyun 	const struct usb_descriptor_header * const *src;
639*4882a593Smuzhiyun 	struct usb_interface_descriptor *streaming_intf_alt0;
640*4882a593Smuzhiyun 	struct usb_descriptor_header **dst;
641*4882a593Smuzhiyun 	struct usb_descriptor_header **hdr;
642*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
643*4882a593Smuzhiyun 	unsigned int control_size;
644*4882a593Smuzhiyun 	unsigned int streaming_size;
645*4882a593Smuzhiyun 	unsigned int n_desc;
646*4882a593Smuzhiyun 	unsigned int bytes;
647*4882a593Smuzhiyun 	void *mem;
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(uvc->func.fi);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	switch (speed) {
652*4882a593Smuzhiyun 	case USB_SPEED_SUPER:
653*4882a593Smuzhiyun 		uvc_control_desc = uvc->desc.ss_control;
654*4882a593Smuzhiyun 		uvc_streaming_cls = uvc->desc.ss_streaming;
655*4882a593Smuzhiyun 		if (!opts->streaming_bulk)
656*4882a593Smuzhiyun 			uvc_streaming_std = uvc_ss_streaming;
657*4882a593Smuzhiyun 		else
658*4882a593Smuzhiyun 			uvc_streaming_std = uvc_ss_bulk_streaming;
659*4882a593Smuzhiyun 		break;
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	case USB_SPEED_HIGH:
662*4882a593Smuzhiyun 		uvc_control_desc = uvc->desc.fs_control;
663*4882a593Smuzhiyun 		uvc_streaming_cls = uvc->desc.hs_streaming;
664*4882a593Smuzhiyun 		if (!opts->streaming_bulk)
665*4882a593Smuzhiyun 			uvc_streaming_std = uvc_hs_streaming;
666*4882a593Smuzhiyun 		else
667*4882a593Smuzhiyun 			uvc_streaming_std = uvc_hs_bulk_streaming;
668*4882a593Smuzhiyun 		break;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	case USB_SPEED_FULL:
671*4882a593Smuzhiyun 	default:
672*4882a593Smuzhiyun 		uvc_control_desc = uvc->desc.fs_control;
673*4882a593Smuzhiyun 		uvc_streaming_cls = uvc->desc.fs_streaming;
674*4882a593Smuzhiyun 		if (!opts->streaming_bulk)
675*4882a593Smuzhiyun 			uvc_streaming_std = uvc_fs_streaming;
676*4882a593Smuzhiyun 		else
677*4882a593Smuzhiyun 			uvc_streaming_std = uvc_fs_bulk_streaming;
678*4882a593Smuzhiyun 		break;
679*4882a593Smuzhiyun 	}
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	if (!uvc_control_desc || !uvc_streaming_cls)
682*4882a593Smuzhiyun 		return ERR_PTR(-ENODEV);
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	/* Descriptors layout
685*4882a593Smuzhiyun 	 *
686*4882a593Smuzhiyun 	 * uvc_iad
687*4882a593Smuzhiyun 	 * uvc_control_intf
688*4882a593Smuzhiyun 	 * Class-specific UVC control descriptors
689*4882a593Smuzhiyun 	 * uvc_control_ep
690*4882a593Smuzhiyun 	 * uvc_control_cs_ep
691*4882a593Smuzhiyun 	 * uvc_ss_control_comp (for SS only)
692*4882a593Smuzhiyun 	 * uvc_streaming_intf_alt0
693*4882a593Smuzhiyun 	 * Class-specific UVC streaming descriptors
694*4882a593Smuzhiyun 	 * uvc_{fs|hs}_streaming
695*4882a593Smuzhiyun 	 */
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	if (!opts->streaming_bulk)
698*4882a593Smuzhiyun 		streaming_intf_alt0 = &uvc_streaming_intf_alt0;
699*4882a593Smuzhiyun 	else
700*4882a593Smuzhiyun 		streaming_intf_alt0 = &uvc_bulk_streaming_intf_alt0;
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	/* Count descriptors and compute their size. */
703*4882a593Smuzhiyun 	control_size = 0;
704*4882a593Smuzhiyun 	streaming_size = 0;
705*4882a593Smuzhiyun 	bytes = uvc_iad.bLength + uvc_control_intf.bLength
706*4882a593Smuzhiyun 	      + uvc_control_ep.bLength + uvc_control_cs_ep.bLength
707*4882a593Smuzhiyun 	      + streaming_intf_alt0->bLength;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	if (speed == USB_SPEED_SUPER) {
710*4882a593Smuzhiyun 		bytes += uvc_ss_control_comp.bLength;
711*4882a593Smuzhiyun 		n_desc = 6;
712*4882a593Smuzhiyun 	} else {
713*4882a593Smuzhiyun 		n_desc = 5;
714*4882a593Smuzhiyun 	}
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	for (src = (const struct usb_descriptor_header **)uvc_control_desc;
717*4882a593Smuzhiyun 	     *src; ++src) {
718*4882a593Smuzhiyun 		control_size += (*src)->bLength;
719*4882a593Smuzhiyun 		bytes += (*src)->bLength;
720*4882a593Smuzhiyun 		n_desc++;
721*4882a593Smuzhiyun 	}
722*4882a593Smuzhiyun 	for (src = (const struct usb_descriptor_header **)uvc_streaming_cls;
723*4882a593Smuzhiyun 	     *src; ++src) {
724*4882a593Smuzhiyun 		streaming_size += (*src)->bLength;
725*4882a593Smuzhiyun 		bytes += (*src)->bLength;
726*4882a593Smuzhiyun 		n_desc++;
727*4882a593Smuzhiyun 	}
728*4882a593Smuzhiyun 	for (src = uvc_streaming_std; *src; ++src) {
729*4882a593Smuzhiyun 		bytes += (*src)->bLength;
730*4882a593Smuzhiyun 		n_desc++;
731*4882a593Smuzhiyun 	}
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	mem = kmalloc((n_desc + 1) * sizeof(*src) + bytes, GFP_KERNEL);
734*4882a593Smuzhiyun 	if (mem == NULL)
735*4882a593Smuzhiyun 		return NULL;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	hdr = mem;
738*4882a593Smuzhiyun 	dst = mem;
739*4882a593Smuzhiyun 	mem += (n_desc + 1) * sizeof(*src);
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	/* Copy the descriptors. */
742*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTOR(mem, dst, &uvc_iad);
743*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_intf);
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	uvc_control_header = mem;
746*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTORS(mem, dst,
747*4882a593Smuzhiyun 		(const struct usb_descriptor_header **)uvc_control_desc);
748*4882a593Smuzhiyun 	uvc_control_header->wTotalLength = cpu_to_le16(control_size);
749*4882a593Smuzhiyun 	uvc_control_header->bInCollection = 1;
750*4882a593Smuzhiyun 	uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep);
753*4882a593Smuzhiyun 	if (speed == USB_SPEED_SUPER)
754*4882a593Smuzhiyun 		UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp);
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep);
757*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTOR(mem, dst, streaming_intf_alt0);
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	uvc_streaming_header = mem;
760*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTORS(mem, dst,
761*4882a593Smuzhiyun 		(const struct usb_descriptor_header**)uvc_streaming_cls);
762*4882a593Smuzhiyun 	uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size);
763*4882a593Smuzhiyun 	uvc_streaming_header->bEndpointAddress = uvc->video.ep->address;
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	*dst = NULL;
768*4882a593Smuzhiyun 	return hdr;
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun static int
uvc_function_bind(struct usb_configuration * c,struct usb_function * f)772*4882a593Smuzhiyun uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
773*4882a593Smuzhiyun {
774*4882a593Smuzhiyun 	struct usb_composite_dev *cdev = c->cdev;
775*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
776*4882a593Smuzhiyun 	struct usb_string *us;
777*4882a593Smuzhiyun 	unsigned int max_packet_mult;
778*4882a593Smuzhiyun 	unsigned int max_packet_size;
779*4882a593Smuzhiyun 	struct usb_ep *ep;
780*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
781*4882a593Smuzhiyun 	int ret = -EINVAL;
782*4882a593Smuzhiyun 	u8 address;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	uvcg_info(f, "%s()\n", __func__);
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(f->fi);
787*4882a593Smuzhiyun 	/* Sanity check the streaming endpoint module parameters.
788*4882a593Smuzhiyun 	 */
789*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
790*4882a593Smuzhiyun 		opts->streaming_interval = clamp(opts->streaming_interval,
791*4882a593Smuzhiyun 						 1U, 16U);
792*4882a593Smuzhiyun 		opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
793*4882a593Smuzhiyun 						  1U, 3072U);
794*4882a593Smuzhiyun 		opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
795*4882a593Smuzhiyun 	} else {
796*4882a593Smuzhiyun 		opts->streaming_maxpacket = clamp(opts->streaming_maxpacket,
797*4882a593Smuzhiyun 						  1U, 1024U);
798*4882a593Smuzhiyun 		opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
799*4882a593Smuzhiyun 	}
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	/* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
802*4882a593Smuzhiyun 	if (opts->streaming_maxburst &&
803*4882a593Smuzhiyun 	    (opts->streaming_maxpacket % 1024) != 0) {
804*4882a593Smuzhiyun 		opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
805*4882a593Smuzhiyun 		uvcg_info(f, "overriding streaming_maxpacket to %d\n",
806*4882a593Smuzhiyun 			  opts->streaming_maxpacket);
807*4882a593Smuzhiyun 	}
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 	/* Fill in the FS/HS/SS Video Streaming specific descriptors from the
810*4882a593Smuzhiyun 	 * module parameters.
811*4882a593Smuzhiyun 	 *
812*4882a593Smuzhiyun 	 * NOTE: We assume that the user knows what they are doing and won't
813*4882a593Smuzhiyun 	 * give parameters that their UDC doesn't support.
814*4882a593Smuzhiyun 	 */
815*4882a593Smuzhiyun 	if (opts->streaming_maxpacket <= 1024) {
816*4882a593Smuzhiyun 		max_packet_mult = 1;
817*4882a593Smuzhiyun 		max_packet_size = opts->streaming_maxpacket;
818*4882a593Smuzhiyun 	} else if (opts->streaming_maxpacket <= 2048) {
819*4882a593Smuzhiyun 		max_packet_mult = 2;
820*4882a593Smuzhiyun 		max_packet_size = opts->streaming_maxpacket / 2;
821*4882a593Smuzhiyun 	} else {
822*4882a593Smuzhiyun 		max_packet_mult = 3;
823*4882a593Smuzhiyun 		max_packet_size = opts->streaming_maxpacket / 3;
824*4882a593Smuzhiyun 	}
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
827*4882a593Smuzhiyun 		uvc_fs_streaming_ep.wMaxPacketSize =
828*4882a593Smuzhiyun 			cpu_to_le16(min(opts->streaming_maxpacket, 1023U));
829*4882a593Smuzhiyun 		uvc_fs_streaming_ep.bInterval = opts->streaming_interval;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 		uvc_hs_streaming_ep.wMaxPacketSize =
832*4882a593Smuzhiyun 			cpu_to_le16(max_packet_size |
833*4882a593Smuzhiyun 				    ((max_packet_mult - 1) << 11));
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 		/* A high-bandwidth endpoint must specify a bInterval value of 1 */
836*4882a593Smuzhiyun 		if (max_packet_mult > 1)
837*4882a593Smuzhiyun 			uvc_hs_streaming_ep.bInterval = 1;
838*4882a593Smuzhiyun 		else
839*4882a593Smuzhiyun 			uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 		uvc_ss_streaming_ep.wMaxPacketSize =
842*4882a593Smuzhiyun 			cpu_to_le16(max_packet_size);
843*4882a593Smuzhiyun 		uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
844*4882a593Smuzhiyun 		uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
845*4882a593Smuzhiyun 		uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
846*4882a593Smuzhiyun 		uvc_ss_streaming_comp.wBytesPerInterval =
847*4882a593Smuzhiyun 			cpu_to_le16(max_packet_size * max_packet_mult *
848*4882a593Smuzhiyun 				    (opts->streaming_maxburst + 1));
849*4882a593Smuzhiyun 	} else {
850*4882a593Smuzhiyun 		uvc_fs_bulk_streaming_ep.wMaxPacketSize =
851*4882a593Smuzhiyun 			cpu_to_le16(min(opts->streaming_maxpacket, 64U));
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 		uvc_hs_bulk_streaming_ep.wMaxPacketSize =
854*4882a593Smuzhiyun 			cpu_to_le16(min(opts->streaming_maxpacket, 512U));
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 		uvc_ss_bulk_streaming_ep.wMaxPacketSize =
857*4882a593Smuzhiyun 			cpu_to_le16(max_packet_size);
858*4882a593Smuzhiyun 		uvc_ss_bulk_streaming_comp.bMaxBurst = opts->streaming_maxburst;
859*4882a593Smuzhiyun 		/*
860*4882a593Smuzhiyun 		 * As per USB 3.1 spec "Table 9-26. SuperSpeed Endpoint
861*4882a593Smuzhiyun 		 * Companion Descriptor", the wBytesPerInterval must be
862*4882a593Smuzhiyun 		 * set to zero for bulk endpoints.
863*4882a593Smuzhiyun 		 */
864*4882a593Smuzhiyun 		uvc_ss_bulk_streaming_comp.wBytesPerInterval = 0;
865*4882a593Smuzhiyun 	}
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	/* Allocate endpoints. */
868*4882a593Smuzhiyun 	ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
869*4882a593Smuzhiyun 	if (!ep) {
870*4882a593Smuzhiyun 		uvcg_info(f, "Unable to allocate control EP\n");
871*4882a593Smuzhiyun 		goto error;
872*4882a593Smuzhiyun 	}
873*4882a593Smuzhiyun 	uvc->control_ep = ep;
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	if (gadget_is_superspeed(c->cdev->gadget)) {
876*4882a593Smuzhiyun 		if (!opts->streaming_bulk)
877*4882a593Smuzhiyun 			ep = usb_ep_autoconfig_ss(cdev->gadget,
878*4882a593Smuzhiyun 						  &uvc_ss_streaming_ep,
879*4882a593Smuzhiyun 						  &uvc_ss_streaming_comp);
880*4882a593Smuzhiyun 		else
881*4882a593Smuzhiyun 			ep = usb_ep_autoconfig_ss(cdev->gadget,
882*4882a593Smuzhiyun 						  &uvc_ss_bulk_streaming_ep,
883*4882a593Smuzhiyun 						  &uvc_ss_bulk_streaming_comp);
884*4882a593Smuzhiyun 	} else if (gadget_is_dualspeed(cdev->gadget)) {
885*4882a593Smuzhiyun 		if (!opts->streaming_bulk) {
886*4882a593Smuzhiyun 			ep = usb_ep_autoconfig(cdev->gadget,
887*4882a593Smuzhiyun 					       &uvc_hs_streaming_ep);
888*4882a593Smuzhiyun 		} else {
889*4882a593Smuzhiyun 			ep = usb_ep_autoconfig(cdev->gadget,
890*4882a593Smuzhiyun 					       &uvc_hs_bulk_streaming_ep);
891*4882a593Smuzhiyun 			/*
892*4882a593Smuzhiyun 			 * In ep_matches(), it will set wMaxPacketSize to 64
893*4882a593Smuzhiyun 			 * bytes if ep is Bulk and ep_comp is NULL for hs/fs
894*4882a593Smuzhiyun 			 * bulk maxpacket. So we need to set hs bulk maxpacket
895*4882a593Smuzhiyun 			 * 512 bytes again here.
896*4882a593Smuzhiyun 			 */
897*4882a593Smuzhiyun 			uvc_hs_bulk_streaming_ep.wMaxPacketSize =
898*4882a593Smuzhiyun 				cpu_to_le16(min(opts->streaming_maxpacket,
899*4882a593Smuzhiyun 						512U));
900*4882a593Smuzhiyun 		}
901*4882a593Smuzhiyun 	} else {
902*4882a593Smuzhiyun 		if (!opts->streaming_bulk)
903*4882a593Smuzhiyun 			ep = usb_ep_autoconfig(cdev->gadget,
904*4882a593Smuzhiyun 					       &uvc_fs_streaming_ep);
905*4882a593Smuzhiyun 		else
906*4882a593Smuzhiyun 			ep = usb_ep_autoconfig(cdev->gadget,
907*4882a593Smuzhiyun 					       &uvc_fs_bulk_streaming_ep);
908*4882a593Smuzhiyun 	}
909*4882a593Smuzhiyun 
910*4882a593Smuzhiyun 	if (!ep) {
911*4882a593Smuzhiyun 		uvcg_info(f, "Unable to allocate streaming EP\n");
912*4882a593Smuzhiyun 		goto error;
913*4882a593Smuzhiyun 	}
914*4882a593Smuzhiyun 	uvc->video.ep = ep;
915*4882a593Smuzhiyun 	address = uvc->video.ep->address;
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
918*4882a593Smuzhiyun 		uvc_fs_streaming_ep.bEndpointAddress = address;
919*4882a593Smuzhiyun 		uvc_hs_streaming_ep.bEndpointAddress = address;
920*4882a593Smuzhiyun 		uvc_ss_streaming_ep.bEndpointAddress = address;
921*4882a593Smuzhiyun 	} else {
922*4882a593Smuzhiyun 		uvc_fs_bulk_streaming_ep.bEndpointAddress = address;
923*4882a593Smuzhiyun 		uvc_hs_bulk_streaming_ep.bEndpointAddress = address;
924*4882a593Smuzhiyun 		uvc_ss_bulk_streaming_ep.bEndpointAddress = address;
925*4882a593Smuzhiyun 	}
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
928*4882a593Smuzhiyun 	if (opts->device_name)
929*4882a593Smuzhiyun 		uvc_en_us_strings[UVC_STRING_CONTROL_IDX].s = opts->device_name;
930*4882a593Smuzhiyun #endif
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	uvc_en_us_strings[UVC_STRING_CONTROL_IDX].s = opts->function_name;
933*4882a593Smuzhiyun 	us = usb_gstrings_attach(cdev, uvc_function_strings,
934*4882a593Smuzhiyun 				 ARRAY_SIZE(uvc_en_us_strings));
935*4882a593Smuzhiyun 	if (IS_ERR(us)) {
936*4882a593Smuzhiyun 		ret = PTR_ERR(us);
937*4882a593Smuzhiyun 		goto error;
938*4882a593Smuzhiyun 	}
939*4882a593Smuzhiyun 	uvc_iad.iFunction = us[UVC_STRING_CONTROL_IDX].id;
940*4882a593Smuzhiyun 	uvc_control_intf.iInterface = us[UVC_STRING_CONTROL_IDX].id;
941*4882a593Smuzhiyun 	ret = us[UVC_STRING_STREAMING_IDX].id;
942*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
943*4882a593Smuzhiyun 		uvc_streaming_intf_alt0.iInterface = ret;
944*4882a593Smuzhiyun 		uvc_streaming_intf_alt1.iInterface = ret;
945*4882a593Smuzhiyun 	} else {
946*4882a593Smuzhiyun 		uvc_bulk_streaming_intf_alt0.iInterface = ret;
947*4882a593Smuzhiyun 	}
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 	/* Allocate interface IDs. */
950*4882a593Smuzhiyun 	if ((ret = usb_interface_id(c, f)) < 0)
951*4882a593Smuzhiyun 		goto error;
952*4882a593Smuzhiyun 	uvc_iad.bFirstInterface = ret;
953*4882a593Smuzhiyun 	uvc_control_intf.bInterfaceNumber = ret;
954*4882a593Smuzhiyun 	uvc->control_intf = ret;
955*4882a593Smuzhiyun 	opts->control_interface = ret;
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 	if ((ret = usb_interface_id(c, f)) < 0)
958*4882a593Smuzhiyun 		goto error;
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	if (!opts->streaming_bulk) {
961*4882a593Smuzhiyun 		uvc_streaming_intf_alt0.bInterfaceNumber = ret;
962*4882a593Smuzhiyun 		uvc_streaming_intf_alt1.bInterfaceNumber = ret;
963*4882a593Smuzhiyun 	} else {
964*4882a593Smuzhiyun 		uvc_bulk_streaming_intf_alt0.bInterfaceNumber = ret;
965*4882a593Smuzhiyun 	}
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	uvc->streaming_intf = ret;
968*4882a593Smuzhiyun 	opts->streaming_interface = ret;
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 	/* Copy descriptors */
971*4882a593Smuzhiyun 	f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
972*4882a593Smuzhiyun 	if (IS_ERR(f->fs_descriptors)) {
973*4882a593Smuzhiyun 		ret = PTR_ERR(f->fs_descriptors);
974*4882a593Smuzhiyun 		f->fs_descriptors = NULL;
975*4882a593Smuzhiyun 		goto error;
976*4882a593Smuzhiyun 	}
977*4882a593Smuzhiyun 	if (gadget_is_dualspeed(cdev->gadget)) {
978*4882a593Smuzhiyun 		f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH);
979*4882a593Smuzhiyun 		if (IS_ERR(f->hs_descriptors)) {
980*4882a593Smuzhiyun 			ret = PTR_ERR(f->hs_descriptors);
981*4882a593Smuzhiyun 			f->hs_descriptors = NULL;
982*4882a593Smuzhiyun 			goto error;
983*4882a593Smuzhiyun 		}
984*4882a593Smuzhiyun 	}
985*4882a593Smuzhiyun 	if (gadget_is_superspeed(c->cdev->gadget)) {
986*4882a593Smuzhiyun 		f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER);
987*4882a593Smuzhiyun 		if (IS_ERR(f->ss_descriptors)) {
988*4882a593Smuzhiyun 			ret = PTR_ERR(f->ss_descriptors);
989*4882a593Smuzhiyun 			f->ss_descriptors = NULL;
990*4882a593Smuzhiyun 			goto error;
991*4882a593Smuzhiyun 		}
992*4882a593Smuzhiyun 	}
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	/* Preallocate control endpoint request. */
995*4882a593Smuzhiyun 	uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
996*4882a593Smuzhiyun 	uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL);
997*4882a593Smuzhiyun 	if (uvc->control_req == NULL || uvc->control_buf == NULL) {
998*4882a593Smuzhiyun 		ret = -ENOMEM;
999*4882a593Smuzhiyun 		goto error;
1000*4882a593Smuzhiyun 	}
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	uvc->control_req->buf = uvc->control_buf;
1003*4882a593Smuzhiyun 	uvc->control_req->complete = uvc_function_ep0_complete;
1004*4882a593Smuzhiyun 	uvc->control_req->context = uvc;
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) {
1007*4882a593Smuzhiyun 		uvcg_err(f, "failed to register V4L2 device\n");
1008*4882a593Smuzhiyun 		goto error;
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	/* Initialise video. */
1012*4882a593Smuzhiyun 	ret = uvcg_video_init(&uvc->video, uvc);
1013*4882a593Smuzhiyun 	if (ret < 0)
1014*4882a593Smuzhiyun 		goto v4l2_error;
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 	if (opts->streaming_bulk)
1017*4882a593Smuzhiyun 		uvc->video.max_payload_size = uvc->video.imagesize;
1018*4882a593Smuzhiyun 	/* Register a V4L2 device. */
1019*4882a593Smuzhiyun 	ret = uvc_register_video(uvc);
1020*4882a593Smuzhiyun 	if (ret < 0) {
1021*4882a593Smuzhiyun 		uvcg_err(f, "failed to register video device\n");
1022*4882a593Smuzhiyun 		goto v4l2_error;
1023*4882a593Smuzhiyun 	}
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	return 0;
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun v4l2_error:
1028*4882a593Smuzhiyun 	v4l2_device_unregister(&uvc->v4l2_dev);
1029*4882a593Smuzhiyun error:
1030*4882a593Smuzhiyun 	if (uvc->control_req)
1031*4882a593Smuzhiyun 		usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
1032*4882a593Smuzhiyun 	kfree(uvc->control_buf);
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	usb_free_all_descriptors(f);
1035*4882a593Smuzhiyun 	return ret;
1036*4882a593Smuzhiyun }
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun /* --------------------------------------------------------------------------
1039*4882a593Smuzhiyun  * USB gadget function
1040*4882a593Smuzhiyun  */
1041*4882a593Smuzhiyun 
uvc_free_inst(struct usb_function_instance * f)1042*4882a593Smuzhiyun static void uvc_free_inst(struct usb_function_instance *f)
1043*4882a593Smuzhiyun {
1044*4882a593Smuzhiyun 	struct f_uvc_opts *opts = fi_to_f_uvc_opts(f);
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	mutex_destroy(&opts->lock);
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
1049*4882a593Smuzhiyun 	if (opts->device_name_allocated) {
1050*4882a593Smuzhiyun 		opts->device_name_allocated = false;
1051*4882a593Smuzhiyun 		kfree(opts->device_name);
1052*4882a593Smuzhiyun 		opts->device_name = NULL;
1053*4882a593Smuzhiyun 	}
1054*4882a593Smuzhiyun #endif
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	kfree(opts);
1057*4882a593Smuzhiyun }
1058*4882a593Smuzhiyun 
uvc_alloc_inst(void)1059*4882a593Smuzhiyun static struct usb_function_instance *uvc_alloc_inst(void)
1060*4882a593Smuzhiyun {
1061*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
1062*4882a593Smuzhiyun 	struct uvc_camera_terminal_descriptor *cd;
1063*4882a593Smuzhiyun 	struct uvc_processing_unit_descriptor *pd;
1064*4882a593Smuzhiyun 	struct uvc_output_terminal_descriptor *od;
1065*4882a593Smuzhiyun 	struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 1) *ed;
1066*4882a593Smuzhiyun 	struct uvc_color_matching_descriptor *md;
1067*4882a593Smuzhiyun 	struct uvc_descriptor_header **ctl_cls;
1068*4882a593Smuzhiyun 	int ret;
1069*4882a593Smuzhiyun 
1070*4882a593Smuzhiyun 	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
1071*4882a593Smuzhiyun 	if (!opts)
1072*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1073*4882a593Smuzhiyun 	opts->func_inst.free_func_inst = uvc_free_inst;
1074*4882a593Smuzhiyun 	mutex_init(&opts->lock);
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 	cd = &opts->uvc_camera_terminal;
1077*4882a593Smuzhiyun 	cd->bLength			= UVC_DT_CAMERA_TERMINAL_SIZE(3);
1078*4882a593Smuzhiyun 	cd->bDescriptorType		= USB_DT_CS_INTERFACE;
1079*4882a593Smuzhiyun 	cd->bDescriptorSubType		= UVC_VC_INPUT_TERMINAL;
1080*4882a593Smuzhiyun 	cd->bTerminalID			= 1;
1081*4882a593Smuzhiyun 	cd->wTerminalType		= cpu_to_le16(0x0201);
1082*4882a593Smuzhiyun 	cd->bAssocTerminal		= 0;
1083*4882a593Smuzhiyun 	cd->iTerminal			= 0;
1084*4882a593Smuzhiyun 	cd->wObjectiveFocalLengthMin	= cpu_to_le16(0);
1085*4882a593Smuzhiyun 	cd->wObjectiveFocalLengthMax	= cpu_to_le16(0);
1086*4882a593Smuzhiyun 	cd->wOcularFocalLength		= cpu_to_le16(0);
1087*4882a593Smuzhiyun 	cd->bControlSize		= 3;
1088*4882a593Smuzhiyun 	cd->bmControls[0]		= 2;
1089*4882a593Smuzhiyun 	cd->bmControls[1]		= 0;
1090*4882a593Smuzhiyun 	cd->bmControls[2]		= 0;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	pd = &opts->uvc_processing;
1093*4882a593Smuzhiyun 	pd->bLength			= UVC_DT_PROCESSING_UNIT_SIZE(2);
1094*4882a593Smuzhiyun 	pd->bDescriptorType		= USB_DT_CS_INTERFACE;
1095*4882a593Smuzhiyun 	pd->bDescriptorSubType		= UVC_VC_PROCESSING_UNIT;
1096*4882a593Smuzhiyun 	pd->bUnitID			= 2;
1097*4882a593Smuzhiyun 	pd->bSourceID			= 1;
1098*4882a593Smuzhiyun 	pd->wMaxMultiplier		= cpu_to_le16(16*1024);
1099*4882a593Smuzhiyun 	pd->bControlSize		= 2;
1100*4882a593Smuzhiyun 	pd->bmControls[0]		= 1;
1101*4882a593Smuzhiyun 	pd->bmControls[1]		= 0;
1102*4882a593Smuzhiyun 	pd->iProcessing			= 0;
1103*4882a593Smuzhiyun 	pd->bmVideoStandards		= 0;
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	od = &opts->uvc_output_terminal;
1106*4882a593Smuzhiyun 	od->bLength			= UVC_DT_OUTPUT_TERMINAL_SIZE;
1107*4882a593Smuzhiyun 	od->bDescriptorType		= USB_DT_CS_INTERFACE;
1108*4882a593Smuzhiyun 	od->bDescriptorSubType		= UVC_VC_OUTPUT_TERMINAL;
1109*4882a593Smuzhiyun 	od->bTerminalID			= 3;
1110*4882a593Smuzhiyun 	od->wTerminalType		= cpu_to_le16(0x0101);
1111*4882a593Smuzhiyun 	od->bAssocTerminal		= 0;
1112*4882a593Smuzhiyun 	od->bSourceID			= 2;
1113*4882a593Smuzhiyun 	od->iTerminal			= 0;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	ed = &opts->uvc_extension;
1116*4882a593Smuzhiyun 	ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 1);
1117*4882a593Smuzhiyun 	ed->bDescriptorType = USB_DT_CS_INTERFACE;
1118*4882a593Smuzhiyun 	ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT;
1119*4882a593Smuzhiyun 	ed->bUnitID = 6;
1120*4882a593Smuzhiyun 	ed->guidExtensionCode[0] = 0xa2;
1121*4882a593Smuzhiyun 	ed->guidExtensionCode[1] = 0x9e;
1122*4882a593Smuzhiyun 	ed->guidExtensionCode[2] = 0x76;
1123*4882a593Smuzhiyun 	ed->guidExtensionCode[3] = 0x41;
1124*4882a593Smuzhiyun 	ed->guidExtensionCode[4] = 0xde;
1125*4882a593Smuzhiyun 	ed->guidExtensionCode[5] = 0x04;
1126*4882a593Smuzhiyun 	ed->guidExtensionCode[6] = 0x47;
1127*4882a593Smuzhiyun 	ed->guidExtensionCode[7] = 0xe3;
1128*4882a593Smuzhiyun 	ed->guidExtensionCode[8] = 0x8b;
1129*4882a593Smuzhiyun 	ed->guidExtensionCode[9] = 0x2b;
1130*4882a593Smuzhiyun 	ed->guidExtensionCode[10] = 0xf4;
1131*4882a593Smuzhiyun 	ed->guidExtensionCode[11] = 0x34;
1132*4882a593Smuzhiyun 	ed->guidExtensionCode[12] = 0x1a;
1133*4882a593Smuzhiyun 	ed->guidExtensionCode[13] = 0xff;
1134*4882a593Smuzhiyun 	ed->guidExtensionCode[14] = 0x00;
1135*4882a593Smuzhiyun 	ed->guidExtensionCode[15] = 0x3b;
1136*4882a593Smuzhiyun 	ed->bNumControls = 3;
1137*4882a593Smuzhiyun 	ed->bNrInPins = 1;
1138*4882a593Smuzhiyun 	ed->baSourceID[0] = 2;
1139*4882a593Smuzhiyun 	ed->bControlSize = 1;
1140*4882a593Smuzhiyun 	ed->bmControls[0] = 7;
1141*4882a593Smuzhiyun 	ed->iExtension = 0;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	md = &opts->uvc_color_matching;
1144*4882a593Smuzhiyun 	md->bLength			= UVC_DT_COLOR_MATCHING_SIZE;
1145*4882a593Smuzhiyun 	md->bDescriptorType		= USB_DT_CS_INTERFACE;
1146*4882a593Smuzhiyun 	md->bDescriptorSubType		= UVC_VS_COLORFORMAT;
1147*4882a593Smuzhiyun 	md->bColorPrimaries		= 1;
1148*4882a593Smuzhiyun 	md->bTransferCharacteristics	= 1;
1149*4882a593Smuzhiyun 	md->bMatrixCoefficients		= 4;
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 	/* Prepare fs control class descriptors for configfs-based gadgets */
1152*4882a593Smuzhiyun 	ctl_cls = opts->uvc_fs_control_cls;
1153*4882a593Smuzhiyun 	ctl_cls[0] = NULL;	/* assigned elsewhere by configfs */
1154*4882a593Smuzhiyun 	ctl_cls[1] = (struct uvc_descriptor_header *)cd;
1155*4882a593Smuzhiyun 	ctl_cls[2] = (struct uvc_descriptor_header *)pd;
1156*4882a593Smuzhiyun 	ctl_cls[3] = (struct uvc_descriptor_header *)od;
1157*4882a593Smuzhiyun 	ctl_cls[4] = (struct uvc_descriptor_header *)ed;
1158*4882a593Smuzhiyun 	ctl_cls[5] = NULL;	/* NULL-terminate */
1159*4882a593Smuzhiyun 	opts->fs_control =
1160*4882a593Smuzhiyun 		(const struct uvc_descriptor_header * const *)ctl_cls;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 	/* Prepare hs control class descriptors for configfs-based gadgets */
1163*4882a593Smuzhiyun 	ctl_cls = opts->uvc_ss_control_cls;
1164*4882a593Smuzhiyun 	ctl_cls[0] = NULL;	/* assigned elsewhere by configfs */
1165*4882a593Smuzhiyun 	ctl_cls[1] = (struct uvc_descriptor_header *)cd;
1166*4882a593Smuzhiyun 	ctl_cls[2] = (struct uvc_descriptor_header *)pd;
1167*4882a593Smuzhiyun 	ctl_cls[3] = (struct uvc_descriptor_header *)od;
1168*4882a593Smuzhiyun 	ctl_cls[4] = (struct uvc_descriptor_header *)ed;
1169*4882a593Smuzhiyun 	ctl_cls[5] = NULL;	/* NULL-terminate */
1170*4882a593Smuzhiyun 	opts->ss_control =
1171*4882a593Smuzhiyun 		(const struct uvc_descriptor_header * const *)ctl_cls;
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 	opts->streaming_interval = 1;
1174*4882a593Smuzhiyun 	opts->streaming_maxpacket = 1024;
1175*4882a593Smuzhiyun 	opts->pm_qos_latency = 0;
1176*4882a593Smuzhiyun 	snprintf(opts->function_name, sizeof(opts->function_name), "UVC Camera");
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun 	ret = uvcg_attach_configfs(opts);
1179*4882a593Smuzhiyun 	if (ret < 0) {
1180*4882a593Smuzhiyun 		kfree(opts);
1181*4882a593Smuzhiyun 		return ERR_PTR(ret);
1182*4882a593Smuzhiyun 	}
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun 	return &opts->func_inst;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun 
uvc_free(struct usb_function * f)1187*4882a593Smuzhiyun static void uvc_free(struct usb_function *f)
1188*4882a593Smuzhiyun {
1189*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
1190*4882a593Smuzhiyun 	struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts,
1191*4882a593Smuzhiyun 					       func_inst);
1192*4882a593Smuzhiyun 	--opts->refcnt;
1193*4882a593Smuzhiyun 	kfree(uvc);
1194*4882a593Smuzhiyun }
1195*4882a593Smuzhiyun 
uvc_function_unbind(struct usb_configuration * c,struct usb_function * f)1196*4882a593Smuzhiyun static void uvc_function_unbind(struct usb_configuration *c,
1197*4882a593Smuzhiyun 				struct usb_function *f)
1198*4882a593Smuzhiyun {
1199*4882a593Smuzhiyun 	struct usb_composite_dev *cdev = c->cdev;
1200*4882a593Smuzhiyun 	struct uvc_device *uvc = to_uvc(f);
1201*4882a593Smuzhiyun 	long wait_ret = 1;
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun 	uvcg_info(f, "%s()\n", __func__);
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun 	/* If we know we're connected via v4l2, then there should be a cleanup
1206*4882a593Smuzhiyun 	 * of the device from userspace either via UVC_EVENT_DISCONNECT or
1207*4882a593Smuzhiyun 	 * though the video device removal uevent. Allow some time for the
1208*4882a593Smuzhiyun 	 * application to close out before things get deleted.
1209*4882a593Smuzhiyun 	 */
1210*4882a593Smuzhiyun 	if (uvc->func_connected) {
1211*4882a593Smuzhiyun 		uvcg_dbg(f, "waiting for clean disconnect\n");
1212*4882a593Smuzhiyun 		wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
1213*4882a593Smuzhiyun 				uvc->func_connected == false, msecs_to_jiffies(500));
1214*4882a593Smuzhiyun 		uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret);
1215*4882a593Smuzhiyun 	}
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun 	device_remove_file(&uvc->vdev.dev, &dev_attr_function_name);
1218*4882a593Smuzhiyun 	video_unregister_device(&uvc->vdev);
1219*4882a593Smuzhiyun 	v4l2_device_unregister(&uvc->v4l2_dev);
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	if (uvc->func_connected) {
1222*4882a593Smuzhiyun 		/* Wait for the release to occur to ensure there are no longer any
1223*4882a593Smuzhiyun 		 * pending operations that may cause panics when resources are cleaned
1224*4882a593Smuzhiyun 		 * up.
1225*4882a593Smuzhiyun 		 */
1226*4882a593Smuzhiyun 		uvcg_warn(f, "%s no clean disconnect, wait for release\n", __func__);
1227*4882a593Smuzhiyun 		wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
1228*4882a593Smuzhiyun 				uvc->func_connected == false, msecs_to_jiffies(1000));
1229*4882a593Smuzhiyun 		uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret);
1230*4882a593Smuzhiyun 	}
1231*4882a593Smuzhiyun 
1232*4882a593Smuzhiyun 	usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
1233*4882a593Smuzhiyun 	kfree(uvc->control_buf);
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun 	usb_free_all_descriptors(f);
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun 
uvc_alloc(struct usb_function_instance * fi)1238*4882a593Smuzhiyun static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
1239*4882a593Smuzhiyun {
1240*4882a593Smuzhiyun 	struct uvc_device *uvc;
1241*4882a593Smuzhiyun 	struct f_uvc_opts *opts;
1242*4882a593Smuzhiyun 	struct uvc_descriptor_header **strm_cls;
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun 	uvc = kzalloc(sizeof(*uvc), GFP_KERNEL);
1245*4882a593Smuzhiyun 	if (uvc == NULL)
1246*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun 	mutex_init(&uvc->video.mutex);
1249*4882a593Smuzhiyun 	uvc->state = UVC_STATE_DISCONNECTED;
1250*4882a593Smuzhiyun 	init_waitqueue_head(&uvc->func_connected_queue);
1251*4882a593Smuzhiyun 	opts = fi_to_f_uvc_opts(fi);
1252*4882a593Smuzhiyun 
1253*4882a593Smuzhiyun 	mutex_lock(&opts->lock);
1254*4882a593Smuzhiyun 	if (opts->uvc_fs_streaming_cls) {
1255*4882a593Smuzhiyun 		strm_cls = opts->uvc_fs_streaming_cls;
1256*4882a593Smuzhiyun 		opts->fs_streaming =
1257*4882a593Smuzhiyun 			(const struct uvc_descriptor_header * const *)strm_cls;
1258*4882a593Smuzhiyun 	}
1259*4882a593Smuzhiyun 	if (opts->uvc_hs_streaming_cls) {
1260*4882a593Smuzhiyun 		strm_cls = opts->uvc_hs_streaming_cls;
1261*4882a593Smuzhiyun 		opts->hs_streaming =
1262*4882a593Smuzhiyun 			(const struct uvc_descriptor_header * const *)strm_cls;
1263*4882a593Smuzhiyun 	}
1264*4882a593Smuzhiyun 	if (opts->uvc_ss_streaming_cls) {
1265*4882a593Smuzhiyun 		strm_cls = opts->uvc_ss_streaming_cls;
1266*4882a593Smuzhiyun 		opts->ss_streaming =
1267*4882a593Smuzhiyun 			(const struct uvc_descriptor_header * const *)strm_cls;
1268*4882a593Smuzhiyun 	}
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun 	uvc->desc.fs_control = opts->fs_control;
1271*4882a593Smuzhiyun 	uvc->desc.ss_control = opts->ss_control;
1272*4882a593Smuzhiyun 	uvc->desc.fs_streaming = opts->fs_streaming;
1273*4882a593Smuzhiyun 	uvc->desc.hs_streaming = opts->hs_streaming;
1274*4882a593Smuzhiyun 	uvc->desc.ss_streaming = opts->ss_streaming;
1275*4882a593Smuzhiyun 	++opts->refcnt;
1276*4882a593Smuzhiyun 	mutex_unlock(&opts->lock);
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	/* Register the function. */
1279*4882a593Smuzhiyun 	uvc->func.name = "uvc";
1280*4882a593Smuzhiyun 	uvc->func.bind = uvc_function_bind;
1281*4882a593Smuzhiyun 	uvc->func.unbind = uvc_function_unbind;
1282*4882a593Smuzhiyun 	uvc->func.get_alt = uvc_function_get_alt;
1283*4882a593Smuzhiyun 	uvc->func.set_alt = uvc_function_set_alt;
1284*4882a593Smuzhiyun 	uvc->func.disable = uvc_function_disable;
1285*4882a593Smuzhiyun 	uvc->func.setup = uvc_function_setup;
1286*4882a593Smuzhiyun 	uvc->func.free_func = uvc_free;
1287*4882a593Smuzhiyun 	uvc->func.suspend = uvc_function_suspend;
1288*4882a593Smuzhiyun 	uvc->func.resume = uvc_function_resume;
1289*4882a593Smuzhiyun 	uvc->func.bind_deactivated = true;
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun 	return &uvc->func;
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun DECLARE_USB_FUNCTION_INIT(uvc, uvc_alloc_inst, uvc_alloc);
1295*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1296*4882a593Smuzhiyun MODULE_AUTHOR("Laurent Pinchart");
1297