25 #include <linux/slab.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
48 #define dprintk(args...) \
50 if (debug) printk(KERN_DEBUG "cx24110: " args); \
119 struct i2c_msg msg = { .addr = state->
config->demod_address, .flags = 0, .buf =
buf, .len = 2 };
123 dprintk (
"%s: writereg error (err == %i, reg == 0x%02x,"
124 " data == 0x%02x)\n", __func__, err, reg, data);
136 struct i2c_msg msg [] = { { .
addr = state->
config->demod_address, .flags = 0, .buf = b0, .len = 1 },
137 { .addr = state->
config->demod_address, .flags =
I2C_M_RD, .buf = b1, .len = 1 } };
141 if (ret != 2)
return ret;
152 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
154 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
156 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
162 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
164 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
166 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
170 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
184 static const int rate[]={-1,1,2,3,5,7,-1};
185 static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
186 static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
196 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
198 cx24110_writereg(state,0x18,0xae);
200 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
202 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
204 cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
208 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
211 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
213 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
215 cx24110_writereg(state,0x1a,g1[fec]);
216 cx24110_writereg(state,0x1b,g2[fec]);
229 i=cx24110_readreg(state,0x22)&0x0f;
247 static const u32 bands[]={5000000
UL,15000000
UL,90999000UL/2};
250 dprintk(
"cx24110 debug: entering %s(%d)\n",__func__,srate);
251 if (srate>90999000
UL/2)
256 for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[
i]); i++)
261 tmp=cx24110_readreg(state,0x07)&0xfc;
262 if(srate<90999000
UL/4) {
263 cx24110_writereg(state,0x07,tmp);
264 cx24110_writereg(state,0x06,0x78);
266 }
else if(srate<60666000
UL/2) {
267 cx24110_writereg(state,0x07,tmp|0x1);
268 cx24110_writereg(state,0x06,0xa5);
270 }
else if(srate<80888000
UL/2) {
271 cx24110_writereg(state,0x07,tmp|0x2);
272 cx24110_writereg(state,0x06,0x87);
275 cx24110_writereg(state,0x07,tmp|0x3);
276 cx24110_writereg(state,0x06,0x78);
279 dprintk(
"cx24110 debug: fclk %d Hz\n",fclk);
293 ratio=(ratio<<8)+(tmp/BDRI);
296 ratio=(ratio<<8)+(tmp/BDRI);
299 ratio=(ratio<<1)+(tmp/BDRI);
301 dprintk(
"srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
303 dprintk(
"ratio= %08x\n", ratio);
305 cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
306 cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
307 cx24110_writereg(state, 0x3, (ratio)&0xff);
324 cx24110_writereg(state,0x6d,0x30);
325 cx24110_writereg(state,0x70,0x15);
328 while (cx24110_readreg(state,0x6d)&0x80)
329 cx24110_writereg(state,0x72,0);
332 cx24110_writereg(state,0x72,buf[0]);
335 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
339 cx24110_writereg(state,0x72,buf[1]);
340 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
344 cx24110_writereg(state,0x72,buf[2]);
345 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
349 cx24110_writereg(state,0x6d,0x32);
350 cx24110_writereg(state,0x6d,0x30);
361 dprintk(
"%s: init chip\n", __func__);
363 for(i = 0; i <
ARRAY_SIZE(cx24110_regdata); i++) {
364 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
376 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
378 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
397 rv = cx24110_readreg(state, 0x77);
399 cx24110_writereg(state, 0x77, rv | 0x04);
401 rv = cx24110_readreg(state, 0x76);
402 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
404 while (!
time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
410 static int cx24110_send_diseqc_msg(
struct dvb_frontend* fe,
415 unsigned long timeout;
420 for (i = 0; i < cmd->
msg_len; i++)
421 cx24110_writereg(state, 0x79 + i, cmd->
msg[i]);
423 rv = cx24110_readreg(state, 0x77);
425 cx24110_writereg(state, 0x77, rv & ~0x04);
429 rv = cx24110_readreg(state, 0x76);
431 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->
msg_len-3) & 3));
433 while (!
time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
443 int sync = cx24110_readreg (state, 0x55);
453 sync = cx24110_readreg (state, 0x08);
461 if ((sync & 0x60) == 0x60)
472 if(cx24110_readreg(state,0x24)&0x10) {
474 cx24110_writereg(state,0x24,0x04);
475 state->
lastber=cx24110_readreg(state,0x25)|
476 (cx24110_readreg(state,0x26)<<8);
477 cx24110_writereg(state,0x24,0x04);
478 cx24110_writereg(state,0x24,0x14);
485 static int cx24110_read_signal_strength(
struct dvb_frontend* fe,
u16* signal_strength)
490 u8 signal = cx24110_readreg (state, 0x27)+128;
491 *signal_strength = (signal << 8) | signal;
501 if(cx24110_readreg(state,0x6a)&0x80) {
503 state->
lastesn0=cx24110_readreg(state,0x69)|
504 (cx24110_readreg(state,0x68)<<8);
505 cx24110_writereg(state,0x6a,0x84);
512 static int cx24110_read_ucblocks(
struct dvb_frontend* fe,
u32* ucblocks)
516 if(cx24110_readreg(state,0x10)&0x40) {
518 cx24110_writereg(state,0x10,0x60);
519 (
void)(cx24110_readreg(state, 0x12) |
520 (cx24110_readreg(state, 0x13) << 8) |
521 (cx24110_readreg(state, 0x14) << 16));
522 cx24110_writereg(state,0x10,0x70);
523 state->
lastbler=cx24110_readreg(state,0x12)|
524 (cx24110_readreg(state,0x13)<<8)|
525 (cx24110_readreg(state,0x14)<<16);
526 cx24110_writereg(state,0x10,0x20);
533 static int cx24110_set_frontend(
struct dvb_frontend *fe)
538 if (fe->
ops.tuner_ops.set_params) {
539 fe->
ops.tuner_ops.set_params(fe);
540 if (fe->
ops.i2c_gate_ctrl) fe->
ops.i2c_gate_ctrl(fe, 0);
543 cx24110_set_inversion(state, p->
inversion);
546 cx24110_writereg(state,0x04,0x05);
551 static int cx24110_get_frontend(
struct dvb_frontend *fe)
559 sclk = cx24110_readreg (state, 0x07) & 0x03;
562 if (sclk==0) sclk=90999000
L/2
L;
563 else if (sclk==1) sclk=60666000
L;
564 else if (sclk==2) sclk=80888000
L;
567 afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
568 ((sclk*cx24110_readreg (state, 0x45))>>8)+
569 ((sclk*cx24110_readreg (state, 0x46))>>16);
572 p->
inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
583 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==
SEC_TONE_ON))?0x10:0));
612 ret = cx24110_readreg(state, 0x00);
613 if ((ret != 0x5a) && (ret != 0x69))
goto error;
628 .name =
"Conexant CX24110 DVB-S",
629 .frequency_min = 950000,
630 .frequency_max = 2150000,
631 .frequency_stepsize = 1011,
632 .frequency_tolerance = 29500,
633 .symbol_rate_min = 1000000,
634 .symbol_rate_max = 45000000,
641 .release = cx24110_release,
643 .init = cx24110_initfe,
644 .write = _cx24110_pll_write,
645 .set_frontend = cx24110_set_frontend,
646 .get_frontend = cx24110_get_frontend,
647 .read_status = cx24110_read_status,
648 .read_ber = cx24110_read_ber,
649 .read_signal_strength = cx24110_read_signal_strength,
650 .read_snr = cx24110_read_snr,
651 .read_ucblocks = cx24110_read_ucblocks,
653 .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
654 .set_tone = cx24110_set_tone,
655 .set_voltage = cx24110_set_voltage,
656 .diseqc_send_burst = cx24110_diseqc_send_burst,