mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Michael Hunold <hunold@linuxtv.org>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@osdl.org>
Subject: [PATCH][5/5] DVB: misc. updates to frontend drivers
Date: Wed, 27 Oct 2004 11:55:52 +0200	[thread overview]
Message-ID: <417F70A8.8000800@linuxtv.org> (raw)
In-Reply-To: <417F702B.9050909@linuxtv.org>

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: 05-dvb-frontend-update.diff --]
[-- Type: text/plain, Size: 29643 bytes --]

- [DVB] add legacy DishNetwork support to dvb core and stv0299, thanks to Jeremy Hall
- [DVB] mt352: major cleanup, support DVICO FusionHDTV DVB-T, thanks to Christopher Pascoe

Signed-off-by: Michael Hunold <hunold@linuxtv.org>

diff -uraNwB linux-2.6.10-rc1/include/linux/dvb/frontend.h linux-2.6.10-rc1-patched/include/linux/dvb/frontend.h
--- linux-2.6.10-rc1/include/linux/dvb/frontend.h	2004-10-25 14:03:20.000000000 +0200
+++ linux-2.6.10-rc1-patched/include/linux/dvb/frontend.h	2004-10-25 14:14:44.000000000 +0200
@@ -258,6 +258,8 @@
 #define FE_GET_FRONTEND            _IOR('o', 77, struct dvb_frontend_parameters)
 #define FE_GET_EVENT               _IOR('o', 78, struct dvb_frontend_event)
 
+#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+
 
 #endif /*_DVBFRONTEND_H_*/
 diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/stv0299.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/stv0299.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/stv0299.c	2004-10-25 14:07:56.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/stv0299.c	2004-10-25 14:14:43.000000000 +0200
@@ -885,6 +885,43 @@
 }
 
 
+static int stv0299_send_legacy_dish_cmd(struct i2c_adapter *i2c, u32 cmd, 
+                                        int tuner_type)
+{
+	u8 last = 1;
+	int i;
+
+	/* reset voltage at the end
+	if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
+		cmd |= 0x80;
+	else
+		cmd &= 0x7F;
+	*/
+
+	cmd = cmd << 1;
+	dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
+
+	stv0299_set_voltage(i2c,SEC_VOLTAGE_18,tuner_type);
+	msleep(32);
+
+	for (i=0; i<9; i++) {
+		if((cmd & 0x01) != last) {
+			stv0299_set_voltage(i2c,
+					    last ? SEC_VOLTAGE_13 :
+					    	   SEC_VOLTAGE_18,
+					    tuner_type);
+			last = (last) ? 0 : 1;
+		}
+
+		cmd = cmd >> 1;
+
+		if (i != 8)
+			msleep(8);
+	}
+
+	return 0;
+}
+
 static int stv0299_set_symbolrate (struct i2c_adapter *i2c, u32 srate, int tuner_type)
 {
 	u64 big = srate;
@@ -1229,6 +1266,10 @@
 		return stv0299_set_voltage (i2c, (fe_sec_voltage_t) arg,
 					    state->tuner_type);
 
+	case FE_DISHNETWORK_SEND_LEGACY_CMD:
+		return stv0299_send_legacy_dish_cmd (i2c, (u32) arg,
+						     state->tuner_type);
+
 	case FE_GET_TUNE_SETTINGS:
 	{
 		struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;
@@ -1276,12 +1317,12 @@
         u8 stat [] = { 0 };
 	u8 tda6100_buf [] = { 0, 0 };
 	int ret;
-	struct i2c_msg msg1 [] = {{ .addr = 0x68, .buf = rpt,  .len = 2 },
+	struct i2c_msg msg1 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt,  len: 2 },
 			   { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
-	struct i2c_msg msg2 [] = {{ .addr = 0x68, .buf = rpt,  .len = 2 },
+	struct i2c_msg msg2 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt,  len: 2 },
 			   { .addr = 0x61, .flags = I2C_M_RD, .buf = stat, .len = 1 }};
-	struct i2c_msg msg3 [] = {{ .addr = 0x68, .buf = rpt,  .len = 2 },
-			   { .addr = 0x60, .buf = tda6100_buf, .len = 2 }};
+	struct i2c_msg msg3 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt,  len: 2 },
+			   { .addr = 0x60, .flags = 0, .buf = tda6100_buf, .len = 2 }};
 
 	stv0299_writereg (i2c, 0x01, 0x15);
 	stv0299_writereg (i2c, 0x02, 0x30);
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.c linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.c
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.c	2004-10-25 14:07:57.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.c	2004-10-25 14:14:43.000000000 +0200
@@ -8,10 +8,12 @@
  *       Wolfram Joost <dbox2@frokaschwei.de>
  *
  *  Support for Samsung TDTC9251DH01C(M) tuner
