V4L/DVB (9457): Optimization, Fix a Bug

* cut down some I/O operations by disabling "disable gate"
* budget_av was left with the gate open, thereby more susceptible
to RF interference due to I/O operations

Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index b775247..3cf9719 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -583,6 +583,9 @@
 		internal->derot_freq = 0;
 		internal->status = NOAGC1;
 
+		/* enable tuner I/O */
+		stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
 		/* Move tuner to frequency	*/
 		dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
 		if (state->config->tuner_set_frequency)
@@ -598,6 +601,10 @@
 		/* There is signal in the band	*/
 		if (config->tuner_get_bandwidth)
 			config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+
+		/* disable tuner I/O */
+		stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
 		if (params->srate <= bandwidth / 2)
 			stb0899_search_tmg(state); /* For low rates (SCPC)	*/
 		else
@@ -1325,12 +1332,18 @@
 	STB0899_SETFIELD_VAL(FRESRS, reg, 1);
 	stb0899_write_reg(state, STB0899_TSTRES, reg);
 
+	/* enable tuner I/O */
+	stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
 	/* Move tuner to frequency	*/
 	if (state->config->tuner_set_frequency)
 		state->config->tuner_set_frequency(&state->frontend, internal->freq);
 	if (state->config->tuner_get_frequency)
 		state->config->tuner_get_frequency(&state->frontend, &internal->freq);
 
+	/* disable tuner I/O */
+	stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
 	/* Set IF AGC to acquisition	*/
 	reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
 	STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  4);
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 196a837..333b983 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -1241,7 +1241,7 @@
 	return 0;
 }
 
-static int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
 	int i2c_stat;
 	struct stb0899_state *state = fe->demodulator_priv;
@@ -1255,10 +1255,15 @@
 		i2c_stat |=  STB0899_I2CTON;
 		if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
 			goto err;
+	} else {
+		dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
+		i2c_stat &= ~STB0899_I2CTON;
+		if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+			goto err;
 	}
 	return 0;
 err:
-	dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater enable failed");
+	dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
 	return -EREMOTEIO;
 }
 
@@ -1592,10 +1597,17 @@
 			internal->derot_percent	= 30;
 
 			/* What to do for tuners having no bandwidth setup ?	*/
+			/* enable tuner I/O */
+			stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
 			if (state->config->tuner_set_bandwidth)
 				state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
 			if (state->config->tuner_get_bandwidth)
 				state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+			/* disable tuner I/O */
+			stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
 			/* Set DVB-S1 AGC		*/
 			stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
 
@@ -1624,11 +1636,17 @@
 			internal->srate			= i_params->srate;
 			internal->srch_range		= SearchRange;
 
+			/* enable tuner I/O */
+			stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
 			if (state->config->tuner_set_bandwidth)
 				state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
 			if (state->config->tuner_get_bandwidth)
 				state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
 
+			/* disable tuner I/O */
+			stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
 //			pParams->SpectralInv		= pSearch->IQ_Inversion;
 
 			/* Set DVB-S2 AGC		*/
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
index 8a7c4ee..7552699 100644
--- a/drivers/media/dvb/frontends/stb0899_priv.h
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -253,6 +253,8 @@
 			       u16 stb0899_reg_offset,
 			       u32 stb0899_data);
 
+extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+
 
 #define STB0899_READ_S2REG(DEVICE, REG) 	(_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
 //#define STB0899_WRITE_S2REG(DEVICE, REG, DATA)	(_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index c8fdc1e..f404a4d 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -134,16 +134,7 @@
 		.len	= STB6100_NUMREGS
 	};
 
-	if (state->frontend->ops.i2c_gate_ctrl)
-		if ((rc = state->frontend->ops.i2c_gate_ctrl(state->frontend, 1)) < 0)
-			return rc;
-
 	rc = i2c_transfer(state->i2c, &msg, 1);
-	if (state->frontend->ops.i2c_gate_ctrl) {
-		int rc2;
-		if ((rc2 = state->frontend->ops.i2c_gate_ctrl(state->frontend, 0)) < 0)
-			return rc2;
-	}
 	if (unlikely(rc != 1)) {
 		dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
 			state->config->tuner_address, rc);
@@ -200,15 +191,7 @@
 		for (i = 0; i < len; i++)
 			dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
 	}
-	if (state->frontend->ops.i2c_gate_ctrl)
-		if ((rc = state->frontend->ops.i2c_gate_ctrl(state->frontend, 1)) < 0)
-			return rc;
 	rc = i2c_transfer(state->i2c, &msg, 1);
-	if (state->frontend->ops.i2c_gate_ctrl) {
-		int rc2;
-		if ((rc2 = state->frontend->ops.i2c_gate_ctrl(state->frontend, 0)) < 0)
-			return rc2;
-	}
 	if (unlikely(rc != 1)) {
 		dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
 			(unsigned int)state->config->tuner_address, start, len,	rc);
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
index 16e833f..b6d1777 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -37,14 +37,10 @@
 
 static int tda8261_read(struct tda8261_state *state, u8 *buf)
 {
-	struct dvb_frontend *fe = state->fe;
 	const struct tda8261_config *config = state->config;
 	int err = 0;
 	struct i2c_msg msg = { .addr	= config->addr, .flags = I2C_M_RD,.buf = buf,  .len = 2 };
 
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-
 	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
 		printk("%s: read error, err=%d\n", __func__, err);
 
@@ -53,14 +49,10 @@
 
 static int tda8261_write(struct tda8261_state *state, u8 *buf)
 {
-	struct dvb_frontend *fe = state->fe;
 	const struct tda8261_config *config = state->config;
 	int err = 0;
 	struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
 
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-
 	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
 		printk("%s: write error, err=%d\n", __func__, err);
 
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index d2b5cad..67a14c5 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -919,7 +919,7 @@
 	{ STB0899_IRQMSK_0		, 0xff },
 	{ STB0899_IRQCFG		, 0x00 },
 	{ STB0899_I2CCFG		, 0x88 },
-	{ STB0899_I2CRPT		, 0x5c },
+	{ STB0899_I2CRPT		, 0x58 }, /* Repeater=8, Stop=disabled */
 	{ STB0899_IOPVALUE5		, 0x00 },
 	{ STB0899_IOPVALUE4		, 0x20 },
 	{ STB0899_IOPVALUE3		, 0xc9 },
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 5b6dbcc..9cb8ff5 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1108,7 +1108,7 @@
 	{ STB0899_IRQMSK_0		, 0xff },
 	{ STB0899_IRQCFG		, 0x00 },
 	{ STB0899_I2CCFG        	, 0x88 },
-	{ STB0899_I2CRPT        	, 0x48 }, /* 12k Pullup */
+	{ STB0899_I2CRPT        	, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
 	{ STB0899_IOPVALUE5		, 0x00 },
 	{ STB0899_IOPVALUE4		, 0x20 },
 	{ STB0899_IOPVALUE3		, 0xc9 },