Change 624f to support bayer format
[microdia.git] / microdia-usb.c
blob91d756a78715db8f3d3a48e39aa54cab9c97833d
1 /**
2 * @file microdia-usb.c
3 * @author Nicolas VIVIEN
4 * @date 2008-02-01
6 * @brief Driver for Microdia USB video camera
8 * @note Copyright (C) Nicolas VIVIEN
10 * @par Licences
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/version.h>
31 #include <linux/errno.h>
32 #include <linux/slab.h>
33 #include <linux/kref.h>
34 #include <linux/stat.h>
36 #include <linux/usb.h>
37 #include <media/v4l2-common.h>
39 #include "microdia.h"
40 #include "sn9c20x.h"
41 #include "mt9vx11.h"
42 #include "ov965x.h"
43 #include "ov7660.h"
45 /**
46 * @var fps
47 * Module parameter to set frame per second
49 static int fps = 25;
51 /**
52 * @var hflip
53 * Module parameter to enable/disable the horizontal flip process
55 static int hflip;
57 /**
58 * @var flip_detect
59 * Module parameter to enable/disable vflip detection
61 static int flip_detect;
63 /**
64 * @var vflip
65 * Module parameter to enable/disable the vertical flip process
67 static int vflip;
69 /**
70 * @var brightness
71 * Module parameter to set the brightness
73 static int brightness = MICRODIA_PERCENT(50, 0xFFFF);
75 /**
76 * @var whiteness
77 * Module parameter to set the whiteness
79 static int whiteness = MICRODIA_PERCENT(20, 0xFFFF);
81 /**
82 * @var contrast
83 * Module parameter to set the contrast
85 static int contrast = MICRODIA_PERCENT(50, 0xFFFF);
87 /**
88 * @var exposure
89 * Module parameter to set the exposure
91 /* static int exposure = MICRODIA_PERCENT(20, 0xFFFF); */
92 static int exposure = MICRODIA_PERCENT(2, 0xFFFF);
94 /**
95 * @var sharpness
96 * Module parameter to set the sharpness
98 static int sharpness = MICRODIA_PERCENT(50, 0x3F);
101 * @var rgb_gain
102 * Module parameter to set the red/green/blue gain
104 static int rgb_gain = MICRODIA_PERCENT(25, 0x7F) |
105 (MICRODIA_PERCENT(25, 0x7F) << 8) |
106 (MICRODIA_PERCENT(25, 0x7F) << 16);
109 * @var min_buffers
110 * Module parameter to set the minimum number of image buffers
112 static int min_buffers = 2;
115 * @var max_buffers
116 * Module parameter to set the maximum number of image buffers
118 static int max_buffers = 5;
121 * @var auto_exposure
122 * Module parameter to set the exposure
124 static int auto_exposure = 1;
127 * @var auto_whitebalance
128 * Module parameter to set the exposure
130 static int auto_whitebalance = 1;
133 * @var log_level
134 * Module parameter to set the log level
136 __u8 log_level = 1;
140 * @var microdia_table
141 * Define all the hotplug supported devices by this driver
143 static struct usb_device_id microdia_table[] = {
144 /* SN9C201 + MI1300 */
145 { USB_DEVICE(USB_0C45_VID, USB_6240_PID) },
146 /* SN9C201 + MI1310 */
147 { USB_DEVICE(USB_0C45_VID, USB_6242_PID) },
148 /* SN9C201 + S5K4AAFX */
149 { USB_DEVICE(USB_0C45_VID, USB_6243_PID) },
150 /* SN9C201 + OV9655 */
151 { USB_DEVICE(USB_0C45_VID, USB_6248_PID) },
152 /* SN9C201 + CX1332 */
153 { USB_DEVICE(USB_0C45_VID, USB_624B_PID) },
154 /* SN9C201 + MI1320 */
155 { USB_DEVICE(USB_0C45_VID, USB_624C_PID) },
156 /* SN9C201 + SOI968 */
157 { USB_DEVICE(USB_0C45_VID, USB_624E_PID) },
158 /* SN9C201 + OV9650 */
159 { USB_DEVICE(USB_0C45_VID, USB_624F_PID) },
160 /* SN9C201 + OV9650 */
161 { USB_DEVICE(USB_0C45_VID, USB_6253_PID) },
162 /* SN9C201 + OV7670ISP */
163 { USB_DEVICE(USB_0C45_VID, USB_6260_PID) },
164 /* SN9C201 + OM6802 */
165 { USB_DEVICE(USB_0C45_VID, USB_6262_PID) },
166 /* SN9C201 + MI0360/MT9V111 */
167 { USB_DEVICE(USB_0C45_VID, USB_6270_PID) },
168 /* SN9C201 + S5K53BEB */
169 { USB_DEVICE(USB_0C45_VID, USB_627A_PID) },
170 /* SN9C201 + OV7660 */
171 { USB_DEVICE(USB_0C45_VID, USB_627B_PID) },
172 /* SN9C201 + HV7131R */
173 { USB_DEVICE(USB_0C45_VID, USB_627C_PID) },
174 /* EEPROM */
175 { USB_DEVICE(USB_0C45_VID, USB_627F_PID) },
176 /* SN9C202 + MI1300 */
177 { USB_DEVICE(USB_0C45_VID, USB_6280_PID) },
178 /* SN9C202 + MI1310 */
179 { USB_DEVICE(USB_0C45_VID, USB_6282_PID) },
180 /* SN9C202 + S5K4AAFX */
181 { USB_DEVICE(USB_0C45_VID, USB_6283_PID) },
182 /* SN9C202 + OV9655 */
183 { USB_DEVICE(USB_0C45_VID, USB_6288_PID) },
184 /* SN9C202 + ICM107 */
185 { USB_DEVICE(USB_0C45_VID, USB_628A_PID) },
186 /* SN9C202 + CX1332 */
187 { USB_DEVICE(USB_0C45_VID, USB_628B_PID) },
188 /* SN9C202 + MI1320 */
189 { USB_DEVICE(USB_0C45_VID, USB_628C_PID) },
190 /* SN9C202 + SOI968 */
191 { USB_DEVICE(USB_0C45_VID, USB_628E_PID) },
192 /* SN9C202 + OV9650 */
193 { USB_DEVICE(USB_0C45_VID, USB_628F_PID) },
194 /* SN9C202 + OV7670ISP */
195 { USB_DEVICE(USB_0C45_VID, USB_62A0_PID) },
196 /* SN9C202 + OM6802 */
197 { USB_DEVICE(USB_0C45_VID, USB_62A2_PID) },
198 /* SN9C202 + MI0360/MT9V111 */
199 { USB_DEVICE(USB_0C45_VID, USB_62B0_PID) },
200 /* SN9C202 + OV9655 */
201 { USB_DEVICE(USB_0C45_VID, USB_62B3_PID) },
202 /* SN9C202 + S5K53BEB */
203 { USB_DEVICE(USB_0C45_VID, USB_62BA_PID) },
204 /* SN9C202 + OV7660 */
205 { USB_DEVICE(USB_0C45_VID, USB_62BB_PID) },
206 /* SN9C202 + HV7131R */
207 { USB_DEVICE(USB_0C45_VID, USB_62BC_PID) },
208 /* SN9C202 + OV7663 */
209 { USB_DEVICE(USB_0C45_VID, USB_62BE_PID) },
210 /* => 628f (SN9C202 + OV9650) */
211 { USB_DEVICE(USB_045E_VID, USB_00F4_PID) },
212 /* => 627b (SN9C201 + OV7660) */
213 { USB_DEVICE(USB_145F_VID, USB_013D_PID) },
214 /* => 62be (SN9C202 + OV7663 + EEPROM) */
215 { USB_DEVICE(USB_04F2_VID, USB_A128_PID) },
220 MODULE_DEVICE_TABLE(usb, microdia_table); /**< Define the supported devices */
222 DEFINE_MUTEX(open_lock); /**< Define global mutex */
224 int microdia_6240_initialize(struct usb_microdia *dev);
225 int microdia_6240_start_stream(struct usb_microdia *dev);
226 int microdia_6240_stop_stream(struct usb_microdia *dev);
227 int microdia_6242_start_stream(struct usb_microdia *dev);
228 int microdia_6242_stop_stream(struct usb_microdia *dev);
229 int microdia_624e_initialize(struct usb_microdia *dev);
230 int microdia_624e_start_stream(struct usb_microdia *dev);
231 int microdia_624e_stop_stream(struct usb_microdia *dev);
232 int microdia_624f_initialize(struct usb_microdia *dev);
233 int microdia_624f_stop_stream(struct usb_microdia *dev);
234 int microdia_624f_start_stream(struct usb_microdia *dev);
235 int microdia_624f_set_exposure(struct usb_microdia *dev);
236 int microdia_624f_flip_detect(struct usb_microdia *dev);
237 int microdia_6260_initialize(struct usb_microdia *dev);
238 int microdia_6260_start_stream(struct usb_microdia *dev);
239 int microdia_6260_stop_stream(struct usb_microdia *dev);
240 int microdia_6260_flip_detect(struct usb_microdia *dev);
241 int microdia_6270_initialize(struct usb_microdia *dev);
242 int microdia_6270_start_stream(struct usb_microdia *dev);
243 int microdia_6270_stop_stream(struct usb_microdia *dev);
244 int microdia_627b_initialize(struct usb_microdia *dev);
245 int microdia_627b_start_stream(struct usb_microdia *dev);
246 int microdia_627b_stop_stream(struct usb_microdia *dev);
247 int microdia_627f_initialize(struct usb_microdia *dev);
248 int microdia_6288_initialize(struct usb_microdia *dev);
249 int microdia_6288_start_stream(struct usb_microdia *dev);
250 int microdia_6288_stop_stream(struct usb_microdia *dev);
253 * @var cameras
255 * This array assigns all specific functions and settings to each cam.
258 struct microdia_camera cameras[] = {
260 .model = CAMERA_MODEL(USB_0C45_VID, USB_6240_PID),
261 .type = MICRODIA_VGA,
262 .sensor_slave_address = 0x5d,
263 .sensor_flags = SN9C20X_I2C_2WIRE,
264 .supported_fmts = 0x03,
265 .initialize = microdia_6240_initialize,
266 .start_stream = microdia_6240_start_stream,
267 .stop_stream = microdia_6240_stop_stream,
270 .model = CAMERA_MODEL(USB_0C45_VID, USB_6242_PID),
271 .type = MICRODIA_VGA,
272 .sensor_slave_address = 0x5d,
273 .sensor_flags = SN9C20X_I2C_2WIRE,
274 .supported_fmts = 0x03,
275 .initialize = microdia_624e_initialize,
276 .start_stream = microdia_6242_start_stream,
277 .stop_stream = microdia_6242_stop_stream,
280 .model = CAMERA_MODEL(USB_0C45_VID, USB_624E_PID),
281 .type = MICRODIA_VGA,
282 .sensor_slave_address = 0x30,
283 .sensor_flags = SN9C20X_I2C_2WIRE,
284 .supported_fmts = 0x03,
285 .initialize = microdia_624e_initialize,
286 .sensor_init = soi968_initialize,
287 .start_stream = microdia_624e_start_stream,
288 .stop_stream = microdia_624e_stop_stream,
289 .set_auto_exposure = ov965x_set_autoexposure,
290 /* .set_exposure = soi968_set_exposure, */
293 .model = CAMERA_MODEL(USB_0C45_VID, USB_624F_PID),
294 .type = MICRODIA_VGA,
295 .sensor_slave_address = 0x30,
296 .sensor_flags = SN9C20X_I2C_2WIRE,
297 .supported_fmts = 0x10,
298 .initialize = microdia_624f_initialize,
299 .sensor_init = ov965x_initialize,
300 .start_stream = microdia_624f_start_stream,
301 .stop_stream = microdia_624f_stop_stream,
302 .flip_detect = microdia_624f_flip_detect,
303 .set_auto_exposure = ov965x_set_autoexposure,
304 .set_exposure = ov965x_set_exposure,
305 .set_hvflip = ov965x_set_hvflip,
308 .model = CAMERA_MODEL(USB_0C45_VID, USB_6253_PID),
309 .type = MICRODIA_VGA,
310 .sensor_slave_address = 0x30,
311 .sensor_flags = SN9C20X_I2C_2WIRE,
312 .supported_fmts = 0x03,
313 .initialize = microdia_624f_initialize,
314 .sensor_init = ov965x_initialize,
315 .start_stream = microdia_624f_start_stream,
316 .stop_stream = microdia_624f_stop_stream,
317 .flip_detect = microdia_624f_flip_detect,
318 .set_auto_exposure = ov965x_set_autoexposure,
319 .set_exposure = ov965x_set_exposure,
320 .set_hvflip = ov965x_set_hvflip,
323 .model = CAMERA_MODEL(USB_0C45_VID, USB_6260_PID),
324 .type = MICRODIA_VGA,
325 .sensor_slave_address = 0x21,
326 .sensor_flags = SN9C20X_I2C_2WIRE,
327 .supported_fmts = 0x08,
328 .initialize = microdia_6260_initialize,
329 .start_stream = microdia_6260_start_stream,
330 .stop_stream = microdia_6260_stop_stream,
331 .flip_detect = microdia_6260_flip_detect,
334 .model = CAMERA_MODEL(USB_0C45_VID, USB_6270_PID),
335 .type = MICRODIA_VGA,
336 .sensor_slave_address = 0,
337 .sensor_flags = SN9C20X_I2C_2WIRE,
338 .supported_fmts = 0x07,
339 .initialize = microdia_6270_initialize,
340 .start_stream = microdia_6270_start_stream,
341 .stop_stream = microdia_6270_stop_stream,
342 .set_exposure = mt9vx11_set_exposure,
343 .set_hvflip = mt9vx11_set_hvflip,
344 .set_auto_exposure = mt9v111_set_autoexposure,
345 .set_auto_whitebalance = mt9v111_set_autowhitebalance,
348 .model = CAMERA_MODEL(USB_0C45_VID, USB_627B_PID),
349 .type = MICRODIA_VGA,
350 .sensor_slave_address = 0x21,
351 .sensor_flags = SN9C20X_I2C_2WIRE,
352 .supported_fmts = 0x07,
353 .initialize = microdia_627b_initialize,
354 .sensor_init = ov7660_initialize,
355 .start_stream = microdia_627b_start_stream,
356 .stop_stream = microdia_627b_stop_stream,
357 .set_auto_exposure = ov7660_set_autoexposure,
358 .set_exposure = ov7660_set_exposure,
361 .model = CAMERA_MODEL(USB_0C45_VID, USB_627F_PID),
362 .type = MICRODIA_VGA,
363 .sensor_slave_address = 0x30,
364 .sensor_flags = SN9C20X_I2C_2WIRE,
365 .supported_fmts = 0x03,
366 .initialize = microdia_624f_initialize,
367 .sensor_init = ov965x_initialize,
368 .start_stream = microdia_624f_start_stream,
369 .stop_stream = microdia_624f_stop_stream,
370 .flip_detect = microdia_624f_flip_detect,
371 .set_exposure = ov965x_set_exposure,
372 .set_hvflip = ov965x_set_hvflip,
375 .model = CAMERA_MODEL(USB_0C45_VID, USB_6288_PID),
376 .type = MICRODIA_VGA,
377 .sensor_slave_address = 0x30,
378 .sensor_flags = SN9C20X_I2C_2WIRE,
379 .supported_fmts = 0x03,
380 .initialize = microdia_6288_initialize,
381 .start_stream = microdia_6288_start_stream,
382 .stop_stream = microdia_6288_stop_stream,
383 .set_auto_exposure = ov965x_set_autoexposure,
386 .model = CAMERA_MODEL(USB_0C45_VID, USB_628F_PID),
387 .type = MICRODIA_VGA,
388 .sensor_slave_address = 0x30,
389 .sensor_flags = SN9C20X_I2C_2WIRE,
390 .supported_fmts = 0x03,
391 .initialize = microdia_624f_initialize,
392 .sensor_init = ov965x_initialize,
393 .start_stream = microdia_624f_start_stream,
394 .stop_stream = microdia_624f_stop_stream,
395 .flip_detect = microdia_624f_flip_detect,
396 .set_auto_exposure = ov965x_set_autoexposure,
397 .set_exposure = ov965x_set_exposure,
398 .set_hvflip = ov965x_set_hvflip,
401 .model = CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID),
402 .type = MICRODIA_VGA,
403 .sensor_slave_address = 0x30,
404 .sensor_flags = SN9C20X_I2C_2WIRE,
405 .supported_fmts = 0x03,
406 .initialize = microdia_6288_initialize,
407 .start_stream = microdia_6288_start_stream,
408 .stop_stream = microdia_6288_stop_stream,
411 .model = CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID),
412 .type = MICRODIA_VGA,
413 .sensor_slave_address = 0x21,
414 .sensor_flags = SN9C20X_I2C_2WIRE,
415 .supported_fmts = 0x07,
416 .initialize = microdia_627b_initialize,
417 .start_stream = microdia_627b_start_stream,
418 .stop_stream = microdia_627b_stop_stream,
421 .model = CAMERA_MODEL(USB_145F_VID, USB_013D_PID),
422 .type = MICRODIA_VGA,
423 .sensor_slave_address = 0x21,
424 .sensor_flags = SN9C20X_I2C_2WIRE,
425 .supported_fmts = 0x07,
426 .initialize = microdia_627b_initialize,
427 .start_stream = microdia_627b_start_stream,
428 .stop_stream = microdia_627b_stop_stream,
431 .model = CAMERA_MODEL(USB_045E_VID, USB_00F4_PID),
432 .type = MICRODIA_VGA,
433 .sensor_slave_address = 0x30,
434 .sensor_flags = SN9C20X_I2C_2WIRE,
435 .supported_fmts = 0x03,
436 .initialize = microdia_624f_initialize,
437 .sensor_init = ov965x_initialize,
438 .start_stream = microdia_624f_start_stream,
439 .stop_stream = microdia_624f_stop_stream,
440 .flip_detect = microdia_624f_flip_detect,
441 .set_auto_exposure = ov965x_set_autoexposure,
442 .set_exposure = ov965x_set_exposure,
443 .set_hvflip = ov965x_set_hvflip,
449 * @brief Find device specific microdia_camera structure for model
451 * @param model Model we are looking for
453 * @returns Pointer to device specific microdia_camera structure or NULL
456 static inline struct microdia_camera *find_camera(__u32 model)
458 int i;
459 for (i = 0; i < ARRAY_SIZE(cameras); i++) {
460 if (cameras[i].model == model)
461 return &cameras[i];
463 return NULL;
467 * @param dev Device structure
469 * @returns 0 if all is OK
471 * @brief Initilize an isochronous pipe.
473 * This function permits to initialize an URB transfert (or isochronous pipe).
475 int usb_microdia_isoc_init(struct usb_microdia *dev)
477 int i, j;
478 int ret = 0;
479 __u16 iso_max_frame_size;
480 struct urb *urb;
481 struct usb_device *udev;
483 if (dev == NULL)
484 return -EFAULT;
486 udev = dev->udev;
488 UDIA_DEBUG("usb_microdia_isoc_init()\n");
490 iso_max_frame_size = max_packet_sz(le16_to_cpu(dev->isoc_in_size)) *
491 hb_multiplier(le16_to_cpu(dev->isoc_in_size));
493 for (i = 0; i < MAX_ISO_BUFS; i++) {
494 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
496 if (urb == NULL) {
497 UDIA_ERROR("Failed to allocate URB %d\n", i);
498 usb_microdia_isoc_cleanup(dev);
499 return -ENOMEM;
502 urb->interval = 1;
503 urb->dev = udev;
504 urb->pipe = usb_rcvisocpipe(udev, dev->isoc_in_endpointAddr);
505 urb->transfer_flags = URB_ISO_ASAP;
506 urb->transfer_buffer_length = iso_max_frame_size * ISO_FRAMES_PER_DESC;
507 urb->complete = usb_microdia_isoc_handler;
508 urb->context = dev;
509 urb->start_frame = 0;
510 urb->number_of_packets = ISO_FRAMES_PER_DESC;
512 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
513 urb->iso_frame_desc[j].offset = j * iso_max_frame_size;
514 urb->iso_frame_desc[j].length = iso_max_frame_size;
517 dev->isobuf[i].data = kzalloc(urb->transfer_buffer_length,
518 GFP_KERNEL);
519 if (dev->isobuf[i].data == NULL) {
520 usb_microdia_isoc_cleanup(dev);
521 return -ENOMEM;
524 urb->transfer_buffer = dev->isobuf[i].data;
525 dev->isobuf[i].urb = urb;
528 UDIA_DEBUG("dev->isoc_in_size = %X\n", (unsigned int)dev->isoc_in_size);
529 UDIA_DEBUG("dev->isoc_in_endpointAddr = %X\n", dev->isoc_in_endpointAddr);
531 for (i = 0; i < MAX_ISO_BUFS; i++) {
532 ret = usb_submit_urb(dev->isobuf[i].urb, GFP_KERNEL);
534 if (ret)
535 UDIA_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
538 return 0;
543 * @param urb URB structure
545 * @brief ISOC handler
547 * This function is called as an URB transfert is complete (Isochronous pipe).
548 * So, the traitement is done in interrupt time, so it has be fast, not crash,
549 * and not stall. Neat.
551 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
552 void usb_microdia_isoc_handler(struct urb *urb, struct pt_regs *regs)
553 #else
554 void usb_microdia_isoc_handler(struct urb *urb)
555 #endif
557 int i;
558 int ret;
560 int framestatus;
561 unsigned int framelen;
562 unsigned long flags;
564 unsigned char *iso_buf = NULL;
566 void *mem = NULL;
567 struct microdia_buffer *buf = NULL;
568 struct usb_microdia *dev = urb->context;
569 struct microdia_video_queue *queue = &dev->queue;
571 unsigned char frame_header[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
573 UDIA_STREAM("Isoc handler\n");
575 switch (urb->status) {
576 case 0:
577 break;
579 default:
580 UDIA_WARNING("Non-zero status (%d) in video "
581 "completion handler.\n", urb->status);
583 case -ENOENT: /* usb_kill_urb() called. */
584 if (dev->frozen)
585 return;
587 case -ECONNRESET: /* usb_unlink_urb() called. */
588 case -ESHUTDOWN: /* The endpoint is being disabled. */
589 microdia_queue_cancel(queue, urb->status == -ESHUTDOWN);
590 return;
593 spin_lock_irqsave(&queue->irqlock, flags);
594 if (!list_empty(&queue->irqqueue))
595 buf = list_first_entry(&queue->irqqueue, struct microdia_buffer,
596 queue);
597 spin_unlock_irqrestore(&queue->irqlock, flags);
599 for (i = 0; i < urb->number_of_packets; i++) {
600 framestatus = urb->iso_frame_desc[i].status;
601 if (framestatus != 0) {
602 UDIA_ERROR("Iso frame %d of USB has error %d\n",
603 i, framestatus);
604 continue;
606 framelen = urb->iso_frame_desc[i].actual_length;
607 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
609 if (buf == NULL)
610 continue;
612 if (memcmp(iso_buf, frame_header, 6) == 0 && framelen == 64) {
613 UDIA_DEBUG("Frame Resolution: %dx%d\n",
614 iso_buf[0x3a] << 4, iso_buf[0x3b] << 3);
615 UDIA_DEBUG("Frame Size: %d\n", buf->buf.bytesused);
616 if (buf->buf.bytesused != 0)
617 buf->state = MICRODIA_BUF_STATE_DONE;
618 } else {
619 if (buf->state != MICRODIA_BUF_STATE_ACTIVE)
620 buf->state = MICRODIA_BUF_STATE_ACTIVE;
622 if (framelen + buf->buf.bytesused > queue->frame_size) {
623 UDIA_WARNING("Frame Buffer overflow!\n");
624 dev->vframes_overflow++;
625 buf->state = MICRODIA_BUF_STATE_DONE;
627 framelen = min(queue->frame_size - buf->buf.bytesused,
628 framelen);
629 mem = queue->mem + buf->buf.m.offset +
630 buf->buf.bytesused;
631 memcpy(mem, iso_buf, framelen);
632 buf->buf.bytesused += framelen;
634 if (buf->state == MICRODIA_BUF_STATE_DONE ||
635 buf->state == MICRODIA_BUF_STATE_ERROR) {
636 buf = microdia_queue_next_buffer(queue, buf);
637 if (buf == NULL)
638 dev->vframes_dropped++;
642 urb->dev = dev->udev;
644 ret = usb_submit_urb(urb, GFP_ATOMIC);
646 if (ret != 0) {
647 UDIA_ERROR("Error (%d) re-submitting urb in "
648 "microdia_isoc_handler.\n", ret);
654 * @param dev Device structure
656 * @brief Clean-up all the ISOC buffers
658 * This function permits to clean-up all the ISOC buffers.
660 void usb_microdia_isoc_cleanup(struct usb_microdia *dev)
662 int i;
663 struct urb *urb;
665 UDIA_DEBUG("Isoc cleanup\n");
667 if (dev == NULL)
668 return;
670 for (i = 0; i < MAX_ISO_BUFS; i++) {
671 urb = dev->isobuf[i].urb;
672 if (urb == NULL)
673 continue;
675 usb_kill_urb(urb);
677 kfree(dev->isobuf[i].data);
679 usb_free_urb(urb);
681 dev->isobuf[i].urb = NULL;
688 * @param dev Device structure
689 * @param index Choice of the interface
691 * @returns 0 if all is OK
693 * @brief Send the message SET_FEATURE and choose the interface
695 * This function permits to send the message SET_FEATURE on the USB bus.
697 int usb_microdia_set_feature(struct usb_microdia *dev, int index)
699 int result;
700 struct usb_device *udev = dev->udev;
702 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
703 USB_REQ_SET_FEATURE,
704 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
705 USB_DEVICE_REMOTE_WAKEUP,
706 index,
707 NULL,
709 500);
711 if (result < 0)
712 UDIA_ERROR("SET FEATURE fail !\n");
713 else
714 UDIA_DEBUG("SET FEATURE\n");
716 return result;
721 * @param dev Device structure
723 * @returns 0 if all is OK
725 * @brief Send the message SET_CONFIGURATION
727 * This function permits to send the message SET_CONFIGURATION on the USB bus.
729 int usb_microdia_set_configuration(struct usb_microdia *dev)
731 int result;
732 struct usb_device *udev = dev->udev;
734 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
735 USB_REQ_SET_CONFIGURATION,
736 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
738 udev->config[0].desc.bConfigurationValue,
739 NULL,
741 500);
743 if (result < 0)
744 UDIA_ERROR("SET CONFIGURATION fail !\n");
745 else
746 UDIA_DEBUG("SET CONFIGURATION %d\n", udev->config[0].desc.bConfigurationValue);
748 return result;
753 * @param dev Device structure
754 * @param value register to write to
755 * @param data
756 * @param length number of bytes
758 * @returns 0 if all is OK
760 * @brief Write a 16-bit value to a 16-bit register
762 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
764 int usb_microdia_control_write(struct usb_microdia *dev, __u16 value, __u8 *data, __u16 length)
766 int result;
767 struct usb_device *udev = dev->udev;
769 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
770 0x08,
771 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
772 value,
773 0x00,
774 data,
775 length,
776 500);
778 if (result < 0)
779 UDIA_ERROR("Write register failed index = 0x%02X\n", value);
781 return result;
785 * @param dev Device structure
786 * @param index register to read from
787 * @param data
788 * @param length number of bytes
790 * @returns 0 if all is OK
792 * @brief Read a 16-bit value from a 16-bit register
794 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
796 int usb_microdia_control_read(struct usb_microdia *dev, __u16 index, __u8 *data, __u16 length)
798 int result;
800 struct usb_device *udev = dev->udev;
802 *data = 0;
804 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
805 0x00,
806 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
807 index,
808 0x00,
809 data,
810 length,
811 500);
813 if (result < 0)
814 UDIA_ERROR("Read register failed 0x%02X\n", index);
816 return result;
821 * @param dev
823 * @returns 0 if all is OK
825 * @brief Set the default value about the video settings.
827 * This function permits to set the video settings for each video camera model.
830 static int usb_microdia_default_settings(struct usb_microdia *dev)
832 struct v4l2_pix_format *def_fmt;
834 dev->vframes_overflow = 0;
835 dev->vframes_incomplete = 0;
836 dev->vframes_dropped = 0;
838 dev->queue.min_buffers = min_buffers;
839 dev->queue.max_buffers = max_buffers;
841 def_fmt = v4l2_enum_supported_formats(dev, 0);
843 switch (dev->webcam_model) {
844 default:
845 dev->vsettings.fps = fps;
846 dev->vsettings.vflip = vflip;
847 dev->vsettings.hflip = hflip;
848 dev->vsettings.brightness = brightness & 0xffff;
849 dev->vsettings.contrast = contrast & 0xffff;
850 dev->vsettings.whiteness = whiteness & 0xffff;
851 dev->vsettings.exposure = exposure & 0xffff;
852 dev->vsettings.sharpness = sharpness & 0x3f;
853 dev->vsettings.rgb_gain[0] = (rgb_gain >> 16) & 0x7f;
854 dev->vsettings.rgb_gain[1] = (rgb_gain >> 8) & 0x7f;
855 dev->vsettings.rgb_gain[2] = (rgb_gain >> 8) & 0x7f;
856 dev->vsettings.rgb_gain[3] = rgb_gain & 0x7f;
857 dev->vsettings.auto_exposure = auto_exposure & 1;
858 dev->vsettings.auto_whitebalance = auto_whitebalance & 1;
859 dev->vsettings.hue = 0xffff;
861 if (def_fmt) {
862 memcpy(&(dev->vsettings.format),
863 def_fmt,
864 sizeof(struct v4l2_pix_format));
867 sn9c20x_set_resolution(dev, 640, 480);
868 break;
870 return 0;
874 * @brief Load the driver
876 * @param interface
877 * @param id
879 * @returns 0 if all is OK
881 * This function detects the device and allocate the buffers for the device
882 * and the video interface.
884 static int usb_microdia_probe(struct usb_interface *interface, const struct usb_device_id *id)
886 int i;
887 int ret;
888 size_t buffer_size;
890 int vendor_id;
891 int product_id;
892 int bNumInterfaces;
894 struct usb_microdia *dev = NULL;
895 struct usb_device *udev = interface_to_usbdev(interface);
896 struct usb_host_interface *iface_desc;
897 struct usb_endpoint_descriptor *endpoint;
898 struct microdia_camera *camera = NULL;
900 /* Get USB VendorID and ProductID */
901 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
902 product_id = le16_to_cpu(udev->descriptor.idProduct);
904 /* Check if we can handle this device */
905 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
906 vendor_id, product_id, interface->cur_altsetting->desc.bInterfaceNumber);
909 //The interface are probed one by one.
910 // We are interested in the video interface (always the interface '0')
911 // The interfaces '1' or '2' (if presents) are the audio control.
913 if (interface->cur_altsetting->desc.bInterfaceNumber > 0) {
914 ret = -ENODEV;
915 goto error;
918 /* Detect device */
919 camera = find_camera(CAMERA_MODEL(vendor_id, product_id));
920 if (camera == NULL) {
921 UDIA_INFO("Camera %04X:%04X not supported.\n",
922 vendor_id, product_id);
923 ret = -ENODEV;
924 goto error;
927 UDIA_INFO("Microdia USB 2.0 Webcam - %04X:%04X plugged-in.\n",
928 vendor_id, product_id);
932 // Allocate structure, initialize pointers, mutexes, etc.
933 // and link it to the usb_device
935 dev = kzalloc(sizeof(struct usb_microdia), GFP_KERNEL);
937 if (dev == NULL) {
938 UDIA_ERROR("Out of memory !\n");
939 ret = -ENOMEM;
940 goto error;
943 /* Init mutexes, spinlock, etc. */
944 mutex_init(&dev->mutex);
945 kref_init(&dev->vopen);
947 /* Save pointers */
948 dev->webcam_model = camera->model;
949 dev->webcam_type = camera->type;
950 if (dev->webcam_model == CAMERA_MODEL(USB_0C45_VID, USB_6260_PID))
951 dev->frame_size_divisor = MICRODIA_FRAME_SIZE_DIVISOR_6260;
952 else
953 dev->frame_size_divisor = MICRODIA_FRAME_SIZE_DIVISOR_DEFAULT;
954 dev->initialize = camera->initialize;
955 dev->sensor_init = camera->sensor_init;
956 dev->stop_stream = camera->stop_stream;
957 dev->start_stream = camera->start_stream;
958 dev->set_contrast = camera->set_contrast == NULL ?
959 sn9c20x_set_contrast : camera->set_contrast;
960 dev->set_brightness = camera->set_brightness == NULL ?
961 sn9c20x_set_brightness : camera->set_brightness;
962 dev->set_gamma = camera->set_gamma == NULL ?
963 sn9c20x_set_gamma : camera->set_gamma;
964 dev->set_sharpness = camera->set_sharpness == NULL ?
965 sn9c20x_set_sharpness : camera->set_sharpness;
966 dev->set_rgb_gain = camera->set_rgb_gain == NULL ?
967 sn9c20x_set_rgb_gain : camera->set_rgb_gain;
968 dev->set_exposure = camera->set_exposure == NULL ?
969 sn9c20x_set_exposure : camera->set_exposure;
970 if (flip_detect) {
971 UDIA_INFO("Rotate detection enabled\n");
972 dev->flip_detect = camera->flip_detect;
974 dev->set_hvflip = camera->set_hvflip;
975 dev->set_auto_exposure = camera->set_auto_exposure;
976 dev->set_auto_whitebalance = camera->set_auto_whitebalance;
977 dev->udev = udev;
978 dev->interface = interface;
980 dev->sensor_slave_address = camera->sensor_slave_address;
981 dev->sensor_flags = camera->sensor_flags;
982 dev->supported_fmts = camera->supported_fmts;
984 /* Read the product release */
985 dev->release = le16_to_cpu(udev->descriptor.bcdDevice);
986 UDIA_DEBUG("Release: %04x\n", dev->release);
988 /* How many interfaces (1 or 3) ? */
989 bNumInterfaces = udev->config->desc.bNumInterfaces;
990 UDIA_DEBUG("Number of interfaces : %d\n", bNumInterfaces);
993 /* Switch on the camera (to detect size of buffers) */
994 dev_microdia_camera_on(dev);
997 // Set up the endpoint information
998 // use only the first int-in and isoc-in endpoints
999 // for the current alternate setting
1001 iface_desc = interface->cur_altsetting;
1003 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
1004 endpoint = &iface_desc->endpoint[i].desc;
1006 if (!dev->int_in_endpointAddr
1007 && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
1008 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
1009 /* we found an interrupt in endpoint */
1010 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
1012 dev->int_in_size = buffer_size;
1013 dev->int_in_endpointAddr = (endpoint->bEndpointAddress & 0xf);
1016 if (!dev->isoc_in_endpointAddr
1017 && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
1018 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)) {
1019 /* we found an isoc in endpoint */
1020 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
1022 dev->isoc_in_size = buffer_size;
1023 dev->isoc_in_endpointAddr = (endpoint->bEndpointAddress & 0xf);
1027 if (!(dev->int_in_endpointAddr && dev->isoc_in_endpointAddr)) {
1028 UDIA_ERROR("Could not find both int-in and isoc-in endpoints\n");
1029 ret = -ENODEV;
1030 goto free_dev;
1033 usb_microdia_default_settings(dev);
1035 dev_microdia_camera_off(dev);
1037 /* Initialize the video device */
1038 dev->vdev = video_device_alloc();
1040 if (!dev->vdev) {
1041 ret = -ENOMEM;
1042 goto free_dev;
1045 /* Initialize the camera */
1046 dev_microdia_initialize_device(dev);
1048 /* Register the video device */
1049 ret = v4l_microdia_register_video_device(dev);
1051 if (ret)
1052 goto free_dev;
1054 /* Create the entries in the sys filesystem */
1055 microdia_create_sysfs_files(dev->vdev);
1057 #ifdef CONFIG_MICRODIA_DEBUGFS
1058 microdia_create_debugfs_files(dev);
1059 #endif
1061 /* Save our data pointer in this interface device */
1062 usb_set_intfdata(interface, dev);
1064 return 0;
1066 free_dev:
1067 kref_put(&dev->vopen, usb_microdia_delete);
1068 error:
1069 return ret;
1072 void usb_microdia_delete(struct kref *kref)
1074 struct usb_microdia *dev;
1075 dev = container_of(kref, struct usb_microdia, vopen);
1077 if (dev->vdev != NULL) {
1078 microdia_remove_sysfs_files(dev->vdev);
1079 #ifdef CONFIG_MICRODIA_DEBUGFS
1080 microdia_remove_debugfs_files(dev);
1081 #endif
1082 v4l_microdia_unregister_video_device(dev);
1084 kfree(dev);
1088 * @param interface
1090 * @brief This function is called when the device is disconnected
1091 * or when the kernel module is unloaded.
1093 static void usb_microdia_disconnect(struct usb_interface *interface)
1095 struct usb_microdia *dev = usb_get_intfdata(interface);
1097 UDIA_INFO("Microdia USB 2.0 Webcam unplugged\n");
1099 usb_set_intfdata(interface, NULL);
1101 mutex_lock(&open_lock);
1102 kref_put(&dev->vopen, usb_microdia_delete);
1103 mutex_unlock(&open_lock);
1108 * @var usb_microdia_driver
1110 * This variable contains some callback
1112 static struct usb_driver usb_microdia_driver = {
1113 .name = "usb_microdia_driver",
1114 .probe = usb_microdia_probe,
1115 .disconnect = usb_microdia_disconnect,
1116 .id_table = microdia_table,
1119 module_param(fps, int, 0444); /**< @brief Module parameter frames per second */
1120 module_param(hflip, int, 0444); /**< @brief Module parameter horizontal flip process */
1121 module_param(vflip, int, 0444); /**< @brief Module parameter vertical flip process */
1122 module_param(flip_detect, int, 0444); /**< @brief Module parameter flip detect */
1123 module_param(auto_exposure, int, 0444); /**< @brief Module parameter automatic exposure control */
1124 module_param(auto_whitebalance, int, 0444); /**< @brief Module parameter automatic whitebalance control */
1125 module_param(brightness, int, 0444); /**< @brief Module parameter brightness */
1126 module_param(whiteness, int, 0444); /**< @brief Module parameter whiteness */
1127 module_param(contrast, int, 0444); /**< @brief Module parameter contrast */
1128 module_param(exposure, int, 0444); /**< @brief Module parameter exposure */
1129 module_param(sharpness, int, 0444); /**< @brief Module parameter sharpness */
1130 module_param(rgb_gain, int, 0444); /**< @brief Module parameter red/green/blue gain */
1132 module_param(min_buffers, int, 0444);
1133 module_param(max_buffers, int, 0444);
1135 module_param(log_level, byte, 0444);
1138 * @returns 0 if all is OK
1140 * @brief Initialize the driver.
1142 * This function is called at first.
1143 * This function permits to define the default values from the command line.
1145 static int __init usb_microdia_init(void)
1147 int result;
1149 UDIA_INFO("Microdia USB 2.0 webcam driver loaded\n");
1151 #ifdef CONFIG_MICRODIA_DEBUGFS
1152 microdia_init_debugfs();
1153 #endif
1155 if (fps < 10 || fps > 30) {
1156 UDIA_WARNING("Framerate out of bounds [10-30]! Defaulting to 25\n");
1157 fps = 25;
1160 if (vflip != 0 && vflip != 1) {
1161 UDIA_WARNING("Vertical flip should be 0 or 1! Defaulting to 0\n");
1162 vflip = 0;
1165 if (hflip != 0 && hflip != 1) {
1166 UDIA_WARNING("Horizontal flip should be 0 or 1! Defaulting to 0\n");
1167 hflip = 0;
1170 if (sharpness < 0 || sharpness > 0x3f) {
1171 UDIA_WARNING("Sharpness should be 0 to 63 ! Defaulting to 31\n");
1172 sharpness = 0x1f;
1175 if ((rgb_gain >> 16) < 0 || (rgb_gain >> 16) > 0x7f) {
1176 UDIA_WARNING("Red Gain should be 0 to 127 ! Defaulting to 32\n");
1177 rgb_gain = (rgb_gain & 0x0000ffff) | 0x200000;
1180 if (((rgb_gain >> 8) & 0xFF) < 0 || ((rgb_gain >> 8) & 0xFF) > 0x7f) {
1181 UDIA_WARNING("Green Gain should be 0 to 127 ! Defaulting to 32\n");
1182 rgb_gain = (rgb_gain & 0x00ff00ff) | 0x002000;
1185 if ((rgb_gain & 0xFF) < 0 || (rgb_gain & 0xFF) > 0x7f) {
1186 UDIA_WARNING("Blue Gain should be 0 to 127 ! Defaulting to 32\n");
1187 rgb_gain = (rgb_gain & 0x00ffff00) | 0x20;
1190 if (auto_exposure != 0 && auto_exposure != 1) {
1191 UDIA_WARNING("Automatic exposure should be 0 or 1! "
1192 "Defaulting to 1\n");
1193 auto_exposure = 1;
1196 if (auto_whitebalance != 0 && auto_whitebalance != 1) {
1197 UDIA_WARNING("Automatic whitebalance should be 0 or 1! "
1198 "Defaulting to 1\n");
1199 auto_whitebalance = 1;
1202 if (min_buffers < 2) {
1203 UDIA_WARNING("Minimum buffers can't be less then 2! "
1204 "Defaulting to 2\n");
1205 min_buffers = 2;
1209 if (min_buffers > max_buffers) {
1210 UDIA_WARNING("Minimum buffers must be less then or equal to "
1211 "max buffers! Defaulting to 2, 10\n");
1212 min_buffers = 2;
1213 max_buffers = 5;
1216 /* Register the driver with the USB subsystem */
1217 result = usb_register(&usb_microdia_driver);
1219 if (result)
1220 UDIA_ERROR("usb_register failed ! Error number %d\n", result);
1222 UDIA_INFO(DRIVER_VERSION " : " DRIVER_DESC "\n");
1224 return result;
1229 * @brief Close the driver
1231 * This function is called at last when you unload the driver.
1233 static void __exit usb_microdia_exit(void)
1235 UDIA_INFO("usb_microdia_exit: Microdia USB 2.0 webcam driver unloaded\n");
1237 #ifdef CONFIG_MICRODIA_DEBUGFS
1238 microdia_uninit_debugfs();
1239 #endif
1241 /* Deregister this driver with the USB subsystem */
1242 usb_deregister(&usb_microdia_driver);
1246 module_init(usb_microdia_init); /**< @brief Module initialize */
1247 module_exit(usb_microdia_exit); /**< @brief Module exit */
1250 MODULE_PARM_DESC(fps, "Frames per second [10-30]"); /**< @brief Description of 'fps' parameter */
1251 MODULE_PARM_DESC(hflip, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1252 MODULE_PARM_DESC(vflip, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1253 MODULE_PARM_DESC(flip_detect, "Image flip detection"); /**< @brief Description of 'vflip_detect' parameter */
1254 MODULE_PARM_DESC(auto_exposure, "Automatic exposure control"); /**< @brief Description of 'auto_exposure' parameter */
1255 MODULE_PARM_DESC(auto_whitebalance, "Automatic whitebalance"); /**< @brief Description of 'auto_whitebalance' parameter */
1256 MODULE_PARM_DESC(brightness, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1257 MODULE_PARM_DESC(whiteness, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1258 MODULE_PARM_DESC(exposure, "Exposure setting"); /**< @brief Description of 'exposure' parameter */
1259 MODULE_PARM_DESC(contrast, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1260 MODULE_PARM_DESC(sharpness, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */
1261 MODULE_PARM_DESC(rgb_gain, "Red/Green/Blue Gain setting"); /**< @brief Description of 'RGB Gain' parameter */
1263 MODULE_PARM_DESC(min_buffers, "Minimum number of image buffers");
1264 MODULE_PARM_DESC(max_buffers, "Maximum number of image buffers");
1265 MODULE_PARM_DESC(log_level, " <n>\n"
1266 "Driver log level\n"
1267 "1 = info (default)\n"
1268 "2 = warning\n"
1269 "4 = error\n"
1270 "8 = debug\n"
1271 "16 = stream\n");
1273 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1274 MODULE_AUTHOR(DRIVER_AUTHOR); /**< @brief Driver is written by Nicolas VIVIEN */
1275 MODULE_DESCRIPTION(DRIVER_DESC); /**< @brief Define the description of the driver */
1276 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT); /**< @brief List of supported device */