V4L/DVB (12231): gspca - main: Version change.
[safe/jmp/linux-2.6] / drivers / media / video / arv.c
index 0823dda..d137bac 100644 (file)
  * 2003-09-01: Support w3cam by Takeo Takahashi
  */
 
-#include <linux/config.h>
 #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/mutex.h>
 
-#include <asm/semaphore.h>
 #include <asm/uaccess.h>
 #include <asm/m32r.h>
 #include <asm/io.h>
@@ -118,7 +116,8 @@ struct ar_device {
        int width, height;
        int frame_bytes, line_bytes;
        wait_queue_head_t wait;
-       struct semaphore lock;
+       unsigned long in_use;
+       struct mutex lock;
 };
 
 static int video_nr = -1;      /* video device number (first free) */
@@ -128,11 +127,11 @@ static unsigned char      yuv[MAX_AR_FRAME_BYTES];
 /* default frequency */
 #define DEFAULT_FREQ   50      /* 50 or 75 (MHz) is available as BCLK */
 static int freq = DEFAULT_FREQ;        /* BCLK: available 50 or 70 (MHz) */
-static int vga = 0;            /* default mode(0:QVGA mode, other:VGA mode) */
-static int vga_interlace = 0;  /* 0 is normal mode for, else interlace mode */
-MODULE_PARM(freq, "i");
-MODULE_PARM(vga, "i");
-MODULE_PARM(vga_interlace, "i");
+static int vga;                        /* default mode(0:QVGA mode, other:VGA mode) */
+static int vga_interlace;      /* 0 is normal mode for, else interlace mode */
+module_param(freq, int, 0);
+module_param(vga, int, 0);
+module_param(vga_interlace, int, 0);
 
 static int ar_initialize(struct video_device *dev);
 
@@ -162,39 +161,39 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
 {
        int i;
 
-       /* Slave Address */
-       ar_outl(addr, PLDI2CDATA);
+       /* Slave Address */
+       ar_outl(addr, PLDI2CDATA);
        wait_for_vsync();
 
-       /* Start */
-       ar_outl(1, PLDI2CCND);
+       /* Start */
+       ar_outl(1, PLDI2CCND);
        wait_acknowledge();
 
        /* Transfer data 1 */
-       ar_outl(data1, PLDI2CDATA);
+       ar_outl(data1, PLDI2CDATA);
        wait_for_vsync();
-       ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
+       ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
        wait_acknowledge();
 
        /* Transfer data 2 */
-       ar_outl(data2, PLDI2CDATA);
+       ar_outl(data2, PLDI2CDATA);
        wait_for_vsync();
-       ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
+       ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
        wait_acknowledge();
 
        if (n == 3) {
                /* Transfer data 3 */
-               ar_outl(data3, PLDI2CDATA);
+               ar_outl(data3, PLDI2CDATA);
                wait_for_vsync();
-               ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
+               ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
                wait_acknowledge();
-       }
+       }
 
-       /* Stop */
+       /* Stop */
        for (i = 0; i < 100; i++)
                cpu_relax();
-       ar_outl(2, PLDI2CCND);
-       ar_outl(2, PLDI2CCND);
+       ar_outl(2, PLDI2CCND);
+       ar_outl(2, PLDI2CCND);
 
        while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
                cpu_relax();
