Commit 05ade5a5 authored by David Johnson's avatar David Johnson Committed by Linus Torvalds
Browse files

[PATCH] dvb: bt8xx: Nebula DigiTV mt352 support



Add support for Nebula DigiTV PCI cards with the MT352 frontend.

Signed-off-by: default avatarDavid Johnson <dj@david-web.co.uk>
Signed-off-by: default avatarJohannes Stezenbach <js@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1f15ddd0
Loading
Loading
Loading
Loading
+108 −33
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
		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;
@@ -150,7 +152,6 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
	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)
@@ -326,7 +327,6 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
	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)
@@ -416,8 +416,7 @@ static void or51211_reset(struct dvb_frontend * fe)
	/* 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);
	/* Now set for normal operation */
@@ -473,6 +472,80 @@ static struct nxt6000_config vp3021_alps_tded4_config = {
	.pll_set = vp3021_alps_tded4_pll_set,
};

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;
@@ -485,7 +558,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
		if (card->fe != NULL) {
			card->fe->ops->info.frequency_min = 174000000;
			card->fe->ops->info.frequency_max = 862000000;
			break;
		}
		break;
#endif
@@ -495,15 +567,26 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
#else
	case BTTV_NEBULA_DIGITV:
#endif
		/*
		 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
		 * this would be a cleaner solution than trying each frontend 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)
			break;
			dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");

		/* 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:
@@ -511,7 +594,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
		if (card->fe != NULL) {
			card->fe->ops->info.frequency_min = 174000000;
			card->fe->ops->info.frequency_max = 862000000;
			break;
		}
		break;

@@ -534,21 +616,14 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
		/*	Conditional Access device			*/
		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;
	}