at v3.6 420 lines 13 kB view raw
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/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 "composite.c" 27#include "usbstring.c" 28#include "config.c" 29#include "epautoconf.c" 30 31#include "uvc_queue.c" 32#include "uvc_video.c" 33#include "uvc_v4l2.c" 34#include "f_uvc.c" 35 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 44static char webcam_vendor_label[] = "Linux Foundation"; 45static char webcam_product_label[] = "Webcam gadget"; 46static char webcam_config_label[] = "Video"; 47 48/* string IDs are assigned dynamically */ 49 50#define STRING_MANUFACTURER_IDX 0 51#define STRING_PRODUCT_IDX 1 52#define STRING_DESCRIPTION_IDX 2 53 54static struct usb_string webcam_strings[] = { 55 [STRING_MANUFACTURER_IDX].s = webcam_vendor_label, 56 [STRING_PRODUCT_IDX].s = webcam_product_label, 57 [STRING_DESCRIPTION_IDX].s = webcam_config_label, 58 { } 59}; 60 61static struct usb_gadget_strings webcam_stringtab = { 62 .language = 0x0409, /* en-us */ 63 .strings = webcam_strings, 64}; 65 66static struct usb_gadget_strings *webcam_device_strings[] = { 67 &webcam_stringtab, 68 NULL, 69}; 70 71static struct usb_device_descriptor webcam_device_descriptor = { 72 .bLength = USB_DT_DEVICE_SIZE, 73 .bDescriptorType = USB_DT_DEVICE, 74 .bcdUSB = cpu_to_le16(0x0200), 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 88DECLARE_UVC_HEADER_DESCRIPTOR(1); 89 90static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { 91 .bLength = UVC_DT_HEADER_SIZE(1), 92 .bDescriptorType = USB_DT_CS_INTERFACE, 93 .bDescriptorSubType = UVC_VC_HEADER, 94 .bcdUVC = cpu_to_le16(0x0100), 95 .wTotalLength = 0, /* dynamic */ 96 .dwClockFrequency = cpu_to_le32(48000000), 97 .bInCollection = 0, /* dynamic */ 98 .baInterfaceNr[0] = 0, /* dynamic */ 99}; 100 101static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = { 102 .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), 103 .bDescriptorType = USB_DT_CS_INTERFACE, 104 .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, 105 .bTerminalID = 1, 106 .wTerminalType = cpu_to_le16(0x0201), 107 .bAssocTerminal = 0, 108 .iTerminal = 0, 109 .wObjectiveFocalLengthMin = cpu_to_le16(0), 110 .wObjectiveFocalLengthMax = cpu_to_le16(0), 111 .wOcularFocalLength = cpu_to_le16(0), 112 .bControlSize = 3, 113 .bmControls[0] = 2, 114 .bmControls[1] = 0, 115 .bmControls[2] = 0, 116}; 117 118static const struct uvc_processing_unit_descriptor uvc_processing = { 119 .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), 120 .bDescriptorType = USB_DT_CS_INTERFACE, 121 .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, 122 .bUnitID = 2, 123 .bSourceID = 1, 124 .wMaxMultiplier = cpu_to_le16(16*1024), 125 .bControlSize = 2, 126 .bmControls[0] = 1, 127 .bmControls[1] = 0, 128 .iProcessing = 0, 129}; 130 131static const struct uvc_output_terminal_descriptor uvc_output_terminal = { 132 .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, 133 .bDescriptorType = USB_DT_CS_INTERFACE, 134 .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL, 135 .bTerminalID = 3, 136 .wTerminalType = cpu_to_le16(0x0101), 137 .bAssocTerminal = 0, 138 .bSourceID = 2, 139 .iTerminal = 0, 140}; 141 142DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2); 143 144static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = { 145 .bLength = UVC_DT_INPUT_HEADER_SIZE(1, 2), 146 .bDescriptorType = USB_DT_CS_INTERFACE, 147 .bDescriptorSubType = UVC_VS_INPUT_HEADER, 148 .bNumFormats = 2, 149 .wTotalLength = 0, /* dynamic */ 150 .bEndpointAddress = 0, /* dynamic */ 151 .bmInfo = 0, 152 .bTerminalLink = 3, 153 .bStillCaptureMethod = 0, 154 .bTriggerSupport = 0, 155 .bTriggerUsage = 0, 156 .bControlSize = 1, 157 .bmaControls[0][0] = 0, 158 .bmaControls[1][0] = 4, 159}; 160 161static const struct uvc_format_uncompressed uvc_format_yuv = { 162 .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, 163 .bDescriptorType = USB_DT_CS_INTERFACE, 164 .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, 165 .bFormatIndex = 1, 166 .bNumFrameDescriptors = 2, 167 .guidFormat = 168 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 169 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, 170 .bBitsPerPixel = 16, 171 .bDefaultFrameIndex = 1, 172 .bAspectRatioX = 0, 173 .bAspectRatioY = 0, 174 .bmInterfaceFlags = 0, 175 .bCopyProtect = 0, 176}; 177 178DECLARE_UVC_FRAME_UNCOMPRESSED(1); 179DECLARE_UVC_FRAME_UNCOMPRESSED(3); 180 181static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { 182 .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), 183 .bDescriptorType = USB_DT_CS_INTERFACE, 184 .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, 185 .bFrameIndex = 1, 186 .bmCapabilities = 0, 187 .wWidth = cpu_to_le16(640), 188 .wHeight = cpu_to_le16(360), 189 .dwMinBitRate = cpu_to_le32(18432000), 190 .dwMaxBitRate = cpu_to_le32(55296000), 191 .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), 192 .dwDefaultFrameInterval = cpu_to_le32(666666), 193 .bFrameIntervalType = 3, 194 .dwFrameInterval[0] = cpu_to_le32(666666), 195 .dwFrameInterval[1] = cpu_to_le32(1000000), 196 .dwFrameInterval[2] = cpu_to_le32(5000000), 197}; 198 199static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { 200 .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), 201 .bDescriptorType = USB_DT_CS_INTERFACE, 202 .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, 203 .bFrameIndex = 2, 204 .bmCapabilities = 0, 205 .wWidth = cpu_to_le16(1280), 206 .wHeight = cpu_to_le16(720), 207 .dwMinBitRate = cpu_to_le32(29491200), 208 .dwMaxBitRate = cpu_to_le32(29491200), 209 .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), 210 .dwDefaultFrameInterval = cpu_to_le32(5000000), 211 .bFrameIntervalType = 1, 212 .dwFrameInterval[0] = cpu_to_le32(5000000), 213}; 214 215static const struct uvc_format_mjpeg uvc_format_mjpg = { 216 .bLength = UVC_DT_FORMAT_MJPEG_SIZE, 217 .bDescriptorType = USB_DT_CS_INTERFACE, 218 .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, 219 .bFormatIndex = 2, 220 .bNumFrameDescriptors = 2, 221 .bmFlags = 0, 222 .bDefaultFrameIndex = 1, 223 .bAspectRatioX = 0, 224 .bAspectRatioY = 0, 225 .bmInterfaceFlags = 0, 226 .bCopyProtect = 0, 227}; 228 229DECLARE_UVC_FRAME_MJPEG(1); 230DECLARE_UVC_FRAME_MJPEG(3); 231 232static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { 233 .bLength = UVC_DT_FRAME_MJPEG_SIZE(3), 234 .bDescriptorType = USB_DT_CS_INTERFACE, 235 .bDescriptorSubType = UVC_VS_FRAME_MJPEG, 236 .bFrameIndex = 1, 237 .bmCapabilities = 0, 238 .wWidth = cpu_to_le16(640), 239 .wHeight = cpu_to_le16(360), 240 .dwMinBitRate = cpu_to_le32(18432000), 241 .dwMaxBitRate = cpu_to_le32(55296000), 242 .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), 243 .dwDefaultFrameInterval = cpu_to_le32(666666), 244 .bFrameIntervalType = 3, 245 .dwFrameInterval[0] = cpu_to_le32(666666), 246 .dwFrameInterval[1] = cpu_to_le32(1000000), 247 .dwFrameInterval[2] = cpu_to_le32(5000000), 248}; 249 250static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { 251 .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), 252 .bDescriptorType = USB_DT_CS_INTERFACE, 253 .bDescriptorSubType = UVC_VS_FRAME_MJPEG, 254 .bFrameIndex = 2, 255 .bmCapabilities = 0, 256 .wWidth = cpu_to_le16(1280), 257 .wHeight = cpu_to_le16(720), 258 .dwMinBitRate = cpu_to_le32(29491200), 259 .dwMaxBitRate = cpu_to_le32(29491200), 260 .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), 261 .dwDefaultFrameInterval = cpu_to_le32(5000000), 262 .bFrameIntervalType = 1, 263 .dwFrameInterval[0] = cpu_to_le32(5000000), 264}; 265 266static const struct uvc_color_matching_descriptor uvc_color_matching = { 267 .bLength = UVC_DT_COLOR_MATCHING_SIZE, 268 .bDescriptorType = USB_DT_CS_INTERFACE, 269 .bDescriptorSubType = UVC_VS_COLORFORMAT, 270 .bColorPrimaries = 1, 271 .bTransferCharacteristics = 1, 272 .bMatrixCoefficients = 4, 273}; 274 275static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { 276 (const struct uvc_descriptor_header *) &uvc_control_header, 277 (const struct uvc_descriptor_header *) &uvc_camera_terminal, 278 (const struct uvc_descriptor_header *) &uvc_processing, 279 (const struct uvc_descriptor_header *) &uvc_output_terminal, 280 NULL, 281}; 282 283static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { 284 (const struct uvc_descriptor_header *) &uvc_control_header, 285 (const struct uvc_descriptor_header *) &uvc_camera_terminal, 286 (const struct uvc_descriptor_header *) &uvc_processing, 287 (const struct uvc_descriptor_header *) &uvc_output_terminal, 288 NULL, 289}; 290 291static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = { 292 (const struct uvc_descriptor_header *) &uvc_input_header, 293 (const struct uvc_descriptor_header *) &uvc_format_yuv, 294 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, 295 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, 296 (const struct uvc_descriptor_header *) &uvc_format_mjpg, 297 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, 298 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, 299 (const struct uvc_descriptor_header *) &uvc_color_matching, 300 NULL, 301}; 302 303static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { 304 (const struct uvc_descriptor_header *) &uvc_input_header, 305 (const struct uvc_descriptor_header *) &uvc_format_yuv, 306 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, 307 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, 308 (const struct uvc_descriptor_header *) &uvc_format_mjpg, 309 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, 310 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, 311 (const struct uvc_descriptor_header *) &uvc_color_matching, 312 NULL, 313}; 314 315static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { 316 (const struct uvc_descriptor_header *) &uvc_input_header, 317 (const struct uvc_descriptor_header *) &uvc_format_yuv, 318 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, 319 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, 320 (const struct uvc_descriptor_header *) &uvc_format_mjpg, 321 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, 322 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, 323 (const struct uvc_descriptor_header *) &uvc_color_matching, 324 NULL, 325}; 326 327/* -------------------------------------------------------------------------- 328 * USB configuration 329 */ 330 331static int __init 332webcam_config_bind(struct usb_configuration *c) 333{ 334 return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls, 335 uvc_fs_streaming_cls, uvc_hs_streaming_cls, 336 uvc_ss_streaming_cls); 337} 338 339static struct usb_configuration webcam_config_driver = { 340 .label = webcam_config_label, 341 .bConfigurationValue = 1, 342 .iConfiguration = 0, /* dynamic */ 343 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 344 .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, 345}; 346 347static int /* __init_or_exit */ 348webcam_unbind(struct usb_composite_dev *cdev) 349{ 350 return 0; 351} 352 353static int __init 354webcam_bind(struct usb_composite_dev *cdev) 355{ 356 int ret; 357 358 /* Allocate string descriptor numbers ... note that string contents 359 * can be overridden by the composite_dev glue. 360 */ 361 if ((ret = usb_string_id(cdev)) < 0) 362 goto error; 363 webcam_strings[STRING_MANUFACTURER_IDX].id = ret; 364 webcam_device_descriptor.iManufacturer = ret; 365 366 if ((ret = usb_string_id(cdev)) < 0) 367 goto error; 368 webcam_strings[STRING_PRODUCT_IDX].id = ret; 369 webcam_device_descriptor.iProduct = ret; 370 371 if ((ret = usb_string_id(cdev)) < 0) 372 goto error; 373 webcam_strings[STRING_DESCRIPTION_IDX].id = ret; 374 webcam_config_driver.iConfiguration = ret; 375 376 /* Register our configuration. */ 377 if ((ret = usb_add_config(cdev, &webcam_config_driver, 378 webcam_config_bind)) < 0) 379 goto error; 380 381 INFO(cdev, "Webcam Video Gadget\n"); 382 return 0; 383 384error: 385 webcam_unbind(cdev); 386 return ret; 387} 388 389/* -------------------------------------------------------------------------- 390 * Driver 391 */ 392 393static struct usb_composite_driver webcam_driver = { 394 .name = "g_webcam", 395 .dev = &webcam_device_descriptor, 396 .strings = webcam_device_strings, 397 .max_speed = USB_SPEED_SUPER, 398 .unbind = webcam_unbind, 399}; 400 401static int __init 402webcam_init(void) 403{ 404 return usb_composite_probe(&webcam_driver, webcam_bind); 405} 406 407static void __exit 408webcam_cleanup(void) 409{ 410 usb_composite_unregister(&webcam_driver); 411} 412 413module_init(webcam_init); 414module_exit(webcam_cleanup); 415 416MODULE_AUTHOR("Laurent Pinchart"); 417MODULE_DESCRIPTION("Webcam Video Gadget"); 418MODULE_LICENSE("GPL"); 419MODULE_VERSION("0.1.0"); 420