Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic...
[safe/jmp/linux-2.6] / drivers / media / video / hexium_gemini.c
index e7bbeb1..ad2c232 100644 (file)
@@ -1,9 +1,9 @@
 /*
     hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
-               
+
     Visit http://www.mihu.de/linux/saa7146/ and follow the link
     to "hexium" for further details about this card.
-    
+
     Copyright (C) 2003 Michael Hunold <michael@mihu.de>
 
     This program is free software; you can redistribute it and/or modify
 
 #include <media/saa7146_vv.h>
 
-static int debug = 0;
+static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "debug verbosity");
 
 /* global variables */
-static int hexium_num = 0;
+static int hexium_num;
 
 #define HEXIUM_GEMINI                  4
 #define HEXIUM_GEMINI_DUAL             5
@@ -56,17 +56,6 @@ struct hexium_data
        u8 byte;
 };
 
-static struct saa7146_extension_ioctls ioctls[] = {
-       { VIDIOC_G_INPUT,       SAA7146_EXCLUSIVE },
-       { VIDIOC_S_INPUT,       SAA7146_EXCLUSIVE },
-       { VIDIOC_QUERYCTRL,     SAA7146_BEFORE },
-       { VIDIOC_ENUMINPUT,     SAA7146_EXCLUSIVE },
-       { VIDIOC_S_STD,         SAA7146_AFTER },
-       { VIDIOC_G_CTRL,        SAA7146_BEFORE },
-       { VIDIOC_S_CTRL,        SAA7146_BEFORE },
-       { 0,                    0 }
-};
-
 #define HEXIUM_CONTROLS        1
 static struct v4l2_queryctrl hexium_controls[] = {
        { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -81,7 +70,7 @@ struct hexium
 
        struct video_device     *video_dev;
        struct i2c_adapter      i2c_adapter;
-               
+
        int             cur_input;      /* current input */
        v4l2_std_id     cur_std;        /* current standard */
        int             cur_bw;         /* current black/white status */
@@ -174,7 +163,7 @@ static struct saa7146_standard hexium_standards[] = {
                .h_offset       = 1,    .h_pixels       = 720,
                .v_max_out      = 576,  .h_max_out      = 768,
        }
-};             
+};
 
 /* bring hardware to a sane state. this has to be done, just in case someone
    wants to capture from this device before it has been properly initialized.
@@ -231,12 +220,139 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
        return 0;
 }
 
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+       DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+       if (i->index >= HEXIUM_INPUTS)
+               return -EINVAL;
+
+       memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+       DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+       return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+       *input = hexium->cur_input;
+
+       DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+       return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+       DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+       if (input >= HEXIUM_INPUTS)
+               return -EINVAL;
+
+       hexium->cur_input = input;
+       hexium_set_input(hexium, input);
+       return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+   which gets registered *after* this function. because of this we have
+   to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       int i;
+
+       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+               if (hexium_controls[i].id == qc->id) {
+                       *qc = hexium_controls[i];
+                       DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+                       return 0;
+               }
+       }
+       return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct hexium *hexium = (struct hexium *) dev->ext_priv;
+       int i;
+
+       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+               if (hexium_controls[i].id == vc->id)
+                       break;
+       }
+
+       if (i < 0)
+               return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+       if (vc->id == V4L2_CID_PRIVATE_BASE) {
+               vc->value = hexium->cur_bw;
+               DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct hexium *hexium = (struct hexium *) dev->ext_priv;
+       int i = 0;
+
+       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+               if (hexium_controls[i].id == vc->id)
+                       break;
+       }
+
+       if (i < 0)
+               return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+       if (vc->id == V4L2_CID_PRIVATE_BASE)
+               hexium->cur_bw = vc->value;
+
+       DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+       if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+               hexium_set_standard(hexium, hexium_pal);
+               return 0;
+       }
+       if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+               hexium_set_standard(hexium, hexium_ntsc);
+               return 0;
+       }
+       if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+               hexium_set_standard(hexium, hexium_secam);
+               return 0;
+       }
+       if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+               hexium_set_standard(hexium, hexium_pal_bw);
+               return 0;
+       }
+       if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+               hexium_set_standard(hexium, hexium_ntsc_bw);
+               return 0;
+       }
+       if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+               /* fixme: is there no bw secam mode? */
+               return -EINVAL;
+
+       return -EINVAL;
+}
+
+
 static struct saa7146_ext_vv vv_data;
 
 /* this function only gets called when the probing was successful */
 static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
 {
        struct hexium *hexium = (struct hexium *) dev->ext_priv;
+       int ret;
 
        DEB_EE((".\n"));
 
@@ -279,9 +395,16 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
        hexium->cur_input = 0;
 
        saa7146_vv_init(dev, &vv_data);
-       if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
+       vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+       vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+       vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+       vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+       vv_data.ops.vidioc_g_input = vidioc_g_input;
+       vv_data.ops.vidioc_s_input = vidioc_s_input;
+       ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
+       if (ret < 0) {
                printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
-               return -1;
+               return ret;
        }
 
        printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
@@ -306,153 +429,6 @@ static int hexium_detach(struct saa7146_dev *dev)
        return 0;
 }
 
