Switch to using new-style i2c devices, which are enumerated rather than
autodetected as the legacy i2c devices were. This solves a number of
problems such as misdetections which can happen when using different
card models in the same machine.

This includes the conversion of all i2c device drivers used by the
various Zoran cards: adv7170, adv7175, bt819, bt856, bt866, ks0127,
saa7110, saa7111, saa7114, saa7185 and vpx3220. These now support
both probing and enumeration.

Signed-off-by: Jean Delvare <[EMAIL PROTECTED]>
Tested-by: Martin Samuelsson <[EMAIL PROTECTED]>
Tested-by: Bernhard Praschinger <[EMAIL PROTECTED]>
---
 drivers/media/video/adv7170.c    |   78 ++++++--------
 drivers/media/video/adv7175.c    |   78 ++++++--------
 drivers/media/video/bt819.c      |  109 +++++++++-----------
 drivers/media/video/bt856.c      |   73 +++++--------
 drivers/media/video/bt866.c      |   78 +++++++-------
 drivers/media/video/ks0127.c     |   75 +++++++------
 drivers/media/video/saa7110.c    |   74 +++++--------
 drivers/media/video/saa7111.c    |   83 +++++++--------
 drivers/media/video/saa7114.c    |   96 ++++++++---------
 drivers/media/video/saa7185.c    |   81 ++++++---------
 drivers/media/video/vpx3220.c    |  103 ++++++++-----------
 drivers/media/video/zoran.h      |    3 
 drivers/media/video/zoran_card.c |  204 ++++++++++++++++----------------------
 13 files changed, 510 insertions(+), 625 deletions(-)

