vserver 2.0 rc7
[linux-2.6.git] / drivers / media / dvb / frontends / nxt6000.c
index a55fd99..966de98 100644 (file)
@@ -1,6 +1,6 @@
-/* 
+/*
        NxtWave Communications - NXT6000 demodulator driver
-       
+
     Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
     Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
 
@@ -17,8 +17,7 @@
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/    
+*/
 
 #include <linux/init.h>
 #include <linux/kernel.h>
 
 
 struct nxt6000_state {
-
-       struct i2c_adapter *i2c;
-
+       struct i2c_adapter* i2c;
        struct dvb_frontend_ops ops;
-
        /* configuration settings */
        const struct nxt6000_config* config;
-
        struct dvb_frontend frontend;
-
 };
 
 static int debug = 0;
@@ -50,10 +44,10 @@ static int debug = 0;
 
 static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
 {
-       u8 buf[] = {reg, data};
+       u8 buf[] = { reg, data };
        struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
        int ret;
-       
+
        if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
                dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
 
@@ -63,18 +57,18 @@ static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
 static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
 {
        int ret;
-       u8 b0[] = {reg};
-       u8 b1[] = {0};
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
        struct i2c_msg msgs[] = {
                {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
                {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
        };
 
        ret = i2c_transfer(state->i2c, msgs, 2);
-       
+
        if (ret != 2)
                dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
-       
+
        return b1[0];
 }
 
@@ -83,7 +77,7 @@ static void nxt6000_reset(struct nxt6000_state* state)
        u8 val;
 
        val = nxt6000_readreg(state, OFDM_COR_CTL);
-       
+
        nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
        nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
 }
@@ -93,71 +87,65 @@ static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t ban
        u16 nominal_rate;
        int result;
 
-       switch(bandwidth) {
-       
-               case BANDWIDTH_6_MHZ:
-               
-                       nominal_rate = 0x55B7;
-                       
-                       break;
+       switch (bandwidth) {
 
-               case BANDWIDTH_7_MHZ:
-
-                       nominal_rate = 0x6400;
-                       
-                       break;
+       case BANDWIDTH_6_MHZ:
+               nominal_rate = 0x55B7;
+               break;
 
-               case BANDWIDTH_8_MHZ:
+       case BANDWIDTH_7_MHZ:
+               nominal_rate = 0x6400;
+               break;
 
-                       nominal_rate = 0x7249;
-                       
-                       break;
+       case BANDWIDTH_8_MHZ:
+               nominal_rate = 0x7249;
+               break;
 
-               default:
-                       return -EINVAL;
+       default:
+               return -EINVAL;
        }
 
        if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
                return result;
-               
+
        return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
 }
 
 static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
 {
-       switch(guard_interval) {
-       
-               case GUARD_INTERVAL_1_32:
+       switch (guard_interval) {
+
+       case GUARD_INTERVAL_1_32:
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
 
-               case GUARD_INTERVAL_1_16:
+       case GUARD_INTERVAL_1_16:
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
 
-               case GUARD_INTERVAL_AUTO:
-               case GUARD_INTERVAL_1_8:
+       case GUARD_INTERVAL_AUTO:
+       case GUARD_INTERVAL_1_8:
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
 
-               case GUARD_INTERVAL_1_4:
+       case GUARD_INTERVAL_1_4:
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
-                       
-               default:
-                       return -EINVAL;
+
+       default:
+               return -EINVAL;
        }
 }
 
 static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
 {
-       switch(inversion) {
-       
-               case INVERSION_OFF:
+       switch (inversion) {
+
+       case INVERSION_OFF:
                return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
-                       
-               case INVERSION_ON:
+
+       case INVERSION_ON:
                return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
 
-               default:
-                       return -EINVAL; 
-       
+       default:
+               return -EINVAL;
+
        }
 }
 
@@ -165,34 +153,39 @@ static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmi
 {
        int result;
 
-       switch(transmission_mode) {
+       switch (transmission_mode) {
 
-               case TRANSMISSION_MODE_2K:      
+       case TRANSMISSION_MODE_2K:
                if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
-                               return result;
-                               
+                       return result;
+
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
 
-               case TRANSMISSION_MODE_8K:      
-               case TRANSMISSION_MODE_AUTO:    
+       case TRANSMISSION_MODE_8K:
+       case TRANSMISSION_MODE_AUTO:
                if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
-                               return result;
+                       return result;
 
                return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
 
-               default:
-                       return -EINVAL;
-       
+       default:
+               return -EINVAL;
+
        }
 }
 
 static void nxt6000_setup(struct dvb_frontend* fe)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
-       
+       struct nxt6000_state* state = fe->demodulator_priv;
+
        nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
        nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
-       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC);
+       nxt6000_writereg(state, VIT_BERTIME_2, 0x00);  // BER Timer = 0x000200 * 256 = 131072 bits
+       nxt6000_writereg(state, VIT_BERTIME_1, 0x02);  //
+       nxt6000_writereg(state, VIT_BERTIME_0, 0x00);  //
+       nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
+       nxt6000_writereg(state, VIT_COR_CTL, 0x82);   // Enable BER measurement
+       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
        nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
        nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
        nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
@@ -214,7 +207,7 @@ static void nxt6000_setup(struct dvb_frontend* fe)
                nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
 
        nxt6000_writereg(state, TS_FORMAT, 0);
-               
+
        if (state->config->pll_init) {
                nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);        /* open i2c bus switch */
                state->config->pll_init(fe);
@@ -241,7 +234,7 @@ static void nxt6000_dump_status(struct nxt6000_state *state)
        printk("NXT6000 status:");
 
        val = nxt6000_readreg(state, RS_COR_STAT);
-       
+
        printk(" DATA DESCR LOCK: %d,", val & 0x01);
        printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
 
@@ -249,91 +242,73 @@ static void nxt6000_dump_status(struct nxt6000_state *state)
 
        printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
 
-       switch((val >> 4) & 0x07) {
-       
-               case 0x00: 
-               
-                       printk(" VITERBI CODERATE: 1/2,");
-                       
-                       break;
-       
-               case 0x01: 
-               
-                       printk(" VITERBI CODERATE: 2/3,");
-                       
-                       break;
-       
-               case 0x02: 
-               
-                       printk(" VITERBI CODERATE: 3/4,");
-                       
-                       break;
-       
-               case 0x03: 
-                       printk(" VITERBI CODERATE: 5/6,");
-               break;
-
-               case 0x04: 
-                       printk(" VITERBI CODERATE: 7/8,");
-                       break;
-
-               default: 
-               
-                       printk(" VITERBI CODERATE: Reserved,");
-                       
+       switch ((val >> 4) & 0x07) {
+
+       case 0x00:
+               printk(" VITERBI CODERATE: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" VITERBI CODERATE: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" VITERBI CODERATE: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" VITERBI CODERATE: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" VITERBI CODERATE: 7/8,");
+               break;
+
+       default:
+               printk(" VITERBI CODERATE: Reserved,");
+
        }
 
        val = nxt6000_readreg(state, OFDM_COR_STAT);
-       
+
        printk(" CHCTrack: %d,", (val >> 7) & 0x01);
        printk(" TPSLock: %d,", (val >> 6) & 0x01);
        printk(" SYRLock: %d,", (val >> 5) & 0x01);
        printk(" AGCLock: %d,", (val >> 4) & 0x01);
 
-       switch(val & 0x0F) {
-       
-               case 0x00:
-               
-                       printk(" CoreState: IDLE,");
-                       
-                       break;
-       
-               case 0x02:
-               
-                       printk(" CoreState: WAIT_AGC,");
-                       
-                       break;
-       
-               case 0x03:
-               
-                       printk(" CoreState: WAIT_SYR,");
-                       
-                       break;
-       
-               case 0x04:
-                       printk(" CoreState: WAIT_PPM,");
-               break;
-
-               case 0x01:
-                       printk(" CoreState: WAIT_TRL,");
-                       break;
-
-               case 0x05:
-               
-                       printk(" CoreState: WAIT_TPS,");
-                       
-                       break;
-
-               case 0x06:
-               
-                       printk(" CoreState: MONITOR_TPS,");
-                       
-                       break;
-
-               default: 
-               
-                       printk(" CoreState: Reserved,");
-                       
+       switch (val & 0x0F) {
+
+       case 0x00:
+               printk(" CoreState: IDLE,");
+               break;
+
+       case 0x02:
+               printk(" CoreState: WAIT_AGC,");
+               break;
+
+       case 0x03:
+               printk(" CoreState: WAIT_SYR,");
+               break;
+
+       case 0x04:
+               printk(" CoreState: WAIT_PPM,");
+               break;
+
+       case 0x01:
+               printk(" CoreState: WAIT_TRL,");
+               break;
+
+       case 0x05:
+               printk(" CoreState: WAIT_TPS,");
+               break;
+
+       case 0x06:
+               printk(" CoreState: MONITOR_TPS,");
+               break;
+
+       default:
+               printk(" CoreState: Reserved,");
+
        }
 
        val = nxt6000_readreg(state, OFDM_SYR_STAT);
@@ -341,133 +316,105 @@ static void nxt6000_dump_status(struct nxt6000_state *state)
        printk(" SYRLock: %d,", (val >> 4) & 0x01);
        printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
 
-       switch((val >> 4) & 0x03) {
-       
-               case 0x00: 
-               
-                       printk(" SYRGuard: 1/32,");
-                       
-                       break;
-       
-               case 0x01: 
-               
-                       printk(" SYRGuard: 1/16,");
-                       
-                       break;
-       
-               case 0x02: 
-               
-                       printk(" SYRGuard: 1/8,");
-                       
-                       break;
-       
-               case 0x03: 
-                       printk(" SYRGuard: 1/4,");
-                       break;
+       switch ((val >> 4) & 0x03) {
+
+       case 0x00:
+               printk(" SYRGuard: 1/32,");
+               break;
+
+       case 0x01:
+               printk(" SYRGuard: 1/16,");
+               break;
+
+       case 0x02:
+               printk(" SYRGuard: 1/8,");
+               break;
+
+       case 0x03:
+               printk(" SYRGuard: 1/4,");
+               break;
        }
 
        val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
-       
-       switch((val >> 4) & 0x07) {
-       
-               case 0x00: 
-               
-                       printk(" TPSLP: 1/2,");
-                       
-                       break;
-       
-               case 0x01: 
-               
-                       printk(" TPSLP: 2/3,");
-                       
-                       break;
-       
-               case 0x02: 
-               
-                       printk(" TPSLP: 3/4,");
-                       
-                       break;
-       
-               case 0x03: 
-                       printk(" TPSLP: 5/6,");
-               break;
-
-               case 0x04: 
-                       printk(" TPSLP: 7/8,");
-                       break;
-
-               default: 
-               
-                       printk(" TPSLP: Reserved,");
-                       
+
+       switch ((val >> 4) & 0x07) {
+
+       case 0x00:
+               printk(" TPSLP: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" TPSLP: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" TPSLP: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" TPSLP: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" TPSLP: 7/8,");
+               break;
+
+       default:
+               printk(" TPSLP: Reserved,");
+
        }
 
-       switch(val & 0x07) {
-       
-               case 0x00: 
-               
-                       printk(" TPSHP: 1/2,");
-                       
-                       break;
-       
-               case 0x01: 
-               
-                       printk(" TPSHP: 2/3,");
-                       
-                       break;
-       
-               case 0x02: 
-               
-                       printk(" TPSHP: 3/4,");
-                       
-                       break;
-       
-               case 0x03: 
-                       printk(" TPSHP: 5/6,");
-               break;
-
-               case 0x04: 
-                       printk(" TPSHP: 7/8,");
-                       break;
-
-               default: 
-               
-                       printk(" TPSHP: Reserved,");
-                       
+       switch (val & 0x07) {
+
+       case 0x00:
+               printk(" TPSHP: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" TPSHP: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" TPSHP: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" TPSHP: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" TPSHP: 7/8,");
+               break;
+
+       default:
+               printk(" TPSHP: Reserved,");
+
        }
 
        val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
-       
+
        printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
-       
-       switch((val >> 4) & 0x03) {
-       
-               case 0x00: 
-               
-                       printk(" TPSGuard: 1/32,");
-                       
-                       break;
-       
-               case 0x01: 
-               
-                       printk(" TPSGuard: 1/16,");
-                       
-                       break;
-       
-               case 0x02: 
-               
-                       printk(" TPSGuard: 1/8,");
-                       
-                       break;
-       
-               case 0x03: 
-               
-                       printk(" TPSGuard: 1/4,");
-                       
-                       break;
-                       
+
+       switch ((val >> 4) & 0x03) {
+
+       case 0x00:
+               printk(" TPSGuard: 1/32,");
+               break;
+
+       case 0x01:
+               printk(" TPSGuard: 1/16,");
+               break;
+
+       case 0x02:
+               printk(" TPSGuard: 1/8,");
+               break;
+
+       case 0x03:
+               printk(" TPSGuard: 1/4,");
+               break;
+
        }
-       
+
        /* Strange magic required to gain access to RF_AGC_STATUS */
        nxt6000_readreg(state, RF_AGC_VAL_1);
        val = nxt6000_readreg(state, RF_AGC_STATUS);
@@ -477,94 +424,116 @@ static void nxt6000_dump_status(struct nxt6000_state *state)
        printk("\n");
 }
 
-
-
-
-
-
-
-
-
-
-
 static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-                       u8 core_status;
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       u8 core_status;
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *status = 0;
 
-                       *status = 0;
-                       
        core_status = nxt6000_readreg(state, OFDM_COR_STAT);
 
-                       if (core_status & AGCLOCKED)
-                               *status |= FE_HAS_SIGNAL;
+       if (core_status & AGCLOCKED)
+               *status |= FE_HAS_SIGNAL;
 
        if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
-                               *status |= FE_HAS_CARRIER;
+               *status |= FE_HAS_CARRIER;
 
        if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
-                               *status |= FE_HAS_VITERBI;
+               *status |= FE_HAS_VITERBI;
 
        if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
-                               *status |= FE_HAS_SYNC;
-                               
-                       if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
-                               *status |= FE_HAS_LOCK;
-                               
-                       if (debug)
+               *status |= FE_HAS_SYNC;
+
+       if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
+               *status |= FE_HAS_LOCK;
+
+       if (debug)
                nxt6000_dump_status(state);
 
-                       return 0;
-               }
-       
+       return 0;
+}
+
 static int nxt6000_init(struct dvb_frontend* fe)
-               {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
 
        nxt6000_reset(state);
        nxt6000_setup(fe);
-       
-                       return 0;
-               }
-       
+
+       return 0;
+}
 
 static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
-               {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
-                       int result;
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+       int result;
 
        nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);        /* open i2c bus switch */
        state->config->pll_set(fe, param);
        nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);        /* close i2c bus switch */
 
        if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
-                                               return result;
+               return result;
        if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0)
-                               return result;
+               return result;
        if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0)
-                               return result;
+               return result;
        if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
-                               return result;
+               return result;
 
        return 0;
-} 
-
+}
 
 static void nxt6000_release(struct dvb_frontend* fe)
 {
-       struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
+       struct nxt6000_state* state = fe->demodulator_priv;
        kfree(state);
-       }
-       
+}
+
+static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
+
+       return 0;
+}
+
+static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
+
+       *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
+               nxt6000_readreg( state, VIT_BER_0 );
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
+
+       return 0;
+}
+
+static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *signal_strength = (short) (511 -
+               (nxt6000_readreg(state, AGC_GAIN_1) +
+               ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
+
+       return 0;
+}
+
 static struct dvb_frontend_ops nxt6000_ops;
-       
+
 struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
                                    struct i2c_adapter* i2c)
 {
        struct nxt6000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
@@ -581,9 +550,9 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
        return &state->frontend;
 
 error:
-       if (state) kfree(state);
+       kfree(state);
        return NULL;
-       }
+}
 
 static struct dvb_frontend_ops nxt6000_ops = {
 
@@ -608,10 +577,13 @@ static struct dvb_frontend_ops nxt6000_ops = {
        .release = nxt6000_release,
 
        .init = nxt6000_init,
-       
+
        .set_frontend = nxt6000_set_frontend,
-       
+
        .read_status = nxt6000_read_status,
+       .read_ber = nxt6000_read_ber,
+       .read_signal_strength = nxt6000_read_signal_strength,
+       .read_snr = nxt6000_read_snr,
 };
 
 module_param(debug, int, 0644);