V4L/DVB (10865): vino: convert to v4l2_subdev.
authorHans Verkuil <hverkuil@xs4all.nl>
Wed, 18 Feb 2009 22:18:26 +0000 (19:18 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Mar 2009 15:43:10 +0000 (12:43 -0300)
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/vino.c

index 308fa419ae04d37d8cb0a34aa0898d4080222f7c..96ce68a3dd9553cf6cf20afff6ec192c1f4b78d4 100644 (file)
@@ -287,20 +287,17 @@ struct vino_channel_settings {
        struct video_device *vdev;
 };
 
-struct vino_client {
-       /* the channel which owns this client:
-        * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
-       unsigned int owner;
-       struct i2c_client *driver;
-};
-
 struct vino_settings {
        struct v4l2_device v4l2_dev;
        struct vino_channel_settings a;
        struct vino_channel_settings b;
 
-       struct vino_client decoder;
-       struct vino_client camera;
+       /* the channel which owns this client:
+        * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
+       unsigned int decoder_owner;
+       struct v4l2_subdev *decoder;
+       unsigned int camera_owner;
+       struct v4l2_subdev *camera;
 
        /* a lock for vino register access */
        spinlock_t vino_lock;
@@ -340,6 +337,11 @@ static struct sgi_vino *vino;
 
 static struct vino_settings *vino_drvdata;
 
+#define camera_call(o, f, args...) \
+       v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
+#define decoder_call(o, f, args...) \
+       v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
+
 static const char *vino_driver_name = "vino";
 static const char *vino_driver_description = "SGI VINO";
 static const char *vino_bus_name = "GIO64 bus";
@@ -670,66 +672,12 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data =
        .ack_timeout  = 1000,
 };
 
-/*
- * There are two possible clients on VINO I2C bus, so we limit usage only
- * to them.
- */
-static int i2c_vino_client_reg(struct i2c_client *client)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-       switch (client->driver->id) {
-       case I2C_DRIVERID_SAA7191:
-               if (vino_drvdata->decoder.driver)
-                       ret = -EBUSY;
-               else
-                       vino_drvdata->decoder.driver = client;
-               break;
-       case I2C_DRIVERID_INDYCAM:
-               if (vino_drvdata->camera.driver)
-                       ret = -EBUSY;
-               else
-                       vino_drvdata->camera.driver = client;
-               break;
-       default:
-               ret = -ENODEV;
-       }
-       spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
-       return ret;
-}
-
-static int i2c_vino_client_unreg(struct i2c_client *client)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-       if (client == vino_drvdata->decoder.driver) {
-               if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
-                       ret = -EBUSY;
-               else
-                       vino_drvdata->decoder.driver = NULL;
-       } else if (client == vino_drvdata->camera.driver) {
-               if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
-                       ret = -EBUSY;
-               else
-                       vino_drvdata->camera.driver = NULL;
-       }
-       spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
-       return ret;
-}
-
 static struct i2c_adapter vino_i2c_adapter =
 {
        .name                   = "VINO I2C bus",
        .id                     = I2C_HW_SGI_VINO,
        .algo_data              = &i2c_sgi_vino_data,
-       .client_register        = &i2c_vino_client_reg,
-       .client_unregister      = &i2c_vino_client_unreg,
+       .owner                  = THIS_MODULE,
 };
 
 static int vino_i2c_add_bus(void)
@@ -742,20 +690,6 @@ static int vino_i2c_del_bus(void)
        return i2c_del_adapter(&vino_i2c_adapter);
 }
 
-static int i2c_camera_command(unsigned int cmd, void *arg)
-{
-       return vino_drvdata->camera.driver->
-               driver->command(vino_drvdata->camera.driver,
-                               cmd, arg);
-}
-
-static int i2c_decoder_command(unsigned int cmd, void *arg)
-{
-       return vino_drvdata->decoder.driver->
-               driver->command(vino_drvdata->decoder.driver,
-                               cmd, arg);
-}
-
 /* VINO framebuffer/DMA descriptor management */
 
 static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
