Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0eb3de20 authored by Hartmut Hackmann's avatar Hartmut Hackmann Committed by Mauro Carvalho Chehab
Browse files

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: default avatarHartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 0157a9cc
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -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 */
	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;
	}
+2 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ enum tda10046_agc {
	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_GPL,	/* same as above, but GPIOs 0 */
};

enum tda10046_if {