• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/usb/gadget/
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