X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Ffrontends%2Fnxt6000.c;h=966de9853d18b7e6d9a8eadd768804603218595f;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=a55fd99a6383a4868cf4644c5561367047065435;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a55fd99a6..966de9853 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c @@ -1,6 +1,6 @@ -/* +/* NxtWave Communications - NXT6000 demodulator driver - + Copyright (C) 2002-2003 Florian Schirmer Copyright (C) 2003 Paul Andreassen @@ -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 #include @@ -33,16 +32,11 @@ 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);