The patch number 9965 was added via Hans Verkuil <[email protected]>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [email protected]

------

From: Hans Verkuil  <[email protected]>
tda9840: convert to v4l2_subdev.


Priority: normal

Signed-off-by: Hans Verkuil <[email protected]>


---

 linux/drivers/media/video/tda9840.c |  212 ++++++++++++++++------------
 1 file changed, 128 insertions(+), 84 deletions(-)

diff -r f4fda0eff315 -r ea44f9576d9c linux/drivers/media/video/tda9840.c
--- a/linux/drivers/media/video/tda9840.c       Thu Dec 18 17:04:05 2008 +0100
+++ b/linux/drivers/media/video/tda9840.c       Thu Dec 18 17:21:57 2008 +0100
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-i2c-drv-legacy.h>
 #include "tda9840.h"
 #include "compat.h"
@@ -63,85 +63,89 @@ static unsigned short normal_i2c[] = { I
 /* magic definition of all other variables and things */
 I2C_CLIENT_INSMOD;
 
-static void tda9840_write(struct i2c_client *client, u8 reg, u8 val)
-{
+static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
        if (i2c_smbus_write_byte_data(client, reg, val))
-               v4l_dbg(1, debug, client, "error writing %02x to %02x\n",
+               v4l2_dbg(1, debug, sd, "error writing %02x to %02x\n",
                                val, reg);
 }
 
-static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-       int byte = *(int *)arg;
+static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
+{
+       int byte;
+
+       if (t->index)
+               return -EINVAL;
+
+       switch (t->audmode) {
+       case V4L2_TUNER_MODE_STEREO:
+               byte = TDA9840_SET_STEREO;
+               break;
+       case V4L2_TUNER_MODE_LANG1_LANG2:
+               byte = TDA9840_SET_BOTH;
+               break;
+       case V4L2_TUNER_MODE_LANG1:
+               byte = TDA9840_SET_LANG1;
+               break;
+       case V4L2_TUNER_MODE_LANG2:
+               byte = TDA9840_SET_LANG2;
+               break;
+       default:
+               byte = TDA9840_SET_MONO;
+               break;
+       }
+       v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
+       tda9840_write(sd, SWITCH, byte);
+       return 0;
+}
+
+static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       u8 byte;
+
+       t->rxsubchans = V4L2_TUNER_SUB_MONO;
+       if (1 != i2c_master_recv(client, &byte, 1)) {
+               v4l2_dbg(1, debug, sd,
+                       "i2c_master_recv() failed\n");
+               return -EIO;
+       }
+
+       if (byte & 0x80) {
+               v4l2_dbg(1, debug, sd,
+                       "TDA9840_DETECT: register contents invalid\n");
+               return -EINVAL;
+       }
+
+       v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
+
+       switch (byte & 0x60) {
+       case 0x00:
+               t->rxsubchans = V4L2_TUNER_SUB_MONO;
+               break;
+       case 0x20:
+               t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+               break;
+       case 0x40:
+               t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+               break;
+       default: /* Incorrect detect */
+               t->rxsubchans = V4L2_TUNER_MODE_MONO;
+               break;
+       }
+       return 0;
+}
+
+static int tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+{
+       int byte;
 
        switch (cmd) {
-       case VIDIOC_S_TUNER: {
-               struct v4l2_tuner *t = arg;
-               int byte;
-
-               if (t->index)
-                       return -EINVAL;
-
-               switch (t->audmode) {
-               case V4L2_TUNER_MODE_STEREO:
-                       byte = TDA9840_SET_STEREO;
-                       break;
-               case V4L2_TUNER_MODE_LANG1_LANG2:
-                       byte = TDA9840_SET_BOTH;
-                       break;
-               case V4L2_TUNER_MODE_LANG1:
-                       byte = TDA9840_SET_LANG1;
-                       break;
-               case V4L2_TUNER_MODE_LANG2:
-                       byte = TDA9840_SET_LANG2;
-                       break;
-               default:
-                       byte = TDA9840_SET_MONO;
-                       break;
-               }
-               v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte);
-               tda9840_write(client, SWITCH, byte);
-               break;
-       }
-
-       case VIDIOC_G_TUNER: {
-               struct v4l2_tuner *t = arg;
-               u8 byte;
-
-               t->rxsubchans = V4L2_TUNER_SUB_MONO;
-               if (1 != i2c_master_recv(client, &byte, 1)) {
-                       v4l_dbg(1, debug, client,
-                               "i2c_master_recv() failed\n");
-                       return -EIO;
-               }
-
-               if (byte & 0x80) {
-                       v4l_dbg(1, debug, client,
-                               "TDA9840_DETECT: register contents invalid\n");
-                       return -EINVAL;
-               }
-
-               v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", 
byte);
-
-               switch (byte & 0x60) {
-               case 0x00:
-                       t->rxsubchans = V4L2_TUNER_SUB_MONO;
-                       break;
-               case 0x20:
-                       t->rxsubchans = V4L2_TUNER_SUB_LANG1 | 
V4L2_TUNER_SUB_LANG2;
-                       break;
-               case 0x40:
-                       t->rxsubchans = V4L2_TUNER_SUB_STEREO | 
V4L2_TUNER_SUB_MONO;
-                       break;
-               default: /* Incorrect detect */
-                       t->rxsubchans = V4L2_TUNER_MODE_MONO;
-                       break;
-               }
-               break;
-       }
-
        case TDA9840_LEVEL_ADJUST:
-               v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte);
+               byte = *(int *)arg;
+               v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
 
                /* check for correct range */
                if (byte > 25 || byte < -20)
