2 * Zoran 364xx based USB webcam module version 0.72
4 * Allows you to use your USB webcam with V4L2 applications
5 * This is still in heavy developpement !
7 * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
8 * http://royale.zerezo.com/zr364xx/
10 * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
11 * V4L2 version inspired by meye.c driver
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.
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.
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
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>
36 #include <linux/highmem.h>
37 #include <media/v4l2-common.h>
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"
48 #define MAX_FRAME_SIZE 100000
49 #define BUFFER_SIZE 0x1000
50 #define CTRL_TIMEOUT 500
54 #define DBG(x...) if (debug) info(x)
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 */
64 /* Module parameters */
69 /* Module parameters interface */
70 module_param(debug, int, 0644);
71 MODULE_PARM_DESC(debug, "Debug level");
72 module_param(mode, int, 0644);
73 MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480");
76 /* Devices supported by this driver
77 * .driver_info contains the init method used by the camera */
78 static 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 },
95 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
96 {} /* Terminating entry */
99 MODULE_DEVICE_TABLE(usb, device_table);
103 struct zr364xx_camera {
104 struct usb_device *udev; /* save off the usb device pointer */
105 struct usb_interface *interface;/* the interface for this device */
106 struct video_device *vdev; /* v4l video device */
109 unsigned char *buffer;
119 /* function used to send initialisation commands to the camera */
120 static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
121 u16 index, unsigned char *cp, u16 size)
125 unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
126 if (!transfer_buffer) {
127 info("kmalloc(%d) failed", size);
131 memcpy(transfer_buffer, cp, size);
133 status = usb_control_msg(udev,
134 usb_sndctrlpipe(udev, 0),
136 USB_DIR_OUT | USB_TYPE_VENDOR |
137 USB_RECIP_DEVICE, value, index,
138 transfer_buffer, size, CTRL_TIMEOUT);
140 kfree(transfer_buffer);
143 info("Failed sending control message, error %d.", status);
149 /* Control messages sent to the camera to initialize it
150 * and launch the capture */
154 unsigned char *bytes;
158 static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
159 static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 };
160 static unsigned char m0d3[] = { 0, 0 };
161 static message m0[] = {
164 {0x3370, sizeof(m0d1), m0d1},
167 {0x2610, sizeof(m0d2), m0d2},
172 {0x9a01, sizeof(m0d3), m0d3},
177 static unsigned char m1d1[] = { 0xff, 0xff };
178 static unsigned char m1d2[] = { 0x00, 0x00 };
179 static message m1[] = {
187 {0x2502, sizeof(m1d1), m1d1},
192 {0x9a01, sizeof(m1d2), m1d2},
197 static unsigned char m2d1[] = { 0xff, 0xff };
198 static message m2[] = {
205 {0x2502, sizeof(m2d1), m2d1},
211 static message *init[3] = { m0, m1, m2 };
214 /* JPEG static data in header (Huffman table, etc) */
215 static unsigned char header1[] = {
218 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
219 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
221 0xFF, 0xDB, 0x00, 0x84
223 static unsigned char header2[] = {
224 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
225 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
227 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
228 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
229 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
230 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
231 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
232 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
233 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
234 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
235 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
236 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
237 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
238 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
239 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
240 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
241 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
242 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
243 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
244 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
245 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
246 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
247 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
248 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
249 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
250 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
251 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
252 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
253 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
254 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
255 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
256 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
257 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
258 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
259 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
260 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
261 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
262 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
263 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
264 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
265 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
268 static unsigned char header3;
272 /********************/
273 /* V4L2 integration */
274 /********************/
276 /* this function reads a full JPEG picture synchronously
277 * TODO: do it asynchronously... */
278 static int read_frame(struct zr364xx_camera *cam, int framenum)
280 int i, n, temp, head, size, actual_length;
281 unsigned char *ptr = NULL, *jpeg;
284 /* hardware brightness */
285 n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
286 temp = (0x60 << 8) + 127 - cam->brightness;
287 n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
289 /* during the first loop we are going to insert JPEG header */
291 /* this is the place in memory where we are going to build
293 jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
296 n = usb_bulk_msg(cam->udev,
297 usb_rcvbulkpipe(cam->udev, 0x81),
298 cam->buffer, BUFFER_SIZE, &actual_length,
300 DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
301 DBG("bulk : n=%d size=%d", n, actual_length);
303 info("error reading bulk msg");
306 if (actual_length < 0 || actual_length > BUFFER_SIZE) {
307 info("wrong number of bytes");
311 /* swap bytes if camera needs it */
312 if (cam->method == METHOD0) {
313 u16 *buf = (u16*)cam->buffer;
314 for (i = 0; i < BUFFER_SIZE/2; i++)
318 /* write the JPEG header */
322 memcpy(ptr, header1, sizeof(header1));
323 ptr += sizeof(header1);
325 memcpy(ptr, &header3, 1);
327 memcpy(ptr, cam->buffer, 64);
330 memcpy(ptr, &header3, 1);
332 memcpy(ptr, cam->buffer + 64, 64);
334 memcpy(ptr, header2, sizeof(header2));
335 ptr += sizeof(header2);
336 memcpy(ptr, cam->buffer + 128,
337 actual_length - 128);
338 ptr += actual_length - 128;
340 DBG("header : %d %d %d %d %d %d %d %d %d",
341 cam->buffer[0], cam->buffer[1], cam->buffer[2],
342 cam->buffer[3], cam->buffer[4], cam->buffer[5],
343 cam->buffer[6], cam->buffer[7], cam->buffer[8]);
345 memcpy(ptr, cam->buffer, actual_length);
346 ptr += actual_length;
349 /* ... until there is no more */
350 while (actual_length == BUFFER_SIZE);
352 /* we skip the 2 first frames which are usually buggy */
358 /* go back to find the JPEG EOI marker */
362 if (*ptr == 0xFF && *(ptr + 1) == 0xD9
363 && *(ptr + 2) == 0xFF)
368 DBG("No EOI marker");
370 /* Sometimes there is junk data in the middle of the picture,
371 * we want to skip this bogus frames */
373 if (*ptr == 0xFF && *(ptr + 1) == 0xFF
374 && *(ptr + 2) == 0xFF)
379 DBG("Bogus frame ? %d", cam->nb);
383 DBG("jpeg : %d %d %d %d %d %d %d %d",
384 jpeg[0], jpeg[1], jpeg[2], jpeg[3],
385 jpeg[4], jpeg[5], jpeg[6], jpeg[7]);
391 static ssize_t zr364xx_read(struct file *file, char *buf, size_t cnt,
394 unsigned long count = cnt;
395 struct video_device *vdev = video_devdata(file);
396 struct zr364xx_camera *cam;
398 DBG("zr364xx_read: read %d bytes.", (int) count);
402 cam = video_get_drvdata(vdev);
411 count = read_frame(cam, 0);
413 if (copy_to_user(buf, cam->framebuf, count))
420 static int zr364xx_vidioc_querycap(struct file *file, void *priv,
421 struct v4l2_capability *cap)
423 memset(cap, 0, sizeof(*cap));
424 strcpy(cap->driver, DRIVER_DESC);
425 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
429 static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
430 struct v4l2_input *i)
434 memset(i, 0, sizeof(*i));
436 strcpy(i->name, DRIVER_DESC " Camera");
437 i->type = V4L2_INPUT_TYPE_CAMERA;
441 static int zr364xx_vidioc_g_input(struct file *file, void *priv,
448 static int zr364xx_vidioc_s_input(struct file *file, void *priv,
456 static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
457 struct v4l2_queryctrl *c)
459 struct video_device *vdev = video_devdata(file);
460 struct zr364xx_camera *cam;
464 cam = video_get_drvdata(vdev);
467 case V4L2_CID_BRIGHTNESS:
468 c->type = V4L2_CTRL_TYPE_INTEGER;
469 strcpy(c->name, "Brightness");
473 c->default_value = cam->brightness;
482 static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv,
483 struct v4l2_control *c)
485 struct video_device *vdev = video_devdata(file);
486 struct zr364xx_camera *cam;
490 cam = video_get_drvdata(vdev);
493 case V4L2_CID_BRIGHTNESS:
494 cam->brightness = c->value;
502 static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
503 struct v4l2_control *c)
505 struct video_device *vdev = video_devdata(file);
506 struct zr364xx_camera *cam;
510 cam = video_get_drvdata(vdev);
513 case V4L2_CID_BRIGHTNESS:
514 c->value = cam->brightness;
522 static int zr364xx_vidioc_enum_fmt_cap(struct file *file,
523 void *priv, struct v4l2_fmtdesc *f)
527 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
529 memset(f, 0, sizeof(*f));
531 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
532 f->flags = V4L2_FMT_FLAG_COMPRESSED;
533 strcpy(f->description, "JPEG");
534 f->pixelformat = V4L2_PIX_FMT_JPEG;
538 static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv,
539 struct v4l2_format *f)
541 struct video_device *vdev = video_devdata(file);
542 struct zr364xx_camera *cam;
546 cam = video_get_drvdata(vdev);
548 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
550 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
552 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
553 f->fmt.pix.field != V4L2_FIELD_NONE)
555 f->fmt.pix.field = V4L2_FIELD_NONE;
556 f->fmt.pix.width = cam->width;
557 f->fmt.pix.height = cam->height;
558 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
559 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
560 f->fmt.pix.colorspace = 0;
565 static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv,
566 struct v4l2_format *f)
568 struct video_device *vdev = video_devdata(file);
569 struct zr364xx_camera *cam;
573 cam = video_get_drvdata(vdev);
575 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
577 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
578 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
579 f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
580 f->fmt.pix.field = V4L2_FIELD_NONE;
581 f->fmt.pix.width = cam->width;
582 f->fmt.pix.height = cam->height;
583 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
584 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
585 f->fmt.pix.colorspace = 0;
590 static int zr364xx_vidioc_s_fmt_cap(struct file *file, void *priv,
591 struct v4l2_format *f)
593 struct video_device *vdev = video_devdata(file);
594 struct zr364xx_camera *cam;
598 cam = video_get_drvdata(vdev);
600 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
602 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
604 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
605 f->fmt.pix.field != V4L2_FIELD_NONE)
607 f->fmt.pix.field = V4L2_FIELD_NONE;
608 f->fmt.pix.width = cam->width;
609 f->fmt.pix.height = cam->height;
610 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
611 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
612 f->fmt.pix.colorspace = 0;
618 static int zr364xx_vidioc_streamon(struct file *file, void *priv,
619 enum v4l2_buf_type type)
624 static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
625 enum v4l2_buf_type type)
631 /* open the camera */
632 static int zr364xx_open(struct inode *inode, struct file *file)
634 struct video_device *vdev = video_devdata(file);
635 struct zr364xx_camera *cam = video_get_drvdata(vdev);
636 struct usb_device *udev = cam->udev;
643 err = video_exclusive_open(inode, file);
647 if (!cam->framebuf) {
648 cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
649 if (!cam->framebuf) {
650 info("vmalloc_32 failed!");
655 mutex_lock(&cam->lock);
656 for (i = 0; init[cam->method][i].size != -1; i++) {
658 send_control_msg(udev, 1, init[cam->method][i].value,
659 0, init[cam->method][i].bytes,
660 init[cam->method][i].size);
662 info("error during open sequence: %d", i);
663 mutex_unlock(&cam->lock);
668 file->private_data = vdev;
670 /* Added some delay here, since opening/closing the camera quickly,
671 * like Ekiga does during its startup, can crash the webcam
675 mutex_unlock(&cam->lock);
680 /* release the camera */
681 static int zr364xx_release(struct inode *inode, struct file *file)
683 struct video_device *vdev = video_devdata(file);
684 struct zr364xx_camera *cam;
685 struct usb_device *udev;
688 DBG("zr364xx_release");
692 cam = video_get_drvdata(vdev);
696 mutex_lock(&cam->lock);
697 for (i = 0; i < 2; i++) {
699 send_control_msg(udev, 1, init[cam->method][i].value,
700 0, init[i][cam->method].bytes,
701 init[cam->method][i].size);
703 info("error during release sequence");
704 mutex_unlock(&cam->lock);
709 file->private_data = NULL;
710 video_exclusive_release(inode, file);
712 /* Added some delay here, since opening/closing the camera quickly,
713 * like Ekiga does during its startup, can crash the webcam
717 mutex_unlock(&cam->lock);
722 static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
725 unsigned long start = vma->vm_start;
726 unsigned long size = vma->vm_end - vma->vm_start;
727 struct video_device *vdev = video_devdata(file);
728 struct zr364xx_camera *cam;
730 DBG("zr364xx_mmap: %ld\n", size);
734 cam = video_get_drvdata(vdev);
738 if (vm_insert_page(vma, start, vmalloc_to_page(pos)))
742 if (size > PAGE_SIZE)
752 static const struct file_operations zr364xx_fops = {
753 .owner = THIS_MODULE,
754 .open = zr364xx_open,
755 .release = zr364xx_release,
756 .read = zr364xx_read,
757 .mmap = zr364xx_mmap,
758 .ioctl = video_ioctl2,
762 static struct video_device zr364xx_template = {
763 .owner = THIS_MODULE,
765 .type = VID_TYPE_CAPTURE,
766 .fops = &zr364xx_fops,
767 .release = video_device_release,
770 .vidioc_querycap = zr364xx_vidioc_querycap,
771 .vidioc_enum_fmt_cap = zr364xx_vidioc_enum_fmt_cap,
772 .vidioc_try_fmt_cap = zr364xx_vidioc_try_fmt_cap,
773 .vidioc_s_fmt_cap = zr364xx_vidioc_s_fmt_cap,
774 .vidioc_g_fmt_cap = zr364xx_vidioc_g_fmt_cap,
775 .vidioc_enum_input = zr364xx_vidioc_enum_input,
776 .vidioc_g_input = zr364xx_vidioc_g_input,
777 .vidioc_s_input = zr364xx_vidioc_s_input,
778 .vidioc_streamon = zr364xx_vidioc_streamon,
779 .vidioc_streamoff = zr364xx_vidioc_streamoff,
780 .vidioc_queryctrl = zr364xx_vidioc_queryctrl,
781 .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl,
782 .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl,
787 /*******************/
788 /* USB integration */
789 /*******************/
791 static int zr364xx_probe(struct usb_interface *intf,
792 const struct usb_device_id *id)
794 struct usb_device *udev = interface_to_usbdev(intf);
795 struct zr364xx_camera *cam = NULL;
800 info(DRIVER_DESC " compatible webcam plugged");
801 info("model %04x:%04x detected", udev->descriptor.idVendor,
802 udev->descriptor.idProduct);
804 cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL);
806 info("cam: out of memory !");
809 /* save the init method used by this camera */
810 cam->method = id->driver_info;
812 cam->vdev = video_device_alloc();
813 if (cam->vdev == NULL) {
814 info("cam->vdev: out of memory !");
818 memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template));
819 video_set_drvdata(cam->vdev, cam);
821 cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
825 if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) {
826 info("cam->buffer: out of memory !");
827 video_device_release(cam->vdev);
834 info("160x120 mode selected");
839 info("640x480 mode selected");
844 info("320x240 mode selected");
851 m1[2].value = 0xf000 + mode;
852 m2[1].value = 0xf000 + mode;
853 header2[437] = cam->height / 256;
854 header2[438] = cam->height % 256;
855 header2[439] = cam->width / 256;
856 header2[440] = cam->width % 256;
859 cam->brightness = 64;
860 mutex_init(&cam->lock);
862 err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1);
864 info("video_register_device failed");
865 video_device_release(cam->vdev);
871 usb_set_intfdata(intf, cam);
873 info(DRIVER_DESC " controlling video device %d", cam->vdev->minor);
878 static void zr364xx_disconnect(struct usb_interface *intf)
880 struct zr364xx_camera *cam = usb_get_intfdata(intf);
881 usb_set_intfdata(intf, NULL);
882 dev_set_drvdata(&intf->dev, NULL);
883 info(DRIVER_DESC " webcam unplugged");
885 video_unregister_device(cam->vdev);
889 vfree(cam->framebuf);
895 /**********************/
896 /* Module integration */
897 /**********************/
899 static struct usb_driver zr364xx_driver = {
901 .probe = zr364xx_probe,
902 .disconnect = zr364xx_disconnect,
903 .id_table = device_table
907 static int __init zr364xx_init(void)
910 retval = usb_register(&zr364xx_driver);
912 info("usb_register failed!");
914 info(DRIVER_DESC " module loaded");
919 static void __exit zr364xx_exit(void)
921 info(DRIVER_DESC " module unloaded");
922 usb_deregister(&zr364xx_driver);
926 module_init(zr364xx_init);
927 module_exit(zr364xx_exit);
929 MODULE_AUTHOR(DRIVER_AUTHOR);
930 MODULE_DESCRIPTION(DRIVER_DESC);
931 MODULE_LICENSE("GPL");