- *
  *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
  *                     Amauri  Celani  <acelani@essegi.net>
  *
+ *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
  *  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
@@ -45,22 +47,23 @@
 	} while (0)
 
 static int debug;
-static int force_card = -1;
-static int card_type = -1;
+#define MAX_CARDS	4
+static int force_card[MAX_CARDS] = { -1, -1, -1, -1 };
+static int force_card_count = 0;
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-//FIXME: Should be an array.
-module_param(force_card, int, 0444);
-MODULE_PARM_DESC(force_card, "Force card type.\n\t(0 == AVDVBT771, 1 == TUA6034, "
-		 "2 == TDTC9251DH01C).\n\tDefault is that AVDVBT771 is attempted "
-		 "to be autodetected,\n\tif you do not have this card, you must "
-		 "specify the card type here.");
-
+module_param_array(force_card, int, &force_card_count, 0444);
+MODULE_PARM_DESC(force_card, "Forces the type of each attached mt352 frontend.\n\t"
+		 "If your card is not autodetected, then you must specify its type here.\n\t"
+		 "Valid card types are: 0 == AVDVBT771, 1 == TUA6034, 2 == TDTC9251DH01C,\n\t"
+		 "3 == DVICO FusionHDTV DVB-T1, 4 == DVICO FusionHDTV DVB-T Lite.");
 
 struct mt352_state {
 	struct i2c_adapter *i2c;
 	struct dvb_adapter *dvb;
+	struct dvb_frontend_info fe_info;
+	int card_type;
 };
 
 #define mt352_write(ibuf, ilen)						\
@@ -75,60 +78,60 @@
 	}								\
 } while (0)
 
-// FIXME:
 static struct _tuner_info tuner_info [] = {
-	//AVERMEDIA 771 board
 	{
+	  .fe_name = "AverMedia DVB-T 771",
 	  .fe_frequency_min = 174000000,
 	  .fe_frequency_max = 862000000,
-	  .fe_frequency_stepsize = 83333,
-	  .coderate_hp_shift = 7,
-	  .coderate_lp_shift = 4,
-	  .constellation_shift = 13,
-	  .tx_mode_shift = 0,
-	  .guard_interval_shift = 2,
-	  .hierarchy_shift = 10,
-	  .read_reg_flag = I2C_M_NOSTART,
+	  .fe_frequency_stepsize = 166667,
+	  .pll_i2c_addr = 0xc2,
 	  .mt352_init = mt352_init_AVERMEDIA771,
 	  .mt352_charge_pump = mt352_cp_AVERMEDIA771,
 	  .mt352_band_select = mt352_bs_AVERMEDIA771
 	},
-	//TUA6034 tuner
 	{
+	  .fe_name = "Zarlink MT352 + TUA6034 DVB-T",
 	  .fe_frequency_min = 174000000,
 	  .fe_frequency_max = 862000000,
 	  .fe_frequency_stepsize = 166667,
-	  .coderate_hp_shift = 9,
-	  .coderate_lp_shift = 6,
-	  .constellation_shift = 14,
-	  .tx_mode_shift = 1,
-	  .guard_interval_shift = 3,
-	  .hierarchy_shift = 12,
-	  .read_reg_flag = I2C_M_NOSTART,
+	  .pll_i2c_addr = 0xc2,
 	  .mt352_init = mt352_init_TUA6034,
 	  .mt352_charge_pump = mt352_cp_TUA6034,
 	  .mt352_band_select = mt352_bs_TUA6034
 	},
-	//TDTC9251DH01C tuner
 	{
+	  .fe_name = "Zarlink MT352 + Samsung TDTC9251DH01C DVB-T",
 	  .fe_frequency_min = 474000000,
 	  .fe_frequency_max = 858000000,
 	  .fe_frequency_stepsize = 166667,
-	  .coderate_hp_shift = 9,
-	  .coderate_lp_shift = 6,
-	  .constellation_shift = 4,
-	  .tx_mode_shift = 1,
-	  .guard_interval_shift = 3,
-	  .hierarchy_shift = 12,
-	  .read_reg_flag = 0,
+	  .pll_i2c_addr = 0xc2,
 	  .mt352_init = mt352_init_TDTC9251DH01C,
 	  .mt352_charge_pump = mt352_cp_TDTC9251DH01C,
 	  .mt352_band_select = mt352_bs_TDTC9251DH01C
+	},
+	{
+	  .fe_name = "DVICO FusionHDTV DVB-T1",
+	  .fe_frequency_min = 174000000,
+	  .fe_frequency_max = 862000000,
+	  .fe_frequency_stepsize = 166667,
+	  .pll_i2c_addr = 0xc2,
+	  .mt352_init = mt352_init_DVICODVBT1,
+	  .mt352_charge_pump = mt352_cp_DVICODVBT1,
+	  .mt352_band_select = mt352_bs_DVICODVBT1,
+	},
+	{
+	  .fe_name = "DVICO FusionHDTV DVB-T Lite",
+	  .fe_frequency_min = 174000000,
+	  .fe_frequency_max = 862000000,
+	  .fe_frequency_stepsize = 166667,
+	  .pll_i2c_addr = 0xc0,
+	  .mt352_init = mt352_init_DVICODVBTLITE,
+	  .mt352_charge_pump = mt352_cp_DVICODVBTLITE,
+	  .mt352_band_select = mt352_bs_DVICODVBTLITE,
 	}
 };
 
