diff mbox

UBUNTU: (pre-stable) Natty - dvb channel switching timeout fix

Message ID 4D9D7F09.8080509@t-online.de
State New
Headers show

Commit Message

Rico Tzschichholz April 7, 2011, 9:08 a.m. UTC
Hello,

i'd like to request the inclusion of the attached patch which can be
found here: https://patchwork.kernel.org/patch/244201/

Since upgrading to 2.6.38.x the usage of stb0899-based DVB cards like
S2-3200 (TT3200) is quite broken. Trying to get a channel-lock results
mostly in a timeout.
This patch fixes the problem as proposed and make channel switching
faster. Unfortunately it isn't included upstream yet.

best regards,
Rico Tzschichholz

Comments

Tim Gardner April 7, 2011, 1:54 p.m. UTC | #1
On 04/07/2011 03:08 AM, Rico Tzschichholz wrote:
> Hello,
>
> i'd like to request the inclusion of the attached patch which can be
> found here: https://patchwork.kernel.org/patch/244201/
>
> Since upgrading to 2.6.38.x the usage of stb0899-based DVB cards like
> S2-3200 (TT3200) is quite broken. Trying to get a channel-lock results
> mostly in a timeout.
> This patch fixes the problem as proposed and make channel switching
> faster. Unfortunately it isn't included upstream yet.
>
> best regards,
> Rico Tzschichholz
>

I'd prefer to wait until this has gone upstream because I don't think 
its gonna make it in its current form. It appears that this single patch 
is composed of at least 2 logic steps. Given that it fixes current 
functionality there is no reason that it cannot get included in 2.6.39, 
but it needs to go through the regular upstream review process.

rtg
diff mbox

Patch

From patchwork Sun Oct 10 15:08:27 2010
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: [v2] V4L/DVB: faster DVB-S lock for mantis cards using stb0899 demod
Date: Sun, 10 Oct 2010 15:08:27 -0000
From: Tuxoholic <tuxoholic@hotmail.de>
X-Patchwork-Id: 244201
Message-Id: <BLU0-SMTP58AB09E7C9178301416281D8520@phx.gbl>
To: linux-media@vger.kernel.org
Cc: manu@linuxtv.org

hi list

This is a modified version of my previous patch [1] to improve the tuning algo 
of stb0899 cards using the mantis bridge.

With the kind help of Bjørn Mork I was able to keep it minimally invasive with 
the same effect.

Over the last month many testers in vdr-portal.de [2] reported positive 
results using the patch.

This should run fine with all sort of cards using the stb0899 demodulator.

[1] http://www.spinics.net/lists/linux-media/msg23181.html
[2] http://www.vdr-portal.de/board/thread.php?threadid=99603

Signed-off-by: SE <tuxoholic@hotmail.de>


diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index 2da55ec..3efde1e 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -206,7 +206,6 @@  static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
 static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
 {
 	struct stb0899_internal *internal = &state->internal;
-	struct stb0899_params *params = &state->params;
 
 	short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
 	int index = 0;
@@ -216,10 +215,9 @@  static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
 
 	/* timing loop computation & symbol rate optimisation	*/
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
-	derot_step = (params->srate / 2L) / internal->mclk;
+	derot_step = internal->derot_step * 4;				/* dertot_step = decreasing delta */
 
 	while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
-		index++;
 		derot_freq += index * internal->direction * derot_step;	/* next derot zig zag position	*/
 
 		if (abs(derot_freq) > derot_limit)
@@ -230,6 +228,7 @@  static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
 			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
 			stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency		*/
 		}
+		index++;
 		internal->direction = -internal->direction;	/* Change zigzag direction		*/
 	}
 
@@ -278,14 +277,18 @@  static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
 {
 	struct stb0899_internal *internal = &state->internal;
 
-	short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
+	short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3;
 	int index = 0;
+	int base_freq;
 	u8 cfr[2];
 	u8 reg;
 
 	internal->status = NOCARRIER;
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
 	derot_freq = internal->derot_freq;
+	derot_step = internal->derot_step * 2;
+	last_derot_freq = internal->derot_freq;
+	base_freq = internal->derot_freq;
 
 	reg = stb0899_read_reg(state, STB0899_CFD);
 	STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
@@ -294,11 +297,10 @@  static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
 	do {
 		dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
 		if (stb0899_check_carrier(state) == NOCARRIER) {
-			index++;
 			last_derot_freq = derot_freq;
-			derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
+			derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position	*/
 
-			if(abs(derot_freq) > derot_limit)
+			if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
 				next_loop--;
 
 			if (next_loop) {
@@ -310,9 +312,10 @@  static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
 				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 			}
+			index++;
+			internal->direction = -internal->direction; /* Change zigzag direction */
 		}
 
-		internal->direction = -internal->direction; /* Change zigzag direction */
 	} while ((internal->status != CARRIEROK) && next_loop);
 
 	if (internal->status == CARRIEROK) {
@@ -338,6 +341,7 @@  static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
 	int lock = 0, index = 0, dataTime = 500, loop;
 	u8 reg;
 
+	msleep(1);
 	internal->status = NODATA;
 
 	/* RESET FEC	*/
@@ -348,6 +352,7 @@  static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
 	reg = stb0899_read_reg(state, STB0899_TSTRES);
 	STB0899_SETFIELD_VAL(FRESACS, reg, 0);
 	stb0899_write_reg(state, STB0899_TSTRES, reg);
+	msleep(1);
 
 	if (params->srate <= 2000000)
 		dataTime = 2000;
@@ -360,6 +365,7 @@  static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
 
 	stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop	*/
 	while (1) {
+		msleep(1); 		// Alex: added 1 mSec
 		/* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP	*/
 		reg = stb0899_read_reg(state, STB0899_VSTATUS);
 		lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
@@ -387,20 +393,21 @@  static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
 	short int derot_freq, derot_step, derot_limit, next_loop = 3;
 	u8 cfr[2];
 	u8 reg;
-	int index = 1;
+	int index = 0;
+	int base_freq;
 
 	struct stb0899_internal *internal = &state->internal;
-	struct stb0899_params *params = &state->params;
 
-	derot_step = (params->srate / 4L) / internal->mclk;
+	derot_step = internal->derot_step;
 	derot_limit = (internal->sub_range / 2L) / internal->mclk;
 	derot_freq = internal->derot_freq;
+	base_freq = internal->derot_freq;
 
 	do {
 		if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
 
 			derot_freq += index * internal->direction * derot_step;	/* next zig zag derotator position */
-			if (abs(derot_freq) > derot_limit)
+			if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit)
 				next_loop--;
 
 			if (next_loop) {
@@ -414,9 +421,9 @@  static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 
 				stb0899_check_carrier(state);
-				index++;
 			}
 		}
+		index++;
 		internal->direction = -internal->direction; /* change zig zag direction */
 	} while ((internal->status != DATAOK) && next_loop);
 
-- 
1.7.1