Re: Wintv Nova-S-Plus: Missing Channels - Patch 2 fails tuning to high band

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



OK, many thanks to Leif for giving me access to a box to try stuff out on. 
This patch should give full tone/voltage/toneburst/diseqc now. 

We noticed some strange problems though; certain channels do not tune.. as far 
as I know it isn't DISEQC/SEC related since I can tune to other channels from 
the full combination of the possible SEC parameters. I'll see if I can spot 
anything obvious in the tuning.
diff -r efc16f26bc6e linux/drivers/media/dvb/frontends/cx24123.c
--- a/linux/drivers/media/dvb/frontends/cx24123.c	Thu May 11 09:21:14 2006 -0300
+++ b/linux/drivers/media/dvb/frontends/cx24123.c	Thu May 11 23:49:40 2006 +0200
@@ -48,7 +48,6 @@ struct cx24123_state
 
 	u32 lastber;
 	u16 snr;
-	u8  lnbreg;
 
 	/* Some PLL specifics for tuning */
 	u32 VCAarg;
@@ -260,29 +259,6 @@ static int cx24123_writereg(struct cx241
 	return 0;
 }
 
-static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
-{
-	u8 buf[] = { reg, data };
-	/* fixme: put the intersil addr int the config */
-	struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
-	int err;
-
-	if (debug>1)
-		printk("cx24123: %s:  writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
-						__FUNCTION__,reg, data);
-
-	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-		printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
-			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
-		return -EREMOTEIO;
-	}
-
-	/* cache the write, no way to read back */
-	state->lnbreg = data;
-
-	return 0;
-}
-
 static int cx24123_readreg(struct cx24123_state* state, u8 reg)
 {
 	int ret;
@@ -304,11 +280,6 @@ static int cx24123_readreg(struct cx2412
 		printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret);
 
 	return b1[0];
-}
-
-static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
-{
-	return state->lnbreg;
 }
 
 static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
@@ -698,10 +669,6 @@ static int cx24123_initfe(struct dvb_fro
 	for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
 		cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
 
-	/* Configure the LNB for 14V */
-	if (state->config->use_isl6421)
-		cx24123_writelnbreg(state, 0x0, 0x2a);
-
 	return 0;
 }
 
@@ -710,50 +677,18 @@ static int cx24123_set_voltage(struct dv
 	struct cx24123_state *state = fe->demodulator_priv;
 	u8 val;
 
-	switch (state->config->use_isl6421) {
-
-	case 1:
-
-		val = cx24123_readlnbreg(state, 0x0);
-
-		switch (voltage) {
-		case SEC_VOLTAGE_13:
-			dprintk("%s:  isl6421 voltage = 13V\n",__FUNCTION__);
-			return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
-		case SEC_VOLTAGE_18:
-			dprintk("%s:  isl6421 voltage = 18V\n",__FUNCTION__);
-			return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
-		case SEC_VOLTAGE_OFF:
-			dprintk("%s:  isl5421 voltage off\n",__FUNCTION__);
-			return cx24123_writelnbreg(state, 0x0, val & 0x30);
-		default:
-			return -EINVAL;
-		};
-
-	case 0:
-
-		val = cx24123_readreg(state, 0x29);
-
-		switch (voltage) {
-		case SEC_VOLTAGE_13:
-			dprintk("%s: setting voltage 13V\n", __FUNCTION__);
-			if (state->config->enable_lnb_voltage)
-				state->config->enable_lnb_voltage(fe, 1);
-			return cx24123_writereg(state, 0x29, val | 0x80);
-		case SEC_VOLTAGE_18:
-			dprintk("%s: setting voltage 18V\n", __FUNCTION__);
-			if (state->config->enable_lnb_voltage)
-				state->config->enable_lnb_voltage(fe, 1);
-			return cx24123_writereg(state, 0x29, val & 0x7f);
-		case SEC_VOLTAGE_OFF:
-			dprintk("%s: setting voltage off\n", __FUNCTION__);
-			if (state->config->enable_lnb_voltage)
-				state->config->enable_lnb_voltage(fe, 0);
-			return 0;
-		default:
-			return -EINVAL;
-		};
-	}
+	val = cx24123_readreg(state, 0x29) & ~0x40;
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		dprintk("%s: setting voltage 13V\n", __FUNCTION__);
+		return cx24123_writereg(state, 0x29, val | 0x80);
+	case SEC_VOLTAGE_18:
+		dprintk("%s: setting voltage 18V\n", __FUNCTION__);
+		return cx24123_writereg(state, 0x29, val & 0x7f);
+	default:
+		return -EINVAL;
+	};
 
 	return 0;
 }
