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