-
-static struct dvb_frontend_info mt352_info = {
+static struct dvb_frontend_info mt352_info_template = {
 	.name			= "DVB-T Zarlink MT352 demodulator driver",
 	.type			= FE_OFDM,
 /*
@@ -150,63 +153,95 @@
 		FE_CAN_MUTE_TS
 };
 
+static u8 mt352_reset [] = { RESET, 0x80 };
+static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+static u8 mt352_capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
 static int mt352_init_TUA6034(struct i2c_adapter *i2c)
 {
-	static u8 mt352_reset [] = { RESET, 0x80 };
 	static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
-	static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
 	static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x19, 0xa0 };
-	static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };
 
 	mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
 	udelay(2000);
 	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));
 
 	mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
 
 	return 0;
 }
 
 static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c)
 {
-	static u8 mt352_reset [] = { RESET, 0x80 };
 	static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
-	static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
 	static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x10, 0x23, 0x00, 0xFF, 0xFF,
 				       0x00, 0xFF, 0x00, 0x40, 0x40 };
-	static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };
 	static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
+	static u8 mt352_capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 
 	mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
 	udelay(2000);
 	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));
 
 	mt352_write(mt352_agc_cfg,sizeof(mt352_agc_cfg));
 	udelay(2000);
 	mt352_write(mt352_av771_extra,sizeof(mt352_av771_extra));
+	mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
 
 	return 0;
 }
 
 static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c)
 {
-	static u8 mt352_reset [] = { RESET, 0x80 };
 	static u8 mt352_clock_config [] = { CLOCK_CTL, 0x10, 0x2d };
-	static u8 mt352_adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
 	static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x28, 0xa1 };
-	static u8 mt352_acq_ctl [] = { ACQ_CTL, 0x50 };
 
 	mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
 	udelay(2000);
 	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));
 
 	mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+	return 0;
+}
+
+static int mt352_init_DVICODVBT1(struct i2c_adapter *i2c)
+{
+	static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
+	static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
+	static u8 mt352_gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+
+	mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
+	udelay(200);
+	mt352_write(mt352_reset, sizeof(mt352_reset));
+	mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+	mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	mt352_write(mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+	mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+	return 0;
+}
+
+static int mt352_init_DVICODVBTLITE(struct i2c_adapter *i2c)
+{
+	static u8 mt352_clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
+	static u8 mt352_agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
+	static u8 mt352_gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+
+	mt352_write(mt352_clock_config, sizeof(mt352_clock_config));
+	udelay(200);
+	mt352_write(mt352_reset, sizeof(mt352_reset));
+	mt352_write(mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+	mt352_write(mt352_agc_cfg, sizeof(mt352_agc_cfg));
+	mt352_write(mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+	mt352_write(mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
 
 	return 0;
 }
@@ -215,9 +250,9 @@
 {
 	unsigned char cp = 0;
 
-	if (freq < 542)
+	if (freq < 542000000)
 		cp = 0xbe;
-	else if (freq < 830)
+	else if (freq < 830000000)
 		cp = 0xf6;
 	else
 		cp = 0xfe;
@@ -229,21 +264,21 @@
 {
 	unsigned char cp = 0;
 
-	if (freq < 150)
+	if (freq < 150000000)
 		cp = 0xB4;
-	else if (freq < 173)
+	else if (freq < 173000000)
 		cp = 0xBC;
-	else if (freq < 250)
+	else if (freq < 250000000)
 		cp = 0xB4;
-	else if (freq < 400)
+	else if (freq < 400000000)
 		cp = 0xBC;
-	else if (freq < 420)
+	else if (freq < 420000000)
 		cp = 0xF4;
-	else if (freq < 470)
+	else if (freq < 470000000)
 		cp = 0xFC;
-	else if (freq < 600)
+	else if (freq < 600000000)
 		cp = 0xBC;
-	else if (freq < 730)
+	else if (freq < 730000000)
 		cp = 0xF4;
 	else
 		cp = 0xFC;
@@ -256,11 +291,39 @@
 	return(0xcc);
 }
 
+static unsigned char mt352_cp_DVICODVBT1(u32 freq)
+{
+	unsigned char cp = 0;
+
+	if (freq < 542000000)
+		cp = 0xbc;
+	else if (freq < 830000000)
+		cp = 0xf4;
+	else
+		cp = 0xfc;
+
+	return cp;
+}
+
+static unsigned char mt352_cp_DVICODVBTLITE(u32 freq)
+{
+	unsigned char cp = 0;
+
+	if (freq < 542000000)
+		cp = 0xb4;
+	else if (freq < 771000000)
+		cp = 0xbc;
+	else 
+		cp = 0xf4;
+
+	return cp;
+}
+
 static unsigned char mt352_bs_TUA6034(u32 freq)
 {
 	unsigned char bs = 0;
 
-	if (freq < 250)
+	if (freq < 250000000)
 		bs = 0x01;
 	else
 		bs = 0x08;
@@ -272,21 +335,21 @@
 {
 	unsigned char bs = 0;
 
-	if (freq < 150)
+	if (freq < 150000000)
 		bs = 0x01;
-	else if (freq < 173)
+	else if (freq < 173000000)
 		bs = 0x01;
-	else if (freq < 250)
+	else if (freq < 250000000)
 		bs = 0x02;
-	else if (freq < 400)
+	else if (freq < 400000000)
 		bs = 0x02;
-	else if (freq < 420)
+	else if (freq < 420000000)
 		bs = 0x02;
-	else if (freq < 470)
+	else if (freq < 470000000)
 		bs = 0x02;
-	else if (freq < 600)
+	else if (freq < 600000000)
 		bs = 0x08;
-	else if (freq < 730)
+	else if (freq < 730000000)
 		bs = 0x08;
 	else
 		bs = 0x08;
@@ -298,54 +361,79 @@
 {
 	unsigned char bs = 0;
 
-	if ((freq >= 48) && (freq <= 154))      /* low band */
+	if (freq >= 48000000 && freq <= 154000000)      /* low band */
 		bs = 0x09;
 
-	if ((freq >= 161) && (freq <= 439))     /* medium band */
+	if (freq >= 161000000 && freq <= 439000000)     /* medium band */
 		bs = 0x0a;
 
-	if ((freq >= 447) && (freq <= 863))     /* high band */
+	if (freq >= 447000000 && freq <= 863000000)     /* high band */
 		bs = 0x08;
 
 	return bs;
 }
 
+static unsigned char mt352_bs_DVICODVBT1(u32 freq)
+{
+	unsigned char bs = 0;
+
+	if (freq == 0)			/* power down PLL */
+		bs = 0x03;
+	else if (freq < 157500000)	/* low band */
+		bs = 0x01;
+	else if (freq < 443250000)	/* mid band */
+		bs = 0x02;
+	else				/* high band */
+		bs = 0x04;
 
-static int mt352_detect_avermedia_771(struct i2c_adapter *i2c)
+	return bs;
+}
+
+static unsigned char mt352_bs_DVICODVBTLITE(u32 freq)
 {
-	int i;
-	u8 reg;
-	u8 id[4];
-	const u8 pciid[4] = { 0x07, 0x71, 0x14, 0x61 };
-	struct i2c_msg msg[2] =
+	unsigned char bs = 0;
+
+	if (freq == 0)			/* power down PLL */
+		bs = 0x03;
+	else if (freq < 443250000)	/* mid band */
+		bs = 0x02;
+	else				/* high band */
+		bs = 0x08;
+
+	return bs;
+}
+
+static u32 mt352_read_eeprom_dword(struct i2c_adapter *i2c, int dword_base)
 	{
+	int i;
+	u32 dword = 0;
+	u8 reg, val;
+	struct i2c_msg msg[2] = {
 		{
 			.addr = 0x50,
-			.flags = I2C_M_NOSTART,
+			.flags = 0,
 			.buf = &reg,
 			.len = 1
 		},
 		{
 			.addr = 0x50,
 			.flags = I2C_M_RD,
+			.buf = &val,
 			.len = 1
 		}
 	};
 
-	for (i = 0; i < 4; i++)
-	{
-		reg = i + 0xFC;
-		msg[1].buf = id + i;
+	for (i = 0; i < 4; i++) {
+		reg = dword_base + i;
 		if (i2c_transfer(i2c,msg,2) != 2)
-		{
 			return 0;
-		}
+		dword = (dword << 8) | val;
 	}
 
-	return *((u32 *) id) == *((u32 *) pciid);
+	return dword;
 }
 
-static int mt352_init(struct i2c_adapter *i2c)
+static int mt352_init(struct i2c_adapter *i2c, int card_type)
 {
 	/**
 	 *  all register write sequence have the register address of the
@@ -366,7 +454,7 @@
 
 static int mt352_sleep(struct i2c_adapter *i2c)
 {
-	static u8 mt352_softdown[] = { 0x89, 0x20, 0x08 };
+	static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
 
 	mt352_write(mt352_softdown, sizeof(mt352_softdown));
 
@@ -374,26 +462,27 @@
 }
 
 static int mt352_set_parameters(struct i2c_adapter *i2c,
-				struct dvb_frontend_parameters *param)
+				struct dvb_frontend_parameters *param,
+				int card_type)
 {
 	unsigned char buf[14];
 	unsigned int tps = 0;
 	struct dvb_ofdm_parameters *op = &param->u.ofdm;
-	u32 freq = param->frequency / 1000000;
 	uint16_t tmp;
+	int i;
 
 	switch (op->code_rate_HP) {
 		case FEC_2_3:
-			tps |= (1 << CODERATE_HP_SHIFT);
+			tps |= (1 << 7);
 			break;
 		case FEC_3_4:
-			tps |= (2 << CODERATE_HP_SHIFT);
+			tps |= (2 << 7);
 			break;
 		case FEC_5_6:
-			tps |= (3 << CODERATE_HP_SHIFT);
+			tps |= (3 << 7);
 			break;
 		case FEC_7_8:
-			tps |= (4 << CODERATE_HP_SHIFT);
+			tps |= (4 << 7);
 			break;
 		case FEC_1_2:
 		case FEC_AUTO:
@@ -404,20 +493,24 @@
 
 	switch (op->code_rate_LP) {
 		case FEC_2_3:
-			tps |= (1 <<  CODERATE_LP_SHIFT);
+			tps |= (1 << 4);
 			break;
 		case FEC_3_4:
-			tps |= (2 <<  CODERATE_LP_SHIFT);
+			tps |= (2 << 4);
 			break;
 		case FEC_5_6:
-			tps |= (3 <<  CODERATE_LP_SHIFT);
+			tps |= (3 << 4);
 			break;
 		case FEC_7_8:
-			tps |= (4 <<  CODERATE_LP_SHIFT);
+			tps |= (4 << 4);
 			break;
 		case FEC_1_2:
 		case FEC_AUTO:
 			break;
+		case FEC_NONE:
+			if (op->hierarchy_information == HIERARCHY_AUTO ||
+			    op->hierarchy_information == HIERARCHY_NONE)
+				break;
 		default:
 			return -EINVAL;
 	}
@@ -427,10 +520,10 @@
 			break;
 		case QAM_AUTO:
 		case QAM_16:
-			tps |= (1 << CONSTELLATION_SHIFT);
+			tps |= (1 << 13);
 			break;
 		case QAM_64:
-			tps |= (2 << CONSTELLATION_SHIFT);
+			tps |= (2 << 13);
 			break;
 		default:
 			return -EINVAL;
@@ -441,7 +534,7 @@
 		case TRANSMISSION_MODE_AUTO:
 			break;
 		case TRANSMISSION_MODE_8K:
-			tps |= (1 << TX_MODE_SHIFT);
+			tps |= (1 << 0);
 			break;
 		default:
 			return -EINVAL;
@@ -452,13 +545,13 @@
 		case GUARD_INTERVAL_AUTO:
 			break;
 		case GUARD_INTERVAL_1_16:
-			tps |= (1 << GUARD_INTERVAL_SHIFT);
+			tps |= (1 << 2);
 			break;
 		case GUARD_INTERVAL_1_8:
-			tps |= (2 << GUARD_INTERVAL_SHIFT);
+			tps |= (2 << 2);
 			break;
 		case GUARD_INTERVAL_1_4:
-			tps |= (3 << GUARD_INTERVAL_SHIFT);
+			tps |= (3 << 2);
 			break;
 		default:
 			return -EINVAL;
@@ -469,13 +562,13 @@
 		case HIERARCHY_NONE:
 			break;
 		case HIERARCHY_1:
-			tps |= (1 << HIERARCHY_SHIFT);
+			tps |= (1 << 10);
 			break;
 		case HIERARCHY_2:
-			tps |= (2 << HIERARCHY_SHIFT);
+			tps |= (2 << 10);
 			break;
 		case HIERARCHY_4:
-			tps |= (3 << HIERARCHY_SHIFT);
+			tps |= (3 << 10);
 			break;
 		default:
 			return -EINVAL;
@@ -507,7 +600,7 @@
 	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;
+	buf[8] = PLL_I2C_ADDR;
 
 	/**
 	 *  All the following settings are tuner module dependent,
@@ -516,17 +609,24 @@
 
 	/* here we assume 1/6MHz == 166.66kHz stepsize */
 	#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-	tmp = ((param->frequency*3)/500000) + IF_FREQUENCYx6;
+	tmp = (((param->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
 
 	buf[9] = msb(tmp);      /* CHAN_START_(1|0) */
 	buf[10] = lsb(tmp);
 
-	buf[11] = MT352_CHARGE_PUMP(freq);
-	buf[12] = MT352_BAND_SELECT(freq);
+	buf[11] = MT352_CHARGE_PUMP(param->frequency);
+	buf[12] = MT352_BAND_SELECT(param->frequency);
 
 	buf[13] = 0x01; /* TUNER_GO!! */
 
+	/* Only send the tuning request if the tuner doesn't have the requested
+	 * parameters already set.  Enhances tuning time and prevents stream
+	 * breakup when retuning the same transponder. */
+	for (i = 1; i < 13; i++)
+		if (buf[i] != mt352_read_register(i2c, i + 0x50)) {
 	mt352_write(buf, sizeof(buf));
+			break;
+		}
 
 	return 0;
 }
@@ -537,7 +637,7 @@
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
 	struct i2c_msg msg [] = { { .addr = I2C_MT352_ADDR,
-				    .flags =  READ_REG_FLAG,
+				    .flags = 0,
 				    .buf = b0, .len = 1 },
 				  { .addr = I2C_MT352_ADDR,
 				    .flags = I2C_M_RD,
@@ -672,6 +772,7 @@
 {
 	struct mt352_state *state = fe->data;
 	struct i2c_adapter *i2c = state->i2c;
+	int card_type = state->card_type;
 	u8 r,snr;
 	fe_status_t *status;
 	u16 signal;
@@ -679,7 +780,7 @@
 
 	switch (cmd) {
 	case FE_GET_INFO:
-		memcpy (arg, &mt352_info, sizeof(struct dvb_frontend_info));
+		memcpy(arg, &state->fe_info, sizeof(struct dvb_frontend_info));
 		break;
 
 	case FE_READ_STATUS:
@@ -727,7 +828,8 @@
 
 	case FE_SET_FRONTEND:
 		return mt352_set_parameters (i2c,
-				 (struct dvb_frontend_parameters *) arg);
+				 (struct dvb_frontend_parameters *) arg,
+				 card_type);
 
 	case FE_GET_FRONTEND:
 		return mt352_get_parameters (i2c,
@@ -744,7 +846,13 @@
 		return mt352_sleep(i2c);
 
 	case FE_INIT:
-		return mt352_init(i2c);
+		/* Only send the initialisation command if the demodulator
+		 * isn't already enabled.  Greatly enhances tuning time. */
+		if ((mt352_read_register(i2c, CLOCK_CTL) & 0x10) == 0 ||
+		    (mt352_read_register(i2c, CONFIG) & 0x20) == 0)
+			return mt352_init(i2c, card_type);
+		else
+			return 0;
 
 	default:
 		return -EOPNOTSUPP;
@@ -757,56 +865,83 @@
 
 static int mt352_attach_adapter(struct i2c_adapter *i2c)
 {
+	static int num_cards_probed;
 	struct mt352_state *state;
 	struct i2c_client *client;
-	static u8 mt352_reset_attach [] = { 0x50, 0xC0 };
+	static u8 mt352_reset_attach [] = { RESET, 0xC0 };
 	int ret;
+	int card_type, forced_card = -1;
 
 	dprintk("Trying to attach to adapter 0x%x:%s.\n",
 		i2c->id, i2c->name);
 
-	/* set the proper MT352 frequency range */
-	mt352_info.frequency_min =  FE_FREQ_MIN;
-	mt352_info.frequency_max =  FE_FREQ_MAX;
-	mt352_info.frequency_stepsize =  FE_FREQ_STEPSIZE;
+	if (mt352_read_register(i2c, CHIP_ID) != ID_MT352)
+		return -ENODEV;
 
 	if ( !(state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL)) )
 		return -ENOMEM;
 
 	memset(state, 0, sizeof(struct mt352_state));
 	state->i2c = i2c;
+	state->card_type = -1;
+	memcpy(&state->fe_info, &mt352_info_template, sizeof(struct dvb_frontend_info));
 
-	if (mt352_detect_avermedia_771(i2c)) {
-		card_type = CARD_AVDVBT771;
-	} else if (force_card < 0) {
-		dprintk("Avermedia 771 not detected, maybe you should try the "
-			"'force_card' module parameter?.\n");
-		kfree(state);
-		return -ENODEV;
+	/* Attempt autodetection of card type based on PCI ID information
+	 * stored in any on-board EEPROM. */
+	switch (mt352_read_eeprom_dword(i2c, 0xFC)) {	/* BT878A chipset */
+	case 0x07711461:
+		state->card_type = CARD_AVDVBT771;
+		break;
+	case 0xdb1018ac:
+		state->card_type = CARD_DVICODVBTLITE;
+		break;
+	default:
+		break;
 	}
 
-	if (force_card > 0) {
-		if (card_type >= 0 && force_card != card_type)
-			printk(KERN_WARNING "dvbfe_mt352: Warning, overriding"
-					    " detected card.\n");
-		card_type = force_card;
+	switch (mt352_read_eeprom_dword(i2c, 0x04)) {	/* CX2388x chipset */
+	case 0xac1800db:
+		state->card_type = CARD_DVICODVBT1;
+		break;
+	default:
+		break;
 	}
 
-	if (mt352_read_register(i2c, CHIP_ID) != ID_MT352) {
+	if (num_cards_probed < force_card_count)
+		forced_card = force_card[num_cards_probed++];
+
+	if (state->card_type == -1 && forced_card < 0) {
+		dprintk("Card type not automatically detected.  You "
+			"must use the 'force_card' module parameter.\n");
 		kfree(state);
 		return -ENODEV;
 	}
 
-	if (card_type == CARD_AVDVBT771)
-		printk(KERN_INFO FRONTEND_NAME ": Setup for Avermedia 771.\n");
-	else if (card_type == CARD_TUA6034)
-		printk(KERN_INFO FRONTEND_NAME ": Setup for TUA6034.\n");
-	else if (card_type == CARD_TDTC9251DH01C)
-		printk(KERN_INFO FRONTEND_NAME ": Setup for TDTC9251DH01C.\n");
+	if (forced_card >= 0) {
+		if (state->card_type >= 0 && forced_card != state->card_type)
+			printk(KERN_WARNING FRONTEND_NAME ": Warning, overriding"
+					    " detected card type.\n");
+		state->card_type = forced_card;
+	}
+
+	card_type = state->card_type;
+	printk(KERN_INFO FRONTEND_NAME ": Setup for %s\n", FE_NAME);
+
+	/* set the frontend name and card-specific frequency info */
+	strlcpy(state->fe_info.name, FE_NAME, sizeof(state->fe_info.name));
+	state->fe_info.frequency_min = FE_FREQ_MIN;
+	state->fe_info.frequency_max = FE_FREQ_MAX;
+	state->fe_info.frequency_stepsize = FE_FREQ_STEPSIZE;
 
 	/* Do a "hard" reset */
 	mt352_write(mt352_reset_attach, sizeof(mt352_reset_attach));
 
+	/* Try to intiialise the device */
+	if (mt352_init(i2c, card_type) != 0) {
+		kfree(state);
+		return -ENODEV;
+	}
+
 	if ( !(client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)) ) {
 		kfree(state);
 		return -ENOMEM;
@@ -823,16 +958,6 @@
 		return ret;
 	}
 
-	BUG_ON(!state->dvb);
-
-	if ((ret = dvb_register_frontend(mt352_ioctl, state->dvb, state,
-					     &mt352_info, THIS_MODULE))) {
-		i2c_detach_client(client);
-		kfree(client);
-		kfree(state);
-		return ret;
-	}
-
 	return 0;
 }
 
@@ -840,9 +965,9 @@
 {
 	struct mt352_state *state = i2c_get_clientdata(client);
 
+	if (state->dvb)
 	dvb_unregister_frontend (mt352_ioctl, state->dvb);
 	i2c_detach_client(client);
-	BUG_ON(state->dvb);
 	kfree(client);
 	kfree(state);
 	return 0;
@@ -851,13 +976,23 @@
 static int mt352_command (struct i2c_client *client, unsigned int cmd, void *arg)
 {
 	struct mt352_state *state = i2c_get_clientdata(client);
+	int ret;
 
 	switch (cmd) {
 	case FE_REGISTER:
+		if (!state->dvb) {
+			if ((ret = dvb_register_frontend(mt352_ioctl, arg,
+							 state, &state->fe_info,
+							 THIS_MODULE)))
+				return ret;
 		state->dvb = arg;
+		}
 		break;
 	case FE_UNREGISTER:
+		if (state->dvb == arg) {
+			dvb_unregister_frontend(mt352_ioctl, state->dvb);
 		state->dvb = NULL;
+		}
 		break;
 	default:
 		return -EOPNOTSUPP;
diff -uraNwB linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.h linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.h
--- linux-2.6.10-rc1/drivers/media/dvb/frontends/mt352.h	2004-10-25 14:07:57.000000000 +0200
+++ linux-2.6.10-rc1-patched/drivers/media/dvb/frontends/mt352.h	2004-10-25 14:14:43.000000000 +0200
@@ -4,11 +4,16 @@
  *  Written by Holger Waechtler <holger@qanu.de>
  *	 and Daniel Mack <daniel@qanu.de>
  *
- *  Support for Samsung TDTC9251DH01C(M) tuner
+ *  AVerMedia AVerTV DVB-T 771 support by
+ *       Wolfram Joost <dbox2@frokaschwei.de>
  *
+ *  Support for Samsung TDTC9251DH01C(M) tuner
  *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
  *                     Amauri  Celani  <acelani@essegi.net>
  *
+ *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
  *  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
@@ -29,12 +34,13 @@
 #define _MT352_
 
 #define I2C_MT352_ADDR  0x0f
-#define I2C_TUNER_ADDR  0xc2
 #define ID_MT352        0x13
 
 #define CARD_AVDVBT771	    0x00
 #define CARD_TUA6034	    0x01
 #define CARD_TDTC9251DH01C  0x02
+#define CARD_DVICODVBT1	    0x03
+#define CARD_DVICODVBTLITE  0x04
 
 #define msb(x) (((x) >> 8) & 0xff)
 #define lsb(x) ((x) & 0xff)
@@ -123,6 +129,9 @@
 };
 
 struct _tuner_info {
+	char *fe_name;
+#define FE_NAME tuner_info[card_type].fe_name
+
 	__u32 fe_frequency_min;
 #define FE_FREQ_MIN tuner_info[card_type].fe_frequency_min
 
@@ -132,26 +141,8 @@
 	__u32 fe_frequency_stepsize; //verificare se u32 e' corretto
 #define FE_FREQ_STEPSIZE  tuner_info[card_type].fe_frequency_stepsize
 
-	__u32 coderate_hp_shift; //verificare se u32 giusto
-#define CODERATE_HP_SHIFT tuner_info[card_type].coderate_hp_shift
-
-	__u32 coderate_lp_shift;
-#define CODERATE_LP_SHIFT tuner_info[card_type].coderate_lp_shift
-
-	int constellation_shift;
-#define CONSTELLATION_SHIFT tuner_info[card_type].constellation_shift
-
-	int tx_mode_shift;
-#define TX_MODE_SHIFT tuner_info[card_type].tx_mode_shift
-
-	int guard_interval_shift;
-#define GUARD_INTERVAL_SHIFT tuner_info[card_type].guard_interval_shift
-
-	int hierarchy_shift;
-#define HIERARCHY_SHIFT tuner_info[card_type].hierarchy_shift
-
-	int read_reg_flag;
-#define READ_REG_FLAG tuner_info[card_type].read_reg_flag
+	u8 pll_i2c_addr;
+#define PLL_I2C_ADDR tuner_info[card_type].pll_i2c_addr
 
 	int (* mt352_init) (struct i2c_adapter *i2c);
 #define MT352_INIT tuner_info[card_type].mt352_init
@@ -166,12 +157,18 @@
 static int mt352_init_TUA6034(struct i2c_adapter *i2c);
 static int mt352_init_AVERMEDIA771(struct i2c_adapter *i2c);
 static int mt352_init_TDTC9251DH01C(struct i2c_adapter *i2c);
+static int mt352_init_DVICODVBT1(struct i2c_adapter *i2c);
+static int mt352_init_DVICODVBTLITE(struct i2c_adapter *i2c);
 static unsigned char mt352_cp_TUA6034(u32 freq);
 static unsigned char mt352_cp_AVERMEDIA771(u32 freq);
 static unsigned char mt352_cp_TDTC9251DH01C(u32 freq);
+static unsigned char mt352_cp_DVICODVBT1(u32 freq);
+static unsigned char mt352_cp_DVICODVBTLITE(u32 freq);
 static unsigned char mt352_bs_TUA6034(u32 freq);
 static unsigned char mt352_bs_AVERMEDIA771(u32 freq);
 static unsigned char mt352_bs_TDTC9251DH01C(u32 freq);
-static int mt352_detect_avermedia_771(struct i2c_adapter *i2c);
+static unsigned char mt352_bs_DVICODVBT1(u32 freq);
+static unsigned char mt352_bs_DVICODVBTLITE(u32 freq);
+static u8 mt352_read_register(struct i2c_adapter *i2c, u8 reg);
 
 #endif                          /* _MT352_ */

      reply	other threads:[~2004-10-27 10:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-27  9:47 [PATCH][0/5] Update the DVB subsystem Michael Hunold
2004-10-27  9:49 ` [PATCH][1/5] DVB: rework debugging in av7110 Michael Hunold
2004-10-27  9:51   ` [PATCH][2/5] DVB: misc. updates to the dvb-core Michael Hunold
2004-10-27  9:52     ` [PATCH][3/5] DVB: add new driver Michael Hunold
2004-10-27  9:53       ` [PATCH][4/5] DVB: revamp dibusb driver Michael Hunold
2004-10-27  9:55         ` Michael Hunold [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=417F70A8.8000800@linuxtv.org \
    --to=hunold@linuxtv.org \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome