Mailing List archive

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

[linux-dvb] Re: Problems with Hauppauge



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.
Is there a chance to get the final SU1278 specs from Philips, TechnoTrend
or Hauppauge? Does anybody have a contact?

Regards,
-- 
Steffen Beyer <sbeyer@reactor.de>

GnuPG key fingerprint: 6C9B 2844 AF75 AC7A C38C  9FFD 06CB A788 398B D2D9
Public key available upon request or at http://wwwkeys.pgp.net
--- 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);

Attachment: pgp00004.pgp
Description: PGP signature


Home | Main Index | Thread Index