- struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
- { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-/* fixme (medium): address might be different from 0x55 */
- ret = i2c->xfer (i2c, msg, 2);
-
- if (ret != 2)
- dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
-
- return b1[0];
-}
-
-
-static int cx24108_write (struct dvb_i2c_bus *i2c, u32 data)
-{
-/* tuner data is 21 bits long, must be left-aligned in data */
-/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
-/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
-
-dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
-
- cx24110_writereg(i2c,0x6d,0x30); /* auto mode at 62kHz */
- cx24110_writereg(i2c,0x70,0x15); /* auto mode 21 bits */
- /* if the auto tuner writer is still busy, clear it out */
- while (cx24110_readreg(i2c,0x6d)&0x80)
- cx24110_writereg(i2c,0x72,0);
- /* write the topmost 8 bits */
- cx24110_writereg(i2c,0x72,(data>>24)&0xff);
- /* wait for the send to be completed */
- while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80)
- ;
- /* send another 8 bytes */
- cx24110_writereg(i2c,0x72,(data>>16)&0xff);
- while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80)
- ;
- /* and the topmost 5 bits of this byte */
- cx24110_writereg(i2c,0x72,(data>>8)&0xff);
- while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80)
- ;
- /* now strobe the enable line once */
- cx24110_writereg(i2c,0x6d,0x32);
- cx24110_writereg(i2c,0x6d,0x30);
-
- return 0;
-}
-
-
-static int cx24108_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
-{
-/* fixme (low): error handling */
- int i, a, n, pump;
- u32 band, pll;
-
-
- static const u32 osci[]={ 950000,1019000,1075000,1178000,
- 1296000,1432000,1576000,1718000,
- 1856000,2036000,2150000};
- static const u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,
- 0x00101000,0x00102000,0x00104000,
- 0x00108000,0x00110000,0x00120000,
- 0x00140000};
-
-#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
- dprintk("cx24110 debug: cx24108_set_tv_freq, freq=%d\n",freq);
-
- if (freq<950000)
- freq=950000; /* kHz */
- if (freq>2150000)
- freq=2150000; /* satellite IF is 950..2150MHz */
- /* decide which VCO to use for the input frequency */
- for (i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++)
- ;
- dprintk("cx24110 debug: select vco #%d (f=%d)\n",i,freq);
- band=bandsel[i];
- /* the gain values must be set by SetSymbolrate */
- /* compute the pll divider needed, from Conexant data sheet,
- resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
- depending on the divider bit. It is set to /4 on the 2 lowest
- bands */
- n=((i<=2?2:1)*freq*10L)/(XTAL/100);
- a=n%32; n/=32;
- if (a==0)
- n--;
- pump=(freq<(osci[i-1]+osci[i])/2);
- pll=0xf8000000|
- ((pump?1:2)<<(14+11))|
- ((n&0x1ff)<<(5+11))|
- ((a&0x1f)<<11);
- /* everything is shifted left 11 bits to left-align the bits in the
- 32bit word. Output to the tuner goes MSB-aligned, after all */
- dprintk("cx24110 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
- cx24108_write(i2c,band);
- /* set vga and vca to their widest-band settings, as a precaution.
- SetSymbolrate might not be called to set this up */
- cx24108_write(i2c,0x500c0000);
- cx24108_write(i2c,0x83f1f800);
- cx24108_write(i2c,pll);
- cx24110_writereg(i2c,0x56,0x7f);
-
- dvb_delay(10); /* wait a moment for the tuner pll to lock */
-
- /* tuner pll lock can be monitored on GPIO pin 4 of cx24110 */
- while (!(cx24110_readreg(i2c,0x66)&0x20)&&i<1000)
- i++;
- dprintk("cx24110 debug: GPIO IN=%2.2x(loop=%d)\n",
- cx24110_readreg(i2c,0x66),i);
- return 0;
-
-}
-