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_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_fs_streaming_cls[] = { 284 (const struct uvc_descriptor_header *) &uvc_input_header, 285 (const struct uvc_descriptor_header *) &uvc_format_yuv, 286 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, 287 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, 288 (const struct uvc_descriptor_header *) &uvc_format_mjpg, 289 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, 290 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, 291 (const struct uvc_descriptor_header *) &uvc_color_matching, 292 NULL, 293}; 294 295static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { 296 (const struct uvc_descriptor_header *) &uvc_input_header, 297 (const struct uvc_descriptor_header *) &uvc_format_yuv, 298 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, 299 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, 300 (const struct uvc_descriptor_header *) &uvc_format_mjpg, 301 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, 302 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, 303 (const struct uvc_descriptor_header *) &uvc_color_matching, 304 NULL, 305}; 306 307/* -------------------------------------------------------------------------- 308 * USB configuration 309 */ 310 311static int __ref 312webcam_config_bind(struct usb_configuration *c) 313{ 314 return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls, 315 uvc_hs_streaming_cls); 316} 317 318static struct usb_configuration webcam_config_driver = { 319 .label = webcam_config_label, 320 .bind = webcam_config_bind, 321 .bConfigurationValue = 1, 322 .iConfiguration = 0, /* dynamic */ 323 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 324 .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, 325}; 326 327static int /* __init_or_exit */ 328webcam_unbind(struct usb_composite_dev *cdev) 329{ 330 return 0; 331} 332 333static int __ref 334webcam_bind(struct usb_composite_dev *cdev) 335{ 336 int ret; 337 338 /* Allocate string descriptor numbers ... note that string contents 339 * can be overridden by the composite_dev glue. 340 */ 341 if ((ret = usb_string_id(cdev)) < 0) 342 goto error; 343 webcam_strings[STRING_MANUFACTURER_IDX].id = ret; 344 webcam_device_descriptor.iManufacturer = ret; 345 346 if ((ret = usb_string_id(cdev)) < 0) 347 goto error; 348 webcam_strings[STRING_PRODUCT_IDX].id = ret; 349 webcam_device_descriptor.iProduct = ret; 350 351 if ((ret = usb_string_id(cdev)) < 0) 352 goto error; 353 webcam_strings[STRING_DESCRIPTION_IDX].id = ret; 354 webcam_config_driver.iConfiguration = ret; 355 356 /* Register our configuration. */ 357 if ((ret = usb_add_config(cdev, &webcam_config_driver)) < 0) 358 goto error; 359 360 INFO(cdev, "Webcam Video Gadget\n"); 361 return 0; 362 363error: 364 webcam_unbind(cdev); 365 return ret; 366} 367 368/* -------------------------------------------------------------------------- 369 * Driver 370 */ 371 372static struct usb_composite_driver webcam_driver = { 373 .name = "g_webcam", 374 .dev = &webcam_device_descriptor, 375 .strings = webcam_device_strings, 376 .bind = webcam_bind, 377 .unbind = webcam_unbind, 378}; 379 380static int __init 381webcam_init(void) 382{ 383 return usb_composite_register(&webcam_driver); 384} 385 386static void __exit 387webcam_cleanup(void) 388{ 389 usb_composite_unregister(&webcam_driver); 390} 391 392module_init(webcam_init); 393module_exit(webcam_cleanup); 394 395MODULE_AUTHOR("Laurent Pinchart"); 396MODULE_DESCRIPTION("Webcam Video Gadget"); 397MODULE_LICENSE("GPL"); 398MODULE_VERSION("0.1.0"); 399