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 <media/v4l2-common.h>
39 /* Version Information */
40 #define DRIVER_VERSION "v0.72"
41 #define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
42 #define DRIVER_DESC "Zoran 364xx"
47 #define MAX_FRAME_SIZE 100000
48 #define BUFFER_SIZE 0x1000
49 #define CTRL_TIMEOUT 500
53 #define DBG(x...) if (debug) info(x)
56 /* Init methods, need to find nicer names for these
57 * the exact names of the chipsets would be the best if someone finds it */
63 /* Module parameters */
68 /* Module parameters interface */
69 module_param(debug
, int, 0644);
70 MODULE_PARM_DESC(debug
, "Debug level");
71 module_param(mode
, int, 0644);
72 MODULE_PARM_DESC(mode
, "0 = 320x240, 1 = 160x120, 2 = 640x480");
75 /* Devices supported by this driver
76 * .driver_info contains the init method used by the camera */
77 static struct usb_device_id device_table
[] = {
78 {USB_DEVICE(0x08ca, 0x0109), .driver_info
= METHOD0
},
79 {USB_DEVICE(0x041e, 0x4024), .driver_info
= METHOD0
},
80 {USB_DEVICE(0x0d64, 0x0108), .driver_info
= METHOD0
},
81 {USB_DEVICE(0x0546, 0x3187), .driver_info
= METHOD0
},
82 {USB_DEVICE(0x0d64, 0x3108), .driver_info
= METHOD0
},
83 {USB_DEVICE(0x0595, 0x4343), .driver_info
= METHOD0
},
84 {USB_DEVICE(0x0bb0, 0x500d), .driver_info
= METHOD0
},
85 {USB_DEVICE(0x0feb, 0x2004), .driver_info
= METHOD0
},
86 {USB_DEVICE(0x055f, 0xb500), .driver_info
= METHOD0
},
87 {USB_DEVICE(0x08ca, 0x2062), .driver_info
= METHOD2
},
88 {USB_DEVICE(0x052b, 0x1a18), .driver_info
= METHOD1
},
89 {USB_DEVICE(0x04c8, 0x0729), .driver_info
= METHOD0
},
90 {USB_DEVICE(0x04f2, 0xa208), .driver_info
= METHOD0
},
91 {USB_DEVICE(0x0784, 0x0040), .driver_info
= METHOD1
},
92 {USB_DEVICE(0x06d6, 0x0034), .driver_info
= METHOD0
},
93 {USB_DEVICE(0x0a17, 0x0062), .driver_info
= METHOD2
},
94 {} /* Terminating entry */
97 MODULE_DEVICE_TABLE(usb
, device_table
);
101 struct zr364xx_camera
{
102 struct usb_device
*udev
; /* save off the usb device pointer */
103 struct usb_interface
*interface
;/* the interface for this device */
104 struct video_device
*vdev
; /* v4l video device */
107 unsigned char *buffer
;
117 /* function used to send initialisation commands to the camera */
118 static int send_control_msg(struct usb_device
*udev
, u8 request
, u16 value
,
119 u16 index
, unsigned char *cp
, u16 size
)
123 unsigned char *transfer_buffer
= kmalloc(size
, GFP_KERNEL
);
124 if (!transfer_buffer
) {
125 info("kmalloc(%d) failed", size
);
129 memcpy(transfer_buffer
, cp
, size
);
131 status
= usb_control_msg(udev
,
132 usb_sndctrlpipe(udev
, 0),
134 USB_DIR_OUT
| USB_TYPE_VENDOR
|
135 USB_RECIP_DEVICE
, value
, index
,
136 transfer_buffer
, size
, CTRL_TIMEOUT
);
138 kfree(transfer_buffer
);
141 info("Failed sending control message, error %d.", status
);
147 /* Control messages sent to the camera to initialize it
148 * and launch the capture */
152 unsigned char *bytes
;
156 static unsigned char m0d1
[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
157 static unsigned char m0d2
[] = { 0, 0, 0, 0, 0, 0 };
158 static unsigned char m0d3
[] = { 0, 0 };
159 static message m0
[] = {
162 {0x3370, sizeof(m0d1
), m0d1
},
165 {0x2610, sizeof(m0d2
), m0d2
},
170 {0x9a01, sizeof(m0d3
), m0d3
},
175 static unsigned char m1d1
[] = { 0xff, 0xff };
176 static unsigned char m1d2
[] = { 0x00, 0x00 };
177 static message m1
[] = {
185 {0x2502, sizeof(m1d1
), m1d1
},
190 {0x9a01, sizeof(m1d2
), m1d2
},
195 static unsigned char m2d1
[] = { 0xff, 0xff };
196 static message m2
[] = {
203 {0x2502, sizeof(m2d1
), m2d1
},
209 static message
*init
[3] = { m0
, m1
, m2
};
212 /* JPEG static data in header (Huffman table, etc) */
213 static unsigned char header1
[] = {
216 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
217 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
219 0xFF, 0xDB, 0x00, 0x84
221 static unsigned char header2
[] = {
222 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
223 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
225 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
226 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
227 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
228 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
229 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
230 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
231 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
232 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
233 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
234 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
235 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
236 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
237 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
238 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
239 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
240 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
241 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
242 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
243 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
244 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
245 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
246 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
247 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
248 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
249 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
250 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
251 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
252 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
253 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
254 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
255 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
256 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
257 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
258 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
259 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
260 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
261 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
262 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
263 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
266 static unsigned char header3
;
270 /********************/
271 /* V4L2 integration */
272 /********************/
274 /* this function reads a full JPEG picture synchronously
275 * TODO: do it asynchronously... */
276 static int read_frame(struct zr364xx_camera
*cam
, int framenum
)
278 int i
, n
, temp
, head
, size
, actual_length
;
279 unsigned char *ptr
= NULL
, *jpeg
, swap
;
282 /* hardware brightness */
283 n
= send_control_msg(cam
->udev
, 1, 0x2001, 0, NULL
, 0);
284 temp
= (0x60 << 8) + 127 - cam
->brightness
;
285 n
= send_control_msg(cam
->udev
, 1, temp
, 0, NULL
, 0);
287 /* during the first loop we are going to insert JPEG header */
289 /* this is the place in memory where we are going to build
291 jpeg
= cam
->framebuf
+ framenum
* MAX_FRAME_SIZE
;
294 n
= usb_bulk_msg(cam
->udev
,
295 usb_rcvbulkpipe(cam
->udev
, 0x81),
296 cam
->buffer
, BUFFER_SIZE
, &actual_length
,
298 DBG("buffer : %d %d", cam
->buffer
[0], cam
->buffer
[1]);
299 DBG("bulk : n=%d size=%d", n
, actual_length
);
301 info("error reading bulk msg");
304 if (actual_length
< 0 || actual_length
> BUFFER_SIZE
) {
305 info("wrong number of bytes");
309 /* swap bytes if camera needs it */
310 if (cam
->method
== METHOD0
)
311 for (i
= 0; i
< BUFFER_SIZE
; i
+= 2) {
312 swap
= cam
->buffer
[i
];
313 cam
->buffer
[i
] = cam
->buffer
[i
+ 1];
314 cam
->buffer
[i
+ 1] = swap
;
317 /* write the JPEG header */
321 memcpy(ptr
, header1
, sizeof(header1
));
322 ptr
+= sizeof(header1
);
324 memcpy(ptr
, &header3
, 1);
326 memcpy(ptr
, cam
->buffer
, 64);
329 memcpy(ptr
, &header3
, 1);
331 memcpy(ptr
, cam
->buffer
+ 64, 64);
333 memcpy(ptr
, header2
, sizeof(header2
));
334 ptr
+= sizeof(header2
);
335 memcpy(ptr
, cam
->buffer
+ 128,
336 actual_length
- 128);
337 ptr
+= actual_length
- 128;
339 DBG("header : %d %d %d %d %d %d %d %d %d",
340 cam
->buffer
[0], cam
->buffer
[1], cam
->buffer
[2],
341 cam
->buffer
[3], cam
->buffer
[4], cam
->buffer
[5],
342 cam
->buffer
[6], cam
->buffer
[7], cam
->buffer
[8]);
344 memcpy(ptr
, cam
->buffer
, actual_length
);
345 ptr
+= actual_length
;
348 /* ... until there is no more */
349 while (actual_length
== BUFFER_SIZE
);
351 /* we skip the 2 first frames which are usually buggy */
357 /* go back to find the JPEG EOI marker */
361 if (*ptr
== 0xFF && *(ptr
+ 1) == 0xD9
362 && *(ptr
+ 2) == 0xFF)
367 DBG("No EOI marker");
369 /* Sometimes there is junk data in the middle of the picture,
370 * we want to skip this bogus frames */
372 if (*ptr
== 0xFF && *(ptr
+ 1) == 0xFF
373 && *(ptr
+ 2) == 0xFF)
378 DBG("Bogus frame ? %d", cam
->nb
);
382 DBG("jpeg : %d %d %d %d %d %d %d %d",
383 jpeg
[0], jpeg
[1], jpeg
[2], jpeg
[3],
384 jpeg
[4], jpeg
[5], jpeg
[6], jpeg
[7]);
390 static ssize_t
zr364xx_read(struct file
*file
, char *buf
, size_t cnt
,
393 unsigned long count
= cnt
;
394 struct video_device
*vdev
= video_devdata(file
);
395 struct zr364xx_camera
*cam
;
397 DBG("zr364xx_read: read %d bytes.", (int) count
);
401 cam
= video_get_drvdata(vdev
);
410 count
= read_frame(cam
, 0);
412 if (copy_to_user(buf
, cam
->framebuf
, count
))
419 static int zr364xx_vidioc_querycap(struct file
*file
, void *priv
,
420 struct v4l2_capability
*cap
)
422 memset(cap
, 0, sizeof(*cap
));
423 strcpy(cap
->driver
, DRIVER_DESC
);
424 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_READWRITE
;
428 static int zr364xx_vidioc_enum_input(struct file
*file
, void *priv
,
429 struct v4l2_input
*i
)
433 memset(i
, 0, sizeof(*i
));
435 strcpy(i
->name
, DRIVER_DESC
" Camera");
436 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
440 static int zr364xx_vidioc_g_input(struct file
*file
, void *priv
,
447 static int zr364xx_vidioc_s_input(struct file
*file
, void *priv
,
455 static int zr364xx_vidioc_queryctrl(struct file
*file
, void *priv
,
456 struct v4l2_queryctrl
*c
)
458 struct video_device
*vdev
= video_devdata(file
);
459 struct zr364xx_camera
*cam
;
463 cam
= video_get_drvdata(vdev
);
466 case V4L2_CID_BRIGHTNESS
:
467 c
->type
= V4L2_CTRL_TYPE_INTEGER
;
468 strcpy(c
->name
, "Brightness");
472 c
->default_value
= cam
->brightness
;
481 static int zr364xx_vidioc_s_ctrl(struct file
*file
, void *priv
,
482 struct v4l2_control
*c
)
484 struct video_device
*vdev
= video_devdata(file
);
485 struct zr364xx_camera
*cam
;
489 cam
= video_get_drvdata(vdev
);
492 case V4L2_CID_BRIGHTNESS
:
493 cam
->brightness
= c
->value
;
501 static int zr364xx_vidioc_g_ctrl(struct file
*file
, void *priv
,
502 struct v4l2_control
*c
)
504 struct video_device
*vdev
= video_devdata(file
);
505 struct zr364xx_camera
*cam
;
509 cam
= video_get_drvdata(vdev
);
512 case V4L2_CID_BRIGHTNESS
:
513 c
->value
= cam
->brightness
;
521 static int zr364xx_vidioc_enum_fmt_cap(struct file
*file
,
522 void *priv
, struct v4l2_fmtdesc
*f
)
526 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
528 memset(f
, 0, sizeof(*f
));
530 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
531 f
->flags
= V4L2_FMT_FLAG_COMPRESSED
;
532 strcpy(f
->description
, "JPEG");
533 f
->pixelformat
= V4L2_PIX_FMT_JPEG
;
537 static int zr364xx_vidioc_try_fmt_cap(struct file
*file
, void *priv
,
538 struct v4l2_format
*f
)
540 struct video_device
*vdev
= video_devdata(file
);
541 struct zr364xx_camera
*cam
;
545 cam
= video_get_drvdata(vdev
);
547 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
549 if (f
->fmt
.pix
.pixelformat
!= V4L2_PIX_FMT_JPEG
)
551 if (f
->fmt
.pix
.field
!= V4L2_FIELD_ANY
&&
552 f
->fmt
.pix
.field
!= V4L2_FIELD_NONE
)
554 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
555 f
->fmt
.pix
.width
= cam
->width
;
556 f
->fmt
.pix
.height
= cam
->height
;
557 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* 2;
558 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
559 f
->fmt
.pix
.colorspace
= 0;
564 static int zr364xx_vidioc_g_fmt_cap(struct file
*file
, void *priv
,
565 struct v4l2_format
*f
)
567 struct video_device
*vdev
= video_devdata(file
);
568 struct zr364xx_camera
*cam
;
572 cam
= video_get_drvdata(vdev
);
574 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
576 memset(&f
->fmt
.pix
, 0, sizeof(struct v4l2_pix_format
));
577 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
578 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_JPEG
;
579 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
580 f
->fmt
.pix
.width
= cam
->width
;
581 f
->fmt
.pix
.height
= cam
->height
;
582 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* 2;
583 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
584 f
->fmt
.pix
.colorspace
= 0;
589 static int zr364xx_vidioc_s_fmt_cap(struct file
*file
, void *priv
,
590 struct v4l2_format
*f
)
592 struct video_device
*vdev
= video_devdata(file
);
593 struct zr364xx_camera
*cam
;
597 cam
= video_get_drvdata(vdev
);
599 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
601 if (f
->fmt
.pix
.pixelformat
!= V4L2_PIX_FMT_JPEG
)
603 if (f
->fmt
.pix
.field
!= V4L2_FIELD_ANY
&&
604 f
->fmt
.pix
.field
!= V4L2_FIELD_NONE
)
606 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
607 f
->fmt
.pix
.width
= cam
->width
;
608 f
->fmt
.pix
.height
= cam
->height
;
609 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
* 2;
610 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
611 f
->fmt
.pix
.colorspace
= 0;
617 static int zr364xx_vidioc_streamon(struct file
*file
, void *priv
,
618 enum v4l2_buf_type type
)
623 static int zr364xx_vidioc_streamoff(struct file
*file
, void *priv
,
624 enum v4l2_buf_type type
)
630 /* open the camera */
631 static int zr364xx_open(struct inode
*inode
, struct file
*file
)
633 struct video_device
*vdev
= video_devdata(file
);
634 struct zr364xx_camera
*cam
= video_get_drvdata(vdev
);
635 struct usb_device
*udev
= cam
->udev
;
642 err
= video_exclusive_open(inode
, file
);
646 if (!cam
->framebuf
) {
647 cam
->framebuf
= vmalloc_32(MAX_FRAME_SIZE
* FRAMES
);
648 if (!cam
->framebuf
) {
649 info("vmalloc_32 failed!");
654 mutex_lock(&cam
->lock
);
655 for (i
= 0; init
[cam
->method
][i
].size
!= -1; i
++) {
657 send_control_msg(udev
, 1, init
[cam
->method
][i
].value
,
658 0, init
[cam
->method
][i
].bytes
,
659 init
[cam
->method
][i
].size
);
661 info("error during open sequence: %d", i
);
662 mutex_unlock(&cam
->lock
);
667 file
->private_data
= vdev
;
669 /* Added some delay here, since opening/closing the camera quickly,
670 * like Ekiga does during its startup, can crash the webcam
674 mutex_unlock(&cam
->lock
);
679 /* release the camera */
680 static int zr364xx_release(struct inode
*inode
, struct file
*file
)
682 struct video_device
*vdev
= video_devdata(file
);
683 struct zr364xx_camera
*cam
;
684 struct usb_device
*udev
;
687 DBG("zr364xx_release");
691 cam
= video_get_drvdata(vdev
);
695 mutex_lock(&cam
->lock
);
696 for (i
= 0; i
< 2; i
++) {
698 send_control_msg(udev
, 1, init
[cam
->method
][i
].value
,
699 0, init
[i
][cam
->method
].bytes
,
700 init
[cam
->method
][i
].size
);
702 info("error during release sequence");
703 mutex_unlock(&cam
->lock
);
708 file
->private_data
= NULL
;
709 video_exclusive_release(inode
, file
);
711 /* Added some delay here, since opening/closing the camera quickly,
712 * like Ekiga does during its startup, can crash the webcam
716 mutex_unlock(&cam
->lock
);
721 static int zr364xx_mmap(struct file
*file
, struct vm_area_struct
*vma
)
724 unsigned long start
= vma
->vm_start
;
725 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
726 struct video_device
*vdev
= video_devdata(file
);
727 struct zr364xx_camera
*cam
;
729 DBG("zr364xx_mmap: %ld\n", size
);
733 cam
= video_get_drvdata(vdev
);
737 if (vm_insert_page(vma
, start
, vmalloc_to_page(pos
)))
741 if (size
> PAGE_SIZE
)
751 static struct file_operations zr364xx_fops
= {
752 .owner
= THIS_MODULE
,
753 .open
= zr364xx_open
,
754 .release
= zr364xx_release
,
755 .read
= zr364xx_read
,
756 .mmap
= zr364xx_mmap
,
757 .ioctl
= video_ioctl2
,
761 static struct video_device zr364xx_template
= {
762 .owner
= THIS_MODULE
,
764 .type
= VID_TYPE_CAPTURE
,
765 .fops
= &zr364xx_fops
,
766 .release
= video_device_release
,
769 .vidioc_querycap
= zr364xx_vidioc_querycap
,
770 .vidioc_enum_fmt_cap
= zr364xx_vidioc_enum_fmt_cap
,
771 .vidioc_try_fmt_cap
= zr364xx_vidioc_try_fmt_cap
,
772 .vidioc_s_fmt_cap
= zr364xx_vidioc_s_fmt_cap
,
773 .vidioc_g_fmt_cap
= zr364xx_vidioc_g_fmt_cap
,
774 .vidioc_enum_input
= zr364xx_vidioc_enum_input
,
775 .vidioc_g_input
= zr364xx_vidioc_g_input
,
776 .vidioc_s_input
= zr364xx_vidioc_s_input
,
777 .vidioc_streamon
= zr364xx_vidioc_streamon
,
778 .vidioc_streamoff
= zr364xx_vidioc_streamoff
,
779 .vidioc_queryctrl
= zr364xx_vidioc_queryctrl
,
780 .vidioc_g_ctrl
= zr364xx_vidioc_g_ctrl
,
781 .vidioc_s_ctrl
= zr364xx_vidioc_s_ctrl
,
786 /*******************/
787 /* USB integration */
788 /*******************/
790 static int zr364xx_probe(struct usb_interface
*intf
,
791 const struct usb_device_id
*id
)
793 struct usb_device
*udev
= interface_to_usbdev(intf
);
794 struct zr364xx_camera
*cam
= NULL
;
798 info(DRIVER_DESC
" compatible webcam plugged");
799 info("model %04x:%04x detected", udev
->descriptor
.idVendor
,
800 udev
->descriptor
.idProduct
);
803 kmalloc(sizeof(struct zr364xx_camera
), GFP_KERNEL
)) == NULL
) {
804 info("cam: out of memory !");
807 memset(cam
, 0x00, sizeof(struct zr364xx_camera
));
808 /* save the init method used by this camera */
809 cam
->method
= id
->driver_info
;
811 cam
->vdev
= video_device_alloc();
812 if (cam
->vdev
== NULL
) {
813 info("cam->vdev: out of memory !");
817 memcpy(cam
->vdev
, &zr364xx_template
, sizeof(zr364xx_template
));
818 video_set_drvdata(cam
->vdev
, cam
);
820 cam
->vdev
->debug
= V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG
;
824 if ((cam
->buffer
= kmalloc(BUFFER_SIZE
, GFP_KERNEL
)) == NULL
) {
825 info("cam->buffer: out of memory !");
826 video_device_release(cam
->vdev
);
833 info("160x120 mode selected");
838 info("640x480 mode selected");
843 info("320x240 mode selected");
850 m1
[2].value
= 0xf000 + mode
;
851 m2
[1].value
= 0xf000 + mode
;
852 header2
[437] = cam
->height
/ 256;
853 header2
[438] = cam
->height
% 256;
854 header2
[439] = cam
->width
/ 256;
855 header2
[440] = cam
->width
% 256;
858 cam
->brightness
= 64;
859 mutex_init(&cam
->lock
);
861 if (video_register_device(cam
->vdev
, VFL_TYPE_GRABBER
, -1) == -1) {
862 info("video_register_device failed");
863 video_device_release(cam
->vdev
);
869 usb_set_intfdata(intf
, cam
);
871 info(DRIVER_DESC
" controlling video device %d", cam
->vdev
->minor
);
876 static void zr364xx_disconnect(struct usb_interface
*intf
)
878 struct zr364xx_camera
*cam
= usb_get_intfdata(intf
);
879 usb_set_intfdata(intf
, NULL
);
880 dev_set_drvdata(&intf
->dev
, NULL
);
881 info(DRIVER_DESC
" webcam unplugged");
883 video_unregister_device(cam
->vdev
);
887 vfree(cam
->framebuf
);
893 /**********************/
894 /* Module integration */
895 /**********************/
897 static struct usb_driver zr364xx_driver
= {
899 .probe
= zr364xx_probe
,
900 .disconnect
= zr364xx_disconnect
,
901 .id_table
= device_table
905 static int __init
zr364xx_init(void)
908 retval
= usb_register(&zr364xx_driver
) < 0;
910 info("usb_register failed!");
912 info(DRIVER_DESC
" module loaded");
917 static void __exit
zr364xx_exit(void)
919 info(DRIVER_DESC
" module unloaded");
920 usb_deregister(&zr364xx_driver
);
924 module_init(zr364xx_init
);
925 module_exit(zr364xx_exit
);
927 MODULE_AUTHOR(DRIVER_AUTHOR
);
928 MODULE_DESCRIPTION(DRIVER_DESC
);
929 MODULE_LICENSE("GPL");