]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/zoran/zoran_card.c
V4L/DVB (10931): zoran: Drop the lock_norm module parameter
[linux-2.6-omap-h63xx.git] / drivers / media / video / zoran / zoran_card.c
index 5d2f090aa0f82c12aa3adec4daed69bffea4d63a..3ffdbe34ecc17785b5ac2b511d80de85ce2bde7d 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/spinlock.h>
 #include <linux/sem.h>
@@ -47,8 +47,6 @@
 
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
 #include <linux/mutex.h>
 
 #include <asm/io.h>
@@ -108,25 +106,8 @@ static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(video_nr, int, NULL, 0444);
 MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
 
-/*
-   Number and size of grab buffers for Video 4 Linux
-   The vast majority of applications should not need more than 2,
-   the very popular BTTV driver actually does ONLY have 2.
-   Time sensitive applications might need more, the maximum
-   is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
-
-   The size is set so that the maximum possible request
-   can be satisfied. Decrease  it, if bigphys_area alloc'd
-   memory is low. If you don't have the bigphys_area patch,
-   set it to 128 KB. Will you allow only to grab small
-   images with V4L, but that's better than nothing.
-
-   v4l_bufsize has to be given in KB !
-
-*/
-
-int v4l_nbufs = 2;
-int v4l_bufsize = 128;         /* Everybody should be able to work with this setting */
+int v4l_nbufs = 4;
+int v4l_bufsize = 864;         /* Everybody should be able to work with this setting */
 module_param(v4l_nbufs, int, 0644);
 MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
 module_param(v4l_bufsize, int, 0644);
@@ -331,50 +312,6 @@ avs6eyes_init (struct zoran *zr)
 
 }
 
-static char *
-i2cid_to_modulename (u16 i2c_id)
-{
-       char *name = NULL;
-
-       switch (i2c_id) {
-       case I2C_DRIVERID_SAA7110:
-               name = "saa7110";
-               break;
-       case I2C_DRIVERID_SAA7111A:
-               name = "saa7111";
-               break;
-       case I2C_DRIVERID_SAA7114:
-               name = "saa7114";
-               break;
-       case I2C_DRIVERID_SAA7185B:
-               name = "saa7185";
-               break;
-       case I2C_DRIVERID_ADV7170:
-               name = "adv7170";
-               break;
-       case I2C_DRIVERID_ADV7175:
-               name = "adv7175";
-               break;
-       case I2C_DRIVERID_BT819:
-               name = "bt819";
-               break;
-       case I2C_DRIVERID_BT856:
-               name = "bt856";
-               break;
-       case I2C_DRIVERID_BT866:
-               name = "bt866";
-               break;
-       case I2C_DRIVERID_VPX3220:
-               name = "vpx3220";
-               break;
-       case I2C_DRIVERID_KS0127:
-               name = "ks0127";
-               break;
-       }
-
-       return name;
-}
-
 static char *
 codecid_to_modulename (u16 codecid)
 {
@@ -425,11 +362,24 @@ static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }
 static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
 static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
 
+static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
+static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
+static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
+static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
+static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
+static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
+static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
+static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
+
 static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        {
                .type = DC10_old,
                .name = "DC10(old)",
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
+               .i2c_decoder = "vpx3220a",
+               .mod_decoder = "vpx3220",
+               .addrs_decoder = vpx3220_addrs,
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -439,7 +389,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 2, "S-Video" },
                        { 0, "Internal/comp" }
                },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                        &f50sqpixel_dc10,
                        &f60sqpixel_dc10,
@@ -457,8 +407,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = DC10_new,
                .name = "DC10(new)",
-               .i2c_decoder = I2C_DRIVERID_SAA7110,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "saa7110",
+               .mod_decoder = "saa7110",
+               .addrs_decoder = saa7110_addrs,
+               .i2c_encoder = "adv7175",
+               .mod_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 3,
@@ -467,7 +421,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                                { 7, "S-Video" },
                                { 5, "Internal/comp" }
                        },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                                &f50sqpixel,
                                &f60sqpixel,
@@ -484,8 +438,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = DC10plus,
                .name = "DC10plus",