@@ -2456,9 +2390,9 @@ static int vino_is_input_owner(struct vino_channel_settings *vcs)
        switch(vcs->input) {
        case VINO_INPUT_COMPOSITE:
        case VINO_INPUT_SVIDEO:
-               return (vino_drvdata->decoder.owner == vcs->channel);
+               return vino_drvdata->decoder_owner == vcs->channel;
        case VINO_INPUT_D1:
-               return (vino_drvdata->camera.owner == vcs->channel);
+               return vino_drvdata->camera_owner == vcs->channel;
        default:
                return 0;
        }
@@ -2474,24 +2408,22 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
        /* First try D1 and then SAA7191 */
-       if (vino_drvdata->camera.driver
-           && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
-               i2c_use_client(vino_drvdata->camera.driver);
-               vino_drvdata->camera.owner = vcs->channel;
+       if (vino_drvdata->camera
+           && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
+               vino_drvdata->camera_owner = vcs->channel;
                vcs->input = VINO_INPUT_D1;
                vcs->data_norm = VINO_DATA_NORM_D1;
-       } else if (vino_drvdata->decoder.driver
-                  && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
+       } else if (vino_drvdata->decoder
+                  && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
                int input;
                int data_norm;
                v4l2_std_id norm;
                struct v4l2_routing route = { 0, 0 };
 
-               i2c_use_client(vino_drvdata->decoder.driver);
                input = VINO_INPUT_COMPOSITE;
 
                route.input = vino_get_saa7191_input(input);
-               ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
+               ret = decoder_call(video, s_routing, &route);
                if (ret) {
                        ret = -EINVAL;
                        goto out;
@@ -2502,7 +2434,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
                /* Don't hold spinlocks while auto-detecting norm
                 * as it may take a while... */
 
-               ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
+               ret = decoder_call(video, querystd, &norm);
                if (!ret) {
                        for (data_norm = 0; data_norm < 3; data_norm++) {
                                if (vino_data_norms[data_norm].std & norm)
@@ -2510,7 +2442,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
                        }
                        if (data_norm == 3)
                                data_norm = VINO_DATA_NORM_PAL;
-                       ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
+                       ret = decoder_call(tuner, s_std, norm);
                }
 
                spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2520,7 +2452,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
                        goto out;
                }
 
-               vino_drvdata->decoder.owner = vcs->channel;
+               vino_drvdata->decoder_owner = vcs->channel;
 
                vcs->input = input;
                vcs->data_norm = data_norm;
@@ -2565,25 +2497,24 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
        switch (input) {
        case VINO_INPUT_COMPOSITE:
        case VINO_INPUT_SVIDEO:
-               if (!vino_drvdata->decoder.driver) {
+               if (!vino_drvdata->decoder) {
                        ret = -EINVAL;
                        goto out;
                }
 
-               if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
-                       i2c_use_client(vino_drvdata->decoder.driver);
-                       vino_drvdata->decoder.owner = vcs->channel;
+               if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
+                       vino_drvdata->decoder_owner = vcs->channel;
                }
 
-               if (vino_drvdata->decoder.owner == vcs->channel) {
+               if (vino_drvdata->decoder_owner == vcs->channel) {
                        int data_norm;
                        v4l2_std_id norm;
                        struct v4l2_routing route = { 0, 0 };
 
                        route.input = vino_get_saa7191_input(input);
-                       ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
+                       ret = decoder_call(video, s_routing, &route);
                        if (ret) {
-                               vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+                               vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
                                ret = -EINVAL;
                                goto out;
                        }
@@ -2593,7 +2524,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
                        /* Don't hold spinlocks while auto-detecting norm
                         * as it may take a while... */
 
-                       ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
+                       ret = decoder_call(video, querystd, &norm);
                        if (!ret) {
                                for (data_norm = 0; data_norm < 3; data_norm++) {
                                        if (vino_data_norms[data_norm].std & norm)
@@ -2601,13 +2532,13 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
                                }
                                if (data_norm == 3)
                                        data_norm = VINO_DATA_NORM_PAL;
-                               ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
+                               ret = decoder_call(tuner, s_std, norm);
                        }
 
                        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
                        if (ret) {
-                               vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+                               vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
                                ret = -EINVAL;
                                goto out;
                        }
@@ -2624,36 +2555,31 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
                        vcs->data_norm = vcs2->data_norm;
                }
 
-               if (vino_drvdata->camera.owner == vcs->channel) {
+               if (vino_drvdata->camera_owner == vcs->channel) {
                        /* Transfer the ownership or release the input */
                        if (vcs2->input == VINO_INPUT_D1) {
-                               vino_drvdata->camera.owner = vcs2->channel;
+                               vino_drvdata->camera_owner = vcs2->channel;
                        } else {
-                               i2c_release_client(vino_drvdata->camera.driver);
-                               vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+                               vino_drvdata->camera_owner = VINO_NO_CHANNEL;
                        }
                }
                break;
        case VINO_INPUT_D1:
-               if (!vino_drvdata->camera.driver) {
+               if (!vino_drvdata->camera) {
                        ret = -EINVAL;
                        goto out;
                }
 
-               if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
-                       i2c_use_client(vino_drvdata->camera.driver);
-                       vino_drvdata->camera.owner = vcs->channel;
-               }
+               if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
+                       vino_drvdata->camera_owner = vcs->channel;
 
-               if (vino_drvdata->decoder.owner == vcs->channel) {
+               if (vino_drvdata->decoder_owner == vcs->channel) {
                        /* Transfer the ownership or release the input */
                        if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
                                 (vcs2->input == VINO_INPUT_SVIDEO)) {
-                               vino_drvdata->decoder.owner = vcs2->channel;
+                               vino_drvdata->decoder_owner = vcs2->channel;
                        } else {
-                               i2c_release_client(vino_drvdata->
-                                                  decoder.driver);
-                               vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+                               vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
                        }
                }
 
@@ -2690,20 +2616,18 @@ static void vino_release_input(struct vino_channel_settings *vcs)
        /* Release ownership of the channel
         * and if the other channel takes input from
         * the same source, transfer the ownership */
-       if (vino_drvdata->camera.owner == vcs->channel) {
+       if (vino_drvdata->camera_owner == vcs->channel) {
                if (vcs2->input == VINO_INPUT_D1) {
-                       vino_drvdata->camera.owner = vcs2->channel;
+                       vino_drvdata->camera_owner = vcs2->channel;
                } else {
-                       i2c_release_client(vino_drvdata->camera.driver);
-                       vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+                       vino_drvdata->camera_owner = VINO_NO_CHANNEL;
                }
-       } else if (vino_drvdata->decoder.owner == vcs->channel) {
+       } else if (vino_drvdata->decoder_owner == vcs->channel) {
                if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
                         (vcs2->input == VINO_INPUT_SVIDEO)) {
-                       vino_drvdata->decoder.owner = vcs2->channel;
+                       vino_drvdata->decoder_owner = vcs2->channel;
                } else {
-                       i2c_release_client(vino_drvdata->decoder.driver);
-                       vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+                       vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
                }
        }
        vcs->input = VINO_INPUT_NONE;
@@ -2742,7 +2666,7 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
                 * as it may take a while... */
 
                norm = vino_data_norms[data_norm].std;
-               err = i2c_decoder_command(VIDIOC_S_STD, &norm);
+               err = decoder_call(tuner, s_std, norm);
 
                spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
 
@@ -2784,7 +2708,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
        unsigned long flags;
 
        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-       if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+       if (vino_drvdata->decoder && vino_drvdata->camera) {
                switch (index) {
                case 0:
                        input = VINO_INPUT_COMPOSITE;
@@ -2796,7 +2720,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
                        input = VINO_INPUT_D1;
                        break;
                }
-       } else if (vino_drvdata->decoder.driver) {
+       } else if (vino_drvdata->decoder) {
                switch (index) {
                case 0:
                        input = VINO_INPUT_COMPOSITE;
@@ -2805,7 +2729,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
                        input = VINO_INPUT_SVIDEO;
                        break;
                }
-       } else if (vino_drvdata->camera.driver) {
+       } else if (vino_drvdata->camera) {
                switch (index) {
                case 0:
                        input = VINO_INPUT_D1;
@@ -2823,7 +2747,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
        __u32 index = 0;
        // FIXME: detect when no inputs available
 
-       if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+       if (vino_drvdata->decoder && vino_drvdata->camera) {
                switch (vcs->input) {
                case VINO_INPUT_COMPOSITE:
                        index = 0;
@@ -2835,7 +2759,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
                        index = 2;
                        break;
                }
-       } else if (vino_drvdata->decoder.driver) {
+       } else if (vino_drvdata->decoder) {
                switch (vcs->input) {
                case VINO_INPUT_COMPOSITE:
                        index = 0;
@@ -2844,7 +2768,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
                        index = 1;
                        break;
                }
-       } else if (vino_drvdata->camera.driver) {
+       } else if (vino_drvdata->camera) {
                switch (vcs->input) {
                case VINO_INPUT_D1:
                        index = 0;
@@ -2893,7 +2817,7 @@ static int vino_enum_input(struct file *file, void *__fh,
        strcpy(i->name, vino_inputs[input].name);
 
        if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
-               i2c_decoder_command(VIDIOC_INT_G_INPUT_STATUS, &i->status);
+               decoder_call(video, g_input_status, &i->status);
        return 0;
 }
 
@@ -2950,7 +2874,7 @@ static int vino_querystd(struct file *file, void *__fh,
                break;
        case VINO_INPUT_COMPOSITE:
        case VINO_INPUT_SVIDEO: {
-               i2c_decoder_command(VIDIOC_QUERYSTD, std);
+               decoder_call(video, querystd, std);
                break;
        }
        default:
@@ -3679,7 +3603,7 @@ static int vino_g_ctrl(struct file *file, void *__fh,
                if (err)
                        goto out;
 
-               err = i2c_camera_command(VIDIOC_G_CTRL, &control);
+               err = camera_call(core, g_ctrl, control);
                if (err)
                        err = -EINVAL;
                break;
@@ -3697,7 +3621,7 @@ static int vino_g_ctrl(struct file *file, void *__fh,
                if (err)
                        goto out;
 
-               err = i2c_decoder_command(VIDIOC_G_CTRL, &control);
+               err = decoder_call(core, g_ctrl, control);
                if (err)
                        err = -EINVAL;
                break;
@@ -3743,7 +3667,7 @@ static int vino_s_ctrl(struct file *file, void *__fh,
                        err = -ERANGE;
                        goto out;
                }
-               err = i2c_camera_command(VIDIOC_S_CTRL, &control);
+               err = camera_call(core, s_ctrl, control);
                if (err)
                        err = -EINVAL;
                break;
@@ -3765,7 +3689,7 @@ static int vino_s_ctrl(struct file *file, void *__fh,
                        goto out;
                }
 
-               err = i2c_decoder_command(VIDIOC_S_CTRL, &control);
+               err = decoder_call(core, s_ctrl, control);
                if (err)
                        err = -EINVAL;
                break;
@@ -4257,6 +4181,7 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs,
 
 static int __init vino_module_init(void)
 {
+       unsigned short addr[] = { 0, I2C_CLIENT_END };
        int ret;
 
        printk(KERN_INFO "SGI VINO driver version %s\n",
@@ -4326,10 +4251,12 @@ static int __init vino_module_init(void)
        }
        vino_init_stage++;
 
-#ifdef MODULE
-       request_module("saa7191");
-       request_module("indycam");
-#endif
+       addr[0] = 0x45;
+       vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+                       "saa7191", "saa7191", addr);
+       addr[0] = 0x2b;
+       vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+                       "indycam", "indycam", addr);
 
        dprintk("init complete!\n");