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