summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/b2c2/skystar2.c6
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.c522
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.h179
3 files changed, 526 insertions, 181 deletions
diff --git a/linux/drivers/media/dvb/b2c2/skystar2.c b/linux/drivers/media/dvb/b2c2/skystar2.c
index d2a2bf350..216e697ca 100644
--- a/linux/drivers/media/dvb/b2c2/skystar2.c
+++ b/linux/drivers/media/dvb/b2c2/skystar2.c
@@ -294,10 +294,10 @@ static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int
ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
- /* allow only the mt312 and stv0299 frontends to access the bus */
- if ((msgs[i].addr != 0x0e) && (msgs[i].addr != 0x68) && (msgs[i].addr != 0x61)) {
+ /* allow only the mt312, mt352 and stv0299 frontends to access the bus */
+ if ((msgs[i].addr != 0x0e) && (msgs[i].addr != 0x68) &&
+ (msgs[i].addr != 0x61) && (msgs[i].addr != 0x0f)) {
up(&tmp->i2c_sem);
-
return -EREMOTEIO;
}
}
diff --git a/linux/drivers/media/dvb/frontends/mt352.c b/linux/drivers/media/dvb/frontends/mt352.c
index 21079b606..ae5027292 100644
--- a/linux/drivers/media/dvb/frontends/mt352.c
+++ b/linux/drivers/media/dvb/frontends/mt352.c
@@ -7,6 +7,11 @@
* 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>
+ *
* 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,10 @@
#include <linux/delay.h>
#include "dvb_frontend.h"
+#include "mt352.h"
-#define I2C_MT352_ADDR 0x0f
-#define I2C_TUNER_ADDR 0xc2
-
-#define CARD_UNKNOWN 0x00
-#define CARD_AVDVBT771 0x01
+static int force_card = -1;
+static u32 card_type = -1;
#define mt352_write(ibuf, ilen) \
do { \
@@ -42,27 +45,75 @@ do { \
.buf = ibuf, .len = ilen }; \
int err = i2c->xfer(i2c, &msg, 1); \
if (err != 1) { \
- printk(KERN_WARNING \
+ printk(KERN_WARNING \
"mt352_write() failed (err = %d)!\n", err); \
return err; \
} \
} while (0)
+static struct _tuner_info tuner_info [] = {
+ //TUA6034 tuner
+ {
+ .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,
+ .mt352_init = mt352_init_TUA6034,
+ .mt352_charge_pump = mt352_cp_TUA6034,
+ .mt352_band_select = mt352_bs_TUA6034
+ },
+ //AVERMEDIA 771 board
+ {
+ .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,
+ .mt352_init = mt352_init_AVERMEDIA771,
+ .mt352_charge_pump = mt352_cp_AVERMEDIA771,
+ .mt352_band_select = mt352_bs_AVERMEDIA771
+ },
+ //TDTC9251DH01C tuner
+ {
+ .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,
+ .mt352_init = mt352_init_TDTC9251DH01C,
+ .mt352_charge_pump = mt352_cp_TDTC9251DH01C,
+ .mt352_band_select = mt352_bs_TDTC9251DH01C
+ }
+};
-#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, /* NIM of AV771 starts at 50MHz */
- .frequency_max = 862000000,
- .frequency_stepsize = 83333,
+ .name = "DVB-T Zarlink MT352 demodulator driver",
+ .type = FE_OFDM,
/*
- .frequency_tolerance = 0,
- .symbol_rate_min = 1000000,
- .symbol_rate_max = 45000000,
- .symbol_rate_tolerance = ???,
+ .frequency_min = 0,
+ .frequency_max = 0,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = ???,
*/
.notifier_delay = 0,
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
@@ -74,8 +125,170 @@ static struct dvb_frontend_info mt352_info = {
FE_CAN_MUTE_TS
};
-int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
+static int mt352_init_TUA6034(struct dvb_i2c_bus *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));
+
+ return 0;
+}
+
+static int mt352_init_AVERMEDIA771(struct dvb_i2c_bus *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 };
+
+ 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));
+
+ return 0;
+}
+
+static int mt352_init_TDTC9251DH01C(struct dvb_i2c_bus *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));
+
+ return 0;
+}
+
+static unsigned char mt352_cp_TUA6034(u32 freq)
+{
+ unsigned char cp = 0;
+
+ if (freq < 542)
+ cp = 0xbe;
+ else if (freq < 830)
+ cp = 0xf6;
+ else
+ cp = 0xfe;
+
+ return cp;
+}
+
+static unsigned char mt352_cp_AVERMEDIA771(u32 freq)
+{
+ unsigned char cp = 0;
+
+ if (freq < 150)
+ cp = 0xB4;
+ else if (freq < 173)
+ cp = 0xBC;
+ else if (freq < 250)
+ cp = 0xB4;
+ else if (freq < 400)
+ cp = 0xBC;
+ else if (freq < 420)
+ cp = 0xF4;
+ else if (freq < 470)
+ cp = 0xFC;
+ else if (freq < 600)
+ cp = 0xBC;
+ else if (freq < 730)
+ cp = 0xF4;
+ else
+ cp = 0xFC;
+
+ return cp;
+}
+
+static unsigned char mt352_cp_TDTC9251DH01C(u32 freq)
+{
+ return(0xcc);
+}
+
+static unsigned char mt352_bs_TUA6034(u32 freq)
+{
+ unsigned char bs = 0;
+
+ if (freq < 250)
+ bs = 0x01;
+ else
+ bs = 0x08;
+
+ return bs;
+}
+
+static unsigned char mt352_bs_AVERMEDIA771(u32 freq)
+{
+ unsigned char bs = 0;
+
+ if (freq < 150)
+ bs = 0x01;
+ else if (freq < 173)
+ bs = 0x01;
+ else if (freq < 250)
+ bs = 0x02;
+ else if (freq < 400)
+ bs = 0x02;
+ else if (freq < 420)
+ bs = 0x02;
+ else if (freq < 470)
+ bs = 0x02;
+ else if (freq < 600)
+ bs = 0x08;
+ else if (freq < 730)
+ bs = 0x08;
+ else
+ bs = 0x08;
+
+ return bs;
+}
+
+static unsigned char mt352_bs_TDTC9251DH01C(u32 freq)
+{
+ unsigned char bs = 0;
+
+ if ((freq >= 48) && (freq <= 154)) /* low band */
+ bs = 0x09;
+
+ if ((freq >= 161) && (freq <= 439)) /* medium band */
+ bs = 0x0a;
+
+ if ((freq >= 447) && (freq <= 863)) /* high band */
+ bs = 0x08;
+
+ return bs;
+}
+
+
+static int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
{
+ int i;
u8 reg;
u8 id[4];
const u8 pciid[4] = { 0x07, 0x71, 0x14, 0x61 };
@@ -92,8 +305,7 @@ int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
.flags = I2C_M_RD,
.len = 1
}
- };
- int i;
+ };
for (i = 0; i < 4; i++)
{
@@ -108,50 +320,49 @@ int mt352_detect_avermedia_771(struct dvb_i2c_bus *i2c)
return *((u32 *) id) == *((u32 *) pciid);
}
-int mt352_init (struct dvb_i2c_bus *i2c, u32 card_type)
+static int mt352_detect_tdtc9251dh01c(struct dvb_i2c_bus *i2c)
+{
+ /* detection code must be written */
+
+ /* for Airstar2 DVB-T checking the PCI ID */
+ /* is not enought because the one reported from */
+ /* lspci is the one of Skystar2 */
+
+ if (force_card == 2)
+ return(1);
+ else
+ return(0);
+}
+
+static int mt352_detect_tua6034(struct dvb_i2c_bus *i2c)
+{
+ /* detection code must be written */
+ if (force_card == 0)
+ return(1);
+ else
+ return(0);
+}
+
+static int mt352_init(struct dvb_i2c_bus *i2c)
{
/**
* 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 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.
- */
- 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));
- 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));
- }
+ *
+ *
+ * The optimal AGC target value and slope might vary from tuner
+ * type to tuner type, so check whether you need to adjust this one...
+ **/
- return 0;
+ return(MT352_INIT(i2c));
}
-int mt352_sleep(struct dvb_i2c_bus *i2c)
+static int mt352_sleep(struct dvb_i2c_bus *i2c)
{
static u8 mt352_softdown[] = { 0x89, 0x20, 0x08 };
@@ -160,27 +371,27 @@ int mt352_sleep(struct dvb_i2c_bus *i2c)
return 0;
}
-int mt352_set_parameters (struct dvb_i2c_bus *i2c,
- struct dvb_frontend_parameters *param, u32 card_type)
+static int mt352_set_parameters(struct dvb_i2c_bus *i2c,
+ struct dvb_frontend_parameters *param)
{
unsigned char buf[14];
unsigned int tps = 0;
struct dvb_ofdm_parameters *op = &param->u.ofdm;
- u32 freq = param->frequency / 1000;
+ u32 freq = param->frequency / 1000000;
uint16_t tmp;
switch (op->code_rate_HP) {
case FEC_2_3:
- tps = (1 << 7);
+ tps |= (1 << CODERATE_HP_SHIFT);
break;
case FEC_3_4:
- tps = (2 << 7);
+ tps |= (2 << CODERATE_HP_SHIFT);
break;
case FEC_5_6:
- tps = (3 << 7);
+ tps |= (3 << CODERATE_HP_SHIFT);
break;
case FEC_7_8:
- tps = (4 << 7);
+ tps |= (4 << CODERATE_HP_SHIFT);
break;
case FEC_1_2:
case FEC_AUTO:
@@ -191,16 +402,16 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
switch (op->code_rate_LP) {
case FEC_2_3:
- tps |= (1 << 4);
+ tps |= (1 << CODERATE_LP_SHIFT);
break;
case FEC_3_4:
- tps |= (2 << 4);
+ tps |= (2 << CODERATE_LP_SHIFT);
break;
case FEC_5_6:
- tps |= (3 << 4);
+ tps |= (3 << CODERATE_LP_SHIFT);
break;
case FEC_7_8:
- tps |= (4 << 4);
+ tps |= (4 << CODERATE_LP_SHIFT);
break;
case FEC_1_2:
case FEC_AUTO:
@@ -214,10 +425,10 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
break;
case QAM_AUTO:
case QAM_16:
- tps |= (1 << 13);
+ tps |= (1 << CONSTELLATION_SHIFT);
break;
case QAM_64:
- tps |= (2 << 13);
+ tps |= (2 << CONSTELLATION_SHIFT);
break;
default:
return -EINVAL;
@@ -228,7 +439,7 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
case TRANSMISSION_MODE_AUTO:
break;
case TRANSMISSION_MODE_8K:
- tps |= (1 << 0);
+ tps |= (1 << TX_MODE_SHIFT);
break;
default:
return -EINVAL;
@@ -239,13 +450,13 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
case GUARD_INTERVAL_AUTO:
break;
case GUARD_INTERVAL_1_16:
- tps |= (1 << 2);
+ tps |= (1 << GUARD_INTERVAL_SHIFT);
break;
case GUARD_INTERVAL_1_8:
- tps |= (2 << 2);
+ tps |= (2 << GUARD_INTERVAL_SHIFT);
break;
case GUARD_INTERVAL_1_4:
- tps |= (3 << 2);
+ tps |= (3 << GUARD_INTERVAL_SHIFT);
break;
default:
return -EINVAL;
@@ -256,20 +467,20 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
case HIERARCHY_NONE:
break;
case HIERARCHY_1:
- tps |= (1 << 10);
+ tps |= (1 << HIERARCHY_SHIFT);
break;
case HIERARCHY_2:
- tps |= (2 << 10);
+ tps |= (2 << HIERARCHY_SHIFT);
break;
case HIERARCHY_4:
- tps |= (3 << 10);
+ tps |= (3 << HIERARCHY_SHIFT);
break;
default:
return -EINVAL;
}
- buf[0] = 0x51; /* TPS_GIVEN_1 and following registers */
+ buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */
buf[2] = lsb(tps);
@@ -291,6 +502,9 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
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;
/**
@@ -300,78 +514,13 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
/* here we assume 1/6MHz == 166.66kHz stepsize */
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
- tmp = (3 * freq) / 500 + IF_FREQUENCYx6;
+ tmp = 6 * freq + 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)
- {
- 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;
- }
- }
- else
- {
-
- 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[11] = MT352_CHARGE_PUMP(freq);
+ buf[12] = MT352_BAND_SELECT(freq);
buf[13] = 0x01; /* TUNER_GO!! */
@@ -380,13 +529,13 @@ int mt352_set_parameters (struct dvb_i2c_bus *i2c,
return 0;
}
-static u8 mt352_read_register (struct dvb_i2c_bus *i2c, u8 reg)
+static u8 mt352_read_register(struct dvb_i2c_bus *i2c, u8 reg)
{
int ret;
u8 b0 [] = { reg };
u8 b1 [] = { 0 };
struct i2c_msg msg [] = { { .addr = I2C_MT352_ADDR,
- .flags = I2C_M_NOSTART,
+ .flags = READ_REG_FLAG,
.buf = b0, .len = 1 },
{ .addr = I2C_MT352_ADDR,
.flags = I2C_M_RD,
@@ -402,13 +551,12 @@ static u8 mt352_read_register (struct dvb_i2c_bus *i2c, u8 reg)
}
-int mt352_get_parameters (struct dvb_i2c_bus *i2c,
- struct dvb_frontend_parameters *param, u32 card_type)
+static int mt352_get_parameters(struct dvb_i2c_bus *i2c,
+ struct dvb_frontend_parameters *param)
{
u16 tps;
u16 div;
u8 trl;
-
struct dvb_ofdm_parameters *op = &param->u.ofdm;
static const u8 tps_fec_to_api[8] =
{
@@ -430,9 +578,9 @@ int mt352_get_parameters (struct dvb_i2c_bus *i2c,
/* 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);
+ tps = (mt352_read_register(i2c, TPS_RECEIVED_1) << 8) | mt352_read_register(i2c, TPS_RECEIVED_0);
+ div = (mt352_read_register(i2c, CHAN_START_1) << 8) | mt352_read_register(i2c, CHAN_START_0);
+ trl = mt352_read_register(i2c, TRL_NOMINAL_RATE_1);
op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
@@ -508,16 +656,19 @@ int mt352_get_parameters (struct dvb_i2c_bus *i2c,
op->bandwidth = BANDWIDTH_6_MHZ;
}
- param->inversion = INVERSION_OFF;
+
+ if (mt352_read_register(i2c, STATUS_2) & 0x02)
+ param->inversion = INVERSION_OFF;
+ else
+ param->inversion = INVERSION_ON;
return 0;
}
-static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+static int mt352_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
struct dvb_i2c_bus *i2c = fe->i2c;
- u32 card_type = (u32) fe->data;
u8 r,snr;
fe_status_t *status;
u16 signal;
@@ -531,7 +682,7 @@ static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
case FE_READ_STATUS:
status = arg;
*status = 0;
- r = mt352_read_register (i2c, 0x00);
+ r = mt352_read_register (i2c, STATUS_0);
if (r & (1 << 4))
*status = FE_HAS_CARRIER;
if (r & (1 << 1))
@@ -539,45 +690,45 @@ static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
if (r & (1 << 5))
*status |= FE_HAS_LOCK;
- r = mt352_read_register (i2c, 0x01);
+ r = mt352_read_register (i2c, STATUS_1);
if (r & (1 << 1))
*status |= FE_HAS_SYNC;
- r = mt352_read_register (i2c, 0x03);
+ r = mt352_read_register (i2c, STATUS_3);
if (r & (1 << 6))
*status |= FE_HAS_SIGNAL;
break;
case FE_READ_BER:
- *((u32 *) arg) = (mt352_read_register (i2c, 0x0D) << 16) |
- (mt352_read_register (i2c, 0x0E) << 8) |
- (mt352_read_register (i2c, 0x0F));
+ *((u32 *) arg) = (mt352_read_register (i2c, RS_ERR_CNT_2) << 16) |
+ (mt352_read_register (i2c, RS_ERR_CNT_1) << 8) |
+ (mt352_read_register (i2c, RS_ERR_CNT_0));
break;
case FE_READ_SIGNAL_STRENGTH:
- signal = (mt352_read_register (i2c, 0x12) << 8) |
- (mt352_read_register (i2c, 0x13));
+ signal = (mt352_read_register (i2c, AGC_GAIN_3) << 8) |
+ (mt352_read_register (i2c, AGC_GAIN_2));
*((u16*) arg) = ~signal;
break;
case FE_READ_SNR:
- snr = mt352_read_register (i2c, 0x09);
+ snr = mt352_read_register (i2c, SNR);
*((u16*) arg) = (snr << 8) | snr;
break;
case FE_READ_UNCORRECTED_BLOCKS:
- *(u32*) arg = (mt352_read_register (i2c, 0x10) << 8) |
- (mt352_read_register (i2c, 0x11));
+ *(u32*) arg = (mt352_read_register (i2c, RS_UBC_1) << 8) |
+ (mt352_read_register (i2c, RS_UBC_0));
break;
case FE_SET_FRONTEND:
return mt352_set_parameters (i2c,
- (struct dvb_frontend_parameters *) arg,card_type);
+ (struct dvb_frontend_parameters *) arg);
case FE_GET_FRONTEND:
return mt352_get_parameters (i2c,
- (struct dvb_frontend_parameters *) arg,card_type);
+ (struct dvb_frontend_parameters *) arg);
case FE_GET_TUNE_SETTINGS:
fe_tune_settings = (struct dvb_frontend_tune_settings *) arg;
@@ -590,7 +741,7 @@ static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
return mt352_sleep(i2c);
case FE_INIT:
- return mt352_init(i2c,card_type);
+ return mt352_init(i2c);
default:
return -EOPNOTSUPP;
@@ -600,26 +751,38 @@ static int mt352_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
}
-static int mt352_attach (struct dvb_i2c_bus *i2c, void **data)
+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)
+ /* 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)
{
if (mt352_detect_avermedia_771(i2c))
{
card_type = CARD_AVDVBT771;
}
+ else if (mt352_detect_tdtc9251dh01c(i2c))
+ {
+ card_type = CARD_TDTC9251DH01C;
+ }
+ else if (mt352_detect_tua6034(i2c))
+ {
+ card_type = CARD_TUA6034;
+ }
else
{
- card_type = CARD_UNKNOWN;
+ return -ENODEV;
}
/* 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,
+ return dvb_register_frontend(mt352_ioctl, i2c, NULL,
&mt352_info);
}
@@ -627,20 +790,20 @@ static int mt352_attach (struct dvb_i2c_bus *i2c, void **data)
}
-static void mt352_detach (struct dvb_i2c_bus *i2c, void *data)
+static void mt352_detach(struct dvb_i2c_bus *i2c, void *data)
{
mt352_sleep(i2c);
dvb_unregister_frontend(mt352_ioctl, i2c);
}
-static int __init init_mt352 (void)
+static int __init init_mt352(void)
{
return dvb_register_i2c_device(NULL, mt352_attach, mt352_detach);
}
-static void __exit exit_mt352 (void)
+static void __exit exit_mt352(void)
{
dvb_unregister_i2c_device(mt352_attach);
}
@@ -651,5 +814,8 @@ module_exit(exit_mt352);
MODULE_DESCRIPTION("DVB-T MT352 Zarlink");
-MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
+MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
MODULE_LICENSE("GPL");
+
+MODULE_PARM(force_card, "i");
+MODULE_PARM_DESC(force_card, "<0: TUA6034 -- 1:AVDVBT771 -- 2: TDTC9251DH01C>");
diff --git a/linux/drivers/media/dvb/frontends/mt352.h b/linux/drivers/media/dvb/frontends/mt352.h
new file mode 100644
index 000000000..4a41ee6e0
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/mt352.h
@@ -0,0 +1,179 @@
+/*
+ * Driver for Zarlink DVB-T MT352 demodulator
+ *
+ * Written by Holger Waechtler <holger@qanu.de>
+ * and Daniel Mack <daniel@qanu.de>
+ *
+ * Support for Samsung TDTC9251DH01C(M) tuner
+ *
+ * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
+ * Amauri Celani <acelani@essegi.net>
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * 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.=
+ */
+
+#ifndef _MT352_
+#define _MT352_
+
+#define I2C_MT352_ADDR 0x0f
+#define I2C_TUNER_ADDR 0xc2
+#define ID_MT352 0x13
+
+#define CARD_TUA6034 0x00
+#define CARD_AVDVBT771 0x01
+#define CARD_TDTC9251DH01C 0x02
+
+#define msb(x) (((x) >> 8) & 0xff)
+#define lsb(x) ((x) & 0xff)
+
+enum mt352_reg_addr {
+ STATUS_0 = 0x00,
+ STATUS_1 = 0x01,
+ STATUS_2 = 0x02,
+ STATUS_3 = 0x03,
+ STATUS_4 = 0x04,
+ INTERRUPT_0 = 0x05,
+ INTERRUPT_1 = 0x06,
+ INTERRUPT_2 = 0x07,
+ INTERRUPT_3 = 0x08,
+ SNR = 0x09,
+ VIT_ERR_CNT_2 = 0x0A,
+ VIT_ERR_CNT_1 = 0x0B,
+ VIT_ERR_CNT_0 = 0x0C,
+ RS_ERR_CNT_2 = 0x0D,
+ RS_ERR_CNT_1 = 0x0E,
+ RS_ERR_CNT_0 = 0x0F,
+ RS_UBC_1 = 0x10,
+ RS_UBC_0 = 0x11,
+ AGC_GAIN_3 = 0x12,
+ AGC_GAIN_2 = 0x13,
+ AGC_GAIN_1 = 0x14,
+ AGC_GAIN_0 = 0x15,
+ FREQ_OFFSET_2 = 0x17,
+ FREQ_OFFSET_1 = 0x18,
+ FREQ_OFFSET_0 = 0x19,
+ TIMING_OFFSET_1 = 0x1A,
+ TIMING_OFFSET_0 = 0x1B,
+ CHAN_FREQ_1 = 0x1C,
+ CHAN_FREQ_0 = 0x1D,
+ TPS_RECEIVED_1 = 0x1E,
+ TPS_RECEIVED_0 = 0x1F,
+ TPS_CURRENT_1 = 0x20,
+ TPS_CURRENT_0 = 0x21,
+ TPS_CELL_ID_1 = 0x22,
+ TPS_CELL_ID_0 = 0x23,
+ TPS_MISC_DATA_2 = 0x24,
+ TPS_MISC_DATA_1 = 0x25,
+ TPS_MISC_DATA_0 = 0x26,
+ RESET = 0x50,
+ TPS_GIVEN_1 = 0x51,
+ TPS_GIVEN_0 = 0x52,
+ ACQ_CTL = 0x53,
+ TRL_NOMINAL_RATE_1 = 0x54,
+ TRL_NOMINAL_RATE_0 = 0x55,
+ INPUT_FREQ_1 = 0x56,
+ INPUT_FREQ_0 = 0x57,
+ TUNER_ADDR = 0x58,
+ CHAN_START_1 = 0x59,
+ CHAN_START_0 = 0x5A,
+ CONT_1 = 0x5B,
+ CONT_0 = 0x5C,
+ TUNER_GO = 0x5D,
+ STATUS_EN_0 = 0x5F,
+ STATUS_EN_1 = 0x60,
+ INTERRUPT_EN_0 = 0x61,
+ INTERRUPT_EN_1 = 0x62,
+ INTERRUPT_EN_2 = 0x63,
+ INTERRUPT_EN_3 = 0x64,
+ AGC_TARGET = 0x67,
+ AGC_CTL = 0x68,
+ CAPT_RANGE = 0x75,
+ SNR_SELECT_1 = 0x79,
+ SNR_SELECT_0 = 0x7A,
+ RS_ERR_PER_1 = 0x7C,
+ RS_ERR_PER_0 = 0x7D,
+ CHIP_ID = 0x7F,
+ CHAN_STOP_1 = 0x80,
+ CHAN_STOP_0 = 0x81,
+ CHAN_STEP_1 = 0x82,
+ CHAN_STEP_0 = 0x83,
+ FEC_LOCK_TIME = 0x85,
+ OFDM_LOCK_TIME = 0x86,
+ ACQ_DELAY = 0x87,
+ SCAN_CTL = 0x88,
+ CLOCK_CTL = 0x89,
+ CONFIG = 0x8A,
+ MCLK_RATIO = 0x8B,
+ GPP_CTL = 0x8C,
+ ADC_CTL_1 = 0x8E,
+ ADC_CTL_0 = 0x8F
+};
+
+struct _tuner_info {
+ __u32 fe_frequency_min;
+#define FE_FREQ_MIN tuner_info[card_type].fe_frequency_min
+
+ __u32 fe_frequency_max;
+#define FE_FREQ_MAX tuner_info[card_type].fe_frequency_max
+
+ __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
+
+ int (* mt352_init) (struct dvb_i2c_bus *i2c);
+#define MT352_INIT tuner_info[card_type].mt352_init
+
+ unsigned char (* mt352_charge_pump) (u32 freq);
+#define MT352_CHARGE_PUMP tuner_info[card_type].mt352_charge_pump
+
+ unsigned char (* mt352_band_select) (u32 freq);
+#define MT352_BAND_SELECT tuner_info[card_type].mt352_band_select
+};
+
+static int mt352_init_TUA6034(struct dvb_i2c_bus *i2c);
+static int mt352_init_AVERMEDIA771(struct dvb_i2c_bus *i2c);
+static int mt352_init_TDTC9251DH01C(struct dvb_i2c_bus *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_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 dvb_i2c_bus *i2c);
+static int mt352_detect_tdtc9251dh01c(struct dvb_i2c_bus *i2c);
+static int mt352_detect_tua6034(struct dvb_i2c_bus *i2c);
+
+#endif /* _MT352_ */