X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Ffrontends%2Fstv0297.c;h=1ca64249010ce54d4a3fa58946695396d22ccf74;hb=refs%2Fheads%2Fvserver;hp=b51a6d2565c562b140a1e3f7e383f5354d843806;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index b51a6d256..1ca642490 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c @@ -24,22 +24,18 @@ #include #include #include +#include +#include #include "dvb_frontend.h" #include "stv0297.h" struct stv0297_state { - - struct i2c_adapter* i2c; - - struct dvb_frontend_ops ops; - - const struct stv0297_config* config; - - struct dvb_frontend frontend; + struct i2c_adapter *i2c; + const struct stv0297_config *config; + struct dvb_frontend frontend; unsigned long base_freq; - u8 pwm; }; #if 1 @@ -50,164 +46,89 @@ struct stv0297_state { #define STV0297_CLOCK_KHZ 28900 -static u8 init_tab [] = { - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x00, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0xff, - 0x4b, 0x7f, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x00, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x00, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x53, - 0xc1, 0x70, - 0xc2, 0x12, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x49, - 0x62, 0x0b, - 0x53, 0x08, - 0x59, 0x08, -}; - -static int stv0297_writereg (struct stv0297_state* state, u8 reg, u8 data) +static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) { - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; + int ret; + u8 buf[] = { reg, data }; + struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 }; - ret = i2c_transfer (state->i2c, &msg, 1); + ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __FUNCTION__, reg, data, ret); + if (ret != 1) + dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " + "ret == %i)\n", __FUNCTION__, reg, data, ret); - return (ret != 1) ? -1 : 0; + return (ret != 1) ? -1 : 0; } -static int stv0297_readreg (struct stv0297_state* state, u8 reg) +static int stv0297_readreg(struct stv0297_state *state, u8 reg) { - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = - 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - - // this device needs a STOP between the register and data - if ((ret = i2c_transfer (state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } - if ((ret = i2c_transfer (state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } - - return b1[0]; + int ret; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, + {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} + }; + + // this device needs a STOP between the register and data + if (state->config->stop_during_read) { + if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + return -1; + } + if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + return -1; + } + } else { + if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + return -1; + } + } + + return b1[0]; } -static int stv0297_writereg_mask (struct stv0297_state* state, u8 reg, u8 mask, u8 data) +static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data) { - int val; + int val; - val = stv0297_readreg(state, reg); - val &= ~mask; - val |= (data & mask); - stv0297_writereg(state, reg, val); + val = stv0297_readreg(state, reg); + val &= ~mask; + val |= (data & mask); + stv0297_writereg(state, reg, val); - return 0; + return 0; } -static int stv0297_readregs (struct stv0297_state* state, u8 reg1, u8 *b, u8 len) +static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len) { - int ret; + int ret; struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = ®1,.len = 1}, {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len} }; - // this device needs a STOP between the register and data - if ((ret = i2c_transfer (state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } - if ((ret = i2c_transfer (state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } - - return 0; + // this device needs a STOP between the register and data + if (state->config->stop_during_read) { + if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + return -1; + } + if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + return -1; + } + } else { + if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + return -1; + } + } + + return 0; } static u32 stv0297_get_symbolrate(struct stv0297_state *state) @@ -233,10 +154,10 @@ static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate) tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */ tmp = tmp * 8192L; /* 8192 = 2^13 */ - stv0297_writereg (state, 0x55,(unsigned char)(tmp & 0xFF)); - stv0297_writereg (state, 0x56,(unsigned char)(tmp>> 8)); - stv0297_writereg (state, 0x57,(unsigned char)(tmp>>16)); - stv0297_writereg (state, 0x58,(unsigned char)(tmp>>24)); + stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF)); + stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8)); + stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16)); + stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24)); } static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate) @@ -247,19 +168,19 @@ static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, lon tmp /= symrate; tmp *= 1024; /* 1024 = 2*10 */ - // adjust - if (tmp >= 0) { - tmp += 500000; - } else { - tmp -= 500000; - } + // adjust + if (tmp >= 0) { + tmp += 500000; + } else { + tmp -= 500000; + } tmp /= 1000000; - stv0297_writereg(state, 0x60, tmp & 0xFF); - stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0); + stv0297_writereg(state, 0x60, tmp & 0xFF); + stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0); } -static void stv0297_set_carrieroffset(struct stv0297_state* state, long offset) +static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset) { long tmp; @@ -276,11 +197,11 @@ static void stv0297_set_carrieroffset(struct stv0297_state* state, long offset) } /* -static long stv0297_get_carrieroffset(struct stv0297_state* state) +static long stv0297_get_carrieroffset(struct stv0297_state *state) { s64 tmp; - stv0297_writereg(state,0x6B, 0x00); + stv0297_writereg(state, 0x6B, 0x00); tmp = stv0297_readreg(state, 0x66); tmp |= (stv0297_readreg(state, 0x67) << 8); @@ -294,7 +215,7 @@ static long stv0297_get_carrieroffset(struct stv0297_state* state) } */ -static void stv0297_set_initialdemodfreq(struct stv0297_state* state, long freq) +static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq) { s32 tmp; @@ -306,254 +227,215 @@ static void stv0297_set_initialdemodfreq(struct stv0297_state* state, long freq) if (tmp > 0xffff) tmp = 0xffff; - stv0297_writereg_mask(state, 0x25, 0x80, 0x80); - stv0297_writereg(state, 0x21, tmp >> 8); - stv0297_writereg(state, 0x20, tmp); + stv0297_writereg_mask(state, 0x25, 0x80, 0x80); + stv0297_writereg(state, 0x21, tmp >> 8); + stv0297_writereg(state, 0x20, tmp); } -static int stv0297_set_qam(struct stv0297_state* state, fe_modulation_t modulation) +static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation) { - int val = 0; + int val = 0; - switch(modulation) { - case QAM_16: - val = 0; - break; + switch (modulation) { + case QAM_16: + val = 0; + break; - case QAM_32: - val = 1; - break; + case QAM_32: + val = 1; + break; - case QAM_64: - val = 4; - break; + case QAM_64: + val = 4; + break; - case QAM_128: - val = 2; - break; + case QAM_128: + val = 2; + break; - case QAM_256: - val = 3; - break; + case QAM_256: + val = 3; + break; - default: - return -EINVAL; - } + default: + return -EINVAL; + } - stv0297_writereg_mask(state, 0x00, 0x70, val << 4); + stv0297_writereg_mask(state, 0x00, 0x70, val << 4); - return 0; + return 0; } -static int stv0297_set_inversion(struct stv0297_state* state, fe_spectral_inversion_t inversion) +static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion) { - int val = 0; + int val = 0; - switch(inversion) { - case INVERSION_OFF: - val = 0; - break; + switch (inversion) { + case INVERSION_OFF: + val = 0; + break; - case INVERSION_ON: - val = 1; - break; + case INVERSION_ON: + val = 1; + break; - default: - return -EINVAL; - } + default: + return -EINVAL; + } - stv0297_writereg_mask(state, 0x83, 0x08, val << 3); + stv0297_writereg_mask(state, 0x83, 0x08, val << 3); - return 0; + return 0; } - - - - - - - - - - - - -int stv0297_enable_plli2c(struct dvb_frontend* fe) +static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; + struct stv0297_state *state = fe->demodulator_priv; - stv0297_writereg(state, 0x87, 0x78); - stv0297_writereg(state, 0x86, 0xc8); + if (enable) { + stv0297_writereg(state, 0x87, 0x78); + stv0297_writereg(state, 0x86, 0xc8); + } - return 0; + return 0; } -static int stv0297_init (struct dvb_frontend* fe) +static int stv0297_init(struct dvb_frontend *fe) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - int i; - - /* soft reset */ - stv0297_writereg_mask(state, 0x80, 1, 1); - stv0297_writereg_mask(state, 0x80, 1, 0); - - /* reset deinterleaver */ - stv0297_writereg_mask(state, 0x81, 1, 1); - stv0297_writereg_mask(state, 0x81, 1, 0); + struct stv0297_state *state = fe->demodulator_priv; + int i; /* load init table */ - for (i=0; ipwm); - msleep(200); + for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) + stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); + msleep(200); - if (state->config->pll_init) - state->config->pll_init(fe); - - return 0; + return 0; } static int stv0297_sleep(struct dvb_frontend *fe) { - struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; + struct stv0297_state *state = fe->demodulator_priv; stv0297_writereg_mask(state, 0x80, 1, 1); return 0; } -static int stv0297_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; + struct stv0297_state *state = fe->demodulator_priv; - u8 sync = stv0297_readreg (state, 0xDF); + u8 sync = stv0297_readreg(state, 0xDF); - *status = 0; - if (sync & 0x80) + *status = 0; + if (sync & 0x80) *status |= FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; - return 0; + return 0; } -static int stv0297_read_ber(struct dvb_frontend* fe, u32* ber) +static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - u8 BER[3]; + struct stv0297_state *state = fe->demodulator_priv; + u8 BER[3]; - stv0297_writereg (state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes - mdelay(25); // Hopefully got 4096 Bytes - stv0297_readregs (state, 0xA0, BER, 3); - mdelay(25); - *ber = (BER[2] << 8 | BER[1]) / ( 8 * 4096); + stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes + mdelay(25); // Hopefully got 4096 Bytes + stv0297_readregs(state, 0xA0, BER, 3); + mdelay(25); + *ber = (BER[2] << 8 | BER[1]) / (8 * 4096); - return 0; + return 0; } -static int stv0297_read_signal_strength(struct dvb_frontend* fe, u16* strength) +static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - u8 STRENGTH[2]; + struct stv0297_state *state = fe->demodulator_priv; + u8 STRENGTH[2]; - stv0297_readregs (state, 0x41, STRENGTH, 2); - *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0]; + stv0297_readregs(state, 0x41, STRENGTH, 2); + *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0]; - return 0; + return 0; } -static int stv0297_read_snr(struct dvb_frontend* fe, u16* snr) +static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - u8 SNR[2]; + struct stv0297_state *state = fe->demodulator_priv; + u8 SNR[2]; - stv0297_readregs (state, 0x07, SNR, 2); - *snr = SNR[1] << 8 | SNR[0]; + stv0297_readregs(state, 0x07, SNR, 2); + *snr = SNR[1] << 8 | SNR[0]; - return 0; + return 0; } -static int stv0297_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) +static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; + struct stv0297_state *state = fe->demodulator_priv; - *ucblocks = (stv0297_readreg (state, 0xD5) << 8) - | stv0297_readreg (state, 0xD4); + *ucblocks = (stv0297_readreg(state, 0xD5) << 8) + | stv0297_readreg(state, 0xD4); - return 0; + return 0; } -static int stv0297_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) +static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - int u_threshold; - int initial_u; - int blind_u; - int delay; - int sweeprate; - int carrieroffset; - unsigned long starttime; - unsigned long timeout; + struct stv0297_state *state = fe->demodulator_priv; + int u_threshold; + int initial_u; + int blind_u; + int delay; + int sweeprate; + int carrieroffset; + unsigned long starttime; + unsigned long timeout; fe_spectral_inversion_t inversion; - switch(p->u.qam.modulation) { - case QAM_16: - case QAM_32: - case QAM_64: - delay = 100; - sweeprate = 1500; - break; - - case QAM_128: - delay = 150; - sweeprate = 1000; - break; - - case QAM_256: - delay = 200; - sweeprate = 500; - break; - - default: - return -EINVAL; - } - - // determine inversion dependant parameters + switch (p->u.qam.modulation) { + case QAM_16: + case QAM_32: + case QAM_64: + delay = 100; + sweeprate = 1000; + break; + + case QAM_128: + case QAM_256: + delay = 200; + sweeprate = 500; + break; + + default: + return -EINVAL; + } + + // determine inversion dependant parameters inversion = p->inversion; if (state->config->invert) inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - carrieroffset = -330; + carrieroffset = -330; switch (inversion) { - case INVERSION_OFF: - break; + case INVERSION_OFF: + break; - case INVERSION_ON: - sweeprate = -sweeprate; - carrieroffset = -carrieroffset; - break; + case INVERSION_ON: + sweeprate = -sweeprate; + carrieroffset = -carrieroffset; + break; - default: - return -EINVAL; - } + default: + return -EINVAL; + } stv0297_init(fe); - state->config->pll_set(fe, p); + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + } /* clear software interrupts */ stv0297_writereg(state, 0x82, 0x0); @@ -562,163 +444,169 @@ static int stv0297_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par stv0297_set_initialdemodfreq(state, 7250); /* setup AGC */ - stv0297_writereg_mask(state, 0x43, 0x10, 0x00); - stv0297_writereg(state, 0x41, 0x00); - stv0297_writereg_mask(state, 0x42, 0x03, 0x01); - stv0297_writereg_mask(state, 0x36, 0x60, 0x00); - stv0297_writereg_mask(state, 0x36, 0x18, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x80); - stv0297_writereg(state, 0x72, 0x00); - stv0297_writereg(state, 0x73, 0x00); - stv0297_writereg_mask(state, 0x74, 0x0F, 0x00); - stv0297_writereg_mask(state, 0x43, 0x08, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x00); + stv0297_writereg_mask(state, 0x43, 0x10, 0x00); + stv0297_writereg(state, 0x41, 0x00); + stv0297_writereg_mask(state, 0x42, 0x03, 0x01); + stv0297_writereg_mask(state, 0x36, 0x60, 0x00); + stv0297_writereg_mask(state, 0x36, 0x18, 0x00); + stv0297_writereg_mask(state, 0x71, 0x80, 0x80); + stv0297_writereg(state, 0x72, 0x00); + stv0297_writereg(state, 0x73, 0x00); + stv0297_writereg_mask(state, 0x74, 0x0F, 0x00); + stv0297_writereg_mask(state, 0x43, 0x08, 0x00); + stv0297_writereg_mask(state, 0x71, 0x80, 0x00); /* setup STL */ - stv0297_writereg_mask(state, 0x5a, 0x20, 0x20); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x02); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x00); - stv0297_writereg_mask(state, 0x5b, 0x01, 0x00); - stv0297_writereg_mask(state, 0x5a, 0x40, 0x40); + stv0297_writereg_mask(state, 0x5a, 0x20, 0x20); + stv0297_writereg_mask(state, 0x5b, 0x02, 0x02); + stv0297_writereg_mask(state, 0x5b, 0x02, 0x00); + stv0297_writereg_mask(state, 0x5b, 0x01, 0x00); + stv0297_writereg_mask(state, 0x5a, 0x40, 0x40); /* disable frequency sweep */ - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); + stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); /* reset deinterleaver */ - stv0297_writereg_mask(state, 0x81, 0x01, 0x01); - stv0297_writereg_mask(state, 0x81, 0x01, 0x00); + stv0297_writereg_mask(state, 0x81, 0x01, 0x01); + stv0297_writereg_mask(state, 0x81, 0x01, 0x00); /* ??? */ - stv0297_writereg_mask(state, 0x83, 0x20, 0x20); - stv0297_writereg_mask(state, 0x83, 0x20, 0x00); + stv0297_writereg_mask(state, 0x83, 0x20, 0x20); + stv0297_writereg_mask(state, 0x83, 0x20, 0x00); /* reset equaliser */ - u_threshold = stv0297_readreg(state, 0x00) & 0xf; - initial_u = stv0297_readreg(state, 0x01) >> 4; - blind_u = stv0297_readreg(state, 0x01) & 0xf; - stv0297_writereg_mask(state, 0x84, 0x01, 0x01); - stv0297_writereg_mask(state, 0x84, 0x01, 0x00); - stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold); - stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4); - stv0297_writereg_mask(state, 0x01, 0x0f, blind_u); + u_threshold = stv0297_readreg(state, 0x00) & 0xf; + initial_u = stv0297_readreg(state, 0x01) >> 4; + blind_u = stv0297_readreg(state, 0x01) & 0xf; + stv0297_writereg_mask(state, 0x84, 0x01, 0x01); + stv0297_writereg_mask(state, 0x84, 0x01, 0x00); + stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold); + stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4); + stv0297_writereg_mask(state, 0x01, 0x0f, blind_u); /* data comes from internal A/D */ - stv0297_writereg_mask(state, 0x87, 0x80, 0x00); + stv0297_writereg_mask(state, 0x87, 0x80, 0x00); /* clear phase registers */ - stv0297_writereg(state, 0x63, 0x00); - stv0297_writereg(state, 0x64, 0x00); - stv0297_writereg(state, 0x65, 0x00); - stv0297_writereg(state, 0x66, 0x00); - stv0297_writereg(state, 0x67, 0x00); - stv0297_writereg(state, 0x68, 0x00); - stv0297_writereg_mask(state, 0x69, 0x0f, 0x00); + stv0297_writereg(state, 0x63, 0x00); + stv0297_writereg(state, 0x64, 0x00); + stv0297_writereg(state, 0x65, 0x00); + stv0297_writereg(state, 0x66, 0x00); + stv0297_writereg(state, 0x67, 0x00); + stv0297_writereg(state, 0x68, 0x00); + stv0297_writereg_mask(state, 0x69, 0x0f, 0x00); /* set parameters */ - stv0297_set_qam(state, p->u.qam.modulation); - stv0297_set_symbolrate(state, p->u.qam.symbol_rate/1000); + stv0297_set_qam(state, p->u.qam.modulation); + stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000); stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000); - stv0297_set_carrieroffset(state, carrieroffset); + stv0297_set_carrieroffset(state, carrieroffset); stv0297_set_inversion(state, inversion); /* kick off lock */ - stv0297_writereg_mask(state, 0x88, 0x08, 0x08); - stv0297_writereg_mask(state, 0x5a, 0x20, 0x00); - stv0297_writereg_mask(state, 0x6a, 0x01, 0x01); - stv0297_writereg_mask(state, 0x43, 0x40, 0x40); - stv0297_writereg_mask(state, 0x5b, 0x30, 0x00); - stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c); - stv0297_writereg_mask(state, 0x03, 0x03, 0x03); - stv0297_writereg_mask(state, 0x43, 0x10, 0x10); + /* Disable corner detection for higher QAMs */ + if (p->u.qam.modulation == QAM_128 || + p->u.qam.modulation == QAM_256) + stv0297_writereg_mask(state, 0x88, 0x08, 0x00); + else + stv0297_writereg_mask(state, 0x88, 0x08, 0x08); + + stv0297_writereg_mask(state, 0x5a, 0x20, 0x00); + stv0297_writereg_mask(state, 0x6a, 0x01, 0x01); + stv0297_writereg_mask(state, 0x43, 0x40, 0x40); + stv0297_writereg_mask(state, 0x5b, 0x30, 0x00); + stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c); + stv0297_writereg_mask(state, 0x03, 0x03, 0x03); + stv0297_writereg_mask(state, 0x43, 0x10, 0x10); /* wait for WGAGC lock */ - starttime = jiffies; - timeout = jiffies + (200*HZ)/1000; - while(time_before(jiffies, timeout)) { - msleep(10); + starttime = jiffies; + timeout = jiffies + msecs_to_jiffies(2000); + while (time_before(jiffies, timeout)) { + msleep(10); if (stv0297_readreg(state, 0x43) & 0x08) break; - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(20); + } + if (time_after(jiffies, timeout)) { + goto timeout; + } + msleep(20); /* wait for equaliser partial convergence */ - timeout = jiffies + (50*HZ)/1000; - while(time_before(jiffies, timeout)) { - msleep(10); + timeout = jiffies + msecs_to_jiffies(500); + while (time_before(jiffies, timeout)) { + msleep(10); - if (stv0297_readreg(state, 0x82) & 0x04) { + if (stv0297_readreg(state, 0x82) & 0x04) { break; - } - } + } + } if (time_after(jiffies, timeout)) { - goto timeout; - } + goto timeout; + } /* wait for equaliser full convergence */ - timeout = jiffies + (delay*HZ)/1000; - while(time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0x82) & 0x08) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } + timeout = jiffies + msecs_to_jiffies(delay); + while (time_before(jiffies, timeout)) { + msleep(10); + + if (stv0297_readreg(state, 0x82) & 0x08) { + break; + } + } + if (time_after(jiffies, timeout)) { + goto timeout; + } /* disable sweep */ - stv0297_writereg_mask(state, 0x6a, 1, 0); - stv0297_writereg_mask(state, 0x88, 8, 0); + stv0297_writereg_mask(state, 0x6a, 1, 0); + stv0297_writereg_mask(state, 0x88, 8, 0); /* wait for main lock */ - timeout = jiffies + (20*HZ)/1000; - while(time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0xDF) & 0x80) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(100); + timeout = jiffies + msecs_to_jiffies(20); + while (time_before(jiffies, timeout)) { + msleep(10); + + if (stv0297_readreg(state, 0xDF) & 0x80) { + break; + } + } + if (time_after(jiffies, timeout)) { + goto timeout; + } + msleep(100); /* is it still locked after that delay? */ - if (!(stv0297_readreg(state, 0xDF) & 0x80)) { - goto timeout; - } + if (!(stv0297_readreg(state, 0xDF) & 0x80)) { + goto timeout; + } /* success!! */ - stv0297_writereg_mask(state, 0x5a, 0x40, 0x00); - state->base_freq = p->frequency; - return 0; + stv0297_writereg_mask(state, 0x5a, 0x40, 0x00); + state->base_freq = p->frequency; + return 0; timeout: - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); - return 0; + stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); + return 0; } -static int stv0297_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) +static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - int reg_00, reg_83; + struct stv0297_state *state = fe->demodulator_priv; + int reg_00, reg_83; - reg_00 = stv0297_readreg(state, 0x00); - reg_83 = stv0297_readreg(state, 0x83); + reg_00 = stv0297_readreg(state, 0x00); + reg_83 = stv0297_readreg(state, 0x83); p->frequency = state->base_freq; - p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF; + p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF; if (state->config->invert) p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000; p->u.qam.fec_inner = FEC_NONE; - switch((reg_00 >> 4) & 0x7) { + switch ((reg_00 >> 4) & 0x7) { case 0: p->u.qam.modulation = QAM_16; break; @@ -734,77 +622,75 @@ static int stv0297_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par case 4: p->u.qam.modulation = QAM_64; break; - } + } - return 0; + return 0; } -static void stv0297_release(struct dvb_frontend* fe) +static void stv0297_release(struct dvb_frontend *fe) { - struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv; - kfree(state); + struct stv0297_state *state = fe->demodulator_priv; + kfree(state); } static struct dvb_frontend_ops stv0297_ops; -struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter *i2c, int pwm) +struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, + struct i2c_adapter *i2c) { - struct stv0297_state* state = NULL; + struct stv0297_state *state = NULL; - /* allocate memory for the internal state */ - state = (struct stv0297_state*) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); if (state == NULL) goto error; - /* setup the state */ - state->config = config; - state->i2c = i2c; - memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); - state->base_freq = 0; - state->pwm = pwm; + /* setup the state */ + state->config = config; + state->i2c = i2c; + state->base_freq = 0; - /* check if the demod is there */ + /* check if the demod is there */ if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20) goto error; - /* create dvb_frontend */ - state->frontend.ops = &state->ops; - state->frontend.demodulator_priv = state; - return &state->frontend; + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; error: - if (state) - kfree(state); - return NULL; + kfree(state); + return NULL; } static struct dvb_frontend_ops stv0297_ops = { - .info = { - .name = "ST STV0297 DVB-C", - .type = FE_QAM, - .frequency_min = 64000000, - .frequency_max = 1300000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 870000, - .symbol_rate_max = 11700000, - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | + .info = { + .name = "ST STV0297 DVB-C", + .type = FE_QAM, + .frequency_min = 64000000, + .frequency_max = 1300000000, + .frequency_stepsize = 62500, + .symbol_rate_min = 870000, + .symbol_rate_max = 11700000, + .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO}, - .release = stv0297_release, + .release = stv0297_release, - .init = stv0297_init, + .init = stv0297_init, .sleep = stv0297_sleep, + .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, - .set_frontend = stv0297_set_frontend, - .get_frontend = stv0297_get_frontend, + .set_frontend = stv0297_set_frontend, + .get_frontend = stv0297_get_frontend, - .read_status = stv0297_read_status, - .read_ber = stv0297_read_ber, - .read_signal_strength = stv0297_read_signal_strength, - .read_snr = stv0297_read_snr, - .read_ucblocks = stv0297_read_ucblocks, + .read_status = stv0297_read_status, + .read_ber = stv0297_read_ber, + .read_signal_strength = stv0297_read_signal_strength, + .read_snr = stv0297_read_snr, + .read_ucblocks = stv0297_read_ucblocks, }; MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver"); @@ -812,4 +698,3 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(stv0297_attach); -EXPORT_SYMBOL(stv0297_enable_plli2c);