#define FREQ_OFFSET_LOW_SYM_RATE 3000
 
 struct ts2020_priv {
+       struct i2c_client *client;
        struct dvb_frontend *fe;
        /* i2c details */
        int i2c_address;
 
 static int ts2020_release(struct dvb_frontend *fe)
 {
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
+       struct ts2020_priv *priv = fe->tuner_priv;
+       struct i2c_client *client = priv->client;
+
+       dev_dbg(&client->dev, "\n");
+
+       i2c_unregister_device(client);
        return 0;
 }
 
                                        const struct ts2020_config *config,
                                        struct i2c_adapter *i2c)
 {
-       struct ts2020_priv *priv = NULL;
-       u8 buf;
-
-       priv = kzalloc(sizeof(struct ts2020_priv), GFP_KERNEL);
-       if (priv == NULL)
+       struct i2c_client *client;
+       struct i2c_board_info board_info;
+       struct ts2020_config pdata;
+
+       memcpy(&pdata, config, sizeof(pdata));
+       pdata.fe = fe;
+       pdata.attach_in_use = true;
+
+       memset(&board_info, 0, sizeof(board_info));
+       strlcpy(board_info.type, "ts2020", I2C_NAME_SIZE);
+       board_info.addr = config->tuner_address;
+       board_info.platform_data = &pdata;
+       client = i2c_new_device(i2c, &board_info);
+       if (!client || !client->dev.driver)
                return NULL;
 
-       priv->i2c_address = config->tuner_address;
-       priv->i2c = i2c;
-       priv->clk_out = config->clk_out;
-       priv->clk_out_div = config->clk_out_div;
-       priv->frequency_div = config->frequency_div;
-       priv->fe = fe;
-       fe->tuner_priv = priv;
-
-       if (!priv->frequency_div)
-               priv->frequency_div = 1060000;
-
-       /* Wake Up the tuner */
-       if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) {
-               ts2020_writereg(fe, 0x00, 0x01);
-               msleep(2);
-       }
-
-       ts2020_writereg(fe, 0x00, 0x03);
-       msleep(2);
-
-       /* Check the tuner version */
-       buf = ts2020_readreg(fe, 0x00);
-       if ((buf == 0x01) || (buf == 0x41) || (buf == 0x81)) {
-               printk(KERN_INFO "%s: Find tuner TS2020!\n", __func__);
-               priv->tuner = TS2020_M88TS2020;
-       } else if ((buf == 0x83) || (buf == 0xc3)) {
-               printk(KERN_INFO "%s: Find tuner TS2022!\n", __func__);
-               priv->tuner = TS2020_M88TS2022;
-       } else {
-               printk(KERN_ERR "%s: Read tuner reg[0] = %d\n", __func__, buf);
-               kfree(priv);
-               return NULL;
-       }
-
-       memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops,
-                               sizeof(struct dvb_tuner_ops));
-
        return fe;
 }
 EXPORT_SYMBOL(ts2020_attach);
        dev->frequency_div = pdata->frequency_div;
        dev->fe = fe;
        fe->tuner_priv = dev;
+       dev->client = client;
 
        /* check if the tuner is there */
        ret = ts2020_readreg(fe, 0x00);
 
        memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops,
                        sizeof(struct dvb_tuner_ops));
-       fe->ops.tuner_ops.release = NULL;
+       if (!pdata->attach_in_use)
+               fe->ops.tuner_ops.release = NULL;
 
        i2c_set_clientdata(client, dev);
        return 0;
 static int ts2020_remove(struct i2c_client *client)
 {
        struct ts2020_priv *dev = i2c_get_clientdata(client);
-       struct dvb_frontend *fe = dev->fe;
 
        dev_dbg(&client->dev, "\n");
 
-       memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = NULL;
        kfree(dev);
-
        return 0;
 }