Merge to kernel-2.6.20-1.2949.fc6.vs2.2.0.1
[linux-2.6.git] / drivers / media / video / usbvideo / vicam.c
similarity index 98%
rename from drivers/usb/media/vicam.c
rename to drivers/media/video/usbvideo/vicam.c
index 5df1440..08f9559 100644 (file)
@@ -7,6 +7,7 @@
  *                    Monroe Williams (monroe@pobox.com)
  *
  * Supports 3COM HomeConnect PC Digital WebCam
+ * Supports Compro PS39U WebCam
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,6 +43,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/mutex.h>
 #include "usbvideo.h"
 
 // #define VICAM_DEBUG
@@ -59,6 +61,8 @@
 /* Define these values to match your device */
 #define USB_VICAM_VENDOR_ID    0x04c1
 #define USB_VICAM_PRODUCT_ID   0x009d
+#define USB_COMPRO_VENDOR_ID   0x0602
+#define USB_COMPRO_PRODUCT_ID  0x1001
 
 #define VICAM_BYTES_PER_PIXEL   3
 #define VICAM_MAX_READ_SIZE     (512*242+128)
 #define VICAM_HEADER_SIZE       64
 
 #define clamp( x, l, h )        max_t( __typeof__( x ),         \
-                                       ( l ),                   \
-                                       min_t( __typeof__( x ),  \
-                                              ( h ),            \
-                                              ( x ) ) )
+                                      ( l ),                   \
+                                      min_t( __typeof__( x ),  \
+                                             ( h ),            \
+                                             ( x ) ) )
 
 /* Not sure what all the bytes in these char
  * arrays do, but they're necessary to make
@@ -356,7 +360,7 @@ static unsigned char setup5[] = {
  * Not sure why these are not yet non-statics which I can reference through
  * usbvideo.h the same as it is in 2.4.20.  I bet this will get fixed sometime
  * in the future.
- * 
+ *
 */
 static void *rvmalloc(unsigned long size)
 {
@@ -407,7 +411,7 @@ struct vicam_camera {
        struct usb_device *udev;        // usb device
 
        /* guard against simultaneous accesses to the camera */
-       struct semaphore cam_lock;
+       struct mutex cam_lock;
 
        int is_initialized;
        u8 open_count;
@@ -461,12 +465,12 @@ static int send_control_msg(struct vicam_camera *cam,
                            u16 size)
 {
        int status = -ENODEV;
-       down(&cam->cam_lock);
+       mutex_lock(&cam->cam_lock);
        if (cam->udev) {
                status = __send_control_msg(cam, request, value,
                                            index, cp, size);
        }
-       up(&cam->cam_lock);
+       mutex_unlock(&cam->cam_lock);
        return status;
 }
 static int
@@ -602,12 +606,12 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
        case VIDIOCSPICT:
                {
                        struct video_picture vp;
-                       
+
                        if (copy_from_user(&vp, user_arg, sizeof(vp))) {
                                retval = -EFAULT;
                                break;
                        }
-                       
+
                        DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
                            vp.palette);
 
@@ -654,7 +658,7 @@ vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsign
                        }
 
                        DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
-                       
+
                        if ( vw.width != 320 || vw.height != 240 )
                                retval = -EFAULT;
 
@@ -763,6 +767,7 @@ vicam_open(struct inode *inode, struct file *file)
        if (!cam) {
                printk(KERN_ERR
                       "vicam video_device improperly initialized");
+               return -EINVAL;
        }
 
        /* the videodev_lock held above us protects us from
@@ -807,12 +812,12 @@ vicam_open(struct inode *inode, struct file *file)
        cam->needsDummyRead = 1;
        cam->open_count++;
 
-       file->private_data = cam;       
-       
+       file->private_data = cam;
+
        return 0;
 }
 
-static int 
+static int
 vicam_close(struct inode *inode, struct file *file)
 {
        struct vicam_camera *cam = file->private_data;
@@ -831,13 +836,13 @@ vicam_close(struct inode *inode, struct file *file)
        rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
        kfree(cam->cntrlbuf);
 
-       down(&cam->cam_lock);
+       mutex_lock(&cam->cam_lock);
 
        cam->open_count--;
        open_count = cam->open_count;
        udev = cam->udev;
 
-       up(&cam->cam_lock);
+       mutex_unlock(&cam->cam_lock);
 
        if (!open_count && !udev) {
                kfree(cam);
@@ -960,7 +965,7 @@ read_frame(struct vicam_camera *cam, int framenum)
        request[8] = 0;
        // bytes 9-15 do not seem to affect exposure or image quality
 
-       down(&cam->cam_lock);
+       mutex_lock(&cam->cam_lock);
 
        if (!cam->udev) {
                goto done;
@@ -985,7 +990,7 @@ read_frame(struct vicam_camera *cam, int framenum)
        }
 
  done:
-       up(&cam->cam_lock);
+       mutex_unlock(&cam->cam_lock);
 }
 
 static ssize_t
@@ -1185,7 +1190,7 @@ vicam_create_proc_entry(struct vicam_camera *cam)
 
        if ( !cam->proc_dir )
                return; // FIXME: We should probably return an error here
-       
+
        ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
                                cam->proc_dir);
        if (ent) {
@@ -1252,6 +1257,7 @@ static struct video_device vicam_template = {
 /* table of devices that work with this driver */
 static struct usb_device_id vicam_table[] = {
        {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
+       {USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)},
        {}                      /* Terminating entry */
 };
 
@@ -1280,7 +1286,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
        const struct usb_host_interface *interface;
        const struct usb_endpoint_descriptor *endpoint;
        struct vicam_camera *cam;
-       
+
        printk(KERN_INFO "ViCam based webcam connected\n");
 
        interface = intf->cur_altsetting;
@@ -1309,7 +1315,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
 
        cam->shutter_speed = 15;
 
-       init_MUTEX(&cam->cam_lock);
+       mutex_init(&cam->cam_lock);
 
        memcpy(&cam->vdev, &vicam_template,
               sizeof (vicam_template));
@@ -1329,7 +1335,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
        printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor);
 
        usb_set_intfdata (intf, cam);
-       
+
        return 0;
 }
 
@@ -1351,7 +1357,7 @@ vicam_disconnect(struct usb_interface *intf)
 
        /* stop the camera from being used */
 
-       down(&cam->cam_lock);
+       mutex_lock(&cam->cam_lock);
 
        /* mark the camera as gone */
 
@@ -1368,7 +1374,7 @@ vicam_disconnect(struct usb_interface *intf)
 
        open_count = cam->open_count;
 
-       up(&cam->cam_lock);
+       mutex_unlock(&cam->cam_lock);
 
        if (!open_count) {
                kfree(cam);