3 * @author Nicolas VIVIEN
6 * @brief Driver for Microdia USB video camera
8 * @note Copyright (C) Nicolas VIVIEN
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/version.h>
31 #include <linux/errno.h>
32 #include <linux/slab.h>
33 #include <linux/kref.h>
34 #include <linux/stat.h>
36 #include <linux/usb.h>
37 #include <media/v4l2-common.h>
47 * Module parameter to set frame per second
53 * Module parameter to enable/disable bulk transfers
59 * Module parameter to enable/disable the horizontal flip process
65 * Module parameter to enable/disable vflip detection
67 static int flip_detect
;
71 * Module parameter to enable/disable the vertical flip process
77 * Module parameter to set the brightness
79 static int brightness
= MICRODIA_PERCENT(50, 0xFFFF);
83 * Module parameter to set the whiteness
85 static int whiteness
= MICRODIA_PERCENT(20, 0xFFFF);
89 * Module parameter to set the contrast
91 static int contrast
= MICRODIA_PERCENT(50, 0xFFFF);
95 * Module parameter to set the exposure
97 /* static int exposure = MICRODIA_PERCENT(20, 0xFFFF); */
98 static int exposure
= MICRODIA_PERCENT(2, 0xFFFF);
102 * Module parameter to set the sharpness
104 static int sharpness
= MICRODIA_PERCENT(50, 0x3F);
108 * Module parameter to set the red/green/blue gain
110 static int rgb_gain
= MICRODIA_PERCENT(25, 0x7F) |
111 (MICRODIA_PERCENT(25, 0x7F) << 8) |
112 (MICRODIA_PERCENT(25, 0x7F) << 16);
116 * Module parameter to set the minimum number of image buffers
118 static int min_buffers
= 2;
122 * Module parameter to set the maximum number of image buffers
124 static int max_buffers
= 5;
128 * Module parameter to set the exposure
130 static int auto_exposure
= 1;
133 * @var auto_whitebalance
134 * Module parameter to set the exposure
136 static int auto_whitebalance
= 1;
140 * Module parameter to set the log level
146 * @var microdia_table
147 * Define all the hotplug supported devices by this driver
149 static struct usb_device_id microdia_table
[] = {
150 /* SN9C201 + MI1300 */
151 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6240_PID
, SN9C20X_BRIDGE
)},
152 /* SN9C201 + MI1310 */
153 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6242_PID
, SN9C20X_BRIDGE
)},
154 /* SN9C201 + S5K4AAFX */
155 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6243_PID
, SN9C20X_BRIDGE
)},
156 /* SN9C201 + OV9655 */
157 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6248_PID
, SN9C20X_BRIDGE
)},
158 /* SN9C201 + CX1332 */
159 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_624B_PID
, SN9C20X_BRIDGE
)},
160 /* SN9C201 + MI1320 */
161 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_624C_PID
, SN9C20X_BRIDGE
)},
162 /* SN9C201 + SOI968 */
163 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_624E_PID
, SN9C20X_BRIDGE
)},
164 /* SN9C201 + OV9650 */
165 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_624F_PID
, SN9C20X_BRIDGE
)},
166 /* SN9C201 + OV9650 */
167 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6253_PID
, SN9C20X_BRIDGE
)},
168 /* SN9C201 + OV7670ISP */
169 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6260_PID
, SN9C20X_BRIDGE
)},
170 /* SN9C201 + OM6802 */
171 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6262_PID
, SN9C20X_BRIDGE
)},
172 /* SN9C201 + MI0360/MT9V111 */
173 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6270_PID
, SN9C20X_BRIDGE
)},
174 /* SN9C201 + S5K53BEB */
175 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_627A_PID
, SN9C20X_BRIDGE
)},
176 /* SN9C201 + OV7660 */
177 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_627B_PID
, SN9C20X_BRIDGE
)},
178 /* SN9C201 + HV7131R */
179 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_627C_PID
, SN9C20X_BRIDGE
)},
181 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_627F_PID
, SN9C20X_BRIDGE
)},
182 /* SN9C202 + MI1300 */
183 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6280_PID
, SN9C20X_BRIDGE
)},
184 /* SN9C202 + MI1310 */
185 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6282_PID
, SN9C20X_BRIDGE
)},
186 /* SN9C202 + S5K4AAFX */
187 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6283_PID
, SN9C20X_BRIDGE
)},
188 /* SN9C202 + OV9655 */
189 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_6288_PID
, SN9C20X_BRIDGE
)},
190 /* SN9C202 + ICM107 */
191 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_628A_PID
, SN9C20X_BRIDGE
)},
192 /* SN9C202 + CX1332 */
193 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_628B_PID
, SN9C20X_BRIDGE
)},
194 /* SN9C202 + MI1320 */
195 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_628C_PID
, SN9C20X_BRIDGE
)},
196 /* SN9C202 + SOI968 */
197 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_628E_PID
, SN9C20X_BRIDGE
)},
198 /* SN9C202 + OV9650 */
199 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_628F_PID
, SN9C20X_BRIDGE
)},
200 /* SN9C202 + OV7670ISP */
201 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62A0_PID
, SN9C20X_BRIDGE
)},
202 /* SN9C202 + OM6802 */
203 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62A2_PID
, SN9C20X_BRIDGE
)},
204 /* SN9C202 + MI0360/MT9V111 */
205 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62B0_PID
, SN9C20X_BRIDGE
)},
206 /* SN9C202 + OV9655 */
207 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62B3_PID
, SN9C20X_BRIDGE
)},
208 /* SN9C202 + S5K53BEB */
209 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62BA_PID
, SN9C20X_BRIDGE
)},
210 /* SN9C202 + OV7660 */
211 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62BB_PID
, SN9C20X_BRIDGE
)},
212 /* SN9C202 + HV7131R */
213 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62BC_PID
, SN9C20X_BRIDGE
)},
214 /* SN9C202 + OV7663 */
215 {MICRODIA_USB_DEVICE(USB_0C45_VID
, USB_62BE_PID
, SN9C20X_BRIDGE
)},
216 /* => 628f (SN9C202 + OV9650) */
217 {MICRODIA_USB_DEVICE(USB_045E_VID
, USB_00F4_PID
, SN9C20X_BRIDGE
)},
218 /* => 627b (SN9C201 + OV7660) */
219 {MICRODIA_USB_DEVICE(USB_145F_VID
, USB_013D_PID
, SN9C20X_BRIDGE
)},
220 /* => 62be (SN9C202 + OV7663 + EEPROM) */
221 {MICRODIA_USB_DEVICE(USB_04F2_VID
, USB_A128_PID
, SN9C20X_BRIDGE
)},
226 MODULE_DEVICE_TABLE(usb
, microdia_table
); /**< Define the supported devices */
228 DEFINE_MUTEX(open_lock
); /**< Define global mutex */
230 struct usb_endpoint_descriptor
*find_endpoint(struct usb_host_interface
*alts
,
234 struct usb_endpoint_descriptor
*ep
;
236 for (i
= 0; i
< alts
->desc
.bNumEndpoints
; ++i
) {
237 ep
= &alts
->endpoint
[i
].desc
;
238 if ((ep
->bEndpointAddress
& 0xf) == epaddr
) {
239 UDIA_INFO("Found Endpoint 0x%X\n", epaddr
);
247 * @param dev Device structure
248 * @param ep Usb endpoint structure
250 * @returns 0 if all is OK
252 * @brief Initilize an isochronous pipe.
254 * This function permits to initialize an URB transfert (or isochronous pipe).
256 int usb_microdia_isoc_init(struct usb_microdia
*dev
,
257 struct usb_endpoint_descriptor
*ep
)
260 __u16 iso_max_frame_size
;
262 struct usb_device
*udev
;
266 UDIA_DEBUG("usb_microdia_isoc_init()\n");
269 max_packet_sz(le16_to_cpu(le16_to_cpu(ep
->wMaxPacketSize
))) *
270 hb_multiplier(le16_to_cpu(le16_to_cpu(ep
->wMaxPacketSize
)));
272 for (i
= 0; i
< MAX_URBS
; i
++) {
273 urb
= usb_alloc_urb(ISO_FRAMES_PER_DESC
, GFP_KERNEL
);
276 UDIA_ERROR("Failed to allocate URB %d\n", i
);
277 usb_microdia_uninit_urbs(dev
);
283 urb
->pipe
= usb_rcvisocpipe(udev
, ep
->bEndpointAddress
);
284 urb
->transfer_flags
= URB_ISO_ASAP
;
285 urb
->transfer_buffer_length
= iso_max_frame_size
* ISO_FRAMES_PER_DESC
;
286 urb
->complete
= usb_microdia_completion_handler
;
288 urb
->start_frame
= 0;
289 urb
->number_of_packets
= ISO_FRAMES_PER_DESC
;
291 for (j
= 0; j
< ISO_FRAMES_PER_DESC
; j
++) {
292 urb
->iso_frame_desc
[j
].offset
= j
* iso_max_frame_size
;
293 urb
->iso_frame_desc
[j
].length
= iso_max_frame_size
;
296 dev
->urbs
[i
].data
= kzalloc(urb
->transfer_buffer_length
,
298 if (dev
->urbs
[i
].data
== NULL
) {
299 usb_microdia_uninit_urbs(dev
);
303 urb
->transfer_buffer
= dev
->urbs
[i
].data
;
304 dev
->urbs
[i
].urb
= urb
;
310 int usb_microdia_bulk_init(struct usb_microdia
*dev
,
311 struct usb_endpoint_descriptor
*ep
)
314 unsigned int pipe
, i
;
317 psize
= max_packet_sz(le16_to_cpu(le16_to_cpu(ep
->wMaxPacketSize
)));
318 size
= psize
* ISO_FRAMES_PER_DESC
;
319 pipe
= usb_rcvbulkpipe(dev
->udev
, ep
->bEndpointAddress
);
321 for (i
= 0; i
< MAX_URBS
; ++i
) {
322 urb
= usb_alloc_urb(0, GFP_KERNEL
);
324 usb_microdia_uninit_urbs(dev
);
328 dev
->urbs
[i
].data
= kzalloc(size
, GFP_KERNEL
);
330 usb_fill_bulk_urb(urb
, dev
->udev
, pipe
,
331 dev
->urbs
[i
].data
, size
,
332 usb_microdia_completion_handler
,
335 dev
->urbs
[i
].urb
= urb
;
341 int usb_microdia_init_urbs(struct usb_microdia
*dev
)
345 struct usb_endpoint_descriptor
*ep
;
346 struct usb_interface
*intf
= dev
->interface
;
348 ret
= usb_microdia_control_read(dev
, 0x1061, &value
, 1);
353 ep
= find_endpoint(usb_altnum_to_altsetting(intf
, 8), MICRODIA_VID_ISOC
);
358 ret
= usb_set_interface(dev
->udev
, 0, 8);
363 ret
= usb_microdia_control_write(dev
, 0x1061, &value
, 1);
367 ret
= usb_microdia_isoc_init(dev
, ep
);
369 ep
= find_endpoint(usb_altnum_to_altsetting(intf
, 0), MICRODIA_BULK
);
373 ret
= usb_set_interface(dev
->udev
, 0, 0);
378 ret
= usb_microdia_control_write(dev
, 0x1061, &value
, 1);
382 ret
= usb_microdia_bulk_init(dev
, ep
);
388 for (i
= 0; i
< MAX_URBS
; i
++) {
389 ret
= usb_submit_urb(dev
->urbs
[i
].urb
, GFP_KERNEL
);
391 UDIA_ERROR("isoc_init() submit_urb %d failed with error %d\n", i
, ret
);
398 * @param dev Device structure
400 * @brief Clean-up all the ISOC buffers
402 * This function permits to clean-up all the ISOC buffers.
404 void usb_microdia_uninit_urbs(struct usb_microdia
*dev
)
409 UDIA_DEBUG("Isoc cleanup\n");
414 for (i
= 0; i
< MAX_URBS
; i
++) {
415 urb
= dev
->urbs
[i
].urb
;
419 kfree(dev
->urbs
[i
].data
);
421 dev
->urbs
[i
].urb
= NULL
;
425 void usb_microdia_assemble_video(struct usb_microdia
*dev
,
426 unsigned char *transfer
, unsigned int transfer_length
,
427 struct microdia_buffer
*buf
)
430 unsigned char frame_header
[] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
431 struct microdia_video_queue
*queue
= &dev
->queue
;
433 if (memcmp(transfer
, frame_header
, 6) == 0 && transfer_length
== 64) {
434 UDIA_INFO("Frame Resolution: %dx%d\n",
435 transfer
[0x3a] << 4, transfer
[0x3b] << 3);
436 UDIA_INFO("Frame Size: %d\n", buf
->buf
.bytesused
);
437 if (buf
->buf
.bytesused
!= 0)
438 buf
->state
= MICRODIA_BUF_STATE_DONE
;
440 if (buf
->state
!= MICRODIA_BUF_STATE_ACTIVE
)
441 buf
->state
= MICRODIA_BUF_STATE_ACTIVE
;
443 if (transfer_length
+ buf
->buf
.bytesused
> buf
->buf
.length
) {
444 UDIA_WARNING("Frame Buffer overflow!\n");
445 dev
->vframes_overflow
++;
446 buf
->state
= MICRODIA_BUF_STATE_DONE
;
448 transfer_length
= min(buf
->buf
.length
- buf
->buf
.bytesused
,
450 mem
= queue
->mem
+ buf
->buf
.m
.offset
+ buf
->buf
.bytesused
;
451 memcpy(mem
, transfer
, transfer_length
);
452 buf
->buf
.bytesused
+= transfer_length
;
456 * @param urb URB structure
458 * @brief ISOC handler
460 * This function is called as an URB transfert is complete (Isochronous pipe).
461 * So, the traitement is done in interrupt time, so it has be fast, not crash,
462 * and not stall. Neat.
464 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
465 void usb_microdia_completion_handler(struct urb
*urb
, struct pt_regs
*regs
)
467 void usb_microdia_completion_handler(struct urb
*urb
)
474 unsigned char *transfer
= NULL
;
475 unsigned int transfer_length
;
477 struct microdia_buffer
*buf
= NULL
;
478 struct usb_microdia
*dev
= urb
->context
;
479 struct microdia_video_queue
*queue
= &dev
->queue
;
481 UDIA_STREAM("Isoc handler\n");
483 switch (urb
->status
) {
488 UDIA_WARNING("Non-zero status (%d) in video "
489 "completion handler.\n", urb
->status
);
491 case -ENOENT
: /* usb_kill_urb() called. */
495 case -ECONNRESET
: /* usb_unlink_urb() called. */
496 case -ESHUTDOWN
: /* The endpoint is being disabled. */
497 microdia_queue_cancel(queue
, urb
->status
== -ESHUTDOWN
);
501 spin_lock_irqsave(&queue
->irqlock
, flags
);
502 if (!list_empty(&queue
->irqqueue
))
503 buf
= list_first_entry(&queue
->irqqueue
, struct microdia_buffer
,
505 spin_unlock_irqrestore(&queue
->irqlock
, flags
);
507 for (i
= 0; i
< urb
->number_of_packets
; i
++) {
508 if (urb
->iso_frame_desc
[i
].status
!= 0) {
509 UDIA_ERROR("Iso frame %d of USB has error %d\n",
510 i
, urb
->iso_frame_desc
[i
].status
);
513 transfer_length
= urb
->iso_frame_desc
[i
].actual_length
;
514 transfer
= urb
->transfer_buffer
+ urb
->iso_frame_desc
[i
].offset
;
518 usb_microdia_assemble_video(dev
, transfer
, transfer_length
, buf
);
519 if (buf
->state
== MICRODIA_BUF_STATE_DONE
||
520 buf
->state
== MICRODIA_BUF_STATE_ERROR
) {
521 buf
= microdia_queue_next_buffer(queue
, buf
);
523 dev
->vframes_dropped
++;
528 usb_microdia_assemble_video(dev
, urb
->transfer_buffer
,
529 urb
->actual_length
, buf
);
530 if (buf
->state
== MICRODIA_BUF_STATE_DONE
||
531 buf
->state
== MICRODIA_BUF_STATE_ERROR
) {
532 buf
= microdia_queue_next_buffer(queue
, buf
);
534 dev
->vframes_dropped
++;
538 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
541 UDIA_INFO("Error (%d) re-submitting urb in "
542 "microdia_isoc_handler.\n", ret
);
547 * @param dev Device structure
548 * @param index Choice of the interface
550 * @returns 0 if all is OK
552 * @brief Send the message SET_FEATURE and choose the interface
554 * This function permits to send the message SET_FEATURE on the USB bus.
556 int usb_microdia_set_feature(struct usb_microdia
*dev
, int index
)
559 struct usb_device
*udev
= dev
->udev
;
561 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
563 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
564 USB_DEVICE_REMOTE_WAKEUP
,
571 UDIA_ERROR("SET FEATURE fail !\n");
573 UDIA_DEBUG("SET FEATURE\n");
580 * @param dev Device structure
582 * @returns 0 if all is OK
584 * @brief Send the message SET_CONFIGURATION
586 * This function permits to send the message SET_CONFIGURATION on the USB bus.
588 int usb_microdia_set_configuration(struct usb_microdia
*dev
)
591 struct usb_device
*udev
= dev
->udev
;
593 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
594 USB_REQ_SET_CONFIGURATION
,
595 USB_TYPE_STANDARD
| USB_DIR_OUT
| USB_RECIP_DEVICE
,
597 udev
->config
[0].desc
.bConfigurationValue
,
603 UDIA_ERROR("SET CONFIGURATION fail !\n");
605 UDIA_DEBUG("SET CONFIGURATION %d\n", udev
->config
[0].desc
.bConfigurationValue
);
612 * @param dev Device structure
613 * @param value register to write to
615 * @param length number of bytes
617 * @returns 0 if all is OK
619 * @brief Write a 16-bit value to a 16-bit register
621 * This function permits to write a 16-bit value to a 16-bit register on the USB bus.
623 int usb_microdia_control_write(struct usb_microdia
*dev
, __u16 value
, __u8
*data
, __u16 length
)
626 struct usb_device
*udev
= dev
->udev
;
628 result
= usb_control_msg(udev
, usb_sndctrlpipe(udev
, 0),
630 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
638 UDIA_ERROR("Write register failed index = 0x%02X\n", value
);
644 * @param dev Device structure
645 * @param index register to read from
647 * @param length number of bytes
649 * @returns 0 if all is OK
651 * @brief Read a 16-bit value from a 16-bit register
653 * This function permits to read a 16-bit value from a 16-bit register on the USB bus.
655 int usb_microdia_control_read(struct usb_microdia
*dev
, __u16 index
, __u8
*data
, __u16 length
)
659 struct usb_device
*udev
= dev
->udev
;
663 result
= usb_control_msg(udev
, usb_rcvctrlpipe(udev
, 0),
665 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
673 UDIA_ERROR("Read register failed 0x%02X\n", index
);
682 * @returns 0 if all is OK
684 * @brief Set the default value about the video settings.
686 * This function permits to set the video settings for each video camera model.
689 static int usb_microdia_default_settings(struct usb_microdia
*dev
)
691 dev
->vframes_overflow
= 0;
692 dev
->vframes_incomplete
= 0;
693 dev
->vframes_dropped
= 0;
695 dev
->queue
.min_buffers
= min_buffers
;
696 dev
->queue
.max_buffers
= max_buffers
;
698 dev
->vsettings
.fps
= fps
;
699 dev
->vsettings
.vflip
= vflip
;
700 dev
->vsettings
.hflip
= hflip
;
701 dev
->vsettings
.brightness
= brightness
& 0xffff;
702 dev
->vsettings
.contrast
= contrast
& 0xffff;
703 dev
->vsettings
.whiteness
= whiteness
& 0xffff;
704 dev
->vsettings
.exposure
= exposure
& 0xffff;
705 dev
->vsettings
.sharpness
= sharpness
& 0x3f;
706 dev
->vsettings
.rgb_gain
[0] = (rgb_gain
>> 16) & 0x7f;
707 dev
->vsettings
.rgb_gain
[1] = (rgb_gain
>> 8) & 0x7f;
708 dev
->vsettings
.rgb_gain
[2] = (rgb_gain
>> 8) & 0x7f;
709 dev
->vsettings
.rgb_gain
[3] = rgb_gain
& 0x7f;
710 dev
->vsettings
.auto_exposure
= auto_exposure
& 1;
711 dev
->vsettings
.auto_whitebalance
= auto_whitebalance
& 1;
712 dev
->vsettings
.hue
= 0xffff;
714 dev
->vsettings
.format
.width
= 640;
715 dev
->vsettings
.format
.height
= 480;
716 dev
->vsettings
.format
.bytesperline
= 640 *
717 dev
->camera
.fmts
[0].bpp
;
718 dev
->vsettings
.format
.sizeimage
= 480 *
719 dev
->vsettings
.format
.bytesperline
;
720 dev
->vsettings
.format
.pixelformat
= dev
->camera
.fmts
[0].pix_fmt
;
721 dev
->vsettings
.format
.colorspace
= V4L2_COLORSPACE_SRGB
;
722 dev
->vsettings
.format
.priv
= 0;
723 sn9c20x_set_resolution(dev
, 640, 480);
729 * @brief Load the driver
734 * @returns 0 if all is OK
736 * This function detects the device and allocate the buffers for the device
737 * and the video interface.
739 static int usb_microdia_probe(struct usb_interface
*interface
, const struct usb_device_id
*id
)
747 struct usb_microdia
*dev
= NULL
;
748 struct usb_device
*udev
= interface_to_usbdev(interface
);
750 /* Get USB VendorID and ProductID */
751 vendor_id
= le16_to_cpu(udev
->descriptor
.idVendor
);
752 product_id
= le16_to_cpu(udev
->descriptor
.idProduct
);
754 /* Check if we can handle this device */
755 UDIA_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
756 vendor_id
, product_id
, interface
->cur_altsetting
->desc
.bInterfaceNumber
);
758 UDIA_INFO("Microdia USB 2.0 Webcam - %04X:%04X plugged-in.\n",
759 vendor_id
, product_id
);
763 // Allocate structure, initialize pointers, mutexes, etc.
764 // and link it to the usb_device
766 dev
= kzalloc(sizeof(struct usb_microdia
), GFP_KERNEL
);
769 UDIA_ERROR("Out of memory !\n");
774 /* Init mutexes, spinlock, etc. */
775 mutex_init(&dev
->mutex
);
776 kref_init(&dev
->vopen
);
779 dev
->interface
= interface
;
781 /* Read the product release */
782 dev
->release
= le16_to_cpu(udev
->descriptor
.bcdDevice
);
783 UDIA_DEBUG("Release: %04x\n", dev
->release
);
785 /* How many interfaces (1 or 3) ? */
786 bNumInterfaces
= udev
->config
->desc
.bNumInterfaces
;
787 UDIA_DEBUG("Number of interfaces : %d\n", bNumInterfaces
);
789 /* Initialize the camera */
790 ret
= dev_microdia_initialize_device(dev
, id
->driver_info
);
794 /* Initialize the video device */
795 dev
->vdev
= video_device_alloc();
802 /* Register the video device */
803 ret
= v4l_microdia_register_video_device(dev
);
808 /* Create the entries in the sys filesystem */
809 microdia_create_sysfs_files(dev
->vdev
);
811 #ifdef CONFIG_MICRODIA_DEBUGFS
812 microdia_create_debugfs_files(dev
);
815 /* Save our data pointer in this interface device */
816 usb_set_intfdata(interface
, dev
);
818 usb_microdia_default_settings(dev
);
823 kref_put(&dev
->vopen
, usb_microdia_delete
);
828 void usb_microdia_delete(struct kref
*kref
)
830 struct usb_microdia
*dev
;
831 dev
= container_of(kref
, struct usb_microdia
, vopen
);
833 if (dev
->vdev
!= NULL
) {
834 microdia_remove_sysfs_files(dev
->vdev
);
835 #ifdef CONFIG_MICRODIA_DEBUGFS
836 microdia_remove_debugfs_files(dev
);
838 v4l_microdia_unregister_video_device(dev
);
846 * @brief This function is called when the device is disconnected
847 * or when the kernel module is unloaded.
849 static void usb_microdia_disconnect(struct usb_interface
*interface
)
851 struct usb_microdia
*dev
= usb_get_intfdata(interface
);
853 UDIA_INFO("Microdia USB 2.0 Webcam unplugged\n");
855 usb_set_intfdata(interface
, NULL
);
857 mutex_lock(&open_lock
);
858 kref_put(&dev
->vopen
, usb_microdia_delete
);
859 mutex_unlock(&open_lock
);
864 * @var usb_microdia_driver
866 * This variable contains some callback
868 static struct usb_driver usb_microdia_driver
= {
869 .name
= "usb_microdia_driver",
870 .probe
= usb_microdia_probe
,
871 .disconnect
= usb_microdia_disconnect
,
872 .id_table
= microdia_table
,
875 module_param(fps
, int, 0444); /**< @brief Module parameter frames per second */
876 module_param(bulk
, int, 0444);
877 module_param(hflip
, int, 0444); /**< @brief Module parameter horizontal flip process */
878 module_param(vflip
, int, 0444); /**< @brief Module parameter vertical flip process */
879 module_param(flip_detect
, int, 0444); /**< @brief Module parameter flip detect */
880 module_param(auto_exposure
, int, 0444); /**< @brief Module parameter automatic exposure control */
881 module_param(auto_whitebalance
, int, 0444); /**< @brief Module parameter automatic whitebalance control */
882 module_param(brightness
, int, 0444); /**< @brief Module parameter brightness */
883 module_param(whiteness
, int, 0444); /**< @brief Module parameter whiteness */
884 module_param(contrast
, int, 0444); /**< @brief Module parameter contrast */
885 module_param(exposure
, int, 0444); /**< @brief Module parameter exposure */
886 module_param(sharpness
, int, 0444); /**< @brief Module parameter sharpness */
887 module_param(rgb_gain
, int, 0444); /**< @brief Module parameter red/green/blue gain */
889 module_param(min_buffers
, int, 0444);
890 module_param(max_buffers
, int, 0444);
892 module_param(log_level
, byte
, 0444);
895 * @returns 0 if all is OK
897 * @brief Initialize the driver.
899 * This function is called at first.
900 * This function permits to define the default values from the command line.
902 static int __init
usb_microdia_init(void)
906 UDIA_INFO("Microdia USB 2.0 webcam driver loaded\n");
908 #ifdef CONFIG_MICRODIA_DEBUGFS
909 microdia_init_debugfs();
912 if (fps
< 10 || fps
> 30) {
913 UDIA_WARNING("Framerate out of bounds [10-30]! Defaulting to 25\n");
917 if (bulk
!= 0 && bulk
!= 1) {
918 UDIA_WARNING("Bulk transfer should be 0 or 1! Defaulting to 0\n");
922 if (vflip
!= 0 && vflip
!= 1) {
923 UDIA_WARNING("Vertical flip should be 0 or 1! Defaulting to 0\n");
927 if (hflip
!= 0 && hflip
!= 1) {
928 UDIA_WARNING("Horizontal flip should be 0 or 1! Defaulting to 0\n");
932 if (sharpness
< 0 || sharpness
> 0x3f) {
933 UDIA_WARNING("Sharpness should be 0 to 63 ! Defaulting to 31\n");
937 if ((rgb_gain
>> 16) < 0 || (rgb_gain
>> 16) > 0x7f) {
938 UDIA_WARNING("Red Gain should be 0 to 127 ! Defaulting to 32\n");
939 rgb_gain
= (rgb_gain
& 0x0000ffff) | 0x200000;
942 if (((rgb_gain
>> 8) & 0xFF) < 0 || ((rgb_gain
>> 8) & 0xFF) > 0x7f) {
943 UDIA_WARNING("Green Gain should be 0 to 127 ! Defaulting to 32\n");
944 rgb_gain
= (rgb_gain
& 0x00ff00ff) | 0x002000;
947 if ((rgb_gain
& 0xFF) < 0 || (rgb_gain
& 0xFF) > 0x7f) {
948 UDIA_WARNING("Blue Gain should be 0 to 127 ! Defaulting to 32\n");
949 rgb_gain
= (rgb_gain
& 0x00ffff00) | 0x20;
952 if (auto_exposure
!= 0 && auto_exposure
!= 1) {
953 UDIA_WARNING("Automatic exposure should be 0 or 1! "
954 "Defaulting to 1\n");
958 if (auto_whitebalance
!= 0 && auto_whitebalance
!= 1) {
959 UDIA_WARNING("Automatic whitebalance should be 0 or 1! "
960 "Defaulting to 1\n");
961 auto_whitebalance
= 1;
964 if (min_buffers
< 2) {
965 UDIA_WARNING("Minimum buffers can't be less then 2! "
966 "Defaulting to 2\n");
971 if (min_buffers
> max_buffers
) {
972 UDIA_WARNING("Minimum buffers must be less then or equal to "
973 "max buffers! Defaulting to 2, 10\n");
978 /* Register the driver with the USB subsystem */
979 result
= usb_register(&usb_microdia_driver
);
982 UDIA_ERROR("usb_register failed ! Error number %d\n", result
);
984 UDIA_INFO(DRIVER_VERSION
" : " DRIVER_DESC
"\n");
991 * @brief Close the driver
993 * This function is called at last when you unload the driver.
995 static void __exit
usb_microdia_exit(void)
997 UDIA_INFO("usb_microdia_exit: Microdia USB 2.0 webcam driver unloaded\n");
999 #ifdef CONFIG_MICRODIA_DEBUGFS
1000 microdia_uninit_debugfs();
1003 /* Deregister this driver with the USB subsystem */
1004 usb_deregister(&usb_microdia_driver
);
1008 module_init(usb_microdia_init
); /**< @brief Module initialize */
1009 module_exit(usb_microdia_exit
); /**< @brief Module exit */
1012 MODULE_PARM_DESC(fps
, "Frames per second [10-30]"); /**< @brief Description of 'fps' parameter */
1013 MODULE_PARM_DESC(bulk
, "Enable Bulk transfer (default is to use ISOC)");
1014 MODULE_PARM_DESC(hflip
, "Horizontal image flip"); /**< @brief Description of 'hflip' parameter */
1015 MODULE_PARM_DESC(vflip
, "Vertical image flip"); /**< @brief Description of 'vflip' parameter */
1016 MODULE_PARM_DESC(flip_detect
, "Image flip detection"); /**< @brief Description of 'vflip_detect' parameter */
1017 MODULE_PARM_DESC(auto_exposure
, "Automatic exposure control"); /**< @brief Description of 'auto_exposure' parameter */
1018 MODULE_PARM_DESC(auto_whitebalance
, "Automatic whitebalance"); /**< @brief Description of 'auto_whitebalance' parameter */
1019 MODULE_PARM_DESC(brightness
, "Brightness setting"); /**< @brief Description of 'brightness' parameter */
1020 MODULE_PARM_DESC(whiteness
, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */
1021 MODULE_PARM_DESC(exposure
, "Exposure setting"); /**< @brief Description of 'exposure' parameter */
1022 MODULE_PARM_DESC(contrast
, "Contrast setting"); /**< @brief Description of 'contrast' parameter */
1023 MODULE_PARM_DESC(sharpness
, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */
1024 MODULE_PARM_DESC(rgb_gain
, "Red/Green/Blue Gain setting"); /**< @brief Description of 'RGB Gain' parameter */
1026 MODULE_PARM_DESC(min_buffers
, "Minimum number of image buffers");
1027 MODULE_PARM_DESC(max_buffers
, "Maximum number of image buffers");
1028 MODULE_PARM_DESC(log_level
, " <n>\n"
1029 "Driver log level\n"
1030 "1 = info (default)\n"
1036 MODULE_LICENSE("GPL"); /**< @brief Driver is under licence GPL */
1037 MODULE_AUTHOR(DRIVER_AUTHOR
); /**< @brief Driver is written by Nicolas VIVIEN */
1038 MODULE_DESCRIPTION(DRIVER_DESC
); /**< @brief Define the description of the driver */
1039 MODULE_SUPPORTED_DEVICE(DRIVER_SUPPORT
); /**< @brief List of supported device */