--- linux-2.6.27-rc4.orig/drivers/media/video/zoran_card.c      2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/zoran_card.c   2008-08-21 
22:23:58.000000000 +0200
@@ -65,12 +65,12 @@ static int card[BUZ_MAX] = { -1, -1, -1,
 module_param_array(card, int, NULL, 0444);
 MODULE_PARM_DESC(card, "The type of card");
 
-static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
-module_param_array(encoder, int, NULL, 0444);
+static char *encoder[BUZ_MAX];
+module_param_array(encoder, charp, NULL, 0444);
 MODULE_PARM_DESC(encoder, "i2c TV encoder");
 
-static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
-module_param_array(decoder, int, NULL, 0444);
+static char *decoder[BUZ_MAX];
+module_param_array(decoder, charp, NULL, 0444);
 MODULE_PARM_DESC(decoder, "i2c TV decoder");
 
 /*
@@ -326,45 +326,32 @@ avs6eyes_init (struct zoran *zr)
 }
 
 static char *
-i2cid_to_modulename (u16 i2c_id)
+i2cid_to_modulename(const char *i2c_name)
 {
        char *name = NULL;
 
-       switch (i2c_id) {
-       case I2C_DRIVERID_SAA7110:
+       if (strcmp(i2c_name, "saa7110") == 0)
                name = "saa7110";
-               break;
-       case I2C_DRIVERID_SAA7111A:
+       else if (strcmp(i2c_name, "saa7111_old") == 0)
                name = "saa7111";
-               break;
-       case I2C_DRIVERID_SAA7114:
+       else if (strcmp(i2c_name, "saa7114_old") == 0)
                name = "saa7114";
-               break;
-       case I2C_DRIVERID_SAA7185B:
+       else if (strcmp(i2c_name, "saa7185") == 0)
                name = "saa7185";
-               break;
-       case I2C_DRIVERID_ADV7170:
+       else if (strcmp(i2c_name, "adv7170") == 0)
                name = "adv7170";
-               break;
-       case I2C_DRIVERID_ADV7175:
+       else if (strcmp(i2c_name, "adv7176") == 0)
                name = "adv7175";
-               break;
-       case I2C_DRIVERID_BT819:
+       else if (strcmp(i2c_name, "bt819a") == 0)
                name = "bt819";
-               break;
-       case I2C_DRIVERID_BT856:
+       else if (strcmp(i2c_name, "bt856") == 0)
                name = "bt856";
-               break;
-       case I2C_DRIVERID_BT866:
+       else if (strcmp(i2c_name, "bt866") == 0)
                name = "bt866";
-               break;
-       case I2C_DRIVERID_VPX3220:
+       else if (strcmp(i2c_name, "vpx3220a") == 0)
                name = "vpx3220";
-               break;
-       case I2C_DRIVERID_KS0127:
+       else if (strcmp(i2c_name, "ks0127") == 0)
                name = "ks0127";
-               break;
-       }
 
        return name;
 }
@@ -423,7 +410,8 @@ static struct card_info zoran_cards[NUM_
        {
                .type = DC10_old,
                .name = "DC10(old)",
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
+               .i2c_decoder = "vpx3220a",
+               .decoder_addr = { 0x86 >> 1, (0x86 >> 1) + 4, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -451,8 +439,10 @@ static struct card_info zoran_cards[NUM_
        }, {
                .type = DC10_new,
                .name = "DC10(new)",
-               .i2c_decoder = I2C_DRIVERID_SAA7110,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "saa7110",
+               .i2c_encoder = "adv7176",
+               .decoder_addr = { 0x9c >> 1, (0x9c >> 1) + 1, I2C_CLIENT_END },
+               .encoder_addr = { 0x54 >> 1, (0x54 >> 1) + 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 3,
@@ -480,8 +470,10 @@ static struct card_info zoran_cards[NUM_
                .name = "DC10plus",
                .vendor_id = PCI_VENDOR_ID_MIRO,
                .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
-               .i2c_decoder = I2C_DRIVERID_SAA7110,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "saa7110",
+               .i2c_encoder = "adv7176",
+               .decoder_addr = { 0x9c >> 1, (0x9c >> 1) + 1, I2C_CLIENT_END },
+               .encoder_addr = { 0x54 >> 1, (0x54 >> 1) + 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 3,
@@ -508,8 +500,10 @@ static struct card_info zoran_cards[NUM_
        }, {
                .type = DC30,
                .name = "DC30",
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "vpx3220a",
+               .i2c_encoder = "adv7176",
+               .decoder_addr = { 0x86 >> 1, (0x86 >> 1) + 4, I2C_CLIENT_END },
+               .encoder_addr = { 0x54 >> 1, (0x54 >> 1) + 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -539,8 +533,10 @@ static struct card_info zoran_cards[NUM_
                .name = "DC30plus",
                .vendor_id = PCI_VENDOR_ID_MIRO,
                .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "vpx3220a",
+               .i2c_encoder = "adv7176",
+               .decoder_addr = { 0x86 >> 1, (0x86 >> 1) + 4, I2C_CLIENT_END },
+               .encoder_addr = { 0x54 >> 1, (0x54 >> 1) + 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -568,8 +564,10 @@ static struct card_info zoran_cards[NUM_
        }, {
                .type = LML33,
                .name = "LML33",
-               .i2c_decoder = I2C_DRIVERID_BT819,
-               .i2c_encoder = I2C_DRIVERID_BT856,
+               .i2c_decoder = "bt819a",
+               .i2c_encoder = "bt856",
+               .decoder_addr = { 0x8a >> 1, I2C_CLIENT_END },
+               .encoder_addr = { 0x88 >> 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -597,8 +595,10 @@ static struct card_info zoran_cards[NUM_
                .name = "LML33R10",
                .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
                .device_id = PCI_DEVICE_ID_LML_33R10,
-               .i2c_decoder = I2C_DRIVERID_SAA7114,
-               .i2c_encoder = I2C_DRIVERID_ADV7170,
+               .i2c_decoder = "saa7114_old",
+               .i2c_encoder = "adv7170",
+               .decoder_addr = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END },
+               .encoder_addr = { 0xd4 >> 1, (0xd4 >> 1) + 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -626,8 +626,10 @@ static struct card_info zoran_cards[NUM_
                .name = "Buz",
                .vendor_id = PCI_VENDOR_ID_IOMEGA,
                .device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
-               .i2c_decoder = I2C_DRIVERID_SAA7111A,
-               .i2c_encoder = I2C_DRIVERID_SAA7185B,
+               .i2c_decoder = "saa7111_old",
+               .i2c_encoder = "saa7185",
+               .decoder_addr = { 0x48 >> 1, I2C_CLIENT_END },
+               .encoder_addr = { 0x88 >> 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -657,8 +659,10 @@ static struct card_info zoran_cards[NUM_
                   can't be autodetected, and requires card=x. */
                .vendor_id = -1,
                .device_id = -1,
-               .i2c_decoder = I2C_DRIVERID_KS0127,
-               .i2c_encoder = I2C_DRIVERID_BT866,
+               .i2c_decoder = "ks0127",
+               .i2c_encoder = "bt866",
+               .decoder_addr = { 0xd8 >> 1, 0xda >> 1, I2C_CLIENT_END },
+               .encoder_addr = { 0x88 >> 1, I2C_CLIENT_END },
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 10,
@@ -739,69 +743,6 @@ zoran_i2c_setscl (void *data,
        btwrite(zr->i2cbr, ZR36057_I2CBR);
 }
 
-static int
-zoran_i2c_client_register (struct i2c_client *client)
-{
-       struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
-       int res = 0;
-
-       dprintk(2,
-               KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
-               ZR_DEVNAME(zr), client->driver->id);
-
-       mutex_lock(&zr->resource_lock);
-
-       if (zr->user > 0) {
-               /* we're already busy, so we keep a reference to
-                * them... Could do a lot of stuff here, but this
-                * is easiest. (Did I ever mention I'm a lazy ass?)
-                */
-               res = -EBUSY;
-               goto clientreg_unlock_and_return;
-       }
-
-       if (client->driver->id == zr->card.i2c_decoder)
-               zr->decoder = client;
-       else if (client->driver->id == zr->card.i2c_encoder)
-               zr->encoder = client;
-       else {
-               res = -ENODEV;
-               goto clientreg_unlock_and_return;
-       }
-
-clientreg_unlock_and_return:
-       mutex_unlock(&zr->resource_lock);
-
-       return res;
-}
-
-static int
-zoran_i2c_client_unregister (struct i2c_client *client)
-{
-       struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
-       int res = 0;
-
-       dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
-
-       mutex_lock(&zr->resource_lock);
-
-       if (zr->user > 0) {
-               res = -EBUSY;
-               goto clientunreg_unlock_and_return;
-       }
-
-       /* try to locate it */
-       if (client == zr->encoder) {
-               zr->encoder = NULL;
-       } else if (client == zr->decoder) {
-               zr->decoder = NULL;
-               snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", 
zr->id);
-       }
-clientunreg_unlock_and_return:
-       mutex_unlock(&zr->resource_lock);
-       return res;
-}
-
 static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
        .setsda = zoran_i2c_setsda,
        .setscl = zoran_i2c_setscl,
@@ -814,23 +755,56 @@ static const struct i2c_algo_bit_data zo
 static int
 zoran_register_i2c (struct zoran *zr)
 {
+       struct i2c_board_info info;
+       int err;
+
        memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
               sizeof(struct i2c_algo_bit_data));
        zr->i2c_algo.data = zr;
-       zr->i2c_adapter.id = I2C_HW_B_ZR36067;
-       zr->i2c_adapter.client_register = zoran_i2c_client_register;
-       zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
        strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
                sizeof(zr->i2c_adapter.name));
        i2c_set_adapdata(&zr->i2c_adapter, zr);
        zr->i2c_adapter.algo_data = &zr->i2c_algo;
        zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