@@ -205,24 +204,24 @@ void init_iic(void)
 {
        DEBUG(1, "init_iic:\n");
 
-       /*
+       /*
         * ICU Setting (iic)
         */
-       /* I2C Setting */
-       ar_outl(0x0, PLDI2CCR);         /* I2CCR Disable                   */
-       ar_outl(0x0300, PLDI2CMOD);     /* I2CMOD ACK/8b-data/7b-addr/auto */
-       ar_outl(0x1, PLDI2CACK);        /* I2CACK ACK                      */
+       /* I2C Setting */
+       ar_outl(0x0, PLDI2CCR);         /* I2CCR Disable                   */
+       ar_outl(0x0300, PLDI2CMOD);     /* I2CMOD ACK/8b-data/7b-addr/auto */
+       ar_outl(0x1, PLDI2CACK);        /* I2CACK ACK                      */
 
-       /* I2C CLK */
-       /* 50MH-100k */
+       /* I2C CLK */
+       /* 50MH-100k */
        if (freq == 75) {
-               ar_outl(369, PLDI2CFREQ);       /* BCLK = 75MHz */
+               ar_outl(369, PLDI2CFREQ);       /* BCLK = 75MHz */
        } else if (freq == 50) {
                ar_outl(244, PLDI2CFREQ);       /* BCLK = 50MHz */
        } else {
                ar_outl(244, PLDI2CFREQ);       /* default: BCLK = 50MHz */
        }
-       ar_outl(0x1, PLDI2CCR);         /* I2CCR Enable */
+       ar_outl(0x1, PLDI2CCR);         /* I2CCR Enable */
 }
 
 /**************************************************************************
@@ -254,7 +253,7 @@ static inline void wait_for_vertical_sync(int exp_line)
 
        /*
         * check HCOUNT because we cannot check vertical sync.
-        */
+        */
        for (; tmout >= 0; tmout--) {
                l = ar_inl(ARVHCOUNT);
                if (l == exp_line)
@@ -271,7 +270,7 @@ static inline void wait_for_vertical_sync(int exp_line)
 static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
        struct video_device *v = video_devdata(file);
-       struct ar_device *ar = v->priv;
+       struct ar_device *ar = video_get_drvdata(v);
        long ret = ar->frame_bytes;             /* return read bytes */
        unsigned long arvcr1 = 0;
        unsigned long flags;
@@ -289,7 +288,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        if (ar->mode == AR_MODE_NORMAL)
                arvcr1 |= ARVCR1_NORMAL;
 
-       down(&ar->lock);
+       mutex_lock(&ar->lock);
 
 #if USE_INT
        local_irq_save(flags);
@@ -393,15 +392,14 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        }
        DEBUG(1, "ret = %d\n", ret);
 out_up:
-       up(&ar->lock);
+       mutex_unlock(&ar->lock);
        return ret;
 }
 
-static int ar_do_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, void *arg)
+static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
        struct video_device *dev = video_devdata(file);
-       struct ar_device *ar = dev->priv;
+       struct ar_device *ar = video_get_drvdata(dev);
 
        DEBUG(1, "ar_ioctl()\n");
        switch(cmd) {
@@ -444,7 +442,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
        {
                struct video_window *w = arg;
                DEBUG(1, "VIDIOCGWIN:\n");
-               memset(w, 0, sizeof(w));
+               memset(w, 0, sizeof(*w));
                w->width = ar->width;
                w->height = ar->height;
                return 0;
@@ -457,7 +455,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
                    (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA))
                                return -EINVAL;
 
-               down(&ar->lock);
+               mutex_lock(&ar->lock);
                ar->width = w->width;
                ar->height = w->height;
                if (ar->width == AR_WIDTH_VGA) {
@@ -474,7 +472,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
                        ar->line_bytes = AR_LINE_BYTES_QVGA;
                        ar->mode = AR_MODE_INTERLACE;
                }
-               up(&ar->lock);
+               mutex_unlock(&ar->lock);
                return 0;
        }
        case VIDIOCGFBUF:
@@ -541,17 +539,17 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
        return 0;
 }
 
-static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+static long ar_ioctl(struct file *file, unsigned int cmd,
                    unsigned long arg)
 {
-       return video_usercopy(inode, file, cmd, arg, ar_do_ioctl);
+       return video_usercopy(file, cmd, arg, ar_do_ioctl);
 }
 
 #if USE_INT
 /*
  * Interrupt handler
  */
