{
        struct cxd2099_cfg cxd_cfg = cxd_cfgtmpl;
        struct i2c_client *client;
-       struct i2c_board_info board_info = {
-               .type = "cxd2099",
-               .addr = 0x40,
-               .platform_data = &cxd_cfg,
-       };
 
        cxd_cfg.bitrate = bitrate;
        cxd_cfg.en = &port->en;
 
-       request_module(board_info.type);
-
-       client = i2c_new_device(&port->i2c->adap, &board_info);
-       if (!client || !client->dev.driver)
-               goto err_ret;
-
-       if (!try_module_get(client->dev.driver->owner))
-               goto err_i2c;
-
-       if (!port->en)
-               goto err_i2c;
+       client = dvb_module_probe("cxd2099", NULL, &port->i2c->adap,
+                                 0x40, &cxd_cfg);
+       if (!client)
+               goto err;
 
        port->dvb[0].i2c_client[0] = client;
        port->en_freedata = 0;
        return 0;
 
-err_i2c:
-       i2c_unregister_device(client);
-err_ret:
+err:
        dev_err(port->dev->dev, "CXD2099AR attach failed\n");
        return -ENODEV;
 }
 
 void ddb_ci_detach(struct ddb_port *port)
 {
-       struct i2c_client *client;
-
        if (port->dvb[0].dev)
                dvb_unregister_device(port->dvb[0].dev);
        if (port->en) {
                dvb_ca_en50221_release(port->en);
 
-               client = port->dvb[0].i2c_client[0];
-               if (client) {
-                       module_put(client->dev.driver->owner);
-                       i2c_unregister_device(client);
-               }
+               dvb_module_release(port->dvb[0].i2c_client[0]);
+               port->dvb[0].i2c_client[0] = NULL;
 
                /* free alloc'ed memory if needed */
                if (port->en_freedata)
 
                .if_dvbt2_8 = 4000,
                .if_dvbc = 5000,
        };
-       struct i2c_board_info board_info = {
-               .type = "tda18212",
-               .platform_data = &config,
-       };
-
-       if (input->nr & 1)
-               board_info.addr = 0x63;
-       else
-               board_info.addr = 0x60;
+       u8 addr = (input->nr & 1) ? 0x63 : 0x60;
 
        /* due to a hardware quirk with the I2C gate on the stv0367+tda18212
         * combo, the tda18212 must be probed by reading it's id _twice_ when
         * cold started, or it very likely will fail.
         */
        if (porttype == DDB_TUNER_DVBCT_ST)
-               tuner_tda18212_ping(input, board_info.addr);
-
-       request_module(board_info.type);
-
-       /* perform tuner init/attach */
-       client = i2c_new_device(adapter, &board_info);
-       if (!client || !client->dev.driver)
-               goto err;
+               tuner_tda18212_ping(input, addr);
 
-       if (!try_module_get(client->dev.driver->owner)) {
-               i2c_unregister_device(client);
+       /* perform tuner probe/init/attach */
+       client = dvb_module_probe("tda18212", NULL, adapter, addr, &config);
+       if (!client)
                goto err;
-       }
 
        dvb->i2c_client[0] = client;
-
        return 0;
 err:
        dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
 {
        struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
        struct dvb_demux *dvbdemux = &dvb->demux;
-       struct i2c_client *client;
 
        switch (dvb->attached) {
        case 0x31:
                        dvb_unregister_frontend(dvb->fe);
                /* fallthrough */
        case 0x30:
-               client = dvb->i2c_client[0];
-               if (client) {
-                       module_put(client->dev.driver->owner);
-                       i2c_unregister_device(client);
-                       dvb->i2c_client[0] = NULL;
-                       client = NULL;
-               }
+               dvb_module_release(dvb->i2c_client[0]);
+               dvb->i2c_client[0] = NULL;
 
                if (dvb->fe2)
                        dvb_frontend_detach(dvb->fe2);