u8 api_version[4];
        u8 gpio[4];
 
-       /* tuner/demod RF and IF AGC limits used for signal strength calc */
-       u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
-       u16 signal_strength;
-       u32 ber;
-       u32 ucblocks;
-       u16 snr;
        u32 bandwidth_hz;
        enum fe_status fe_status;
        /* RF and IF AGC limits used for signal strength calc */
        unsigned long strength_jiffies;
        unsigned long cnr_jiffies;
        unsigned long ber_ucb_jiffies;
+       u16 dvbv3_snr;
+       u16 dvbv3_strength;
+       u32 dvbv3_ber;
+       u32 dvbv3_ucblocks;
        bool first_tune;
        bool i2c_gate_state;
-       unsigned int statistics_step:3;
-       struct delayed_work statistics_work;
 };
 
 static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
        return ret;
 }
 
-static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct i2c_client *client = state->client;
-       int ret;
-
-       dev_dbg(&client->dev, "\n");
-
-       /* reset and start BER counter */
-       ret = regmap_update_bits(state->regmap, 0xd391, 0x10, 0x10);
-       if (ret)
-               goto err;
-
-       return 0;
-err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
-       return ret;
-}
-
-static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct i2c_client *client = state->client;
-       int ret;
-       unsigned int utmp;
-       u8 buf[5];
-
-       dev_dbg(&client->dev, "\n");
-
-       /* check if error bit count is ready */
-       ret = regmap_read(state->regmap, 0xd391, &utmp);
-       if (ret)
-               goto err;
-
-       if (!((utmp >> 4) & 0x01)) {
-               dev_dbg(&client->dev, "not ready\n");
-               return 0;
-       }
-
-       ret = regmap_bulk_read(state->regmap, 0xd387, buf, 5);
-       if (ret)
-               goto err;
-
-       state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-       state->ucblocks += (buf[4] << 8) | buf[3];
-
-       return 0;
-err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
-       return ret;
-}
-
-static int af9013_statistics_snr_start(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct i2c_client *client = state->client;
-       int ret;
-
-       dev_dbg(&client->dev, "\n");
-
-       /* start SNR meas */
-       ret = regmap_update_bits(state->regmap, 0xd2e1, 0x08, 0x08);
-       if (ret)
-               goto err;
-
-       return 0;
-err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
-       return ret;
-}
-
-static int af9013_statistics_snr_result(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct i2c_client *client = state->client;
-       int ret, i, len;
-       unsigned int utmp;
-       u8 buf[3];
-       u32 snr_val;
-       const struct af9013_snr *uninitialized_var(snr_lut);
-
-       dev_dbg(&client->dev, "\n");
-
-       /* check if SNR ready */
-       ret = regmap_read(state->regmap, 0xd2e1, &utmp);
-       if (ret)
-               goto err;
-
-       if (!((utmp >> 3) & 0x01)) {
-               dev_dbg(&client->dev, "not ready\n");
-               return 0;
-       }
-
-       /* read value */
-       ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3);
-       if (ret)
-               goto err;
-
-       snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
-       /* read current modulation */
-       ret = regmap_read(state->regmap, 0xd3c1, &utmp);
-       if (ret)
-               goto err;
-
-       switch ((utmp >> 6) & 3) {
-       case 0:
-               len = ARRAY_SIZE(qpsk_snr_lut);
-               snr_lut = qpsk_snr_lut;
-               break;
-       case 1:
-               len = ARRAY_SIZE(qam16_snr_lut);
-               snr_lut = qam16_snr_lut;
-               break;
-       case 2:
-               len = ARRAY_SIZE(qam64_snr_lut);
-               snr_lut = qam64_snr_lut;
-               break;
-       default:
-               goto err;
-       }
-
-       for (i = 0; i < len; i++) {
-               utmp = snr_lut[i].snr;
-
-               if (snr_val < snr_lut[i].val)
-                       break;
-       }
-       state->snr = utmp * 10; /* dB/10 */
-
-       return 0;
-err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
-       return ret;
-}
-
-static int af9013_statistics_signal_strength(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct i2c_client *client = state->client;
-       int ret = 0;
-       u8 buf[2], rf_gain, if_gain;
-       int signal_strength;
-
-       dev_dbg(&client->dev, "\n");
-
-       if (!state->signal_strength_en)
-               return 0;
-
-       ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2);
-       if (ret)
-               goto err;
-
-       rf_gain = buf[0];
-       if_gain = buf[1];
-
-       signal_strength = (0xffff / \
-               (9 * (state->rf_50 + state->if_50) - \
-               11 * (state->rf_80 + state->if_80))) * \
-               (10 * (rf_gain + if_gain) - \
-               11 * (state->rf_80 + state->if_80));
-       if (signal_strength < 0)
-               signal_strength = 0;
-       else if (signal_strength > 0xffff)
-               signal_strength = 0xffff;
-
-       state->signal_strength = signal_strength;
-
-       return 0;
-err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
-       return ret;
-}
-
-static void af9013_statistics_work(struct work_struct *work)
-{
-       struct af9013_state *state = container_of(work,
-               struct af9013_state, statistics_work.work);
-       unsigned int next_msec;
-
-       /* update only signal strength when demod is not locked */
-       if (!(state->fe_status & FE_HAS_LOCK)) {
-               state->statistics_step = 0;
-               state->ber = 0;
-               state->snr = 0;
-       }
-
-       switch (state->statistics_step) {
-       default:
-               state->statistics_step = 0;
-               /* fall-through */
-       case 0:
-               af9013_statistics_signal_strength(&state->fe);
-               state->statistics_step++;
-               next_msec = 300;
-               break;
-       case 1:
-               af9013_statistics_snr_start(&state->fe);
-               state->statistics_step++;
-               next_msec = 200;
-               break;
-       case 2:
-               af9013_statistics_ber_unc_start(&state->fe);
-               state->statistics_step++;
-               next_msec = 1000;
-               break;
-       case 3:
-               af9013_statistics_snr_result(&state->fe);
-               state->statistics_step++;
-               next_msec = 400;
-               break;
-       case 4:
-               af9013_statistics_ber_unc_result(&state->fe);
-               state->statistics_step++;
-               next_msec = 100;
-               break;
-       }
-
-       schedule_delayed_work(&state->statistics_work,
-               msecs_to_jiffies(next_msec));
-}
-
 static int af9013_get_tune_settings(struct dvb_frontend *fe,
        struct dvb_frontend_tune_settings *fesettings)
 {
                        stmp1, agc_gain, agc_gain_50dbm, agc_gain_80dbm);
 
                state->strength_jiffies = jiffies;
