if (0 != t->index)
                return -EINVAL;
        strcpy(t->name, "Television");
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+       call_all(dev, tuner, g_tuner, t);
 
        dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
 
                return -EINVAL;
 
        /* Update the A/V core */
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+       call_all(dev, tuner, s_tuner, t);
 
        return 0;
 }
        f->type = V4L2_TUNER_ANALOG_TV;
        f->frequency = dev->freq;
 
-       /* Assumption that tuner is always on bus 1 */
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+       call_all(dev, tuner, g_frequency, f);
 
        return 0;
 }
                return -EINVAL;
        dev->freq = f->frequency;
 
-       /* Assumption that tuner is always on bus 1 */
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+       call_all(dev, tuner, s_frequency, f);
 
        cx23885_initialize_codec(dev);
 
        struct cx23885_dev *dev = fh->dev;
 
        /* Update the A/V core */
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+       call_all(dev, core, s_ctrl, ctl);
        return 0;
 }
 
        printk(KERN_INFO
                "%s/2: ============  START LOG STATUS  ============\n",
               dev->name);
-       cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
-               NULL);
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
-               NULL);
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
-               NULL);
+       call_all(dev, core, log_status);
        cx2341x_log_status(&dev->mpeg_params, name);
        printk(KERN_INFO
                "%s/2: =============  END LOG STATUS  =============\n",
 
        case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
        case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
        case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
-               request_module("cx25840");
+               dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+                               "cx25840", "cx25840", 0x88 >> 1);
+               v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
                break;
        }
 
 
        cx23885_i2c_register(&dev->i2c_bus[1]);
        cx23885_i2c_register(&dev->i2c_bus[2]);
        cx23885_card_setup(dev);
-       cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+       call_all(dev, core, s_standby, 0);
        cx23885_ir_init(dev);
 
        if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
 
        fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
        /* Put the analog decoder in standby to keep it quiet */
-       cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+       call_all(dev, core, s_standby, 0);
 
        if (fe0->dvb.frontend->ops.analog_ops.standby)
                fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
        return retval;
 }
 
-static int attach_inform(struct i2c_client *client)
-{
-       struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
-       struct cx23885_dev *dev = to_cx23885(v4l2_dev);
-       struct tuner_setup tun_setup;
-
-       dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-               client->driver->driver.name, client->addr, client->name);
-
-       if (!client->driver->command)
-               return 0;
-
-       if (dev->tuner_type != UNSET) {
-
-               dprintk(1, "%s  (tuner) i2c attach [addr=0x%x,client=%s]\n",
-                       client->driver->driver.name, client->addr,
-                       client->name);
-
-               if ((dev->tuner_addr == ADDR_UNSET) ||
-                       (dev->tuner_addr == client->addr)) {
-
-                       dprintk(1, "%s (tuner || addr UNSET)\n",
-                               client->driver->driver.name);
-
-                       dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-                               client->driver->driver.name,
-                               client->addr, client->name);
-
-                       tun_setup.mode_mask = T_ANALOG_TV;
-                       tun_setup.type = dev->tuner_type;
-                       tun_setup.addr = dev->tuner_addr;
-
-                       client->driver->command(client, TUNER_SET_TYPE_ADDR,
-                               &tun_setup);
-               }
-       }
-
-       return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
-       struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
-       struct cx23885_dev *dev = to_cx23885(v4l2_dev);
-
-       dprintk(1, "i2c detach [client=%s]\n", client->name);
-
-       return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
-                             unsigned int cmd, void *arg)
-{
-       if (bus->i2c_rc != 0)
-               return;
-
-       i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
 static u32 cx23885_functionality(struct i2c_adapter *adap)
 {
        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
        .owner             = THIS_MODULE,
        .id                = I2C_HW_B_CX23885,
        .algo              = &cx23885_i2c_algo_template,
-       .class             = I2C_CLASS_TV_ANALOG,
-       .client_register   = attach_inform,
-       .client_unregister = detach_inform,
 };
 
 static struct i2c_client cx23885_i2c_client_template = {
 
        if (0 == bus->i2c_rc) {
                dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
-               if (i2c_scan)
+               if (i2c_scan) {
+                       printk(KERN_INFO "%s: scan bus %d:\n",
+                                       dev->name, bus->nr);
                        do_i2c_scan(dev->name, &bus->i2c_client);
+               }
        } else
                printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
                        dev->name, bus->nr);
 
 
        dev->tvnorm = norm;
 
-       /* Tell the analog tuner/demods */
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
-       /* Tell the internal A/V decoder */
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+       call_all(dev, tuner, s_std, norm);
 
        return 0;
 }
        route.input = INPUT(input)->vmux;
 
        /* Tell the internal A/V decoder */
-       cx23885_call_i2c_clients(&dev->i2c_bus[2],
-               VIDIOC_INT_S_VIDEO_ROUTING, &route);
+       v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
 
        return 0;
 }
        struct v4l2_control *ctl)
 {
        dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+       call_all(dev, core, g_ctrl, ctl);
        return 0;
 }
 
        fh->vidq.field = f->fmt.pix.field;
        dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
                fh->width, fh->height, fh->vidq.field);
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+       call_all(dev, video, s_fmt, f);
        return 0;
 }
 
        f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        f->frequency = dev->freq;
 
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+       call_all(dev, tuner, g_frequency, f);
 
        return 0;
 }
        mutex_lock(&dev->lock);
        dev->freq = f->frequency;
 
-       cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+       call_all(dev, tuner, s_frequency, f);
 
        /* When changing channels it is required to reset TVAUDIO */
        msleep(10);
        if (!v4l2_chip_match_host(®->match))
                return -EINVAL;
 
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+       call_all(dev, core, g_register, reg);
 
        return 0;
 }
        if (!v4l2_chip_match_host(®->match))
                return -EINVAL;
 
-       cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+       call_all(dev, core, s_register, reg);
 
        return 0;
 }
        /* Don't enable VBI yet */
        cx_set(PCI_INT_MSK, 1);
 
+       if (TUNER_ABSENT != dev->tuner_type) {
+               struct v4l2_subdev *sd = NULL;
+
+               if (dev->tuner_addr)
+                       sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+                               "tuner", "tuner", dev->tuner_addr);
+               else
+                       sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+                               "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+               if (sd) {
+                       struct tuner_setup tun_setup;
+
+                       tun_setup.mode_mask = T_ANALOG_TV;
+                       tun_setup.type = dev->tuner_type;
+                       tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+                       v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+               }
+       }
+
 
        /* register v4l devices */
        dev->video_dev = cx23885_vdev_init(dev, dev->pci,
 
        unsigned int               radio_type;
        unsigned char              radio_addr;
        unsigned int               has_radio;
+       struct v4l2_subdev         *sd_cx25840;
 
        /* V4l */
        u32                        freq;
        return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
 }
 
+#define call_all(dev, o, f, args...) \
+       v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
 extern struct list_head cx23885_devlist;
 
 #define SRAM_CH01  0 /* Video A */
 /* cx23885-i2c.c                                                */
 extern int cx23885_i2c_register(struct cx23885_i2c *bus);
 extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
-                                    void *arg);
 extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
 
 /* ----------------------------------------------------------- */