-       return i2c_bit_add_bus(&zr->i2c_adapter);
+
+       err = i2c_bit_add_bus(&zr->i2c_adapter);
+       if (err)
+               return err;
+
+       mutex_lock(&zr->resource_lock);
+       /* register the decoder */
+       if (zr->card.i2c_decoder) {
+               memset(&info, 0, sizeof(struct i2c_board_info));
+               strlcpy(info.type, zr->card.i2c_decoder, I2C_NAME_SIZE);
+               zr->decoder = i2c_new_probed_device(&zr->i2c_adapter, &info,
+                                                   zr->card.decoder_addr);
+       }
+       /* register the encoder */
+       if (zr->card.i2c_encoder) {
+               memset(&info, 0, sizeof(struct i2c_board_info));
+               strlcpy(info.type, zr->card.i2c_encoder, I2C_NAME_SIZE);
+               zr->encoder = i2c_new_probed_device(&zr->i2c_adapter, &info,
+                                                   zr->card.encoder_addr);
+       }
+       mutex_unlock(&zr->resource_lock);
+
+       return 0;
 }
 
 static void
 zoran_unregister_i2c (struct zoran *zr)
 {
+       mutex_lock(&zr->resource_lock);
+       if (zr->decoder) {
+               i2c_unregister_device(zr->decoder);
+               zr->decoder = NULL;
+       }
+       if (zr->encoder) {
+               i2c_unregister_device(zr->encoder);
+               zr->encoder = NULL;
+       }
+       mutex_unlock(&zr->resource_lock);
+
        i2c_del_adapter(&zr->i2c_adapter);
 }
 
@@ -1423,7 +1397,7 @@ find_zr36057 (void)
                        ZR_DEVNAME(zr));
 
                /* i2c decoder */
