mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
V4L/DVB (3304): TDA10046 Driver update
- Set outputs to tristate in sleep mode - Reduce dangerously high firmware download speed with 16MHz xtal - added tda827x configuration with GPIOs low - added comments to stupid looking IIC reads that work around bugs in the tda10046. - some minor updates Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
0157a9cc72
commit
0eb3de20a1
2 changed files with 23 additions and 5 deletions
|
@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
|
|||
dprintk("%s\n", __FUNCTION__);
|
||||
|
||||
result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
|
||||
msleep(1);
|
||||
msleep(20);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
|
|||
const struct firmware *fw;
|
||||
|
||||
/* reset + wake up chip */
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
|
||||
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
|
||||
} else {
|
||||
dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
|
||||
}
|
||||
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
|
||||
/* let the clocks recover from sleep */
|
||||
msleep(5);
|
||||
|
@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe)
|
|||
// tda setup
|
||||
tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
|
||||
tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer
|
||||
|
||||
switch (state->config->agc_config) {
|
||||
case TDA10046_AGC_DEFAULT:
|
||||
|
@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe)
|
|||
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
|
||||
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
|
||||
break;
|
||||
case TDA10046_AGC_TDA827X_GPL:
|
||||
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
|
||||
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
|
||||
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
|
||||
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
|
||||
break;
|
||||
}
|
||||
tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
|
||||
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
|
||||
|
@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe)
|
|||
tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
|
||||
tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
|
||||
tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
|
||||
// tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
|
||||
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
|
||||
|
||||
state->initialised = 1;
|
||||
|
@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
|
|||
if (status == -1)
|
||||
return -EIO;
|
||||
cber |= (status << 8);
|
||||
// The address 0x20 should be read to cope with a TDA10046 bug
|
||||
tda1004x_read_byte(state, TDA1004X_CBER_RESET);
|
||||
|
||||
if (cber != 65535)
|
||||
|
@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
|
|||
status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
|
||||
if (status == -1)
|
||||
return -EIO;
|
||||
vber |= ((status << 16) & 0x0f);
|
||||
vber |= (status & 0x0f) << 16;
|
||||
// The CVBER_LUT should be read to cope with TDA10046 hardware bug
|
||||
tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
|
||||
|
||||
// if RS has passed some valid TS packets, then we must be
|
||||
|
@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
|
|||
if (tmp < 0)
|
||||
return -EIO;
|
||||
*ber |= (tmp << 9);
|
||||
// The address 0x20 should be read to cope with a TDA10046 bug
|
||||
tda1004x_read_byte(state, TDA1004X_CBER_RESET);
|
||||
|
||||
dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
|
||||
|
@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
|
|||
tda1004x_disable_tuner_i2c(state);
|
||||
}
|
||||
}
|
||||
/* set outputs to tristate */
|
||||
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
|
||||
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ enum tda10046_agc {
|
|||
TDA10046_AGC_DEFAULT, /* original configuration */
|
||||
TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
|
||||
TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
|
||||
TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
|
||||
TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
|
||||
TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */
|
||||
};
|
||||
|
||||
enum tda10046_if {
|
||||
|
|
Loading…
Reference in a new issue