blob: 04949c823654db4b4e95d4a4814d73a23a029d02 [file] [log] [blame]
Antoine Jacquetb7eee612007-04-27 12:30:59 -03001/*
2 * Zoran 364xx based USB webcam module version 0.72
3 *
4 * Allows you to use your USB webcam with V4L2 applications
5 * This is still in heavy developpement !
6 *
7 * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
8 * http://royale.zerezo.com/zr364xx/
9 *
10 * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
11 * V4L2 version inspired by meye.c driver
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/usb.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/proc_fs.h>
Antoine Jacquet2575f842007-03-05 06:32:29 -030036#include <linux/highmem.h>
Antoine Jacquetb7eee612007-04-27 12:30:59 -030037#include <media/v4l2-common.h>
38
39
40/* Version Information */
41#define DRIVER_VERSION "v0.72"
42#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
43#define DRIVER_DESC "Zoran 364xx"
44
45
46/* Camera */
47#define FRAMES 2
48#define MAX_FRAME_SIZE 100000
49#define BUFFER_SIZE 0x1000
50#define CTRL_TIMEOUT 500
51
52
53/* Debug macro */
54#define DBG(x...) if (debug) info(x)
55
56
57/* Init methods, need to find nicer names for these
58 * the exact names of the chipsets would be the best if someone finds it */
59#define METHOD0 0
60#define METHOD1 1
61#define METHOD2 2
62
63
64/* Module parameters */
65static int debug = 0;
66static int mode = 0;
67
68
69/* Module parameters interface */
70module_param(debug, int, 0644);
71MODULE_PARM_DESC(debug, "Debug level");
72module_param(mode, int, 0644);
73MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480");
74
75
76/* Devices supported by this driver
77 * .driver_info contains the init method used by the camera */
78static struct usb_device_id device_table[] = {
79 {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 },
80 {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 },
81 {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 },
82 {USB_DEVICE(0x0546, 0x3187), .driver_info = METHOD0 },
83 {USB_DEVICE(0x0d64, 0x3108), .driver_info = METHOD0 },
84 {USB_DEVICE(0x0595, 0x4343), .driver_info = METHOD0 },
85 {USB_DEVICE(0x0bb0, 0x500d), .driver_info = METHOD0 },
86 {USB_DEVICE(0x0feb, 0x2004), .driver_info = METHOD0 },
87 {USB_DEVICE(0x055f, 0xb500), .driver_info = METHOD0 },
88 {USB_DEVICE(0x08ca, 0x2062), .driver_info = METHOD2 },
89 {USB_DEVICE(0x052b, 0x1a18), .driver_info = METHOD1 },
90 {USB_DEVICE(0x04c8, 0x0729), .driver_info = METHOD0 },
91 {USB_DEVICE(0x04f2, 0xa208), .driver_info = METHOD0 },
92 {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 },
93 {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
94 {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
Antoine Jacquetbebeaea2007-06-25 16:00:34 -030095 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
Antoine Jacquet71c04472008-01-25 22:01:53 -030096 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
Antoine Jacquetc0e0aff2008-01-25 22:03:10 -030097 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
Antoine Jacquetb7eee612007-04-27 12:30:59 -030098 {} /* Terminating entry */
99};
100
101MODULE_DEVICE_TABLE(usb, device_table);
102
103
104/* Camera stuff */
105struct zr364xx_camera {
106 struct usb_device *udev; /* save off the usb device pointer */
107 struct usb_interface *interface;/* the interface for this device */
108 struct video_device *vdev; /* v4l video device */
109 u8 *framebuf;
110 int nb;
111 unsigned char *buffer;
112 int skip;
113 int brightness;
114 int width;
115 int height;
116 int method;
117 struct mutex lock;
118};
119
120
121/* function used to send initialisation commands to the camera */
122static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
123 u16 index, unsigned char *cp, u16 size)
124{
125 int status;
126
127 unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
128 if (!transfer_buffer) {
129 info("kmalloc(%d) failed", size);
130 return -ENOMEM;
131 }
132
133 memcpy(transfer_buffer, cp, size);
134
135 status = usb_control_msg(udev,
136 usb_sndctrlpipe(udev, 0),
137 request,
138 USB_DIR_OUT | USB_TYPE_VENDOR |
139 USB_RECIP_DEVICE, value, index,
140 transfer_buffer, size, CTRL_TIMEOUT);
141
142 kfree(transfer_buffer);
143
144 if (status < 0)
145 info("Failed sending control message, error %d.", status);
146
147 return status;
148}
149
150
151/* Control messages sent to the camera to initialize it
152 * and launch the capture */
153typedef struct {
154 unsigned int value;
155 unsigned int size;
156 unsigned char *bytes;
157} message;
158
159/* method 0 */
160static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
161static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 };
162static unsigned char m0d3[] = { 0, 0 };
163static message m0[] = {
164 {0x1f30, 0, NULL},
165 {0xd000, 0, NULL},
166 {0x3370, sizeof(m0d1), m0d1},
167 {0x2000, 0, NULL},
168 {0x2f0f, 0, NULL},
169 {0x2610, sizeof(m0d2), m0d2},
170 {0xe107, 0, NULL},
171 {0x2502, 0, NULL},
172 {0x1f70, 0, NULL},
173 {0xd000, 0, NULL},
174 {0x9a01, sizeof(m0d3), m0d3},
175 {-1, -1, NULL}
176};
177
178/* method 1 */
179static unsigned char m1d1[] = { 0xff, 0xff };
180static unsigned char m1d2[] = { 0x00, 0x00 };
181static message m1[] = {
182 {0x1f30, 0, NULL},
183 {0xd000, 0, NULL},
184 {0xf000, 0, NULL},
185 {0x2000, 0, NULL},
186 {0x2f0f, 0, NULL},
187 {0x2650, 0, NULL},
188 {0xe107, 0, NULL},
189 {0x2502, sizeof(m1d1), m1d1},
190 {0x1f70, 0, NULL},
191 {0xd000, 0, NULL},
192 {0xd000, 0, NULL},
193 {0xd000, 0, NULL},
194 {0x9a01, sizeof(m1d2), m1d2},
195 {-1, -1, NULL}
196};
197
198/* method 2 */
199static unsigned char m2d1[] = { 0xff, 0xff };
200static message m2[] = {
201 {0x1f30, 0, NULL},
202 {0xf000, 0, NULL},
203 {0x2000, 0, NULL},
204 {0x2f0f, 0, NULL},
205 {0x2650, 0, NULL},
206 {0xe107, 0, NULL},
207 {0x2502, sizeof(m2d1), m2d1},
208 {0x1f70, 0, NULL},
209 {-1, -1, NULL}
210};
211
212/* init table */
213static message *init[3] = { m0, m1, m2 };
214
215
216/* JPEG static data in header (Huffman table, etc) */
217static unsigned char header1[] = {
218 0xFF, 0xD8,
219 /*
220 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
221 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
222 */
223 0xFF, 0xDB, 0x00, 0x84
224};
225static unsigned char header2[] = {
226 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
227 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
229 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
230 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
231 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
232 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
233 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
234 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
235 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
236 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
237 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
238 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
239 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
240 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
241 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
242 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
243 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
244 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
245 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
246 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
247 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
248 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
249 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
250 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
251 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
252 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
253 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
254 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
255 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
256 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
257 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
258 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
259 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
260 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
261 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
262 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
263 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
264 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
265 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
266 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
267 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
268 0x00, 0x3F, 0x00
269};
270static unsigned char header3;
271
272
273
274/********************/
275/* V4L2 integration */
276/********************/
277
278/* this function reads a full JPEG picture synchronously
279 * TODO: do it asynchronously... */
280static int read_frame(struct zr364xx_camera *cam, int framenum)
281{
282 int i, n, temp, head, size, actual_length;
Trent Piepho93566ad2007-03-07 18:19:49 -0300283 unsigned char *ptr = NULL, *jpeg;
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300284
285 redo:
286 /* hardware brightness */
287 n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
288 temp = (0x60 << 8) + 127 - cam->brightness;
289 n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
290
291 /* during the first loop we are going to insert JPEG header */
292 head = 0;
293 /* this is the place in memory where we are going to build
294 * the JPEG image */
295 jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
296 /* read data... */
297 do {
298 n = usb_bulk_msg(cam->udev,
299 usb_rcvbulkpipe(cam->udev, 0x81),
300 cam->buffer, BUFFER_SIZE, &actual_length,
301 CTRL_TIMEOUT);
302 DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
303 DBG("bulk : n=%d size=%d", n, actual_length);
304 if (n < 0) {
305 info("error reading bulk msg");
306 return 0;
307 }
308 if (actual_length < 0 || actual_length > BUFFER_SIZE) {
309 info("wrong number of bytes");
310 return 0;
311 }
312
313 /* swap bytes if camera needs it */
Trent Piepho93566ad2007-03-07 18:19:49 -0300314 if (cam->method == METHOD0) {
315 u16 *buf = (u16*)cam->buffer;
316 for (i = 0; i < BUFFER_SIZE/2; i++)
317 swab16s(buf + i);
318 }
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300319
320 /* write the JPEG header */
321 if (!head) {
322 DBG("jpeg header");
323 ptr = jpeg;
324 memcpy(ptr, header1, sizeof(header1));
325 ptr += sizeof(header1);
326 header3 = 0;
327 memcpy(ptr, &header3, 1);
328 ptr++;
329 memcpy(ptr, cam->buffer, 64);
330 ptr += 64;
331 header3 = 1;
332 memcpy(ptr, &header3, 1);
333 ptr++;
334 memcpy(ptr, cam->buffer + 64, 64);
335 ptr += 64;
336 memcpy(ptr, header2, sizeof(header2));
337 ptr += sizeof(header2);
338 memcpy(ptr, cam->buffer + 128,
339 actual_length - 128);
340 ptr += actual_length - 128;
341 head = 1;
342 DBG("header : %d %d %d %d %d %d %d %d %d",
343 cam->buffer[0], cam->buffer[1], cam->buffer[2],
344 cam->buffer[3], cam->buffer[4], cam->buffer[5],
345 cam->buffer[6], cam->buffer[7], cam->buffer[8]);
346 } else {
347 memcpy(ptr, cam->buffer, actual_length);
348 ptr += actual_length;
349 }
350 }
351 /* ... until there is no more */
352 while (actual_length == BUFFER_SIZE);
353
354 /* we skip the 2 first frames which are usually buggy */
355 if (cam->skip) {
356 cam->skip--;
357 goto redo;
358 }
359
360 /* go back to find the JPEG EOI marker */
361 size = ptr - jpeg;
362 ptr -= 2;
363 while (ptr > jpeg) {
364 if (*ptr == 0xFF && *(ptr + 1) == 0xD9
365 && *(ptr + 2) == 0xFF)
366 break;
367 ptr--;
368 }
369 if (ptr == jpeg)
370 DBG("No EOI marker");
371
372 /* Sometimes there is junk data in the middle of the picture,
373 * we want to skip this bogus frames */
374 while (ptr > jpeg) {
375 if (*ptr == 0xFF && *(ptr + 1) == 0xFF
376 && *(ptr + 2) == 0xFF)
377 break;
378 ptr--;
379 }
380 if (ptr != jpeg) {
381 DBG("Bogus frame ? %d", cam->nb);
382 goto redo;
383 }
384
385 DBG("jpeg : %d %d %d %d %d %d %d %d",
386 jpeg[0], jpeg[1], jpeg[2], jpeg[3],
387 jpeg[4], jpeg[5], jpeg[6], jpeg[7]);
388
389 return size;
390}
391
392
Al Viro97cf0102008-03-29 03:10:48 +0000393static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300394 loff_t * ppos)
395{
396 unsigned long count = cnt;
397 struct video_device *vdev = video_devdata(file);
398 struct zr364xx_camera *cam;
399
400 DBG("zr364xx_read: read %d bytes.", (int) count);
401
402 if (vdev == NULL)
403 return -ENODEV;
404 cam = video_get_drvdata(vdev);
405
406 if (!buf)
407 return -EINVAL;
408
409 if (!count)
410 return -EINVAL;
411
412 /* NoMan Sux ! */
413 count = read_frame(cam, 0);
414
415 if (copy_to_user(buf, cam->framebuf, count))
416 return -EFAULT;
417
418 return count;
419}
420
421
422static int zr364xx_vidioc_querycap(struct file *file, void *priv,
423 struct v4l2_capability *cap)
424{
425 memset(cap, 0, sizeof(*cap));
426 strcpy(cap->driver, DRIVER_DESC);
427 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
428 return 0;
429}
430
431static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
432 struct v4l2_input *i)
433{
434 if (i->index != 0)
435 return -EINVAL;
436 memset(i, 0, sizeof(*i));
437 i->index = 0;
438 strcpy(i->name, DRIVER_DESC " Camera");
439 i->type = V4L2_INPUT_TYPE_CAMERA;
440 return 0;
441}
442
443static int zr364xx_vidioc_g_input(struct file *file, void *priv,
444 unsigned int *i)
445{
446 *i = 0;
447 return 0;
448}
449
450static int zr364xx_vidioc_s_input(struct file *file, void *priv,
451 unsigned int i)
452{
453 if (i != 0)
454 return -EINVAL;
455 return 0;
456}
457
458static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
459 struct v4l2_queryctrl *c)
460{
461 struct video_device *vdev = video_devdata(file);
462 struct zr364xx_camera *cam;
463
464 if (vdev == NULL)
465 return -ENODEV;
466 cam = video_get_drvdata(vdev);
467
468 switch (c->id) {
469 case V4L2_CID_BRIGHTNESS:
470 c->type = V4L2_CTRL_TYPE_INTEGER;
471 strcpy(c->name, "Brightness");
472 c->minimum = 0;
473 c->maximum = 127;
474 c->step = 1;
475 c->default_value = cam->brightness;
476 c->flags = 0;
477 break;
478 default:
479 return -EINVAL;
480 }
481 return 0;
482}
483
484static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv,
485 struct v4l2_control *c)
486{
487 struct video_device *vdev = video_devdata(file);
488 struct zr364xx_camera *cam;
489
490 if (vdev == NULL)
491 return -ENODEV;
492 cam = video_get_drvdata(vdev);
493
494 switch (c->id) {
495 case V4L2_CID_BRIGHTNESS:
496 cam->brightness = c->value;
497 break;
498 default:
499 return -EINVAL;
500 }
501 return 0;
502}
503
504static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
505 struct v4l2_control *c)
506{
507 struct video_device *vdev = video_devdata(file);
508 struct zr364xx_camera *cam;
509
510 if (vdev == NULL)
511 return -ENODEV;
512 cam = video_get_drvdata(vdev);
513
514 switch (c->id) {
515 case V4L2_CID_BRIGHTNESS:
516 c->value = cam->brightness;
517 break;
518 default:
519 return -EINVAL;
520 }
521 return 0;
522}
523
524static int zr364xx_vidioc_enum_fmt_cap(struct file *file,
525 void *priv, struct v4l2_fmtdesc *f)
526{
527 if (f->index > 0)
528 return -EINVAL;
529 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
530 return -EINVAL;
531 memset(f, 0, sizeof(*f));
532 f->index = 0;
533 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
534 f->flags = V4L2_FMT_FLAG_COMPRESSED;
535 strcpy(f->description, "JPEG");
536 f->pixelformat = V4L2_PIX_FMT_JPEG;
537 return 0;
538}
539
540static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv,
541 struct v4l2_format *f)
542{
543 struct video_device *vdev = video_devdata(file);
544 struct zr364xx_camera *cam;
545
546 if (vdev == NULL)
547 return -ENODEV;
548 cam = video_get_drvdata(vdev);
549
550 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
551 return -EINVAL;
552 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
553 return -EINVAL;
554 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
555 f->fmt.pix.field != V4L2_FIELD_NONE)
556 return -EINVAL;
557 f->fmt.pix.field = V4L2_FIELD_NONE;
558 f->fmt.pix.width = cam->width;
559 f->fmt.pix.height = cam->height;
560 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
561 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
562 f->fmt.pix.colorspace = 0;
563 f->fmt.pix.priv = 0;
564 return 0;
565}
566
567static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv,
568 struct v4l2_format *f)
569{
570 struct video_device *vdev = video_devdata(file);
571 struct zr364xx_camera *cam;
572
573 if (vdev == NULL)
574 return -ENODEV;
575 cam = video_get_drvdata(vdev);
576
577 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
578 return -EINVAL;
579 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
580 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
581 f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
582 f->fmt.pix.field = V4L2_FIELD_NONE;
583 f->fmt.pix.width = cam->width;
584 f->fmt.pix.height = cam->height;
585 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
586 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
587 f->fmt.pix.colorspace = 0;
588 f->fmt.pix.priv = 0;
589 return 0;
590}
591
592static int zr364xx_vidioc_s_fmt_cap(struct file *file, void *priv,
593 struct v4l2_format *f)
594{
595 struct video_device *vdev = video_devdata(file);
596 struct zr364xx_camera *cam;
597
598 if (vdev == NULL)
599 return -ENODEV;
600 cam = video_get_drvdata(vdev);
601
602 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
603 return -EINVAL;
604 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
605 return -EINVAL;
606 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
607 f->fmt.pix.field != V4L2_FIELD_NONE)
608 return -EINVAL;
609 f->fmt.pix.field = V4L2_FIELD_NONE;
610 f->fmt.pix.width = cam->width;
611 f->fmt.pix.height = cam->height;
612 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
613 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
614 f->fmt.pix.colorspace = 0;
615 f->fmt.pix.priv = 0;
616 DBG("ok!");
617 return 0;
618}
619
620static int zr364xx_vidioc_streamon(struct file *file, void *priv,
621 enum v4l2_buf_type type)
622{
623 return 0;
624}
625
626static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
627 enum v4l2_buf_type type)
628{
629 return 0;
630}
631
632
633/* open the camera */
634static int zr364xx_open(struct inode *inode, struct file *file)
635{
636 struct video_device *vdev = video_devdata(file);
637 struct zr364xx_camera *cam = video_get_drvdata(vdev);
638 struct usb_device *udev = cam->udev;
639 int i, err;
640
641 DBG("zr364xx_open");
642
643 cam->skip = 2;
644
645 err = video_exclusive_open(inode, file);
646 if (err < 0)
647 return err;
648
649 if (!cam->framebuf) {
650 cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
651 if (!cam->framebuf) {
652 info("vmalloc_32 failed!");
653 return -ENOMEM;
654 }
655 }
656
657 mutex_lock(&cam->lock);
658 for (i = 0; init[cam->method][i].size != -1; i++) {
659 err =
660 send_control_msg(udev, 1, init[cam->method][i].value,
661 0, init[cam->method][i].bytes,
662 init[cam->method][i].size);
663 if (err < 0) {
664 info("error during open sequence: %d", i);
665 mutex_unlock(&cam->lock);
666 return err;
667 }
668 }
669
670 file->private_data = vdev;
671
672 /* Added some delay here, since opening/closing the camera quickly,
673 * like Ekiga does during its startup, can crash the webcam
674 */
675 mdelay(100);
676
677 mutex_unlock(&cam->lock);
678 return 0;
679}
680
681
682/* release the camera */
683static int zr364xx_release(struct inode *inode, struct file *file)
684{
685 struct video_device *vdev = video_devdata(file);
686 struct zr364xx_camera *cam;
687 struct usb_device *udev;
688 int i, err;
689
690 DBG("zr364xx_release");
691
692 if (vdev == NULL)
693 return -ENODEV;
694 cam = video_get_drvdata(vdev);
695
696 udev = cam->udev;
697
698 mutex_lock(&cam->lock);
699 for (i = 0; i < 2; i++) {
700 err =
701 send_control_msg(udev, 1, init[cam->method][i].value,
702 0, init[i][cam->method].bytes,
703 init[cam->method][i].size);
704 if (err < 0) {
705 info("error during release sequence");
706 mutex_unlock(&cam->lock);
707 return err;
708 }
709 }
710
711 file->private_data = NULL;
712 video_exclusive_release(inode, file);
713
714 /* Added some delay here, since opening/closing the camera quickly,
715 * like Ekiga does during its startup, can crash the webcam
716 */
717 mdelay(100);
718
719 mutex_unlock(&cam->lock);
720 return 0;
721}
722
723
724static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
725{
726 void *pos;
727 unsigned long start = vma->vm_start;
728 unsigned long size = vma->vm_end - vma->vm_start;
729 struct video_device *vdev = video_devdata(file);
730 struct zr364xx_camera *cam;
731
732 DBG("zr364xx_mmap: %ld\n", size);
733
734 if (vdev == NULL)
735 return -ENODEV;
736 cam = video_get_drvdata(vdev);
737
738 pos = cam->framebuf;
739 while (size > 0) {
740 if (vm_insert_page(vma, start, vmalloc_to_page(pos)))
741 return -EAGAIN;
742 start += PAGE_SIZE;
743 pos += PAGE_SIZE;
744 if (size > PAGE_SIZE)
745 size -= PAGE_SIZE;
746 else
747 size = 0;
748 }
749
750 return 0;
751}
752
753
Douglas Schilling Landgrafbdd36652007-10-29 00:37:07 -0300754static const struct file_operations zr364xx_fops = {
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300755 .owner = THIS_MODULE,
756 .open = zr364xx_open,
757 .release = zr364xx_release,
758 .read = zr364xx_read,
759 .mmap = zr364xx_mmap,
760 .ioctl = video_ioctl2,
761 .llseek = no_llseek,
762};
763
764static struct video_device zr364xx_template = {
765 .owner = THIS_MODULE,
766 .name = DRIVER_DESC,
767 .type = VID_TYPE_CAPTURE,
768 .fops = &zr364xx_fops,
769 .release = video_device_release,
770 .minor = -1,
771
772 .vidioc_querycap = zr364xx_vidioc_querycap,
773 .vidioc_enum_fmt_cap = zr364xx_vidioc_enum_fmt_cap,
774 .vidioc_try_fmt_cap = zr364xx_vidioc_try_fmt_cap,
775 .vidioc_s_fmt_cap = zr364xx_vidioc_s_fmt_cap,
776 .vidioc_g_fmt_cap = zr364xx_vidioc_g_fmt_cap,
777 .vidioc_enum_input = zr364xx_vidioc_enum_input,
778 .vidioc_g_input = zr364xx_vidioc_g_input,
779 .vidioc_s_input = zr364xx_vidioc_s_input,
780 .vidioc_streamon = zr364xx_vidioc_streamon,
781 .vidioc_streamoff = zr364xx_vidioc_streamoff,
782 .vidioc_queryctrl = zr364xx_vidioc_queryctrl,
783 .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl,
784 .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl,
785};
786
787
788
789/*******************/
790/* USB integration */
791/*******************/
792
793static int zr364xx_probe(struct usb_interface *intf,
794 const struct usb_device_id *id)
795{
796 struct usb_device *udev = interface_to_usbdev(intf);
797 struct zr364xx_camera *cam = NULL;
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300798 int err;
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300799
800 DBG("probing...");
801
802 info(DRIVER_DESC " compatible webcam plugged");
803 info("model %04x:%04x detected", udev->descriptor.idVendor,
804 udev->descriptor.idProduct);
805
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300806 cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL);
807 if (cam == NULL) {
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300808 info("cam: out of memory !");
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300809 return -ENOMEM;
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300810 }
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300811 /* save the init method used by this camera */
812 cam->method = id->driver_info;
813
814 cam->vdev = video_device_alloc();
815 if (cam->vdev == NULL) {
816 info("cam->vdev: out of memory !");
817 kfree(cam);
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300818 return -ENOMEM;
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300819 }
820 memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template));
821 video_set_drvdata(cam->vdev, cam);
822 if (debug)
823 cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
824
825 cam->udev = udev;
826
827 if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) {
828 info("cam->buffer: out of memory !");
829 video_device_release(cam->vdev);
830 kfree(cam);
831 return -ENODEV;
832 }
833
834 switch (mode) {
835 case 1:
836 info("160x120 mode selected");
837 cam->width = 160;
838 cam->height = 120;
839 break;
840 case 2:
841 info("640x480 mode selected");
842 cam->width = 640;
843 cam->height = 480;
844 break;
845 default:
846 info("320x240 mode selected");
847 cam->width = 320;
848 cam->height = 240;
849 break;
850 }
851
852 m0d1[0] = mode;
853 m1[2].value = 0xf000 + mode;
854 m2[1].value = 0xf000 + mode;
855 header2[437] = cam->height / 256;
856 header2[438] = cam->height % 256;
857 header2[439] = cam->width / 256;
858 header2[440] = cam->width % 256;
859
860 cam->nb = 0;
861 cam->brightness = 64;
862 mutex_init(&cam->lock);
863
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300864 err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1);
865 if (err) {
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300866 info("video_register_device failed");
867 video_device_release(cam->vdev);
868 kfree(cam->buffer);
869 kfree(cam);
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300870 return err;
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300871 }
872
873 usb_set_intfdata(intf, cam);
874
875 info(DRIVER_DESC " controlling video device %d", cam->vdev->minor);
876 return 0;
877}
878
879
880static void zr364xx_disconnect(struct usb_interface *intf)
881{
882 struct zr364xx_camera *cam = usb_get_intfdata(intf);
883 usb_set_intfdata(intf, NULL);
884 dev_set_drvdata(&intf->dev, NULL);
885 info(DRIVER_DESC " webcam unplugged");
886 if (cam->vdev)
887 video_unregister_device(cam->vdev);
888 cam->vdev = NULL;
889 kfree(cam->buffer);
890 if (cam->framebuf)
891 vfree(cam->framebuf);
892 kfree(cam);
893}
894
895
896
897/**********************/
898/* Module integration */
899/**********************/
900
901static struct usb_driver zr364xx_driver = {
902 .name = "zr364xx",
903 .probe = zr364xx_probe,
904 .disconnect = zr364xx_disconnect,
905 .id_table = device_table
906};
907
908
909static int __init zr364xx_init(void)
910{
911 int retval;
Akinobu Mita783aa8f2007-05-20 09:12:10 -0300912 retval = usb_register(&zr364xx_driver);
Antoine Jacquetb7eee612007-04-27 12:30:59 -0300913 if (retval)
914 info("usb_register failed!");
915 else
916 info(DRIVER_DESC " module loaded");
917 return retval;
918}
919
920
921static void __exit zr364xx_exit(void)
922{
923 info(DRIVER_DESC " module unloaded");
924 usb_deregister(&zr364xx_driver);
925}
926
927
928module_init(zr364xx_init);
929module_exit(zr364xx_exit);
930
931MODULE_AUTHOR(DRIVER_AUTHOR);
932MODULE_DESCRIPTION(DRIVER_DESC);
933MODULE_LICENSE("GPL");