@@ -153,11 +157,12 @@ static int tda9840_command(struct i2c_cl
                        byte += 0x8;
                else
                        byte = -byte;
-               tda9840_write(client, LEVEL_ADJUST, byte);
+               tda9840_write(sd, LEVEL_ADJUST, byte);
                break;
 
        case TDA9840_STEREO_ADJUST:
-               v4l_dbg(1, debug, client, "TDA9840_STEREO_ADJUST: %d\n", byte);
+               byte = *(int *)arg;
+               v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
 
                /* check for correct range */
                if (byte > 25 || byte < -24)
@@ -170,18 +175,41 @@ static int tda9840_command(struct i2c_cl
                else
                        byte = -byte;
 
-               tda9840_write(client, STEREO_ADJUST, byte);
+               tda9840_write(sd, STEREO_ADJUST, byte);
                break;
        default:
                return -ENOIOCTLCMD;
        }
-
-       return 0;
-}
+       return 0;
+}
+
+static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
+{
+       return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops tda9840_core_ops = {
+       .ioctl = tda9840_ioctl,
+};
+
+static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
+       .s_tuner = tda9840_s_tuner,
+       .g_tuner = tda9840_g_tuner,
+};
+
+static const struct v4l2_subdev_ops tda9840_ops = {
+       .core = &tda9840_core_ops,
+       .tuner = &tda9840_tuner_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int tda9840_probe(struct i2c_client *client,
                          const struct i2c_device_id *id)
 {
+       struct v4l2_subdev *sd;
        int result;
        int byte;
 
@@ -189,20 +217,35 @@ static int tda9840_probe(struct i2c_clie
        if (!i2c_check_functionality(client->adapter,
                        I2C_FUNC_SMBUS_READ_BYTE_DATA |
                        I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-               return 0;
+               return -EIO;
 
        v4l_info(client, "chip found @ 0x%x (%s)\n",
                        client->addr << 1, client->adapter->name);
 
+       sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+       v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
+
        /* set initial values for level & stereo - adjustment, mode */
        byte = 0;
-       result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte);
-       result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte);
-       tda9840_write(client, SWITCH, TDA9840_SET_STEREO);
+       result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
+       result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
+       tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
        if (result) {
-               v4l_dbg(1, debug, client, "could not initialize tda9840\n");
+               v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
+               kfree(sd);
                return -ENODEV;
        }
+       return 0;
+}
+
+static int tda9840_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+       v4l2_device_unregister_subdev(sd);
+       kfree(sd);
        return 0;
 }
 
@@ -225,6 +268,7 @@ static struct v4l2_i2c_driver_data v4l2_
        .driverid = I2C_DRIVERID_TDA9840,
        .command = tda9840_command,
        .probe = tda9840_probe,
+       .remove = tda9840_remove,
        .legacy_probe = tda9840_legacy_probe,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
        .id_table = tda9840_id,


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/ea44f9576d9c3148335c4a2a0365fcdb6ba150b2

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to