]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/usb/gadget/legacy/webcam.c
Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-artful-kernel.git] / drivers / usb / gadget / legacy / webcam.c
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 = cpu_to_le16(0x0200),
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