@@ -774,27 +709,20 @@ static int cx24123_send_diseqc_msg(struc
 static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
-	int i, val;
+	int i, val, tone;
 
 	dprintk("%s:\n",__FUNCTION__);
 
-	/* check if continuous tone has been stopped */
-	if (state->config->use_isl6421)
-		val = cx24123_readlnbreg(state, 0x00) & 0x10;
-	else
-		val = cx24123_readreg(state, 0x29) & 0x10;
-
-
-	if (val) {
-		printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
-		return -ENOTSUPP;
-	}
+	/* stop continuous tone if enabled */
+	tone = cx24123_readreg(state, 0x29);
+	if (tone & 0x10)
+		cx24123_writereg(state, 0x29, tone & ~0x50);
 
 	/* wait for diseqc queue ready */
 	cx24123_wait_for_diseqc(state);
 
 	/* select tone mode */
-	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8);
+	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
 
 	for (i = 0; i < cmd->msg_len; i++)
 		cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
@@ -805,36 +733,33 @@ static int cx24123_send_diseqc_msg(struc
 	/* wait for diseqc message to finish sending */
 	cx24123_wait_for_diseqc(state);
 
+	/* restart continuous tone if enabled */
+	if (tone & 0x10) {
+		cx24123_writereg(state, 0x29, tone & ~0x40);
+	}
+
 	return 0;
 }
 
 static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
-	int val;
+	int val, tone;
 
 	dprintk("%s:\n", __FUNCTION__);
 
-	/* check if continuous tone has been stoped */
-	if (state->config->use_isl6421)
-		val = cx24123_readlnbreg(state, 0x00) & 0x10;
-	else
-		val = cx24123_readreg(state, 0x29) & 0x10;
-
-
-	if (val) {
-		printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
-		return -ENOTSUPP;
-	}
-
+	/* stop continuous tone if enabled */
+	tone = cx24123_readreg(state, 0x29);
+	if (tone & 0x10)
+		cx24123_writereg(state, 0x29, tone & ~0x50);
+
+	/* wait for diseqc queue ready */
 	cx24123_wait_for_diseqc(state);
 
 	/* select tone mode */
-	val = cx24123_readreg(state, 0x2a) & 0xf8;
-	cx24123_writereg(state, 0x2a, val | 0x04);
-
+	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
+	msleep(30);
 	val = cx24123_readreg(state, 0x29);
-
 	if (burst == SEC_MINI_A)
 		cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
 	else if (burst == SEC_MINI_B)
@@ -843,7 +768,12 @@ static int cx24123_diseqc_send_burst(str
 		return -EINVAL;
 
 	cx24123_wait_for_diseqc(state);
-
+        cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
+
+	/* restart continuous tone if enabled */
+	if (tone & 0x10) {
+		cx24123_writereg(state, 0x29, tone & ~0x40);
+	}	
 	return 0;
 }
 
