summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorHolger Waechtler <devnull@localhost>2003-12-01 08:26:55 +0000
committerHolger Waechtler <devnull@localhost>2003-12-01 08:26:55 +0000
commit819173108ff264ac976ae6184b612719a6648b2c (patch)
treed12dea1718be7395578de4531cbdb3d48af3c068 /linux
parentccf3562cf37c23c1ae6a31b3efe75e459933ce94 (diff)
downloadmediapointer-dvb-s2-819173108ff264ac976ae6184b612719a6648b2c.tar.gz
mediapointer-dvb-s2-819173108ff264ac976ae6184b612719a6648b2c.tar.bz2
patch for the mt312 module, targeting the VP310. Contributed by Augusto Cardoso.
1) Reduced heat in most applications of the VP310. This is specially important on the Skystar2 application. Some old boards based on the VP310 will have heat problems without this patch an may be permanently damaged. 2) Implement "auto" inversion mode for the VP310. With this and a VP310, you don't have to worry about inversion, this is like it should be. 3) Remove unnecessary "prints". 4) Add the ability to generate a module with the option to use debug. When MT312_DEBUG is 0, there is no debug code in the module. When it's set to 1, it's possible to control debug using the module parameter "debug=1"
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/frontends/mt312.c91
1 files changed, 74 insertions, 17 deletions
diff --git a/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c
index b94adc4e3..58fb627ec 100644
--- a/linux/drivers/media/dvb/frontends/mt312.c
+++ b/linux/drivers/media/dvb/frontends/mt312.c
@@ -39,11 +39,19 @@
#define MT312_DEBUG 0
#define MT312_SYS_CLK 90000000UL /* 90 MHz */
+#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
#define MT312_PLL_CLK 10000000UL /* 10 MHz */
/* number of active frontends */
static int mt312_count = 0;
+#if MT312_DEBUG == 0
+#define dprintk(x...)
+#else
+static int debug = 0;
+#define dprintk if(debug == 1) printk
+#endif
+
static struct dvb_frontend_info mt312_info = {
.name = "Zarlink MT312",
.type = FE_QPSK,
@@ -86,7 +94,7 @@ static int mt312_read(struct dvb_i2c_bus *i2c,
return -EREMOTEIO;
}
#if MT312_DEBUG
- {
+ if(debug) {
int i;
printk(KERN_INFO "R(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
@@ -107,7 +115,7 @@ static int mt312_write(struct dvb_i2c_bus *i2c,
struct i2c_msg msg;
#if MT312_DEBUG
- {
+ if(debug) {
int i;
printk(KERN_INFO "W(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
@@ -205,7 +213,7 @@ static int sl1935_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
if (freq < 1550000)
buf[3] |= 0x10;
- printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
+ dprintk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
buf[1], buf[2], buf[3]);
return mt312_pll_write(i2c, I2C_ADDR_SL1935, buf, sizeof(buf));
@@ -225,7 +233,7 @@ static int tsa5059_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
if (freq < 1550000)
buf[3] |= 0x02;
- printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
+ dprintk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
buf[1], buf[2], buf[3]);
return mt312_pll_write(i2c, I2C_ADDR_TSA5059, buf, sizeof(buf));
@@ -236,13 +244,13 @@ static int mt312_reset(struct dvb_i2c_bus *i2c, const u8 full)
return mt312_writereg(i2c, RESET, full ? 0x80 : 0x40);
}
-static int mt312_init(struct dvb_i2c_bus *i2c, const long id)
+static int mt312_init(struct dvb_i2c_bus *i2c, const long id, u8 pll)
{
int ret;
u8 buf[2];
/* wake up */
- if ((ret = mt312_writereg(i2c, CONFIG, 0x8c)) < 0)
+ if ((ret = mt312_writereg(i2c, CONFIG, (pll == 60 ? 0x88 : 0x8c))) < 0)
return ret;
/* wait at least 150 usec */
@@ -252,8 +260,17 @@ static int mt312_init(struct dvb_i2c_bus *i2c, const long id)
if ((ret = mt312_reset(i2c, 1)) < 0)
return ret;
+// Per datasheet, write correct values. 09/28/03 ACCJr.
+// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
+ {
+ u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
+
+ if ((ret = mt312_write(i2c, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
+ return ret;
+ }
+
/* SYS_CLK */
- buf[0] = mt312_div(MT312_SYS_CLK * 2, 1000000);
+ buf[0] = mt312_div((pll == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
/* DISEQC_RATIO */
buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
@@ -370,16 +387,18 @@ static int mt312_set_voltage(struct dvb_i2c_bus *i2c, const fe_sec_voltage_t v)
return mt312_writereg(i2c, DISEQC_MODE, volt_tab[v]);
}
-static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s)
+static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s, const long id)
{
int ret;
- u8 status[3];
+ u8 status[3], vit_mode;
*s = 0;
if ((ret = mt312_read(i2c, QPSK_STAT_H, status, sizeof(status))) < 0)
return ret;
+ dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
+
if (status[0] & 0xc0)
*s |= FE_HAS_SIGNAL; /* signal noise ratio */
if (status[0] & 0x04)
@@ -390,6 +409,16 @@ static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s)
*s |= FE_HAS_SYNC; /* byte align lock */
if (status[0] & 0x01)
*s |= FE_HAS_LOCK; /* qpsk lock */
+ // VP310 doesn't have AUTO, so we "implement it here" ACCJr
+ if ((id == ID_VP310) && !(status[0] & 0x01)) {
+ if ((ret = mt312_readreg(i2c, VIT_MODE, &vit_mode)) < 0)
+ return ret;
+ vit_mode ^= 0x40;
+ if ((ret = mt312_writereg(i2c, VIT_MODE, vit_mode)) < 0)
+ return ret;
+ if ((ret = mt312_writereg(i2c, GO, 0x01)) < 0)
+ return ret;
+ }
return 0;
}
@@ -422,7 +451,7 @@ static int mt312_read_agc(struct dvb_i2c_bus *i2c, u16 *signal_strength)
*signal_strength = agc;
- printk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
+ dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
return 0;
}
@@ -458,7 +487,7 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
const long id)
{
int ret;
- u8 buf[5];
+ u8 buf[5], config_val;
u16 sr;
const u8 fec_tab[10] =
@@ -467,6 +496,8 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
int (*set_tv_freq)(struct dvb_i2c_bus *i2c, u32 freq, u32 sr);
+ dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
+
if ((p->frequency < mt312_info.frequency_min)
|| (p->frequency > mt312_info.frequency_max))
return -EINVAL;
@@ -489,6 +520,22 @@ static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
switch (id) {
case ID_VP310:
+ // For now we will do this only for the VP310.
+ // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
+ if ((ret = mt312_readreg(i2c, CONFIG, &config_val) < 0))
+ return ret;
+ if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
+ {
+ if ((config_val & 0x0c) == 0x08) //We are running 60MHz
+ if ((ret = mt312_init(i2c, id, (u8) 90)) < 0)
+ return ret;
+ }
+ else
+ {
+ if ((config_val & 0x0c) == 0x0C) //We are running 90MHz
+ if ((ret = mt312_init(i2c, id, (u8) 60)) < 0)
+ return ret;
+ }
set_tv_freq = tsa5059_set_tv_freq;
break;
case ID_MT312:
@@ -562,7 +609,7 @@ static int mt312_get_symbol_rate(struct dvb_i2c_bus *i2c, u32 *sr)
monitor = (buf[0] << 8) | buf[1];
- printk(KERN_DEBUG "sr(auto) = %u\n",
+ dprintk(KERN_DEBUG "sr(auto) = %u\n",
mt312_div(monitor * 15625, 4));
} else {
if ((ret = mt312_writereg(i2c, MON_CTRL, 0x05)) < 0)
@@ -578,9 +625,9 @@ static int mt312_get_symbol_rate(struct dvb_i2c_bus *i2c, u32 *sr)
sym_rat_op = (buf[0] << 8) | buf[1];
- printk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
+ dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
sym_rat_op, dec_ratio);
- printk(KERN_DEBUG "*sr(manual) = %lu\n",
+ dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
(((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
2) - dec_ratio);
}
@@ -675,7 +722,7 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return -EOPNOTSUPP;
case FE_READ_STATUS:
- return mt312_read_status(i2c, arg);
+ return mt312_read_status(i2c, arg, (long) fe->data);
case FE_READ_BER:
return mt312_read_bercnt(i2c, arg);
@@ -702,8 +749,13 @@ static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
return mt312_sleep(i2c);
case FE_INIT:
- return mt312_init(i2c, (long) fe->data);
-
+ //For the VP310 we should run at 60MHz when ever possible.
+ //It should be better to run the mt312 ar lower speed when ever possible, but tunning will be slower. ACCJr 09/29/03
+ if ((long)fe->data == ID_MT312)
+ return mt312_init(i2c, (long) fe->data, (u8) 90);
+ else
+ return mt312_init(i2c, (long) fe->data, (u8) 60);
+
case FE_RESET:
return mt312_reset(i2c, 0);
@@ -755,6 +807,11 @@ static void __exit mt312_module_exit(void)
module_init(mt312_module_init);
module_exit(mt312_module_exit);
+#if MT312_DEBUG != 0
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+#endif
+
MODULE_DESCRIPTION("MT312 Satellite Channel Decoder Driver");
MODULE_AUTHOR("Andreas Oberritter <obi@saftware.de>");
MODULE_LICENSE("GPL");