Merge branch 'master' of git+ssh://anarsoul@repo.or.cz/srv/git/microdia
[microdia.git] / microdia-usb.c
blob6863df691bae9c5b3f75073938a652e7e9af82aa
1 /**
2 * @file microdia-usb.c
3 * @author Nicolas VIVIEN
4 * @date 2008-02-01
5 * @version v0.0.0
7 * @brief Driver for Microdia USB video camera
9 * @note Copyright (C) Nicolas VIVIEN
11 * @par Licences
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 * 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
27 * @par SubVersion
28 * $Date: 2007-12-08 11:34:45 +0100 (sam, 08 déc 2007) $
29 * $Revision: 68 $
30 * $Author: nicklas79 $
31 * $HeadURL: https://syntekdriver.svn.sourceforge.net/svnroot/syntekdriver/trunk/driver/microdia-usb.c $
34 #include <linux/module.h>
35 #include <linux/init.h>
36 #include <linux/kernel.h>
37 #include <linux/version.h>
38 #include <linux/errno.h>
39 #include <linux/slab.h>
40 #include <linux/kref.h>
41 #include <linux/debugfs.h>
42 #include <linux/stat.h>
44 #include <linux/usb.h>
45 #include <media/v4l2-common.h>
47 #include "microdia.h"
50 /**
51 * @var default_fps
52 * Number of frame per second by default
54 static int default_fps = -1;
56 /**
57 * @var default_hflip
58 * Enable / Disable horizontal flip image
60 static int default_hflip = -1;
62 /**
63 * @var default_vflip
64 * Enable / Disable vertical flip image
66 static int default_vflip = -1;
68 /**
69 * @var default_brightness
70 * Set brightness
72 static int default_brightness = -1;
74 /**
75 * @var default_whiteness
76 * Set whiteness
78 static int default_whiteness = -1;
80 /**
81 * @var default_contrast
82 * Set contrast
84 static int default_contrast = -1;
86 /**
87 * @var default_colour
88 * Set colour
90 static int default_colour = -1;
92 /**
93 * @var debug_dir_name
94 * Name of our directory in debugfs
96 static const char * debug_dir_name = "microdia";
98 /**
99 * @var debug_file_name
100 * Name of our debug file in debugfs
102 static const char * debug_file_name = "debug_level";
105 * @var debug_dir
106 * Dentry for our debug dir (for cleanup)
108 static struct dentry * debug_dir;
111 * @var debug_file
112 * Dentry for our debug file (for cleanup)
114 static struct dentry * debug_file;
117 * @var debug_level
118 * Level at which we do debugging
120 static __u8 debug_level = 0;
124 * @var microdia_table
125 * Define all the hotplug supported devices by this driver
127 static struct usb_device_id microdia_table[] = {
128 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6027_PRODUCT_ID) },
129 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_608F_PRODUCT_ID) },
130 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_60FE_PRODUCT_ID) },
131 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6242_PRODUCT_ID) },
132 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6253_PRODUCT_ID) },
133 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6260_PRODUCT_ID) },
134 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6270_PRODUCT_ID) },
135 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_62C0_PRODUCT_ID) },
136 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_613B_PRODUCT_ID) },
137 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_613C_PRODUCT_ID) },
138 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_624F_PRODUCT_ID) },
139 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_627B_PRODUCT_ID) },
140 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_62C0_PRODUCT_ID) },
141 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_8105_PRODUCT_ID) },
142 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_624E_PRODUCT_ID) },
143 { USB_DEVICE(USB_MICRODIA_VENDOR_ID, USB_UDIA_6128_PRODUCT_ID) },
148 MODULE_DEVICE_TABLE(usb, microdia_table); /**< Define the supported devices */
152 /**
153 * @param dev Device structure
155 * @returns 0 if all is OK
157 * @brief Initilize an isochronous pipe.
159 * This function permits to initialize an URB transfert (or isochronous pipe).
161 int usb_microdia_isoc_init(struct usb_microdia *dev)
163 int i, j;
164 int ret = 0;
165 __u16 iso_max_frame_size;
166 struct urb *urb;
167 struct usb_device *udev;
169 if (dev == NULL)
170 return -EFAULT;
172 if (dev->isoc_init_ok)
173 return 0;
175 udev = dev->udev;
177 UDIA_DEBUG("usb_microdia_isoc_init()\n");
179 // Allocate URB structure
180 for (i=0; i<MAX_ISO_BUFS; i++) {
181 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
183 if (urb == NULL) {
184 UDIA_ERROR("Failed to allocate URB %d\n", i);
185 ret = -ENOMEM;
186 break;
189 dev->isobuf[i].urb = urb;
192 if (ret) {
193 while (i >= 0) {
194 if (dev->isobuf[i].urb != NULL)
195 usb_free_urb(dev->isobuf[i].urb);
197 dev->isobuf[i].urb = NULL;
198 i--;
201 return ret;
205 // iso_max_frame_size should be the endpoints maximum packetsize * the highbandwidth multiplier.
207 iso_max_frame_size = max_packet_sz(le16_to_cpu(dev->isoc_in_size)) * hb_multiplier(le16_to_cpu(dev->isoc_in_size));
209 // Init URB structure
210 for (i=0; i<MAX_ISO_BUFS; i++) {
211 urb = dev->isobuf[i].urb;
213 urb->interval = 1;
214 urb->dev = udev;
215 urb->pipe = usb_rcvisocpipe(udev, dev->isoc_in_endpointAddr);
216 urb->transfer_flags = URB_ISO_ASAP;
217 urb->transfer_buffer = dev->isobuf[i].data;
218 urb->transfer_buffer_length = iso_max_frame_size * ISO_FRAMES_PER_DESC;
219 urb->complete = usb_microdia_isoc_handler;
220 urb->context = dev;
221 urb->start_frame = 0;
222 urb->number_of_packets = ISO_FRAMES_PER_DESC;
224 for (j=0; j<ISO_FRAMES_PER_DESC; j++) {
225 urb->iso_frame_desc[j].offset = j * iso_max_frame_size;
226 urb->iso_frame_desc[j].length = iso_max_frame_size; //dev->isoc_in_size;
230 UDIA_DEBUG("dev->isoc_in_size = %X\n", dev->isoc_in_size);
231 UDIA_DEBUG("dev->isoc_in_endpointAddr = %X\n", dev->isoc_in_endpointAddr);
233 // Link
234 for (i=0; i<MAX_ISO_BUFS; i++) {
235 ret = usb_submit_urb(dev->isobuf[i].urb, GFP_KERNEL);
237 if (ret)
238 UDIA_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
239 else
240 UDIA_DEBUG("URB 0x%p submitted.\n", dev->isobuf[i].urb);
242 switch (ret) {
243 case -ENOMEM:
244 UDIA_ERROR("ENOMEM\n");
245 break;
246 case -ENODEV:
247 UDIA_ERROR("ENODEV\n");
248 break;
249 case -ENXIO:
250 UDIA_ERROR("ENXIO\n");
251 break;
252 case -EINVAL:
253 UDIA_ERROR("EINVAL\n");
254 break;
255 case -EAGAIN:
256 UDIA_ERROR("EAGAIN\n");
257 break;
258 case -EFBIG:
259 UDIA_ERROR("EFBIG\n");
260 break;
261 case -EPIPE:
262 UDIA_ERROR("EPIPE\n");
263 break;
264 case -EMSGSIZE:
265 UDIA_ERROR("EMSGSIZE\n");
266 break;
270 // All is done
271 dev->isoc_init_ok = 1;
273 return 0;
277 /**
278 * @param urb URB structure
280 * @brief ISOC handler
282 * This function is called as an URB transfert is complete (Isochronous pipe).
283 * So, the traitement is done in interrupt time, so it has be fast, not crash,
284 * ans not stall. Neat.
286 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
287 void usb_microdia_isoc_handler(struct urb *urb, struct pt_regs *regs)
288 #else
289 void usb_microdia_isoc_handler(struct urb *urb)
290 #endif
292 int i;
293 int ret;
294 int skip;
296 int awake = 0;
297 int framestatus;
298 int framelen;
300 unsigned char *fill = NULL;
301 unsigned char *iso_buf = NULL;
303 struct usb_microdia *dev;
304 struct microdia_frame_buf *framebuf;
306 unsigned char frame_header[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
308 UDIA_STREAM("Isoc handler\n");
310 dev = (struct usb_microdia *) urb->context;
312 if (dev == NULL) {
313 UDIA_ERROR("isoc_handler called with NULL device !\n");
314 return;
317 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
318 UDIA_DEBUG("URB unlinked synchronuously !\n");
319 return;
322 if (urb->status != -EINPROGRESS && urb->status != 0) {
323 const char *errmsg;
325 errmsg = "Unknown";
327 switch(urb->status) {
328 case -ENOSR:
329 errmsg = "Buffer error (overrun)";
330 break;
332 case -EPIPE:
333 errmsg = "Stalled (device not responding)";
334 break;
336 case -EOVERFLOW:
337 errmsg = "Babble (bad cable?)";
338 break;
340 case -EPROTO:
341 errmsg = "Bit-stuff error (bad cable?)";
342 break;
344 case -EILSEQ:
345 errmsg = "CRC/Timeout (could be anything)";
346 break;
348 case -ETIMEDOUT:
349 errmsg = "NAK (device does not respond)";
350 break;
353 UDIA_ERROR("isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
355 dev->visoc_errors++;
357 wake_up_interruptible(&dev->wait_frame);
359 urb->dev = dev->udev;
360 ret = usb_submit_urb(urb, GFP_ATOMIC);
362 if (ret != 0) {
363 UDIA_ERROR("Error (%d) re-submitting urb in microdia_isoc_handler.\n", ret);
366 return;
369 framebuf = dev->fill_frame;
371 if (framebuf == NULL) {
372 UDIA_ERROR("isoc_handler without valid fill frame !\n");
374 wake_up_interruptible(&dev->wait_frame);
376 urb->dev = dev->udev;
377 ret = usb_submit_urb(urb, GFP_ATOMIC);
379 if (ret != 0) {
380 UDIA_ERROR("Error (%d) re-submitting urb in microdia_isoc_handler.\n", ret);
383 return;
385 else {
386 fill = framebuf->data + framebuf->filled;
389 // Reset ISOC error counter
390 dev->visoc_errors = 0;
392 // Compact data
393 for (i=0; i<urb->number_of_packets; i++) {
394 framestatus = urb->iso_frame_desc[i].status;
395 framelen = urb->iso_frame_desc[i].actual_length;
396 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
398 if (framestatus == 0) {
399 // By default, I keep all packet.
400 // So I don't skip byte !
401 skip = 0;
403 if (framelen > 0) {
404 // For microdia devices, data are isoc packet with site > 0.
405 // ...
406 if (memcmp(iso_buf, frame_header, 6) == 0) {
407 if ((framebuf->filled == dev->frame_size + (dev->frame_size/2)) && framebuf->errors == 0) {
408 if (microdia_next_frame(dev)) {
409 dev->vframes_dumped++;
411 } else {
412 dev->vframes_error++;
414 awake = 1;
415 framebuf = dev->fill_frame;
416 framebuf->filled = 0;
417 framebuf->errors = 0;
418 fill = framebuf->data;
419 skip = 64;
421 // Our buffer is full !!!
422 if (framelen - skip + framebuf->filled > dev->frame_size + (dev->frame_size/2)) {
423 UDIA_ERROR("Frame buffer overflow !\n");
424 framebuf->errors++;
426 // All is OK
427 else {
428 memcpy(fill, iso_buf + skip, framelen - skip);
429 fill += framelen - skip;
432 // New size of our buffer
433 framebuf->filled += framelen - skip;
436 UDIA_STREAM("URB : Length = %d - Skip = %d - Buffer size = %d\n",
437 framelen, skip, framebuf->filled);
439 else {
440 UDIA_ERROR("Iso frame %d of USB has error %d\n", i, framestatus);
444 if (awake == 1)
445 wake_up_interruptible(&dev->wait_frame);
447 urb->dev = dev->udev;
449 ret = usb_submit_urb(urb, GFP_ATOMIC);
451 if (ret != 0) {
452 UDIA_ERROR("Error (%d) re-submitting urb in microdia_isoc_handler.\n", ret);
457 /**
458 * @param dev Device structure
460 * @brief Clean-up all the ISOC buffers
462 * This function permits to clean-up all the ISOC buffers.
464 void usb_microdia_isoc_cleanup(struct usb_microdia *dev)
466 int i;
468 UDIA_DEBUG("Isoc cleanup\n");
470 if (dev == NULL)
471 return;
473 if (dev->isoc_init_ok == 0)
474 return;
476 // Unlinking ISOC buffers
477 for (i=0; i<MAX_ISO_BUFS; i++) {
478 struct urb *urb;
480 urb = dev->isobuf[i].urb;
482 if (urb != 0) {
483 if (dev->isoc_init_ok)
484 usb_kill_urb(urb);
486 usb_free_urb(urb);
487 dev->isobuf[i].urb = NULL;
491 // All is done
492 dev->isoc_init_ok = 0;
497 /**
498 * @param dev Device structure
499 * @param index Choice of the interface
501 * @returns 0 if all is OK
503 * @brief Send the message SET_FEATURE and choose the interface
505 * This function permits to send the message SET_FEATURE on the USB bus.
507 int usb_microdia_set_feature(struct usb_microdia *dev, int index)
509 int result;
510 struct usb_device *udev = dev->udev;
512 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
513 USB_REQ_SET_FEATURE,
514 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
515 USB_DEVICE_REMOTE_WAKEUP,
516 index,
517 NULL,
519 500);
521 if (result < 0)
522 UDIA_ERROR("SET FEATURE fail !\n");
523 else
524 UDIA_DEBUG("SET FEATURE\n");
526 return result;
530 /**
531 * @param dev Device structure
533 * @returns 0 if all is OK
535 * @brief Send the message SET_CONFIGURATION
537 * This function permits to send the message SET_CONFIGURATION on the USB bus.
539 int usb_microdia_set_configuration(struct usb_microdia *dev)
541 int result;
542 struct usb_device *udev = dev->udev;
544 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
545 USB_REQ_SET_CONFIGURATION,
546 USB_TYPE_STANDARD | USB_DIR_OUT | USB_RECIP_DEVICE,
548 udev->config[0].desc.bConfigurationValue,
549 NULL,
551 500);
553 if (result < 0)
554 UDIA_ERROR("SET CONFIGURATION fail !\n");
555 else
556 UDIA_DEBUG("SET CONFIGURATION %d\n", udev->config[0].desc.bConfigurationValue);
558 return result;
562 /**
563 * @param dev
564 * @param index
565 * @param value
567 * @returns 0 if all is OK
569 * @brief Write a 16-bit value to a 16-bit register
571 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
573 int usb_microdia_control_write(struct usb_microdia *dev, __u16 value, __u8 *data, __u16 length)
575 int result;
576 struct usb_device *udev = dev->udev;
578 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
579 0x08,
580 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
581 value,
582 0x00,
583 data,
584 length,
585 500);
587 if (result < 0)
588 UDIA_ERROR("Write register failed index = %02X", value);
590 return result;
593 /**
594 * @param dev
595 * @param commands
596 * @param data
597 * @param cmdlen
598 * @param datalen
600 * @returns 0 if all is OK
602 * @brief Write a series of 16-bit "commands" using the same buffer
604 int usb_microdia_control_write_multi(struct usb_microdia *dev, __u16 *commands, __u8 *data,
605 __u16 cmdlen, __u16 datalen)
607 int result, i;
609 for(i = 0; i < cmdlen; i++) {
610 result = usb_microdia_control_write(dev, commands[i], data, datalen);
612 if(result < 0)
613 return result;
616 return 0;
619 /**
620 * @param dev
621 * @param index
622 * @param value
624 * @returns 0 if all is OK
626 * @brief Read a 16-bit value from a 16-bit register
628 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
630 int usb_microdia_control_read(struct usb_microdia *dev, __u16 index, __u8 *data, __u16 length)
632 int result;
634 struct usb_device *udev = dev->udev;
636 *data = 0;
638 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
639 0x00,
640 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
641 index,
642 0x00,
643 data,
644 length,
645 500);
647 if (result < 0)
648 UDIA_ERROR("Read register failed %02X", index);
650 return result;
654 /**
655 * @param dev
657 * @returns 0 if all is OK
659 * @brief Set the default value about the video settings.
661 * This function permits to set the video settings for each video camera model.
664 static int usb_microdia_default_settings(struct usb_microdia *dev)
666 switch (dev->webcam_model) {
667 default:
668 dev->vsettings.fps = (default_fps == -1) ? 25 : default_fps;
669 dev->vsettings.vflip = (default_vflip == -1) ? 0 : default_vflip;
670 dev->vsettings.hflip = (default_hflip == -1) ? 0 : default_hflip;
672 dev->vsettings.brightness = (default_brightness == -1) ? MICRODIA_PERCENT(50, 0xFFFF) : default_brightness;
673 dev->vsettings.contrast = (default_contrast == -1) ? MICRODIA_PERCENT(50, 0xFFFF) : default_contrast;
674 dev->vsettings.colour = (default_colour == -1) ? MICRODIA_PERCENT(50, 0xFFFF) : default_colour;
675 dev->vsettings.whiteness = MICRODIA_PERCENT(20, 0xFFFF);
676 dev->vsettings.exposure = MICRODIA_PERCENT(20, 0xFFFF);
677 break;
681 return 0;
684 extern int microdia_627b_initialize(struct usb_microdia *dev);
685 extern int microdia_627b_start_stream(struct usb_microdia *dev);
686 extern int microdia_627b_stop_stream(struct usb_microdia *dev);
687 extern int microdia_624f_initialize(struct usb_microdia *dev);
688 extern int microdia_624e_initialize(struct usb_microdia *dev);
689 extern int microdia_6128_initialize(struct usb_microdia *dev);
690 extern int microdia_6270_initialize(struct usb_microdia *dev);
691 extern int microdia_624f_stop_stream(struct usb_microdia *dev);
692 extern int microdia_624f_start_stream(struct usb_microdia *dev);
693 extern int microdia_624f_set_exposure(struct usb_microdia *dev);
694 extern int microdia_6128_start_stream(struct usb_microdia *dev);
695 extern int microdia_6128_stop_stream(struct usb_microdia *dev);
696 extern int microdia_624e_start_stream(struct usb_microdia *dev);
697 extern int microdia_624e_stop_stream(struct usb_microdia *dev);
698 extern int microdia_6242_start_stream(struct usb_microdia *dev);
699 extern int microdia_6242_stop_stream(struct usb_microdia *dev);
700 extern int microdia_6260_initialize(struct usb_microdia *dev);
701 extern int microdia_6260_start_stream(struct usb_microdia *dev);
702 extern int microdia_6260_stop_stream(struct usb_microdia *dev);
703 extern int microdia_6270_start_stream(struct usb_microdia *dev);
704 extern int microdia_6270_stop_stream(struct usb_microdia *dev);
705 extern int microdia_6270_set_exposure(struct usb_microdia *dev);
708 /**
709 * @param interface
710 * @param id
712 * @returns 0 if all is OK
714 * @brief Load the driver
716 * This function detects the device and allocate the buffers for the device
717 * and the video interface.
719 static int usb_microdia_probe(struct usb_interface *interface, const struct usb_device_id *id)
721 int i;
722 int err;
723 size_t buffer_size;
725 int vendor_id;
726 int product_id;
727 int bNumInterfaces;
728 int webcam_model;
729 int webcam_type;
730 int (*initialize)(struct usb_microdia *) = NULL;
731 int (*stop_stream)(struct usb_microdia *) = NULL;
732 int (*start_stream)(struct usb_microdia *) = NULL;
733 int (*set_exposure)(struct usb_microdia *) = NULL;
735 struct usb_microdia *dev = NULL;
736 struct usb_device *udev = interface_to_usbdev(interface);
737 struct usb_host_interface *iface_desc;
738 struct usb_endpoint_descriptor *endpoint;
741 // Get USB VendorID and ProductID
742 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
743 product_id = le16_to_cpu(udev->descriptor.idProduct);
745 // Check if we can handle this device
746 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
747 vendor_id, product_id, interface->cur_altsetting->desc.bInterfaceNumber);
749 // The interface are probed one by one.
750 // We are interested in the video interface (always the interface '0')
751 // The interfaces '1' or '2' (if presents) are the audio control.
752 if (interface->cur_altsetting->desc.bInterfaceNumber > 0)
753 return -ENODEV;
755 // Detect device
756 if (vendor_id == USB_MICRODIA_VENDOR_ID) {
757 switch (product_id) {
758 case USB_UDIA_6027_PRODUCT_ID:
759 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6027.\n");
760 webcam_model = MICRODIA_6027;
761 webcam_type = MICRODIA_VGA;
762 break;
764 case USB_UDIA_608F_PRODUCT_ID:
765 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 608F.\n");
766 webcam_model = MICRODIA_608F;
767 webcam_type = MICRODIA_VGA;
768 break;
770 case USB_UDIA_60FE_PRODUCT_ID:
771 webcam_model = MICRODIA_60FE;
772 webcam_type = MICRODIA_VGA;
773 break;
775 case USB_UDIA_6242_PRODUCT_ID:
776 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6242.\n");
777 webcam_model = MICRODIA_6242;
778 webcam_type = MICRODIA_VGA;
779 initialize = microdia_624e_initialize;
780 start_stream = microdia_6242_start_stream;
781 stop_stream = microdia_6242_stop_stream;
782 break;
784 case USB_UDIA_6253_PRODUCT_ID:
785 webcam_model = MICRODIA_6253;
786 webcam_type = MICRODIA_VGA;
787 break;
789 case USB_UDIA_6260_PRODUCT_ID:
790 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6260.\n");
791 webcam_model = MICRODIA_6260;
792 webcam_type = MICRODIA_VGA;
793 initialize = microdia_6260_initialize;
794 start_stream = microdia_6260_start_stream;
795 stop_stream = microdia_6260_stop_stream;
796 break;
798 case USB_UDIA_6270_PRODUCT_ID:
799 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6270.\n");
800 webcam_model = MICRODIA_6270;
801 webcam_type = MICRODIA_VGA;
802 initialize = microdia_6270_initialize;
803 start_stream = microdia_6270_start_stream;
804 stop_stream = microdia_6270_stop_stream;
805 set_exposure = microdia_6270_set_exposure;
806 break;
808 case USB_UDIA_60C0_PRODUCT_ID:
809 webcam_model = MICRODIA_60C0;
810 webcam_type = MICRODIA_VGA;
811 break;
813 case USB_UDIA_613B_PRODUCT_ID:
814 webcam_model = MICRODIA_613B;
815 webcam_type = MICRODIA_VGA;
816 break;
818 case USB_UDIA_613C_PRODUCT_ID:
819 webcam_model = MICRODIA_613C;
820 webcam_type = MICRODIA_VGA;
821 break;
823 case USB_UDIA_624F_PRODUCT_ID:
824 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624F.\n");
825 webcam_model = MICRODIA_624F;
826 webcam_type = MICRODIA_VGA;
827 initialize = microdia_624f_initialize;
828 start_stream = microdia_624f_start_stream;
829 stop_stream = microdia_624f_stop_stream;
830 set_exposure = microdia_624f_set_exposure;
831 break;
833 case USB_UDIA_627B_PRODUCT_ID:
834 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627B.\n");
835 webcam_model = MICRODIA_627B;
836 webcam_type = MICRODIA_VGA;
837 initialize = microdia_627b_initialize;
838 start_stream = microdia_627b_start_stream;
839 stop_stream = microdia_627b_stop_stream;
840 break;
842 case USB_UDIA_62C0_PRODUCT_ID:
843 webcam_model = MICRODIA_62C0;
844 webcam_type = MICRODIA_VGA;
845 break;
847 case USB_UDIA_8105_PRODUCT_ID:
848 webcam_model = MICRODIA_8105;
849 webcam_type = MICRODIA_VGA;
850 break;
852 case USB_UDIA_624E_PRODUCT_ID:
853 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624E.\n");
854 webcam_model = MICRODIA_624E;
855 webcam_type = MICRODIA_SXGA;
856 initialize = microdia_624e_initialize;
857 start_stream = microdia_624e_start_stream;
858 stop_stream = microdia_624e_stop_stream;
859 break;
861 case USB_UDIA_6128_PRODUCT_ID:
862 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6128.\n");
863 webcam_model = MICRODIA_6128;
864 webcam_type = MICRODIA_SXGA;
865 initialize = microdia_6128_initialize;
866 start_stream = microdia_6128_start_stream;
867 stop_stream = microdia_6128_stop_stream;
868 break;
870 default:
871 UDIA_ERROR("usb_microdia_probe failed ! Camera product 0x%04X is not supported.\n",
872 le16_to_cpu(udev->descriptor.idProduct));
873 return -ENODEV;
876 else
877 return -ENODEV;
879 // Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device
880 dev = kzalloc(sizeof(struct usb_microdia), GFP_KERNEL);
882 if (dev == NULL) {
883 UDIA_ERROR("Out of memory !\n");
884 return -ENOMEM;
887 // Init mutexes, spinlock, etc.
888 init_MUTEX(&dev->mutex);
889 spin_lock_init(&dev->spinlock);
890 init_waitqueue_head(&dev->wait_frame);
892 // Save pointers
893 dev->webcam_model = webcam_model;
894 dev->webcam_type = webcam_type;
895 dev->initialize = initialize;
896 dev->stop_stream = stop_stream;
897 dev->start_stream = start_stream;
898 dev->set_exposure = set_exposure;
899 dev->udev = udev;
900 dev->interface = interface;
902 // Read the product release
903 dev->release = le16_to_cpu(udev->descriptor.bcdDevice);
904 UDIA_INFO("Release: %04x\n", dev->release);
906 // How many interfaces (1 or 3) ?
907 bNumInterfaces = udev->config->desc.bNumInterfaces;
908 UDIA_INFO("Number of interfaces : %d\n", bNumInterfaces);
911 // Constructor
912 dev->nbuffers = 2;
913 dev->len_per_image = PAGE_ALIGN((1280 * 1024 * 4));
916 // Switch on the camera (to detect size of buffers)
917 dev_microdia_camera_on(dev);
920 // Set up the endpoint information
921 // use only the first int-in and isoc-in endpoints
922 // for the current alternate setting
923 iface_desc = interface->cur_altsetting;
925 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
926 endpoint = &iface_desc->endpoint[i].desc;
928 if (!dev->int_in_endpointAddr
929 && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
930 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
931 // we found an interrupt in endpoint
932 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
934 dev->int_in_size = buffer_size;
935 dev->int_in_endpointAddr = (endpoint->bEndpointAddress & 0xf);
938 if (!dev->isoc_in_endpointAddr
939 && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
940 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)) {
941 // we found an isoc in endpoint
942 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
944 dev->isoc_in_size = buffer_size;
945 dev->isoc_in_endpointAddr = (endpoint->bEndpointAddress & 0xf);
949 if (!(dev->int_in_endpointAddr && dev->isoc_in_endpointAddr)) {
950 UDIA_ERROR("Could not find both int-in and isoc-in endpoints");
952 kfree(dev);
954 return -ENODEV;
958 // Switch off camera
959 dev_microdia_camera_off(dev);
961 // Initialize the video device
962 dev->vdev = video_device_alloc();
964 if (!dev->vdev) {
965 kfree(dev);
966 return -ENOMEM;
969 // Initialize the camera
970 dev_microdia_initialize_device(dev);
972 // Register the video device
973 err = v4l_microdia_register_video_device(dev);
975 if (err) {
976 video_device_release(dev->vdev); // Oops release video dev
977 kfree(dev);
978 return err;
981 // Create the entries in the sys filesystem
982 microdia_create_sysfs_files(dev->vdev);
984 // Save our data pointer in this interface device
985 usb_set_intfdata(interface, dev);
987 // Default settings video device
988 usb_microdia_default_settings(dev);
991 return 0;
995 /**
996 * @param interface
998 * @brief This function is called when the device is disconnected
999 * or when the kernel module is unloaded.
1001 static void usb_microdia_disconnect(struct usb_interface *interface)
1003 struct usb_microdia *dev = usb_get_intfdata(interface);
1005 UDIA_INFO("Microdia USB2.0 Camera disconnected\n");
1007 usb_set_intfdata(interface, NULL);
1009 // We got unplugged; this is signalled by an EPIPE error code
1010 if (dev->vopen) {
1011 UDIA_INFO("Disconnected while webcam is in use !\n");
1012 dev->error_status = EPIPE;
1015 // Alert waiting processes
1016 wake_up_interruptible(&dev->wait_frame);
1018 // Wait until device is closed
1019 while (dev->vopen)
1020 schedule();
1022 // Remove the entries in the sys filesystem
1023 microdia_remove_sysfs_files(dev->vdev);
1025 // Unregister the video device
1026 v4l_microdia_unregister_video_device(dev);
1031 * @var usb_microdia_driver
1033 * This variable contains some callback
1035 static struct usb_driver usb_microdia_driver = {
1036 .name = "usb_microdia_driver",
1037 .probe = usb_microdia_probe,
1038 .disconnect = usb_microdia_disconnect,
1039 .id_table = microdia_table,
1044 * @var fps
1045 * Module parameter to set frame per second
1047 static int fps;
1050 * @var hflip
1051 * Module parameter to enable/disable the horizontal flip process
1053 static int hflip = -1;
1056 * @var vflip
1057 * Module parameter to enable/disable the vertical flip process
1059 static int vflip = -1;
1062 * @var brightness
1063 * Module parameter to set the brightness
1065 static int brightness = -1;
1068 * @var whiteness
1069 * Module parameter to set the whiteness
1071 static int whiteness = -1;
1074 * @var contrast
1075 * Module parameter to set the contrast
1077 static int contrast = -1;
1080 * @var colour
1081 * Module parameter to set the colour
1083 static int colour = -1;
1086 module_param(fps, int, 0444); /**< @brief Module frame per second parameter */
1087 module_param(hflip, int, 0444); /**< @brief Module horizontal flip process */
1088 module_param(vflip, int, 0444); /**< @brief Module vertical flip process */
1090 module_param(brightness, int, 0444); /**< @brief Module brightness */
1091 module_param(whiteness, int, 0444); /**< @brief Module whiteness */
1092 module_param(contrast, int, 0444); /**< @brief Module contrast */
1093 module_param(colour, int, 0444); /**< @brief Module colour */
1096 /**
1097 * @returns 0 if all is OK
1099 * @brief Initialize the driver.
1101 * This function is called at first.
1102 * This function permits to define the default values from the command line.
1104 static int __init usb_microdia_init(void)
1106 int result;
1109 UDIA_INFO("Microdia USB2.0 webcam driver startup\n");
1111 debug_dir = debugfs_create_dir(debug_dir_name, NULL);
1112 if(debug_dir)
1113 debug_file = debugfs_create_u8(debug_file_name, S_IRUGO | S_IWUGO,
1114 debug_dir, &debug_level);
1116 // Frame per second parameter
1117 if (fps) {
1118 if (fps < 9 || fps > 30) {
1119 UDIA_ERROR("Framerate out of bounds [10-30] !\n");
1120 return -EINVAL;
1123 default_fps = fps;
1126 // Horizontal flip value
1127 if ((hflip == 0) || (hflip == 1)) {
1128 UDIA_DEBUG("Set horizontal flip = %d\n", hflip);
1130 default_hflip = hflip;
1133 // Vertical flip value
1134 if ((vflip == 0) || (vflip == 1)) {
1135 UDIA_DEBUG("Set vertical flip = %d\n", vflip);
1137 default_vflip = vflip;
1140 // Brightness value
1141 if (brightness > -1) {
1142 UDIA_DEBUG("Set brightness = 0x%X\n", brightness);
1144 default_brightness = 0xffff & brightness;
1147 // Whiteness value
1148 if (whiteness > -1) {
1149 UDIA_DEBUG("Set whiteness = 0x%X\n", whiteness);
1151 default_whiteness = 0xffff & whiteness;
1154 // Contrast value
1155 if (contrast > -1) {
1156 UDIA_DEBUG("Set contrast = 0x%X\n", contrast);
1158 default_contrast = 0xffff & contrast;
1161 // Colour value
1162 if (colour > -1) {
1163 UDIA_DEBUG("Set colour = 0x%X\n", colour);
1165 default_colour = 0xffff & colour;
1169 // Register the driver with the USB subsystem
1170 result = usb_register(&usb_microdia_driver);
1172 if (result)
1173 UDIA_ERROR("usb_register failed ! Error number %d\n", result);
1175 UDIA_INFO(DRIVER_VERSION " : " DRIVER_DESC "\n");
1177 return result;
1181 /**
1182 * @brief Close the driver
1184 * This function is called at last when you unload the driver.
1186 static void __exit usb_microdia_exit(void)
1188 UDIA_INFO("usb_microdia_exit: Microdia USB2.0 webcam driver shutdown\n");
1190 if(debug_file)
1191 debugfs_remove(debug_file);
1192 if(debug_dir)
1193 debugfs_remove(debug_dir);
1195 // Deregister this driver with the USB subsystem
1196 usb_deregister(&usb_microdia_driver);
1200 module_init(usb_microdia_init); /**< @brief Module initialize */
1201 module_exit(usb_microdia_exit); /**< @brief Module exit */
1204 MODULE_PARM_DESC(fps, "Frames per second [5-30]"); /**< @brief Description of 'fps' parameter */
1205 MODULE_PARM_DESC(hflip, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1206 MODULE_PARM_DESC(vflip, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1207 MODULE_PARM_DESC(brightness, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1208 MODULE_PARM_DESC(whiteness, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1209 MODULE_PARM_DESC(colour, "Colour setting"); /**< @brief Description of 'colour' parameter */
1210 MODULE_PARM_DESC(contrast, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1213 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1214 MODULE_AUTHOR(DRIVER_AUTHOR); /**< @brief Driver is written by Nicolas VIVIEN */
1215 MODULE_DESCRIPTION(DRIVER_DESC); /**< @brief Define the description of the driver */
1216 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT); /**< @brief List of supported device */