diff options
Diffstat (limited to 'v4l')
-rw-r--r-- | v4l/mt352.c | 151 | ||||
-rw-r--r-- | v4l/mt352.h | 13 | ||||
-rw-r--r-- | v4l/scripts/update | 2 |
3 files changed, 93 insertions, 73 deletions
diff --git a/v4l/mt352.c b/v4l/mt352.c index 7b0489dec..fe9ff3505 100644 --- a/v4l/mt352.c +++ b/v4l/mt352.c @@ -63,14 +63,13 @@ int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) struct mt352_state* state = (struct mt352_state*) fe->demodulator_priv; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = ibuf, .len = ilen }; -#if 0 - int i; - - printk("%s:",__FUNCTION__); - for (i = 0; i < ilen; i++) - printk(" %02x",ibuf[i]); - printk("\n"); -#endif + if (debug) { + int i; + printk("%s:",__FUNCTION__); + for (i = 0; i < ilen; i++) + printk(" %02x",ibuf[i]); + printk("\n"); + } int err = i2c_transfer(state->i2c, &msg, 1); if (err != 1) { @@ -94,11 +93,13 @@ static u8 mt352_read_register(struct mt352_state* state, u8 reg) .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - for (i = 0; i < 3; i++) { + for (i = 0; i < 5; i++) { ret = i2c_transfer(state->i2c, msg, 2); if (2 == ret) break; - udelay(10); + msleep(10); + dprintk("%s: readreg error #%d, retrying\n", + __FUNCTION__, i+1); } if (ret != 2) @@ -108,51 +109,74 @@ static u8 mt352_read_register(struct mt352_state* state, u8 reg) return b1[0]; } -static u8 mt352_register_dump(struct mt352_state* state) +static int mt352_sleep(struct dvb_frontend* fe) { - int i,val; + static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; - for (i = 0x50; i < 0x8f; i++) { - val = mt352_read_register(state,i); - printk("%s: %02x %02x\n",__FUNCTION__,i,val); - } + mt352_write(fe, mt352_softdown, sizeof(mt352_softdown)); + + return 0; } -static u8 mt352_state_dump(struct mt352_state* state) +static void mt352_calc_nominal_rate(struct mt352_state* state, + enum fe_bandwidth bandwidth, + unsigned char *buf) { - int i,val,agc,snr; - - printk("mt352: status:"); - for (i = STATUS_0; i <= STATUS_4; i++) { - val = mt352_read_register(state,i); - printk(" %02x",val); + u32 adc_clock = 20480; /* 20.340 MHz */ + u32 bw,value; + + switch (bandwidth) { + case BANDWIDTH_6_MHZ: + bw = 6; + break; + case BANDWIDTH_7_MHZ: + bw = 7; + break; + case BANDWIDTH_8_MHZ: + default: + bw = 8; + break; } - agc = 0; - agc |= mt352_read_register(state,AGC_GAIN_3) << 24; - agc |= mt352_read_register(state,AGC_GAIN_2) << 16; - agc |= mt352_read_register(state,AGC_GAIN_1) << 8; - agc |= mt352_read_register(state,AGC_GAIN_0); - snr = mt352_read_register(state,SNR); - printk(" agc: %5d snr: %02x\n", (~agc)>>16, snr); + if (state->config->adc_clock) + adc_clock = state->config->adc_clock; + + value = 64 * bw * (1<<16) / (7 * 8); + value = value * 1000 / adc_clock; + dprintk("%s: bw %d, adc_clock %d => 0x%x\n", + __FUNCTION__, bw, adc_clock, value); + buf[0] = msb(value); + buf[1] = lsb(value); } -static int mt352_sleep(struct dvb_frontend* fe) +static void mt352_calc_input_freq(struct mt352_state* state, + unsigned char *buf) { - static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; - - mt352_write(fe, mt352_softdown, sizeof(mt352_softdown)); - - return 0; + int adc_clock = 20480; /* 20.480000 MHz */ + int if2 = 36167; /* 36.166667 MHz */ + int ife,value; + + if (state->config->adc_clock) + adc_clock = state->config->adc_clock; + if (state->config->if2) + if2 = state->config->if2; + + ife = (2*adc_clock - if2); + value = -16374 * ife / adc_clock; + dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", + __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff); + buf[0] = msb(value); + buf[1] = lsb(value); } static int mt352_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) { struct mt352_state* state = (struct mt352_state*) fe->demodulator_priv; - unsigned char buf[14]; + unsigned char buf[13]; + static unsigned char tuner_go[] = { 0x5d, 0x01 }; + static unsigned char fsm_go[] = { 0x5e, 0x01 }; unsigned int tps = 0; struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - int i; switch (op->code_rate_HP) { case FEC_2_3: @@ -263,49 +287,32 @@ static int mt352_set_parameters(struct dvb_frontend* fe, buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */ buf[2] = lsb(tps); -// buf[3] = 0x50; - buf[3] = 0xf4; - - /** - * these settings assume 20.48MHz f_ADC, for other tuners you might - * need other values. See p. 33 in the MT352 Design Manual. - */ - if (op->bandwidth == BANDWIDTH_8_MHZ) { - buf[4] = 0x72; /* TRL_NOMINAL_RATE_(1|0) */ - buf[5] = 0x49; - } else if (op->bandwidth == BANDWIDTH_7_MHZ) { - buf[4] = 0x64; - buf[5] = 0x00; - } else { /* 6MHz */ - buf[4] = 0x55; - buf[5] = 0xb7; - } - - buf[6] = 0x31; /* INPUT_FREQ_(1|0), 20.48MHz clock, 36.166667MHz IF */ - buf[7] = 0x05; /* see MT352 Design Manual page 32 for details */ +// buf[3] = 0x50; // old + buf[3] = 0xf4; // pinnacle + mt352_calc_nominal_rate(state, op->bandwidth, buf+4); + mt352_calc_input_freq(state, buf+6); state->config->pll_set(fe, param, buf+8); - buf[13] = 0x01; /* TUNER_GO!! */ - -#if 0 +#if 0 /* FIXME: should be catched elsewhere ... */ /* Only send the tuning request if the tuner doesn't have the requested * parameters already set. Enhances tuning time and prevents stream * breakup when retuning the same transponder. */ for (i = 1; i < 13; i++) - if (buf[i] != mt352_read_register(state, i + 0x50)) { - mt352_write(fe, buf, sizeof(buf)); + if (buf[i] != mt352_read_register(state, i + 0x50)) break; - } -#else - mt352_write(fe, buf, sizeof(buf)); + if (13 == i) + /* no changes */ + return 0; #endif - if (0) - mt352_register_dump(state); - for (i = 0; i < 2; i++) { - msleep(500); - mt352_state_dump(state); + mt352_write(fe, buf, sizeof(buf)); + if (state->config->no_tuner) { + /* start decoding */ + mt352_write(fe, fsm_go, 2); + } else { + /* start tuning */ + mt352_write(fe, tuner_go, 2); } return 0; } @@ -498,7 +505,7 @@ static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) { - fe_tune_settings->min_delay_ms = 800 * 10000; + fe_tune_settings->min_delay_ms = 800; fe_tune_settings->step_size = 0; fe_tune_settings->max_drift = 0; diff --git a/v4l/mt352.h b/v4l/mt352.h index 635095b49..8bc032f7f 100644 --- a/v4l/mt352.h +++ b/v4l/mt352.h @@ -40,6 +40,13 @@ struct mt352_config /* the demodulator's i2c address */ u8 demod_address; + /* frequencies in kHz */ + int adc_clock; // default: 20480 + int if2; // default: 36166 + + /* set if no pll is connected to the secondary i2c bus */ + int no_tuner; + /* Initialise the demodulator and PLL. Cannot be NULL */ int (*demod_init)(struct dvb_frontend* fe); @@ -56,3 +63,9 @@ extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen); #endif // MT352_H + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/v4l/scripts/update b/v4l/scripts/update index 1a9731e47..0c2966ab5 100644 --- a/v4l/scripts/update +++ b/v4l/scripts/update @@ -99,5 +99,5 @@ xinsmod saa7134-empress xinsmod cx22702 debug=0 xinsmod mt352 debug=1 xinsmod video-buf-dvb -xinsmod cx88-dvb +#xinsmod cx88-dvb xinsmod saa7134-dvb |