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 = DYNAMIC */ 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 441