-               .i2c_decoder = I2C_DRIVERID_SAA7110,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "saa7110",
+               .mod_decoder = "saa7110",
+               .addrs_decoder = saa7110_addrs,
+               .i2c_encoder = "adv7175",
+               .mod_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 3,
@@ -494,7 +452,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 7, "S-Video" },
                        { 5, "Internal/comp" }
                },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                        &f50sqpixel,
                        &f60sqpixel,
@@ -512,8 +470,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = DC30,
                .name = "DC30",
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "vpx3220a",
+               .mod_decoder = "vpx3220",
+               .addrs_decoder = vpx3220_addrs,
+               .i2c_encoder = "adv7175",
+               .mod_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -523,7 +485,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 2, "S-Video" },
                        { 0, "Internal/comp" }
                },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                        &f50sqpixel_dc10,
                        &f60sqpixel_dc10,
@@ -541,8 +503,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = DC30plus,
                .name = "DC30plus",
-               .i2c_decoder = I2C_DRIVERID_VPX3220,
-               .i2c_encoder = I2C_DRIVERID_ADV7175,
+               .i2c_decoder = "vpx3220a",
+               .mod_decoder = "vpx3220",
+               .addrs_decoder = vpx3220_addrs,
+               .i2c_encoder = "adv7175",
+               .mod_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
                .video_codec = CODEC_TYPE_ZR36050,
                .video_vfe = CODEC_TYPE_ZR36016,
 
@@ -552,7 +518,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 2, "S-Video" },
                        { 0, "Internal/comp" }
                },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                        &f50sqpixel_dc10,
                        &f60sqpixel_dc10,
@@ -570,8 +536,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = LML33,
                .name = "LML33",
-               .i2c_decoder = I2C_DRIVERID_BT819,
-               .i2c_encoder = I2C_DRIVERID_BT856,
+               .i2c_decoder = "bt819a",
+               .mod_decoder = "bt819",
+               .addrs_decoder = bt819_addrs,
+               .i2c_encoder = "bt856",
+               .mod_encoder = "bt856",
+               .addrs_encoder = bt856_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -579,7 +549,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 0, "Composite" },
                        { 7, "S-Video" }
                },
-               .norms = 2,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
                .tvn = {
                        &f50ccir601_lml33,
                        &f60ccir601_lml33,
@@ -597,8 +567,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = LML33R10,
                .name = "LML33R10",
-               .i2c_decoder = I2C_DRIVERID_SAA7114,
-               .i2c_encoder = I2C_DRIVERID_ADV7170,
+               .i2c_decoder = "saa7114",
+               .mod_decoder = "saa7115",
+               .addrs_decoder = saa7114_addrs,
+               .i2c_encoder = "adv7170",
+               .mod_encoder = "adv7170",
+               .addrs_encoder = adv717x_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -606,7 +580,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 0, "Composite" },
                        { 7, "S-Video" }
                },
-               .norms = 2,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
                .tvn = {
                        &f50ccir601_lm33r10,
                        &f60ccir601_lm33r10,
@@ -624,8 +598,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
        }, {
                .type = BUZ,
                .name = "Buz",
-               .i2c_decoder = I2C_DRIVERID_SAA7111A,
-               .i2c_encoder = I2C_DRIVERID_SAA7185B,
+               .i2c_decoder = "saa7111",
+               .mod_decoder = "saa7115",
+               .addrs_decoder = saa7111_addrs,
+               .i2c_encoder = "saa7185",
+               .mod_encoder = "saa7185",
+               .addrs_encoder = saa7185_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 2,
@@ -633,7 +611,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        { 3, "Composite" },
                        { 7, "S-Video" }
                },
-               .norms = 3,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
                .tvn = {
                        &f50ccir601,
                        &f60ccir601,
@@ -653,8 +631,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                .name = "6-Eyes",
                /* AverMedia chose not to brand the 6-Eyes. Thus it
                   can't be autodetected, and requires card=x. */
-               .i2c_decoder = I2C_DRIVERID_KS0127,
-               .i2c_encoder = I2C_DRIVERID_BT866,
+               .i2c_decoder = "ks0127",
+               .mod_decoder = "ks0127",
+               .addrs_decoder = ks0127_addrs,
+               .i2c_encoder = "bt866",
+               .mod_encoder = "bt866",
+               .addrs_encoder = bt866_addrs,
                .video_codec = CODEC_TYPE_ZR36060,
 
                .inputs = 10,
@@ -670,7 +652,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
                        {10, "S-Video 3" },
                        {15, "YCbCr" }
                },