-               if (decoder[zr->id] != -1) {
+               if (decoder[zr->id]) {
                        i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
                        zr->card.i2c_decoder = decoder[zr->id];
                } else if (zr->card.i2c_decoder != 0) {
@@ -1443,7 +1417,7 @@ find_zr36057 (void)
                }
 
                /* i2c encoder */
-               if (encoder[zr->id] != -1) {
+               if (encoder[zr->id]) {
                        i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
                        zr->card.i2c_encoder = encoder[zr->id];
                } else if (zr->card.i2c_encoder != 0) {
--- linux-2.6.27-rc4.orig/drivers/media/video/adv7170.c 2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/adv7170.c      2008-08-21 
22:23:58.000000000 +0200
@@ -388,31 +388,24 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_adv7170;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-adv7170_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+adv7170_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       int i;
-       struct i2c_client *client;
-       struct adv7170 *encoder;
+       struct i2c_adapter *adapter = client->adapter;
        char *dname;
 
        dprintk(1,
                KERN_INFO
                "adv7170.c: detecting adv7170 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_adv7170;
        if ((client->addr == I2C_ADV7170 >> 1) ||
            (client->addr == (I2C_ADV7170 >> 1) + 1)) {
                dname = adv7170_name;
@@ -421,14 +414,22 @@ adv7170_detect_client (struct i2c_adapte
                dname = adv7171_name;
        } else {
                /* We should never get here!!! */
-               kfree(client);
-               return 0;
+               return -ENODEV;
        }
-       strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+       strlcpy(info->type, dname, I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+adv7170_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       int i;
+       struct adv7170 *encoder;
 
        encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
        if (encoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        encoder->norm = VIDEO_MODE_NTSC;
@@ -436,13 +437,6 @@ adv7170_detect_client (struct i2c_adapte
        encoder->enable = 1;
        i2c_set_clientdata(client, encoder);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(encoder);
-               return i;
-       }
-
        i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
        if (i >= 0) {
                i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
@@ -460,43 +454,37 @@ adv7170_detect_client (struct i2c_adapte
 }
 
 static int
-adv7170_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "adv7170.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
-}
-
-static int
-adv7170_detach_client (struct i2c_client *client)
+adv7170_remove(struct i2c_client *client)
 {
        struct adv7170 *encoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(encoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id adv7170_id[] = {
+       { "adv7170", 0 },
+       { "adv7171", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7170_id);
+
 static struct i2c_driver i2c_driver_adv7170 = {
        .driver = {
                .name = "adv7170",      /* name */
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_ADV7170,
 
-       .attach_adapter = adv7170_attach_adapter,
-       .detach_client = adv7170_detach_client,
+       .probe = adv7170_probe,
+       .remove = adv7170_remove,
+       .id_table = adv7170_id,
+       .detect = adv7170_detect,
+       .address_data = &addr_data,
        .command = adv7170_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/adv7175.c 2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/adv7175.c      2008-08-21 
22:23:58.000000000 +0200
@@ -406,31 +406,24 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_adv7175;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-adv7175_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+adv7175_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       int i;
-       struct i2c_client *client;
-       struct adv7175 *encoder;
+       struct i2c_adapter *adapter = client->adapter;
        char *dname;
 
        dprintk(1,
                KERN_INFO
                "adv7175.c: detecting adv7175 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_adv7175;
        if ((client->addr == I2C_ADV7175 >> 1) ||
            (client->addr == (I2C_ADV7175 >> 1) + 1)) {
                dname = adv7175_name;
@@ -439,14 +432,22 @@ adv7175_detect_client (struct i2c_adapte
                dname = adv7176_name;
        } else {
                /* We should never get here!!! */
-               kfree(client);
-               return 0;
+               return -ENODEV;
        }
-       strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+       strlcpy(info->type, dname, I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+adv7175_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       int i;
+       struct adv7175 *encoder;
 
        encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
        if (encoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        encoder->norm = VIDEO_MODE_PAL;
@@ -454,13 +455,6 @@ adv7175_detect_client (struct i2c_adapte
        encoder->enable = 1;
        i2c_set_clientdata(client, encoder);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(encoder);
-               return i;
-       }
-
        i = adv7175_write_block(client, init_common, sizeof(init_common));
        if (i >= 0) {
                i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
@@ -478,43 +472,37 @@ adv7175_detect_client (struct i2c_adapte
 }
 
 static int
-adv7175_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "adv7175.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
-}
-
-static int
-adv7175_detach_client (struct i2c_client *client)
+adv7175_remove(struct i2c_client *client)
 {
        struct adv7175 *encoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(encoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id adv7175_id[] = {
+       { "adv7175", 0 },
+       { "adv7176", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7175_id);
+
 static struct i2c_driver i2c_driver_adv7175 = {
        .driver = {
                .name = "adv7175",      /* name */
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_ADV7175,
 
-       .attach_adapter = adv7175_attach_adapter,
-       .detach_client = adv7175_detach_client,
+       .probe = adv7175_probe,
+       .remove = adv7175_remove,
+       .id_table = adv7175_id,
+       .detect = adv7175_detect,
+       .address_data = &addr_data,
        .command = adv7175_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/bt819.c   2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/bt819.c        2008-08-21 
22:23:58.000000000 +0200
@@ -505,74 +505,70 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_bt819;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-bt819_detect_client (struct i2c_adapter *adapter,
-                    int                 address,
-                    int                 kind)
+bt819_detect(struct i2c_client     *client,
+            int                    kind,
+            struct i2c_board_info *info)
 {
-       int i, id;
-       struct bt819 *decoder;
-       struct i2c_client *client;
+       int id;
+       struct i2c_adapter *adapter = client->adapter;
+       const char *dname;
 
        dprintk(1,
                KERN_INFO
                "bt819: detecting bt819 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
-
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_bt819;
-
-       decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
-       if (decoder == NULL) {
-               kfree(client);
-               return -ENOMEM;
-       }
-       decoder->norm = VIDEO_MODE_NTSC;
-       decoder->input = 0;
-       decoder->enable = 1;
-       decoder->bright = 32768;
-       decoder->contrast = 32768;
-       decoder->hue = 32768;
-       decoder->sat = 32768;
-       decoder->initialized = 0;
-       i2c_set_clientdata(client, decoder);
+               return -ENODEV;
 
        id = bt819_read(client, 0x17);
        switch (id & 0xf0) {
        case 0x70:
-               strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
+               dname = "bt819a";
                break;
        case 0x60:
-               strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
+               dname = "bt817a";
                break;
        case 0x20:
-               strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
+               dname = "bt815a";
                break;
        default:
                dprintk(1,
                        KERN_ERR
                        "bt819: unknown chip version 0x%x (ver 0x%x)\n",
                        id & 0xf0, id & 0x0f);
-               kfree(decoder);
-               kfree(client);
-               return 0;
+               return -ENODEV;
        }
+       strlcpy(info->type, dname, I2C_NAME_SIZE);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(decoder);
-               return i;
+       return 0;
+}
+
+static int
+bt819_probe(struct i2c_client          *client,
+           const struct i2c_device_id *did)
+{
+       int id, i;
+       struct bt819 *decoder;
+
+       decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+       if (decoder == NULL) {
+               return -ENOMEM;
        }
+       decoder->norm = VIDEO_MODE_NTSC;
+       decoder->input = 0;
+       decoder->enable = 1;
+       decoder->bright = 32768;
+       decoder->contrast = 32768;
+       decoder->hue = 32768;
+       decoder->sat = 32768;
+       decoder->initialized = 0;
+       i2c_set_clientdata(client, decoder);
 
+       id = bt819_read(client, 0x17);
        i = bt819_init(client);
        if (i < 0) {
                dprintk(1, KERN_ERR "%s_attach: init status %d\n",
@@ -589,39 +585,38 @@ bt819_detect_client (struct i2c_adapter 
 }
 
 static int
-bt819_attach_adapter (struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, &bt819_detect_client);
-}
-
-static int
-bt819_detach_client (struct i2c_client *client)
+bt819_remove(struct i2c_client *client)
 {
        struct bt819 *decoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(decoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id bt819_id[] = {
+       { "bt819a", 0 },
+       { "bt817a", 0 },
+       { "bt815a", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, bt819_id);
+
 static struct i2c_driver i2c_driver_bt819 = {
        .driver = {
                .name = "bt819",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_BT819,
 
-       .attach_adapter = bt819_attach_adapter,
-       .detach_client = bt819_detach_client,
+       .probe = bt819_probe,
+       .remove = bt819_remove,
+       .id_table = bt819_id,
+       .detect = bt819_detect,
+       .address_data = &addr_data,
        .command = bt819_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/bt856.c   2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/bt856.c        2008-08-21 
22:23:58.000000000 +0200
@@ -292,48 +292,42 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_bt856;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-bt856_detect_client (struct i2c_adapter *adapter,
-                    int                 address,
-                    int                 kind)
+bt856_detect(struct i2c_client     *client,
+            int                    kind,
+            struct i2c_board_info *info)
 {
-       int i;
-       struct i2c_client *client;
-       struct bt856 *encoder;
+       struct i2c_adapter *adapter = client->adapter;
 
        dprintk(1,
                KERN_INFO
                "bt856.c: detecting bt856 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_bt856;
-       strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
+       strlcpy(info->type, "bt856", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+bt856_probe(struct i2c_client          *client,
+           const struct i2c_device_id *id)
+{
+       struct bt856 *encoder;
 
        encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
        if (encoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        encoder->norm = VIDEO_MODE_NTSC;
        encoder->enable = 1;
        i2c_set_clientdata(client, encoder);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(encoder);
-               return i;
-       }
-
        bt856_write(client, 0xdc, 0x18);
        bt856_write(client, 0xda, 0);
        bt856_write(client, 0xde, 0);
@@ -367,43 +361,36 @@ bt856_detect_client (struct i2c_adapter 
 }
 
 static int
-bt856_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "bt856.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &bt856_detect_client);
-}
-
-static int
-bt856_detach_client (struct i2c_client *client)
+bt856_remove(struct i2c_client *client)
 {
        struct bt856 *encoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(encoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id bt856_id[] = {
+       { "bt856", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, bt856_id);
+
 static struct i2c_driver i2c_driver_bt856 = {
        .driver = {
                .name = "bt856",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_BT856,
 
-       .attach_adapter = bt856_attach_adapter,
-       .detach_client = bt856_detach_client,
+       .probe = bt856_probe,
+       .remove = bt856_remove,
+       .id_table = bt856_id,
+       .detect = bt856_detect,
+       .address_data = &addr_data,
        .command = bt856_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/saa7110.c 2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/saa7110.c      2008-08-21 
22:23:58.000000000 +0200
@@ -467,37 +467,39 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_saa7110;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-saa7110_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+saa7110_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       struct i2c_client *client;
-       struct saa7110 *decoder;
-       int rv;
+       struct i2c_adapter *adapter = client->adapter;
 
        dprintk(1,
                KERN_INFO
                "saa7110.c: detecting saa7110 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality
            (adapter,
             I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_saa7110;
-       strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
+       strlcpy(info->type, "saa7110", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+saa7110_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       struct saa7110 *decoder;
+       int rv;
 
        decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
        if (!decoder) {
-               kfree(client);
                return -ENOMEM;
        }
        decoder->norm = VIDEO_MODE_PAL;
@@ -510,13 +512,6 @@ saa7110_detect_client (struct i2c_adapte
        init_waitqueue_head(&decoder->wq);
        i2c_set_clientdata(client, decoder);
 
-       rv = i2c_attach_client(client);
-       if (rv) {
-               kfree(client);
-               kfree(decoder);
-               return rv;
-       }
-
        rv = saa7110_write_block(client, initseq, sizeof(initseq));
        if (rv < 0)
                dprintk(1, KERN_ERR "%s_attach: init status %d\n",
@@ -548,43 +543,36 @@ saa7110_detect_client (struct i2c_adapte
 }
 
 static int
-saa7110_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "saa7110.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
-}
-
-static int
-saa7110_detach_client (struct i2c_client *client)
+saa7110_remove(struct i2c_client *client)
 {
        struct saa7110 *decoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(decoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id saa7110_id[] = {
+       { "saa7110", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7110_id);
+
 static struct i2c_driver i2c_driver_saa7110 = {
        .driver = {
                .name = "saa7110",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_SAA7110,
 
-       .attach_adapter = saa7110_attach_adapter,
-       .detach_client = saa7110_detach_client,
+       .probe = saa7110_probe,
+       .remove = saa7110_remove,
+       .id_table = saa7110_id,
+       .detect = saa7110_detect,
+       .address_data = &addr_data,
        .command = saa7110_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/saa7111.c 2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/saa7111.c      2008-08-21 
22:23:58.000000000 +0200
@@ -482,36 +482,47 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_saa7111;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-saa7111_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+saa7111_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
        int i;
-       struct i2c_client *client;
-       struct saa7111 *decoder;
-       struct video_decoder_init vdi;
+       const u8 id[6] = { 0x1, 0xf, 0x7, 0x1, 0x1, 0x1 };
+       struct i2c_adapter *adapter = client->adapter;
 
        dprintk(1,
                KERN_INFO
                "saa7111.c: detecting saa7111 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_saa7111;
-       strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
+       /* Make sure it's a SAA7111 chip */
+       for (i = 0; i < ARRAY_SIZE(id); i++) {
+               i2c_smbus_write_byte_data(client, 0, i);
+               if ((i2c_smbus_read_byte_data(client, 0) & 0xf) != id[i])
+                       return -ENODEV;
+       }
+
+       strlcpy(info->type, "saa7111_old", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+saa7111_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       int i;
+       struct saa7111 *decoder;
+       struct video_decoder_init vdi;
 
        decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
        if (decoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        decoder->norm = VIDEO_MODE_NTSC;
@@ -519,13 +530,6 @@ saa7111_detect_client (struct i2c_adapte
        decoder->enable = 1;
        i2c_set_clientdata(client, decoder);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(decoder);
-               return i;
-       }
-
        vdi.data = saa7111_i2c_init;
        vdi.len = sizeof(saa7111_i2c_init);
        i = saa7111_init_decoder(client, &vdi);
@@ -544,43 +548,36 @@ saa7111_detect_client (struct i2c_adapte
 }
 
 static int
-saa7111_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "saa7111.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
-}
-
-static int
-saa7111_detach_client (struct i2c_client *client)
+saa7111_remove(struct i2c_client *client)
 {
        struct saa7111 *decoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(decoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id saa7111_id[] = {
+       { "saa7111_old", 0 },   /* "saa7111" maps to the saa7115 driver */
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7111_id);
+
 static struct i2c_driver i2c_driver_saa7111 = {
        .driver = {
                .name = "saa7111",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_SAA7111A,
 
-       .attach_adapter = saa7111_attach_adapter,
-       .detach_client = saa7111_detach_client,
+       .probe = saa7111_probe,
+       .remove = saa7111_remove,
+       .id_table = saa7111_id,
+       .detect = saa7111_detect,
+       .address_data = &addr_data,
        .command = saa7111_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/saa7114.c 2008-08-21 
18:46:10.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/saa7114.c      2008-08-21 
22:23:58.000000000 +0200
@@ -818,39 +818,50 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_saa7114;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-saa7114_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+saa7114_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       int i, err[30];
-       short int hoff = SAA_7114_NTSC_HOFFSET;
-       short int voff = SAA_7114_NTSC_VOFFSET;
-       short int w = SAA_7114_NTSC_WIDTH;
-       short int h = SAA_7114_NTSC_HEIGHT;
-       struct i2c_client *client;
-       struct saa7114 *decoder;
+       int i;
+       const u8 id[6] = { 0x1, 0xf, 0x7, 0x1, 0x1, 0x4 };
+       struct i2c_adapter *adapter = client->adapter;
 
        dprintk(1,
                KERN_INFO
                "saa7114.c: detecting saa7114 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_saa7114;
-       strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
+       /* Make sure it's a SAA7114 chip */
+       for (i = 0; i < ARRAY_SIZE(id); i++) {
+               i2c_smbus_write_byte_data(client, 0, i);
+               if ((i2c_smbus_read_byte_data(client, 0) & 0xf) != id[i])
+                       return -ENODEV;
+       }
+
+       strlcpy(info->type, "saa7114_old", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+saa7114_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       int i, err[30];
+       short int hoff = SAA_7114_NTSC_HOFFSET;
+       short int voff = SAA_7114_NTSC_VOFFSET;
+       short int w = SAA_7114_NTSC_WIDTH;
+       short int h = SAA_7114_NTSC_HEIGHT;
+       struct saa7114 *decoder;
 
        decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
        if (decoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        decoder->norm = VIDEO_MODE_NTSC;
@@ -967,7 +978,6 @@ saa7114_detect_client (struct i2c_adapte
                                "%s_attach: init error %d at stage %d, leaving 
attach.\n",
                                I2C_NAME(client), i, err[i]);
                        kfree(decoder);
-                       kfree(client);
                        return 0;
                }
        }
@@ -996,7 +1006,6 @@ saa7114_detect_client (struct i2c_adapte
                                "%s_attach: init error %d at stage %d, leaving 
attach.\n",
                                I2C_NAME(client), i, err[i]);
                        kfree(decoder);
-                       kfree(client);
                        return 0;
                }
        }
@@ -1044,7 +1053,6 @@ saa7114_detect_client (struct i2c_adapte
                                "%s_attach: init error %d at stage %d, leaving 
attach.\n",
                                I2C_NAME(client), i, err[i]);
                        kfree(decoder);
-                       kfree(client);
                        return 0;
                }
        }
@@ -1085,7 +1093,6 @@ saa7114_detect_client (struct i2c_adapte
                                "%s_attach: init error %d at stage %d, leaving 
attach.\n",
                                I2C_NAME(client), i, err[i]);
                        kfree(decoder);
-                       kfree(client);
                        return 0;
                }
        }
@@ -1107,7 +1114,6 @@ saa7114_detect_client (struct i2c_adapte
                                "%s_attach: init error %d at stage %d, leaving 
attach.\n",
                                I2C_NAME(client), i, err[i]);
                        kfree(decoder);
-                       kfree(client);
                        return 0;
                }
        }
@@ -1136,13 +1142,6 @@ saa7114_detect_client (struct i2c_adapte
                        decoder->reg[REG_ADDR(i)]);
        }
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(decoder);
-               return i;
-       }
-
        //i = saa7114_write_block(client, init, sizeof(init));
        i = 0;
        if (i < 0) {
@@ -1160,43 +1159,36 @@ saa7114_detect_client (struct i2c_adapte
 }
 
 static int
-saa7114_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "saa7114.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
-}
-
-static int
-saa7114_detach_client (struct i2c_client *client)
+saa7114_remove(struct i2c_client *client)
 {
        struct saa7114 *decoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(decoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id saa7114_id[] = {
+       { "saa7114_old", 0 },   /* "saa7114" maps to the saa7115 driver */
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7114_id);
+
 static struct i2c_driver i2c_driver_saa7114 = {
        .driver = {
                .name = "saa7114",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_SAA7114,
 
-       .attach_adapter = saa7114_attach_adapter,
-       .detach_client = saa7114_detach_client,
+       .probe = saa7114_probe,
+       .remove = saa7114_remove,
+       .id_table = saa7114_id,
+       .detect = saa7114_detect,
+       .address_data = &addr_data,
        .command = saa7114_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/saa7185.c 2008-08-21 
18:46:10.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/saa7185.c      2008-08-21 
22:23:58.000000000 +0200
@@ -384,48 +384,48 @@ static struct i2c_client_address_data ad
 
 static struct i2c_driver i2c_driver_saa7185;
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-saa7185_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+saa7185_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       int i;
-       struct i2c_client *client;
-       struct saa7185 *encoder;
+       struct i2c_adapter *adapter = client->adapter;
 
        dprintk(1,
                KERN_INFO
                "saa7185.c: detecting saa7185 client on address 0x%x\n",
-               address << 1);
+               client->addr << 1);
 
        /* Check if the adapter supports the needed features */
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return 0;
+       if (!i2c_check_functionality(adapter,
+                                    I2C_FUNC_SMBUS_WRITE_BYTE_DATA
+                                    | I2C_FUNC_SMBUS_READ_BYTE))
+               return -ENODEV;
 
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!client)
-               return -ENOMEM;
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &i2c_driver_saa7185;
-       strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
+       if ((i2c_smbus_read_byte(client) >> 5) > 4)
+               return -ENODEV;
+
+       strlcpy(info->type, "saa7185", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+saa7185_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       int i;
+       struct saa7185 *encoder;
 
        encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
        if (encoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        encoder->norm = VIDEO_MODE_NTSC;
        encoder->enable = 1;
        i2c_set_clientdata(client, encoder);
 
-       i = i2c_attach_client(client);
-       if (i) {
-               kfree(client);
-               kfree(encoder);
-               return i;
-       }
-
        i = saa7185_write_block(client, init_common, sizeof(init_common));
        if (i >= 0) {
                i = saa7185_write_block(client, init_ntsc,
@@ -446,46 +446,39 @@ saa7185_detect_client (struct i2c_adapte
 }
 
 static int
-saa7185_attach_adapter (struct i2c_adapter *adapter)
-{
-       dprintk(1,
-               KERN_INFO
-               "saa7185.c: starting probe for adapter %s (0x%x)\n",
-               I2C_NAME(adapter), adapter->id);
-       return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
-}
-
-static int
-saa7185_detach_client (struct i2c_client *client)
+saa7185_remove(struct i2c_client *client)
 {
        struct saa7185 *encoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40);       /* SW: 
output off is active */
        //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: 
color bar */
 
        kfree(encoder);
-       kfree(client);
 
        return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id saa7185_id[] = {
+       { "saa7185", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7185_id);
+
 static struct i2c_driver i2c_driver_saa7185 = {
        .driver = {
                .name = "saa7185",      /* name */
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_SAA7185B,
 
-       .attach_adapter = saa7185_attach_adapter,
-       .detach_client = saa7185_detach_client,
+       .probe = saa7185_probe,
+       .remove = saa7185_remove,
+       .id_table = saa7185_id,
+       .detect = saa7185_detect,
+       .address_data = &addr_data,
        .command = saa7185_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/vpx3220.c 2008-08-21 
18:46:10.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/vpx3220.c      2008-08-21 
22:23:58.000000000 +0200
@@ -589,93 +589,82 @@ static struct i2c_client_address_data ad
 static struct i2c_driver vpx3220_i2c_driver;
 
 static int
-vpx3220_detach_client (struct i2c_client *client)
+vpx3220_remove(struct i2c_client *client)
 {
        struct vpx3220 *decoder = i2c_get_clientdata(client);
-       int err;
-
-       err = i2c_detach_client(client);
-       if (err) {
-               return err;
-       }
 
        kfree(decoder);
-       kfree(client);
 
        return 0;
 }
 
+/* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-vpx3220_detect_client (struct i2c_adapter *adapter,
-                      int                 address,
-                      int                 kind)
+vpx3220_detect(struct i2c_client     *client,
+              int                    kind,
+              struct i2c_board_info *info)
 {
-       int err;
-       struct i2c_client *client;
-       struct vpx3220 *decoder;
+       struct i2c_adapter *adapter = client->adapter;
+       const char *dname;
 
        dprintk(1, VPX3220_DEBUG "%s\n", __func__);
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality
            (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
-               return 0;
-
-       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == NULL) {
-               return -ENOMEM;
-       }
-
-       client->addr = address;
-       client->adapter = adapter;
-       client->driver = &vpx3220_i2c_driver;
+               return -ENODEV;
 
        /* Check for manufacture ID and part number */
        if (kind < 0) {
                u8 id;
                u16 pn;
 
-               id = vpx3220_read(client, 0x00);
+               id = i2c_smbus_read_byte_data(client, 0x00);
                if (id != 0xec) {
                        dprintk(1,
                                KERN_INFO
                                "vpx3220_attach: Wrong manufacturer ID 
(0x%02x)\n",
                                id);
-                       kfree(client);
-                       return 0;
+                       return -ENODEV;
                }
 
-               pn = (vpx3220_read(client, 0x02) << 8) +
-                   vpx3220_read(client, 0x01);
+               pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
+                   i2c_smbus_read_byte_data(client, 0x01);
                switch (pn) {
                case 0x4680:
-                       strlcpy(I2C_NAME(client), "vpx3220a",
-                               sizeof(I2C_NAME(client)));
+                       dname = "vpx3220a";
                        break;
                case 0x4260:
-                       strlcpy(I2C_NAME(client), "vpx3216b",
-                               sizeof(I2C_NAME(client)));
+                       dname = "vpx3216b";
                        break;
                case 0x4280:
-                       strlcpy(I2C_NAME(client), "vpx3214c",
-                               sizeof(I2C_NAME(client)));
+                       dname = "vpx3214c";
                        break;
                default:
                        dprintk(1,
                                KERN_INFO
                                "%s: Wrong part number (0x%04x)\n",
                                __func__, pn);
-                       kfree(client);
-                       return 0;
+                       return -ENODEV;
                }
        } else {
-               strlcpy(I2C_NAME(client), "forced vpx32xx",
-                       sizeof(I2C_NAME(client)));
+               /* Can't actually happen */
+               return -ENODEV;
        }
 
+       strlcpy(info->type, dname, I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int
+vpx3220_probe(struct i2c_client          *client,
+             const struct i2c_device_id *id)
+{
+       struct vpx3220 *decoder;
+
        decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
        if (decoder == NULL) {
-               kfree(client);
                return -ENOMEM;
        }
        decoder->norm = VIDEO_MODE_PAL;
@@ -687,13 +676,6 @@ vpx3220_detect_client (struct i2c_adapte
        decoder->sat = 32768;
        i2c_set_clientdata(client, decoder);
 
-       err = i2c_attach_client(client);
-       if (err) {
-               kfree(client);
-               kfree(decoder);
-               return err;
-       }
-
        dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
                I2C_NAME(client), client->addr << 1);
 
@@ -702,30 +684,31 @@ vpx3220_detect_client (struct i2c_adapte
        return 0;
 }
 
-static int
-vpx3220_attach_adapter (struct i2c_adapter *adapter)
-{
-       int ret;
-
-       ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
-       dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
-               __func__, ret);
-       return ret;
-}
-
 /* -----------------------------------------------------------------------
  * Driver initialization and cleanup code
  */
 
+static const struct i2c_device_id vpx3220_id[] = {
+       { "vpx3220a", 0 },
+       { "vpx3216b", 0 },
+       { "vpx3214c", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, vpx3220_id);
+
 static struct i2c_driver vpx3220_i2c_driver = {
        .driver = {
                .name = "vpx3220",
        },
 
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_VPX3220,
 
-       .attach_adapter = vpx3220_attach_adapter,
-       .detach_client = vpx3220_detach_client,
+       .probe = vpx3220_probe,
+       .remove = vpx3220_remove,
+       .id_table = vpx3220_id,
+       .detect = vpx3220_detect,
+       .address_data = &addr_data,
        .command = vpx3220_command,
 };
 
--- linux-2.6.27-rc4.orig/drivers/media/video/bt866.c   2008-08-21 
18:46:10.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/bt866.c        2008-08-21 
22:23:58.000000000 +0200
@@ -268,8 +268,11 @@ static int bt866_write(struct bt866 *enc
        return 0;
 }
 
-static int bt866_attach(struct i2c_adapter *adapter);
-static int bt866_detach(struct i2c_client *client);
+static int bt866_detect(struct i2c_client *client, int kind,
+                       struct i2c_board_info *info);
+static int bt866_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id);
+static int bt866_remove(struct i2c_client *client);
 static int bt866_command(struct i2c_client *client,
                         unsigned int cmd, void *arg);
 
@@ -285,70 +288,65 @@ static struct i2c_client_address_data ad
        ignore,
 };
 
+static const struct i2c_device_id bt866_id[] = {
+       { "bt866", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, bt866_id);
+
 static struct i2c_driver i2c_driver_bt866 = {
        .driver.name = BT866_DEVNAME,
+       .class = I2C_CLASS_TV_ANALOG,
        .id = I2C_DRIVERID_BT866,
-       .attach_adapter = bt866_attach,
-       .detach_client = bt866_detach,
+       .probe = bt866_probe,
+       .remove = bt866_remove,
+       .id_table = bt866_id,
+       .detect = bt866_detect,
+       .address_data = &addr_data,
        .command = bt866_command
 };
 
 
-static struct i2c_client bt866_client_tmpl =
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int bt866_detect(struct i2c_client *client, int kind,
+                       struct i2c_board_info *info)
 {
-       .name = "(nil)",
-       .addr = 0,
-       .adapter = NULL,
-       .driver = &i2c_driver_bt866,
-};
+       struct i2c_adapter *adapter = client->adapter;
+
+       if (adapter->id != I2C_HW_B_ZR36067)
+               return -ENODEV;
+
+       /* Check if the adapter supports the needed features */
+       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+               return -ENODEV;
+
+       strlcpy(info->type, "bt866", I2C_NAME_SIZE);
+
+       return 0;
+}
 
-static int bt866_found_proc(struct i2c_adapter *adapter,
-                           int addr, int kind)
+static int bt866_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id)
 {
        struct bt866 *encoder;
-       struct i2c_client *client;
-
-       client = kzalloc(sizeof(*client), GFP_KERNEL);
-       if (client == NULL)
-               return -ENOMEM;
-       memcpy(client, &bt866_client_tmpl, sizeof(*client));
 
        encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
-       if (encoder == NULL) {
-               kfree(client);
+       if (encoder == NULL)
                return -ENOMEM;
-       }
 
        i2c_set_clientdata(client, encoder);
-       client->adapter = adapter;
-       client->addr = addr;
-       sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
-
        encoder->i2c = client;
-       encoder->addr = addr;
+       encoder->addr = client->addr;
        //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
 
-       /* initialize */
-
-       i2c_attach_client(client);
-
-       return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter)
-{
-       if (adapter->id == I2C_HW_B_ZR36067)
-               return i2c_probe(adapter, &addr_data, bt866_found_proc);
        return 0;
 }
 
-static int bt866_detach(struct i2c_client *client)
+static int bt866_remove(struct i2c_client *client)
 {
        struct bt866 *encoder = i2c_get_clientdata(client);
 
-       i2c_detach_client(client);
        kfree(encoder);
-       kfree(client);
 
        return 0;
 }
--- linux-2.6.27-rc4.orig/drivers/media/video/ks0127.c  2008-08-21 
18:46:10.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/ks0127.c       2008-08-21 
22:23:58.000000000 +0200
@@ -732,8 +732,11 @@ static int ks0127_command(struct i2c_cli
 
 
 
-static int ks0127_probe(struct i2c_adapter *adapter);
-static int ks0127_detach(struct i2c_client *client);
+static int ks0127_detect(struct i2c_client *client, int kind,
+                        struct i2c_board_info *info);
+static int ks0127_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id);
+static int ks0127_remove(struct i2c_client *client);
 static int ks0127_command(struct i2c_client *client,
                          unsigned int cmd, void *arg);
 
@@ -750,45 +753,54 @@ static struct i2c_client_address_data ad
        ignore,
 };
 
+static const struct i2c_device_id ks0127_id[] = {
+       { "ks0127", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ks0127_id);
+
 static struct i2c_driver i2c_driver_ks0127 = {
        .driver.name = "ks0127",
+       .class          = I2C_CLASS_TV_ANALOG,
        .id             = I2C_DRIVERID_KS0127,
-       .attach_adapter = ks0127_probe,
-       .detach_client  = ks0127_detach,
+       .probe          = ks0127_probe,
+       .remove         = ks0127_remove,
+       .id_table       = ks0127_id,
+       .detect         = ks0127_detect,
+       .address_data   = &addr_data,
        .command        = ks0127_command
 };
 
-static struct i2c_client ks0127_client_tmpl =
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int ks0127_detect(struct i2c_client *client, int kind,
+                        struct i2c_board_info *info)
 {
-       .name = "(ks0127 unset)",
-       .addr = 0,
-       .adapter = NULL,
-       .driver = &i2c_driver_ks0127,
-};
+       struct i2c_adapter *adapter = client->adapter;
+
+       if (adapter->id != I2C_HW_B_ZR36067)
+               return -ENODEV;
+
+       /* Check if the adapter supports the needed features */
+       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+               return -ENODEV;
+
+       strlcpy(info->type, "ks0127", I2C_NAME_SIZE);
+
+       return 0;
+}
 
-static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
+static int ks0127_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
 {
        struct ks0127 *ks;
-       struct i2c_client *client;
-
-       client = kzalloc(sizeof(*client), GFP_KERNEL);
-       if (client == NULL)
-               return -ENOMEM;
-       memcpy(client, &ks0127_client_tmpl, sizeof(*client));
 
        ks = kzalloc(sizeof(*ks), GFP_KERNEL);
-       if (ks == NULL) {
-               kfree(client);
+       if (ks == NULL)
                return -ENOMEM;
-       }
 
        i2c_set_clientdata(client, ks);
-       client->adapter = adapter;
-       client->addr = addr;
-       sprintf(client->name, "ks0127-%02x", adapter->id);
-
        ks->client = client;
-       ks->addr = addr;
+       ks->addr = client->addr;
        ks->ks_type = KS_TYPE_UNKNOWN;
 
        /* power up */
@@ -800,28 +812,17 @@ static int ks0127_found_proc(struct i2c_
        printk(KERN_INFO "ks0127: attach: %s video decoder\n",
               ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
 
-       i2c_attach_client(client);
-       return 0;
-}
-
-
-static int ks0127_probe(struct i2c_adapter *adapter)
-{
-       if (adapter->id == I2C_HW_B_ZR36067)
-               return i2c_probe(adapter, &addr_data, ks0127_found_proc);
        return 0;
 }
 
-static int ks0127_detach(struct i2c_client *client)
+static int ks0127_remove(struct i2c_client *client)
 {
        struct ks0127 *ks = i2c_get_clientdata(client);
 
        ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
        ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
 
-       i2c_detach_client(client);
        kfree(ks);
-       kfree(client);
 
        dprintk("ks0127: detach\n");
        return 0;
--- linux-2.6.27-rc4.orig/drivers/media/video/zoran.h   2008-08-21 
18:46:11.000000000 +0200
+++ linux-2.6.27-rc4/drivers/media/video/zoran.h        2008-08-21 
22:23:58.000000000 +0200
@@ -346,7 +346,8 @@ struct zoran_fh {
 struct card_info {
        enum card_type type;
        char name[32];
-       u16 i2c_decoder, i2c_encoder;                   /* I2C types */
+       const char *i2c_decoder, *i2c_encoder;          /* I2C chip names */
+       unsigned short decoder_addr[3], encoder_addr[3];
        u16 video_vfe, video_codec;                     /* videocodec types */
        u16 audio_chip;                                 /* audio type */
        u16 vendor_id, device_id;       /* subsystem vendor/device ID */


-- 
Jean Delvare

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Mjpeg-users mailing list
Mjpeg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mjpeg-users

Reply via email to