+               /* Convert [-90, -30] dBm to [0x0000, 0xffff] for dvbv3 */
+               utmp1 = clamp(stmp1 + 90000, 0, 60000);
+               state->dvbv3_strength = div_u64((u64)utmp1 * 0xffff, 60000);
 
                c->strength.stat[0].scale = FE_SCALE_DECIBEL;
                c->strength.stat[0].svalue = stmp1;
                dev_dbg(&client->dev, "cnr %u\n", utmp1);
 
                state->cnr_jiffies = jiffies;
+               state->dvbv3_snr = utmp1 / 100;
 
                c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
                c->cnr.stat[0].svalue = utmp1;
                        utmp3, utmp4);
 
                state->ber_ucb_jiffies = jiffies;
+               state->dvbv3_ber = utmp1;
+               state->dvbv3_ucblocks += utmp3;
 
                c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
                c->post_bit_error.stat[0].uvalue += utmp1;
 static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
        struct af9013_state *state = fe->demodulator_priv;
-       *snr = state->snr;
+
+       *snr = state->dvbv3_snr;
+
        return 0;
 }
 
 static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
        struct af9013_state *state = fe->demodulator_priv;
-       *strength = state->signal_strength;
+
+       *strength = state->dvbv3_strength;
+
        return 0;
 }
 
 static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
        struct af9013_state *state = fe->demodulator_priv;
-       *ber = state->ber;
+
+       *ber = state->dvbv3_ber;
+
        return 0;
 }
 
 static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
        struct af9013_state *state = fe->demodulator_priv;
-       *ucblocks = state->ucblocks;
+
+       *ucblocks = state->dvbv3_ucblocks;
+
        return 0;
 }
 
        if (ret)
                goto err;
 
-       /* check if we support signal strength */
-       if (!state->signal_strength_en) {
-               ret = regmap_read(state->regmap, 0x9bee, &utmp);
-               if (ret)
-                       goto err;
-
-               state->signal_strength_en = (utmp >> 0) & 0x01;
-       }
-
-       /* read values needed for signal strength calculation */
-       if (state->signal_strength_en && !state->rf_50) {
-               ret = regmap_bulk_read(state->regmap, 0x9bbd, &state->rf_50, 1);
-               if (ret)
-                       goto err;
-               ret = regmap_bulk_read(state->regmap, 0x9bd0, &state->rf_80, 1);
-               if (ret)
-                       goto err;
-               ret = regmap_bulk_read(state->regmap, 0x9be2, &state->if_50, 1);
-               if (ret)
-                       goto err;
-               ret = regmap_bulk_read(state->regmap, 0x9be4, &state->if_80, 1);
-               if (ret)
-                       goto err;
-       }
-
-       /* SNR */
-       ret = regmap_write(state->regmap, 0xd2e2, 0x01);
-       if (ret)
-               goto err;
-
-       /* BER / UCB */
-       buf[0] = (10000 >> 0) & 0xff;
-       buf[1] = (10000 >> 8) & 0xff;
-       ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2);
-       if (ret)
-               goto err;
-
-       /* enable FEC monitor */
-       ret = regmap_update_bits(state->regmap, 0xd392, 0x02, 0x02);
-       if (ret)
-               goto err;
-
        state->first_tune = true;
-       schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400));
 
        return 0;
 err:
 
        dev_dbg(&client->dev, "\n");
 
-       /* stop statistics polling */
-       cancel_delayed_work_sync(&state->statistics_work);
-
        /* disable lock led */
        ret = regmap_update_bits(state->regmap, 0xd730, 0x01, 0x00);
        if (ret)
        state->spec_inv = pdata->spec_inv;
        memcpy(&state->api_version, pdata->api_version, sizeof(state->api_version));
        memcpy(&state->gpio, pdata->gpio, sizeof(state->gpio));
-       INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work);
        state->regmap = regmap_init(&client->dev, ®map_bus, client,
                                  ®map_config);
        if (IS_ERR(state->regmap)) {
 
        dev_dbg(&client->dev, "\n");
 
-       /* Stop statistics polling */
-       cancel_delayed_work_sync(&state->statistics_work);
-
        regmap_exit(state->regmap);
 
        kfree(state);