Reenable 624e (sensor SOI968)
[microdia.git] / microdia-usb.c
blob65e6ea110acb0d39a12efb1d7cb5bae03ce475d1
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 bulk
53 * Module parameter to enable/disable bulk transfers
55 static int bulk;
57 /**
58 * @var hflip
59 * Module parameter to enable/disable the horizontal flip process
61 static int hflip;
63 /**
64 * @var flip_detect
65 * Module parameter to enable/disable vflip detection
67 static int flip_detect;
69 /**
70 * @var vflip
71 * Module parameter to enable/disable the vertical flip process
73 static int vflip;
75 /**
76 * @var brightness
77 * Module parameter to set the brightness
79 static int brightness = MICRODIA_PERCENT(50, 0xFFFF);
81 /**
82 * @var whiteness
83 * Module parameter to set the whiteness
85 static int whiteness = MICRODIA_PERCENT(20, 0xFFFF);
87 /**
88 * @var contrast
89 * Module parameter to set the contrast
91 static int contrast = MICRODIA_PERCENT(50, 0xFFFF);
93 /**
94 * @var exposure
95 * Module parameter to set the exposure
97 /* static int exposure = MICRODIA_PERCENT(20, 0xFFFF); */
98 static int exposure = MICRODIA_PERCENT(2, 0xFFFF);
101 * @var sharpness
102 * Module parameter to set the sharpness
104 static int sharpness = MICRODIA_PERCENT(50, 0x3F);
107 * @var rgb_gain
108 * Module parameter to set the red/green/blue gain
110 static int rgb_gain = MICRODIA_PERCENT(25, 0x7F) |
111 (MICRODIA_PERCENT(25, 0x7F) << 8) |
112 (MICRODIA_PERCENT(25, 0x7F) << 16);
115 * @var min_buffers
116 * Module parameter to set the minimum number of image buffers
118 static int min_buffers = 2;
121 * @var max_buffers
122 * Module parameter to set the maximum number of image buffers
124 static int max_buffers = 5;
127 * @var auto_exposure
128 * Module parameter to set the exposure
130 static int auto_exposure = 1;
133 * @var auto_whitebalance
134 * Module parameter to set the exposure
136 static int auto_whitebalance = 1;
139 * @var log_level
140 * Module parameter to set the log level
142 __u8 log_level = 1;
146 * @var microdia_table
147 * Define all the hotplug supported devices by this driver
149 static struct usb_device_id microdia_table[] = {
150 /* SN9C201 + MI1300 */
151 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6240_PID, SN9C20X_BRIDGE)},
152 /* SN9C201 + MI1310 */
153 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6242_PID, SN9C20X_BRIDGE)},
154 /* SN9C201 + S5K4AAFX */
155 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6243_PID, SN9C20X_BRIDGE)},
156 /* SN9C201 + OV9655 */
157 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6248_PID, SN9C20X_BRIDGE)},
158 /* SN9C201 + CX1332 */
159 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_624B_PID, SN9C20X_BRIDGE)},
160 /* SN9C201 + MI1320 */
161 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_624C_PID, SN9C20X_BRIDGE)},
162 /* SN9C201 + SOI968 */
163 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_624E_PID, SN9C20X_BRIDGE)},
164 /* SN9C201 + OV9650 */
165 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_624F_PID, SN9C20X_BRIDGE)},
166 /* SN9C201 + OV9650 */
167 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6253_PID, SN9C20X_BRIDGE)},
168 /* SN9C201 + OV7670ISP */
169 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6260_PID, SN9C20X_BRIDGE)},
170 /* SN9C201 + OM6802 */
171 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6262_PID, SN9C20X_BRIDGE)},
172 /* SN9C201 + MI0360/MT9V111 */
173 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6270_PID, SN9C20X_BRIDGE)},
174 /* SN9C201 + S5K53BEB */
175 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_627A_PID, SN9C20X_BRIDGE)},
176 /* SN9C201 + OV7660 */
177 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_627B_PID, SN9C20X_BRIDGE)},
178 /* SN9C201 + HV7131R */
179 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_627C_PID, SN9C20X_BRIDGE)},
180 /* EEPROM */
181 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_627F_PID, SN9C20X_BRIDGE)},
182 /* SN9C202 + MI1300 */
183 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6280_PID, SN9C20X_BRIDGE)},
184 /* SN9C202 + MI1310 */
185 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6282_PID, SN9C20X_BRIDGE)},
186 /* SN9C202 + S5K4AAFX */
187 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6283_PID, SN9C20X_BRIDGE)},
188 /* SN9C202 + OV9655 */
189 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_6288_PID, SN9C20X_BRIDGE)},
190 /* SN9C202 + ICM107 */
191 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_628A_PID, SN9C20X_BRIDGE)},
192 /* SN9C202 + CX1332 */
193 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_628B_PID, SN9C20X_BRIDGE)},
194 /* SN9C202 + MI1320 */
195 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_628C_PID, SN9C20X_BRIDGE)},
196 /* SN9C202 + SOI968 */
197 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_628E_PID, SN9C20X_BRIDGE)},
198 /* SN9C202 + OV9650 */
199 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_628F_PID, SN9C20X_BRIDGE)},
200 /* SN9C202 + OV7670ISP */
201 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62A0_PID, SN9C20X_BRIDGE)},
202 /* SN9C202 + OM6802 */
203 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62A2_PID, SN9C20X_BRIDGE)},
204 /* SN9C202 + MI0360/MT9V111 */
205 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62B0_PID, SN9C20X_BRIDGE)},
206 /* SN9C202 + OV9655 */
207 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62B3_PID, SN9C20X_BRIDGE)},
208 /* SN9C202 + S5K53BEB */
209 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62BA_PID, SN9C20X_BRIDGE)},
210 /* SN9C202 + OV7660 */
211 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62BB_PID, SN9C20X_BRIDGE)},
212 /* SN9C202 + HV7131R */
213 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62BC_PID, SN9C20X_BRIDGE)},
214 /* SN9C202 + OV7663 */
215 {MICRODIA_USB_DEVICE(USB_0C45_VID, USB_62BE_PID, SN9C20X_BRIDGE)},
216 /* => 628f (SN9C202 + OV9650) */
217 {MICRODIA_USB_DEVICE(USB_045E_VID, USB_00F4_PID, SN9C20X_BRIDGE)},
218 /* => 627b (SN9C201 + OV7660) */
219 {MICRODIA_USB_DEVICE(USB_145F_VID, USB_013D_PID, SN9C20X_BRIDGE)},
220 /* => 62be (SN9C202 + OV7663 + EEPROM) */
221 {MICRODIA_USB_DEVICE(USB_04F2_VID, USB_A128_PID, SN9C20X_BRIDGE)},
226 MODULE_DEVICE_TABLE(usb, microdia_table); /**< Define the supported devices */
228 DEFINE_MUTEX(open_lock); /**< Define global mutex */
230 struct usb_endpoint_descriptor *find_endpoint(struct usb_host_interface *alts,
231 __u8 epaddr)
233 unsigned long i;
234 struct usb_endpoint_descriptor *ep;
236 for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
237 ep = &alts->endpoint[i].desc;
238 if ((ep->bEndpointAddress & 0xf) == epaddr) {
239 UDIA_INFO("Found Endpoint 0x%X\n", epaddr);
240 return ep;
244 return NULL;
247 * @param dev Device structure
248 * @param ep Usb endpoint structure
250 * @returns 0 if all is OK
252 * @brief Initilize an isochronous pipe.
254 * This function permits to initialize an URB transfert (or isochronous pipe).
256 int usb_microdia_isoc_init(struct usb_microdia *dev,
257 struct usb_endpoint_descriptor *ep)
259 int i, j;
260 __u16 iso_max_frame_size;
261 struct urb *urb;
262 struct usb_device *udev;
264 udev = dev->udev;
266 UDIA_DEBUG("usb_microdia_isoc_init()\n");
268 iso_max_frame_size =
269 max_packet_sz(le16_to_cpu(le16_to_cpu(ep->wMaxPacketSize))) *
270 hb_multiplier(le16_to_cpu(le16_to_cpu(ep->wMaxPacketSize)));
272 for (i = 0; i < MAX_URBS; i++) {
273 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
275 if (urb == NULL) {
276 UDIA_ERROR("Failed to allocate URB %d\n", i);
277 usb_microdia_uninit_urbs(dev);
278 return -ENOMEM;
281 urb->interval = 1;
282 urb->dev = udev;
283 urb->pipe = usb_rcvisocpipe(udev, ep->bEndpointAddress);
284 urb->transfer_flags = URB_ISO_ASAP;
285 urb->transfer_buffer_length = iso_max_frame_size * ISO_FRAMES_PER_DESC;
286 urb->complete = usb_microdia_completion_handler;
287 urb->context = dev;
288 urb->start_frame = 0;
289 urb->number_of_packets = ISO_FRAMES_PER_DESC;
291 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
292 urb->iso_frame_desc[j].offset = j * iso_max_frame_size;
293 urb->iso_frame_desc[j].length = iso_max_frame_size;
296 dev->urbs[i].data = kzalloc(urb->transfer_buffer_length,
297 GFP_KERNEL);
298 if (dev->urbs[i].data == NULL) {
299 usb_microdia_uninit_urbs(dev);
300 return -ENOMEM;
303 urb->transfer_buffer = dev->urbs[i].data;
304 dev->urbs[i].urb = urb;
307 return 0;
310 int usb_microdia_bulk_init(struct usb_microdia *dev,
311 struct usb_endpoint_descriptor *ep)
313 struct urb *urb;
314 unsigned int pipe, i;
315 __u16 psize;
316 __u32 size;
317 psize = max_packet_sz(le16_to_cpu(le16_to_cpu(ep->wMaxPacketSize)));
318 size = psize * ISO_FRAMES_PER_DESC;
319 pipe = usb_rcvbulkpipe(dev->udev, ep->bEndpointAddress);
321 for (i = 0; i < MAX_URBS; ++i) {
322 urb = usb_alloc_urb(0, GFP_KERNEL);
323 if (urb == NULL) {
324 usb_microdia_uninit_urbs(dev);
325 return -ENOMEM;
328 dev->urbs[i].data = kzalloc(size, GFP_KERNEL);
330 usb_fill_bulk_urb(urb, dev->udev, pipe,
331 dev->urbs[i].data, size,
332 usb_microdia_completion_handler,
333 dev);
335 dev->urbs[i].urb = urb;
338 return 0;
341 int usb_microdia_init_urbs(struct usb_microdia *dev)
343 int ret, i;
344 __u8 value;
345 struct usb_endpoint_descriptor *ep;
346 struct usb_interface *intf = dev->interface;
348 ret = usb_microdia_control_read(dev, 0x1061, &value, 1);
349 if (ret < 0)
350 return ret;
352 if (!bulk) {
353 ep = find_endpoint(usb_altnum_to_altsetting(intf, 8), MICRODIA_VID_ISOC);
355 if (ep == NULL)
356 return -EIO;
358 ret = usb_set_interface(dev->udev, 0, 8);
359 if (ret < 0)
360 return ret;
362 value |= 0x01;
363 ret = usb_microdia_control_write(dev, 0x1061, &value, 1);
364 if (ret < 0)
365 return ret;
367 ret = usb_microdia_isoc_init(dev, ep);
368 } else {
369 ep = find_endpoint(usb_altnum_to_altsetting(intf, 0), MICRODIA_BULK);
370 if (ep == NULL)
371 return -EIO;
373 ret = usb_set_interface(dev->udev, 0, 0);
374 if (ret < 0)
375 return ret;
377 value &= ~0x01;
378 ret = usb_microdia_control_write(dev, 0x1061, &value, 1);
379 if (ret < 0)
380 return ret;
382 ret = usb_microdia_bulk_init(dev, ep);
385 if (ret < 0)
386 return ret;
388 for (i = 0; i < MAX_URBS; i++) {
389 ret = usb_submit_urb(dev->urbs[i].urb, GFP_KERNEL);
390 if (ret)
391 UDIA_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
394 return 0;
398 * @param dev Device structure
400 * @brief Clean-up all the ISOC buffers
402 * This function permits to clean-up all the ISOC buffers.
404 void usb_microdia_uninit_urbs(struct usb_microdia *dev)
406 int i;
407 struct urb *urb;
409 UDIA_DEBUG("Isoc cleanup\n");
411 if (dev == NULL)
412 return;
414 for (i = 0; i < MAX_URBS; i++) {
415 urb = dev->urbs[i].urb;
416 if (urb == NULL)
417 continue;
418 usb_kill_urb(urb);
419 kfree(dev->urbs[i].data);
420 usb_free_urb(urb);
421 dev->urbs[i].urb = NULL;
425 void usb_microdia_assemble_video(struct usb_microdia *dev,
426 unsigned char *transfer, unsigned int transfer_length,
427 struct microdia_buffer *buf)
429 void *mem = NULL;
430 unsigned char frame_header[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
431 struct microdia_video_queue *queue = &dev->queue;
433 if (memcmp(transfer, frame_header, 6) == 0 && transfer_length == 64) {
434 UDIA_INFO("Frame Resolution: %dx%d\n",
435 transfer[0x3a] << 4, transfer[0x3b] << 3);
436 UDIA_INFO("Frame Size: %d\n", buf->buf.bytesused);
437 if (buf->buf.bytesused != 0)
438 buf->state = MICRODIA_BUF_STATE_DONE;
439 } else {
440 if (buf->state != MICRODIA_BUF_STATE_ACTIVE)
441 buf->state = MICRODIA_BUF_STATE_ACTIVE;
443 if (transfer_length + buf->buf.bytesused > buf->buf.length) {
444 UDIA_WARNING("Frame Buffer overflow!\n");
445 dev->vframes_overflow++;
446 buf->state = MICRODIA_BUF_STATE_DONE;
448 transfer_length = min(buf->buf.length - buf->buf.bytesused,
449 transfer_length);
450 mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
451 memcpy(mem, transfer, transfer_length);
452 buf->buf.bytesused += transfer_length;
456 * @param urb URB structure
458 * @brief ISOC handler
460 * This function is called as an URB transfert is complete (Isochronous pipe).
461 * So, the traitement is done in interrupt time, so it has be fast, not crash,
462 * and not stall. Neat.
464 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
465 void usb_microdia_completion_handler(struct urb *urb, struct pt_regs *regs)
466 #else
467 void usb_microdia_completion_handler(struct urb *urb)
468 #endif
470 int i;
471 int ret;
472 unsigned long flags;
474 unsigned char *transfer = NULL;
475 unsigned int transfer_length;
477 struct microdia_buffer *buf = NULL;
478 struct usb_microdia *dev = urb->context;
479 struct microdia_video_queue *queue = &dev->queue;
481 UDIA_STREAM("Isoc handler\n");
483 switch (urb->status) {
484 case 0:
485 break;
487 default:
488 UDIA_WARNING("Non-zero status (%d) in video "
489 "completion handler.\n", urb->status);
491 case -ENOENT: /* usb_kill_urb() called. */
492 if (dev->frozen)
493 return;
495 case -ECONNRESET: /* usb_unlink_urb() called. */
496 case -ESHUTDOWN: /* The endpoint is being disabled. */
497 microdia_queue_cancel(queue, urb->status == -ESHUTDOWN);
498 return;
501 spin_lock_irqsave(&queue->irqlock, flags);
502 if (!list_empty(&queue->irqqueue))
503 buf = list_first_entry(&queue->irqqueue, struct microdia_buffer,
504 queue);
505 spin_unlock_irqrestore(&queue->irqlock, flags);
506 if (!bulk) {
507 for (i = 0; i < urb->number_of_packets; i++) {
508 if (urb->iso_frame_desc[i].status != 0) {
509 UDIA_ERROR("Iso frame %d of USB has error %d\n",
510 i, urb->iso_frame_desc[i].status);
511 continue;
513 transfer_length = urb->iso_frame_desc[i].actual_length;
514 transfer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
515 if (buf == NULL)
516 continue;
518 usb_microdia_assemble_video(dev, transfer, transfer_length, buf);
519 if (buf->state == MICRODIA_BUF_STATE_DONE ||
520 buf->state == MICRODIA_BUF_STATE_ERROR) {
521 buf = microdia_queue_next_buffer(queue, buf);
522 if (buf == NULL)
523 dev->vframes_dropped++;
526 } else {
527 if (buf != NULL) {
528 usb_microdia_assemble_video(dev, urb->transfer_buffer,
529 urb->actual_length, buf);
530 if (buf->state == MICRODIA_BUF_STATE_DONE ||
531 buf->state == MICRODIA_BUF_STATE_ERROR) {
532 buf = microdia_queue_next_buffer(queue, buf);
533 if (buf == NULL)
534 dev->vframes_dropped++;
538 ret = usb_submit_urb(urb, GFP_ATOMIC);
540 if (ret != 0) {
541 UDIA_INFO("Error (%d) re-submitting urb in "
542 "microdia_isoc_handler.\n", ret);
547 * @param dev Device structure
548 * @param index Choice of the interface
550 * @returns 0 if all is OK
552 * @brief Send the message SET_FEATURE and choose the interface
554 * This function permits to send the message SET_FEATURE on the USB bus.
556 int usb_microdia_set_feature(struct usb_microdia *dev, int index)
558 int result;
559 struct usb_device *udev = dev->udev;
561 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
562 USB_REQ_SET_FEATURE,
563 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
564 USB_DEVICE_REMOTE_WAKEUP,
565 index,
566 NULL,
568 500);
570 if (result < 0)
571 UDIA_ERROR("SET FEATURE fail !\n");
572 else
573 UDIA_DEBUG("SET FEATURE\n");
575 return result;
580 * @param dev Device structure
582 * @returns 0 if all is OK
584 * @brief Send the message SET_CONFIGURATION
586 * This function permits to send the message SET_CONFIGURATION on the USB bus.
588 int usb_microdia_set_configuration(struct usb_microdia *dev)
590 int result;
591 struct usb_device *udev = dev->udev;
593 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
594 USB_REQ_SET_CONFIGURATION,
595 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
597 udev->config[0].desc.bConfigurationValue,
598 NULL,
600 500);
602 if (result < 0)
603 UDIA_ERROR("SET CONFIGURATION fail !\n");
604 else
605 UDIA_DEBUG("SET CONFIGURATION %d\n", udev->config[0].desc.bConfigurationValue);
607 return result;
612 * @param dev Device structure
613 * @param value register to write to
614 * @param data
615 * @param length number of bytes
617 * @returns 0 if all is OK
619 * @brief Write a 16-bit value to a 16-bit register
621 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
623 int usb_microdia_control_write(struct usb_microdia *dev, __u16 value, __u8 *data, __u16 length)
625 int result;
626 struct usb_device *udev = dev->udev;
628 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
629 0x08,
630 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
631 value,
632 0x00,
633 data,
634 length,
635 500);
637 if (result < 0)
638 UDIA_ERROR("Write register failed index = 0x%02X\n", value);
640 return result;
644 * @param dev Device structure
645 * @param index register to read from
646 * @param data
647 * @param length number of bytes
649 * @returns 0 if all is OK
651 * @brief Read a 16-bit value from a 16-bit register
653 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
655 int usb_microdia_control_read(struct usb_microdia *dev, __u16 index, __u8 *data, __u16 length)
657 int result;
659 struct usb_device *udev = dev->udev;
661 *data = 0;
663 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
664 0x00,
665 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
666 index,
667 0x00,
668 data,
669 length,
670 500);
672 if (result < 0)
673 UDIA_ERROR("Read register failed 0x%02X\n", index);
675 return result;
680 * @param dev
682 * @returns 0 if all is OK
684 * @brief Set the default value about the video settings.
686 * This function permits to set the video settings for each video camera model.
689 static int usb_microdia_default_settings(struct usb_microdia *dev)
691 dev->vframes_overflow = 0;
692 dev->vframes_incomplete = 0;
693 dev->vframes_dropped = 0;
695 dev->queue.min_buffers = min_buffers;
696 dev->queue.max_buffers = max_buffers;
698 dev->vsettings.fps = fps;
699 dev->vsettings.vflip = vflip;
700 dev->vsettings.hflip = hflip;
701 dev->vsettings.brightness = brightness & 0xffff;
702 dev->vsettings.contrast = contrast & 0xffff;
703 dev->vsettings.whiteness = whiteness & 0xffff;
704 dev->vsettings.exposure = exposure & 0xffff;
705 dev->vsettings.sharpness = sharpness & 0x3f;
706 dev->vsettings.rgb_gain[0] = (rgb_gain >> 16) & 0x7f;
707 dev->vsettings.rgb_gain[1] = (rgb_gain >> 8) & 0x7f;
708 dev->vsettings.rgb_gain[2] = (rgb_gain >> 8) & 0x7f;
709 dev->vsettings.rgb_gain[3] = rgb_gain & 0x7f;
710 dev->vsettings.auto_exposure = auto_exposure & 1;
711 dev->vsettings.auto_whitebalance = auto_whitebalance & 1;
712 dev->vsettings.hue = 0xffff;
714 dev->vsettings.format.width = 640;
715 dev->vsettings.format.height = 480;
716 dev->vsettings.format.bytesperline = 640 *
717 dev->camera.fmts[0].bpp;
718 dev->vsettings.format.sizeimage = 480 *
719 dev->vsettings.format.bytesperline;
720 dev->vsettings.format.pixelformat = dev->camera.fmts[0].pix_fmt;
721 dev->vsettings.format.colorspace = V4L2_COLORSPACE_SRGB;
722 dev->vsettings.format.priv = 0;
723 sn9c20x_set_resolution(dev, 640, 480);
725 return 0;
729 * @brief Load the driver
731 * @param interface
732 * @param id
734 * @returns 0 if all is OK
736 * This function detects the device and allocate the buffers for the device
737 * and the video interface.
739 static int usb_microdia_probe(struct usb_interface *interface, const struct usb_device_id *id)
741 int ret;
743 int vendor_id;
744 int product_id;
745 int bNumInterfaces;
747 struct usb_microdia *dev = NULL;
748 struct usb_device *udev = interface_to_usbdev(interface);
750 /* Get USB VendorID and ProductID */
751 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
752 product_id = le16_to_cpu(udev->descriptor.idProduct);
754 /* Check if we can handle this device */
755 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
756 vendor_id, product_id, interface->cur_altsetting->desc.bInterfaceNumber);
758 UDIA_INFO("Microdia USB 2.0 Webcam - %04X:%04X plugged-in.\n",
759 vendor_id, product_id);
763 // Allocate structure, initialize pointers, mutexes, etc.
764 // and link it to the usb_device
766 dev = kzalloc(sizeof(struct usb_microdia), GFP_KERNEL);
768 if (dev == NULL) {
769 UDIA_ERROR("Out of memory !\n");
770 ret = -ENOMEM;
771 goto error;
774 /* Init mutexes, spinlock, etc. */
775 mutex_init(&dev->mutex);
776 kref_init(&dev->vopen);
778 dev->udev = udev;
779 dev->interface = interface;
781 /* Read the product release */
782 dev->release = le16_to_cpu(udev->descriptor.bcdDevice);
783 UDIA_DEBUG("Release: %04x\n", dev->release);
785 /* How many interfaces (1 or 3) ? */
786 bNumInterfaces = udev->config->desc.bNumInterfaces;
787 UDIA_DEBUG("Number of interfaces : %d\n", bNumInterfaces);
789 /* Initialize the camera */
790 ret = dev_microdia_initialize_device(dev, id->driver_info);
791 if (ret < 0)
792 goto error;
794 /* Initialize the video device */
795 dev->vdev = video_device_alloc();
797 if (!dev->vdev) {
798 ret = -ENOMEM;
799 goto free_dev;
802 /* Register the video device */
803 ret = v4l_microdia_register_video_device(dev);
805 if (ret)
806 goto free_dev;
808 /* Create the entries in the sys filesystem */
809 microdia_create_sysfs_files(dev->vdev);
811 #ifdef CONFIG_MICRODIA_DEBUGFS
812 microdia_create_debugfs_files(dev);
813 #endif
815 /* Save our data pointer in this interface device */
816 usb_set_intfdata(interface, dev);
818 usb_microdia_default_settings(dev);
820 return 0;
822 free_dev:
823 kref_put(&dev->vopen, usb_microdia_delete);
824 error:
825 return ret;
828 void usb_microdia_delete(struct kref *kref)
830 struct usb_microdia *dev;
831 dev = container_of(kref, struct usb_microdia, vopen);
833 if (dev->vdev != NULL) {
834 microdia_remove_sysfs_files(dev->vdev);
835 #ifdef CONFIG_MICRODIA_DEBUGFS
836 microdia_remove_debugfs_files(dev);
837 #endif
838 v4l_microdia_unregister_video_device(dev);
840 kfree(dev);
844 * @param interface
846 * @brief This function is called when the device is disconnected
847 * or when the kernel module is unloaded.
849 static void usb_microdia_disconnect(struct usb_interface *interface)
851 struct usb_microdia *dev = usb_get_intfdata(interface);
853 UDIA_INFO("Microdia USB 2.0 Webcam unplugged\n");
855 usb_set_intfdata(interface, NULL);
857 mutex_lock(&open_lock);
858 kref_put(&dev->vopen, usb_microdia_delete);
859 mutex_unlock(&open_lock);
864 * @var usb_microdia_driver
866 * This variable contains some callback
868 static struct usb_driver usb_microdia_driver = {
869 .name = "usb_microdia_driver",
870 .probe = usb_microdia_probe,
871 .disconnect = usb_microdia_disconnect,
872 .id_table = microdia_table,
875 module_param(fps, int, 0444); /**< @brief Module parameter frames per second */
876 module_param(bulk, int, 0444);
877 module_param(hflip, int, 0444); /**< @brief Module parameter horizontal flip process */
878 module_param(vflip, int, 0444); /**< @brief Module parameter vertical flip process */
879 module_param(flip_detect, int, 0444); /**< @brief Module parameter flip detect */
880 module_param(auto_exposure, int, 0444); /**< @brief Module parameter automatic exposure control */
881 module_param(auto_whitebalance, int, 0444); /**< @brief Module parameter automatic whitebalance control */
882 module_param(brightness, int, 0444); /**< @brief Module parameter brightness */
883 module_param(whiteness, int, 0444); /**< @brief Module parameter whiteness */
884 module_param(contrast, int, 0444); /**< @brief Module parameter contrast */
885 module_param(exposure, int, 0444); /**< @brief Module parameter exposure */
886 module_param(sharpness, int, 0444); /**< @brief Module parameter sharpness */
887 module_param(rgb_gain, int, 0444); /**< @brief Module parameter red/green/blue gain */
889 module_param(min_buffers, int, 0444);
890 module_param(max_buffers, int, 0444);
892 module_param(log_level, byte, 0444);
895 * @returns 0 if all is OK
897 * @brief Initialize the driver.
899 * This function is called at first.
900 * This function permits to define the default values from the command line.
902 static int __init usb_microdia_init(void)
904 int result;
906 UDIA_INFO("Microdia USB 2.0 webcam driver loaded\n");
908 #ifdef CONFIG_MICRODIA_DEBUGFS
909 microdia_init_debugfs();
910 #endif
912 if (fps < 10 || fps > 30) {
913 UDIA_WARNING("Framerate out of bounds [10-30]! Defaulting to 25\n");
914 fps = 25;
917 if (bulk != 0 && bulk != 1) {
918 UDIA_WARNING("Bulk transfer should be 0 or 1! Defaulting to 0\n");
919 bulk = 0;
922 if (vflip != 0 && vflip != 1) {
923 UDIA_WARNING("Vertical flip should be 0 or 1! Defaulting to 0\n");
924 vflip = 0;
927 if (hflip != 0 && hflip != 1) {
928 UDIA_WARNING("Horizontal flip should be 0 or 1! Defaulting to 0\n");
929 hflip = 0;
932 if (sharpness < 0 || sharpness > 0x3f) {
933 UDIA_WARNING("Sharpness should be 0 to 63 ! Defaulting to 31\n");
934 sharpness = 0x1f;
937 if ((rgb_gain >> 16) < 0 || (rgb_gain >> 16) > 0x7f) {
938 UDIA_WARNING("Red Gain should be 0 to 127 ! Defaulting to 32\n");
939 rgb_gain = (rgb_gain & 0x0000ffff) | 0x200000;
942 if (((rgb_gain >> 8) & 0xFF) < 0 || ((rgb_gain >> 8) & 0xFF) > 0x7f) {
943 UDIA_WARNING("Green Gain should be 0 to 127 ! Defaulting to 32\n");
944 rgb_gain = (rgb_gain & 0x00ff00ff) | 0x002000;
947 if ((rgb_gain & 0xFF) < 0 || (rgb_gain & 0xFF) > 0x7f) {
948 UDIA_WARNING("Blue Gain should be 0 to 127 ! Defaulting to 32\n");
949 rgb_gain = (rgb_gain & 0x00ffff00) | 0x20;
952 if (auto_exposure != 0 && auto_exposure != 1) {
953 UDIA_WARNING("Automatic exposure should be 0 or 1! "
954 "Defaulting to 1\n");
955 auto_exposure = 1;
958 if (auto_whitebalance != 0 && auto_whitebalance != 1) {
959 UDIA_WARNING("Automatic whitebalance should be 0 or 1! "
960 "Defaulting to 1\n");
961 auto_whitebalance = 1;
964 if (min_buffers < 2) {
965 UDIA_WARNING("Minimum buffers can't be less then 2! "
966 "Defaulting to 2\n");
967 min_buffers = 2;
971 if (min_buffers > max_buffers) {
972 UDIA_WARNING("Minimum buffers must be less then or equal to "
973 "max buffers! Defaulting to 2, 10\n");
974 min_buffers = 2;
975 max_buffers = 5;
978 /* Register the driver with the USB subsystem */
979 result = usb_register(&usb_microdia_driver);
981 if (result)
982 UDIA_ERROR("usb_register failed ! Error number %d\n", result);
984 UDIA_INFO(DRIVER_VERSION " : " DRIVER_DESC "\n");
986 return result;
991 * @brief Close the driver
993 * This function is called at last when you unload the driver.
995 static void __exit usb_microdia_exit(void)
997 UDIA_INFO("usb_microdia_exit: Microdia USB 2.0 webcam driver unloaded\n");
999 #ifdef CONFIG_MICRODIA_DEBUGFS
1000 microdia_uninit_debugfs();
1001 #endif
1003 /* Deregister this driver with the USB subsystem */
1004 usb_deregister(&usb_microdia_driver);
1008 module_init(usb_microdia_init); /**< @brief Module initialize */
1009 module_exit(usb_microdia_exit); /**< @brief Module exit */
1012 MODULE_PARM_DESC(fps, "Frames per second [10-30]"); /**< @brief Description of 'fps' parameter */
1013 MODULE_PARM_DESC(bulk, "Enable Bulk transfer (default is to use ISOC)");
1014 MODULE_PARM_DESC(hflip, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1015 MODULE_PARM_DESC(vflip, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1016 MODULE_PARM_DESC(flip_detect, "Image flip detection"); /**< @brief Description of 'vflip_detect' parameter */
1017 MODULE_PARM_DESC(auto_exposure, "Automatic exposure control"); /**< @brief Description of 'auto_exposure' parameter */
1018 MODULE_PARM_DESC(auto_whitebalance, "Automatic whitebalance"); /**< @brief Description of 'auto_whitebalance' parameter */
1019 MODULE_PARM_DESC(brightness, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1020 MODULE_PARM_DESC(whiteness, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1021 MODULE_PARM_DESC(exposure, "Exposure setting"); /**< @brief Description of 'exposure' parameter */
1022 MODULE_PARM_DESC(contrast, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1023 MODULE_PARM_DESC(sharpness, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */
1024 MODULE_PARM_DESC(rgb_gain, "Red/Green/Blue Gain setting"); /**< @brief Description of 'RGB Gain' parameter */
1026 MODULE_PARM_DESC(min_buffers, "Minimum number of image buffers");
1027 MODULE_PARM_DESC(max_buffers, "Maximum number of image buffers");
1028 MODULE_PARM_DESC(log_level, " <n>\n"
1029 "Driver log level\n"
1030 "1 = info (default)\n"
1031 "2 = warning\n"
1032 "4 = error\n"
1033 "8 = debug\n"
1034 "16 = stream\n");
1036 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1037 MODULE_AUTHOR(DRIVER_AUTHOR); /**< @brief Driver is written by Nicolas VIVIEN */
1038 MODULE_DESCRIPTION(DRIVER_DESC); /**< @brief Define the description of the driver */
1039 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT); /**< @brief List of supported device */