xref: /openbmc/linux/drivers/usb/gadget/legacy/webcam.c (revision 236a9bf2)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *	webcam.c -- USB webcam gadget driver
4  *
5  *	Copyright (C) 2009-2010
6  *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/device.h>
11 #include <linux/module.h>
12 #include <linux/usb/video.h>
13 
14 #include "u_uvc.h"
15 #include "uvc_configfs.h"
16 
17 USB_GADGET_COMPOSITE_OPTIONS();
18 
19 /*-------------------------------------------------------------------------*/
20 
21 /* module parameters specific to the Video streaming endpoint */
22 static unsigned int streaming_interval = 1;
23 module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
24 MODULE_PARM_DESC(streaming_interval, "1 - 16");
25 
26 static unsigned int streaming_maxpacket = 1024;
27 module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
28 MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)");
29 
30 static unsigned int streaming_maxburst;
31 module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
32 MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
33 
34 /* --------------------------------------------------------------------------
35  * Device descriptor
36  */
37 
38 #define WEBCAM_VENDOR_ID		0x1d6b	/* Linux Foundation */
39 #define WEBCAM_PRODUCT_ID		0x0102	/* Webcam A/V gadget */
40 #define WEBCAM_DEVICE_BCD		0x0010	/* 0.10 */
41 
42 static char webcam_vendor_label[] = "Linux Foundation";
43 static char webcam_product_label[] = "Webcam gadget";
44 static char webcam_config_label[] = "Video";
45 
46 /* string IDs are assigned dynamically */
47 
48 #define STRING_DESCRIPTION_IDX		USB_GADGET_FIRST_AVAIL_IDX
49 
50 static struct usb_string webcam_strings[] = {
51 	[USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label,
52 	[USB_GADGET_PRODUCT_IDX].s = webcam_product_label,
53 	[USB_GADGET_SERIAL_IDX].s = "",
54 	[STRING_DESCRIPTION_IDX].s = webcam_config_label,
55 	{  }
56 };
57 
58 static struct usb_gadget_strings webcam_stringtab = {
59 	.language = 0x0409,	/* en-us */
60 	.strings = webcam_strings,
61 };
62 
63 static struct usb_gadget_strings *webcam_device_strings[] = {
64 	&webcam_stringtab,
65 	NULL,
66 };
67 
68 static struct usb_function_instance *fi_uvc;
69 static struct usb_function *f_uvc;
70 
71 static struct usb_device_descriptor webcam_device_descriptor = {
72 	.bLength		= USB_DT_DEVICE_SIZE,
73 	.bDescriptorType	= USB_DT_DEVICE,
74 	/* .bcdUSB = DYNAMIC */
75 	.bDeviceClass		= USB_CLASS_MISC,
76 	.bDeviceSubClass	= 0x02,
77 	.bDeviceProtocol	= 0x01,
78 	.bMaxPacketSize0	= 0, /* dynamic */
79 	.idVendor		= cpu_to_le16(WEBCAM_VENDOR_ID),
80 	.idProduct		= cpu_to_le16(WEBCAM_PRODUCT_ID),
81 	.bcdDevice		= cpu_to_le16(WEBCAM_DEVICE_BCD),
82 	.iManufacturer		= 0, /* dynamic */
83 	.iProduct		= 0, /* dynamic */
84 	.iSerialNumber		= 0, /* dynamic */
85 	.bNumConfigurations	= 0, /* dynamic */
86 };
87 
88 static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
89 	.bLength		= UVC_DT_HEADER_SIZE(1),
90 	.bDescriptorType	= USB_DT_CS_INTERFACE,
91 	.bDescriptorSubType	= UVC_VC_HEADER,
92 	.bcdUVC			= cpu_to_le16(0x0110),
93 	.wTotalLength		= 0, /* dynamic */
94 	.dwClockFrequency	= cpu_to_le32(48000000),
95 	.bInCollection		= 0, /* dynamic */
96 	.baInterfaceNr[0]	= 0, /* dynamic */
97 };
98 
99 static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
100 	.bLength		= UVC_DT_CAMERA_TERMINAL_SIZE(3),
101 	.bDescriptorType	= USB_DT_CS_INTERFACE,
102 	.bDescriptorSubType	= UVC_VC_INPUT_TERMINAL,
103 	.bTerminalID		= 1,
104 	.wTerminalType		= cpu_to_le16(0x0201),
105 	.bAssocTerminal		= 0,
106 	.iTerminal		= 0,
107 	.wObjectiveFocalLengthMin	= cpu_to_le16(0),
108 	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
109 	.wOcularFocalLength		= cpu_to_le16(0),
110 	.bControlSize		= 3,
111 	.bmControls[0]		= 2,
112 	.bmControls[1]		= 0,
113 	.bmControls[2]		= 0,
114 };
115 
116 static const struct uvc_processing_unit_descriptor uvc_processing = {
117 	.bLength		= UVC_DT_PROCESSING_UNIT_SIZE(2),
118 	.bDescriptorType	= USB_DT_CS_INTERFACE,
119 	.bDescriptorSubType	= UVC_VC_PROCESSING_UNIT,
120 	.bUnitID		= 2,
121 	.bSourceID		= 1,
122 	.wMaxMultiplier		= cpu_to_le16(16*1024),
123 	.bControlSize		= 2,
124 	.bmControls[0]		= 1,
125 	.bmControls[1]		= 0,
126 	.iProcessing		= 0,
127 	.bmVideoStandards	= 0,
128 };
129 
130 static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
131 	.bLength		= UVC_DT_OUTPUT_TERMINAL_SIZE,
132 	.bDescriptorType	= USB_DT_CS_INTERFACE,
133 	.bDescriptorSubType	= UVC_VC_OUTPUT_TERMINAL,
134 	.bTerminalID		= 3,
135 	.wTerminalType		= cpu_to_le16(0x0101),
136 	.bAssocTerminal		= 0,
137 	.bSourceID		= 2,
138 	.iTerminal		= 0,
139 };
140 
141 DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
142 
143 static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
144 	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 2),
145 	.bDescriptorType	= USB_DT_CS_INTERFACE,
146 	.bDescriptorSubType	= UVC_VS_INPUT_HEADER,
147 	.bNumFormats		= 2,
148 	.wTotalLength		= 0, /* dynamic */
149 	.bEndpointAddress	= 0, /* dynamic */
150 	.bmInfo			= 0,
151 	.bTerminalLink		= 3,
152 	.bStillCaptureMethod	= 0,
153 	.bTriggerSupport	= 0,
154 	.bTriggerUsage		= 0,
155 	.bControlSize		= 1,
156 	.bmaControls[0][0]	= 0,
157 	.bmaControls[1][0]	= 4,
158 };
159 
160 static const struct uvcg_color_matching uvcg_color_matching = {
161 	.desc = {
162 		.bLength		= UVC_DT_COLOR_MATCHING_SIZE,
163 		.bDescriptorType	= USB_DT_CS_INTERFACE,
164 		.bDescriptorSubType	= UVC_VS_COLORFORMAT,
165 		.bColorPrimaries	= 1,
166 		.bTransferCharacteristics	= 1,
167 		.bMatrixCoefficients	= 4,
168 	},
169 };
170 
171 static struct uvcg_uncompressed uvcg_format_yuv = {
172 	.fmt = {
173 		.type			= UVCG_UNCOMPRESSED,
174 		/* add to .frames and fill .num_frames at runtime */
175 		.color_matching		= (struct uvcg_color_matching *)&uvcg_color_matching,
176 	},
177 	.desc = {
178 		.bLength		= UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
179 		.bDescriptorType	= USB_DT_CS_INTERFACE,
180 		.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED,
181 		.bFormatIndex		= 1,
182 		.bNumFrameDescriptors	= 2,
183 		.guidFormat		= {
184 			'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
185 			 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
186 		},
187 		.bBitsPerPixel		= 16,
188 		.bDefaultFrameIndex	= 1,
189 		.bAspectRatioX		= 0,
190 		.bAspectRatioY		= 0,
191 		.bmInterlaceFlags	= 0,
192 		.bCopyProtect		= 0,
193 	},
194 };
195 
196 static struct uvcg_format_ptr uvcg_format_ptr_yuv = {
197 	.fmt = &uvcg_format_yuv.fmt,
198 };
199 
200 DECLARE_UVC_FRAME_UNCOMPRESSED(1);
201 DECLARE_UVC_FRAME_UNCOMPRESSED(3);
202 
203 #define UVCG_WIDTH_360P			640
204 #define UVCG_HEIGHT_360P		360
205 #define UVCG_MIN_BITRATE_360P		18432000
206 #define UVCG_MAX_BITRATE_360P		55296000
207 #define UVCG_MAX_VIDEO_FB_SZ_360P	460800
208 #define UVCG_FRM_INTERV_0_360P		666666
209 #define UVCG_FRM_INTERV_1_360P		1000000
210 #define UVCG_FRM_INTERV_2_360P		5000000
211 #define UVCG_DEFAULT_FRM_INTERV_360P	UVCG_FRM_INTERV_0_360P
212 
213 static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
214 	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
215 	.bDescriptorType	= USB_DT_CS_INTERFACE,
216 	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
217 	.bFrameIndex		= 1,
218 	.bmCapabilities		= 0,
219 	.wWidth			= cpu_to_le16(UVCG_WIDTH_360P),
220 	.wHeight		= cpu_to_le16(UVCG_HEIGHT_360P),
221 	.dwMinBitRate		= cpu_to_le32(UVCG_MIN_BITRATE_360P),
222 	.dwMaxBitRate		= cpu_to_le32(UVCG_MAX_BITRATE_360P),
223 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P),
224 	.dwDefaultFrameInterval	= cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P),
225 	.bFrameIntervalType	= 3,
226 	.dwFrameInterval[0]	= cpu_to_le32(UVCG_FRM_INTERV_0_360P),
227 	.dwFrameInterval[1]	= cpu_to_le32(UVCG_FRM_INTERV_1_360P),
228 	.dwFrameInterval[2]	= cpu_to_le32(UVCG_FRM_INTERV_2_360P),
229 };
230 
231 static u32 uvcg_frame_yuv_360p_dw_frame_interval[] = {
232 	[0] = UVCG_FRM_INTERV_0_360P,
233 	[1] = UVCG_FRM_INTERV_1_360P,
234 	[2] = UVCG_FRM_INTERV_2_360P,
235 };
236 
237 static const struct uvcg_frame uvcg_frame_yuv_360p = {
238 	.fmt_type		= UVCG_UNCOMPRESSED,
239 	.frame = {
240 		.b_length			= UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
241 		.b_descriptor_type		= USB_DT_CS_INTERFACE,
242 		.b_descriptor_subtype		= UVC_VS_FRAME_UNCOMPRESSED,
243 		.b_frame_index			= 1,
244 		.bm_capabilities		= 0,
245 		.w_width			= UVCG_WIDTH_360P,
246 		.w_height			= UVCG_HEIGHT_360P,
247 		.dw_min_bit_rate		= UVCG_MIN_BITRATE_360P,
248 		.dw_max_bit_rate		= UVCG_MAX_BITRATE_360P,
249 		.dw_max_video_frame_buffer_size	= UVCG_MAX_VIDEO_FB_SZ_360P,
250 		.dw_default_frame_interval	= UVCG_DEFAULT_FRM_INTERV_360P,
251 		.b_frame_interval_type		= 3,
252 	},
253 	.dw_frame_interval	= uvcg_frame_yuv_360p_dw_frame_interval,
254 };
255 
256 static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_360p = {
257 	.frm = (struct uvcg_frame *)&uvcg_frame_yuv_360p,
258 };
259 #define UVCG_WIDTH_720P			1280
260 #define UVCG_HEIGHT_720P		720
261 #define UVCG_MIN_BITRATE_720P		29491200
262 #define UVCG_MAX_BITRATE_720P		29491200
263 #define UVCG_MAX_VIDEO_FB_SZ_720P	1843200
264 #define UVCG_FRM_INTERV_0_720P		5000000
265 #define UVCG_DEFAULT_FRM_INTERV_720P	UVCG_FRM_INTERV_0_720P
266 
267 static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
268 	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
269 	.bDescriptorType	= USB_DT_CS_INTERFACE,
270 	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
271 	.bFrameIndex		= 2,
272 	.bmCapabilities		= 0,
273 	.wWidth			= cpu_to_le16(UVCG_WIDTH_720P),
274 	.wHeight		= cpu_to_le16(UVCG_HEIGHT_720P),
275 	.dwMinBitRate		= cpu_to_le32(UVCG_MIN_BITRATE_720P),
276 	.dwMaxBitRate		= cpu_to_le32(UVCG_MAX_BITRATE_720P),
277 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P),
278 	.dwDefaultFrameInterval	= cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P),
279 	.bFrameIntervalType	= 1,
280 	.dwFrameInterval[0]	= cpu_to_le32(UVCG_FRM_INTERV_0_720P),
281 };
282 
283 static u32 uvcg_frame_yuv_720p_dw_frame_interval[] = {
284 	[0] = UVCG_FRM_INTERV_0_720P,
285 };
286 
287 static const struct uvcg_frame uvcg_frame_yuv_720p = {
288 	.fmt_type		= UVCG_UNCOMPRESSED,
289 	.frame = {
290 		.b_length			= UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
291 		.b_descriptor_type		= USB_DT_CS_INTERFACE,
292 		.b_descriptor_subtype		= UVC_VS_FRAME_UNCOMPRESSED,
293 		.b_frame_index			= 2,
294 		.bm_capabilities		= 0,
295 		.w_width			= UVCG_WIDTH_720P,
296 		.w_height			= UVCG_HEIGHT_720P,
297 		.dw_min_bit_rate		= UVCG_MIN_BITRATE_720P,
298 		.dw_max_bit_rate		= UVCG_MAX_BITRATE_720P,
299 		.dw_max_video_frame_buffer_size	= UVCG_MAX_VIDEO_FB_SZ_720P,
300 		.dw_default_frame_interval	= UVCG_DEFAULT_FRM_INTERV_720P,
301 		.b_frame_interval_type		= 1,
302 	},
303 	.dw_frame_interval	= uvcg_frame_yuv_720p_dw_frame_interval,
304 };
305 
306 static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_720p = {
307 	.frm = (struct uvcg_frame *)&uvcg_frame_yuv_720p,
308 };
309 
310 static struct uvcg_mjpeg uvcg_format_mjpeg = {
311 	.fmt = {
312 		.type			= UVCG_MJPEG,
313 		/* add to .frames and fill .num_frames at runtime */
314 		.color_matching		= (struct uvcg_color_matching *)&uvcg_color_matching,
315 	},
316 	.desc = {
317 		.bLength		= UVC_DT_FORMAT_MJPEG_SIZE,
318 		.bDescriptorType	= USB_DT_CS_INTERFACE,
319 		.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG,
320 		.bFormatIndex		= 2,
321 		.bNumFrameDescriptors	= 2,
322 		.bmFlags		= 0,
323 		.bDefaultFrameIndex	= 1,
324 		.bAspectRatioX		= 0,
325 		.bAspectRatioY		= 0,
326 		.bmInterlaceFlags	= 0,
327 		.bCopyProtect		= 0,
328 	},
329 };
330 
331 static struct uvcg_format_ptr uvcg_format_ptr_mjpeg = {
332 	.fmt = &uvcg_format_mjpeg.fmt,
333 };
334 
335 DECLARE_UVC_FRAME_MJPEG(1);
336 DECLARE_UVC_FRAME_MJPEG(3);
337 
338 static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
339 	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(3),
340 	.bDescriptorType	= USB_DT_CS_INTERFACE,
341 	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
342 	.bFrameIndex		= 1,
343 	.bmCapabilities		= 0,
344 	.wWidth			= cpu_to_le16(UVCG_WIDTH_360P),
345 	.wHeight		= cpu_to_le16(UVCG_HEIGHT_360P),
346 	.dwMinBitRate		= cpu_to_le32(UVCG_MIN_BITRATE_360P),
347 	.dwMaxBitRate		= cpu_to_le32(UVCG_MAX_BITRATE_360P),
348 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P),
349 	.dwDefaultFrameInterval	= cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P),
350 	.bFrameIntervalType	= 3,
351 	.dwFrameInterval[0]	= cpu_to_le32(UVCG_FRM_INTERV_0_360P),
352 	.dwFrameInterval[1]	= cpu_to_le32(UVCG_FRM_INTERV_1_360P),
353 	.dwFrameInterval[2]	= cpu_to_le32(UVCG_FRM_INTERV_2_360P),
354 };
355 
356 static u32 uvcg_frame_mjpeg_360p_dw_frame_interval[] = {
357 	[0] = UVCG_FRM_INTERV_0_360P,
358 	[1] = UVCG_FRM_INTERV_1_360P,
359 	[2] = UVCG_FRM_INTERV_2_360P,
360 };
361 
362 static const struct uvcg_frame uvcg_frame_mjpeg_360p = {
363 	.fmt_type		= UVCG_MJPEG,
364 	.frame = {
365 		.b_length			= UVC_DT_FRAME_MJPEG_SIZE(3),
366 		.b_descriptor_type		= USB_DT_CS_INTERFACE,
367 		.b_descriptor_subtype		= UVC_VS_FRAME_MJPEG,
368 		.b_frame_index			= 1,
369 		.bm_capabilities		= 0,
370 		.w_width			= UVCG_WIDTH_360P,
371 		.w_height			= UVCG_HEIGHT_360P,
372 		.dw_min_bit_rate		= UVCG_MIN_BITRATE_360P,
373 		.dw_max_bit_rate		= UVCG_MAX_BITRATE_360P,
374 		.dw_max_video_frame_buffer_size	= UVCG_MAX_VIDEO_FB_SZ_360P,
375 		.dw_default_frame_interval	= UVCG_DEFAULT_FRM_INTERV_360P,
376 		.b_frame_interval_type		= 3,
377 	},
378 	.dw_frame_interval	= uvcg_frame_mjpeg_360p_dw_frame_interval,
379 };
380 
381 static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_360p = {
382 	.frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_360p,
383 };
384 
385 static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
386 	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(1),
387 	.bDescriptorType	= USB_DT_CS_INTERFACE,
388 	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
389 	.bFrameIndex		= 2,
390 	.bmCapabilities		= 0,
391 	.wWidth			= cpu_to_le16(UVCG_WIDTH_720P),
392 	.wHeight		= cpu_to_le16(UVCG_HEIGHT_720P),
393 	.dwMinBitRate		= cpu_to_le32(UVCG_MIN_BITRATE_720P),
394 	.dwMaxBitRate		= cpu_to_le32(UVCG_MAX_BITRATE_720P),
395 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P),
396 	.dwDefaultFrameInterval	= cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P),
397 	.bFrameIntervalType	= 1,
398 	.dwFrameInterval[0]	= cpu_to_le32(UVCG_FRM_INTERV_0_720P),
399 };
400 
401 static u32 uvcg_frame_mjpeg_720p_dw_frame_interval[] = {
402 	[0] = UVCG_FRM_INTERV_0_720P,
403 };
404 
405 static const struct uvcg_frame uvcg_frame_mjpeg_720p = {
406 	.fmt_type		= UVCG_MJPEG,
407 	.frame = {
408 		.b_length			= UVC_DT_FRAME_MJPEG_SIZE(1),
409 		.b_descriptor_type		= USB_DT_CS_INTERFACE,
410 		.b_descriptor_subtype		= UVC_VS_FRAME_MJPEG,
411 		.b_frame_index			= 2,
412 		.bm_capabilities		= 0,
413 		.w_width			= UVCG_WIDTH_720P,
414 		.w_height			= UVCG_HEIGHT_720P,
415 		.dw_min_bit_rate		= UVCG_MIN_BITRATE_720P,
416 		.dw_max_bit_rate		= UVCG_MAX_BITRATE_720P,
417 		.dw_max_video_frame_buffer_size	= UVCG_MAX_VIDEO_FB_SZ_720P,
418 		.dw_default_frame_interval	= UVCG_DEFAULT_FRM_INTERV_720P,
419 		.b_frame_interval_type		= 1,
420 	},
421 	.dw_frame_interval	= uvcg_frame_mjpeg_720p_dw_frame_interval,
422 };
423 
424 static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_720p = {
425 	.frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_720p,
426 };
427 
428 static struct uvcg_streaming_header uvcg_streaming_header = {
429 };
430 
431 static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
432 	(const struct uvc_descriptor_header *) &uvc_control_header,
433 	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
434 	(const struct uvc_descriptor_header *) &uvc_processing,
435 	(const struct uvc_descriptor_header *) &uvc_output_terminal,
436 	NULL,
437 };
438 
439 static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
440 	(const struct uvc_descriptor_header *) &uvc_control_header,
441 	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
442 	(const struct uvc_descriptor_header *) &uvc_processing,
443 	(const struct uvc_descriptor_header *) &uvc_output_terminal,
444 	NULL,
445 };
446 
447 static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
448 	(const struct uvc_descriptor_header *) &uvc_input_header,
449 	(const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
450 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
451 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
452 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
453 	(const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
454 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
455 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
456 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
457 	NULL,
458 };
459 
460 static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
461 	(const struct uvc_descriptor_header *) &uvc_input_header,
462 	(const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
463 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
464 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
465 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
466 	(const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
467 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
468 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
469 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
470 	NULL,
471 };
472 
473 static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
474 	(const struct uvc_descriptor_header *) &uvc_input_header,
475 	(const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
476 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
477 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
478 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
479 	(const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
480 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
481 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
482 	(const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
483 	NULL,
484 };
485 
486 /* --------------------------------------------------------------------------
487  * USB configuration
488  */
489 
490 static int
491 webcam_config_bind(struct usb_configuration *c)
492 {
493 	int status = 0;
494 
495 	f_uvc = usb_get_function(fi_uvc);
496 	if (IS_ERR(f_uvc))
497 		return PTR_ERR(f_uvc);
498 
499 	status = usb_add_function(c, f_uvc);
500 	if (status < 0)
501 		usb_put_function(f_uvc);
502 
503 	return status;
504 }
505 
506 static struct usb_configuration webcam_config_driver = {
507 	.label			= webcam_config_label,
508 	.bConfigurationValue	= 1,
509 	.iConfiguration		= 0, /* dynamic */
510 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
511 	.MaxPower		= CONFIG_USB_GADGET_VBUS_DRAW,
512 };
513 
514 static int
515 webcam_unbind(struct usb_composite_dev *cdev)
516 {
517 	if (!IS_ERR_OR_NULL(f_uvc))
518 		usb_put_function(f_uvc);
519 	if (!IS_ERR_OR_NULL(fi_uvc))
520 		usb_put_function_instance(fi_uvc);
521 	return 0;
522 }
523 
524 static int
525 webcam_bind(struct usb_composite_dev *cdev)
526 {
527 	struct f_uvc_opts *uvc_opts;
528 	int ret;
529 
530 	fi_uvc = usb_get_function_instance("uvc");
531 	if (IS_ERR(fi_uvc))
532 		return PTR_ERR(fi_uvc);
533 
534 	uvc_opts = container_of(fi_uvc, struct f_uvc_opts, func_inst);
535 
536 	uvc_opts->streaming_interval = streaming_interval;
537 	uvc_opts->streaming_maxpacket = streaming_maxpacket;
538 	uvc_opts->streaming_maxburst = streaming_maxburst;
539 
540 	uvc_opts->fs_control = uvc_fs_control_cls;
541 	uvc_opts->ss_control = uvc_ss_control_cls;
542 	uvc_opts->fs_streaming = uvc_fs_streaming_cls;
543 	uvc_opts->hs_streaming = uvc_hs_streaming_cls;
544 	uvc_opts->ss_streaming = uvc_ss_streaming_cls;
545 
546 	INIT_LIST_HEAD(&uvcg_format_yuv.fmt.frames);
547 	list_add_tail(&uvcg_frame_ptr_yuv_360p.entry, &uvcg_format_yuv.fmt.frames);
548 	list_add_tail(&uvcg_frame_ptr_yuv_720p.entry, &uvcg_format_yuv.fmt.frames);
549 	uvcg_format_yuv.fmt.num_frames = 2;
550 
551 	INIT_LIST_HEAD(&uvcg_format_mjpeg.fmt.frames);
552 	list_add_tail(&uvcg_frame_ptr_mjpeg_360p.entry, &uvcg_format_mjpeg.fmt.frames);
553 	list_add_tail(&uvcg_frame_ptr_mjpeg_720p.entry, &uvcg_format_mjpeg.fmt.frames);
554 	uvcg_format_mjpeg.fmt.num_frames = 2;
555 
556 	INIT_LIST_HEAD(&uvcg_streaming_header.formats);
557 	list_add_tail(&uvcg_format_ptr_yuv.entry, &uvcg_streaming_header.formats);
558 	list_add_tail(&uvcg_format_ptr_mjpeg.entry, &uvcg_streaming_header.formats);
559 	uvcg_streaming_header.num_fmt = 2;
560 
561 	uvc_opts->header = &uvcg_streaming_header;
562 
563 	/* Allocate string descriptor numbers ... note that string contents
564 	 * can be overridden by the composite_dev glue.
565 	 */
566 	ret = usb_string_ids_tab(cdev, webcam_strings);
567 	if (ret < 0)
568 		goto error;
569 	webcam_device_descriptor.iManufacturer =
570 		webcam_strings[USB_GADGET_MANUFACTURER_IDX].id;
571 	webcam_device_descriptor.iProduct =
572 		webcam_strings[USB_GADGET_PRODUCT_IDX].id;
573 	webcam_config_driver.iConfiguration =
574 		webcam_strings[STRING_DESCRIPTION_IDX].id;
575 
576 	/* Register our configuration. */
577 	if ((ret = usb_add_config(cdev, &webcam_config_driver,
578 					webcam_config_bind)) < 0)
579 		goto error;
580 
581 	usb_composite_overwrite_options(cdev, &coverwrite);
582 	INFO(cdev, "Webcam Video Gadget\n");
583 	return 0;
584 
585 error:
586 	usb_put_function_instance(fi_uvc);
587 	return ret;
588 }
589 
590 /* --------------------------------------------------------------------------
591  * Driver
592  */
593 
594 static struct usb_composite_driver webcam_driver = {
595 	.name		= "g_webcam",
596 	.dev		= &webcam_device_descriptor,
597 	.strings	= webcam_device_strings,
598 	.max_speed	= USB_SPEED_SUPER,
599 	.bind		= webcam_bind,
600 	.unbind		= webcam_unbind,
601 };
602 
603 module_usb_composite_driver(webcam_driver);
604 
605 MODULE_AUTHOR("Laurent Pinchart");
606 MODULE_DESCRIPTION("Webcam Video Gadget");
607 MODULE_LICENSE("GPL");
608 
609