3 * @author Nicolas VIVIEN
7 * @brief Driver for Microdia USB video camera
9 * @note Copyright (C) Nicolas VIVIEN
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
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
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/kernel.h>
31 #include <linux/version.h>
32 #include <linux/errno.h>
33 #include <linux/slab.h>
34 #include <linux/kref.h>
35 #include <linux/debugfs.h>
36 #include <linux/stat.h>
38 #include <linux/usb.h>
39 #include <media/v4l2-common.h>
47 * Module parameter to set frame per second
53 * Module parameter to enable/disable the horizontal flip process
59 * Module parameter to enable/disable vflip detection
61 static int flip_detect
= 0;
65 * Module parameter to enable/disable the vertical flip process
71 * Module parameter to set the brightness
73 static int brightness
= MICRODIA_PERCENT(50, 0xFFFF);
77 * Module parameter to set the whiteness
79 static int whiteness
= MICRODIA_PERCENT(20, 0xFFFF);
83 * Module parameter to set the contrast
85 static int contrast
= MICRODIA_PERCENT(50, 0xFFFF);
89 * Module parameter to set the exposure
91 static int exposure
= MICRODIA_PERCENT(20, 0xFFFF);
95 * Module parameter to set the sharpness
97 static int sharpness
= MICRODIA_PERCENT(50, 0x3F);
101 * Module parameter to set the minimum number of image buffers
103 static int min_buffers
= 2;
107 * Module parameter to set the maximum number of image buffers
109 static int max_buffers
= 5;
113 * Module parameter to set the exposure
115 static int auto_exposure
= 1;
118 * @var auto_whitebalance
119 * Module parameter to set the exposure
121 static int auto_whitebalance
= 1;
124 * @var debug_dir_name
125 * Name of our directory in debugfs
127 static const char * debug_dir_name
= "microdia";
130 * @var debug_file_name
131 * Name of our debug file in debugfs
133 static const char * debug_file_name
= "debug_level";
137 * Dentry for our debug dir (for cleanup)
139 static struct dentry
* debug_dir
;
143 * Dentry for our debug file (for cleanup)
145 static struct dentry
* debug_file
;
149 * Level at which we do debugging
151 static __u8 debug_level
= 0;
155 * @var microdia_table
156 * Define all the hotplug supported devices by this driver
158 static struct usb_device_id microdia_table
[] = {
159 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6240
) }, // SN9C201 + MI1300
160 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6242
) }, // SN9C201 + MI1310
161 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6243
) }, // SN9C201 + S5K4AAFX
162 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6248
) }, // SN9C201 + OV9655
163 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_624B
) }, // SN9C201 + CX1332
164 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_624C
) }, // SN9C201 + MI1320
165 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_624E
) }, // SN9C201 + SOI968
166 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_624F
) }, // SN9C201 + OV9650
167 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6253
) }, // SN9C201 + OV9650
168 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6260
) }, // SN9C201 + OV7670ISP
169 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6262
) }, // SN9C201 + OM6802
170 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6270
) }, // SN9C201 + MI0360/MT9V111
171 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_627A
) }, // SN9C201 + S5K53BEB
172 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_627B
) }, // SN9C201 + OV7660
173 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_627C
) }, // SN9C201 + HV7131R
174 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_627F
) }, // EEPROM
175 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6280
) }, // SN9C202 + MI1300
176 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6282
) }, // SN9C202 + MI1310
177 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6283
) }, // SN9C202 + S5K4AAFX
178 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6288
) }, // SN9C202 + OV9655
179 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_628A
) }, // SN9C202 + ICM107
180 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_628B
) }, // SN9C202 + CX1332
181 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_628C
) }, // SN9C202 + MI1320
182 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_628E
) }, // SN9C202 + SOI968
183 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_628F
) }, // SN9C202 + OV9650
184 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62A0
) }, // SN9C202 + OV7670ISP
185 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62A2
) }, // SN9C202 + OM6802
186 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62B0
) }, // SN9C202 + MI0360/MT9V111
187 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62B3
) }, // SN9C202 + OV9655
188 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62BA
) }, // SN9C202 + S5K53BEB
189 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62BB
) }, // SN9C202 + OV7660
190 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62BC
) }, // SN9C202 + HV7131R
191 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_62BE
) }, // SN9C202 + OV7663
192 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_6128
) }, // SN9C325 + OM6802
193 { USB_DEVICE(USB_VENDOR_ID_MICRODIA
, USB_UDIA_MICRODIA_PRODUCT_ID_612A
) }, // SN9C325 + OV7648 + POx1030xC + SOI768 + PO2030N + OV7660 + OV7670 + HV7131R
194 { USB_DEVICE(USB_VENDOR_ID_MICROSOFT
, USB_UDIA_MICROSOFT_PRODUCT_ID_00F4
) }, // => 628f (SN9C202 + OV9650)
195 { USB_DEVICE(USB_VENDOR_ID_TRUST
, USB_UDIA_TRUST_PRODUCT_ID_013D
) }, // => 627b (SN9C201 + OV7660)
196 { USB_DEVICE(USB_VENDOR_ID_CHICONY
, USB_UDIA_CHICONY_PRODUCT_ID_A128
) }, // => 62be (SN9C202 + OV7663 + EEPROM)
201 MODULE_DEVICE_TABLE(usb
, microdia_table
); /**< Define the supported devices */
203 DEFINE_MUTEX(open_lock
); /**< Define global mutex */
206 * @param dev Device structure
208 * @returns 0 if all is OK
210 * @brief Initilize an isochronous pipe.
212 * This function permits to initialize an URB transfert (or isochronous pipe).
214 int usb_microdia_isoc_init(struct usb_microdia
*dev
)
218 __u16 iso_max_frame_size
;
220 struct usb_device
*udev
;
227 UDIA_DEBUG("usb_microdia_isoc_init()\n");
229 iso_max_frame_size
= max_packet_sz(le16_to_cpu(dev
->isoc_in_size
)) *
230 hb_multiplier(le16_to_cpu(dev
->isoc_in_size
));
232 for (i
= 0; i
< MAX_ISO_BUFS
; i
++) {
233 urb
= usb_alloc_urb(ISO_FRAMES_PER_DESC
, GFP_KERNEL
);
236 UDIA_ERROR("Failed to allocate URB %d\n", i
);
237 usb_microdia_isoc_cleanup(dev
);
243 urb
->pipe
= usb_rcvisocpipe(udev
, dev
->isoc_in_endpointAddr
);
244 urb
->transfer_flags
= URB_ISO_ASAP
;
245 urb
->transfer_buffer_length
= iso_max_frame_size
* ISO_FRAMES_PER_DESC
;
246 urb
->complete
= usb_microdia_isoc_handler
;
248 urb
->start_frame
= 0;
249 urb
->number_of_packets
= ISO_FRAMES_PER_DESC
;
251 for (j
= 0; j
< ISO_FRAMES_PER_DESC
; j
++) {
252 urb
->iso_frame_desc
[j
].offset
= j
* iso_max_frame_size
;
253 urb
->iso_frame_desc
[j
].length
= iso_max_frame_size
;
256 dev
->isobuf
[i
].data
= kzalloc(urb
->transfer_buffer_length
,
258 if (dev
->isobuf
[i
].data
== NULL
) {
259 usb_microdia_isoc_cleanup(dev
);
263 urb
->transfer_buffer
= dev
->isobuf
[i
].data
;
264 dev
->isobuf
[i
].urb
= urb
;
267 UDIA_DEBUG("dev->isoc_in_size = %X\n", dev
->isoc_in_size
);
268 UDIA_DEBUG("dev->isoc_in_endpointAddr = %X\n", dev
->isoc_in_endpointAddr
);
270 for (i
= 0; i
< MAX_ISO_BUFS
; i
++) {
271 ret
= usb_submit_urb(dev
->isobuf
[i
].urb
, GFP_KERNEL
);
274 UDIA_ERROR("isoc_init() submit_urb %d failed with error %d\n", i
, ret
);
275 usb_microdia_isoc_cleanup(dev
);
285 * @param urb URB structure
287 * @brief ISOC handler
289 * This function is called as an URB transfert is complete (Isochronous pipe).
290 * So, the traitement is done in interrupt time, so it has be fast, not crash,
291 * ans not stall. Neat.
293 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
294 void usb_microdia_isoc_handler(struct urb
*urb
, struct pt_regs
*regs
)
296 void usb_microdia_isoc_handler(struct urb
*urb
)
303 unsigned int framelen
;
306 unsigned char *iso_buf
= NULL
;
309 struct microdia_buffer
*buf
= NULL
;
310 struct usb_microdia
*dev
= urb
->context
;
311 struct microdia_video_queue
*queue
= &dev
->queue
;
313 unsigned char frame_header
[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
315 UDIA_STREAM("Isoc handler\n");
317 switch (urb
->status
) {
322 UDIA_WARNING("Non-zero status (%d) in video "
323 "completion handler.\n", urb
->status
);
325 case -ENOENT
: /* usb_kill_urb() called. */
329 case -ECONNRESET
: /* usb_unlink_urb() called. */
330 case -ESHUTDOWN
: /* The endpoint is being disabled. */
331 microdia_queue_cancel(queue
);
335 spin_lock_irqsave(&queue
->irqlock
, flags
);
336 if (!list_empty(&queue
->irqqueue
))
337 buf
= list_first_entry(&queue
->irqqueue
, struct microdia_buffer
,
339 spin_unlock_irqrestore(&queue
->irqlock
, flags
);
341 for (i
=0; i
<urb
->number_of_packets
; i
++) {
342 framestatus
= urb
->iso_frame_desc
[i
].status
;
343 if (framestatus
!= 0) {
344 UDIA_ERROR("Iso frame %d of USB has error %d\n",
348 framelen
= urb
->iso_frame_desc
[i
].actual_length
;
349 iso_buf
= urb
->transfer_buffer
+ urb
->iso_frame_desc
[i
].offset
;
354 if (memcmp(iso_buf
, frame_header
, 6) == 0 && framelen
== 64) {
355 UDIA_DEBUG("Frame Resolution: %dx%d\n",
356 iso_buf
[0x3a] << 4, iso_buf
[0x3b] << 3);
357 if (buf
->buf
.bytesused
!= 0)
358 buf
->state
= MICRODIA_BUF_STATE_DONE
;
360 if (buf
->state
!= MICRODIA_BUF_STATE_ACTIVE
)
361 buf
->state
= MICRODIA_BUF_STATE_ACTIVE
;
363 if (framelen
+ buf
->buf
.bytesused
> queue
->frame_size
) {
364 UDIA_WARNING("Frame Buffer overflow!\n");
365 dev
->vframes_overflow
++;
366 buf
->state
= MICRODIA_BUF_STATE_DONE
;
368 framelen
= min(queue
->frame_size
- buf
->buf
.bytesused
,
370 mem
= queue
->mem
+ buf
->buf
.m
.offset
+
372 memcpy(mem
, iso_buf
, framelen
);
373 buf
->buf
.bytesused
+= framelen
;
375 if (buf
->state
== MICRODIA_BUF_STATE_DONE
||
376 buf
->state
== MICRODIA_BUF_STATE_ERROR
) {
377 buf
= microdia_queue_next_buffer(queue
, buf
);
379 dev
->vframes_dropped
++;
383 urb
->dev
= dev
->udev
;
385 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
388 UDIA_ERROR("Error (%d) re-submitting urb in "
389 "microdia_isoc_handler.\n", ret
);
395 * @param dev Device structure
397 * @brief Clean-up all the ISOC buffers
399 * This function permits to clean-up all the ISOC buffers.
401 void usb_microdia_isoc_cleanup(struct usb_microdia
*dev
)
406 UDIA_DEBUG("Isoc cleanup\n");
411 for (i
=0; i
<MAX_ISO_BUFS
; i
++) {
412 urb
= dev
->isobuf
[i
].urb
;
417 if (dev
->isobuf
[i
].data
) {
418 kfree(dev
->isobuf
[i
].data
);
419 dev
->isobuf
[i
].data
= NULL
;
422 dev
->isobuf
[i
].urb
= NULL
;
429 * @param dev Device structure
430 * @param index Choice of the interface
432 * @returns 0 if all is OK
434 * @brief Send the message SET_FEATURE and choose the interface
436 * This function permits to send the message SET_FEATURE on the USB bus.
438 int usb_microdia_set_feature(struct usb_microdia
*dev
, int index
)
441 struct usb_device
*udev
= dev
->udev
;
443 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
445 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
446 USB_DEVICE_REMOTE_WAKEUP
,
453 UDIA_ERROR("SET FEATURE fail !\n");
455 UDIA_DEBUG("SET FEATURE\n");
462 * @param dev Device structure
464 * @returns 0 if all is OK
466 * @brief Send the message SET_CONFIGURATION
468 * This function permits to send the message SET_CONFIGURATION on the USB bus.
470 int usb_microdia_set_configuration(struct usb_microdia
*dev
)
473 struct usb_device
*udev
= dev
->udev
;
475 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
476 USB_REQ_SET_CONFIGURATION
,
477 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
479 udev
->config
[0].desc
.bConfigurationValue
,
485 UDIA_ERROR("SET CONFIGURATION fail !\n");
487 UDIA_DEBUG("SET CONFIGURATION %d\n", udev
->config
[0].desc
.bConfigurationValue
);
494 * @param dev Device structure
495 * @param value register to write to
497 * @param length number of bytes
499 * @returns 0 if all is OK
501 * @brief Write a 16-bit value to a 16-bit register
503 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
505 int usb_microdia_control_write(struct usb_microdia
*dev
, __u16 value
, __u8
*data
, __u16 length
)
508 struct usb_device
*udev
= dev
->udev
;
510 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
512 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
520 UDIA_ERROR("Write register failed index = 0x%02X\n", value
);
532 * @returns 0 if all is OK
534 * @brief Write a series of 16-bit "commands" using the same buffer
536 int usb_microdia_control_write_multi(struct usb_microdia
*dev
, __u16
*commands
, __u8
*data
,
537 __u16 cmdlen
, __u16 datalen
)
541 for(i
= 0; i
< cmdlen
; i
++) {
542 result
= usb_microdia_control_write(dev
, commands
[i
], data
, datalen
);
552 * @param dev Device structure
553 * @param index register to read from
555 * @param length number of bytes
557 * @returns 0 if all is OK
559 * @brief Read a 16-bit value from a 16-bit register
561 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
563 int usb_microdia_control_read(struct usb_microdia
*dev
, __u16 index
, __u8
*data
, __u16 length
)
567 struct usb_device
*udev
= dev
->udev
;
571 result
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
573 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
581 UDIA_ERROR("Read register failed 0x%02X\n", index
);
590 * @returns 0 if all is OK
592 * @brief Set the default value about the video settings.
594 * This function permits to set the video settings for each video camera model.
597 static int usb_microdia_default_settings(struct usb_microdia
*dev
)
599 struct v4l2_pix_format
*def_fmt
;
601 dev
->vframes_overflow
= 0;
602 dev
->vframes_incomplete
= 0;
603 dev
->vframes_dropped
= 0;
605 dev
->queue
.min_buffers
= min_buffers
;
606 dev
->queue
.max_buffers
= max_buffers
;
608 def_fmt
= v4l2_enum_supported_formats(dev
, 0);
610 switch (dev
->webcam_model
) {
612 dev
->vsettings
.fps
= fps
;
613 dev
->vsettings
.vflip
= vflip
;
614 dev
->vsettings
.hflip
= hflip
;
615 dev
->vsettings
.brightness
= brightness
& 0xffff;
616 dev
->vsettings
.contrast
= contrast
& 0xffff;
617 dev
->vsettings
.whiteness
= whiteness
& 0xffff;
618 dev
->vsettings
.exposure
= exposure
& 0xffff;
619 dev
->vsettings
.sharpness
= sharpness
& 0x3f;
620 dev
->vsettings
.auto_exposure
= auto_exposure
& 1;
621 dev
->vsettings
.auto_whitebalance
= auto_whitebalance
& 1;
622 dev
->vsettings
.hue
= 0xffff;
625 memcpy(&(dev
->vsettings
.format
),
627 sizeof(struct v4l2_pix_format
));
630 v4l_microdia_select_video_mode(dev
, MICRODIA_640x480
);
636 extern int microdia_6240_initialize(struct usb_microdia
*dev
);
637 extern int microdia_6240_start_stream(struct usb_microdia
*dev
);
638 extern int microdia_6240_stop_stream(struct usb_microdia
*dev
);
639 extern int microdia_6242_start_stream(struct usb_microdia
*dev
);
640 extern int microdia_6242_stop_stream(struct usb_microdia
*dev
);
641 extern int microdia_624e_initialize(struct usb_microdia
*dev
);
642 extern int microdia_624e_start_stream(struct usb_microdia
*dev
);
643 extern int microdia_624e_stop_stream(struct usb_microdia
*dev
);
644 extern int microdia_624f_initialize(struct usb_microdia
*dev
);
645 extern int microdia_624f_stop_stream(struct usb_microdia
*dev
);
646 extern int microdia_624f_start_stream(struct usb_microdia
*dev
);
647 extern int microdia_624f_set_exposure(struct usb_microdia
*dev
);
648 extern int microdia_624f_flip_detect(struct usb_microdia
*dev
);
649 extern int microdia_6260_initialize(struct usb_microdia
*dev
);
650 extern int microdia_6260_start_stream(struct usb_microdia
*dev
);
651 extern int microdia_6260_stop_stream(struct usb_microdia
*dev
);
652 extern int microdia_6260_flip_detect(struct usb_microdia
*dev
);
653 extern int microdia_6270_initialize(struct usb_microdia
*dev
);
654 extern int microdia_6270_start_stream(struct usb_microdia
*dev
);
655 extern int microdia_6270_stop_stream(struct usb_microdia
*dev
);
656 extern int microdia_627b_initialize(struct usb_microdia
*dev
);
657 extern int microdia_627b_start_stream(struct usb_microdia
*dev
);
658 extern int microdia_627b_stop_stream(struct usb_microdia
*dev
);
659 extern int microdia_627f_initialize(struct usb_microdia
*dev
);
660 extern int microdia_6288_initialize(struct usb_microdia
*dev
);
661 extern int microdia_6288_start_stream(struct usb_microdia
*dev
);
662 extern int microdia_6288_stop_stream(struct usb_microdia
*dev
);
663 extern int microdia_6128_initialize(struct usb_microdia
*dev
);
664 extern int microdia_6128_start_stream(struct usb_microdia
*dev
);
665 extern int microdia_6128_stop_stream(struct usb_microdia
*dev
);
672 * @returns 0 if all is OK
674 * @brief Load the driver
676 * This function detects the device and allocate the buffers for the device
677 * and the video interface.
679 static int usb_microdia_probe(struct usb_interface
*interface
, const struct usb_device_id
*id
)
690 __u8 sensor_slave_address
= 0;
691 __u8 supported_fmts
= 0;
692 __u8 sensor_flags
= 0x80; // 2-WIRE,100KHz
693 int (*initialize
)(struct usb_microdia
*) = NULL
;
694 int (*stop_stream
)(struct usb_microdia
*) = NULL
;
695 int (*start_stream
)(struct usb_microdia
*) = NULL
;
696 int (*set_contrast
)(struct usb_microdia
*) = NULL
;
697 int (*set_brightness
)(struct usb_microdia
*) = NULL
;
698 int (*set_gamma
)(struct usb_microdia
*) = NULL
;
699 int (*set_exposure
)(struct usb_microdia
*) = NULL
;
700 int (*flip_detect_f
)(struct usb_microdia
*) = NULL
;
701 int (*set_hvflip
)(struct usb_microdia
*) = NULL
;
702 int (*set_sharpness
)(struct usb_microdia
*) = NULL
;
703 int (*set_auto_exposure
)(struct usb_microdia
*) = NULL
;
704 int (*set_auto_whitebalance
)(struct usb_microdia
*) = NULL
;
706 struct usb_microdia
*dev
= NULL
;
707 struct usb_device
*udev
= interface_to_usbdev(interface
);
708 struct usb_host_interface
*iface_desc
;
709 struct usb_endpoint_descriptor
*endpoint
;
711 // Set default device parameters:
712 webcam_type
= MICRODIA_VGA
;
713 sensor_flags
= SN9C20X_I2C_2WIRE
;
714 set_contrast
= sn9c20x_set_contrast
;
715 set_brightness
= sn9c20x_set_brightness
;
716 set_gamma
= sn9c20x_set_gamma
;
717 set_sharpness
= sn9c20x_set_sharpness
;
719 // Get USB VendorID and ProductID
720 vendor_id
= le16_to_cpu(udev
->descriptor
.idVendor
);
721 product_id
= le16_to_cpu(udev
->descriptor
.idProduct
);
723 // Check if we can handle this device
724 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
725 vendor_id
, product_id
, interface
->cur_altsetting
->desc
.bInterfaceNumber
);
727 // The interface are probed one by one.
728 // We are interested in the video interface (always the interface '0')
729 // The interfaces '1' or '2' (if presents) are the audio control.
730 if (interface
->cur_altsetting
->desc
.bInterfaceNumber
> 0) {
736 if (vendor_id
== USB_VENDOR_ID_MICRODIA
) {
737 switch (product_id
) {
738 case USB_UDIA_MICRODIA_PRODUCT_ID_6240
:
739 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6240.\n");
740 UDIA_INFO("This device is under development. Please contact microdia@googlegroups for further info\n");
741 webcam_model
= MICRODIA_6240
;
742 initialize
= microdia_6240_initialize
;
743 start_stream
= microdia_6240_start_stream
;
744 stop_stream
= microdia_6240_stop_stream
;
747 case USB_UDIA_MICRODIA_PRODUCT_ID_6242
:
748 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6242.\n");
749 webcam_model
= MICRODIA_6242
;
750 sensor_slave_address
= 0x5d;
751 supported_fmts
= 0x03;
752 initialize
= microdia_624e_initialize
;
753 start_stream
= microdia_6242_start_stream
;
754 stop_stream
= microdia_6242_stop_stream
;
757 case USB_UDIA_MICRODIA_PRODUCT_ID_6243
:
758 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6243.\n");
759 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
760 webcam_model
= MICRODIA_6243
;
764 case USB_UDIA_MICRODIA_PRODUCT_ID_6248
:
765 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6248.\n");
766 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
767 webcam_model
= MICRODIA_6248
;
771 case USB_UDIA_MICRODIA_PRODUCT_ID_624B
:
772 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624B.\n");
773 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
774 webcam_model
= MICRODIA_624B
;
778 case USB_UDIA_MICRODIA_PRODUCT_ID_624C
:
779 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624C.\n");
780 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
781 webcam_model
= MICRODIA_624C
;
785 case USB_UDIA_MICRODIA_PRODUCT_ID_624E
:
786 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624E.\n");
787 webcam_model
= MICRODIA_624E
;
788 webcam_type
= MICRODIA_SXGA
;
789 sensor_slave_address
= 0x30;
790 supported_fmts
= 0x03;
791 initialize
= microdia_624e_initialize
;
792 start_stream
= microdia_624e_start_stream
;
793 stop_stream
= microdia_624e_stop_stream
;
796 case USB_UDIA_MICRODIA_PRODUCT_ID_624F
:
797 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624F.\n");
798 webcam_model
= MICRODIA_624F
;
799 webcam_type
= MICRODIA_SXGA
;
800 sensor_slave_address
= 0x30;
801 supported_fmts
= 0x03;
802 initialize
= microdia_624f_initialize
;
803 start_stream
= microdia_624f_start_stream
;
804 stop_stream
= microdia_624f_stop_stream
;
805 set_exposure
= microdia_624f_set_exposure
;
806 flip_detect_f
= microdia_624f_flip_detect
;
809 case USB_UDIA_MICRODIA_PRODUCT_ID_6253
:
810 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6253.\n");
811 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
812 webcam_model
= MICRODIA_6253
;
816 case USB_UDIA_MICRODIA_PRODUCT_ID_6260
:
817 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6260.\n");
818 webcam_model
= MICRODIA_6260
;
819 sensor_slave_address
= 0x21;
820 supported_fmts
= 0x08;
821 initialize
= microdia_6260_initialize
;
822 start_stream
= microdia_6260_start_stream
;
823 stop_stream
= microdia_6260_stop_stream
;
824 flip_detect_f
= microdia_6260_flip_detect
;
827 case USB_UDIA_MICRODIA_PRODUCT_ID_6262
:
828 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6262.\n");
829 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
830 webcam_model
= MICRODIA_6262
;
834 case USB_UDIA_MICRODIA_PRODUCT_ID_6270
:
835 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6270.\n");
836 webcam_model
= MICRODIA_6270
;
837 sensor_slave_address
= 0; // will be probed during initialisation
838 supported_fmts
= 0x07;
839 initialize
= microdia_6270_initialize
;
840 start_stream
= microdia_6270_start_stream
;
841 stop_stream
= microdia_6270_stop_stream
;
842 set_exposure
= mt9vx11_set_exposure
;
843 set_hvflip
= mt9vx11_set_hvflip
;
844 set_auto_exposure
= mt9v111_set_autoexposure
;
845 set_auto_whitebalance
= mt9v111_set_autowhitebalance
;
848 case USB_UDIA_MICRODIA_PRODUCT_ID_627A
:
849 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627A.\n");
850 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
851 webcam_model
= MICRODIA_627A
;
855 case USB_UDIA_MICRODIA_PRODUCT_ID_627B
:
856 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627B.\n");
857 webcam_model
= MICRODIA_627B
;
858 sensor_slave_address
= 0x21;
859 supported_fmts
= 0x07;
860 initialize
= microdia_627b_initialize
;
861 start_stream
= microdia_627b_start_stream
;
862 stop_stream
= microdia_627b_stop_stream
;
865 case USB_UDIA_MICRODIA_PRODUCT_ID_627C
:
866 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627C.\n");
867 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
868 webcam_model
= MICRODIA_627C
;
872 case USB_UDIA_MICRODIA_PRODUCT_ID_627F
:
873 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627F.\n");
874 webcam_model
= MICRODIA_627F
;
875 webcam_type
= MICRODIA_SXGA
;
876 sensor_slave_address
= 0x30;
877 initialize
= microdia_627f_initialize
;
878 start_stream
= microdia_624f_start_stream
;
879 stop_stream
= microdia_624f_stop_stream
;
880 set_exposure
= microdia_624f_set_exposure
;
881 //flip_detect_f = microdia_624f_flip_detect;
884 case USB_UDIA_MICRODIA_PRODUCT_ID_6280
:
885 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6280.\n");
886 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
887 webcam_model
= MICRODIA_6280
;
891 case USB_UDIA_MICRODIA_PRODUCT_ID_6282
:
892 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6282.\n");
893 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
894 webcam_model
= MICRODIA_6282
;
898 case USB_UDIA_MICRODIA_PRODUCT_ID_6283
:
899 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6283.\n");
900 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
901 webcam_model
= MICRODIA_6283
;
905 case USB_UDIA_MICRODIA_PRODUCT_ID_6288
:
906 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6288.\n");
907 webcam_model
= MICRODIA_6288
;
908 sensor_slave_address
= 0x30;
909 supported_fmts
= 0x03;
910 initialize
= microdia_6288_initialize
;
911 start_stream
= microdia_6288_start_stream
;
912 stop_stream
= microdia_6288_stop_stream
;
915 case USB_UDIA_MICRODIA_PRODUCT_ID_628A
:
916 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 628A.\n");
917 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
918 webcam_model
= MICRODIA_628A
;
922 case USB_UDIA_MICRODIA_PRODUCT_ID_628B
:
923 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 628B.\n");
924 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
925 webcam_model
= MICRODIA_628B
;
929 case USB_UDIA_MICRODIA_PRODUCT_ID_628C
:
930 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 628C.\n");
931 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
932 webcam_model
= MICRODIA_628C
;
936 case USB_UDIA_MICRODIA_PRODUCT_ID_628E
:
937 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 628E.\n");
938 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
939 webcam_model
= MICRODIA_628E
;
943 case USB_UDIA_MICRODIA_PRODUCT_ID_628F
:
944 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 628F.\n");
945 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
946 webcam_model
= MICRODIA_628F
;
950 case USB_UDIA_MICRODIA_PRODUCT_ID_62A0
:
951 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62A0.\n");
952 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
953 webcam_model
= MICRODIA_62A0
;
957 case USB_UDIA_MICRODIA_PRODUCT_ID_62A2
:
958 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62A2.\n");
959 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
960 webcam_model
= MICRODIA_62A2
;
964 case USB_UDIA_MICRODIA_PRODUCT_ID_62B0
:
965 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62B0.\n");
966 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
967 webcam_model
= MICRODIA_62B0
;
971 case USB_UDIA_MICRODIA_PRODUCT_ID_62B3
:
972 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62B3.\n");
973 webcam_model
= MICRODIA_62B3
;
974 sensor_slave_address
= 0x30;
975 initialize
= microdia_6288_initialize
;
976 start_stream
= microdia_6288_start_stream
;
977 stop_stream
= microdia_6288_stop_stream
;
980 case USB_UDIA_MICRODIA_PRODUCT_ID_62BA
:
981 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BA.\n");
982 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
983 webcam_model
= MICRODIA_62BA
;
987 case USB_UDIA_MICRODIA_PRODUCT_ID_62BB
:
988 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BB.\n");
989 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
990 webcam_model
= MICRODIA_62BB
;
994 case USB_UDIA_MICRODIA_PRODUCT_ID_62BC
:
995 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BC.\n");
996 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
997 webcam_model
= MICRODIA_62BC
;
1001 case USB_UDIA_MICRODIA_PRODUCT_ID_62BE
:
1002 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BE.\n");
1003 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1004 webcam_model
= MICRODIA_62BE
;
1008 case USB_UDIA_MICRODIA_PRODUCT_ID_6128
:
1009 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6128.\n");
1010 webcam_model
= MICRODIA_6128
;
1011 webcam_type
= MICRODIA_SXGA
;
1012 sensor_slave_address
= 0x34;
1013 initialize
= microdia_6128_initialize
;
1014 start_stream
= microdia_6128_start_stream
;
1015 stop_stream
= microdia_6128_stop_stream
;
1016 set_contrast
= NULL
; // sn9c325_set_contrast
1017 set_brightness
= NULL
; // sn9c325_set_brightness
1018 set_gamma
= NULL
; // sn9c325_set_gamma
1019 set_sharpness
= NULL
; // sn9c325_set_sharpness
1022 case USB_UDIA_MICRODIA_PRODUCT_ID_612A
:
1023 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 612A.\n");
1024 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1025 webcam_model
= MICRODIA_612A
;
1026 set_contrast
= NULL
; // sn9c325_set_contrast
1027 set_brightness
= NULL
; // sn9c325_set_brightness
1028 set_gamma
= NULL
; // sn9c325_set_gamma
1029 set_sharpness
= NULL
; // sn9c325_set_sharpness
1039 else if (vendor_id
== USB_VENDOR_ID_MICROSOFT
) {
1040 switch (product_id
) {
1041 case USB_UDIA_MICROSOFT_PRODUCT_ID_00F4
:
1042 UDIA_INFO("Microdia PID 628F Compatible USB2.0 Webcam:\n Microsoft LifeCam VX-6000 (045e:00f4)\n");
1043 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1044 webcam_model
= MICRODIA_628F
;
1045 webcam_type
= MICRODIA_SXGA
;
1046 sensor_slave_address
= 0x30;
1054 else if (vendor_id
== USB_VENDOR_ID_CHICONY
) {
1055 switch (product_id
) {
1056 case USB_UDIA_CHICONY_PRODUCT_ID_A128
:
1057 UDIA_INFO("Microdia PID 62BE Compatible USB2.0 Webcam:\n Chicony Panda 7 (04f2:a128)\n");
1058 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1059 webcam_model
= MICRODIA_62BE
;
1067 else if (vendor_id
== USB_VENDOR_ID_TRUST
) {
1068 switch (product_id
) {
1069 case USB_UDIA_TRUST_PRODUCT_ID_013D
:
1070 UDIA_INFO("Microdia PID 627B Compatible USB2.0 Webcam:\n Trust WB-3600R (145f:013d)\n");
1071 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1072 webcam_model
= MICRODIA_627B
;
1073 sensor_slave_address
= 0x21;
1085 // Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device
1086 dev
= kzalloc(sizeof(struct usb_microdia
), GFP_KERNEL
);
1089 UDIA_ERROR("Out of memory !\n");
1094 // Init mutexes, spinlock, etc.
1095 mutex_init(&dev
->mutex
);
1096 kref_init(&dev
->vopen
);
1099 dev
->webcam_model
= webcam_model
;
1100 dev
->webcam_type
= webcam_type
;
1101 if (webcam_model
== MICRODIA_6260
)
1102 dev
->frame_size_divisor
= MICRODIA_FRAME_SIZE_DIVISOR_6260
;
1104 dev
->frame_size_divisor
= MICRODIA_FRAME_SIZE_DIVISOR_DEFAULT
;
1105 dev
->initialize
= initialize
;
1106 dev
->stop_stream
= stop_stream
;
1107 dev
->start_stream
= start_stream
;
1108 dev
->set_contrast
= set_contrast
;
1109 dev
->set_brightness
= set_brightness
;
1110 dev
->set_gamma
= set_gamma
;
1111 dev
->set_exposure
= set_exposure
;
1113 UDIA_INFO("Rotate detection enabled\n");
1114 dev
->flip_detect
= flip_detect_f
;
1116 dev
->set_hvflip
= set_hvflip
;
1117 dev
->set_sharpness
= set_sharpness
;
1118 dev
->set_auto_exposure
= set_auto_exposure
;
1119 dev
->set_auto_whitebalance
= set_auto_whitebalance
;
1121 dev
->interface
= interface
;
1122 dev
->sensor_slave_address
= sensor_slave_address
;
1123 dev
->sensor_flags
= sensor_flags
;
1124 dev
->supported_fmts
= supported_fmts
;
1126 // Read the product release
1127 dev
->release
= le16_to_cpu(udev
->descriptor
.bcdDevice
);
1128 UDIA_INFO("Release: %04x\n", dev
->release
);
1130 // How many interfaces (1 or 3) ?
1131 bNumInterfaces
= udev
->config
->desc
.bNumInterfaces
;
1132 UDIA_INFO("Number of interfaces : %d\n", bNumInterfaces
);
1135 // Switch on the camera (to detect size of buffers)
1136 dev_microdia_camera_on(dev
);
1139 // Set up the endpoint information
1140 // use only the first int-in and isoc-in endpoints
1141 // for the current alternate setting
1142 iface_desc
= interface
->cur_altsetting
;
1144 for (i
= 0; i
< iface_desc
->desc
.bNumEndpoints
; ++i
) {
1145 endpoint
= &iface_desc
->endpoint
[i
].desc
;
1147 if (!dev
->int_in_endpointAddr
1148 && ((endpoint
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
)
1149 && ((endpoint
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_INT
)) {
1150 // we found an interrupt in endpoint
1151 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
1153 dev
->int_in_size
= buffer_size
;
1154 dev
->int_in_endpointAddr
= (endpoint
->bEndpointAddress
& 0xf);
1157 if (!dev
->isoc_in_endpointAddr
1158 && ((endpoint
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
)
1159 && ((endpoint
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_ISOC
)) {
1160 // we found an isoc in endpoint
1161 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
1163 dev
->isoc_in_size
= buffer_size
;
1164 dev
->isoc_in_endpointAddr
= (endpoint
->bEndpointAddress
& 0xf);
1168 if (!(dev
->int_in_endpointAddr
&& dev
->isoc_in_endpointAddr
)) {
1169 UDIA_ERROR("Could not find both int-in and isoc-in endpoints");
1174 usb_microdia_default_settings(dev
);
1176 dev_microdia_camera_off(dev
);
1178 // Initialize the video device
1179 dev
->vdev
= video_device_alloc();
1186 // Initialize the camera
1187 dev_microdia_initialize_device(dev
);
1189 // Register the video device
1190 ret
= v4l_microdia_register_video_device(dev
);
1196 // Create the entries in the sys filesystem
1197 microdia_create_sysfs_files(dev
->vdev
);
1199 // Save our data pointer in this interface device
1200 usb_set_intfdata(interface
, dev
);
1205 kref_put(&dev
->vopen
, usb_microdia_delete
);
1210 void usb_microdia_delete(struct kref
*kref
)
1212 struct usb_microdia
*dev
;
1213 dev
= container_of(kref
, struct usb_microdia
, vopen
);
1215 if (dev
->vdev
!= NULL
) {
1216 microdia_remove_sysfs_files(dev
->vdev
);
1217 v4l_microdia_unregister_video_device(dev
);
1225 * @brief This function is called when the device is disconnected
1226 * or when the kernel module is unloaded.
1228 static void usb_microdia_disconnect(struct usb_interface
*interface
)
1230 struct usb_microdia
*dev
= usb_get_intfdata(interface
);
1232 UDIA_INFO("Microdia USB2.0 Camera disconnected\n");
1234 usb_set_intfdata(interface
, NULL
);
1236 mutex_lock(&open_lock
);
1237 kref_put(&dev
->vopen
, usb_microdia_delete
);
1238 mutex_unlock(&open_lock
);
1243 * @var usb_microdia_driver
1245 * This variable contains some callback
1247 static struct usb_driver usb_microdia_driver
= {
1248 .name
= "usb_microdia_driver",
1249 .probe
= usb_microdia_probe
,
1250 .disconnect
= usb_microdia_disconnect
,
1251 .id_table
= microdia_table
,
1254 module_param(fps
, int, 0444); /**< @brief Module parameter frames per second */
1255 module_param(hflip
, int, 0444); /**< @brief Module parameter horizontal flip process */
1256 module_param(vflip
, int, 0444); /**< @brief Module parameter vertical flip process */
1257 module_param(flip_detect
, int, 0444); /**< @brief Module parameter flip detect */
1258 module_param(auto_exposure
, int, 0444); /**< @brief Module parameter automatic exposure control */
1259 module_param(auto_whitebalance
, int, 0444); /**< @brief Module parameter automatic whitebalance control */
1260 module_param(brightness
, int, 0444); /**< @brief Module parameter brightness */
1261 module_param(whiteness
, int, 0444); /**< @brief Module parameter whiteness */
1262 module_param(contrast
, int, 0444); /**< @brief Module parameter contrast */
1263 module_param(exposure
, int, 0444); /**< @brief Module parameter exposure */
1264 module_param(sharpness
, int, 0444); /**< @brief Module parameter sharpness */
1266 module_param(min_buffers
, int, 0444);
1267 module_param(max_buffers
, int, 0444);
1271 * @returns 0 if all is OK
1273 * @brief Initialize the driver.
1275 * This function is called at first.
1276 * This function permits to define the default values from the command line.
1278 static int __init
usb_microdia_init(void)
1282 UDIA_INFO("Microdia USB2.0 webcam driver startup\n");
1284 debug_dir
= debugfs_create_dir(debug_dir_name
, NULL
);
1286 debug_file
= debugfs_create_u8(debug_file_name
, S_IRUGO
| S_IWUGO
,
1287 debug_dir
, &debug_level
);
1289 if(fps
< 10 || fps
> 30) {
1290 UDIA_WARNING("Framerate out of bounds [10-30]! Defaulting to 25\n");
1294 if(vflip
!= 0 && vflip
!= 1) {
1295 UDIA_WARNING("Vertical flip should be 0 or 1! Defaulting to 0\n");
1299 if(hflip
!= 0 && hflip
!= 1) {
1300 UDIA_WARNING("Horizontal flip should be 0 or 1! Defaulting to 0\n");
1304 if (sharpness
< 0 || sharpness
> 0x3f) {
1305 UDIA_WARNING("Sharpness should be 0 to 63 ! Defaulting to 31\n");
1309 if(auto_exposure
!= 0 && auto_exposure
!= 1) {
1310 UDIA_WARNING("Automatic exposure should be 0 or 1! "
1311 "Defaulting to 1\n");
1315 if(auto_whitebalance
!= 0 && auto_whitebalance
!= 1) {
1316 UDIA_WARNING("Automatic whitebalance should be 0 or 1! "
1317 "Defaulting to 1\n");
1318 auto_whitebalance
= 1;
1321 if (min_buffers
< 2) {
1322 UDIA_WARNING("Minimum buffers can't be less then 2! "
1323 "Defaulting to 2\n");
1328 if (min_buffers
> max_buffers
) {
1329 UDIA_WARNING("Minimum buffers must be less then or equal to "
1330 "max buffers! Defaulting to 2, 10\n");
1335 // Register the driver with the USB subsystem
1336 result
= usb_register(&usb_microdia_driver
);
1339 UDIA_ERROR("usb_register failed ! Error number %d\n", result
);
1341 UDIA_INFO(DRIVER_VERSION
" : " DRIVER_DESC
"\n");
1348 * @brief Close the driver
1350 * This function is called at last when you unload the driver.
1352 static void __exit
usb_microdia_exit(void)
1354 UDIA_INFO("usb_microdia_exit: Microdia USB2.0 webcam driver shutdown\n");
1357 debugfs_remove(debug_file
);
1359 debugfs_remove(debug_dir
);
1361 // Deregister this driver with the USB subsystem
1362 usb_deregister(&usb_microdia_driver
);
1366 module_init(usb_microdia_init
); /**< @brief Module initialize */
1367 module_exit(usb_microdia_exit
); /**< @brief Module exit */
1370 MODULE_PARM_DESC(fps
, "Frames per second [10-30]"); /**< @brief Description of 'fps' parameter */
1371 MODULE_PARM_DESC(hflip
, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1372 MODULE_PARM_DESC(vflip
, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1373 MODULE_PARM_DESC(flip_detect
, "Image flip detection"); /**< @brief Description of 'vflip_detect' parameter */
1374 MODULE_PARM_DESC(auto_exposure
, "Automatic exposure control"); /**< @brief Description of 'auto_exposure' parameter */
1375 MODULE_PARM_DESC(auto_whitebalance
, "Automatic whitebalance"); /**< @brief Description of 'auto_whitebalance' parameter */
1376 MODULE_PARM_DESC(brightness
, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1377 MODULE_PARM_DESC(whiteness
, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1378 MODULE_PARM_DESC(exposure
, "Exposure setting"); /**< @brief Description of 'exposure' parameter */
1379 MODULE_PARM_DESC(contrast
, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1380 MODULE_PARM_DESC(sharpness
, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */
1382 MODULE_PARM_DESC(min_buffers
, "Minimum number of image buffers");
1383 MODULE_PARM_DESC(max_buffers
, "Maximum number of image buffers");
1385 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1386 MODULE_AUTHOR(DRIVER_AUTHOR
); /**< @brief Driver is written by Nicolas VIVIEN */
1387 MODULE_DESCRIPTION(DRIVER_DESC
); /**< @brief Define the description of the driver */
1388 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT
); /**< @brief List of supported device */