Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
webcam.c
Go to the documentation of this file.
1 /*
2  * webcam.c -- USB webcam gadget driver
3  *
4  * Copyright (C) 2009-2010
5  * Laurent Pinchart ([email protected])
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/usb/video.h>
16 
17 #include "f_uvc.h"
18 
19 /*
20  * Kbuild is not very cooperative with respect to linking separately
21  * compiled library objects into one module. So for now we won't use
22  * separate compilation ... ensuring init/exit sections work to shrink
23  * the runtime footprint, and giving us at least some parts of what
24  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
25  */
26 #include "uvc_queue.c"
27 #include "uvc_video.c"
28 #include "uvc_v4l2.c"
29 #include "f_uvc.c"
30 
32 /* --------------------------------------------------------------------------
33  * Device descriptor
34  */
35 
36 #define WEBCAM_VENDOR_ID 0x1d6b /* Linux Foundation */
37 #define WEBCAM_PRODUCT_ID 0x0102 /* Webcam A/V gadget */
38 #define WEBCAM_DEVICE_BCD 0x0010 /* 0.10 */
39 
40 static char webcam_vendor_label[] = "Linux Foundation";
41 static char webcam_product_label[] = "Webcam gadget";
42 static char webcam_config_label[] = "Video";
43 
44 /* string IDs are assigned dynamically */
45 
46 #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX
47 
48 static struct usb_string webcam_strings[] = {
49  [USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label,
50  [USB_GADGET_PRODUCT_IDX].s = webcam_product_label,
51  [USB_GADGET_SERIAL_IDX].s = "",
52  [STRING_DESCRIPTION_IDX].s = webcam_config_label,
53  { }
54 };
55 
56 static struct usb_gadget_strings webcam_stringtab = {
57  .language = 0x0409, /* en-us */
58  .strings = webcam_strings,
59 };
60 
61 static struct usb_gadget_strings *webcam_device_strings[] = {
62  &webcam_stringtab,
63  NULL,
64 };
65 
66 static struct usb_device_descriptor webcam_device_descriptor = {
67  .bLength = USB_DT_DEVICE_SIZE,
68  .bDescriptorType = USB_DT_DEVICE,
69  .bcdUSB = cpu_to_le16(0x0200),
70  .bDeviceClass = USB_CLASS_MISC,
71  .bDeviceSubClass = 0x02,
72  .bDeviceProtocol = 0x01,
73  .bMaxPacketSize0 = 0, /* dynamic */
74  .idVendor = cpu_to_le16(WEBCAM_VENDOR_ID),
75  .idProduct = cpu_to_le16(WEBCAM_PRODUCT_ID),
76  .bcdDevice = cpu_to_le16(WEBCAM_DEVICE_BCD),
77  .iManufacturer = 0, /* dynamic */
78  .iProduct = 0, /* dynamic */
79  .iSerialNumber = 0, /* dynamic */
80  .bNumConfigurations = 0, /* dynamic */
81 };
82 
84 
85 static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
86  .bLength = UVC_DT_HEADER_SIZE(1),
87  .bDescriptorType = USB_DT_CS_INTERFACE,
88  .bDescriptorSubType = UVC_VC_HEADER,
89  .bcdUVC = cpu_to_le16(0x0100),
90  .wTotalLength = 0, /* dynamic */
91  .dwClockFrequency = cpu_to_le32(48000000),
92  .bInCollection = 0, /* dynamic */
93  .baInterfaceNr[0] = 0, /* dynamic */
94 };
95 
96 static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
97  .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3),
98  .bDescriptorType = USB_DT_CS_INTERFACE,
99  .bDescriptorSubType = UVC_VC_INPUT_TERMINAL,
100  .bTerminalID = 1,
101  .wTerminalType = cpu_to_le16(0x0201),
102  .bAssocTerminal = 0,
103  .iTerminal = 0,
104  .wObjectiveFocalLengthMin = cpu_to_le16(0),
105  .wObjectiveFocalLengthMax = cpu_to_le16(0),
106  .wOcularFocalLength = cpu_to_le16(0),
107  .bControlSize = 3,
108  .bmControls[0] = 2,
109  .bmControls[1] = 0,
110  .bmControls[2] = 0,
111 };
112 
113 static const struct uvc_processing_unit_descriptor uvc_processing = {
114  .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2),
115  .bDescriptorType = USB_DT_CS_INTERFACE,
116  .bDescriptorSubType = UVC_VC_PROCESSING_UNIT,
117  .bUnitID = 2,
118  .bSourceID = 1,
119  .wMaxMultiplier = cpu_to_le16(16*1024),
120  .bControlSize = 2,
121  .bmControls[0] = 1,
122  .bmControls[1] = 0,
123  .iProcessing = 0,
124 };
125 
126 static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
127  .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE,
128  .bDescriptorType = USB_DT_CS_INTERFACE,
129  .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL,
130  .bTerminalID = 3,
131  .wTerminalType = cpu_to_le16(0x0101),
132  .bAssocTerminal = 0,
133  .bSourceID = 2,
134  .iTerminal = 0,
135 };
136 
138 
139 static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
140  .bLength = UVC_DT_INPUT_HEADER_SIZE(1, 2),
141  .bDescriptorType = USB_DT_CS_INTERFACE,
142  .bDescriptorSubType = UVC_VS_INPUT_HEADER,
143  .bNumFormats = 2,
144  .wTotalLength = 0, /* dynamic */
145  .bEndpointAddress = 0, /* dynamic */
146  .bmInfo = 0,
147  .bTerminalLink = 3,
148  .bStillCaptureMethod = 0,
149  .bTriggerSupport = 0,
150  .bTriggerUsage = 0,
151  .bControlSize = 1,
152  .bmaControls[0][0] = 0,
153  .bmaControls[1][0] = 4,
154 };
155 
156 static const struct uvc_format_uncompressed uvc_format_yuv = {
158  .bDescriptorType = USB_DT_CS_INTERFACE,
159  .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED,
160  .bFormatIndex = 1,
161  .bNumFrameDescriptors = 2,
162  .guidFormat =
163  { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00,
164  0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71},
165  .bBitsPerPixel = 16,
166  .bDefaultFrameIndex = 1,
167  .bAspectRatioX = 0,
168  .bAspectRatioY = 0,
169  .bmInterfaceFlags = 0,
170  .bCopyProtect = 0,
171 };
172 
175 
176 static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
177  .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
178  .bDescriptorType = USB_DT_CS_INTERFACE,
179  .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
180  .bFrameIndex = 1,
181  .bmCapabilities = 0,
182  .wWidth = cpu_to_le16(640),
183  .wHeight = cpu_to_le16(360),
184  .dwMinBitRate = cpu_to_le32(18432000),
185  .dwMaxBitRate = cpu_to_le32(55296000),
186  .dwMaxVideoFrameBufferSize = cpu_to_le32(460800),
187  .dwDefaultFrameInterval = cpu_to_le32(666666),
188  .bFrameIntervalType = 3,
189  .dwFrameInterval[0] = cpu_to_le32(666666),
190  .dwFrameInterval[1] = cpu_to_le32(1000000),
191  .dwFrameInterval[2] = cpu_to_le32(5000000),
192 };
193 
194 static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
195  .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
196  .bDescriptorType = USB_DT_CS_INTERFACE,
197  .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
198  .bFrameIndex = 2,
199  .bmCapabilities = 0,
200  .wWidth = cpu_to_le16(1280),
201  .wHeight = cpu_to_le16(720),
202  .dwMinBitRate = cpu_to_le32(29491200),
203  .dwMaxBitRate = cpu_to_le32(29491200),
204  .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200),
205  .dwDefaultFrameInterval = cpu_to_le32(5000000),
206  .bFrameIntervalType = 1,
207  .dwFrameInterval[0] = cpu_to_le32(5000000),
208 };
209 
210 static const struct uvc_format_mjpeg uvc_format_mjpg = {
211  .bLength = UVC_DT_FORMAT_MJPEG_SIZE,
212  .bDescriptorType = USB_DT_CS_INTERFACE,
213  .bDescriptorSubType = UVC_VS_FORMAT_MJPEG,
214  .bFormatIndex = 2,
215  .bNumFrameDescriptors = 2,
216  .bmFlags = 0,
217  .bDefaultFrameIndex = 1,
218  .bAspectRatioX = 0,
219  .bAspectRatioY = 0,
220  .bmInterfaceFlags = 0,
221  .bCopyProtect = 0,
222 };
223 
226 
227 static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
228  .bLength = UVC_DT_FRAME_MJPEG_SIZE(3),
229  .bDescriptorType = USB_DT_CS_INTERFACE,
230  .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
231  .bFrameIndex = 1,
232  .bmCapabilities = 0,
233  .wWidth = cpu_to_le16(640),
234  .wHeight = cpu_to_le16(360),
235  .dwMinBitRate = cpu_to_le32(18432000),
236  .dwMaxBitRate = cpu_to_le32(55296000),
237  .dwMaxVideoFrameBufferSize = cpu_to_le32(460800),
238  .dwDefaultFrameInterval = cpu_to_le32(666666),
239  .bFrameIntervalType = 3,
240  .dwFrameInterval[0] = cpu_to_le32(666666),
241  .dwFrameInterval[1] = cpu_to_le32(1000000),
242  .dwFrameInterval[2] = cpu_to_le32(5000000),
243 };
244 
245 static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
246  .bLength = UVC_DT_FRAME_MJPEG_SIZE(1),
247  .bDescriptorType = USB_DT_CS_INTERFACE,
248  .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
249  .bFrameIndex = 2,
250  .bmCapabilities = 0,
251  .wWidth = cpu_to_le16(1280),
252  .wHeight = cpu_to_le16(720),
253  .dwMinBitRate = cpu_to_le32(29491200),
254  .dwMaxBitRate = cpu_to_le32(29491200),
255  .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200),
256  .dwDefaultFrameInterval = cpu_to_le32(5000000),
257  .bFrameIntervalType = 1,
258  .dwFrameInterval[0] = cpu_to_le32(5000000),
259 };
260 
261 static const struct uvc_color_matching_descriptor uvc_color_matching = {
262  .bLength = UVC_DT_COLOR_MATCHING_SIZE,
263  .bDescriptorType = USB_DT_CS_INTERFACE,
264  .bDescriptorSubType = UVC_VS_COLORFORMAT,
265  .bColorPrimaries = 1,
266  .bTransferCharacteristics = 1,
267  .bMatrixCoefficients = 4,
268 };
269 
270 static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
271  (const struct uvc_descriptor_header *) &uvc_control_header,
272  (const struct uvc_descriptor_header *) &uvc_camera_terminal,
273  (const struct uvc_descriptor_header *) &uvc_processing,
274  (const struct uvc_descriptor_header *) &uvc_output_terminal,
275  NULL,
276 };
277 
278 static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
279  (const struct uvc_descriptor_header *) &uvc_control_header,
280  (const struct uvc_descriptor_header *) &uvc_camera_terminal,
281  (const struct uvc_descriptor_header *) &uvc_processing,
282  (const struct uvc_descriptor_header *) &uvc_output_terminal,
283  NULL,
284 };
285 
286 static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
287  (const struct uvc_descriptor_header *) &uvc_input_header,
288  (const struct uvc_descriptor_header *) &uvc_format_yuv,
289  (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
290  (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
291  (const struct uvc_descriptor_header *) &uvc_format_mjpg,
292  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
293  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
294  (const struct uvc_descriptor_header *) &uvc_color_matching,
295  NULL,
296 };
297 
298 static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
299  (const struct uvc_descriptor_header *) &uvc_input_header,
300  (const struct uvc_descriptor_header *) &uvc_format_yuv,
301  (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
302  (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
303  (const struct uvc_descriptor_header *) &uvc_format_mjpg,
304  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
305  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
306  (const struct uvc_descriptor_header *) &uvc_color_matching,
307  NULL,
308 };
309 
310 static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
311  (const struct uvc_descriptor_header *) &uvc_input_header,
312  (const struct uvc_descriptor_header *) &uvc_format_yuv,
313  (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
314  (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
315  (const struct uvc_descriptor_header *) &uvc_format_mjpg,
316  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
317  (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
318  (const struct uvc_descriptor_header *) &uvc_color_matching,
319  NULL,
320 };
321 
322 /* --------------------------------------------------------------------------
323  * USB configuration
324  */
325 
326 static int __init
327 webcam_config_bind(struct usb_configuration *c)
328 {
329  return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls,
330  uvc_fs_streaming_cls, uvc_hs_streaming_cls,
331  uvc_ss_streaming_cls);
332 }
333 
334 static struct usb_configuration webcam_config_driver = {
335  .label = webcam_config_label,
336  .bConfigurationValue = 1,
337  .iConfiguration = 0, /* dynamic */
338  .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
339  .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
340 };
341 
342 static int /* __init_or_exit */
343 webcam_unbind(struct usb_composite_dev *cdev)
344 {
345  return 0;
346 }
347 
348 static int __init
349 webcam_bind(struct usb_composite_dev *cdev)
350 {
351  int ret;
352 
353  /* Allocate string descriptor numbers ... note that string contents
354  * can be overridden by the composite_dev glue.
355  */
356  ret = usb_string_ids_tab(cdev, webcam_strings);
357  if (ret < 0)
358  goto error;
359  webcam_device_descriptor.iManufacturer =
360  webcam_strings[USB_GADGET_MANUFACTURER_IDX].id;
361  webcam_device_descriptor.iProduct =
362  webcam_strings[USB_GADGET_PRODUCT_IDX].id;
363  webcam_config_driver.iConfiguration =
364  webcam_strings[STRING_DESCRIPTION_IDX].id;
365 
366  /* Register our configuration. */
367  if ((ret = usb_add_config(cdev, &webcam_config_driver,
368  webcam_config_bind)) < 0)
369  goto error;
370 
371  usb_composite_overwrite_options(cdev, &coverwrite);
372  INFO(cdev, "Webcam Video Gadget\n");
373  return 0;
374 
375 error:
376  webcam_unbind(cdev);
377  return ret;
378 }
379 
380 /* --------------------------------------------------------------------------
381  * Driver
382  */
383 
384 static __refdata struct usb_composite_driver webcam_driver = {
385  .name = "g_webcam",
386  .dev = &webcam_device_descriptor,
387  .strings = webcam_device_strings,
388  .max_speed = USB_SPEED_SUPER,
389  .bind = webcam_bind,
390  .unbind = webcam_unbind,
391 };
392 
393 static int __init
394 webcam_init(void)
395 {
396  return usb_composite_probe(&webcam_driver);
397 }
398 
399 static void __exit
400 webcam_cleanup(void)
401 {
402  usb_composite_unregister(&webcam_driver);
403 }
404 
405 module_init(webcam_init);
406 module_exit(webcam_cleanup);
407 
408 MODULE_AUTHOR("Laurent Pinchart");
409 MODULE_DESCRIPTION("Webcam Video Gadget");
410 MODULE_LICENSE("GPL");
411 MODULE_VERSION("0.1.0");
412