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
webcam_config_bind(struct usb_configuration * c)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
webcam_unbind(struct usb_composite_dev * cdev)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
webcam_bind(struct usb_composite_dev * cdev)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