repo init
[linux-rt-nao.git] / drivers / media / dvb / frontends / cx24116.c
blob28ad609e73f40e95c3b31555aef44a74cc93aa2a
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.
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <linux/slab.h>
35 #include <linux/kernel.h>
36 #include <linux/module.h>
37 #include <linux/moduleparam.h>
38 #include <linux/init.h>
39 #include <linux/firmware.h>
41 #include "dvb_frontend.h"
42 #include "cx24116.h"
44 static int debug;
45 module_param(debug, int, 0644);
46 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
48 #define dprintk(args...) \
49 do { \
50 if (debug) \
51 printk(KERN_INFO "cx24116: " args); \
52 } while (0)
54 #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
55 #define CX24116_SEARCH_RANGE_KHZ 5000
57 /* known registers */
58 #define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
59 #define CX24116_REG_EXECUTE (0x1f) /* execute command */
60 #define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
61 #define CX24116_REG_RESET (0x20) /* reset status > 0 */
62 #define CX24116_REG_SIGNAL (0x9e) /* signal low */
63 #define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
64 #define CX24116_REG_QUALITY8 (0xa3)
65 #define CX24116_REG_QSTATUS (0xbc)
66 #define CX24116_REG_QUALITY0 (0xd5)
67 #define CX24116_REG_BER0 (0xc9)
68 #define CX24116_REG_BER8 (0xc8)
69 #define CX24116_REG_BER16 (0xc7)
70 #define CX24116_REG_BER24 (0xc6)
71 #define CX24116_REG_UCB0 (0xcb)
72 #define CX24116_REG_UCB8 (0xca)
73 #define CX24116_REG_CLKDIV (0xf3)
74 #define CX24116_REG_RATEDIV (0xf9)
76 /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
77 #define CX24116_REG_FECSTATUS (0x9c)
79 /* FECSTATUS bits */
80 /* mask to determine configured fec (not tuned) or actual fec (tuned) */
81 #define CX24116_FEC_FECMASK (0x1f)
83 /* Select DVB-S demodulator, else DVB-S2 */
84 #define CX24116_FEC_DVBS (0x20)
85 #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
87 /* Pilot mode requested when tuning else always reset when tuned */
88 #define CX24116_FEC_PILOT (0x80)
90 /* arg buffer size */
91 #define CX24116_ARGLEN (0x1e)
93 /* rolloff */
94 #define CX24116_ROLLOFF_020 (0x00)
95 #define CX24116_ROLLOFF_025 (0x01)
96 #define CX24116_ROLLOFF_035 (0x02)
98 /* pilot bit */
99 #define CX24116_PILOT_OFF (0x00)
100 #define CX24116_PILOT_ON (0x40)
102 /* signal status */
103 #define CX24116_HAS_SIGNAL (0x01)
104 #define CX24116_HAS_CARRIER (0x02)
105 #define CX24116_HAS_VITERBI (0x04)
106 #define CX24116_HAS_SYNCLOCK (0x08)
107 #define CX24116_HAS_UNKNOWN1 (0x10)
108 #define CX24116_HAS_UNKNOWN2 (0x20)
109 #define CX24116_STATUS_MASK (0x0f)
110 #define CX24116_SIGNAL_MASK (0xc0)
112 #define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
113 #define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
114 #define CX24116_DISEQC_MESGCACHE (2) /* message cached */
116 /* arg offset for DiSEqC */
117 #define CX24116_DISEQC_BURST (1)
118 #define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
119 #define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
120 #define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
121 #define CX24116_DISEQC_MSGLEN (5)
122 #define CX24116_DISEQC_MSGOFS (6)
124 /* DiSEqC burst */
125 #define CX24116_DISEQC_MINI_A (0)
126 #define CX24116_DISEQC_MINI_B (1)
128 /* DiSEqC tone burst */
129 static int toneburst = 1;
130 module_param(toneburst, int, 0644);
131 MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
132 "2=MESSAGE CACHE (default:1)");
134 /* SNR measurements */
135 static int esno_snr;
136 module_param(esno_snr, int, 0644);
137 MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
138 "1=ESNO(db * 10) (default:0)");
140 enum cmds {
141 CMD_SET_VCO = 0x10,
142 CMD_TUNEREQUEST = 0x11,
143 CMD_MPEGCONFIG = 0x13,
144 CMD_TUNERINIT = 0x14,
145 CMD_BANDWIDTH = 0x15,
146 CMD_GETAGC = 0x19,
147 CMD_LNBCONFIG = 0x20,
148 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
149 CMD_SET_TONEPRE = 0x22,
150 CMD_SET_TONE = 0x23,
151 CMD_UPDFWVERS = 0x35,
152 CMD_TUNERSLEEP = 0x36,
153 CMD_AGCCONTROL = 0x3b, /* Unknown */
156 /* The Demod/Tuner can't easily provide these, we cache them */
157 struct cx24116_tuning {
158 u32 frequency;
159 u32 symbol_rate;
160 fe_spectral_inversion_t inversion;
161 fe_code_rate_t fec;
163 fe_delivery_system_t delsys;
164 fe_modulation_t modulation;
165 fe_pilot_t pilot;
166 fe_rolloff_t rolloff;
168 /* Demod values */
169 u8 fec_val;
170 u8 fec_mask;
171 u8 inversion_val;
172 u8 pilot_val;
173 u8 rolloff_val;
176 /* Basic commands that are sent to the firmware */
177 struct cx24116_cmd {
178 u8 len;
179 u8 args[CX24116_ARGLEN];
182 struct cx24116_state {
183 struct i2c_adapter *i2c;
184 const struct cx24116_config *config;
186 struct dvb_frontend frontend;
188 struct cx24116_tuning dcur;
189 struct cx24116_tuning dnxt;
191 u8 skip_fw_load;
192 u8 burst;
193 struct cx24116_cmd dsec_cmd;
196 static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
198 u8 buf[] = { reg, data };
199 struct i2c_msg msg = { .addr = state->config->demod_address,
200 .flags = 0, .buf = buf, .len = 2 };
201 int err;
203 if (debug > 1)
204 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
205 __func__, reg, data);
207 err = i2c_transfer(state->i2c, &msg, 1);
208 if (err != 1) {
209 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
210 " value == 0x%02x)\n", __func__, err, reg, data);
211 return -EREMOTEIO;
214 return 0;
217 /* Bulk byte writes to a single I2C address, for 32k firmware load */
218 static int cx24116_writeregN(struct cx24116_state *state, int reg,
219 const u8 *data, u16 len)
221 int ret = -EREMOTEIO;
222 struct i2c_msg msg;
223 u8 *buf;
225 buf = kmalloc(len + 1, GFP_KERNEL);
226 if (buf == NULL) {
227 printk("Unable to kmalloc\n");
228 ret = -ENOMEM;
229 goto error;
232 *(buf) = reg;
233 memcpy(buf + 1, data, len);
235 msg.addr = state->config->demod_address;
236 msg.flags = 0;
237 msg.buf = buf;
238 msg.len = len + 1;
240 if (debug > 1)
241 printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
242 __func__, reg, len);
244 ret = i2c_transfer(state->i2c, &msg, 1);
245 if (ret != 1) {
246 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
247 __func__, ret, reg);
248 ret = -EREMOTEIO;
251 error:
252 kfree(buf);
254 return ret;
257 static int cx24116_readreg(struct cx24116_state *state, u8 reg)
259 int ret;
260 u8 b0[] = { reg };
261 u8 b1[] = { 0 };
262 struct i2c_msg msg[] = {
263 { .addr = state->config->demod_address, .flags = 0,
264 .buf = b0, .len = 1 },
265 { .addr = state->config->demod_address, .flags = I2C_M_RD,
266 .buf = b1, .len = 1 }
269 ret = i2c_transfer(state->i2c, msg, 2);
271 if (ret != 2) {
272 printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
273 __func__, reg, ret);
274 return ret;
277 if (debug > 1)
278 printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
279 reg, b1[0]);
281 return b1[0];
284 static int cx24116_set_inversion(struct cx24116_state *state,
285 fe_spectral_inversion_t inversion)
287 dprintk("%s(%d)\n", __func__, inversion);
289 switch (inversion) {
290 case INVERSION_OFF:
291 state->dnxt.inversion_val = 0x00;
292 break;
293 case INVERSION_ON:
294 state->dnxt.inversion_val = 0x04;
295 break;
296 case INVERSION_AUTO:
297 state->dnxt.inversion_val = 0x0C;
298 break;
299 default:
300 return -EINVAL;
303 state->dnxt.inversion = inversion;
305 return 0;
309 * modfec (modulation and FEC)
310 * ===========================
312 * MOD FEC mask/val standard
313 * ---- -------- ----------- --------
314 * QPSK FEC_1_2 0x02 0x02+X DVB-S
315 * QPSK FEC_2_3 0x04 0x02+X DVB-S
316 * QPSK FEC_3_4 0x08 0x02+X DVB-S
317 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
318 * QPSK FEC_5_6 0x20 0x02+X DVB-S
319 * QPSK FEC_6_7 0x40 0x02+X DVB-S
320 * QPSK FEC_7_8 0x80 0x02+X DVB-S
321 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
322 * QPSK AUTO 0xff 0x02+X DVB-S
324 * For DVB-S high byte probably represents FEC
325 * and low byte selects the modulator. The high
326 * byte is search range mask. Bit 5 may turn
327 * on DVB-S and remaining bits represent some
328 * kind of calibration (how/what i do not know).
330 * Eg.(2/3) szap "Zone Horror"
332 * mask/val = 0x04, 0x20
333 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
335 * mask/val = 0x04, 0x30
336 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
338 * After tuning FECSTATUS contains actual FEC
339 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
341 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
343 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
344 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
345 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
346 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
347 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
348 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
349 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
350 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
352 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
353 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
354 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
355 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
356 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
357 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
359 * For DVB-S2 low bytes selects both modulator
360 * and FEC. High byte is meaningless here. To
361 * set pilot, bit 6 (0x40) is set. When inspecting
362 * FECSTATUS bit 7 (0x80) represents the pilot
363 * selection whilst not tuned. When tuned, actual FEC
364 * in use is found in FECSTATUS as per above. Pilot
365 * value is reset.
368 /* A table of modulation, fec and configuration bytes for the demod.
369 * Not all S2 mmodulation schemes are support and not all rates with
370 * a scheme are support. Especially, no auto detect when in S2 mode.
372 static struct cx24116_modfec {
373 fe_delivery_system_t delivery_system;
374 fe_modulation_t modulation;
375 fe_code_rate_t fec;
376 u8 mask; /* In DVBS mode this is used to autodetect */
377 u8 val; /* Passed to the firmware to indicate mode selection */
378 } CX24116_MODFEC_MODES[] = {
379 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
381 /*mod fec mask val */
382 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
383 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
384 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
385 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
386 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
387 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
388 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
389 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
390 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
391 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
392 /* NBC-QPSK */
393 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
394 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
395 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
396 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
397 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
398 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
399 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
400 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
401 /* 8PSK */
402 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
403 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
404 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
405 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
406 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
407 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
409 * `val' can be found in the FECSTATUS register when tuning.
410 * FECSTATUS will give the actual FEC in use if tuning was successful.
414 static int cx24116_lookup_fecmod(struct cx24116_state *state,
415 fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
417 int i, ret = -EOPNOTSUPP;
419 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
421 for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
422 if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
423 (m == CX24116_MODFEC_MODES[i].modulation) &&
424 (f == CX24116_MODFEC_MODES[i].fec)) {
425 ret = i;
426 break;
430 return ret;
433 static int cx24116_set_fec(struct cx24116_state *state,
434 fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
436 int ret = 0;
438 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
440 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
442 if (ret < 0)
443 return ret;
445 state->dnxt.fec = fec;
446 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
447 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
448 dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
449 state->dnxt.fec_mask, state->dnxt.fec_val);
451 return 0;
454 static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
456 dprintk("%s(%d)\n", __func__, rate);
458 /* check if symbol rate is within limits */
459 if ((rate > state->frontend.ops.info.symbol_rate_max) ||
460 (rate < state->frontend.ops.info.symbol_rate_min)) {
461 dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
462 return -EOPNOTSUPP;
465 state->dnxt.symbol_rate = rate;
466 dprintk("%s() symbol_rate = %d\n", __func__, rate);
468 return 0;
471 static int cx24116_load_firmware(struct dvb_frontend *fe,
472 const struct firmware *fw);
474 static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
476 struct cx24116_state *state = fe->demodulator_priv;
477 const struct firmware *fw;
478 int ret = 0;
480 dprintk("%s()\n", __func__);
482 if (cx24116_readreg(state, 0x20) > 0) {
484 if (state->skip_fw_load)
485 return 0;
487 /* Load firmware */
488 /* request the firmware, this will block until loaded */
489 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
490 __func__, CX24116_DEFAULT_FIRMWARE);
491 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
492 &state->i2c->dev);
493 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
494 __func__);
495 if (ret) {
496 printk(KERN_ERR "%s: No firmware uploaded "
497 "(timeout or file not found?)\n", __func__);
498 return ret;
501 /* Make sure we don't recurse back through here
502 * during loading */
503 state->skip_fw_load = 1;
505 ret = cx24116_load_firmware(fe, fw);
506 if (ret)
507 printk(KERN_ERR "%s: Writing firmware to device failed\n",
508 __func__);
510 release_firmware(fw);
512 printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
513 ret == 0 ? "complete" : "failed");
515 /* Ensure firmware is always loaded if required */
516 state->skip_fw_load = 0;
519 return ret;
522 /* Take a basic firmware command structure, format it
523 * and forward it for processing
525 static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
527 struct cx24116_state *state = fe->demodulator_priv;
528 int i, ret;
530 dprintk("%s()\n", __func__);
532 /* Load the firmware if required */
533 ret = cx24116_firmware_ondemand(fe);
534 if (ret != 0) {
535 printk(KERN_ERR "%s(): Unable initialise the firmware\n",
536 __func__);
537 return ret;
540 /* Write the command */
541 for (i = 0; i < cmd->len ; i++) {
542 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
543 cx24116_writereg(state, i, cmd->args[i]);
546 /* Start execution and wait for cmd to terminate */
547 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
548 while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
549 msleep(10);
550 if (i++ > 64) {
551 /* Avoid looping forever if the firmware does
552 not respond */
553 printk(KERN_WARNING "%s() Firmware not responding\n",
554 __func__);
555 return -EREMOTEIO;
558 return 0;
561 static int cx24116_load_firmware(struct dvb_frontend *fe,
562 const struct firmware *fw)
564 struct cx24116_state *state = fe->demodulator_priv;
565 struct cx24116_cmd cmd;
566 int i, ret;
567 unsigned char vers[4];
569 dprintk("%s\n", __func__);
570 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
571 fw->size,
572 fw->data[0],
573 fw->data[1],
574 fw->data[fw->size-2],
575 fw->data[fw->size-1]);
577 /* Toggle 88x SRST pin to reset demod */
578 if (state->config->reset_device)
579 state->config->reset_device(fe);
581 /* Begin the firmware load process */
582 /* Prepare the demod, load the firmware, cleanup after load */
584 /* Init PLL */
585 cx24116_writereg(state, 0xE5, 0x00);
586 cx24116_writereg(state, 0xF1, 0x08);
587 cx24116_writereg(state, 0xF2, 0x13);
589 /* Start PLL */
590 cx24116_writereg(state, 0xe0, 0x03);
591 cx24116_writereg(state, 0xe0, 0x00);
593 /* Unknown */
594 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
595 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
597 /* Unknown */
598 cx24116_writereg(state, 0xF0, 0x03);
599 cx24116_writereg(state, 0xF4, 0x81);
600 cx24116_writereg(state, 0xF5, 0x00);
601 cx24116_writereg(state, 0xF6, 0x00);
603 /* write the entire firmware as one transaction */
604 cx24116_writeregN(state, 0xF7, fw->data, fw->size);
606 cx24116_writereg(state, 0xF4, 0x10);
607 cx24116_writereg(state, 0xF0, 0x00);
608 cx24116_writereg(state, 0xF8, 0x06);
610 /* Firmware CMD 10: VCO config */
611 cmd.args[0x00] = CMD_SET_VCO;
612 cmd.args[0x01] = 0x05;
613 cmd.args[0x02] = 0xdc;
614 cmd.args[0x03] = 0xda;
615 cmd.args[0x04] = 0xae;
616 cmd.args[0x05] = 0xaa;
617 cmd.args[0x06] = 0x04;
618 cmd.args[0x07] = 0x9d;
619 cmd.args[0x08] = 0xfc;
620 cmd.args[0x09] = 0x06;
621 cmd.len = 0x0a;
622 ret = cx24116_cmd_execute(fe, &cmd);
623 if (ret != 0)
624 return ret;
626 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
628 /* Firmware CMD 14: Tuner config */
629 cmd.args[0x00] = CMD_TUNERINIT;
630 cmd.args[0x01] = 0x00;
631 cmd.args[0x02] = 0x00;
632 cmd.len = 0x03;
633 ret = cx24116_cmd_execute(fe, &cmd);
634 if (ret != 0)
635 return ret;
637 cx24116_writereg(state, 0xe5, 0x00);
639 /* Firmware CMD 13: MPEG config */
640 cmd.args[0x00] = CMD_MPEGCONFIG;
641 cmd.args[0x01] = 0x01;
642 cmd.args[0x02] = 0x75;
643 cmd.args[0x03] = 0x00;
644 if (state->config->mpg_clk_pos_pol)
645 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
646 else
647 cmd.args[0x04] = 0x02;
648 cmd.args[0x05] = 0x00;
649 cmd.len = 0x06;
650 ret = cx24116_cmd_execute(fe, &cmd);
651 if (ret != 0)
652 return ret;
654 /* Firmware CMD 35: Get firmware version */
655 cmd.args[0x00] = CMD_UPDFWVERS;
656 cmd.len = 0x02;
657 for (i = 0; i < 4; i++) {
658 cmd.args[0x01] = i;
659 ret = cx24116_cmd_execute(fe, &cmd);
660 if (ret != 0)
661 return ret;
662 vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
664 printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
665 vers[0], vers[1], vers[2], vers[3]);
667 return 0;
670 static int cx24116_set_voltage(struct dvb_frontend *fe,
671 fe_sec_voltage_t voltage)
673 /* The isl6421 module will override this function in the fops. */
674 dprintk("%s() This should never appear if the isl6421 module "
675 "is loaded correctly\n", __func__);
677 return -EOPNOTSUPP;
680 static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
682 struct cx24116_state *state = fe->demodulator_priv;
684 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
685 CX24116_STATUS_MASK;
687 dprintk("%s: status = 0x%02x\n", __func__, lock);
689 *status = 0;
691 if (lock & CX24116_HAS_SIGNAL)
692 *status |= FE_HAS_SIGNAL;
693 if (lock & CX24116_HAS_CARRIER)
694 *status |= FE_HAS_CARRIER;
695 if (lock & CX24116_HAS_VITERBI)
696 *status |= FE_HAS_VITERBI;
697 if (lock & CX24116_HAS_SYNCLOCK)
698 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
700 return 0;
703 static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
705 struct cx24116_state *state = fe->demodulator_priv;
707 dprintk("%s()\n", __func__);
709 *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
710 (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
711 (cx24116_readreg(state, CX24116_REG_BER8) << 8) |
712 cx24116_readreg(state, CX24116_REG_BER0);
714 return 0;
717 /* TODO Determine function and scale appropriately */
718 static int cx24116_read_signal_strength(struct dvb_frontend *fe,
719 u16 *signal_strength)
721 struct cx24116_state *state = fe->demodulator_priv;
722 struct cx24116_cmd cmd;
723 int ret;
724 u16 sig_reading;
726 dprintk("%s()\n", __func__);
728 /* Firmware CMD 19: Get AGC */
729 cmd.args[0x00] = CMD_GETAGC;
730 cmd.len = 0x01;
731 ret = cx24116_cmd_execute(fe, &cmd);
732 if (ret != 0)
733 return ret;
735 sig_reading =
736 (cx24116_readreg(state,
737 CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
738 (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
739 *signal_strength = 0 - sig_reading;
741 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
742 __func__, sig_reading, *signal_strength);
744 return 0;
747 /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
748 static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
750 struct cx24116_state *state = fe->demodulator_priv;
751 u8 snr_reading;
752 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
753 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
754 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
755 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
756 0x18000 };
758 dprintk("%s()\n", __func__);
760 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
762 if (snr_reading >= 0xa0 /* 100% */)
763 *snr = 0xffff;
764 else
765 *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
766 (snr_tab[(snr_reading & 0x0f)] >> 4);
768 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
769 snr_reading, *snr);
771 return 0;
774 /* The reelbox patches show the value in the registers represents
775 * ESNO, from 0->30db (values 0->300). We provide this value by
776 * default.
778 static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
780 struct cx24116_state *state = fe->demodulator_priv;
782 dprintk("%s()\n", __func__);
784 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
785 cx24116_readreg(state, CX24116_REG_QUALITY0);
787 dprintk("%s: raw 0x%04x\n", __func__, *snr);
789 return 0;
792 static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
794 if (esno_snr == 1)
795 return cx24116_read_snr_esno(fe, snr);
796 else
797 return cx24116_read_snr_pct(fe, snr);
800 static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
802 struct cx24116_state *state = fe->demodulator_priv;
804 dprintk("%s()\n", __func__);
806 *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
807 cx24116_readreg(state, CX24116_REG_UCB0);
809 return 0;
812 /* Overwrite the current tuning params, we are about to tune */
813 static void cx24116_clone_params(struct dvb_frontend *fe)
815 struct cx24116_state *state = fe->demodulator_priv;
816 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
819 /* Wait for LNB */
820 static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
822 struct cx24116_state *state = fe->demodulator_priv;
823 int i;
825 dprintk("%s() qstatus = 0x%02x\n", __func__,
826 cx24116_readreg(state, CX24116_REG_QSTATUS));
828 /* Wait for up to 300 ms */
829 for (i = 0; i < 30 ; i++) {
830 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
831 return 0;
832 msleep(10);
835 dprintk("%s(): LNB not ready\n", __func__);
837 return -ETIMEDOUT; /* -EBUSY ? */
840 static int cx24116_set_tone(struct dvb_frontend *fe,
841 fe_sec_tone_mode_t tone)
843 struct cx24116_cmd cmd;
844 int ret;
846 dprintk("%s(%d)\n", __func__, tone);
847 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
848 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
849 return -EINVAL;
852 /* Wait for LNB ready */
853 ret = cx24116_wait_for_lnb(fe);
854 if (ret != 0)
855 return ret;
857 /* Min delay time after DiSEqC send */
858 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
860 /* This is always done before the tone is set */
861 cmd.args[0x00] = CMD_SET_TONEPRE;
862 cmd.args[0x01] = 0x00;
863 cmd.len = 0x02;
864 ret = cx24116_cmd_execute(fe, &cmd);
865 if (ret != 0)
866 return ret;
868 /* Now we set the tone */
869 cmd.args[0x00] = CMD_SET_TONE;
870 cmd.args[0x01] = 0x00;
871 cmd.args[0x02] = 0x00;
873 switch (tone) {
874 case SEC_TONE_ON:
875 dprintk("%s: setting tone on\n", __func__);
876 cmd.args[0x03] = 0x01;
877 break;
878 case SEC_TONE_OFF:
879 dprintk("%s: setting tone off\n", __func__);
880 cmd.args[0x03] = 0x00;
881 break;
883 cmd.len = 0x04;
885 /* Min delay time before DiSEqC send */
886 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
888 return cx24116_cmd_execute(fe, &cmd);
891 /* Initialise DiSEqC */
892 static int cx24116_diseqc_init(struct dvb_frontend *fe)
894 struct cx24116_state *state = fe->demodulator_priv;
895 struct cx24116_cmd cmd;
896 int ret;
898 /* Firmware CMD 20: LNB/DiSEqC config */
899 cmd.args[0x00] = CMD_LNBCONFIG;
900 cmd.args[0x01] = 0x00;
901 cmd.args[0x02] = 0x10;
902 cmd.args[0x03] = 0x00;
903 cmd.args[0x04] = 0x8f;
904 cmd.args[0x05] = 0x28;
905 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
906 cmd.args[0x07] = 0x01;
907 cmd.len = 0x08;
908 ret = cx24116_cmd_execute(fe, &cmd);
909 if (ret != 0)
910 return ret;
912 /* Prepare a DiSEqC command */
913 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
915 /* DiSEqC burst */
916 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
918 /* Unknown */
919 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
920 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
921 /* Continuation flag? */
922 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
924 /* DiSEqC message length */
925 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
927 /* Command length */
928 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
930 return 0;
933 /* Send DiSEqC message with derived burst (hack) || previous burst */
934 static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
935 struct dvb_diseqc_master_cmd *d)
937 struct cx24116_state *state = fe->demodulator_priv;
938 int i, ret;
940 /* Dump DiSEqC message */
941 if (debug) {
942 printk(KERN_INFO "cx24116: %s(", __func__);
943 for (i = 0 ; i < d->msg_len ;) {
944 printk(KERN_INFO "0x%02x", d->msg[i]);
945 if (++i < d->msg_len)
946 printk(KERN_INFO ", ");
948 printk(") toneburst=%d\n", toneburst);
951 /* Validate length */
952 if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
953 return -EINVAL;
955 /* DiSEqC message */
956 for (i = 0; i < d->msg_len; i++)
957 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
959 /* DiSEqC message length */
960 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
962 /* Command length */
963 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
964 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
966 /* DiSEqC toneburst */
967 if (toneburst == CX24116_DISEQC_MESGCACHE)
968 /* Message is cached */
969 return 0;
971 else if (toneburst == CX24116_DISEQC_TONEOFF)
972 /* Message is sent without burst */
973 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
975 else if (toneburst == CX24116_DISEQC_TONECACHE) {
977 * Message is sent with derived else cached burst
979 * WRITE PORT GROUP COMMAND 38
981 * 0/A/A: E0 10 38 F0..F3
982 * 1/B/B: E0 10 38 F4..F7
983 * 2/C/A: E0 10 38 F8..FB
984 * 3/D/B: E0 10 38 FC..FF
986 * databyte[3]= 8421:8421
987 * ABCD:WXYZ
988 * CLR :SET
990 * WX= PORT SELECT 0..3 (X=TONEBURST)
991 * Y = VOLTAGE (0=13V, 1=18V)
992 * Z = BAND (0=LOW, 1=HIGH(22K))
994 if (d->msg_len >= 4 && d->msg[2] == 0x38)
995 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
996 ((d->msg[3] & 4) >> 2);
997 if (debug)
998 dprintk("%s burst=%d\n", __func__,
999 state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1002 /* Wait for LNB ready */
1003 ret = cx24116_wait_for_lnb(fe);
1004 if (ret != 0)
1005 return ret;
1007 /* Wait for voltage/min repeat delay */
1008 msleep(100);
1010 /* Command */
1011 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1012 if (ret != 0)
1013 return ret;
1015 * Wait for send
1017 * Eutelsat spec:
1018 * >15ms delay + (XXX determine if FW does this, see set_tone)
1019 * 13.5ms per byte +
1020 * >15ms delay +
1021 * 12.5ms burst +
1022 * >15ms delay (XXX determine if FW does this, see set_tone)
1024 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1025 ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1027 return 0;
1030 /* Send DiSEqC burst */
1031 static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
1032 fe_sec_mini_cmd_t burst)
1034 struct cx24116_state *state = fe->demodulator_priv;
1035 int ret;
1037 dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1039 /* DiSEqC burst */
1040 if (burst == SEC_MINI_A)
1041 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1042 CX24116_DISEQC_MINI_A;
1043 else if (burst == SEC_MINI_B)
1044 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1045 CX24116_DISEQC_MINI_B;
1046 else
1047 return -EINVAL;
1049 /* DiSEqC toneburst */
1050 if (toneburst != CX24116_DISEQC_MESGCACHE)
1051 /* Burst is cached */
1052 return 0;
1054 /* Burst is to be sent with cached message */
1056 /* Wait for LNB ready */
1057 ret = cx24116_wait_for_lnb(fe);
1058 if (ret != 0)
1059 return ret;
1061 /* Wait for voltage/min repeat delay */
1062 msleep(100);
1064 /* Command */
1065 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1066 if (ret != 0)
1067 return ret;
1070 * Wait for send
1072 * Eutelsat spec:
1073 * >15ms delay + (XXX determine if FW does this, see set_tone)
1074 * 13.5ms per byte +
1075 * >15ms delay +
1076 * 12.5ms burst +
1077 * >15ms delay (XXX determine if FW does this, see set_tone)
1079 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1081 return 0;
1084 static void cx24116_release(struct dvb_frontend *fe)
1086 struct cx24116_state *state = fe->demodulator_priv;
1087 dprintk("%s\n", __func__);
1088 kfree(state);
1091 static struct dvb_frontend_ops cx24116_ops;
1093 struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1094 struct i2c_adapter *i2c)
1096 struct cx24116_state *state = NULL;
1097 int ret;
1099 dprintk("%s\n", __func__);
1101 /* allocate memory for the internal state */
1102 state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1103 if (state == NULL)
1104 goto error1;
1106 /* setup the state */
1107 memset(state, 0, sizeof(struct cx24116_state));
1109 state->config = config;
1110 state->i2c = i2c;
1112 /* check if the demod is present */
1113 ret = (cx24116_readreg(state, 0xFF) << 8) |
1114 cx24116_readreg(state, 0xFE);
1115 if (ret != 0x0501) {
1116 printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1117 goto error2;
1120 /* create dvb_frontend */
1121 memcpy(&state->frontend.ops, &cx24116_ops,
1122 sizeof(struct dvb_frontend_ops));
1123 state->frontend.demodulator_priv = state;
1124 return &state->frontend;
1126 error2: kfree(state);
1127 error1: return NULL;
1129 EXPORT_SYMBOL(cx24116_attach);
1132 * Initialise or wake up device
1134 * Power config will reset and load initial firmware if required
1136 static int cx24116_initfe(struct dvb_frontend *fe)
1138 struct cx24116_state *state = fe->demodulator_priv;
1139 struct cx24116_cmd cmd;
1140 int ret;
1142 dprintk("%s()\n", __func__);
1144 /* Power on */
1145 cx24116_writereg(state, 0xe0, 0);
1146 cx24116_writereg(state, 0xe1, 0);
1147 cx24116_writereg(state, 0xea, 0);
1149 /* Firmware CMD 36: Power config */
1150 cmd.args[0x00] = CMD_TUNERSLEEP;
1151 cmd.args[0x01] = 0;
1152 cmd.len = 0x02;
1153 ret = cx24116_cmd_execute(fe, &cmd);
1154 if (ret != 0)
1155 return ret;
1157 return cx24116_diseqc_init(fe);
1161 * Put device to sleep
1163 static int cx24116_sleep(struct dvb_frontend *fe)
1165 struct cx24116_state *state = fe->demodulator_priv;
1166 struct cx24116_cmd cmd;
1167 int ret;
1169 dprintk("%s()\n", __func__);
1171 /* Firmware CMD 36: Power config */
1172 cmd.args[0x00] = CMD_TUNERSLEEP;
1173 cmd.args[0x01] = 1;
1174 cmd.len = 0x02;
1175 ret = cx24116_cmd_execute(fe, &cmd);
1176 if (ret != 0)
1177 return ret;
1179 /* Power off (Shutdown clocks) */
1180 cx24116_writereg(state, 0xea, 0xff);
1181 cx24116_writereg(state, 0xe1, 1);
1182 cx24116_writereg(state, 0xe0, 1);
1184 return 0;
1187 static int cx24116_set_property(struct dvb_frontend *fe,
1188 struct dtv_property *tvp)
1190 dprintk("%s(..)\n", __func__);
1191 return 0;
1194 static int cx24116_get_property(struct dvb_frontend *fe,
1195 struct dtv_property *tvp)
1197 dprintk("%s(..)\n", __func__);
1198 return 0;
1201 /* dvb-core told us to tune, the tv property cache will be complete,
1202 * it's safe for is to pull values and use them for tuning purposes.
1204 static int cx24116_set_frontend(struct dvb_frontend *fe,
1205 struct dvb_frontend_parameters *p)
1207 struct cx24116_state *state = fe->demodulator_priv;
1208 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1209 struct cx24116_cmd cmd;
1210 fe_status_t tunerstat;
1211 int i, status, ret, retune = 1;
1213 dprintk("%s()\n", __func__);
1215 switch (c->delivery_system) {
1216 case SYS_DVBS:
1217 dprintk("%s: DVB-S delivery system selected\n", __func__);
1219 /* Only QPSK is supported for DVB-S */
1220 if (c->modulation != QPSK) {
1221 dprintk("%s: unsupported modulation selected (%d)\n",
1222 __func__, c->modulation);
1223 return -EOPNOTSUPP;
1226 /* Pilot doesn't exist in DVB-S, turn bit off */
1227 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1229 /* DVB-S only supports 0.35 */
1230 if (c->rolloff != ROLLOFF_35) {
1231 dprintk("%s: unsupported rolloff selected (%d)\n",
1232 __func__, c->rolloff);
1233 return -EOPNOTSUPP;
1235 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1236 break;
1238 case SYS_DVBS2:
1239 dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1242 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1243 * but not hardware auto detection
1245 if (c->modulation != PSK_8 && c->modulation != QPSK) {
1246 dprintk("%s: unsupported modulation selected (%d)\n",
1247 __func__, c->modulation);
1248 return -EOPNOTSUPP;
1251 switch (c->pilot) {
1252 case PILOT_AUTO: /* Not supported but emulated */
1253 state->dnxt.pilot_val = (c->modulation == QPSK)
1254 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1255 retune++;
1256 break;
1257 case PILOT_OFF:
1258 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1259 break;
1260 case PILOT_ON:
1261 state->dnxt.pilot_val = CX24116_PILOT_ON;
1262 break;
1263 default:
1264 dprintk("%s: unsupported pilot mode selected (%d)\n",
1265 __func__, c->pilot);
1266 return -EOPNOTSUPP;
1269 switch (c->rolloff) {
1270 case ROLLOFF_20:
1271 state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1272 break;
1273 case ROLLOFF_25:
1274 state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1275 break;
1276 case ROLLOFF_35:
1277 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1278 break;
1279 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1280 default:
1281 dprintk("%s: unsupported rolloff selected (%d)\n",
1282 __func__, c->rolloff);
1283 return -EOPNOTSUPP;
1285 break;
1287 default:
1288 dprintk("%s: unsupported delivery system selected (%d)\n",
1289 __func__, c->delivery_system);
1290 return -EOPNOTSUPP;
1292 state->dnxt.delsys = c->delivery_system;
1293 state->dnxt.modulation = c->modulation;
1294 state->dnxt.frequency = c->frequency;
1295 state->dnxt.pilot = c->pilot;
1296 state->dnxt.rolloff = c->rolloff;
1298 ret = cx24116_set_inversion(state, c->inversion);
1299 if (ret != 0)
1300 return ret;
1302 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1303 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1304 if (ret != 0)
1305 return ret;
1307 ret = cx24116_set_symbolrate(state, c->symbol_rate);
1308 if (ret != 0)
1309 return ret;
1311 /* discard the 'current' tuning parameters and prepare to tune */
1312 cx24116_clone_params(fe);
1314 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
1315 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1316 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1317 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1318 state->dcur.pilot, state->dcur.pilot_val);
1319 dprintk("%s: retune = %d\n", __func__, retune);
1320 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1321 state->dcur.rolloff, state->dcur.rolloff_val);
1322 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1323 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1324 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1325 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1326 state->dcur.inversion, state->dcur.inversion_val);
1328 /* This is also done in advise/acquire on HVR4000 but not on LITE */
1329 if (state->config->set_ts_params)
1330 state->config->set_ts_params(fe, 0);
1332 /* Set/Reset B/W */
1333 cmd.args[0x00] = CMD_BANDWIDTH;
1334 cmd.args[0x01] = 0x01;
1335 cmd.len = 0x02;
1336 ret = cx24116_cmd_execute(fe, &cmd);
1337 if (ret != 0)
1338 return ret;
1340 /* Prepare a tune request */
1341 cmd.args[0x00] = CMD_TUNEREQUEST;
1343 /* Frequency */
1344 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1345 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1346 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1348 /* Symbol Rate */
1349 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1350 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1352 /* Automatic Inversion */
1353 cmd.args[0x06] = state->dcur.inversion_val;
1355 /* Modulation / FEC / Pilot */
1356 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1358 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1359 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1360 cmd.args[0x0a] = 0x00;
1361 cmd.args[0x0b] = 0x00;
1362 cmd.args[0x0c] = state->dcur.rolloff_val;
1363 cmd.args[0x0d] = state->dcur.fec_mask;
1365 if (state->dcur.symbol_rate > 30000000) {
1366 cmd.args[0x0e] = 0x04;
1367 cmd.args[0x0f] = 0x00;
1368 cmd.args[0x10] = 0x01;
1369 cmd.args[0x11] = 0x77;
1370 cmd.args[0x12] = 0x36;
1371 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1372 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1373 } else {
1374 cmd.args[0x0e] = 0x06;
1375 cmd.args[0x0f] = 0x00;
1376 cmd.args[0x10] = 0x00;
1377 cmd.args[0x11] = 0xFA;
1378 cmd.args[0x12] = 0x24;
1379 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1380 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1383 cmd.len = 0x13;
1385 /* We need to support pilot and non-pilot tuning in the
1386 * driver automatically. This is a workaround for because
1387 * the demod does not support autodetect.
1389 do {
1390 /* Reset status register */
1391 status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1392 & CX24116_SIGNAL_MASK;
1393 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1395 /* Tune */
1396 ret = cx24116_cmd_execute(fe, &cmd);
1397 if (ret != 0)
1398 break;
1401 * Wait for up to 500 ms before retrying
1403 * If we are able to tune then generally it occurs within 100ms.
1404 * If it takes longer, try a different toneburst setting.
1406 for (i = 0; i < 50 ; i++) {
1407 cx24116_read_status(fe, &tunerstat);
1408 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1409 if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1410 dprintk("%s: Tuned\n", __func__);
1411 goto tuned;
1413 msleep(10);
1416 dprintk("%s: Not tuned\n", __func__);
1418 /* Toggle pilot bit when in auto-pilot */
1419 if (state->dcur.pilot == PILOT_AUTO)
1420 cmd.args[0x07] ^= CX24116_PILOT_ON;
1421 } while (--retune);
1423 tuned: /* Set/Reset B/W */
1424 cmd.args[0x00] = CMD_BANDWIDTH;
1425 cmd.args[0x01] = 0x00;
1426 cmd.len = 0x02;
1427 ret = cx24116_cmd_execute(fe, &cmd);
1428 if (ret != 0)
1429 return ret;
1431 return ret;
1434 static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
1435 unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
1437 *delay = HZ / 5;
1438 if (params) {
1439 int ret = cx24116_set_frontend(fe, params);
1440 if (ret)
1441 return ret;
1443 return cx24116_read_status(fe, status);
1446 static int cx24116_get_algo(struct dvb_frontend *fe)
1448 return DVBFE_ALGO_HW;
1451 static struct dvb_frontend_ops cx24116_ops = {
1453 .info = {
1454 .name = "Conexant CX24116/CX24118",
1455 .type = FE_QPSK,
1456 .frequency_min = 950000,
1457 .frequency_max = 2150000,
1458 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1459 .frequency_tolerance = 5000,
1460 .symbol_rate_min = 1000000,
1461 .symbol_rate_max = 45000000,
1462 .caps = FE_CAN_INVERSION_AUTO |
1463 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1464 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1465 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1466 FE_CAN_2G_MODULATION |
1467 FE_CAN_QPSK | FE_CAN_RECOVER
1470 .release = cx24116_release,
1472 .init = cx24116_initfe,
1473 .sleep = cx24116_sleep,
1474 .read_status = cx24116_read_status,
1475 .read_ber = cx24116_read_ber,
1476 .read_signal_strength = cx24116_read_signal_strength,
1477 .read_snr = cx24116_read_snr,
1478 .read_ucblocks = cx24116_read_ucblocks,
1479 .set_tone = cx24116_set_tone,
1480 .set_voltage = cx24116_set_voltage,
1481 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1482 .diseqc_send_burst = cx24116_diseqc_send_burst,
1483 .get_frontend_algo = cx24116_get_algo,
1484 .tune = cx24116_tune,
1486 .set_property = cx24116_set_property,
1487 .get_property = cx24116_get_property,
1488 .set_frontend = cx24116_set_frontend,
1491 MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1492 MODULE_AUTHOR("Steven Toth");
1493 MODULE_LICENSE("GPL");