-static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
-       struct saa7146_dev *dev = fh->dev;
-       struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
-       struct saa7146_vv *vv = dev->vv_data; 
-*/
-       switch (cmd) {
-       case VIDIOC_ENUMINPUT:
-               {
-                       struct v4l2_input *i = arg;
-                       DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
-                       if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
-                               return -EINVAL;
-                       }
-
-                       memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
-                       DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
-                       return 0;
-               }
-       case VIDIOC_G_INPUT:
-               {
-                       int *input = (int *) arg;
-                       *input = hexium->cur_input;
-
-                       DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
-                       return 0;
-               }
-       case VIDIOC_S_INPUT:
-               {
-                       int input = *(int *) arg;
-
-                       DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
-                       if (input < 0 || input >= HEXIUM_INPUTS) {
-                               return -EINVAL;
-                       }
-
-                       hexium->cur_input = input;
-                       hexium_set_input(hexium, input);
-
-                       return 0;
-               }
-               /* the saa7146 provides some controls (brightness, contrast, saturation)
-                  which gets registered *after* this function. because of this we have
-                  to return with a value != 0 even if the function succeded.. */
-       case VIDIOC_QUERYCTRL:
-               {
-                       struct v4l2_queryctrl *qc = arg;
-                       int i;
-
-                       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-                               if (hexium_controls[i].id == qc->id) {
-                                       *qc = hexium_controls[i];
-                                       DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
-                                       return 0;
-                               }
-                       }
-                       return -EAGAIN;
-               }
-       case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *vc = arg;
-                       int i;
-
-                       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-                               if (hexium_controls[i].id == vc->id) {
-                                       break;
-                               }
-                       }
-
-                       if (i < 0) {
-                               return -EAGAIN;
-                       }
-
-                       switch (vc->id) {
-                       case V4L2_CID_PRIVATE_BASE:{
-                                       vc->value = hexium->cur_bw;
-                                       DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
-                                       return 0;
-                               }
-                       }
-                       return -EINVAL;
-               }
-
-       case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *vc = arg;
-                       int i = 0;
-
-                       for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-                               if (hexium_controls[i].id == vc->id) {
-                                       break;
-                               }
-                       }
-
-                       if (i < 0) {
-                               return -EAGAIN;
-                       }
-
-                       switch (vc->id) {
-                       case V4L2_CID_PRIVATE_BASE:{
-                                       hexium->cur_bw = vc->value;
-                                       break;
-                               }
-                       }
-
-                       DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
-                       if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-                               hexium_set_standard(hexium, hexium_pal);
-                               return 0;
-                       }
-                       if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-                               hexium_set_standard(hexium, hexium_ntsc);
-                               return 0;
-                       }
-                       if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-                               hexium_set_standard(hexium, hexium_secam);
-                               return 0;
-                       }
-                       if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-                               hexium_set_standard(hexium, hexium_pal_bw);
-                               return 0;
-                       }
-                       if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-                               hexium_set_standard(hexium, hexium_ntsc_bw);
-                               return 0;
-                       }
-                       if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-                               /* fixme: is there no bw secam mode? */
-                               return -EINVAL;
-                       }
-
-                       return -EINVAL;
-               }
-       default:
-/*
-               DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
-               return -ENOIOCTLCMD;
-       }
-       return 0;
-}
-
 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
 {
        struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +490,6 @@ static struct saa7146_ext_vv vv_data = {
        .stds = &hexium_standards[0],
        .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
        .std_callback = &std_callback,
-       .ioctls = &ioctls[0],
-       .ioctl = hexium_ioctl,
 };
 
 static struct saa7146_extension hexium_extension = {