-               .norms = 2,
+               .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
                .tvn = {
                        &f50ccir601_avs6eyes,
                        &f60ccir601_avs6eyes,
@@ -735,69 +717,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,
@@ -813,13 +732,10 @@ zoran_register_i2c (struct zoran *zr)
        memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
               sizeof(struct i2c_algo_bit_data));
        zr->i2c_algo.data = zr;
-       zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
        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);
+       i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
        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);
@@ -835,7 +751,8 @@ zoran_unregister_i2c (struct zoran *zr)
 
 int
 zoran_check_jpg_settings (struct zoran              *zr,
-                         struct zoran_jpg_settings *settings)
+                         struct zoran_jpg_settings *settings,
+                         int try)
 {
        int err = 0, err0 = 0;
 
@@ -900,38 +817,61 @@ zoran_check_jpg_settings (struct zoran              *zr,
                /* We have to check the data the user has set */
 
                if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
-                   (zr->card.type == DC10_new || settings->HorDcm != 4))
+                   (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+                       settings->HorDcm = clamp(settings->HorDcm, 1, 2);
                        err0++;
-               if (settings->VerDcm != 1 && settings->VerDcm != 2)
+               }
+               if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+                       settings->VerDcm = clamp(settings->VerDcm, 1, 2);
                        err0++;
-               if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+               }
+               if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+                       settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
                        err0++;
+               }
                if (settings->field_per_buff != 1 &&
-                   settings->field_per_buff != 2)
+                   settings->field_per_buff != 2) {
+                       settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
+                       err0++;
+               }
+               if (settings->img_x < 0) {
+                       settings->img_x = 0;
+                       err0++;
+               }
+               if (settings->img_y < 0) {
+                       settings->img_y = 0;
                        err0++;
-               if (settings->img_x < 0)
+               }
+               if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
                        err0++;
-               if (settings->img_y < 0)
+               }
+               if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
                        err0++;
-               if (settings->img_width < 0)
+               }
+               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
                        err0++;
-               if (settings->img_height < 0)
+               }
+               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
                        err0++;
