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 "uvc_queue.c" 27 #include "uvc_video.c" 28 #include "uvc_v4l2.c" 29 #include "f_uvc.c" 30 31 USB_GADGET_COMPOSITE_OPTIONS(); 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 83 DECLARE_UVC_HEADER_DESCRIPTOR(1); 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 137 DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2); 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 = { 157 .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, 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 173 DECLARE_UVC_FRAME_UNCOMPRESSED(1); 174 DECLARE_UVC_FRAME_UNCOMPRESSED(3); 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 224 DECLARE_UVC_FRAME_MJPEG(1); 225 DECLARE_UVC_FRAME_MJPEG(3); 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 .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW, 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 module_usb_composite_driver(webcam_driver); 394 395 MODULE_AUTHOR("Laurent Pinchart"); 396 MODULE_DESCRIPTION("Webcam Video Gadget"); 397 MODULE_LICENSE("GPL"); 398 MODULE_VERSION("0.1.0"); 399 400