[linux-dvb] Patch for Nebula DVB-T with MT352 Frontend

Mike Saywell dvb at saywell.net
Mon Apr 18 16:31:33 CEST 2005


On Mon, Apr 18, 2005 at 03:31:53PM +0200, Johannes Stezenbach wrote:
> Mike Saywell wrote:
> > Apologies if the code is a bit rough, it's the first time I've ever done
> > any driver code! ;)
> 
> I have a few comments:

Attached is an updated patch.

I've fixed the printk bug and applied your stylistic comments to the
entire file to maintain some continuity.

> > +		/* FIXME: Should probably choose the frontend intelligently rather than trying each in turn. */
> 
> if you can't do it based on PCI/USB ids then there's no other way, so
> please drop the comment

Nebula show a method of detecting it via the I2C bus in the SDK available
on their website.

Cheers,

Mike
-------------- next part --------------
--- dvb-bt8xx.c.old	2005-04-18 13:41:46.000000000 +0100
+++ dvb-bt8xx.c	2005-04-18 16:11:31.000000000 +0100
@@ -47,6 +47,8 @@
 		if (debug) printk(KERN_DEBUG args); \
 	} while (0)
 
+#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
+
 static void dvb_bt8xx_task(unsigned long data)
 {
 	struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
@@ -154,7 +156,6 @@
 	unsigned char bs = 0;
 	unsigned char cp = 0;
 
-	#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
 	div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
 
 	if (params->frequency < 542000000) cp = 0xb4;
@@ -323,7 +324,6 @@
 	unsigned char bs = 0;
 	unsigned char cp = 0;
 
-	#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
 	div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
 
 	if (params->frequency < 150000000) cp = 0xB4;
@@ -399,8 +399,7 @@
 	/* reset & PRM1,2&4 are outputs */
 	int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
 	if (ret != 0) {
-		printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
-		       "(%i)\n", ret);
+		printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
 	}
 	bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000);   /* Reset */
 	msleep(20);
@@ -461,6 +460,82 @@
 };
 
 
+
+static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
+{
+	static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+	static u8 mt352_reset [] = { 0x50, 0x80 };
+	static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 
+	static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
+	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+	udelay(2000);
+	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+	mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
+	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+	return 0;
+}
+
+
+static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
+{
+	u32 div;
+	struct dvb_ofdm_parameters *op = &params->u.ofdm;
+
+	div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+	pllbuf[0] = 0xc2;
+	pllbuf[1] = (div >> 8) & 0x7F;
+	pllbuf[2] = div & 0xFF;
+	pllbuf[3] = 0x85;
+
+	dprintk("frequency %u, div %u\n", params->frequency, div);
+
+	if (params->frequency < 470000000) pllbuf[4] = 0x02;
+	else if (params->frequency > 823000000) pllbuf[4] = 0x88;
+	else pllbuf[4] = 0x08;
+
+	if(op->bandwidth == 8)
+		pllbuf[4] |= 0x04;
+
+	return 0;
+}
+
+static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
+{
+	/*
+	 * Reset the frontend, must be called before trying
+	 * to initialise the MT352 or mt352_attach
+	 * will fail.
+	 *
+	 * Presumably not required for the NXT6000 frontend.
+	 *
+	 */
+
+	int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
+	if (ret != 0) {
+		printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
+	}
+
+	/* Pulse the reset line */
+	bttv_write_gpio(bt->bttv_nr, 0x08, 0x08);	/* High */
+	bttv_write_gpio(bt->bttv_nr, 0x08, 0x00);	/* Low  */
+	msleep(100);
+
+	bttv_write_gpio(bt->bttv_nr, 0x08, 0x08);	/* High */
+}
+
+
+static struct mt352_config digitv_alps_tded4_config = {
+	.demod_address = 0x0a,
+	.demod_init = digitv_alps_tded4_demod_init,
+	.pll_set = digitv_alps_tded4_pll_set,
+};
+
+
 static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 {
 	int ret;
@@ -473,7 +548,6 @@
 		if (card->fe != NULL) {
 			card->fe->ops->info.frequency_min = 174000000;
 			card->fe->ops->info.frequency_max = 862000000;
-			break;
 		}
 		break;
 #endif
@@ -483,17 +557,28 @@
 #else
 	case BTTV_NEBULA_DIGITV:
 #endif
+		/* FIXME: Should probably choose the frontend intelligently rather than trying each in turn. */
+
+		/* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
 		card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
+
 		if (card->fe != NULL) {
+			dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
 			break;
 		}
+
+		/* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
+		digitv_alps_tded4_reset(card);
+		card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
+
+		if (card->fe != NULL) {
+			dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
+		}
 		break;
 
+
 	case BTTV_AVDVBT_761:
 		card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
-		if (card->fe != NULL) {
-			break;
-		}
 		break;
 
 	case BTTV_AVDVBT_771:
@@ -501,7 +586,6 @@
 		if (card->fe != NULL) {
 			card->fe->ops->info.frequency_min = 174000000;
 			card->fe->ops->info.frequency_max = 862000000;
-			break;
 		}
 		break;
 
@@ -525,23 +609,14 @@
 		if (state->dst_hw_cap & DST_TYPE_HAS_CA) {
 			ret = dst_ca_attach(state, &card->dvb_adapter);
 		}
-		if (card->fe != NULL) {
-			break;
-		}
 		break;
 
 	case BTTV_PINNACLESAT:
 		card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
-		if (card->fe != NULL) {
-			break;
-		}
 		break;
 
 	case BTTV_PC_HDTV:
 		card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
-		if (card->fe != NULL) {
-			break;
-		}
 		break;
 	}
 


More information about the linux-dvb mailing list