xref: /openbmc/linux/drivers/usb/gadget/legacy/webcam.c (revision e3b9f1e8)
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 
16 USB_GADGET_COMPOSITE_OPTIONS();
17 
18 /*-------------------------------------------------------------------------*/
19 
20 /* module parameters specific to the Video streaming endpoint */
21 static unsigned int streaming_interval = 1;
22 module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
23 MODULE_PARM_DESC(streaming_interval, "1 - 16");
24 
25 static unsigned int streaming_maxpacket = 1024;
26 module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
27 MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)");
28 
29 static unsigned int streaming_maxburst;
30 module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
31 MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
32 
33 static unsigned int trace;
34 module_param(trace, uint, S_IRUGO|S_IWUSR);
35 MODULE_PARM_DESC(trace, "Trace level bitmask");
36 /* --------------------------------------------------------------------------
37  * Device descriptor
38  */
39 
40 #define WEBCAM_VENDOR_ID		0x1d6b	/* Linux Foundation */
41 #define WEBCAM_PRODUCT_ID		0x0102	/* Webcam A/V gadget */
42 #define WEBCAM_DEVICE_BCD		0x0010	/* 0.10 */
43 
44 static char webcam_vendor_label[] = "Linux Foundation";
45 static char webcam_product_label[] = "Webcam gadget";
46 static char webcam_config_label[] = "Video";
47 
48 /* string IDs are assigned dynamically */
49 
50 #define STRING_DESCRIPTION_IDX		USB_GADGET_FIRST_AVAIL_IDX
51 
52 static struct usb_string webcam_strings[] = {
53 	[USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label,
54 	[USB_GADGET_PRODUCT_IDX].s = webcam_product_label,
55 	[USB_GADGET_SERIAL_IDX].s = "",
56 	[STRING_DESCRIPTION_IDX].s = webcam_config_label,
57 	{  }
58 };
59 
60 static struct usb_gadget_strings webcam_stringtab = {
61 	.language = 0x0409,	/* en-us */
62 	.strings = webcam_strings,
63 };
64 
65 static struct usb_gadget_strings *webcam_device_strings[] = {
66 	&webcam_stringtab,
67 	NULL,
68 };
69 
70 static struct usb_function_instance *fi_uvc;
71 static struct usb_function *f_uvc;
72 
73 static struct usb_device_descriptor webcam_device_descriptor = {
74 	.bLength		= USB_DT_DEVICE_SIZE,
75 	.bDescriptorType	= USB_DT_DEVICE,
76 	/* .bcdUSB = DYNAMIC */
77 	.bDeviceClass		= USB_CLASS_MISC,
78 	.bDeviceSubClass	= 0x02,
79 	.bDeviceProtocol	= 0x01,
80 	.bMaxPacketSize0	= 0, /* dynamic */
81 	.idVendor		= cpu_to_le16(WEBCAM_VENDOR_ID),
82 	.idProduct		= cpu_to_le16(WEBCAM_PRODUCT_ID),
83 	.bcdDevice		= cpu_to_le16(WEBCAM_DEVICE_BCD),
84 	.iManufacturer		= 0, /* dynamic */
85 	.iProduct		= 0, /* dynamic */
86 	.iSerialNumber		= 0, /* dynamic */
87 	.bNumConfigurations	= 0, /* dynamic */
88 };
89 
90 DECLARE_UVC_HEADER_DESCRIPTOR(1);
91 
92 static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
93 	.bLength		= UVC_DT_HEADER_SIZE(1),
94 	.bDescriptorType	= USB_DT_CS_INTERFACE,
95 	.bDescriptorSubType	= UVC_VC_HEADER,
96 	.bcdUVC			= cpu_to_le16(0x0100),
97 	.wTotalLength		= 0, /* dynamic */
98 	.dwClockFrequency	= cpu_to_le32(48000000),
99 	.bInCollection		= 0, /* dynamic */
100 	.baInterfaceNr[0]	= 0, /* dynamic */
101 };
102 
103 static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
104 	.bLength		= UVC_DT_CAMERA_TERMINAL_SIZE(3),
105 	.bDescriptorType	= USB_DT_CS_INTERFACE,
106 	.bDescriptorSubType	= UVC_VC_INPUT_TERMINAL,
107 	.bTerminalID		= 1,
108 	.wTerminalType		= cpu_to_le16(0x0201),
109 	.bAssocTerminal		= 0,
110 	.iTerminal		= 0,
111 	.wObjectiveFocalLengthMin	= cpu_to_le16(0),
112 	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
113 	.wOcularFocalLength		= cpu_to_le16(0),
114 	.bControlSize		= 3,
115 	.bmControls[0]		= 2,
116 	.bmControls[1]		= 0,
117 	.bmControls[2]		= 0,
118 };
119 
120 static const struct uvc_processing_unit_descriptor uvc_processing = {
121 	.bLength		= UVC_DT_PROCESSING_UNIT_SIZE(2),
122 	.bDescriptorType	= USB_DT_CS_INTERFACE,
123 	.bDescriptorSubType	= UVC_VC_PROCESSING_UNIT,
124 	.bUnitID		= 2,
125 	.bSourceID		= 1,
126 	.wMaxMultiplier		= cpu_to_le16(16*1024),
127 	.bControlSize		= 2,
128 	.bmControls[0]		= 1,
129 	.bmControls[1]		= 0,
130 	.iProcessing		= 0,
131 };
132 
133 static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
134 	.bLength		= UVC_DT_OUTPUT_TERMINAL_SIZE,
135 	.bDescriptorType	= USB_DT_CS_INTERFACE,
136 	.bDescriptorSubType	= UVC_VC_OUTPUT_TERMINAL,
137 	.bTerminalID		= 3,
138 	.wTerminalType		= cpu_to_le16(0x0101),
139 	.bAssocTerminal		= 0,
140 	.bSourceID		= 2,
141 	.iTerminal		= 0,
142 };
143 
144 DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
145 
146 static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
147 	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 2),
148 	.bDescriptorType	= USB_DT_CS_INTERFACE,
149 	.bDescriptorSubType	= UVC_VS_INPUT_HEADER,
150 	.bNumFormats		= 2,
151 	.wTotalLength		= 0, /* dynamic */
152 	.bEndpointAddress	= 0, /* dynamic */
153 	.bmInfo			= 0,
154 	.bTerminalLink		= 3,
155 	.bStillCaptureMethod	= 0,
156 	.bTriggerSupport	= 0,
157 	.bTriggerUsage		= 0,
158 	.bControlSize		= 1,
159 	.bmaControls[0][0]	= 0,
160 	.bmaControls[1][0]	= 4,
161 };
162 
163 static const struct uvc_format_uncompressed uvc_format_yuv = {
164 	.bLength		= UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
165 	.bDescriptorType	= USB_DT_CS_INTERFACE,
166 	.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED,
167 	.bFormatIndex		= 1,
168 	.bNumFrameDescriptors	= 2,
169 	.guidFormat		=
170 		{ 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
171 		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71},
172 	.bBitsPerPixel		= 16,
173 	.bDefaultFrameIndex	= 1,
174 	.bAspectRatioX		= 0,
175 	.bAspectRatioY		= 0,
176 	.bmInterfaceFlags	= 0,
177 	.bCopyProtect		= 0,
178 };
179 
180 DECLARE_UVC_FRAME_UNCOMPRESSED(1);
181 DECLARE_UVC_FRAME_UNCOMPRESSED(3);
182 
183 static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
184 	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
185 	.bDescriptorType	= USB_DT_CS_INTERFACE,
186 	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
187 	.bFrameIndex		= 1,
188 	.bmCapabilities		= 0,
189 	.wWidth			= cpu_to_le16(640),
190 	.wHeight		= cpu_to_le16(360),
191 	.dwMinBitRate		= cpu_to_le32(18432000),
192 	.dwMaxBitRate		= cpu_to_le32(55296000),
193 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(460800),
194 	.dwDefaultFrameInterval	= cpu_to_le32(666666),
195 	.bFrameIntervalType	= 3,
196 	.dwFrameInterval[0]	= cpu_to_le32(666666),
197 	.dwFrameInterval[1]	= cpu_to_le32(1000000),
198 	.dwFrameInterval[2]	= cpu_to_le32(5000000),
199 };
200 
201 static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
202 	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
203 	.bDescriptorType	= USB_DT_CS_INTERFACE,
204 	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
205 	.bFrameIndex		= 2,
206 	.bmCapabilities		= 0,
207 	.wWidth			= cpu_to_le16(1280),
208 	.wHeight		= cpu_to_le16(720),
209 	.dwMinBitRate		= cpu_to_le32(29491200),
210 	.dwMaxBitRate		= cpu_to_le32(29491200),
211 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(1843200),
212 	.dwDefaultFrameInterval	= cpu_to_le32(5000000),
213 	.bFrameIntervalType	= 1,
214 	.dwFrameInterval[0]	= cpu_to_le32(5000000),
215 };
216 
217 static const struct uvc_format_mjpeg uvc_format_mjpg = {
218 	.bLength		= UVC_DT_FORMAT_MJPEG_SIZE,
219 	.bDescriptorType	= USB_DT_CS_INTERFACE,
220 	.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG,
221 	.bFormatIndex		= 2,
222 	.bNumFrameDescriptors	= 2,
223 	.bmFlags		= 0,
224 	.bDefaultFrameIndex	= 1,
225 	.bAspectRatioX		= 0,
226 	.bAspectRatioY		= 0,
227 	.bmInterfaceFlags	= 0,
228 	.bCopyProtect		= 0,
229 };
230 
231 DECLARE_UVC_FRAME_MJPEG(1);
232 DECLARE_UVC_FRAME_MJPEG(3);
233 
234 static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
235 	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(3),
236 	.bDescriptorType	= USB_DT_CS_INTERFACE,
237 	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
238 	.bFrameIndex		= 1,
239 	.bmCapabilities		= 0,
240 	.wWidth			= cpu_to_le16(640),
241 	.wHeight		= cpu_to_le16(360),
242 	.dwMinBitRate		= cpu_to_le32(18432000),
243 	.dwMaxBitRate		= cpu_to_le32(55296000),
244 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(460800),
245 	.dwDefaultFrameInterval	= cpu_to_le32(666666),
246 	.bFrameIntervalType	= 3,
247 	.dwFrameInterval[0]	= cpu_to_le32(666666),
248 	.dwFrameInterval[1]	= cpu_to_le32(1000000),
249 	.dwFrameInterval[2]	= cpu_to_le32(5000000),
250 };
251 
252 static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
253 	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(1),
254 	.bDescriptorType	= USB_DT_CS_INTERFACE,
255 	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
256 	.bFrameIndex		= 2,
257 	.bmCapabilities		= 0,
258 	.wWidth			= cpu_to_le16(1280),
259 	.wHeight		= cpu_to_le16(720),
260 	.dwMinBitRate		= cpu_to_le32(29491200),
261 	.dwMaxBitRate		= cpu_to_le32(29491200),
262 	.dwMaxVideoFrameBufferSize	= cpu_to_le32(1843200),
263 	.dwDefaultFrameInterval	= cpu_to_le32(5000000),
264 	.bFrameIntervalType	= 1,
265 	.dwFrameInterval[0]	= cpu_to_le32(5000000),
266 };
267 
268 static const struct uvc_color_matching_descriptor uvc_color_matching = {
269 	.bLength		= UVC_DT_COLOR_MATCHING_SIZE,
270 	.bDescriptorType	= USB_DT_CS_INTERFACE,
271 	.bDescriptorSubType	= UVC_VS_COLORFORMAT,
272 	.bColorPrimaries	= 1,
273 	.bTransferCharacteristics	= 1,
274 	.bMatrixCoefficients	= 4,
275 };
276 
277 static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
278 	(const struct uvc_descriptor_header *) &uvc_control_header,
279 	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
280 	(const struct uvc_descriptor_header *) &uvc_processing,
281 	(const struct uvc_descriptor_header *) &uvc_output_terminal,
282 	NULL,
283 };
284 
285 static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
286 	(const struct uvc_descriptor_header *) &uvc_control_header,
287 	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
288 	(const struct uvc_descriptor_header *) &uvc_processing,
289 	(const struct uvc_descriptor_header *) &uvc_output_terminal,
290 	NULL,
291 };
292 
293 static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
294 	(const struct uvc_descriptor_header *) &uvc_input_header,
295 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
296 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
297 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
298 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
299 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
300 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
301 	(const struct uvc_descriptor_header *) &uvc_color_matching,
302 	NULL,
303 };
304 
305 static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
306 	(const struct uvc_descriptor_header *) &uvc_input_header,
307 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
308 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
309 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
310 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
311 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
312 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
313 	(const struct uvc_descriptor_header *) &uvc_color_matching,
314 	NULL,
315 };
316 
317 static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
318 	(const struct uvc_descriptor_header *) &uvc_input_header,
319 	(const struct uvc_descriptor_header *) &uvc_format_yuv,
320 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
321 	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
322 	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
323 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
324 	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
325 	(const struct uvc_descriptor_header *) &uvc_color_matching,
326 	NULL,
327 };
328 
329 /* --------------------------------------------------------------------------
330  * USB configuration
331  */
332 
333 static int
334 webcam_config_bind(struct usb_configuration *c)
335 {
336 	int status = 0;
337 
338 	f_uvc = usb_get_function(fi_uvc);
339 	if (IS_ERR(f_uvc))
340 		return PTR_ERR(f_uvc);
341 
342 	status = usb_add_function(c, f_uvc);
343 	if (status < 0)
344 		usb_put_function(f_uvc);
345 
346 	return status;
347 }
348 
349 static struct usb_configuration webcam_config_driver = {
350 	.label			= webcam_config_label,
351 	.bConfigurationValue	= 1,
352 	.iConfiguration		= 0, /* dynamic */
353 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
354 	.MaxPower		= CONFIG_USB_GADGET_VBUS_DRAW,
355 };
356 
357 static int
358 webcam_unbind(struct usb_composite_dev *cdev)
359 {
360 	if (!IS_ERR_OR_NULL(f_uvc))
361 		usb_put_function(f_uvc);
362 	if (!IS_ERR_OR_NULL(fi_uvc))
363 		usb_put_function_instance(fi_uvc);
364 	return 0;
365 }
366 
367 static int
368 webcam_bind(struct usb_composite_dev *cdev)
369 {
370 	struct f_uvc_opts *uvc_opts;
371 	int ret;
372 
373 	fi_uvc = usb_get_function_instance("uvc");
374 	if (IS_ERR(fi_uvc))
375 		return PTR_ERR(fi_uvc);
376 
377 	uvc_opts = container_of(fi_uvc, struct f_uvc_opts, func_inst);
378 
379 	uvc_opts->streaming_interval = streaming_interval;
380 	uvc_opts->streaming_maxpacket = streaming_maxpacket;
381 	uvc_opts->streaming_maxburst = streaming_maxburst;
382 	uvc_set_trace_param(trace);
383 
384 	uvc_opts->fs_control = uvc_fs_control_cls;
385 	uvc_opts->ss_control = uvc_ss_control_cls;
386 	uvc_opts->fs_streaming = uvc_fs_streaming_cls;
387 	uvc_opts->hs_streaming = uvc_hs_streaming_cls;
388 	uvc_opts->ss_streaming = uvc_ss_streaming_cls;
389 
390 	/* Allocate string descriptor numbers ... note that string contents
391 	 * can be overridden by the composite_dev glue.
392 	 */
393 	ret = usb_string_ids_tab(cdev, webcam_strings);
394 	if (ret < 0)
395 		goto error;
396 	webcam_device_descriptor.iManufacturer =
397 		webcam_strings[USB_GADGET_MANUFACTURER_IDX].id;
398 	webcam_device_descriptor.iProduct =
399 		webcam_strings[USB_GADGET_PRODUCT_IDX].id;
400 	webcam_config_driver.iConfiguration =
401 		webcam_strings[STRING_DESCRIPTION_IDX].id;
402 
403 	/* Register our configuration. */
404 	if ((ret = usb_add_config(cdev, &webcam_config_driver,
405 					webcam_config_bind)) < 0)
406 		goto error;
407 
408 	usb_composite_overwrite_options(cdev, &coverwrite);
409 	INFO(cdev, "Webcam Video Gadget\n");
410 	return 0;
411 
412 error:
413 	usb_put_function_instance(fi_uvc);
414 	return ret;
415 }
416 
417 /* --------------------------------------------------------------------------
418  * Driver
419  */
420 
421 static struct usb_composite_driver webcam_driver = {
422 	.name		= "g_webcam",
423 	.dev		= &webcam_device_descriptor,
424 	.strings	= webcam_device_strings,
425 	.max_speed	= USB_SPEED_SUPER,
426 	.bind		= webcam_bind,
427 	.unbind		= webcam_unbind,
428 };
429 
430 module_usb_composite_driver(webcam_driver);
431 
432 MODULE_AUTHOR("Laurent Pinchart");
433 MODULE_DESCRIPTION("Webcam Video Gadget");
434 MODULE_LICENSE("GPL");
435 
436