Mailing List archive

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

[linux-dvb] [PATCH] mt352.c



Hi,

here is my final version. The diffs are against the current cvs-version. From 
my point of view they can be commited.

Wolfram

--- bt878.c.cvs	2004-06-07 19:51:03.000000000 +0200
+++ bt878.c	2004-06-07 19:54:02.000000000 +0200
@@ -293,7 +293,7 @@
 				       (astat & BT878_ASCERR) ? " SCERR" :
 				       "",
 				       (astat & BT878_AOCERR) ? " OCERR" :
-				       "", btread(BT878_ARISC_PC));
+				       "", le32_to_cpu(btread(BT878_ARISC_PC)));
 			}
 		}
 		if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
@@ -306,7 +306,7 @@
 				     (astat & BT878_ARIPERR) ? " RIPERR" :
 				     "",
 				     (astat & BT878_APPERR) ? " PPERR" :
-				     "", btread(BT878_ARISC_PC));
+				     "", le32_to_cpu(btread(BT878_ARISC_PC)));
 			}
 		}
 		if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
@@ -318,7 +318,7 @@
 				     (astat & BT878_AFTRGT) ? " FTRGT" :
 				     "",
 				     (astat & BT878_AFBUS) ? " FBUS" : "",
-				     btread(BT878_ARISC_PC));
+				     le32_to_cpu(btread(BT878_ARISC_PC)));
 			}
 		}
 		if (astat & BT878_ARISCI) {
--- dvb-bt8xx.c.cvs	2004-06-07 19:51:20.000000000 +0200
+++ dvb-bt8xx.c	2004-06-07 20:00:14.000000000 +0200
@@ -55,7 +55,7 @@
 {
 	struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
 
-	//printk("%d ", finished_block);
+	//printk("%d ", card->bt->finished_block);
 
 	while (card->bt->last_block != card->bt->finished_block) {
 		(card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)(&card->demux, &card->bt->buf_cpu[card->bt->last_block * card->bt->block_bytes], card->bt->block_bytes);
@@ -427,7 +427,7 @@
 				dvb_bt8xx_card_match(card_nr, "Pinnacle PCTV DVB-S",
 					       0x0400C060, 0, 0);
 				/* 26, 15, 14, 6, 5 
-				 * A_G2X  DA_DPM DA_SBR DA_IOM_DA 
+				 * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA 
 				 * DA_APP(parallel) */
 				break;
 			case 0x01010071:
@@ -438,11 +438,16 @@
 				/* A_PWRDN DA_SBR DA_APP (high speed serial) */
 				break;
 			case 0x07611461:
-				dvb_bt8xx_card_match(card_nr, "Avermedia DVB-T",
+				dvb_bt8xx_card_match(card_nr, "Avermedia DVB-T 761",
 					     (1 << 26) | (1 << 14) | (1 << 5),
 					     0, 0);
 				/* A_PWRDN DA_SBR DA_APP (high speed serial) */
 				break;
+			case 0x07711461:
+				dvb_bt8xx_card_match(card_nr, "Avermedia DVB-T 771",
+					0x0400402B,BT878_RISC_SYNC_MASK,0);
+				/* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
+                                break;
 			case 0x0:
 				if (card_type == BT878_NEBULA ||
 					card_type == BT878_TWINHAN_DST)
--- mt352.c.cvs	2004-06-07 19:44:50.000000000 +0200
+++ mt352.c	2004-06-07 19:45:32.000000000 +0200
@@ -1,9 +1,12 @@
-/* 
+/*
  *  Driver for Zarlink DVB-T MT352 demodulator
  *
- *  Written by Holger Waechtler <holger@qanu.de> 
+ *  Written by Holger Waechtler <holger@qanu.de>
  *	 and Daniel Mack <daniel@qanu.de>
  *
+ *  AVerMedia AVerTV DVB-T 771 support by
+ *       Wolfram Joost <dbox2@frokaschwei.de>
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -18,7 +21,7 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */    
+ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -30,6 +33,9 @@
 #define I2C_MT352_ADDR 0x0f
 #define I2C_TUNER_ADDR 0xc2
 
+#define CARD_UNKNOWN	0x00
+#define CARD_AVDVBT771	0x01
+
 #define mt352_write(ibuf, ilen)						\
 do {									\
 	struct i2c_msg msg = { .addr = I2C_MT352_ADDR, .flags = 0,	\
@@ -46,11 +52,10 @@
 #define msb(x) (((x) >> 8) & 0xff)
 #define lsb(x) ((x) & 0xff)
 
-
 static struct dvb_frontend_info mt352_info = {
 	.name 			= "DVB-T Zarlink MT352 demodulator driver",
 	.type 			= FE_OFDM,
-	.frequency_min 		= 174000000,
+	.frequency_min 		= 174000000, /* NIM of AV771 starts at 50MHz */
 	.frequency_max 		= 862000000,
 	.frequency_stepsize 	= 166667,
 /*
@@ -60,29 +65,65 @@
 	.symbol_rate_tolerance 	= ???,
 */
 	.notifier_delay		 = 0,
-	.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 
+	.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
 		FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 		FE_CAN_FEC_AUTO |
 		FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
 		FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-		FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | 
+		FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
 		FE_CAN_MUTE_TS
 };
 
+int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
+{
+	u8 reg;
+	u8 id[4];
+	const u8 pciid[4] = { 0x07, 0x71, 0x14, 0x61 };
+	struct i2c_msg msg[2] =
+	{
+		{
+			.addr = 0x50,
+			.flags = I2C_M_NOSTART,
+			.buf = &reg,
+			.len = 1
+		},
+		{
+			.addr = 0x50,
+			.flags = I2C_M_RD,
+			.len = 1
+		}
+    };
+	int i;
 
-int mt352_init (struct dvb_i2c_bus *i2c)
+	for (i = 0; i < 4; i++)
+	{
+		reg = i + 0xFC;
+		msg[1].buf = id + i;
+		if (i2c->xfer(i2c,msg,2) != 2)
+		{
+			return 0;
+		}
+	}
+
+	return *((u32 *) id) == *((u32 *) pciid);
+}
+
+int mt352_init (struct dvb_i2c_bus *i2c, u32 card_type)
 {
 	/**
 	 *  all register write sequence have the register address of the
 	 *  first register in the first byte, thenafter the value to write
 	 *  into this and the following registers.
 	 */
-	static unsigned char mt352_reset [] = { 0x50, 0x80 };
-	static unsigned char mt352_clock_config [] = { 0x89, 0x38, 0x2d };
-	static unsigned char mt352_adc_ctl_1_cfg [] = { 0x8e, 0x40 };
-	static unsigned char mt352_agc_cfg [] = { 0x67, 0x19, 0xa0 };
-	static unsigned char mt352_acq_ctl [] = { 0x53, 0x50 };
-
+	static u8 mt352_reset [] = { 0x50, 0x80 };
+	static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+	static u8 mt352_adc_ctl_1_cfg [] = { 0x8e, 0x40 };
+	static u8 mt352_agc_cfg [] = { 0x67, 0x19, 0xa0 };
+	static u8 mt352_acq_ctl [] = { 0x53, 0x50 };
+
+	static u8 mt352_agc_cfg_av771 [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
+										 0x00, 0xFF, 0x00, 0x40, 0x40 };
+	static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
 	/**
 	 *  We only write non-default settings, all default settings are
 	 *  restored by the full mt352_reset sequence.
@@ -92,42 +133,60 @@
 	mt352_write(mt352_reset, sizeof(mt352_reset));
 	mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
 	mt352_write(mt352_acq_ctl, sizeof(mt352_acq_ctl));
-
-	/**
-	 *  The optimal AGC target value and slope might vary from tuner
-	 *  type to tuner type, so check whether you need to adjust this one...
-	 */
-	mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	if (card_type == CARD_AVDVBT771)
+	{
+		mt352_write(mt352_agc_cfg_av771,sizeof(mt352_agc_cfg_av771));
+		udelay(2000);
+		mt352_write(mt352_av771_extra,sizeof(mt352_av771_extra));
+	}
+	else
+	{
+		/**
+		 *  The optimal AGC target value and slope might vary from tuner
+		 *  type to tuner type, so check whether you need to adjust this one...
+		 */
+		mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	}
 
 	return 0;
 }
 
+int mt352_sleep(struct dvb_i2c_bus *i2c)
+{
+	static u8 mt352_softdown[] = { 0x89, 0x20, 0x08 };
+
+	mt352_write(mt352_softdown, sizeof(mt352_softdown));
+
+	return 0;
+}
 
 int mt352_set_parameters (struct dvb_i2c_bus *i2c,
-			  struct dvb_frontend_parameters *param)
+			  struct dvb_frontend_parameters *param, u32 card_type)
 {
 	unsigned char buf[14];
 	unsigned int tps = 0;
 	struct dvb_ofdm_parameters *op = &param->u.ofdm;
 	u32 freq = param->frequency / 1000;
+	uint16_t tmp;
 
 	switch (op->code_rate_HP) {
 		case FEC_2_3:
-			tps |= (1 << 7);
+			tps = (1 << 7);
 			break;
 		case FEC_3_4:
-			tps |= (2 << 7);
+			tps = (2 << 7);
 			break;
 		case FEC_5_6:
-			tps |= (3 << 7);
+			tps = (3 << 7);
 			break;
 		case FEC_7_8:
-			tps |= (4 << 7);
+			tps = (4 << 7);
 			break;
+		case FEC_1_2:
 		case FEC_AUTO:
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
 
 	switch (op->code_rate_LP) {
@@ -143,13 +202,17 @@
 		case FEC_7_8:
 			tps |= (4 << 4);
 			break;
+		case FEC_1_2:
 		case FEC_AUTO:
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
 
 	switch (op->constellation) {
+		case QPSK:
+			break;
+		case QAM_AUTO:
 		case QAM_16:
 			tps |= (1 << 13);
 			break;
@@ -157,18 +220,24 @@
 			tps |= (2 << 13);
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
 
 	switch (op->transmission_mode) {
+		case TRANSMISSION_MODE_2K:
+		case TRANSMISSION_MODE_AUTO:
+			break;
 		case TRANSMISSION_MODE_8K:
 			tps |= (1 << 0);
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
 
 	switch (op->guard_interval) {
+		case GUARD_INTERVAL_1_32:
+		case GUARD_INTERVAL_AUTO:
+			break;
 		case GUARD_INTERVAL_1_16:
 			tps |= (1 << 2);
 			break;
@@ -179,10 +248,13 @@
 			tps |= (3 << 2);
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
-	
+
 	switch (op->hierarchy_information) {
+		case HIERARCHY_AUTO:
+		case HIERARCHY_NONE:
+			break;
 		case HIERARCHY_1:
 			tps |= (1 << 10);
 			break;
@@ -193,7 +265,7 @@
 			tps |= (3 << 10);
 			break;
 		default:
-			;
+			return -EINVAL;
 	}
 
 
@@ -202,8 +274,7 @@
 	buf[1] = msb(tps);      /* TPS_GIVEN_(1|0) */
 	buf[2] = lsb(tps);
 
-//      buf[3] = 0xf3;  /* ACQ_CTL, force parameters, automatic spectral inv */
-	buf[3] = 0x50;  /* ACQ_CTL, fully automatic parameter search */
+	buf[3] = 0x50;
 
 	/**
 	 *  these settings assume 20.48MHz f_ADC, for other tuners you might
@@ -220,45 +291,95 @@
 		buf[5] = 0xb7;
 	}
 
-	buf[6] = 0x31;  /* INPUT_FREQ_(1|0), 20.48MHz clock, 36.166667MHz IF */
-	buf[7] = 0x05;  /* see MT352 Design Manual page 32 for details */
-
 	buf[8] = I2C_TUNER_ADDR;
 
 	/**
 	 *  All the following settings are tuner module dependent,
 	 *  check the datasheet...
 	 */
+
+	/* here we assume 1/6MHz == 166.66kHz stepsize */
+	#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
+	tmp = (3 * freq) / 500 + IF_FREQUENCYx6;
+	buf[9] = msb(tmp);      /* CHAN_START_(1|0) */
+	buf[10] = lsb(tmp);
+
+	buf[6] = 0x31;  /* INPUT_FREQ_(1|0), 20.48MHz clock, 36.166667MHz IF */
+	buf[7] = 0x05;  /* see MT352 Design Manual page 32 for details */
+
+	if (card_type == CARD_AVDVBT771)
 	{
-		/* here we assume 1/6MHz == 166.66kHz stepsize */
-		#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-		uint16_t tmp = (6 * freq) / 1000 + IF_FREQUENCYx6;
-		buf[9] = msb(tmp);      /* CHAN_START_(1|0) */
-		buf[10] = lsb(tmp);
+		if (freq < 150000)
+		{
+			buf[11] = 0xB4;
+			buf[12] = 0x01;
+		}
+		else if (freq < 173000)
+		{
+			buf[11] = 0xBC;
+			buf[12] = 0x01;
+		}
+		else if (freq < 250000)
+		{
+			buf[11] = 0xB4;
+			buf[12] = 0x02;
+		}
+		else if (freq < 400000)
+		{
+			buf[11] = 0xBC;
+			buf[12] = 0x02;
+		}
+		else if (freq < 420000)
+		{
+			buf[11] = 0xF4;
+			buf[12] = 0x02;
+		}
+		else if (freq < 470000)
+		{
+			buf[11] = 0xFC;
+			buf[12] = 0x02;
+		}
+		else if (freq < 600000)
+		{
+			buf[11] = 0xBC;
+			buf[12] = 0x08;
+		}
+		else if (freq < 730000)
+		{
+			buf[11] = 0xF4;
+			buf[12] = 0x08;
+		}
+		else
+		{
+			buf[11] = 0xFC;
+			buf[12] = 0x08;
+		}
 	}
-
-	printk (KERN_WARNING "buf9,10: %02x %02x\n", buf[9], buf[10]);
-	
-	if (freq < 542000)
-		buf[11] = 0xbe; /* CONT_1, charge pump byte */
-	else if (freq < 830000)
-		buf[11] = 0xf6;
 	else
-		buf[11] = 0xfe;
+	{
 
-	if (freq < 250000)	 /* VHF, freq < 250MHz */
-		buf[12] = 0x01; /* CONT_0, bandswitch byte */
-	else
-		buf[12] = 0x08;
+		printk (KERN_WARNING "buf9,10: %02x %02x\n", buf[9], buf[10]);
+
+		if (freq < 542000)
+			buf[11] = 0xbe; /* CONT_1, charge pump byte */
+		else if (freq < 830000)
+			buf[11] = 0xf6;
+		else
+			buf[11] = 0xfe;
+
+		if (freq < 250000)	 /* VHF, freq < 250MHz */
+			buf[12] = 0x01; /* CONT_0, bandswitch byte */
+		else
+			buf[12] = 0x08;
+	}
 
 	buf[13] = 0x01; /* TUNER_GO!! */
 
 	mt352_write(buf, sizeof(buf));
-	
+
 	return 0;
 }
 
-
 static u8 mt352_read_register (struct dvb_i2c_bus *i2c, u8 reg)
 {
 	int ret;
@@ -281,12 +402,114 @@
 }
 
 
-static int mt352_dump (struct dvb_i2c_bus *i2c) {
-	int i;
+int mt352_get_parameters (struct dvb_i2c_bus *i2c,
+			  struct dvb_frontend_parameters *param, u32 card_type)
+{
+	u16 tps;
+	u16 div;
+	u8 trl;
+
+	struct dvb_ofdm_parameters *op = &param->u.ofdm;
+	static const u8 tps_fec_to_api[8] =
+	{
+		FEC_1_2,
+		FEC_2_3,
+		FEC_3_4,
+		FEC_5_6,
+		FEC_7_8,
+		FEC_AUTO,
+		FEC_AUTO,
+		FEC_AUTO
+	};
+
+	if ( (mt352_read_register(i2c,0x00) & 0xC0) != 0xC0 )
+	{
+		return -EINVAL;
+	}
+
+	/* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
+	 * the mt352 sometimes works with the wrong parameters
+	 */
+	tps = (mt352_read_register(i2c,0x1E) << 8) | mt352_read_register(i2c,0x1F);
+	div = (mt352_read_register(i2c,0x59) << 8) | mt352_read_register(i2c,0x5A);
+	trl = mt352_read_register(i2c,0x54);
+
+	op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
+	op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
+
+	switch ( (tps >> 13) & 3)
+	{
+		case 0:
+			op->constellation = QPSK;
+			break;
+		case 1:
+			op->constellation = QAM_16;
+			break;
+		case 2:
+			op->constellation = QAM_64;
+			break;
+		default:
+			op->constellation = QAM_AUTO;
+			break;
+	}
+
+	op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
+
+	switch ( (tps >> 2) & 3)
+	{
+		case 0:
+			op->guard_interval = GUARD_INTERVAL_1_32;
+			break;
+		case 1:
+			op->guard_interval = GUARD_INTERVAL_1_16;
+			break;
+		case 2:
+			op->guard_interval = GUARD_INTERVAL_1_8;
+			break;
+		case 3:
+			op->guard_interval = GUARD_INTERVAL_1_4;
+			break;
+		default:
+			op->guard_interval = GUARD_INTERVAL_AUTO;
+			break;
+	}
+
+	switch ( (tps >> 10) & 7)
+	{
+		case 0:
+			op->hierarchy_information = HIERARCHY_NONE;
+			break;
+		case 1:
+			op->hierarchy_information = HIERARCHY_1;
+			break;
+		case 2:
+			op->hierarchy_information = HIERARCHY_2;
+			break;
+		case 3:
+			op->hierarchy_information = HIERARCHY_4;
+			break;
+		default:
+			op->hierarchy_information = HIERARCHY_AUTO;
+			break;
+	}
+
+	param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;
+
+	if (trl == 0x72)
+	{
+		op->bandwidth = BANDWIDTH_8_MHZ;
+	}
+	else if (trl == 0x64)
+	{
+		op->bandwidth = BANDWIDTH_7_MHZ;
+	}
+	else
+	{
+		op->bandwidth = BANDWIDTH_6_MHZ;
+	}
+
+	param->inversion = INVERSION_OFF;
 
-	for (i=0x50; i<=0x7f; i++)
-		printk("mt352[%03x]: %02x\n", i, mt352_read_register (i2c, i));
-	
 	return 0;
 }
 
@@ -294,7 +517,10 @@
 static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
 {
 	struct dvb_i2c_bus *i2c = fe->i2c;
-	int i;
+	u32 card_type = (u32) fe->data;
+	u8 r,snr;
+	fe_status_t *status;
+	u16 signal;
 
 	switch (cmd) {
 	case FE_GET_INFO:
@@ -302,53 +528,42 @@
 		break;
 
 	case FE_READ_STATUS:
-	{
-		u8 r;
-		fe_status_t *status = arg;
+		status = arg;
 		*status = 0;
-
-		r = mt352_read_register (i2c, 0x0);
-		if (r & (1 << 5))
-			*status |= FE_HAS_LOCK;
+		r = mt352_read_register (i2c, 0x00);
 		if (r & (1 << 4))
-			*status |= FE_HAS_CARRIER;
+			*status = FE_HAS_CARRIER;
 		if (r & (1 << 1))
 			*status |= FE_HAS_VITERBI;
+		if (r & (1 << 5))
+			*status |= FE_HAS_LOCK;
 
-		r = mt352_read_register (i2c, 0x1);
+		r = mt352_read_register (i2c, 0x01);
 		if (r & (1 << 1))
 			*status |= FE_HAS_SYNC;
-		
-		r = mt352_read_register (i2c, 0x3);
+
+		r = mt352_read_register (i2c, 0x03);
 		if (r & (1 << 6))
 			*status |= FE_HAS_SIGNAL;
 
 		break;
-	}
 
 	case FE_READ_BER:
-	{
-		u32 *ber = (u32 *) arg;
-		*ber = (mt352_read_register (i2c, 0xA) << 16) |
-		       (mt352_read_register (i2c, 0xB) << 8) |
-		       (mt352_read_register (i2c, 0xC));
+		*((u32 *) arg) = (mt352_read_register (i2c, 0x0A) << 16) |
+		       (mt352_read_register (i2c, 0x0B) << 8) |
+		       (mt352_read_register (i2c, 0x0C));
 		break;
-	}
 
 	case FE_READ_SIGNAL_STRENGTH:
-	{
-		u16 signal = (mt352_read_register (i2c, 0x12) << 8) |
+		signal = (mt352_read_register (i2c, 0x12) << 8) |
 			     (mt352_read_register (i2c, 0x13));
 		*((u16*) arg) = ~signal;
 		break;
-	}
 
 	case FE_READ_SNR:
-	{
-		u8 snr = mt352_read_register (i2c, 0x9);
-		*(u16*) arg = (snr << 8) | snr;
+		snr = mt352_read_register (i2c, 0x09);
+		*((u16*) arg) = (snr << 8) | snr;
 		break;
-	}
 
 	case FE_READ_UNCORRECTED_BLOCKS:
 		*(u32*) arg = (mt352_read_register (i2c, 0x10) << 8) |
@@ -356,40 +571,57 @@
 		break;
 
 	case FE_SET_FRONTEND:
-		i = mt352_set_parameters (i2c,
-				 (struct dvb_frontend_parameters *) arg);
-		mt352_dump(i2c);
-		return i;
+		return mt352_set_parameters (i2c,
+				 (struct dvb_frontend_parameters *) arg,card_type);
 
 	case FE_GET_FRONTEND:
-		break;
+		return mt352_get_parameters (i2c,
+				 (struct dvb_frontend_parameters *) arg,card_type);
 
 	case FE_SLEEP:
-		return 0;
+		return mt352_sleep(i2c);
 
 	case FE_INIT:
-		return mt352_init(i2c);
+		return mt352_init(i2c,card_type);
 
 	default:
 		return -EOPNOTSUPP;
 	}
 
 	return 0;
-} 
+}
 
 
 static int mt352_attach (struct dvb_i2c_bus *i2c, void **data)
 {
+	u32 card_type;
+	static u8 mt352_reset_attach [] = { 0x50, 0xC0 };
+
 	if (mt352_read_register(i2c, 0x7f) == 0x13)
-		return dvb_register_frontend(mt352_ioctl, i2c, NULL,
+	{
+		if (mt352_detect_avermedia_771(i2c))
+		{
+			card_type = CARD_AVDVBT771;
+		}
+		else
+		{
+			card_type = CARD_UNKNOWN;
+		}
+		/* Do a "hard" reset */
+		mt352_write(mt352_reset_attach,sizeof(mt352_reset_attach));
+		/* Don't waste power and (maybe) pci bandwidth */
+		mt352_sleep(i2c);
+		return dvb_register_frontend(mt352_ioctl, i2c, (void *) card_type,
 					     &mt352_info);
-	
+	}
+
 	return -ENODEV;
 }
 
 
 static void mt352_detach (struct dvb_i2c_bus *i2c, void *data)
 {
+	mt352_sleep(i2c);
 	dvb_unregister_frontend(mt352_ioctl, i2c);
 }
 
@@ -413,4 +645,3 @@
 MODULE_DESCRIPTION("DVB-T MT352 Zarlink");
 MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
 MODULE_LICENSE("GPL");
-

Home | Main Index | Thread Index