-               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+               }
+               if (settings->img_width % (16 * settings->HorDcm) != 0) {
+                       settings->img_width -= settings->img_width % (16 * settings->HorDcm);
+                       if (settings->img_width == 0)
+                               settings->img_width = 16 * settings->HorDcm;
                        err0++;
-               if (settings->img_y + settings->img_height >
-                   BUZ_MAX_HEIGHT / 2)
+               }
+               if (settings->img_height % (8 * settings->VerDcm) != 0) {
+                       settings->img_height -= settings->img_height % (8 * settings->VerDcm);
+                       if (settings->img_height == 0)
+                               settings->img_height = 8 * settings->VerDcm;
                        err0++;
-               if (settings->HorDcm && settings->VerDcm) {
-                       if (settings->img_width %
-                           (16 * settings->HorDcm) != 0)
-                               err0++;
-                       if (settings->img_height %
-                           (8 * settings->VerDcm) != 0)
-                               err0++;
                }
 
-               if (err0) {
+               if (!try && err0) {
                        dprintk(1,
                                KERN_ERR
                                "%s: check_jpg_settings() - error in params for decimation = 0\n",
@@ -1021,7 +961,7 @@ zoran_open_init_params (struct zoran *zr)
               sizeof(zr->jpg_settings.jpg_comp.COM_data));
        zr->jpg_settings.jpg_comp.jpeg_markers =
            JPEG_MARKER_DHT | JPEG_MARKER_DQT;
-       i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+       i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
        if (i)
                dprintk(1,
                        KERN_ERR
@@ -1062,8 +1002,6 @@ static int __devinit
 zr36057_init (struct zoran *zr)
 {
        int j, err;
-       int two = 2;
-       int zero = 0;
 
        dprintk(1,
                KERN_INFO
@@ -1079,24 +1017,32 @@ zr36057_init (struct zoran *zr)
        zr->jpg_buffers.allocated = 0;
        zr->v4l_buffers.allocated = 0;
 
-       zr->buffer.base = (void *) vidmem;
-       zr->buffer.width = 0;
-       zr->buffer.height = 0;
-       zr->buffer.depth = 0;
-       zr->buffer.bytesperline = 0;
+       zr->vbuf_base = (void *) vidmem;
+       zr->vbuf_width = 0;
+       zr->vbuf_height = 0;
+       zr->vbuf_depth = 0;
+       zr->vbuf_bytesperline = 0;
 
        /* Avoid nonsense settings from user for default input/norm */
-       if (default_norm < VIDEO_MODE_PAL &&
-           default_norm > VIDEO_MODE_SECAM)
-               default_norm = VIDEO_MODE_PAL;
-       zr->norm = default_norm;
-       if (!(zr->timing = zr->card.tvn[zr->norm])) {
+       if (default_norm < 0 && default_norm > 2)
+               default_norm = 0;
+       if (default_norm == 0) {
+               zr->norm = V4L2_STD_PAL;
+               zr->timing = zr->card.tvn[0];
+       } else if (default_norm == 1) {
+               zr->norm = V4L2_STD_NTSC;
+               zr->timing = zr->card.tvn[1];
+       } else {
+               zr->norm = V4L2_STD_SECAM;
+               zr->timing = zr->card.tvn[2];
+       }
+       if (zr->timing == NULL) {
                dprintk(1,
                        KERN_WARNING
                        "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
                        ZR_DEVNAME(zr));
-               zr->norm = VIDEO_MODE_PAL;
-               zr->timing = zr->card.tvn[zr->norm];
+               zr->norm = V4L2_STD_PAL;
+               zr->timing = zr->card.tvn[0];
        }
 
        if (default_input > zr->card.inputs-1) {
@@ -1108,12 +1054,6 @@ zr36057_init (struct zoran *zr)
        }
        zr->input = default_input;
 
-       /* Should the following be reset at every open ? */
-       zr->hue = 32768;
-       zr->contrast = 32768;
-       zr->saturation = 32768;
-       zr->brightness = 32768;
-
        /* default setup (will be repeated at every open) */
        zoran_open_init_params(zr);
 
@@ -1137,6 +1077,7 @@ zr36057_init (struct zoran *zr)
         *   Now add the template and register the device unit.
         */
        memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
+       zr->video_dev->parent = &zr->pci_dev->dev;
        strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
        err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
        if (err < 0)
@@ -1148,8 +1089,10 @@ zr36057_init (struct zoran *zr)
                detect_guest_activity(zr);
        test_interrupts(zr);
        if (!pass_through) {
-               decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
-               encoder_command(zr, ENCODER_SET_INPUT, &two);
+               struct v4l2_routing route = { 2, 0 };
+
+               decoder_call(zr, video, s_stream, 0);
+               encoder_call(zr, video, s_routing, &route);
        }
 
        zr->zoran_proc = NULL;
@@ -1164,7 +1107,8 @@ exit_free:
 
 static void __devexit zoran_remove(struct pci_dev *pdev)
 {
-       struct zoran *zr = pci_get_drvdata(pdev);
+       struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+       struct zoran *zr = to_zoran(v4l2_dev);
 
        if (!zr->initialized)
                goto exit_free;
@@ -1197,7 +1141,7 @@ static void __devexit zoran_remove(struct pci_dev *pdev)
        pci_disable_device(zr->pci_dev);
        video_unregister_device(zr->video_dev);
 exit_free:
-       pci_set_drvdata(pdev, NULL);
+       v4l2_device_unregister(&zr->v4l2_dev);
        kfree(zr);
 }
 
@@ -1269,7 +1213,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
        struct videocodec_master *master_vfe = NULL;
        struct videocodec_master *master_codec = NULL;
        int card_num;
-       char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+       char *codec_name, *vfe_name;
        unsigned int nr;
 
 
@@ -1290,13 +1234,15 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                        ZORAN_NAME);
                return -ENOMEM;
        }
+       if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
+               goto zr_free_mem;
        zr->pci_dev = pdev;
        zr->id = nr;
        snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
        spin_lock_init(&zr->spinlock);
        mutex_init(&zr->resource_lock);
        if (pci_enable_device(pdev))
-               goto zr_free_mem;
+               goto zr_unreg;
        pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
 
        dprintk(1,
@@ -1323,7 +1269,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                                KERN_ERR
                                "%s: It is not possible to auto-detect ZR36057 based cards\n",
                                ZR_DEVNAME(zr));
-                       goto zr_free_mem;
+                       goto zr_unreg;
                }
 
                card_num = ent->driver_data;
@@ -1332,7 +1278,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                                KERN_ERR
                                "%s: Unknown card, try specifying card=X module parameter\n",
                                ZR_DEVNAME(zr));
-                       goto zr_free_mem;
+                       goto zr_unreg;
                }
                dprintk(3,
                        KERN_DEBUG
@@ -1345,7 +1291,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                                KERN_ERR
                                "%s: User specified card type %d out of range (0 .. %d)\n",
                                ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
-                       goto zr_free_mem;
+                       goto zr_unreg;
                }
        }
 
@@ -1364,7 +1310,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                        KERN_ERR
                        "%s: %s() - ioremap failed\n",
                        ZR_DEVNAME(zr), __func__);