-static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
+static void ar_interrupt(int irq, void *dev)
 {
        struct ar_device *ar = dev;
        unsigned int line_count;
@@ -563,8 +561,8 @@ static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
                /* operations for interlace mode */
                if ( line_count < (AR_HEIGHT_VGA/2) )   /* even line */
                        line_number = (line_count << 1);
-               else                                    /* odd line */
-                       line_number =
+               else                                    /* odd line */
+                       line_number =
                        (((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
        } else {
                line_number = line_count;
@@ -627,7 +625,7 @@ static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
  */
 static int ar_initialize(struct video_device *dev)
 {
-       struct ar_device *ar = dev->priv;
+       struct ar_device *ar = video_get_drvdata(dev);
        unsigned long cr = 0;
        int i,found=0;
 
@@ -652,7 +650,7 @@ static int ar_initialize(struct video_device *dev)
                cr |= ARVCR1_NORMAL;
        ar_outl(cr, ARVCR1);
 
-       /*
+       /*
         * Initialize IIC so that CPU can communicate with AR LSI,
         * and send boot commands to AR LSI.
         */
@@ -734,8 +732,8 @@ static int ar_initialize(struct video_device *dev)
 
 void ar_release(struct video_device *vfd)
 {
-       struct ar_device *ar = vfd->priv;
-       down(&ar->lock);
+       struct ar_device *ar = video_get_drvdata(vfd);
+       mutex_lock(&ar->lock);
        video_device_release(vfd);
 }
 
@@ -744,27 +742,35 @@ void ar_release(struct video_device *vfd)
  * Video4Linux Module functions
  *
  ****************************************************************************/
-static struct file_operations ar_fops = {
+static struct ar_device ardev;
+
+static int ar_exclusive_open(struct file *file)
+{
+       return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
+}
+
+static int ar_exclusive_release(struct file *file)
+{
+       clear_bit(0, &ardev.in_use);
+       return 0;
+}
+
+static const struct v4l2_file_operations ar_fops = {
        .owner          = THIS_MODULE,
-       .open           = video_exclusive_open,
-       .release        = video_exclusive_release,
+       .open           = ar_exclusive_open,
+       .release        = ar_exclusive_release,
        .read           = ar_read,
        .ioctl          = ar_ioctl,
-       .llseek         = no_llseek,
 };
 
 static struct video_device ar_template = {
-       .owner          = THIS_MODULE,
        .name           = "Colour AR VGA",
-       .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_ARV,
        .fops           = &ar_fops,
        .release        = ar_release,
        .minor          = -1,
 };
 
 #define ALIGN4(x)      ((((int)(x)) & 0x3) == 0)
-static struct ar_device ardev;
 
 static int __init ar_init(void)
 {
@@ -804,7 +810,7 @@ static int __init ar_init(void)
                return -ENOMEM;
        }
        memcpy(ar->vdev, &ar_template, sizeof(ar_template));
-       ar->vdev->priv = ar;
+       video_set_drvdata(ar->vdev, ar);
 
        if (vga) {
                ar->width       = AR_WIDTH_VGA;
@@ -824,7 +830,7 @@ static int __init ar_init(void)
                ar->line_bytes  = AR_LINE_BYTES_QVGA;
                ar->mode        = AR_MODE_INTERLACE;
        }
-       init_MUTEX(&ar->lock);
+       mutex_init(&ar->lock);
        init_waitqueue_head(&ar->wait);
 
 #if USE_INT
@@ -846,7 +852,7 @@ static int __init ar_init(void)
         * so register video device as a frame grabber type.
         * device is named "video[0-64]".
         * video_register_device() initializes h/w using ar_initialize().
-        */
+        */
        if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
                /* return -1, -ENFILE(full) or others */
                printk("arv: register video (Colour AR) failed.\n");
@@ -855,7 +861,7 @@ static int __init ar_init(void)
        }
 
        printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
-               ar->vdev->minor, M32R_IRQ_INT3, freq);
+               ar->vdev->num, M32R_IRQ_INT3, freq);
 
        return 0;