Full support for Ginger Console
[linux-ginger.git] / drivers / media / dvb / frontends / cx24116.c
blob2410d8b59b6b428aa7621ed8b71839bef23282a8
1 /*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
4 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
5 Copyright (C) 2006-2007 Georg Acher
6 Copyright (C) 2007-2008 Darron Broad
7 March 2007
8 Fixed some bugs.
9 Added diseqc support.
10 Added corrected signal strength support.
11 August 2007
12 Sync with legacy version.
13 Some clean ups.
14 Copyright (C) 2008 Igor Liplianin
15 September, 9th 2008
16 Fixed locking on high symbol rates (>30000).
17 Implement MPEG initialization parameter.
18 January, 17th 2009
19 Fill set_voltage with actually control voltage code.
20 Correct set tone to not affect voltage.
22 This program is free software; you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation; either version 2 of the License, or
25 (at your option) any later version.
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to the Free Software
34 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 #include <linux/slab.h>
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/moduleparam.h>
41 #include <linux/init.h>
42 #include <linux/firmware.h>
44 #include "dvb_frontend.h"
45 #include "cx24116.h"
47 static int debug;
48 module_param(debug, int, 0644);
49 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
51 #define dprintk(args...) \
52 do { \
53 if (debug) \
54 printk(KERN_INFO "cx24116: " args); \
55 } while (0)
57 #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
58 #define CX24116_SEARCH_RANGE_KHZ 5000
60 /* known registers */
61 #define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
62 #define CX24116_REG_EXECUTE (0x1f) /* execute command */
63 #define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
64 #define CX24116_REG_RESET (0x20) /* reset status > 0 */
65 #define CX24116_REG_SIGNAL (0x9e) /* signal low */
66 #define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
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)
79 /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
80 #define CX24116_REG_FECSTATUS (0x9c)
82 /* FECSTATUS bits */
83 /* mask to determine configured fec (not tuned) or actual fec (tuned) */
84 #define CX24116_FEC_FECMASK (0x1f)
86 /* Select DVB-S demodulator, else DVB-S2 */
87 #define CX24116_FEC_DVBS (0x20)
88 #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
90 /* Pilot mode requested when tuning else always reset when tuned */
91 #define CX24116_FEC_PILOT (0x80)
93 /* arg buffer size */
94 #define CX24116_ARGLEN (0x1e)
96 /* rolloff */
97 #define CX24116_ROLLOFF_020 (0x00)
98 #define CX24116_ROLLOFF_025 (0x01)
99 #define CX24116_ROLLOFF_035 (0x02)
101 /* pilot bit */
102 #define CX24116_PILOT_OFF (0x00)
103 #define CX24116_PILOT_ON (0x40)
105 /* signal status */
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) /* toneburst never sent */
116 #define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
117 #define CX24116_DISEQC_MESGCACHE (2) /* message cached */
119 /* arg offset for DiSEqC */
120 #define CX24116_DISEQC_BURST (1)
121 #define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
122 #define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
123 #define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
124 #define CX24116_DISEQC_MSGLEN (5)
125 #define CX24116_DISEQC_MSGOFS (6)
127 /* DiSEqC burst */
128 #define CX24116_DISEQC_MINI_A (0)
129 #define CX24116_DISEQC_MINI_B (1)
131 /* DiSEqC tone burst */
132 static int toneburst = 1;
133 module_param(toneburst, int, 0644);
134 MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
135 "2=MESSAGE CACHE (default:1)");
137 /* SNR measurements */
138 static int esno_snr;
139 module_param(esno_snr, int, 0644);
140 MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
141 "1=ESNO(db * 10) (default:0)");
143 enum cmds {
144 CMD_SET_VCO = 0x10,
145 CMD_TUNEREQUEST = 0x11,
146 CMD_MPEGCONFIG = 0x13,
147 CMD_TUNERINIT = 0x14,
148 CMD_BANDWIDTH = 0x15,
149 CMD_GETAGC = 0x19,
150 CMD_LNBCONFIG = 0x20,
151 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
152 CMD_LNBDCLEVEL = 0x22,
153 CMD_SET_TONE = 0x23,
154 CMD_UPDFWVERS = 0x35,
155 CMD_TUNERSLEEP = 0x36,
156 CMD_AGCCONTROL = 0x3b, /* Unknown */
159 /* The Demod/Tuner can't easily provide these, we cache them */
160 struct cx24116_tuning {
161 u32 frequency;
162 u32 symbol_rate;
163 fe_spectral_inversion_t inversion;
164 fe_code_rate_t fec;
166 fe_delivery_system_t delsys;
167 fe_modulation_t modulation;
168 fe_pilot_t pilot;
169 fe_rolloff_t rolloff;
171 /* Demod values */
172 u8 fec_val;
173 u8 fec_mask;
174 u8 inversion_val;
175 u8 pilot_val;
176 u8 rolloff_val;
179 /* Basic commands that are sent to the firmware */
180 struct cx24116_cmd {
181 u8 len;
182 u8 args[CX24116_ARGLEN];
185 struct cx24116_state {
186 struct i2c_adapter *i2c;
187 const struct cx24116_config *config;
189 struct dvb_frontend frontend;
191 struct cx24116_tuning dcur;
192 struct cx24116_tuning dnxt;
194 u8 skip_fw_load;
195 u8 burst;
196 struct cx24116_cmd dsec_cmd;
199 static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
201 u8 buf[] = { reg, data };
202 struct i2c_msg msg = { .addr = state->config->demod_address,
203 .flags = 0, .buf = buf, .len = 2 };
204 int err;
206 if (debug > 1)
207 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
208 __func__, reg, data);
210 err = i2c_transfer(state->i2c, &msg, 1);
211 if (err != 1) {
212 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
213 " value == 0x%02x)\n", __func__, err, reg, data);
214 return -EREMOTEIO;
217 return 0;
220 /* Bulk byte writes to a single I2C address, for 32k firmware load */
221 static int cx24116_writeregN(struct cx24116_state *state, int reg,
222 const u8 *data, u16 len)
224 int ret = -EREMOTEIO;
225 struct i2c_msg msg;
226 u8 *buf;
228 buf = kmalloc(len + 1, GFP_KERNEL);
229 if (buf == NULL) {
230 printk("Unable to kmalloc\n");
231 ret = -ENOMEM;
232 goto error;
235 *(buf) = reg;
236 memcpy(buf + 1, data, len);
238 msg.addr = state->config->demod_address;
239 msg.flags = 0;
240 msg.buf = buf;
241 msg.len = len + 1;
243 if (debug > 1)
244 printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
245 __func__, reg, len);
247 ret = i2c_transfer(state->i2c, &msg, 1);
248 if (ret != 1) {
249 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
250 __func__, ret, reg);
251 ret = -EREMOTEIO;
254 error:
255 kfree(buf);
257 return ret;
260 static int cx24116_readreg(struct cx24116_state *state, u8 reg)
262 int ret;
263 u8 b0[] = { reg };
264 u8 b1[] = { 0 };
265 struct i2c_msg msg[] = {
266 { .addr = state->config->demod_address, .flags = 0,
267 .buf = b0, .len = 1 },
268 { .addr = state->config->demod_address, .flags = I2C_M_RD,
269 .buf = b1, .len = 1 }
272 ret = i2c_transfer(state->i2c, msg, 2);
274 if (ret != 2) {
275 printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
276 __func__, reg, ret);
277 return ret;
280 if (debug > 1)
281 printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
282 reg, b1[0]);
284 return b1[0];
287 static int cx24116_set_inversion(struct cx24116_state *state,
288 fe_spectral_inversion_t inversion)
290 dprintk("%s(%d)\n", __func__, inversion);
292 switch (inversion) {
293 case INVERSION_OFF:
294 state->dnxt.inversion_val = 0x00;
295 break;
296 case INVERSION_ON:
297 state->dnxt.inversion_val = 0x04;
298 break;
299 case INVERSION_AUTO:
300 state->dnxt.inversion_val = 0x0C;
301 break;
302 default:
303 return -EINVAL;
306 state->dnxt.inversion = inversion;
308 return 0;
312 * modfec (modulation and FEC)
313 * ===========================
315 * MOD FEC mask/val standard
316 * ---- -------- ----------- --------
317 * QPSK FEC_1_2 0x02 0x02+X DVB-S
318 * QPSK FEC_2_3 0x04 0x02+X DVB-S
319 * QPSK FEC_3_4 0x08 0x02+X DVB-S
320 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
321 * QPSK FEC_5_6 0x20 0x02+X DVB-S
322 * QPSK FEC_6_7 0x40 0x02+X DVB-S
323 * QPSK FEC_7_8 0x80 0x02+X DVB-S
324 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
325 * QPSK AUTO 0xff 0x02+X DVB-S
327 * For DVB-S high byte probably represents FEC
328 * and low byte selects the modulator. The high
329 * byte is search range mask. Bit 5 may turn
330 * on DVB-S and remaining bits represent some
331 * kind of calibration (how/what i do not know).
333 * Eg.(2/3) szap "Zone Horror"
335 * mask/val = 0x04, 0x20
336 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
338 * mask/val = 0x04, 0x30
339 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
341 * After tuning FECSTATUS contains actual FEC
342 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
344 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
346 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
347 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
348 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
349 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
350 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
351 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
352 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
353 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
355 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
356 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
357 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
358 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
359 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
360 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
362 * For DVB-S2 low bytes selects both modulator
363 * and FEC. High byte is meaningless here. To
364 * set pilot, bit 6 (0x40) is set. When inspecting
365 * FECSTATUS bit 7 (0x80) represents the pilot
366 * selection whilst not tuned. When tuned, actual FEC
367 * in use is found in FECSTATUS as per above. Pilot
368 * value is reset.
371 /* A table of modulation, fec and configuration bytes for the demod.
372 * Not all S2 mmodulation schemes are support and not all rates with
373 * a scheme are support. Especially, no auto detect when in S2 mode.
375 static struct cx24116_modfec {
376 fe_delivery_system_t delivery_system;
377 fe_modulation_t modulation;
378 fe_code_rate_t fec;
379 u8 mask; /* In DVBS mode this is used to autodetect */
380 u8 val; /* Passed to the firmware to indicate mode selection */
381 } CX24116_MODFEC_MODES[] = {
382 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
384 /*mod fec mask val */
385 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
386 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
387 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
388 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
389 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
390 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
391 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
392 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
393 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
394 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
395 /* NBC-QPSK */
396 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
397 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
398 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
399 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
400 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
401 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
402 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
403 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
404 /* 8PSK */
405 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
406 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
407 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
408 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
409 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
410 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
412 * `val' can be found in the FECSTATUS register when tuning.
413 * FECSTATUS will give the actual FEC in use if tuning was successful.
417 static int cx24116_lookup_fecmod(struct cx24116_state *state,
418 fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
420 int i, ret = -EOPNOTSUPP;
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)) {
428 ret = i;
429 break;
433 return ret;
436 static int cx24116_set_fec(struct cx24116_state *state,
437 fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
439 int ret = 0;
441 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
443 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
445 if (ret < 0)
446 return ret;
448 state->dnxt.fec = 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);
454 return 0;
457 static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
459 dprintk("%s(%d)\n", __func__, rate);
461 /* check if symbol rate is within limits */
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);
465 return -EOPNOTSUPP;
468 state->dnxt.symbol_rate = rate;
469 dprintk("%s() symbol_rate = %d\n", __func__, rate);
471 return 0;
474 static int cx24116_load_firmware(struct dvb_frontend *fe,
475 const struct firmware *fw);
477 static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
479 struct cx24116_state *state = fe->demodulator_priv;
480 const struct firmware *fw;
481 int ret = 0;
483 dprintk("%s()\n", __func__);
485 if (cx24116_readreg(state, 0x20) > 0) {
487 if (state->skip_fw_load)
488 return 0;
490 /* Load firmware */
491 /* request the firmware, this will block until loaded */
492 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
493 __func__, CX24116_DEFAULT_FIRMWARE);
494 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
495 state->i2c->dev.parent);
496 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
497 __func__);
498 if (ret) {
499 printk(KERN_ERR "%s: No firmware uploaded "
500 "(timeout or file not found?)\n", __func__);
501 return ret;
504 /* Make sure we don't recurse back through here
505 * during loading */
506 state->skip_fw_load = 1;
508 ret = cx24116_load_firmware(fe, fw);
509 if (ret)
510 printk(KERN_ERR "%s: Writing firmware to device failed\n",
511 __func__);
513 release_firmware(fw);
515 printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
516 ret == 0 ? "complete" : "failed");
518 /* Ensure firmware is always loaded if required */
519 state->skip_fw_load = 0;
522 return ret;
525 /* Take a basic firmware command structure, format it
526 * and forward it for processing
528 static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
530 struct cx24116_state *state = fe->demodulator_priv;
531 int i, ret;
533 dprintk("%s()\n", __func__);
535 /* Load the firmware if required */
536 ret = cx24116_firmware_ondemand(fe);
537 if (ret != 0) {
538 printk(KERN_ERR "%s(): Unable initialise the firmware\n",
539 __func__);
540 return ret;
543 /* Write the command */
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]);
549 /* Start execution and wait for cmd to terminate */
550 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
551 while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
552 msleep(10);
553 if (i++ > 64) {
554 /* Avoid looping forever if the firmware does
555 not respond */
556 printk(KERN_WARNING "%s() Firmware not responding\n",
557 __func__);
558 return -EREMOTEIO;
561 return 0;
564 static int cx24116_load_firmware(struct dvb_frontend *fe,
565 const struct firmware *fw)
567 struct cx24116_state *state = fe->demodulator_priv;
568 struct cx24116_cmd cmd;
569 int i, ret;
570 unsigned char vers[4];
572 dprintk("%s\n", __func__);
573 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
574 fw->size,
575 fw->data[0],
576 fw->data[1],
577 fw->data[fw->size-2],
578 fw->data[fw->size-1]);
580 /* Toggle 88x SRST pin to reset demod */
581 if (state->config->reset_device)
582 state->config->reset_device(fe);
584 /* Begin the firmware load process */
585 /* Prepare the demod, load the firmware, cleanup after load */
587 /* Init PLL */
588 cx24116_writereg(state, 0xE5, 0x00);
589 cx24116_writereg(state, 0xF1, 0x08);
590 cx24116_writereg(state, 0xF2, 0x13);
592 /* Start PLL */
593 cx24116_writereg(state, 0xe0, 0x03);
594 cx24116_writereg(state, 0xe0, 0x00);
596 /* Unknown */
597 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
598 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
600 /* Unknown */
601 cx24116_writereg(state, 0xF0, 0x03);
602 cx24116_writereg(state, 0xF4, 0x81);
603 cx24116_writereg(state, 0xF5, 0x00);
604 cx24116_writereg(state, 0xF6, 0x00);
606 /* write the entire firmware as one transaction */
607 cx24116_writeregN(state, 0xF7, fw->data, fw->size);
609 cx24116_writereg(state, 0xF4, 0x10);
610 cx24116_writereg(state, 0xF0, 0x00);
611 cx24116_writereg(state, 0xF8, 0x06);
613 /* Firmware CMD 10: VCO config */
614 cmd.args[0x00] = CMD_SET_VCO;
615 cmd.args[0x01] = 0x05;
616 cmd.args[0x02] = 0xdc;
617 cmd.args[0x03] = 0xda;
618 cmd.args[0x04] = 0xae;
619 cmd.args[0x05] = 0xaa;
620 cmd.args[0x06] = 0x04;
621 cmd.args[0x07] = 0x9d;
622 cmd.args[0x08] = 0xfc;
623 cmd.args[0x09] = 0x06;
624 cmd.len = 0x0a;
625 ret = cx24116_cmd_execute(fe, &cmd);
626 if (ret != 0)
627 return ret;
629 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
631 /* Firmware CMD 14: Tuner config */
632 cmd.args[0x00] = CMD_TUNERINIT;
633 cmd.args[0x01] = 0x00;
634 cmd.args[0x02] = 0x00;
635 cmd.len = 0x03;
636 ret = cx24116_cmd_execute(fe, &cmd);
637 if (ret != 0)
638 return ret;
640 cx24116_writereg(state, 0xe5, 0x00);
642 /* Firmware CMD 13: MPEG config */
643 cmd.args[0x00] = CMD_MPEGCONFIG;
644 cmd.args[0x01] = 0x01;
645 cmd.args[0x02] = 0x75;
646 cmd.args[0x03] = 0x00;
647 if (state->config->mpg_clk_pos_pol)
648 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
649 else
650 cmd.args[0x04] = 0x02;
651 cmd.args[0x05] = 0x00;
652 cmd.len = 0x06;
653 ret = cx24116_cmd_execute(fe, &cmd);
654 if (ret != 0)
655 return ret;
657 /* Firmware CMD 35: Get firmware version */
658 cmd.args[0x00] = CMD_UPDFWVERS;
659 cmd.len = 0x02;
660 for (i = 0; i < 4; i++) {
661 cmd.args[0x01] = i;
662 ret = cx24116_cmd_execute(fe, &cmd);
663 if (ret != 0)
664 return ret;
665 vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
667 printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
668 vers[0], vers[1], vers[2], vers[3]);
670 return 0;
673 static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
675 struct cx24116_state *state = fe->demodulator_priv;
677 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
678 CX24116_STATUS_MASK;
680 dprintk("%s: status = 0x%02x\n", __func__, lock);
682 *status = 0;
684 if (lock & CX24116_HAS_SIGNAL)
685 *status |= FE_HAS_SIGNAL;
686 if (lock & CX24116_HAS_CARRIER)
687 *status |= FE_HAS_CARRIER;
688 if (lock & CX24116_HAS_VITERBI)
689 *status |= FE_HAS_VITERBI;
690 if (lock & CX24116_HAS_SYNCLOCK)
691 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
693 return 0;
696 static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
698 struct cx24116_state *state = fe->demodulator_priv;
700 dprintk("%s()\n", __func__);
702 *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
703 (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
704 (cx24116_readreg(state, CX24116_REG_BER8) << 8) |
705 cx24116_readreg(state, CX24116_REG_BER0);
707 return 0;
710 /* TODO Determine function and scale appropriately */
711 static int cx24116_read_signal_strength(struct dvb_frontend *fe,
712 u16 *signal_strength)
714 struct cx24116_state *state = fe->demodulator_priv;
715 struct cx24116_cmd cmd;
716 int ret;
717 u16 sig_reading;
719 dprintk("%s()\n", __func__);
721 /* Firmware CMD 19: Get AGC */
722 cmd.args[0x00] = CMD_GETAGC;
723 cmd.len = 0x01;
724 ret = cx24116_cmd_execute(fe, &cmd);
725 if (ret != 0)
726 return ret;
728 sig_reading =
729 (cx24116_readreg(state,
730 CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
731 (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
732 *signal_strength = 0 - sig_reading;
734 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
735 __func__, sig_reading, *signal_strength);
737 return 0;
740 /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
741 static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
743 struct cx24116_state *state = fe->demodulator_priv;
744 u8 snr_reading;
745 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
746 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
747 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
748 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
749 0x18000 };
751 dprintk("%s()\n", __func__);
753 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
755 if (snr_reading >= 0xa0 /* 100% */)
756 *snr = 0xffff;
757 else
758 *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
759 (snr_tab[(snr_reading & 0x0f)] >> 4);
761 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
762 snr_reading, *snr);
764 return 0;
767 /* The reelbox patches show the value in the registers represents
768 * ESNO, from 0->30db (values 0->300). We provide this value by
769 * default.
771 static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
773 struct cx24116_state *state = fe->demodulator_priv;
775 dprintk("%s()\n", __func__);
777 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
778 cx24116_readreg(state, CX24116_REG_QUALITY0);
780 dprintk("%s: raw 0x%04x\n", __func__, *snr);
782 return 0;
785 static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
787 if (esno_snr == 1)
788 return cx24116_read_snr_esno(fe, snr);
789 else
790 return cx24116_read_snr_pct(fe, snr);
793 static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
795 struct cx24116_state *state = fe->demodulator_priv;
797 dprintk("%s()\n", __func__);
799 *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
800 cx24116_readreg(state, CX24116_REG_UCB0);
802 return 0;
805 /* Overwrite the current tuning params, we are about to tune */
806 static void cx24116_clone_params(struct dvb_frontend *fe)
808 struct cx24116_state *state = fe->demodulator_priv;
809 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
812 /* Wait for LNB */
813 static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
815 struct cx24116_state *state = fe->demodulator_priv;
816 int i;
818 dprintk("%s() qstatus = 0x%02x\n", __func__,
819 cx24116_readreg(state, CX24116_REG_QSTATUS));
821 /* Wait for up to 300 ms */
822 for (i = 0; i < 30 ; i++) {
823 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
824 return 0;
825 msleep(10);
828 dprintk("%s(): LNB not ready\n", __func__);
830 return -ETIMEDOUT; /* -EBUSY ? */
833 static int cx24116_set_voltage(struct dvb_frontend *fe,
834 fe_sec_voltage_t voltage)
836 struct cx24116_cmd cmd;
837 int ret;
839 dprintk("%s: %s\n", __func__,
840 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
841 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
843 /* Wait for LNB ready */
844 ret = cx24116_wait_for_lnb(fe);
845 if (ret != 0)
846 return ret;
848 /* Wait for voltage/min repeat delay */
849 msleep(100);
851 cmd.args[0x00] = CMD_LNBDCLEVEL;
852 cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
853 cmd.len = 0x02;
855 /* Min delay time before DiSEqC send */
856 msleep(15);
858 return cx24116_cmd_execute(fe, &cmd);
861 static int cx24116_set_tone(struct dvb_frontend *fe,
862 fe_sec_tone_mode_t tone)
864 struct cx24116_cmd cmd;
865 int ret;
867 dprintk("%s(%d)\n", __func__, tone);
868 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
869 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
870 return -EINVAL;
873 /* Wait for LNB ready */
874 ret = cx24116_wait_for_lnb(fe);
875 if (ret != 0)
876 return ret;
878 /* Min delay time after DiSEqC send */
879 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
881 /* Now we set the tone */
882 cmd.args[0x00] = CMD_SET_TONE;
883 cmd.args[0x01] = 0x00;
884 cmd.args[0x02] = 0x00;
886 switch (tone) {
887 case SEC_TONE_ON:
888 dprintk("%s: setting tone on\n", __func__);
889 cmd.args[0x03] = 0x01;
890 break;
891 case SEC_TONE_OFF:
892 dprintk("%s: setting tone off\n", __func__);
893 cmd.args[0x03] = 0x00;
894 break;
896 cmd.len = 0x04;
898 /* Min delay time before DiSEqC send */
899 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
901 return cx24116_cmd_execute(fe, &cmd);
904 /* Initialise DiSEqC */
905 static int cx24116_diseqc_init(struct dvb_frontend *fe)
907 struct cx24116_state *state = fe->demodulator_priv;
908 struct cx24116_cmd cmd;
909 int ret;
911 /* Firmware CMD 20: LNB/DiSEqC config */
912 cmd.args[0x00] = CMD_LNBCONFIG;
913 cmd.args[0x01] = 0x00;
914 cmd.args[0x02] = 0x10;
915 cmd.args[0x03] = 0x00;
916 cmd.args[0x04] = 0x8f;
917 cmd.args[0x05] = 0x28;
918 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
919 cmd.args[0x07] = 0x01;
920 cmd.len = 0x08;
921 ret = cx24116_cmd_execute(fe, &cmd);
922 if (ret != 0)
923 return ret;
925 /* Prepare a DiSEqC command */
926 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
928 /* DiSEqC burst */
929 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
931 /* Unknown */
932 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
933 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
934 /* Continuation flag? */
935 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
937 /* DiSEqC message length */
938 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
940 /* Command length */
941 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
943 return 0;
946 /* Send DiSEqC message with derived burst (hack) || previous burst */
947 static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
948 struct dvb_diseqc_master_cmd *d)
950 struct cx24116_state *state = fe->demodulator_priv;
951 int i, ret;
953 /* Dump DiSEqC message */
954 if (debug) {
955 printk(KERN_INFO "cx24116: %s(", __func__);
956 for (i = 0 ; i < d->msg_len ;) {
957 printk(KERN_INFO "0x%02x", d->msg[i]);
958 if (++i < d->msg_len)
959 printk(KERN_INFO ", ");
961 printk(") toneburst=%d\n", toneburst);
964 /* Validate length */
965 if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
966 return -EINVAL;
968 /* DiSEqC message */
969 for (i = 0; i < d->msg_len; i++)
970 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
972 /* DiSEqC message length */
973 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
975 /* Command length */
976 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
977 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
979 /* DiSEqC toneburst */
980 if (toneburst == CX24116_DISEQC_MESGCACHE)
981 /* Message is cached */
982 return 0;
984 else if (toneburst == CX24116_DISEQC_TONEOFF)
985 /* Message is sent without burst */
986 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
988 else if (toneburst == CX24116_DISEQC_TONECACHE) {
990 * Message is sent with derived else cached burst
992 * WRITE PORT GROUP COMMAND 38
994 * 0/A/A: E0 10 38 F0..F3
995 * 1/B/B: E0 10 38 F4..F7
996 * 2/C/A: E0 10 38 F8..FB
997 * 3/D/B: E0 10 38 FC..FF
999 * databyte[3]= 8421:8421
1000 * ABCD:WXYZ
1001 * CLR :SET
1003 * WX= PORT SELECT 0..3 (X=TONEBURST)
1004 * Y = VOLTAGE (0=13V, 1=18V)
1005 * Z = BAND (0=LOW, 1=HIGH(22K))
1007 if (d->msg_len >= 4 && d->msg[2] == 0x38)
1008 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1009 ((d->msg[3] & 4) >> 2);
1010 if (debug)
1011 dprintk("%s burst=%d\n", __func__,
1012 state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1015 /* Wait for LNB ready */
1016 ret = cx24116_wait_for_lnb(fe);
1017 if (ret != 0)
1018 return ret;
1020 /* Wait for voltage/min repeat delay */
1021 msleep(100);
1023 /* Command */
1024 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1025 if (ret != 0)
1026 return ret;
1028 * Wait for send
1030 * Eutelsat spec:
1031 * >15ms delay + (XXX determine if FW does this, see set_tone)
1032 * 13.5ms per byte +
1033 * >15ms delay +
1034 * 12.5ms burst +
1035 * >15ms delay (XXX determine if FW does this, see set_tone)
1037 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1038 ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1040 return 0;
1043 /* Send DiSEqC burst */
1044 static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
1045 fe_sec_mini_cmd_t burst)
1047 struct cx24116_state *state = fe->demodulator_priv;
1048 int ret;
1050 dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1052 /* DiSEqC burst */
1053 if (burst == SEC_MINI_A)
1054 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1055 CX24116_DISEQC_MINI_A;
1056 else if (burst == SEC_MINI_B)
1057 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1058 CX24116_DISEQC_MINI_B;
1059 else
1060 return -EINVAL;
1062 /* DiSEqC toneburst */
1063 if (toneburst != CX24116_DISEQC_MESGCACHE)
1064 /* Burst is cached */
1065 return 0;
1067 /* Burst is to be sent with cached message */
1069 /* Wait for LNB ready */
1070 ret = cx24116_wait_for_lnb(fe);
1071 if (ret != 0)
1072 return ret;
1074 /* Wait for voltage/min repeat delay */
1075 msleep(100);
1077 /* Command */
1078 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1079 if (ret != 0)
1080 return ret;
1083 * Wait for send
1085 * Eutelsat spec:
1086 * >15ms delay + (XXX determine if FW does this, see set_tone)
1087 * 13.5ms per byte +
1088 * >15ms delay +
1089 * 12.5ms burst +
1090 * >15ms delay (XXX determine if FW does this, see set_tone)
1092 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1094 return 0;
1097 static void cx24116_release(struct dvb_frontend *fe)
1099 struct cx24116_state *state = fe->demodulator_priv;
1100 dprintk("%s\n", __func__);
1101 kfree(state);
1104 static struct dvb_frontend_ops cx24116_ops;
1106 struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1107 struct i2c_adapter *i2c)
1109 struct cx24116_state *state = NULL;
1110 int ret;
1112 dprintk("%s\n", __func__);
1114 /* allocate memory for the internal state */
1115 state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1116 if (state == NULL)
1117 goto error1;
1119 state->config = config;
1120 state->i2c = i2c;
1122 /* check if the demod is present */
1123 ret = (cx24116_readreg(state, 0xFF) << 8) |
1124 cx24116_readreg(state, 0xFE);
1125 if (ret != 0x0501) {
1126 printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1127 goto error2;
1130 /* create dvb_frontend */
1131 memcpy(&state->frontend.ops, &cx24116_ops,
1132 sizeof(struct dvb_frontend_ops));
1133 state->frontend.demodulator_priv = state;
1134 return &state->frontend;
1136 error2: kfree(state);
1137 error1: return NULL;
1139 EXPORT_SYMBOL(cx24116_attach);
1142 * Initialise or wake up device
1144 * Power config will reset and load initial firmware if required
1146 static int cx24116_initfe(struct dvb_frontend *fe)
1148 struct cx24116_state *state = fe->demodulator_priv;
1149 struct cx24116_cmd cmd;
1150 int ret;
1152 dprintk("%s()\n", __func__);
1154 /* Power on */
1155 cx24116_writereg(state, 0xe0, 0);
1156 cx24116_writereg(state, 0xe1, 0);
1157 cx24116_writereg(state, 0xea, 0);
1159 /* Firmware CMD 36: Power config */
1160 cmd.args[0x00] = CMD_TUNERSLEEP;
1161 cmd.args[0x01] = 0;
1162 cmd.len = 0x02;
1163 ret = cx24116_cmd_execute(fe, &cmd);
1164 if (ret != 0)
1165 return ret;
1167 ret = cx24116_diseqc_init(fe);
1168 if (ret != 0)
1169 return ret;
1171 /* HVR-4000 needs this */
1172 return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
1176 * Put device to sleep
1178 static int cx24116_sleep(struct dvb_frontend *fe)
1180 struct cx24116_state *state = fe->demodulator_priv;
1181 struct cx24116_cmd cmd;
1182 int ret;
1184 dprintk("%s()\n", __func__);
1186 /* Firmware CMD 36: Power config */
1187 cmd.args[0x00] = CMD_TUNERSLEEP;
1188 cmd.args[0x01] = 1;
1189 cmd.len = 0x02;
1190 ret = cx24116_cmd_execute(fe, &cmd);
1191 if (ret != 0)
1192 return ret;
1194 /* Power off (Shutdown clocks) */
1195 cx24116_writereg(state, 0xea, 0xff);
1196 cx24116_writereg(state, 0xe1, 1);
1197 cx24116_writereg(state, 0xe0, 1);
1199 return 0;
1202 static int cx24116_set_property(struct dvb_frontend *fe,
1203 struct dtv_property *tvp)
1205 dprintk("%s(..)\n", __func__);
1206 return 0;
1209 static int cx24116_get_property(struct dvb_frontend *fe,
1210 struct dtv_property *tvp)
1212 dprintk("%s(..)\n", __func__);
1213 return 0;
1216 /* dvb-core told us to tune, the tv property cache will be complete,
1217 * it's safe for is to pull values and use them for tuning purposes.
1219 static int cx24116_set_frontend(struct dvb_frontend *fe,
1220 struct dvb_frontend_parameters *p)
1222 struct cx24116_state *state = fe->demodulator_priv;
1223 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1224 struct cx24116_cmd cmd;
1225 fe_status_t tunerstat;
1226 int i, status, ret, retune = 1;
1228 dprintk("%s()\n", __func__);
1230 switch (c->delivery_system) {
1231 case SYS_DVBS:
1232 dprintk("%s: DVB-S delivery system selected\n", __func__);
1234 /* Only QPSK is supported for DVB-S */
1235 if (c->modulation != QPSK) {
1236 dprintk("%s: unsupported modulation selected (%d)\n",
1237 __func__, c->modulation);
1238 return -EOPNOTSUPP;
1241 /* Pilot doesn't exist in DVB-S, turn bit off */
1242 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1244 /* DVB-S only supports 0.35 */
1245 if (c->rolloff != ROLLOFF_35) {
1246 dprintk("%s: unsupported rolloff selected (%d)\n",
1247 __func__, c->rolloff);
1248 return -EOPNOTSUPP;
1250 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1251 break;
1253 case SYS_DVBS2:
1254 dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1257 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1258 * but not hardware auto detection
1260 if (c->modulation != PSK_8 && c->modulation != QPSK) {
1261 dprintk("%s: unsupported modulation selected (%d)\n",
1262 __func__, c->modulation);
1263 return -EOPNOTSUPP;
1266 switch (c->pilot) {
1267 case PILOT_AUTO: /* Not supported but emulated */
1268 state->dnxt.pilot_val = (c->modulation == QPSK)
1269 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1270 retune++;
1271 break;
1272 case PILOT_OFF:
1273 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1274 break;
1275 case PILOT_ON:
1276 state->dnxt.pilot_val = CX24116_PILOT_ON;
1277 break;
1278 default:
1279 dprintk("%s: unsupported pilot mode selected (%d)\n",
1280 __func__, c->pilot);
1281 return -EOPNOTSUPP;
1284 switch (c->rolloff) {
1285 case ROLLOFF_20:
1286 state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1287 break;
1288 case ROLLOFF_25:
1289 state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1290 break;
1291 case ROLLOFF_35:
1292 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1293 break;
1294 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1295 default:
1296 dprintk("%s: unsupported rolloff selected (%d)\n",
1297 __func__, c->rolloff);
1298 return -EOPNOTSUPP;
1300 break;
1302 default:
1303 dprintk("%s: unsupported delivery system selected (%d)\n",
1304 __func__, c->delivery_system);
1305 return -EOPNOTSUPP;
1307 state->dnxt.delsys = c->delivery_system;
1308 state->dnxt.modulation = c->modulation;
1309 state->dnxt.frequency = c->frequency;
1310 state->dnxt.pilot = c->pilot;
1311 state->dnxt.rolloff = c->rolloff;
1313 ret = cx24116_set_inversion(state, c->inversion);
1314 if (ret != 0)
1315 return ret;
1317 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1318 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1319 if (ret != 0)
1320 return ret;
1322 ret = cx24116_set_symbolrate(state, c->symbol_rate);
1323 if (ret != 0)
1324 return ret;
1326 /* discard the 'current' tuning parameters and prepare to tune */
1327 cx24116_clone_params(fe);
1329 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
1330 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1331 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1332 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1333 state->dcur.pilot, state->dcur.pilot_val);
1334 dprintk("%s: retune = %d\n", __func__, retune);
1335 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1336 state->dcur.rolloff, state->dcur.rolloff_val);
1337 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1338 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1339 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1340 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1341 state->dcur.inversion, state->dcur.inversion_val);
1343 /* This is also done in advise/acquire on HVR4000 but not on LITE */
1344 if (state->config->set_ts_params)
1345 state->config->set_ts_params(fe, 0);
1347 /* Set/Reset B/W */
1348 cmd.args[0x00] = CMD_BANDWIDTH;
1349 cmd.args[0x01] = 0x01;
1350 cmd.len = 0x02;
1351 ret = cx24116_cmd_execute(fe, &cmd);
1352 if (ret != 0)
1353 return ret;
1355 /* Prepare a tune request */
1356 cmd.args[0x00] = CMD_TUNEREQUEST;
1358 /* Frequency */
1359 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1360 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1361 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1363 /* Symbol Rate */
1364 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1365 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1367 /* Automatic Inversion */
1368 cmd.args[0x06] = state->dcur.inversion_val;
1370 /* Modulation / FEC / Pilot */
1371 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1373 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1374 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1375 cmd.args[0x0a] = 0x00;
1376 cmd.args[0x0b] = 0x00;
1377 cmd.args[0x0c] = state->dcur.rolloff_val;
1378 cmd.args[0x0d] = state->dcur.fec_mask;
1380 if (state->dcur.symbol_rate > 30000000) {
1381 cmd.args[0x0e] = 0x04;
1382 cmd.args[0x0f] = 0x00;
1383 cmd.args[0x10] = 0x01;
1384 cmd.args[0x11] = 0x77;
1385 cmd.args[0x12] = 0x36;
1386 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1387 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1388 } else {
1389 cmd.args[0x0e] = 0x06;
1390 cmd.args[0x0f] = 0x00;
1391 cmd.args[0x10] = 0x00;
1392 cmd.args[0x11] = 0xFA;
1393 cmd.args[0x12] = 0x24;
1394 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1395 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1398 cmd.len = 0x13;
1400 /* We need to support pilot and non-pilot tuning in the
1401 * driver automatically. This is a workaround for because
1402 * the demod does not support autodetect.
1404 do {
1405 /* Reset status register */
1406 status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1407 & CX24116_SIGNAL_MASK;
1408 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1410 /* Tune */
1411 ret = cx24116_cmd_execute(fe, &cmd);
1412 if (ret != 0)
1413 break;
1416 * Wait for up to 500 ms before retrying
1418 * If we are able to tune then generally it occurs within 100ms.
1419 * If it takes longer, try a different toneburst setting.
1421 for (i = 0; i < 50 ; i++) {
1422 cx24116_read_status(fe, &tunerstat);
1423 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1424 if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1425 dprintk("%s: Tuned\n", __func__);
1426 goto tuned;
1428 msleep(10);
1431 dprintk("%s: Not tuned\n", __func__);
1433 /* Toggle pilot bit when in auto-pilot */
1434 if (state->dcur.pilot == PILOT_AUTO)
1435 cmd.args[0x07] ^= CX24116_PILOT_ON;
1436 } while (--retune);
1438 tuned: /* Set/Reset B/W */
1439 cmd.args[0x00] = CMD_BANDWIDTH;
1440 cmd.args[0x01] = 0x00;
1441 cmd.len = 0x02;
1442 ret = cx24116_cmd_execute(fe, &cmd);
1443 if (ret != 0)
1444 return ret;
1446 return ret;
1449 static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
1450 unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
1452 *delay = HZ / 5;
1453 if (params) {
1454 int ret = cx24116_set_frontend(fe, params);
1455 if (ret)
1456 return ret;
1458 return cx24116_read_status(fe, status);
1461 static int cx24116_get_algo(struct dvb_frontend *fe)
1463 return DVBFE_ALGO_HW;
1466 static struct dvb_frontend_ops cx24116_ops = {
1468 .info = {
1469 .name = "Conexant CX24116/CX24118",
1470 .type = FE_QPSK,
1471 .frequency_min = 950000,
1472 .frequency_max = 2150000,
1473 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1474 .frequency_tolerance = 5000,
1475 .symbol_rate_min = 1000000,
1476 .symbol_rate_max = 45000000,
1477 .caps = FE_CAN_INVERSION_AUTO |
1478 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1479 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1480 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1481 FE_CAN_2G_MODULATION |
1482 FE_CAN_QPSK | FE_CAN_RECOVER
1485 .release = cx24116_release,
1487 .init = cx24116_initfe,
1488 .sleep = cx24116_sleep,
1489 .read_status = cx24116_read_status,
1490 .read_ber = cx24116_read_ber,
1491 .read_signal_strength = cx24116_read_signal_strength,
1492 .read_snr = cx24116_read_snr,
1493 .read_ucblocks = cx24116_read_ucblocks,
1494 .set_tone = cx24116_set_tone,
1495 .set_voltage = cx24116_set_voltage,
1496 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1497 .diseqc_send_burst = cx24116_diseqc_send_burst,
1498 .get_frontend_algo = cx24116_get_algo,
1499 .tune = cx24116_tune,
1501 .set_property = cx24116_set_property,
1502 .get_property = cx24116_get_property,
1503 .set_frontend = cx24116_set_frontend,
1506 MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1507 MODULE_AUTHOR("Steven Toth");
1508 MODULE_LICENSE("GPL");