-               goto zr_free_mem;
+               goto zr_unreg;
        }
 
        result = request_irq(zr->pci_dev->irq, zoran_irq,
@@ -1407,46 +1353,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
        dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
                ZR_DEVNAME(zr));
 
-       /* i2c decoder */
-       if (decoder[zr->id] != -1) {
-               i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
-               zr->card.i2c_decoder = decoder[zr->id];
-       } else if (zr->card.i2c_decoder != 0) {
-               i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
-       } else {
-               i2c_dec_name = NULL;
-       }
-
-       if (i2c_dec_name) {
-               result = request_module(i2c_dec_name);
-               if (result < 0) {
-                       dprintk(1,
-                               KERN_ERR
-                               "%s: failed to load module %s: %d\n",
-                               ZR_DEVNAME(zr), i2c_dec_name, result);
-               }
-       }
-
-       /* i2c encoder */
-       if (encoder[zr->id] != -1) {
-               i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
-               zr->card.i2c_encoder = encoder[zr->id];
-       } else if (zr->card.i2c_encoder != 0) {
-               i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
-       } else {
-               i2c_enc_name = NULL;
-       }
-
-       if (i2c_enc_name) {
-               result = request_module(i2c_enc_name);
-               if (result < 0) {
-                       dprintk(1,
-                               KERN_ERR
-                               "%s: failed to load module %s: %d\n",
-                               ZR_DEVNAME(zr), i2c_enc_name, result);
-               }
-       }
-
        if (zoran_register_i2c(zr) < 0) {
                dprintk(1,
                        KERN_ERR
@@ -1455,6 +1361,14 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
                goto zr_free_irq;
        }
 
+       zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+               zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder);
+
+       if (zr->card.mod_encoder)
+               zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+                       zr->card.mod_encoder, zr->card.i2c_encoder,
+                       zr->card.addrs_encoder);
+
        dprintk(2,
                KERN_INFO "%s: Initializing videocodec bus...\n",
                ZR_DEVNAME(zr));
@@ -1544,8 +1458,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
 
        zoran_proc_init(zr);
 
-       pci_set_drvdata(pdev, zr);
-
        return 0;
 
 zr_detach_vfe:
@@ -1563,6 +1475,8 @@ zr_free_irq:
        free_irq(zr->pci_dev->irq, zr);
 zr_unmap:
        iounmap(zr->zr36057_mem);
+zr_unreg:
+       v4l2_device_unregister(&zr->v4l2_dev);
 zr_free_mem:
        kfree(zr);
 
@@ -1613,9 +1527,6 @@ static int __init zoran_init(void)
                        ZORAN_NAME, vidmem);
        }
 
-       /* random nonsense */
-       dprintk(6, KERN_DEBUG "Jotti is een held!\n");
-
        /* some mainboards might not do PCI-PCI data transfer well */
        if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
                dprintk(1,