@@ -984,38 +914,21 @@ static int cx24123_set_tone(struct dvb_f
 	struct cx24123_state *state = fe->demodulator_priv;
 	u8 val;
 
-	switch (state->config->use_isl6421) {
-	case 1:
-
-		val = cx24123_readlnbreg(state, 0x0);
-
-		switch (tone) {
-		case SEC_TONE_ON:
-			dprintk("%s:  isl6421 sec tone on\n",__FUNCTION__);
-			return cx24123_writelnbreg(state, 0x0, val | 0x10);
-		case SEC_TONE_OFF:
-			dprintk("%s:  isl6421 sec tone off\n",__FUNCTION__);
-			return cx24123_writelnbreg(state, 0x0, val & 0x2f);
-		default:
-			printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
-			return -EINVAL;
-		}
-
-	case 0:
-
-		val = cx24123_readreg(state, 0x29);
-
-		switch (tone) {
-		case SEC_TONE_ON:
-			dprintk("%s: setting tone on\n", __FUNCTION__);
-			return cx24123_writereg(state, 0x29, val | 0x10);
-		case SEC_TONE_OFF:
-			dprintk("%s: setting tone off\n",__FUNCTION__);
-			return cx24123_writereg(state, 0x29, val & 0xef);
-		default:
-			printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
-			return -EINVAL;
-		}
+	/* wait for diseqc queue ready */
+	cx24123_wait_for_diseqc(state);
+
+	val = cx24123_readreg(state, 0x29) & ~0x40;
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		dprintk("%s: setting tone on\n", __FUNCTION__);
+		return cx24123_writereg(state, 0x29, val | 0x10);
+	case SEC_TONE_OFF:
+		dprintk("%s: setting tone off\n",__FUNCTION__);
+		return cx24123_writereg(state, 0x29, val & 0xef);
+	default:
+		printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
+		return -EINVAL;
 	}
 
 	return 0;
@@ -1051,7 +964,6 @@ struct dvb_frontend* cx24123_attach(cons
 	memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
 	state->lastber = 0;
 	state->snr = 0;
-	state->lnbreg = 0;
 	state->VCAarg = 0;
 	state->VGAarg = 0;
 	state->bandselectarg = 0;
diff -r efc16f26bc6e linux/drivers/media/dvb/frontends/cx24123.h
--- a/linux/drivers/media/dvb/frontends/cx24123.h	Thu May 11 09:21:14 2006 -0300
+++ b/linux/drivers/media/dvb/frontends/cx24123.h	Thu May 11 23:49:40 2006 +0200
@@ -28,17 +28,8 @@ struct cx24123_config
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
-	/*
-	   cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
-	   for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
-	   from register 0x29 of the CX24123 demodulator
-	*/
-	int use_isl6421;
-
 	/* Need to set device param for start_dma */
 	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
-
-	void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
 };
 
 extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
diff -r efc16f26bc6e linux/drivers/media/video/cx88/Kconfig
--- a/linux/drivers/media/video/cx88/Kconfig	Thu May 11 09:21:14 2006 -0300
+++ b/linux/drivers/media/video/cx88/Kconfig	Thu May 11 23:49:40 2006 +0200
@@ -61,6 +61,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_LGDT330X
 	select DVB_NXT200X
 	select DVB_CX24123
+	select DVB_ISL6421
 	---help---
 	  This builds cx88-dvb with all currently supported frontend
 	  demodulators.  If you wish to tweak your configuration, and
@@ -139,6 +140,7 @@ config VIDEO_CX88_DVB_CX24123
 	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_CX24123
+	select DVB_ISL6421
 	---help---
 	  This adds DVB-S support for cards based on the
 	  Connexant 2388x chip and the CX24123 demodulator.
diff -r efc16f26bc6e linux/drivers/media/video/cx88/cx88-dvb.c
--- a/linux/drivers/media/video/cx88/cx88-dvb.c	Thu May 11 09:21:14 2006 -0300
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c	Thu May 11 23:49:40 2006 +0200
@@ -60,6 +60,7 @@
 #ifdef HAVE_CX24123
 # include "cx24123.h"
 #endif
+#include "isl6421.h"
 
 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@xxxxxxxxxxxxxx>");
@@ -480,28 +481,30 @@ static int cx24123_set_ts_param(struct d
 	return 0;
 }
 
-static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
+static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
 	struct cx8802_dev *dev= fe->dvb->priv;
 	struct cx88_core *core = dev->core;
 
-	if (on)
+	if (voltage == SEC_VOLTAGE_OFF) {
+		cx_write(MO_GP0_IO, 0x000006fB);
+	} else {
 		cx_write(MO_GP0_IO, 0x000006f9);
-	else
-		cx_write(MO_GP0_IO, 0x000006fB);
+	}
+
+	if (core->prev_set_voltage)
+		return core->prev_set_voltage(fe, voltage);
+	return 0;
 }
 
 static struct cx24123_config hauppauge_novas_config = {
 	.demod_address		= 0x55,
-	.use_isl6421		= 1,
 	.set_ts_params		= cx24123_set_ts_param,
 };
 
 static struct cx24123_config kworld_dvbs_100_config = {
 	.demod_address		= 0x15,
-	.use_isl6421		= 0,
 	.set_ts_params		= cx24123_set_ts_param,
-	.enable_lnb_voltage	= cx24123_enable_lnb_voltage,
 };
 #endif
 
@@ -711,10 +714,17 @@ static int dvb_register(struct cx8802_de
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 		dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
 			&dev->core->i2c_adap);
+		if (dev->dvb.frontend) {
+			isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap, 0x08, 0x00, 0x00);
+		}
 		break;
 	case CX88_BOARD_KWORLD_DVBS_100:
 		dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
 			&dev->core->i2c_adap);
+		if (dev->dvb.frontend) {
+			dev->core->prev_set_voltage = dev->dvb.frontend->ops->set_voltage;
+			dev->dvb.frontend->ops->set_voltage = kworld_dvbs_100_set_voltage;
+		}
 		break;
 #endif
 	default:
diff -r efc16f26bc6e linux/drivers/media/video/cx88/cx88.h
--- a/linux/drivers/media/video/cx88/cx88.h	Thu May 11 09:21:14 2006 -0300
+++ b/linux/drivers/media/video/cx88/cx88.h	Thu May 11 23:49:40 2006 +0200
@@ -309,6 +309,7 @@ struct cx88_core {
 	/* config info -- dvb */
 	struct dvb_pll_desc        *pll_desc;
 	unsigned int               pll_addr;
+	int 			   (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
 
 	/* state info */
 	struct task_struct         *kthread;
_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux