37 #include <linux/slab.h>
38 #include <linux/kernel.h>
39 #include <linux/module.h>
51 #define dprintk(args...) \
54 printk(KERN_INFO "cx24116: " args); \
57 #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
58 #define CX24116_SEARCH_RANGE_KHZ 5000
61 #define CX24116_REG_COMMAND (0x00)
62 #define CX24116_REG_EXECUTE (0x1f)
63 #define CX24116_REG_MAILBOX (0x96)
64 #define CX24116_REG_RESET (0x20)
65 #define CX24116_REG_SIGNAL (0x9e)
66 #define CX24116_REG_SSTATUS (0x9d)
67 #define CX24116_REG_QUALITY8 (0xa3)
68 #define CX24116_REG_QSTATUS (0xbc)
69 #define CX24116_REG_QUALITY0 (0xd5)
70 #define CX24116_REG_BER0 (0xc9)
71 #define CX24116_REG_BER8 (0xc8)
72 #define CX24116_REG_BER16 (0xc7)
73 #define CX24116_REG_BER24 (0xc6)
74 #define CX24116_REG_UCB0 (0xcb)
75 #define CX24116_REG_UCB8 (0xca)
76 #define CX24116_REG_CLKDIV (0xf3)
77 #define CX24116_REG_RATEDIV (0xf9)
80 #define CX24116_REG_FECSTATUS (0x9c)
84 #define CX24116_FEC_FECMASK (0x1f)
87 #define CX24116_FEC_DVBS (0x20)
88 #define CX24116_FEC_UNKNOWN (0x40)
91 #define CX24116_FEC_PILOT (0x80)
94 #define CX24116_ARGLEN (0x1e)
97 #define CX24116_ROLLOFF_020 (0x00)
98 #define CX24116_ROLLOFF_025 (0x01)
99 #define CX24116_ROLLOFF_035 (0x02)
102 #define CX24116_PILOT_OFF (0x00)
103 #define CX24116_PILOT_ON (0x40)
106 #define CX24116_HAS_SIGNAL (0x01)
107 #define CX24116_HAS_CARRIER (0x02)
108 #define CX24116_HAS_VITERBI (0x04)
109 #define CX24116_HAS_SYNCLOCK (0x08)
110 #define CX24116_HAS_UNKNOWN1 (0x10)
111 #define CX24116_HAS_UNKNOWN2 (0x20)
112 #define CX24116_STATUS_MASK (0x0f)
113 #define CX24116_SIGNAL_MASK (0xc0)
115 #define CX24116_DISEQC_TONEOFF (0)
116 #define CX24116_DISEQC_TONECACHE (1)
117 #define CX24116_DISEQC_MESGCACHE (2)
120 #define CX24116_DISEQC_BURST (1)
121 #define CX24116_DISEQC_ARG2_2 (2)
122 #define CX24116_DISEQC_ARG3_0 (3)
123 #define CX24116_DISEQC_ARG4_0 (4)
124 #define CX24116_DISEQC_MSGLEN (5)
125 #define CX24116_DISEQC_MSGOFS (6)
128 #define CX24116_DISEQC_MINI_A (0)
129 #define CX24116_DISEQC_MINI_B (1)
132 static int toneburst = 1;
135 "2=MESSAGE CACHE (default:1)");
141 "1=ESNO(db * 10) (default:0)");
203 .flags = 0, .buf =
buf, .len = 2 };
207 printk(
"cx24116: %s: write reg 0x%02x, value 0x%02x\n",
208 __func__, reg, data);
213 " value == 0x%02x)\n", __func__, err, reg, data);
221 static int cx24116_writeregN(
struct cx24116_state *state,
int reg,
230 printk(
"Unable to kmalloc\n");
236 memcpy(buf + 1, data, len);
266 { .
addr = state->
config->demod_address, .flags = 0,
267 .buf = b0, .len = 1 },
269 .buf = b1, .len = 1 }
287 static int cx24116_set_inversion(
struct cx24116_state *state,
290 dprintk(
"%s(%d)\n", __func__, inversion);
294 state->
dnxt.inversion_val = 0x00;
297 state->
dnxt.inversion_val = 0x04;
300 state->
dnxt.inversion_val = 0x0C;
306 state->
dnxt.inversion = inversion;
375 static struct cx24116_modfec {
381 } CX24116_MODFEC_MODES[] = {
417 static int cx24116_lookup_fecmod(
struct cx24116_state *state,
422 dprintk(
"%s(0x%02x,0x%02x)\n", __func__, m, f);
424 for (i = 0; i <
ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
425 if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
426 (m == CX24116_MODFEC_MODES[
i].modulation) &&
427 (f == CX24116_MODFEC_MODES[i].
fec)) {
441 dprintk(
"%s(0x%02x,0x%02x)\n", __func__, mod, fec);
443 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
449 state->
dnxt.fec_val = CX24116_MODFEC_MODES[
ret].val;
450 state->
dnxt.fec_mask = CX24116_MODFEC_MODES[
ret].mask;
451 dprintk(
"%s() mask/val = 0x%02x/0x%02x\n", __func__,
452 state->
dnxt.fec_mask, state->
dnxt.fec_val);
459 dprintk(
"%s(%d)\n", __func__, rate);
462 if ((rate > state->
frontend.ops.info.symbol_rate_max) ||
463 (rate < state->frontend.ops.info.symbol_rate_min)) {
464 dprintk(
"%s() unsupported symbol_rate = %d\n", __func__, rate);
469 dprintk(
"%s() symbol_rate = %d\n", __func__, rate);
474 static int cx24116_load_firmware(
struct dvb_frontend *fe,
477 static int cx24116_firmware_ondemand(
struct dvb_frontend *fe)
485 if (cx24116_readreg(state, 0x20) > 0) {
495 state->
i2c->dev.parent);
500 "(timeout or file not found?)\n", __func__);
508 ret = cx24116_load_firmware(fe, fw);
516 ret == 0 ?
"complete" :
"failed");
536 ret = cx24116_firmware_ondemand(fe);
544 for (i = 0; i < cmd->
len ; i++) {
545 dprintk(
"%s: 0x%02x == 0x%02x\n", __func__, i, cmd->
args[i]);
546 cx24116_writereg(state, i, cmd->
args[i]);
564 static int cx24116_load_firmware(
struct dvb_frontend *fe,
570 unsigned char vers[4];
573 dprintk(
"Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
581 if (state->
config->reset_device)
582 state->
config->reset_device(fe);
588 cx24116_writereg(state, 0xE5, 0x00);
589 cx24116_writereg(state, 0xF1, 0x08);
590 cx24116_writereg(state, 0xF2, 0x13);
593 cx24116_writereg(state, 0xe0, 0x03);
594 cx24116_writereg(state, 0xe0, 0x00);
601 cx24116_writereg(state, 0xF0, 0x03);
602 cx24116_writereg(state, 0xF4, 0x81);
603 cx24116_writereg(state, 0xF5, 0x00);
604 cx24116_writereg(state, 0xF6, 0x00);
608 if (state->
config->i2c_wr_max)
609 max = state->
config->i2c_wr_max;
613 for (remaining = fw->
size; remaining > 0; remaining -= max - 1) {
618 cx24116_writeregN(state, 0xF7, &fw->
data[fw->
size - remaining],
622 cx24116_writereg(state, 0xF4, 0x10);
623 cx24116_writereg(state, 0xF0, 0x00);
624 cx24116_writereg(state, 0xF8, 0x06);
628 cmd.
args[0x01] = 0x05;
629 cmd.
args[0x02] = 0xdc;
630 cmd.
args[0x03] = 0xda;
631 cmd.
args[0x04] = 0xae;
632 cmd.
args[0x05] = 0xaa;
633 cmd.
args[0x06] = 0x04;
634 cmd.
args[0x07] = 0x9d;
635 cmd.
args[0x08] = 0xfc;
636 cmd.
args[0x09] = 0x06;
638 ret = cx24116_cmd_execute(fe, &cmd);
646 cmd.
args[0x01] = 0x00;
647 cmd.
args[0x02] = 0x00;
649 ret = cx24116_cmd_execute(fe, &cmd);
653 cx24116_writereg(state, 0xe5, 0x00);
657 cmd.
args[0x01] = 0x01;
658 cmd.
args[0x02] = 0x75;
659 cmd.
args[0x03] = 0x00;
660 if (state->
config->mpg_clk_pos_pol)
661 cmd.
args[0x04] = state->
config->mpg_clk_pos_pol;
663 cmd.
args[0x04] = 0x02;
664 cmd.
args[0x05] = 0x00;
666 ret = cx24116_cmd_execute(fe, &cmd);
673 for (i = 0; i < 4; i++) {
675 ret = cx24116_cmd_execute(fe, &cmd);
681 vers[0], vers[1], vers[2], vers[3]);
693 dprintk(
"%s: status = 0x%02x\n", __func__, lock);
724 static int cx24116_read_signal_strength(
struct dvb_frontend *fe,
725 u16 *signal_strength)
737 ret = cx24116_cmd_execute(fe, &cmd);
742 (cx24116_readreg(state,
745 *signal_strength = 0 - sig_reading;
747 dprintk(
"%s: raw / cooked = 0x%04x / 0x%04x\n",
748 __func__, sig_reading, *signal_strength);
758 static const u32 snr_tab[] = {
759 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
760 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
761 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
768 if (snr_reading >= 0xa0 )
771 *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
772 (snr_tab[(snr_reading & 0x0f)] >> 4);
774 dprintk(
"%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
793 dprintk(
"%s: raw 0x%04x\n", __func__, *snr);
801 return cx24116_read_snr_esno(fe, snr);
803 return cx24116_read_snr_pct(fe, snr);
806 static int cx24116_read_ucblocks(
struct dvb_frontend *fe,
u32 *ucblocks)
819 static void cx24116_clone_params(
struct dvb_frontend *fe)
826 static int cx24116_wait_for_lnb(
struct dvb_frontend *fe)
831 dprintk(
"%s() qstatus = 0x%02x\n", __func__,
835 for (i = 0; i < 30 ; i++) {
841 dprintk(
"%s(): LNB not ready\n", __func__);
857 ret = cx24116_wait_for_lnb(fe);
871 return cx24116_cmd_execute(fe, &cmd);
880 dprintk(
"%s(%d)\n", __func__, tone);
887 ret = cx24116_wait_for_lnb(fe);
896 cmd.
args[0x01] = 0x00;
897 cmd.
args[0x02] = 0x00;
901 dprintk(
"%s: setting tone on\n", __func__);
902 cmd.
args[0x03] = 0x01;
905 dprintk(
"%s: setting tone off\n", __func__);
906 cmd.
args[0x03] = 0x00;
914 return cx24116_cmd_execute(fe, &cmd);
926 cmd.
args[0x01] = 0x00;
927 cmd.
args[0x02] = 0x10;
928 cmd.
args[0x03] = 0x00;
929 cmd.
args[0x04] = 0x8f;
930 cmd.
args[0x05] = 0x28;
932 cmd.
args[0x07] = 0x01;
934 ret = cx24116_cmd_execute(fe, &cmd);
960 static int cx24116_send_diseqc_msg(
struct dvb_frontend *fe,
969 for (i = 0 ; i < d->
msg_len ;) {
974 printk(
") toneburst=%d\n", toneburst);
982 for (i = 0; i < d->
msg_len; i++)
1022 ((d->
msg[3] & 4) >> 2);
1024 dprintk(
"%s burst=%d\n", __func__,
1029 ret = cx24116_wait_for_lnb(fe);
1037 ret = cx24116_cmd_execute(fe, &state->
dsec_cmd);
1057 static int cx24116_diseqc_send_burst(
struct dvb_frontend *fe,
1063 dprintk(
"%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1083 ret = cx24116_wait_for_lnb(fe);
1091 ret = cx24116_cmd_execute(fe, &state->
dsec_cmd);
1136 ret = (cx24116_readreg(state, 0xFF) << 8) |
1137 cx24116_readreg(state, 0xFE);
1138 if (ret != 0x0501) {
1149 error2:
kfree(state);
1150 error1:
return NULL;
1168 cx24116_writereg(state, 0xe0, 0);
1169 cx24116_writereg(state, 0xe1, 0);
1170 cx24116_writereg(state, 0xea, 0);
1176 ret = cx24116_cmd_execute(fe, &cmd);
1180 ret = cx24116_diseqc_init(fe);
1203 ret = cx24116_cmd_execute(fe, &cmd);
1208 cx24116_writereg(state, 0xea, 0xff);
1209 cx24116_writereg(state, 0xe1, 1);
1210 cx24116_writereg(state, 0xe0, 1);
1218 static int cx24116_set_frontend(
struct dvb_frontend *fe)
1230 dprintk(
"%s: DVB-S delivery system selected\n", __func__);
1234 dprintk(
"%s: unsupported modulation selected (%d)\n",
1244 dprintk(
"%s: unsupported rolloff selected (%d)\n",
1252 dprintk(
"%s: DVB-S2 delivery system selected\n", __func__);
1259 dprintk(
"%s: unsupported modulation selected (%d)\n",
1277 dprintk(
"%s: unsupported pilot mode selected (%d)\n",
1278 __func__, c->
pilot);
1294 dprintk(
"%s: unsupported rolloff selected (%d)\n",
1301 dprintk(
"%s: unsupported delivery system selected (%d)\n",
1311 ret = cx24116_set_inversion(state, c->
inversion);
1320 ret = cx24116_set_symbolrate(state, c->
symbol_rate);
1325 cx24116_clone_params(fe);
1327 dprintk(
"%s: delsys = %d\n", __func__, state->
dcur.delsys);
1328 dprintk(
"%s: modulation = %d\n", __func__, state->
dcur.modulation);
1329 dprintk(
"%s: frequency = %d\n", __func__, state->
dcur.frequency);
1330 dprintk(
"%s: pilot = %d (val = 0x%02x)\n", __func__,
1331 state->
dcur.pilot, state->
dcur.pilot_val);
1332 dprintk(
"%s: retune = %d\n", __func__, retune);
1333 dprintk(
"%s: rolloff = %d (val = 0x%02x)\n", __func__,
1334 state->
dcur.rolloff, state->
dcur.rolloff_val);
1335 dprintk(
"%s: symbol_rate = %d\n", __func__, state->
dcur.symbol_rate);
1336 dprintk(
"%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1337 state->
dcur.fec, state->
dcur.fec_mask, state->
dcur.fec_val);
1338 dprintk(
"%s: Inversion = %d (val = 0x%02x)\n", __func__,
1339 state->
dcur.inversion, state->
dcur.inversion_val);
1342 if (state->
config->set_ts_params)
1343 state->
config->set_ts_params(fe, 0);
1347 cmd.
args[0x01] = 0x01;
1349 ret = cx24116_cmd_execute(fe, &cmd);
1357 cmd.
args[0x01] = (state->
dcur.frequency & 0xff0000) >> 16;
1358 cmd.
args[0x02] = (state->
dcur.frequency & 0x00ff00) >> 8;
1359 cmd.
args[0x03] = (state->
dcur.frequency & 0x0000ff);
1362 cmd.
args[0x04] = ((state->
dcur.symbol_rate / 1000) & 0xff00) >> 8;
1363 cmd.
args[0x05] = ((state->
dcur.symbol_rate / 1000) & 0x00ff);
1366 cmd.
args[0x06] = state->
dcur.inversion_val;
1369 cmd.
args[0x07] = state->
dcur.fec_val | state->
dcur.pilot_val;
1373 cmd.
args[0x0a] = 0x00;
1374 cmd.
args[0x0b] = 0x00;
1375 cmd.
args[0x0c] = state->
dcur.rolloff_val;
1376 cmd.
args[0x0d] = state->
dcur.fec_mask;
1378 if (state->
dcur.symbol_rate > 30000000) {
1379 cmd.
args[0x0e] = 0x04;
1380 cmd.
args[0x0f] = 0x00;
1381 cmd.
args[0x10] = 0x01;
1382 cmd.
args[0x11] = 0x77;
1383 cmd.
args[0x12] = 0x36;
1387 cmd.
args[0x0e] = 0x06;
1388 cmd.
args[0x0f] = 0x00;
1389 cmd.
args[0x10] = 0x00;
1390 cmd.
args[0x11] = 0xFA;
1391 cmd.
args[0x12] = 0x24;
1409 ret = cx24116_cmd_execute(fe, &cmd);
1419 for (i = 0; i < 50 ; i++) {
1420 cx24116_read_status(fe, &tunerstat);
1423 dprintk(
"%s: Tuned\n", __func__);
1429 dprintk(
"%s: Not tuned\n", __func__);
1438 cmd.
args[0x01] = 0x00;
1440 return cx24116_cmd_execute(fe, &cmd);
1443 static int cx24116_tune(
struct dvb_frontend *fe,
bool re_tune,
1456 int ret = cx24116_set_frontend(fe);
1460 return cx24116_read_status(fe, status);
1471 .name =
"Conexant CX24116/CX24118",
1472 .frequency_min = 950000,
1473 .frequency_max = 2150000,
1474 .frequency_stepsize = 1011,
1475 .frequency_tolerance = 5000,
1476 .symbol_rate_min = 1000000,
1477 .symbol_rate_max = 45000000,
1486 .release = cx24116_release,
1488 .init = cx24116_initfe,
1489 .sleep = cx24116_sleep,
1490 .read_status = cx24116_read_status,
1491 .read_ber = cx24116_read_ber,
1492 .read_signal_strength = cx24116_read_signal_strength,
1493 .read_snr = cx24116_read_snr,
1494 .read_ucblocks = cx24116_read_ucblocks,
1495 .set_tone = cx24116_set_tone,
1496 .set_voltage = cx24116_set_voltage,
1497 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1498 .diseqc_send_burst = cx24116_diseqc_send_burst,
1499 .get_frontend_algo = cx24116_get_algo,
1500 .tune = cx24116_tune,
1502 .set_frontend = cx24116_set_frontend,