Mailing List archive

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

[linux-dvb] Re: Problems with Hauppauge



Steffen Beyer wrote:
Hi,

here's another version of the patch. I copied some initial register
settings from the (preliminary) SU1278 specs, which improved my signal
strength and SNR a bit. Note that this version may break/worsen the
functionality for non-SU1278 users.
Have you tried the Windows driver, is this working reliably? If so, have you found out what are they doing differently?

Holger


------------------------------------------------------------------------

--- stv0299.c 31 Jul 2003 23:15:45 -0000 1.8
+++ stv0299.c 20 Nov 2003 20:03:06 -0000
@@ -40,6 +40,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
+#include <asm/div64.h>
#include "dvb_frontend.h"
#include "compat.h"
@@ -89,8 +90,8 @@
u8 init_tab [] = {
/* clock registers */
0x01, 0x15, /* K = 0, DIRCLK = 0, M = 0x15 */
- 0x02, 0x30, /* STDBY = 0, VCO = 0 (ON), SERCLK = 0, P = 0 */
- /* f_VCO = 4MHz * 4 * (M+1) / (K+1) = 352 MHz */
+ 0x02, 0x00, /* M-CLK = 88 MHz, doesn't fit STV0299 specs */
+ /* taken from SU1278 specs */
0x03, 0x00, /* auxiliary clock not used */
0x04, 0x7d, /* F22FR = 0x7d */
/* F22 = f_VCO / 128 / 0x7d = 22 kHz */
@@ -99,28 +100,30 @@
0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
/* general purpose DAC registers */
- 0x06, 0x40, /* DAC not used, set to high impendance mode */
+ 0x06, 0x00, /* DAC not used */
+ /* taken from SU1278 specs */
0x07, 0x00, /* DAC LSB */
/* DiSEqC registers */
- 0x08, 0x40, /* DiSEqC off */
+ 0x08, 0x00, /* DiSEqC off */
0x09, 0x00, /* FIFO */
/* Input/Output configuration register */
- 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+ 0x0c, 0x50, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
/* OP0 ctl = Normal, OP0 val = 1 (18 V) */
/* Nyquist filter = 00, QPSK reverse = 0 */
/* AGC1 control register */
- 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
+ 0x0d, 0x81, /* DC offset compensation = ON, beta_agc1 = 1 */
+ /* taken from SU1278 specs */
/* Timing loop register */
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
- 0x10, 0x3f, // AGC2 0x3d
+ 0x10, 0x39, // AGC2 0x3d
0x11, 0x84,
- 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
- 0x13, 0xb6, // alpha_car b:4 a:0 noise est:256ks derot:on
+ 0x12, 0x39, // CFD, taken from SU1278 specs
+ 0x13, 0xb5, // ACLC, taken from SU1278 specs
0x14, 0x93, // beat carc:0 d:0 e:0xf phase detect algo: 1
0x15, 0xc9, // lock detector threshold
@@ -151,7 +154,6 @@
0x2b, 0x0f, // 3/4 threshold
0x2c, 0x09, // 5/6 threshold
0x2d, 0x05, // 7/8 threshold
- 0x2e, 0x01,
0x31, 0x1f, // test all FECs
@@ -161,6 +163,7 @@
0x0b, 0x00,
0x27, 0x00,
+ 0x2e, 0x00,
0x2f, 0x00,
0x30, 0x00,
0x35, 0x00,
@@ -189,7 +192,6 @@
0x4c, 0x00,
0x4d, 0x00,
0x4e, 0x00,
- 0x4f, 0x00
};
@@ -254,20 +256,21 @@
int pll_write (struct dvb_i2c_bus *i2c, u8 data [4], int ftype)
{
int ret;
- u8 rpt1 [] = { 0x05, 0xb5 }; /* enable i2c repeater on stv0299 */
/* TSA5059 i2c-bus address */
u8 addr = (ftype == PHILIPS_SU1278SH) ? 0x60 : 0x61;
- struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 },
- { addr: addr, flags: 0, buf: data, len: 4 }};
+ struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = 4 };
dprintk ("%s\n", __FUNCTION__);
- ret = i2c->xfer (i2c, msg, 2);
+ stv0299_writereg(i2c, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- if (ret != 2)
+ ret = i2c->xfer (i2c, &msg, 1);
+
+ if (ret != 1)
dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
+ stv0299_writereg(i2c, 0x05, 0x35); /* disable i2c repeater on stv0299 */
- return (ret != 2) ? -1 : 0;
+ return (ret != 1) ? -1 : 0;
}
@@ -303,31 +306,54 @@
* reference clock comparision frequency of 125 kHz.
*/
static
-int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype)
+int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
{
- u32 div = freq / 125;
-
- u8 buf[4] = { (div >> 8) & 0x7f, div & 0xff, 0x84 };
+ u32 div;
+ u8 buf[4];
- if (ftype == PHILIPS_SU1278SH)
- /* activate f_xtal/f_comp signal output */
- /* charge pump current C0/C1 = 00 */
- buf[3] = 0x20;
- else
- buf[3] = freq > 1530000 ? 0xc0 : 0xc4;
+ if ((freq < 950000) || (freq > 2150000)) return -EINVAL;
+ // setup frequency divisor
+ div = freq / 1000;
+ buf[0] = (div >> 8) & 0x7f;
+ buf[1] = div & 0xff;
+ buf[2] = 0x81 | ((div & 0x18000) >> 10);
+ buf[3] = 0;
+
+ // tuner-specific settings
+ switch(ftype) {
+ case PHILIPS_SU1278SH:
+ buf[3] |= 0x20;
+
+ if (srate < 4000000) buf[3] |= 1;
+ + if (freq <= 1250000) buf[3] |= 0;
+ else if (freq <= 1550000) buf[3] |= 0x40;
+ // violates the SU1278 specs, but seems to work better
+ // else if (freq <= 2050000) buf[3] |= 0x80;
+ else if (freq <= 2150000) buf[3] |= 0xC0;
+ break;
+
+ case ALPS_BSRU6:
+ buf[3] |= 0xC0;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ dprintk ("%s\n", __FUNCTION__);
return pll_write (i2c, buf, ftype);
}
static
-int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype)
+int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
{
if (ftype == LG_TDQF_S001F)
return sl1935_set_tv_freq(i2c, freq, ftype);
else
- return tsa5059_set_tv_freq(i2c, freq, ftype);
+ return tsa5059_set_tv_freq(i2c, freq, ftype, srate);
}
#if 0
@@ -365,7 +391,7 @@
/* AGC1 reference register setup */
if (ftype == PHILIPS_SU1278SH)
- stv0299_writereg (i2c, 0x0f, 0xd2); /* Iagc = Inverse, m1 = 18 */
+ stv0299_writereg (i2c, 0x0f, 0x92); /* Iagc = Inverse, m1 = 18 */
else
stv0299_writereg (i2c, 0x0f, 0x52); /* Iagc = Normal, m1 = 18 */
@@ -593,39 +619,63 @@
static
-int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
+int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int ftype)
{
+ u64 big = srate;
u32 ratio;
- u32 tmp;
- u8 aclk = 0xb4, bclk = 0x51;
+ u8 aclk = 0;
+ u8 bclk = 0;
+ u8 m1;
+
+ if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
+
+ switch (ftype) {
+ case PHILIPS_SU1278SH:
+ aclk = 0xb5; + if (srate < 2000000) bclk = 0x86;
+ else if (srate < 5000000) bclk = 0x89;
+ else if (srate < 15000000) bclk = 0x8f;
+ else if (srate < 45000000) bclk = 0x95;
- if (srate > M_CLK)
- srate = M_CLK;
- if (srate < 500000)
- srate = 500000;
-
- if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
- if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
- if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
- if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
- if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
+ m1 = 0x14;
+ if (srate < 4000000) m1 = 0x10;
+ break;
+
+ case ALPS_BSRU6:
+ default:
+ if (srate <= 1500000) { aclk = 0xb7; bclk = 0x87; }
+ else if (srate <= 3000000) { aclk = 0xb7; bclk = 0x8b; } + else if (srate <= 7000000) { aclk = 0xb7; bclk = 0x8f; }
+ else if (srate <= 14000000) { aclk = 0xb7; bclk = 0x93; } + else if (srate <= 30000000) { aclk = 0xb6; bclk = 0x93; }
+ else if (srate <= 45000000) { aclk = 0xb4; bclk = 0x91; }
+ + m1 = 0x12;
+ break;
+ }
-#define FIN (M_CLK >> 4)
- tmp = srate << 4;
- ratio = tmp / FIN;
- - tmp = (tmp % FIN) << 8;
- ratio = (ratio << 8) + tmp / FIN;
- - tmp = (tmp % FIN) << 8;
- ratio = (ratio << 8) + tmp / FIN;
- stv0299_writereg (i2c, 0x13, aclk);
stv0299_writereg (i2c, 0x14, bclk);
+
+ dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff), (int) (big & 0xffffffff) );
+
+ big = big << 20;
+
+ dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff), (int) (big & 0xffffffff) );
+
+ do_div(big, M_CLK);
+
+ dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff), (int) (big & 0xffffffff) );
+
+ ratio = big << 4;
+
+ dprintk("%s : ratio = %i\n", __FUNCTION__, ratio);
+
stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
stv0299_writereg (i2c, 0x20, (ratio >> 8) & 0xff);
stv0299_writereg (i2c, 0x21, (ratio ) & 0xf0);
+ stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1);
return 0;
}
@@ -740,9 +790,9 @@
{
struct dvb_frontend_parameters *p = arg;
- pll_set_tv_freq (i2c, p->frequency, tuner_type);
+ pll_set_tv_freq (i2c, p->frequency, tuner_type, p->u.qpsk.symbol_rate);
stv0299_set_FEC (i2c, p->u.qpsk.fec_inner);
- stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
+ stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, tuner_type);
stv0299_writereg (i2c, 0x22, 0x00);
stv0299_writereg (i2c, 0x23, 0x00);
stv0299_readreg (i2c, 0x23);



--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index