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
);
283 * @param urb URB structure
285 * @brief ISOC handler
287 * This function is called as an URB transfert is complete (Isochronous pipe).
288 * So, the traitement is done in interrupt time, so it has be fast, not crash,
289 * ans not stall. Neat.
291 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
292 void usb_microdia_isoc_handler(struct urb
*urb
, struct pt_regs
*regs
)
294 void usb_microdia_isoc_handler(struct urb
*urb
)
301 unsigned int framelen
;
304 unsigned char *iso_buf
= NULL
;
307 struct microdia_buffer
*buf
= NULL
;
308 struct usb_microdia
*dev
= urb
->context
;
309 struct microdia_video_queue
*queue
= &dev
->queue
;
311 unsigned char frame_header
[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
313 UDIA_STREAM("Isoc handler\n");
315 switch (urb
->status
) {
320 UDIA_WARNING("Non-zero status (%d) in video "
321 "completion handler.\n", urb
->status
);
323 case -ENOENT
: /* usb_kill_urb() called. */
327 case -ECONNRESET
: /* usb_unlink_urb() called. */
328 case -ESHUTDOWN
: /* The endpoint is being disabled. */
329 microdia_queue_cancel(queue
);
333 spin_lock_irqsave(&queue
->irqlock
, flags
);
334 if (!list_empty(&queue
->irqqueue
))
335 buf
= list_first_entry(&queue
->irqqueue
, struct microdia_buffer
,
337 spin_unlock_irqrestore(&queue
->irqlock
, flags
);
339 for (i
=0; i
<urb
->number_of_packets
; i
++) {
340 framestatus
= urb
->iso_frame_desc
[i
].status
;
341 if (framestatus
!= 0) {
342 UDIA_ERROR("Iso frame %d of USB has error %d\n",
346 framelen
= urb
->iso_frame_desc
[i
].actual_length
;
347 iso_buf
= urb
->transfer_buffer
+ urb
->iso_frame_desc
[i
].offset
;
352 if (memcmp(iso_buf
, frame_header
, 6) == 0 && framelen
== 64) {
353 UDIA_DEBUG("Frame Resolution: %dx%d\n",
354 iso_buf
[0x3a] << 4, iso_buf
[0x3b] << 3);
355 if (buf
->buf
.bytesused
!= 0)
356 buf
->state
= MICRODIA_BUF_STATE_DONE
;
358 if (buf
->state
!= MICRODIA_BUF_STATE_ACTIVE
)
359 buf
->state
= MICRODIA_BUF_STATE_ACTIVE
;
361 if (framelen
+ buf
->buf
.bytesused
> queue
->frame_size
) {
362 UDIA_WARNING("Frame Buffer overflow!\n");
363 dev
->vframes_overflow
++;
364 buf
->state
= MICRODIA_BUF_STATE_DONE
;
366 framelen
= min(queue
->frame_size
- buf
->buf
.bytesused
,
368 mem
= queue
->mem
+ buf
->buf
.m
.offset
+
370 memcpy(mem
, iso_buf
, framelen
);
371 buf
->buf
.bytesused
+= framelen
;
373 if (buf
->state
== MICRODIA_BUF_STATE_DONE
||
374 buf
->state
== MICRODIA_BUF_STATE_ERROR
) {
375 buf
= microdia_queue_next_buffer(queue
, buf
);
377 dev
->vframes_dropped
++;
381 urb
->dev
= dev
->udev
;
383 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
386 UDIA_ERROR("Error (%d) re-submitting urb in "
387 "microdia_isoc_handler.\n", ret
);
393 * @param dev Device structure
395 * @brief Clean-up all the ISOC buffers
397 * This function permits to clean-up all the ISOC buffers.
399 void usb_microdia_isoc_cleanup(struct usb_microdia
*dev
)
404 UDIA_DEBUG("Isoc cleanup\n");
409 for (i
=0; i
<MAX_ISO_BUFS
; i
++) {
410 urb
= dev
->isobuf
[i
].urb
;
415 if (dev
->isobuf
[i
].data
) {
416 kfree(dev
->isobuf
[i
].data
);
417 dev
->isobuf
[i
].data
= NULL
;
420 dev
->isobuf
[i
].urb
= NULL
;
427 * @param dev Device structure
428 * @param index Choice of the interface
430 * @returns 0 if all is OK
432 * @brief Send the message SET_FEATURE and choose the interface
434 * This function permits to send the message SET_FEATURE on the USB bus.
436 int usb_microdia_set_feature(struct usb_microdia
*dev
, int index
)
439 struct usb_device
*udev
= dev
->udev
;
441 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
443 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
444 USB_DEVICE_REMOTE_WAKEUP
,
451 UDIA_ERROR("SET FEATURE fail !\n");
453 UDIA_DEBUG("SET FEATURE\n");
460 * @param dev Device structure
462 * @returns 0 if all is OK
464 * @brief Send the message SET_CONFIGURATION
466 * This function permits to send the message SET_CONFIGURATION on the USB bus.
468 int usb_microdia_set_configuration(struct usb_microdia
*dev
)
471 struct usb_device
*udev
= dev
->udev
;
473 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
474 USB_REQ_SET_CONFIGURATION
,
475 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
477 udev
->config
[0].desc
.bConfigurationValue
,
483 UDIA_ERROR("SET CONFIGURATION fail !\n");
485 UDIA_DEBUG("SET CONFIGURATION %d\n", udev
->config
[0].desc
.bConfigurationValue
);
492 * @param dev Device structure
493 * @param value register to write to
495 * @param length number of bytes
497 * @returns 0 if all is OK
499 * @brief Write a 16-bit value to a 16-bit register
501 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
503 int usb_microdia_control_write(struct usb_microdia
*dev
, __u16 value
, __u8
*data
, __u16 length
)
506 struct usb_device
*udev
= dev
->udev
;
508 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
510 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
518 UDIA_ERROR("Write register failed index = 0x%02X\n", value
);
530 * @returns 0 if all is OK
532 * @brief Write a series of 16-bit "commands" using the same buffer
534 int usb_microdia_control_write_multi(struct usb_microdia
*dev
, __u16
*commands
, __u8
*data
,
535 __u16 cmdlen
, __u16 datalen
)
539 for(i
= 0; i
< cmdlen
; i
++) {
540 result
= usb_microdia_control_write(dev
, commands
[i
], data
, datalen
);
550 * @param dev Device structure
551 * @param index register to read from
553 * @param length number of bytes
555 * @returns 0 if all is OK
557 * @brief Read a 16-bit value from a 16-bit register
559 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
561 int usb_microdia_control_read(struct usb_microdia
*dev
, __u16 index
, __u8
*data
, __u16 length
)
565 struct usb_device
*udev
= dev
->udev
;
569 result
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
571 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
579 UDIA_ERROR("Read register failed 0x%02X\n", index
);
588 * @returns 0 if all is OK
590 * @brief Set the default value about the video settings.
592 * This function permits to set the video settings for each video camera model.
595 static int usb_microdia_default_settings(struct usb_microdia
*dev
)
597 struct v4l2_pix_format
*def_fmt
;
599 dev
->vframes_overflow
= 0;
600 dev
->vframes_incomplete
= 0;
601 dev
->vframes_dropped
= 0;
603 dev
->queue
.min_buffers
= min_buffers
;
604 dev
->queue
.max_buffers
= max_buffers
;
606 def_fmt
= v4l2_enum_supported_formats(dev
, 0);
608 switch (dev
->webcam_model
) {
610 dev
->vsettings
.fps
= fps
;
611 dev
->vsettings
.vflip
= vflip
;
612 dev
->vsettings
.hflip
= hflip
;
613 dev
->vsettings
.brightness
= brightness
& 0xffff;
614 dev
->vsettings
.contrast
= contrast
& 0xffff;
615 dev
->vsettings
.whiteness
= whiteness
& 0xffff;
616 dev
->vsettings
.exposure
= exposure
& 0xffff;
617 dev
->vsettings
.sharpness
= sharpness
& 0x3f;
618 dev
->vsettings
.auto_exposure
= auto_exposure
& 1;
619 dev
->vsettings
.auto_whitebalance
= auto_whitebalance
& 1;
620 dev
->vsettings
.hue
= 0xffff;
623 memcpy(&(dev
->vsettings
.format
),
625 sizeof(struct v4l2_pix_format
));
628 v4l_microdia_select_video_mode(dev
, MICRODIA_640x480
);
634 extern int microdia_6240_initialize(struct usb_microdia
*dev
);
635 extern int microdia_6240_start_stream(struct usb_microdia
*dev
);
636 extern int microdia_6240_stop_stream(struct usb_microdia
*dev
);
637 extern int microdia_6242_start_stream(struct usb_microdia
*dev
);
638 extern int microdia_6242_stop_stream(struct usb_microdia
*dev
);
639 extern int microdia_624e_initialize(struct usb_microdia
*dev
);
640 extern int microdia_624e_start_stream(struct usb_microdia
*dev
);
641 extern int microdia_624e_stop_stream(struct usb_microdia
*dev
);
642 extern int microdia_624f_initialize(struct usb_microdia
*dev
);
643 extern int microdia_624f_stop_stream(struct usb_microdia
*dev
);
644 extern int microdia_624f_start_stream(struct usb_microdia
*dev
);
645 extern int microdia_624f_set_exposure(struct usb_microdia
*dev
);
646 extern int microdia_624f_flip_detect(struct usb_microdia
*dev
);
647 extern int microdia_6260_initialize(struct usb_microdia
*dev
);
648 extern int microdia_6260_start_stream(struct usb_microdia
*dev
);
649 extern int microdia_6260_stop_stream(struct usb_microdia
*dev
);
650 extern int microdia_6260_flip_detect(struct usb_microdia
*dev
);
651 extern int microdia_6270_initialize(struct usb_microdia
*dev
);
652 extern int microdia_6270_start_stream(struct usb_microdia
*dev
);
653 extern int microdia_6270_stop_stream(struct usb_microdia
*dev
);
654 extern int microdia_627b_initialize(struct usb_microdia
*dev
);
655 extern int microdia_627b_start_stream(struct usb_microdia
*dev
);
656 extern int microdia_627b_stop_stream(struct usb_microdia
*dev
);
657 extern int microdia_627f_initialize(struct usb_microdia
*dev
);
658 extern int microdia_6288_initialize(struct usb_microdia
*dev
);
659 extern int microdia_6288_start_stream(struct usb_microdia
*dev
);
660 extern int microdia_6288_stop_stream(struct usb_microdia
*dev
);
661 extern int microdia_6128_initialize(struct usb_microdia
*dev
);
662 extern int microdia_6128_start_stream(struct usb_microdia
*dev
);
663 extern int microdia_6128_stop_stream(struct usb_microdia
*dev
);
670 * @returns 0 if all is OK
672 * @brief Load the driver
674 * This function detects the device and allocate the buffers for the device
675 * and the video interface.
677 static int usb_microdia_probe(struct usb_interface
*interface
, const struct usb_device_id
*id
)
688 __u8 sensor_slave_address
= 0;
689 __u8 supported_fmts
= 0;
690 __u8 sensor_flags
= 0x80; // 2-WIRE,100KHz
691 int (*initialize
)(struct usb_microdia
*) = NULL
;
692 int (*stop_stream
)(struct usb_microdia
*) = NULL
;
693 int (*start_stream
)(struct usb_microdia
*) = NULL
;
694 int (*set_contrast
)(struct usb_microdia
*) = NULL
;
695 int (*set_brightness
)(struct usb_microdia
*) = NULL
;
696 int (*set_gamma
)(struct usb_microdia
*) = NULL
;
697 int (*set_exposure
)(struct usb_microdia
*) = NULL
;
698 int (*flip_detect_f
)(struct usb_microdia
*) = NULL
;
699 int (*set_hvflip
)(struct usb_microdia
*) = NULL
;
700 int (*set_sharpness
)(struct usb_microdia
*) = NULL
;
701 int (*set_auto_exposure
)(struct usb_microdia
*) = NULL
;
702 int (*set_auto_whitebalance
)(struct usb_microdia
*) = NULL
;
704 struct usb_microdia
*dev
= NULL
;
705 struct usb_device
*udev
= interface_to_usbdev(interface
);
706 struct usb_host_interface
*iface_desc
;
707 struct usb_endpoint_descriptor
*endpoint
;
709 // Set default device parameters:
710 webcam_type
= MICRODIA_VGA
;
711 sensor_flags
= SN9C20X_I2C_2WIRE
;
712 set_contrast
= sn9c20x_set_contrast
;
713 set_brightness
= sn9c20x_set_brightness
;
714 set_gamma
= sn9c20x_set_gamma
;
715 set_sharpness
= sn9c20x_set_sharpness
;
717 // Get USB VendorID and ProductID
718 vendor_id
= le16_to_cpu(udev
->descriptor
.idVendor
);
719 product_id
= le16_to_cpu(udev
->descriptor
.idProduct
);
721 // Check if we can handle this device
722 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
723 vendor_id
, product_id
, interface
->cur_altsetting
->desc
.bInterfaceNumber
);
725 // The interface are probed one by one.
726 // We are interested in the video interface (always the interface '0')
727 // The interfaces '1' or '2' (if presents) are the audio control.
728 if (interface
->cur_altsetting
->desc
.bInterfaceNumber
> 0) {
734 if (vendor_id
== USB_VENDOR_ID_MICRODIA
) {
735 switch (product_id
) {
736 case USB_UDIA_MICRODIA_PRODUCT_ID_6240
:
737 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6240.\n");
738 UDIA_INFO("This device is under development. Please contact microdia@googlegroups for further info\n");
739 webcam_model
= MICRODIA_6240
;
740 supported_fmts
= 0x03;
741 initialize
= microdia_6240_initialize
;
742 start_stream
= microdia_6240_start_stream
;
743 stop_stream
= microdia_6240_stop_stream
;
746 case USB_UDIA_MICRODIA_PRODUCT_ID_6242
:
747 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6242.\n");
748 webcam_model
= MICRODIA_6242
;
749 sensor_slave_address
= 0x5d;
750 supported_fmts
= 0x03;
751 initialize
= microdia_624e_initialize
;
752 start_stream
= microdia_6242_start_stream
;
753 stop_stream
= microdia_6242_stop_stream
;
756 case USB_UDIA_MICRODIA_PRODUCT_ID_6243
:
757 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6243.\n");
758 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
759 webcam_model
= MICRODIA_6243
;
763 case USB_UDIA_MICRODIA_PRODUCT_ID_6248
:
764 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6248.\n");
765 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
766 webcam_model
= MICRODIA_6248
;
770 case USB_UDIA_MICRODIA_PRODUCT_ID_624B
:
771 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624B.\n");
772 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
773 webcam_model
= MICRODIA_624B
;
777 case USB_UDIA_MICRODIA_PRODUCT_ID_624C
:
778 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624C.\n");
779 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
780 webcam_model
= MICRODIA_624C
;
784 case USB_UDIA_MICRODIA_PRODUCT_ID_624E
:
785 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624E.\n");
786 webcam_model
= MICRODIA_624E
;
787 webcam_type
= MICRODIA_SXGA
;
788 sensor_slave_address
= 0x30;
789 supported_fmts
= 0x03;
790 initialize
= microdia_624e_initialize
;
791 start_stream
= microdia_624e_start_stream
;
792 stop_stream
= microdia_624e_stop_stream
;
795 case USB_UDIA_MICRODIA_PRODUCT_ID_624F
:
796 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 624F.\n");
797 webcam_model
= MICRODIA_624F
;
798 webcam_type
= MICRODIA_SXGA
;
799 sensor_slave_address
= 0x30;
800 supported_fmts
= 0x03;
801 initialize
= microdia_624f_initialize
;
802 start_stream
= microdia_624f_start_stream
;
803 stop_stream
= microdia_624f_stop_stream
;
804 set_exposure
= microdia_624f_set_exposure
;
805 flip_detect_f
= microdia_624f_flip_detect
;
808 case USB_UDIA_MICRODIA_PRODUCT_ID_6253
:
809 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6253.\n");
810 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
811 webcam_model
= MICRODIA_6253
;
815 case USB_UDIA_MICRODIA_PRODUCT_ID_6260
:
816 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6260.\n");
817 webcam_model
= MICRODIA_6260
;
818 sensor_slave_address
= 0x21;
819 supported_fmts
= 0x08;
820 initialize
= microdia_6260_initialize
;
821 start_stream
= microdia_6260_start_stream
;
822 stop_stream
= microdia_6260_stop_stream
;
823 flip_detect_f
= microdia_6260_flip_detect
;
826 case USB_UDIA_MICRODIA_PRODUCT_ID_6262
:
827 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6262.\n");
828 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
829 webcam_model
= MICRODIA_6262
;
833 case USB_UDIA_MICRODIA_PRODUCT_ID_6270
:
834 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6270.\n");
835 webcam_model
= MICRODIA_6270
;
836 sensor_slave_address
= 0; // will be probed during initialisation
837 supported_fmts
= 0x07;
838 initialize
= microdia_6270_initialize
;
839 start_stream
= microdia_6270_start_stream
;
840 stop_stream
= microdia_6270_stop_stream
;
841 set_exposure
= mt9vx11_set_exposure
;
842 set_hvflip
= mt9vx11_set_hvflip
;
843 set_auto_exposure
= mt9v111_set_autoexposure
;
844 set_auto_whitebalance
= mt9v111_set_autowhitebalance
;
847 case USB_UDIA_MICRODIA_PRODUCT_ID_627A
:
848 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627A.\n");
849 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
850 webcam_model
= MICRODIA_627A
;
854 case USB_UDIA_MICRODIA_PRODUCT_ID_627B
:
855 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627B.\n");
856 webcam_model
= MICRODIA_627B
;
857 sensor_slave_address
= 0x21;
858 supported_fmts
= 0x07;
859 initialize
= microdia_627b_initialize
;
860 start_stream
= microdia_627b_start_stream
;
861 stop_stream
= microdia_627b_stop_stream
;
864 case USB_UDIA_MICRODIA_PRODUCT_ID_627C
:
865 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627C.\n");
866 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
867 webcam_model
= MICRODIA_627C
;
871 case USB_UDIA_MICRODIA_PRODUCT_ID_627F
:
872 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627F.\n");
873 webcam_model
= MICRODIA_627F
;
874 webcam_type
= MICRODIA_SXGA
;
875 sensor_slave_address
= 0x30;
876 supported_fmts
= 0x03;
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 supported_fmts
= 0x03;
976 initialize
= microdia_6288_initialize
;
977 start_stream
= microdia_6288_start_stream
;
978 stop_stream
= microdia_6288_stop_stream
;
981 case USB_UDIA_MICRODIA_PRODUCT_ID_62BA
:
982 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BA.\n");
983 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
984 webcam_model
= MICRODIA_62BA
;
988 case USB_UDIA_MICRODIA_PRODUCT_ID_62BB
:
989 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BB.\n");
990 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
991 webcam_model
= MICRODIA_62BB
;
995 case USB_UDIA_MICRODIA_PRODUCT_ID_62BC
:
996 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BC.\n");
997 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
998 webcam_model
= MICRODIA_62BC
;
1002 case USB_UDIA_MICRODIA_PRODUCT_ID_62BE
:
1003 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 62BE.\n");
1004 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1005 webcam_model
= MICRODIA_62BE
;
1009 case USB_UDIA_MICRODIA_PRODUCT_ID_6128
:
1010 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 6128.\n");
1011 webcam_model
= MICRODIA_6128
;
1012 webcam_type
= MICRODIA_SXGA
;
1013 sensor_slave_address
= 0x34;
1014 initialize
= microdia_6128_initialize
;
1015 start_stream
= microdia_6128_start_stream
;
1016 stop_stream
= microdia_6128_stop_stream
;
1017 set_contrast
= NULL
; // sn9c325_set_contrast
1018 set_brightness
= NULL
; // sn9c325_set_brightness
1019 set_gamma
= NULL
; // sn9c325_set_gamma
1020 set_sharpness
= NULL
; // sn9c325_set_sharpness
1023 case USB_UDIA_MICRODIA_PRODUCT_ID_612A
:
1024 UDIA_INFO("Microdia USB2.0 Webcam - Product ID 612A.\n");
1025 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1026 webcam_model
= MICRODIA_612A
;
1027 set_contrast
= NULL
; // sn9c325_set_contrast
1028 set_brightness
= NULL
; // sn9c325_set_brightness
1029 set_gamma
= NULL
; // sn9c325_set_gamma
1030 set_sharpness
= NULL
; // sn9c325_set_sharpness
1040 else if (vendor_id
== USB_VENDOR_ID_MICROSOFT
) {
1041 switch (product_id
) {
1042 case USB_UDIA_MICROSOFT_PRODUCT_ID_00F4
:
1043 UDIA_INFO("Microdia PID 628F Compatible USB2.0 Webcam:\n Microsoft LifeCam VX-6000 (045e:00f4)\n");
1044 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1045 webcam_model
= MICRODIA_628F
;
1046 webcam_type
= MICRODIA_SXGA
;
1047 sensor_slave_address
= 0x30;
1055 else if (vendor_id
== USB_VENDOR_ID_CHICONY
) {
1056 switch (product_id
) {
1057 case USB_UDIA_CHICONY_PRODUCT_ID_A128
:
1058 UDIA_INFO("Microdia PID 62BE Compatible USB2.0 Webcam:\n Chicony Panda 7 (04f2:a128)\n");
1059 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1060 webcam_model
= MICRODIA_62BE
;
1068 else if (vendor_id
== USB_VENDOR_ID_TRUST
) {
1069 switch (product_id
) {
1070 case USB_UDIA_TRUST_PRODUCT_ID_013D
:
1071 UDIA_INFO("Microdia PID 627B Compatible USB2.0 Webcam:\n Trust WB-3600R (145f:013d)\n");
1072 UDIA_INFO("This device is not supported yet. Please contact microdia@googlegroups.com if you want to add support for this device\n");
1073 webcam_model
= MICRODIA_627B
;
1074 sensor_slave_address
= 0x21;
1086 // Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device
1087 dev
= kzalloc(sizeof(struct usb_microdia
), GFP_KERNEL
);
1090 UDIA_ERROR("Out of memory !\n");
1095 // Init mutexes, spinlock, etc.
1096 mutex_init(&dev
->mutex
);
1097 kref_init(&dev
->vopen
);
1100 dev
->webcam_model
= webcam_model
;
1101 dev
->webcam_type
= webcam_type
;
1102 if (webcam_model
== MICRODIA_6260
)
1103 dev
->frame_size_divisor
= MICRODIA_FRAME_SIZE_DIVISOR_6260
;
1105 dev
->frame_size_divisor
= MICRODIA_FRAME_SIZE_DIVISOR_DEFAULT
;
1106 dev
->initialize
= initialize
;
1107 dev
->stop_stream
= stop_stream
;
1108 dev
->start_stream
= start_stream
;
1109 dev
->set_contrast
= set_contrast
;
1110 dev
->set_brightness
= set_brightness
;
1111 dev
->set_gamma
= set_gamma
;
1112 dev
->set_exposure
= set_exposure
;
1114 UDIA_INFO("Rotate detection enabled\n");
1115 dev
->flip_detect
= flip_detect_f
;
1117 dev
->set_hvflip
= set_hvflip
;
1118 dev
->set_sharpness
= set_sharpness
;
1119 dev
->set_auto_exposure
= set_auto_exposure
;
1120 dev
->set_auto_whitebalance
= set_auto_whitebalance
;
1122 dev
->interface
= interface
;
1123 dev
->sensor_slave_address
= sensor_slave_address
;
1124 dev
->sensor_flags
= sensor_flags
;
1125 dev
->supported_fmts
= supported_fmts
;
1127 // Read the product release
1128 dev
->release
= le16_to_cpu(udev
->descriptor
.bcdDevice
);
1129 UDIA_INFO("Release: %04x\n", dev
->release
);
1131 // How many interfaces (1 or 3) ?
1132 bNumInterfaces
= udev
->config
->desc
.bNumInterfaces
;
1133 UDIA_INFO("Number of interfaces : %d\n", bNumInterfaces
);
1136 // Switch on the camera (to detect size of buffers)
1137 dev_microdia_camera_on(dev
);
1140 // Set up the endpoint information
1141 // use only the first int-in and isoc-in endpoints
1142 // for the current alternate setting
1143 iface_desc
= interface
->cur_altsetting
;
1145 for (i
= 0; i
< iface_desc
->desc
.bNumEndpoints
; ++i
) {
1146 endpoint
= &iface_desc
->endpoint
[i
].desc
;
1148 if (!dev
->int_in_endpointAddr
1149 && ((endpoint
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
)
1150 && ((endpoint
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_INT
)) {
1151 // we found an interrupt in endpoint
1152 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
1154 dev
->int_in_size
= buffer_size
;
1155 dev
->int_in_endpointAddr
= (endpoint
->bEndpointAddress
& 0xf);
1158 if (!dev
->isoc_in_endpointAddr
1159 && ((endpoint
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
)
1160 && ((endpoint
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_ISOC
)) {
1161 // we found an isoc in endpoint
1162 buffer_size
= le16_to_cpu(endpoint
->wMaxPacketSize
);
1164 dev
->isoc_in_size
= buffer_size
;
1165 dev
->isoc_in_endpointAddr
= (endpoint
->bEndpointAddress
& 0xf);
1169 if (!(dev
->int_in_endpointAddr
&& dev
->isoc_in_endpointAddr
)) {
1170 UDIA_ERROR("Could not find both int-in and isoc-in endpoints");
1175 usb_microdia_default_settings(dev
);
1177 dev_microdia_camera_off(dev
);
1179 // Initialize the video device
1180 dev
->vdev
= video_device_alloc();
1187 // Initialize the camera
1188 dev_microdia_initialize_device(dev
);
1190 // Register the video device
1191 ret
= v4l_microdia_register_video_device(dev
);
1197 // Create the entries in the sys filesystem
1198 microdia_create_sysfs_files(dev
->vdev
);
1200 // Save our data pointer in this interface device
1201 usb_set_intfdata(interface
, dev
);
1206 kref_put(&dev
->vopen
, usb_microdia_delete
);
1211 void usb_microdia_delete(struct kref
*kref
)
1213 struct usb_microdia
*dev
;
1214 dev
= container_of(kref
, struct usb_microdia
, vopen
);
1216 if (dev
->vdev
!= NULL
) {
1217 microdia_remove_sysfs_files(dev
->vdev
);
1218 v4l_microdia_unregister_video_device(dev
);
1226 * @brief This function is called when the device is disconnected
1227 * or when the kernel module is unloaded.
1229 static void usb_microdia_disconnect(struct usb_interface
*interface
)
1231 struct usb_microdia
*dev
= usb_get_intfdata(interface
);
1233 UDIA_INFO("Microdia USB2.0 Camera disconnected\n");
1235 usb_set_intfdata(interface
, NULL
);
1237 mutex_lock(&open_lock
);
1238 kref_put(&dev
->vopen
, usb_microdia_delete
);
1239 mutex_unlock(&open_lock
);
1244 * @var usb_microdia_driver
1246 * This variable contains some callback
1248 static struct usb_driver usb_microdia_driver
= {
1249 .name
= "usb_microdia_driver",
1250 .probe
= usb_microdia_probe
,
1251 .disconnect
= usb_microdia_disconnect
,
1252 .id_table
= microdia_table
,
1255 module_param(fps
, int, 0444); /**< @brief Module parameter frames per second */
1256 module_param(hflip
, int, 0444); /**< @brief Module parameter horizontal flip process */
1257 module_param(vflip
, int, 0444); /**< @brief Module parameter vertical flip process */
1258 module_param(flip_detect
, int, 0444); /**< @brief Module parameter flip detect */
1259 module_param(auto_exposure
, int, 0444); /**< @brief Module parameter automatic exposure control */
1260 module_param(auto_whitebalance
, int, 0444); /**< @brief Module parameter automatic whitebalance control */
1261 module_param(brightness
, int, 0444); /**< @brief Module parameter brightness */
1262 module_param(whiteness
, int, 0444); /**< @brief Module parameter whiteness */
1263 module_param(contrast
, int, 0444); /**< @brief Module parameter contrast */
1264 module_param(exposure
, int, 0444); /**< @brief Module parameter exposure */
1265 module_param(sharpness
, int, 0444); /**< @brief Module parameter sharpness */
1267 module_param(min_buffers
, int, 0444);
1268 module_param(max_buffers
, int, 0444);
1272 * @returns 0 if all is OK
1274 * @brief Initialize the driver.
1276 * This function is called at first.
1277 * This function permits to define the default values from the command line.
1279 static int __init
usb_microdia_init(void)
1283 UDIA_INFO("Microdia USB2.0 webcam driver startup\n");
1285 debug_dir
= debugfs_create_dir(debug_dir_name
, NULL
);
1287 debug_file
= debugfs_create_u8(debug_file_name
, S_IRUGO
| S_IWUGO
,
1288 debug_dir
, &debug_level
);
1290 if(fps
< 10 || fps
> 30) {
1291 UDIA_WARNING("Framerate out of bounds [10-30]! Defaulting to 25\n");
1295 if(vflip
!= 0 && vflip
!= 1) {
1296 UDIA_WARNING("Vertical flip should be 0 or 1! Defaulting to 0\n");
1300 if(hflip
!= 0 && hflip
!= 1) {
1301 UDIA_WARNING("Horizontal flip should be 0 or 1! Defaulting to 0\n");
1305 if (sharpness
< 0 || sharpness
> 0x3f) {
1306 UDIA_WARNING("Sharpness should be 0 to 63 ! Defaulting to 31\n");
1310 if(auto_exposure
!= 0 && auto_exposure
!= 1) {
1311 UDIA_WARNING("Automatic exposure should be 0 or 1! "
1312 "Defaulting to 1\n");
1316 if(auto_whitebalance
!= 0 && auto_whitebalance
!= 1) {
1317 UDIA_WARNING("Automatic whitebalance should be 0 or 1! "
1318 "Defaulting to 1\n");
1319 auto_whitebalance
= 1;
1322 if (min_buffers
< 2) {
1323 UDIA_WARNING("Minimum buffers can't be less then 2! "
1324 "Defaulting to 2\n");
1329 if (min_buffers
> max_buffers
) {
1330 UDIA_WARNING("Minimum buffers must be less then or equal to "
1331 "max buffers! Defaulting to 2, 10\n");
1336 // Register the driver with the USB subsystem
1337 result
= usb_register(&usb_microdia_driver
);
1340 UDIA_ERROR("usb_register failed ! Error number %d\n", result
);
1342 UDIA_INFO(DRIVER_VERSION
" : " DRIVER_DESC
"\n");
1349 * @brief Close the driver
1351 * This function is called at last when you unload the driver.
1353 static void __exit
usb_microdia_exit(void)
1355 UDIA_INFO("usb_microdia_exit: Microdia USB2.0 webcam driver shutdown\n");
1358 debugfs_remove(debug_file
);
1360 debugfs_remove(debug_dir
);
1362 // Deregister this driver with the USB subsystem
1363 usb_deregister(&usb_microdia_driver
);
1367 module_init(usb_microdia_init
); /**< @brief Module initialize */
1368 module_exit(usb_microdia_exit
); /**< @brief Module exit */
1371 MODULE_PARM_DESC(fps
, "Frames per second [10-30]"); /**< @brief Description of 'fps' parameter */
1372 MODULE_PARM_DESC(hflip
, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1373 MODULE_PARM_DESC(vflip
, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1374 MODULE_PARM_DESC(flip_detect
, "Image flip detection"); /**< @brief Description of 'vflip_detect' parameter */
1375 MODULE_PARM_DESC(auto_exposure
, "Automatic exposure control"); /**< @brief Description of 'auto_exposure' parameter */
1376 MODULE_PARM_DESC(auto_whitebalance
, "Automatic whitebalance"); /**< @brief Description of 'auto_whitebalance' parameter */
1377 MODULE_PARM_DESC(brightness
, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1378 MODULE_PARM_DESC(whiteness
, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1379 MODULE_PARM_DESC(exposure
, "Exposure setting"); /**< @brief Description of 'exposure' parameter */
1380 MODULE_PARM_DESC(contrast
, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1381 MODULE_PARM_DESC(sharpness
, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */
1383 MODULE_PARM_DESC(min_buffers
, "Minimum number of image buffers");
1384 MODULE_PARM_DESC(max_buffers
, "Maximum number of image buffers");
1386 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1387 MODULE_AUTHOR(DRIVER_AUTHOR
); /**< @brief Driver is written by Nicolas VIVIEN */
1388 MODULE_DESCRIPTION(DRIVER_DESC
); /**< @brief Define the description of the driver */
1389 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT
); /**< @brief List of supported device */