Merge branch 'x86/ras' into x86/core, to fix conflicts
[deliverable/linux.git] / drivers / usb / gadget / legacy / webcam.c
CommitLineData
a9914127
LP
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.
a9914127 11 */
28c9fc68 12
a9914127
LP
13#include <linux/kernel.h>
14#include <linux/device.h>
3a83c16e 15#include <linux/module.h>
a9914127
LP
16#include <linux/usb/video.h>
17
c913881e 18#include "u_uvc.h"
a9914127 19
7d16e8d3 20USB_GADGET_COMPOSITE_OPTIONS();
efb540c8
AP
21
22/*-------------------------------------------------------------------------*/
23
24/* module parameters specific to the Video streaming endpoint */
25static unsigned int streaming_interval = 1;
26module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
27MODULE_PARM_DESC(streaming_interval, "1 - 16");
28
29static unsigned int streaming_maxpacket = 1024;
30module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
31MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)");
32
33static unsigned int streaming_maxburst;
34module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
35MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
36
37static unsigned int trace;
38module_param(trace, uint, S_IRUGO|S_IWUSR);
39MODULE_PARM_DESC(trace, "Trace level bitmask");
a9914127
LP
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
48static char webcam_vendor_label[] = "Linux Foundation";
49static char webcam_product_label[] = "Webcam gadget";
50static char webcam_config_label[] = "Video";
51
52/* string IDs are assigned dynamically */
53
276e2e4f 54#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX
a9914127
LP
55
56static struct usb_string webcam_strings[] = {
276e2e4f
SAS
57 [USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label,
58 [USB_GADGET_PRODUCT_IDX].s = webcam_product_label,
59 [USB_GADGET_SERIAL_IDX].s = "",
a9914127
LP
60 [STRING_DESCRIPTION_IDX].s = webcam_config_label,
61 { }
62};
63
64static struct usb_gadget_strings webcam_stringtab = {
65 .language = 0x0409, /* en-us */
66 .strings = webcam_strings,
67};
68
69static struct usb_gadget_strings *webcam_device_strings[] = {
70 &webcam_stringtab,
71 NULL,
72};
73
c913881e
AP
74static struct usb_function_instance *fi_uvc;
75static struct usb_function *f_uvc;
76
a9914127
LP
77static struct usb_device_descriptor webcam_device_descriptor = {
78 .bLength = USB_DT_DEVICE_SIZE,
79 .bDescriptorType = USB_DT_DEVICE,
80 .bcdUSB = cpu_to_le16(0x0200),
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
94DECLARE_UVC_HEADER_DESCRIPTOR(1);
95
96static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
97 .bLength = UVC_DT_HEADER_SIZE(1),
98 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 99 .bDescriptorSubType = UVC_VC_HEADER,
a9914127
LP
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
107static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
108 .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3),
109 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 110 .bDescriptorSubType = UVC_VC_INPUT_TERMINAL,
a9914127
LP
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
124static const struct uvc_processing_unit_descriptor uvc_processing = {
125 .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2),
126 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 127 .bDescriptorSubType = UVC_VC_PROCESSING_UNIT,
a9914127
LP
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
137static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
138 .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE,
139 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 140 .bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL,
a9914127
LP
141 .bTerminalID = 3,
142 .wTerminalType = cpu_to_le16(0x0101),
143 .bAssocTerminal = 0,
144 .bSourceID = 2,
145 .iTerminal = 0,
146};
147
148DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
149
150static 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,
bbafc0cb 153 .bDescriptorSubType = UVC_VS_INPUT_HEADER,
a9914127
LP
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
167static const struct uvc_format_uncompressed uvc_format_yuv = {
168 .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
169 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 170 .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED,
a9914127
LP
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
184DECLARE_UVC_FRAME_UNCOMPRESSED(1);
185DECLARE_UVC_FRAME_UNCOMPRESSED(3);
186
187static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
188 .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
189 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 190 .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
a9914127
LP
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
205static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
206 .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
207 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 208 .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED,
a9914127
LP
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
221static const struct uvc_format_mjpeg uvc_format_mjpg = {
222 .bLength = UVC_DT_FORMAT_MJPEG_SIZE,
223 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 224 .bDescriptorSubType = UVC_VS_FORMAT_MJPEG,
a9914127
LP
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
235DECLARE_UVC_FRAME_MJPEG(1);
236DECLARE_UVC_FRAME_MJPEG(3);
237
238static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
239 .bLength = UVC_DT_FRAME_MJPEG_SIZE(3),
240 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 241 .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
a9914127
LP
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
256static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
257 .bLength = UVC_DT_FRAME_MJPEG_SIZE(1),
258 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 259 .bDescriptorSubType = UVC_VS_FRAME_MJPEG,
a9914127
LP
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
272static const struct uvc_color_matching_descriptor uvc_color_matching = {
273 .bLength = UVC_DT_COLOR_MATCHING_SIZE,
274 .bDescriptorType = USB_DT_CS_INTERFACE,
bbafc0cb 275 .bDescriptorSubType = UVC_VS_COLORFORMAT,
a9914127
LP
276 .bColorPrimaries = 1,
277 .bTransferCharacteristics = 1,
278 .bMatrixCoefficients = 4,
279};
280
fbcaba0e
BS
281static 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
289static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
a9914127
LP
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
297static 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
309static 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
fbcaba0e
BS
321static 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
a9914127
LP
333/* --------------------------------------------------------------------------
334 * USB configuration
335 */
336
c94e289f 337static int
a9914127
LP
338webcam_config_bind(struct usb_configuration *c)
339{
c913881e
AP
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;
a9914127
LP
351}
352
353static struct usb_configuration webcam_config_driver = {
354 .label = webcam_config_label,
a9914127
LP
355 .bConfigurationValue = 1,
356 .iConfiguration = 0, /* dynamic */
357 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
8f900a9a 358 .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW,
a9914127
LP
359};
360
c94e289f 361static int
a9914127
LP
362webcam_unbind(struct usb_composite_dev *cdev)
363{
c913881e
AP
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);
a9914127
LP
368 return 0;
369}
370
c94e289f 371static int
a9914127
LP
372webcam_bind(struct usb_composite_dev *cdev)
373{
c913881e 374 struct f_uvc_opts *uvc_opts;
a9914127
LP
375 int ret;
376
c913881e
AP
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
a9914127
LP
394 /* Allocate string descriptor numbers ... note that string contents
395 * can be overridden by the composite_dev glue.
396 */
e1f15ccb
SAS
397 ret = usb_string_ids_tab(cdev, webcam_strings);
398 if (ret < 0)
a9914127 399 goto error;
e1f15ccb 400 webcam_device_descriptor.iManufacturer =
276e2e4f 401 webcam_strings[USB_GADGET_MANUFACTURER_IDX].id;
e1f15ccb 402 webcam_device_descriptor.iProduct =
276e2e4f 403 webcam_strings[USB_GADGET_PRODUCT_IDX].id;
e1f15ccb
SAS
404 webcam_config_driver.iConfiguration =
405 webcam_strings[STRING_DESCRIPTION_IDX].id;
a9914127
LP
406
407 /* Register our configuration. */
c9bfff9c
UKK
408 if ((ret = usb_add_config(cdev, &webcam_config_driver,
409 webcam_config_bind)) < 0)
a9914127
LP
410 goto error;
411
7d16e8d3 412 usb_composite_overwrite_options(cdev, &coverwrite);
a9914127
LP
413 INFO(cdev, "Webcam Video Gadget\n");
414 return 0;
415
416error:
c913881e 417 usb_put_function_instance(fi_uvc);
a9914127
LP
418 return ret;
419}
420
421/* --------------------------------------------------------------------------
422 * Driver
423 */
424
c94e289f 425static struct usb_composite_driver webcam_driver = {
a9914127
LP
426 .name = "g_webcam",
427 .dev = &webcam_device_descriptor,
428 .strings = webcam_device_strings,
fbcaba0e 429 .max_speed = USB_SPEED_SUPER,
03e42bd5 430 .bind = webcam_bind,
a9914127
LP
431 .unbind = webcam_unbind,
432};
433
909346a8 434module_usb_composite_driver(webcam_driver);
a9914127
LP
435
436MODULE_AUTHOR("Laurent Pinchart");
437MODULE_DESCRIPTION("Webcam Video Gadget");
438MODULE_LICENSE("GPL");
439MODULE_VERSION("0.1.0");
440
This page took 0.370535 seconds and 5 git commands to generate.