Merge tag 'libnvdimm-fixes-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / drivers / media / dvb-frontends / cx24116.c
CommitLineData
74ba9207 1// SPDX-License-Identifier: GPL-2.0-or-later
0d46748c
ST
2/*
3 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
4
5 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
490c8684
DB
6 Copyright (C) 2006-2007 Georg Acher
7 Copyright (C) 2007-2008 Darron Broad
8 March 2007
9 Fixed some bugs.
10 Added diseqc support.
11 Added corrected signal strength support.
12 August 2007
13 Sync with legacy version.
14 Some clean ups.
15 Copyright (C) 2008 Igor Liplianin
16 September, 9th 2008
c063a489
IL
17 Fixed locking on high symbol rates (>30000).
18 Implement MPEG initialization parameter.
c7bdcd0f
IL
19 January, 17th 2009
20 Fill set_voltage with actually control voltage code.
21 Correct set tone to not affect voltage.
0d46748c 22
0d46748c
ST
23*/
24
0d46748c
ST
25#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/firmware.h>
31
fada1935 32#include <media/dvb_frontend.h>
0d46748c
ST
33#include "cx24116.h"
34
f11ec7d4
ST
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
38
490c8684
DB
39#define dprintk(args...) \
40 do { \
f11ec7d4 41 if (debug) \
98c94823 42 printk(KERN_INFO "cx24116: " args); \
490c8684
DB
43 } while (0)
44
0d46748c
ST
45#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
46#define CX24116_SEARCH_RANGE_KHZ 5000
47
490c8684
DB
48/* known registers */
49#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
50#define CX24116_REG_EXECUTE (0x1f) /* execute command */
51#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
52#define CX24116_REG_RESET (0x20) /* reset status > 0 */
53#define CX24116_REG_SIGNAL (0x9e) /* signal low */
54#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
8953db79 55#define CX24116_REG_QUALITY8 (0xa3)
490c8684 56#define CX24116_REG_QSTATUS (0xbc)
8953db79 57#define CX24116_REG_QUALITY0 (0xd5)
490c8684
DB
58#define CX24116_REG_BER0 (0xc9)
59#define CX24116_REG_BER8 (0xc8)
60#define CX24116_REG_BER16 (0xc7)
61#define CX24116_REG_BER24 (0xc6)
62#define CX24116_REG_UCB0 (0xcb)
63#define CX24116_REG_UCB8 (0xca)
64#define CX24116_REG_CLKDIV (0xf3)
65#define CX24116_REG_RATEDIV (0xf9)
98c94823
ST
66
67/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
68#define CX24116_REG_FECSTATUS (0x9c)
681faa0b
DB
69
70/* FECSTATUS bits */
98c94823
ST
71/* mask to determine configured fec (not tuned) or actual fec (tuned) */
72#define CX24116_FEC_FECMASK (0x1f)
73
74/* Select DVB-S demodulator, else DVB-S2 */
75#define CX24116_FEC_DVBS (0x20)
681faa0b 76#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
98c94823
ST
77
78/* Pilot mode requested when tuning else always reset when tuned */
79#define CX24116_FEC_PILOT (0x80)
0d46748c
ST
80
81/* arg buffer size */
82#define CX24116_ARGLEN (0x1e)
83
490c8684
DB
84/* rolloff */
85#define CX24116_ROLLOFF_020 (0x00)
86#define CX24116_ROLLOFF_025 (0x01)
87#define CX24116_ROLLOFF_035 (0x02)
88
89/* pilot bit */
01a8f038
DB
90#define CX24116_PILOT_OFF (0x00)
91#define CX24116_PILOT_ON (0x40)
490c8684
DB
92
93/* signal status */
94#define CX24116_HAS_SIGNAL (0x01)
95#define CX24116_HAS_CARRIER (0x02)
96#define CX24116_HAS_VITERBI (0x04)
97#define CX24116_HAS_SYNCLOCK (0x08)
98#define CX24116_HAS_UNKNOWN1 (0x10)
99#define CX24116_HAS_UNKNOWN2 (0x20)
6639f1e0 100#define CX24116_STATUS_MASK (0x0f)
490c8684
DB
101#define CX24116_SIGNAL_MASK (0xc0)
102
103#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
104#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
105#define CX24116_DISEQC_MESGCACHE (2) /* message cached */
106
0d46748c
ST
107/* arg offset for DiSEqC */
108#define CX24116_DISEQC_BURST (1)
109#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
110#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
111#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
112#define CX24116_DISEQC_MSGLEN (5)
113#define CX24116_DISEQC_MSGOFS (6)
114
115/* DiSEqC burst */
116#define CX24116_DISEQC_MINI_A (0)
117#define CX24116_DISEQC_MINI_B (1)
118
490c8684
DB
119/* DiSEqC tone burst */
120static int toneburst = 1;
f11ec7d4 121module_param(toneburst, int, 0644);
98c94823
ST
122MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
123 "2=MESSAGE CACHE (default:1)");
490c8684 124
8953db79 125/* SNR measurements */
f11ec7d4
ST
126static int esno_snr;
127module_param(esno_snr, int, 0644);
53f1fe94 128MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
98c94823 129 "1=ESNO(db * 10) (default:0)");
8953db79 130
f11ec7d4 131enum cmds {
490c8684 132 CMD_SET_VCO = 0x10,
0d46748c 133 CMD_TUNEREQUEST = 0x11,
490c8684
DB
134 CMD_MPEGCONFIG = 0x13,
135 CMD_TUNERINIT = 0x14,
136 CMD_BANDWIDTH = 0x15,
137 CMD_GETAGC = 0x19,
138 CMD_LNBCONFIG = 0x20,
139 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
c7bdcd0f 140 CMD_LNBDCLEVEL = 0x22,
0d46748c 141 CMD_SET_TONE = 0x23,
490c8684
DB
142 CMD_UPDFWVERS = 0x35,
143 CMD_TUNERSLEEP = 0x36,
144 CMD_AGCCONTROL = 0x3b, /* Unknown */
0d46748c
ST
145};
146
147/* The Demod/Tuner can't easily provide these, we cache them */
f11ec7d4 148struct cx24116_tuning {
0d46748c
ST
149 u32 frequency;
150 u32 symbol_rate;
0df289a2
MCC
151 enum fe_spectral_inversion inversion;
152 enum fe_code_rate fec;
0d46748c 153
0df289a2
MCC
154 enum fe_delivery_system delsys;
155 enum fe_modulation modulation;
156 enum fe_pilot pilot;
157 enum fe_rolloff rolloff;
0d46748c
ST
158
159 /* Demod values */
160 u8 fec_val;
161 u8 fec_mask;
162 u8 inversion_val;
01a8f038 163 u8 pilot_val;
490c8684 164 u8 rolloff_val;
0d46748c
ST
165};
166
167/* Basic commands that are sent to the firmware */
f11ec7d4 168struct cx24116_cmd {
0d46748c
ST
169 u8 len;
170 u8 args[CX24116_ARGLEN];
171};
172
f11ec7d4
ST
173struct cx24116_state {
174 struct i2c_adapter *i2c;
175 const struct cx24116_config *config;
0d46748c
ST
176
177 struct dvb_frontend frontend;
178
179 struct cx24116_tuning dcur;
180 struct cx24116_tuning dnxt;
181
182 u8 skip_fw_load;
183 u8 burst;
490c8684 184 struct cx24116_cmd dsec_cmd;
0d46748c
ST
185};
186
f11ec7d4 187static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
0d46748c
ST
188{
189 u8 buf[] = { reg, data };
190 struct i2c_msg msg = { .addr = state->config->demod_address,
191 .flags = 0, .buf = buf, .len = 2 };
192 int err;
193
f11ec7d4 194 if (debug > 1)
0d46748c 195 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
f11ec7d4 196 __func__, reg, data);
0d46748c 197
f11ec7d4
ST
198 err = i2c_transfer(state->i2c, &msg, 1);
199 if (err != 1) {
4bd69e7b
MCC
200 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n",
201 __func__, err, reg, data);
0d46748c
ST
202 return -EREMOTEIO;
203 }
204
205 return 0;
206}
207
208/* Bulk byte writes to a single I2C address, for 32k firmware load */
f11ec7d4 209static int cx24116_writeregN(struct cx24116_state *state, int reg,
64decbfe 210 const u8 *data, u16 len)
0d46748c 211{
d303b7c5 212 int ret;
0d46748c
ST
213 struct i2c_msg msg;
214 u8 *buf;
215
216 buf = kmalloc(len + 1, GFP_KERNEL);
9722e569
ME
217 if (!buf)
218 return -ENOMEM;
0d46748c
ST
219
220 *(buf) = reg;
221 memcpy(buf + 1, data, len);
222
223 msg.addr = state->config->demod_address;
224 msg.flags = 0;
225 msg.buf = buf;
226 msg.len = len + 1;
227
f11ec7d4 228 if (debug > 1)
98c94823 229 printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
f11ec7d4 230 __func__, reg, len);
0d46748c 231
f11ec7d4
ST
232 ret = i2c_transfer(state->i2c, &msg, 1);
233 if (ret != 1) {
98c94823 234 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
0d46748c
ST
235 __func__, ret, reg);
236 ret = -EREMOTEIO;
237 }
238
0d46748c
ST
239 kfree(buf);
240
241 return ret;
242}
243
f11ec7d4 244static int cx24116_readreg(struct cx24116_state *state, u8 reg)
0d46748c
ST
245{
246 int ret;
247 u8 b0[] = { reg };
248 u8 b1[] = { 0 };
249 struct i2c_msg msg[] = {
f11ec7d4
ST
250 { .addr = state->config->demod_address, .flags = 0,
251 .buf = b0, .len = 1 },
252 { .addr = state->config->demod_address, .flags = I2C_M_RD,
253 .buf = b1, .len = 1 }
0d46748c
ST
254 };
255
256 ret = i2c_transfer(state->i2c, msg, 2);
257
258 if (ret != 2) {
98c94823
ST
259 printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
260 __func__, reg, ret);
0d46748c
ST
261 return ret;
262 }
263
f11ec7d4 264 if (debug > 1)
98c94823 265 printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
f11ec7d4 266 reg, b1[0]);
0d46748c
ST
267
268 return b1[0];
269}
270
98c94823 271static int cx24116_set_inversion(struct cx24116_state *state,
0df289a2 272 enum fe_spectral_inversion inversion)
0d46748c
ST
273{
274 dprintk("%s(%d)\n", __func__, inversion);
275
276 switch (inversion) {
277 case INVERSION_OFF:
278 state->dnxt.inversion_val = 0x00;
279 break;
280 case INVERSION_ON:
281 state->dnxt.inversion_val = 0x04;
282 break;
283 case INVERSION_AUTO:
284 state->dnxt.inversion_val = 0x0C;
285 break;
286 default:
287 return -EINVAL;
288 }
289
290 state->dnxt.inversion = inversion;
291
292 return 0;
293}
294
490c8684
DB
295/*
296 * modfec (modulation and FEC)
297 * ===========================
298 *
299 * MOD FEC mask/val standard
300 * ---- -------- ----------- --------
301 * QPSK FEC_1_2 0x02 0x02+X DVB-S
302 * QPSK FEC_2_3 0x04 0x02+X DVB-S
303 * QPSK FEC_3_4 0x08 0x02+X DVB-S
304 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
305 * QPSK FEC_5_6 0x20 0x02+X DVB-S
306 * QPSK FEC_6_7 0x40 0x02+X DVB-S
307 * QPSK FEC_7_8 0x80 0x02+X DVB-S
308 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
309 * QPSK AUTO 0xff 0x02+X DVB-S
310 *
311 * For DVB-S high byte probably represents FEC
312 * and low byte selects the modulator. The high
313 * byte is search range mask. Bit 5 may turn
314 * on DVB-S and remaining bits represent some
315 * kind of calibration (how/what i do not know).
316 *
317 * Eg.(2/3) szap "Zone Horror"
318 *
319 * mask/val = 0x04, 0x20
98c94823 320 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
490c8684
DB
321 *
322 * mask/val = 0x04, 0x30
98c94823 323 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
490c8684
DB
324 *
325 * After tuning FECSTATUS contains actual FEC
326 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
327 *
328 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
329 *
330 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
331 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
332 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
333 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
334 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
335 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
336 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
337 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
338 *
339 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
340 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
341 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
342 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
343 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
344 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
345 *
346 * For DVB-S2 low bytes selects both modulator
347 * and FEC. High byte is meaningless here. To
348 * set pilot, bit 6 (0x40) is set. When inspecting
349 * FECSTATUS bit 7 (0x80) represents the pilot
350 * selection whilst not tuned. When tuned, actual FEC
351 * in use is found in FECSTATUS as per above. Pilot
352 * value is reset.
353 */
354
0d46748c
ST
355/* A table of modulation, fec and configuration bytes for the demod.
356 * Not all S2 mmodulation schemes are support and not all rates with
357 * a scheme are support. Especially, no auto detect when in S2 mode.
358 */
ffbc5f88 359static struct cx24116_modfec {
0df289a2
MCC
360 enum fe_delivery_system delivery_system;
361 enum fe_modulation modulation;
362 enum fe_code_rate fec;
0d46748c
ST
363 u8 mask; /* In DVBS mode this is used to autodetect */
364 u8 val; /* Passed to the firmware to indicate mode selection */
365} CX24116_MODFEC_MODES[] = {
366 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
490c8684
DB
367
368 /*mod fec mask val */
0a6393ae
ST
369 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
370 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
371 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
372 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
373 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
374 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
375 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
376 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
377 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
378 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
0d46748c 379 /* NBC-QPSK */
0a6393ae
ST
380 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
381 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
382 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
383 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
384 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
385 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
386 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
387 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
0d46748c 388 /* 8PSK */
0a6393ae
ST
389 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
390 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
391 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
392 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
393 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
394 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
490c8684
DB
395 /*
396 * `val' can be found in the FECSTATUS register when tuning.
397 * FECSTATUS will give the actual FEC in use if tuning was successful.
398 */
0d46748c
ST
399};
400
f11ec7d4 401static int cx24116_lookup_fecmod(struct cx24116_state *state,
0df289a2 402 enum fe_delivery_system d, enum fe_modulation m, enum fe_code_rate f)
0d46748c
ST
403{
404 int i, ret = -EOPNOTSUPP;
405
490c8684
DB
406 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
407
f11ec7d4 408 for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
3569476d
DB
409 if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
410 (m == CX24116_MODFEC_MODES[i].modulation) &&
f11ec7d4 411 (f == CX24116_MODFEC_MODES[i].fec)) {
0d46748c
ST
412 ret = i;
413 break;
414 }
415 }
416
417 return ret;
418}
419
98c94823 420static int cx24116_set_fec(struct cx24116_state *state,
0df289a2
MCC
421 enum fe_delivery_system delsys,
422 enum fe_modulation mod,
423 enum fe_code_rate fec)
0d46748c
ST
424{
425 int ret = 0;
490c8684
DB
426
427 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
0d46748c 428
3569476d 429 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
0d46748c 430
f11ec7d4 431 if (ret < 0)
0d46748c
ST
432 return ret;
433
490c8684 434 state->dnxt.fec = fec;
0d46748c
ST
435 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
436 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
490c8684
DB
437 dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
438 state->dnxt.fec_mask, state->dnxt.fec_val);
0d46748c
ST
439
440 return 0;
441}
442
f11ec7d4 443static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
0d46748c 444{
490c8684 445 dprintk("%s(%d)\n", __func__, rate);
0d46748c 446
490c8684
DB
447 /* check if symbol rate is within limits */
448 if ((rate > state->frontend.ops.info.symbol_rate_max) ||
449 (rate < state->frontend.ops.info.symbol_rate_min)) {
450 dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
451 return -EOPNOTSUPP;
452 }
0d46748c
ST
453
454 state->dnxt.symbol_rate = rate;
490c8684 455 dprintk("%s() symbol_rate = %d\n", __func__, rate);
0d46748c 456
490c8684 457 return 0;
0d46748c
ST
458}
459
f11ec7d4
ST
460static int cx24116_load_firmware(struct dvb_frontend *fe,
461 const struct firmware *fw);
0d46748c 462
f11ec7d4 463static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
0d46748c
ST
464{
465 struct cx24116_state *state = fe->demodulator_priv;
466 const struct firmware *fw;
467 int ret = 0;
468
f11ec7d4 469 dprintk("%s()\n", __func__);
0d46748c 470
f11ec7d4 471 if (cx24116_readreg(state, 0x20) > 0) {
0d46748c
ST
472
473 if (state->skip_fw_load)
474 return 0;
475
476 /* Load firmware */
98c94823
ST
477 /* request the firmware, this will block until loaded */
478 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
479 __func__, CX24116_DEFAULT_FIRMWARE);
480 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
e9785250 481 state->i2c->dev.parent);
98c94823
ST
482 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
483 __func__);
0d46748c 484 if (ret) {
4bd69e7b
MCC
485 printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n",
486 __func__);
0d46748c
ST
487 return ret;
488 }
489
98c94823
ST
490 /* Make sure we don't recurse back through here
491 * during loading */
0d46748c
ST
492 state->skip_fw_load = 1;
493
494 ret = cx24116_load_firmware(fe, fw);
495 if (ret)
98c94823
ST
496 printk(KERN_ERR "%s: Writing firmware to device failed\n",
497 __func__);
0d46748c
ST
498
499 release_firmware(fw);
500
98c94823
ST
501 printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
502 ret == 0 ? "complete" : "failed");
0d46748c
ST
503
504 /* Ensure firmware is always loaded if required */
505 state->skip_fw_load = 0;
506 }
507
508 return ret;
509}
510
98c94823
ST
511/* Take a basic firmware command structure, format it
512 * and forward it for processing
513 */
f11ec7d4 514static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
0d46748c
ST
515{
516 struct cx24116_state *state = fe->demodulator_priv;
517 int i, ret;
518
519 dprintk("%s()\n", __func__);
520
521 /* Load the firmware if required */
f11ec7d4
ST
522 ret = cx24116_firmware_ondemand(fe);
523 if (ret != 0) {
98c94823
ST
524 printk(KERN_ERR "%s(): Unable initialise the firmware\n",
525 __func__);
0d46748c
ST
526 return ret;
527 }
528
529 /* Write the command */
f11ec7d4 530 for (i = 0; i < cmd->len ; i++) {
0d46748c
ST
531 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
532 cx24116_writereg(state, i, cmd->args[i]);
533 }
534
535 /* Start execution and wait for cmd to terminate */
490c8684 536 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
f11ec7d4 537 while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
0d46748c 538 msleep(10);
f11ec7d4 539 if (i++ > 64) {
98c94823
ST
540 /* Avoid looping forever if the firmware does
541 not respond */
542 printk(KERN_WARNING "%s() Firmware not responding\n",
543 __func__);
0d46748c
ST
544 return -EREMOTEIO;
545 }
546 }
547 return 0;
548}
549
f11ec7d4
ST
550static int cx24116_load_firmware(struct dvb_frontend *fe,
551 const struct firmware *fw)
0d46748c 552{
f11ec7d4 553 struct cx24116_state *state = fe->demodulator_priv;
0d46748c 554 struct cx24116_cmd cmd;
e0bae9b3 555 int i, ret, len, max, remaining;
490c8684 556 unsigned char vers[4];
0d46748c
ST
557
558 dprintk("%s\n", __func__);
f11ec7d4
ST
559 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
560 fw->size,
561 fw->data[0],
562 fw->data[1],
563 fw->data[fw->size-2],
564 fw->data[fw->size-1]);
0d46748c
ST
565
566 /* Toggle 88x SRST pin to reset demod */
567 if (state->config->reset_device)
568 state->config->reset_device(fe);
569
570 /* Begin the firmware load process */
571 /* Prepare the demod, load the firmware, cleanup after load */
490c8684
DB
572
573 /* Init PLL */
574 cx24116_writereg(state, 0xE5, 0x00);
0d46748c 575 cx24116_writereg(state, 0xF1, 0x08);
490c8684
DB
576 cx24116_writereg(state, 0xF2, 0x13);
577
578 /* Start PLL */
579 cx24116_writereg(state, 0xe0, 0x03);
580 cx24116_writereg(state, 0xe0, 0x00);
581
582 /* Unknown */
583 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
584 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
0d46748c 585
490c8684 586 /* Unknown */
0d46748c
ST
587 cx24116_writereg(state, 0xF0, 0x03);
588 cx24116_writereg(state, 0xF4, 0x81);
589 cx24116_writereg(state, 0xF5, 0x00);
590 cx24116_writereg(state, 0xF6, 0x00);
591
107d7b18 592 /* Split firmware to the max I2C write len and write.
e0bae9b3
AP
593 * Writes whole firmware as one write when i2c_wr_max is set to 0. */
594 if (state->config->i2c_wr_max)
595 max = state->config->i2c_wr_max;
596 else
597 max = INT_MAX; /* enough for 32k firmware */
107d7b18 598
e0bae9b3 599 for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
107d7b18 600 len = remaining;
e0bae9b3
AP
601 if (len > max - 1)
602 len = max - 1;
107d7b18
AP
603
604 cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
605 len);
606 }
0d46748c
ST
607
608 cx24116_writereg(state, 0xF4, 0x10);
609 cx24116_writereg(state, 0xF0, 0x00);
610 cx24116_writereg(state, 0xF8, 0x06);
611
490c8684
DB
612 /* Firmware CMD 10: VCO config */
613 cmd.args[0x00] = CMD_SET_VCO;
0d46748c
ST
614 cmd.args[0x01] = 0x05;
615 cmd.args[0x02] = 0xdc;
616 cmd.args[0x03] = 0xda;
617 cmd.args[0x04] = 0xae;
618 cmd.args[0x05] = 0xaa;
619 cmd.args[0x06] = 0x04;
620 cmd.args[0x07] = 0x9d;
621 cmd.args[0x08] = 0xfc;
622 cmd.args[0x09] = 0x06;
f11ec7d4 623 cmd.len = 0x0a;
0d46748c
ST
624 ret = cx24116_cmd_execute(fe, &cmd);
625 if (ret != 0)
626 return ret;
627
490c8684 628 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
0d46748c 629
490c8684
DB
630 /* Firmware CMD 14: Tuner config */
631 cmd.args[0x00] = CMD_TUNERINIT;
0d46748c
ST
632 cmd.args[0x01] = 0x00;
633 cmd.args[0x02] = 0x00;
f11ec7d4 634 cmd.len = 0x03;
0d46748c
ST
635 ret = cx24116_cmd_execute(fe, &cmd);
636 if (ret != 0)
637 return ret;
638
639 cx24116_writereg(state, 0xe5, 0x00);
640
490c8684
DB
641 /* Firmware CMD 13: MPEG config */
642 cmd.args[0x00] = CMD_MPEGCONFIG;
0d46748c
ST
643 cmd.args[0x01] = 0x01;
644 cmd.args[0x02] = 0x75;
645 cmd.args[0x03] = 0x00;
cc8c4f3a
IL
646 if (state->config->mpg_clk_pos_pol)
647 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
648 else
649 cmd.args[0x04] = 0x02;
0d46748c 650 cmd.args[0x05] = 0x00;
f11ec7d4 651 cmd.len = 0x06;
0d46748c
ST
652 ret = cx24116_cmd_execute(fe, &cmd);
653 if (ret != 0)
654 return ret;
655
490c8684
DB
656 /* Firmware CMD 35: Get firmware version */
657 cmd.args[0x00] = CMD_UPDFWVERS;
f11ec7d4
ST
658 cmd.len = 0x02;
659 for (i = 0; i < 4; i++) {
490c8684
DB
660 cmd.args[0x01] = i;
661 ret = cx24116_cmd_execute(fe, &cmd);
662 if (ret != 0)
663 return ret;
f11ec7d4 664 vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
490c8684 665 }
98c94823 666 printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
490c8684
DB
667 vers[0], vers[1], vers[2], vers[3]);
668
0d46748c
ST
669 return 0;
670}
671
0df289a2 672static int cx24116_read_status(struct dvb_frontend *fe, enum fe_status *status)
0d46748c
ST
673{
674 struct cx24116_state *state = fe->demodulator_priv;
675
6639f1e0
DB
676 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
677 CX24116_STATUS_MASK;
0d46748c
ST
678
679 dprintk("%s: status = 0x%02x\n", __func__, lock);
680
681 *status = 0;
682
490c8684 683 if (lock & CX24116_HAS_SIGNAL)
0d46748c 684 *status |= FE_HAS_SIGNAL;
490c8684 685 if (lock & CX24116_HAS_CARRIER)
0d46748c 686 *status |= FE_HAS_CARRIER;
490c8684 687 if (lock & CX24116_HAS_VITERBI)
0d46748c 688 *status |= FE_HAS_VITERBI;
490c8684 689 if (lock & CX24116_HAS_SYNCLOCK)
0d46748c
ST
690 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
691
692 return 0;
693}
694
f11ec7d4 695static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
0d46748c 696{
490c8684
DB
697 struct cx24116_state *state = fe->demodulator_priv;
698
0d46748c 699 dprintk("%s()\n", __func__);
490c8684 700
f11ec7d4
ST
701 *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
702 (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
703 (cx24116_readreg(state, CX24116_REG_BER8) << 8) |
704 cx24116_readreg(state, CX24116_REG_BER0);
0d46748c
ST
705
706 return 0;
707}
708
490c8684 709/* TODO Determine function and scale appropriately */
f11ec7d4
ST
710static int cx24116_read_signal_strength(struct dvb_frontend *fe,
711 u16 *signal_strength)
0d46748c
ST
712{
713 struct cx24116_state *state = fe->demodulator_priv;
490c8684
DB
714 struct cx24116_cmd cmd;
715 int ret;
716 u16 sig_reading;
0d46748c
ST
717
718 dprintk("%s()\n", __func__);
719
490c8684
DB
720 /* Firmware CMD 19: Get AGC */
721 cmd.args[0x00] = CMD_GETAGC;
f11ec7d4 722 cmd.len = 0x01;
490c8684
DB
723 ret = cx24116_cmd_execute(fe, &cmd);
724 if (ret != 0)
725 return ret;
0d46748c 726
f11ec7d4
ST
727 sig_reading =
728 (cx24116_readreg(state,
729 CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
730 (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
731 *signal_strength = 0 - sig_reading;
0d46748c 732
f11ec7d4
ST
733 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
734 __func__, sig_reading, *signal_strength);
0d46748c
ST
735
736 return 0;
737}
738
490c8684 739/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
f11ec7d4 740static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
0d46748c 741{
490c8684
DB
742 struct cx24116_state *state = fe->demodulator_priv;
743 u8 snr_reading;
744 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
f11ec7d4
ST
745 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
746 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
747 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
748 0x18000 };
490c8684 749
0d46748c 750 dprintk("%s()\n", __func__);
490c8684 751
8953db79 752 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
490c8684 753
f11ec7d4 754 if (snr_reading >= 0xa0 /* 100% */)
490c8684
DB
755 *snr = 0xffff;
756 else
f11ec7d4
ST
757 *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
758 (snr_tab[(snr_reading & 0x0f)] >> 4);
490c8684
DB
759
760 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
761 snr_reading, *snr);
0d46748c
ST
762
763 return 0;
764}
765
8953db79
ST
766/* The reelbox patches show the value in the registers represents
767 * ESNO, from 0->30db (values 0->300). We provide this value by
768 * default.
769 */
f11ec7d4 770static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
8953db79
ST
771{
772 struct cx24116_state *state = fe->demodulator_priv;
773
774 dprintk("%s()\n", __func__);
775
776 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
777 cx24116_readreg(state, CX24116_REG_QUALITY0);
778
779 dprintk("%s: raw 0x%04x\n", __func__, *snr);
780
781 return 0;
782}
783
f11ec7d4 784static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
8953db79
ST
785{
786 if (esno_snr == 1)
787 return cx24116_read_snr_esno(fe, snr);
788 else
789 return cx24116_read_snr_pct(fe, snr);
790}
791
f11ec7d4 792static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
0d46748c 793{
490c8684
DB
794 struct cx24116_state *state = fe->demodulator_priv;
795
0d46748c 796 dprintk("%s()\n", __func__);
490c8684 797
f11ec7d4 798 *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
490c8684 799 cx24116_readreg(state, CX24116_REG_UCB0);
0d46748c
ST
800
801 return 0;
802}
803
804/* Overwrite the current tuning params, we are about to tune */
f11ec7d4 805static void cx24116_clone_params(struct dvb_frontend *fe)
0d46748c
ST
806{
807 struct cx24116_state *state = fe->demodulator_priv;
ee45ddc1 808 state->dcur = state->dnxt;
0d46748c
ST
809}
810
490c8684 811/* Wait for LNB */
f11ec7d4 812static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
490c8684
DB
813{
814 struct cx24116_state *state = fe->demodulator_priv;
815 int i;
816
817 dprintk("%s() qstatus = 0x%02x\n", __func__,
818 cx24116_readreg(state, CX24116_REG_QSTATUS));
819
820 /* Wait for up to 300 ms */
f11ec7d4 821 for (i = 0; i < 30 ; i++) {
490c8684
DB
822 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
823 return 0;
824 msleep(10);
825 }
826
827 dprintk("%s(): LNB not ready\n", __func__);
828
829 return -ETIMEDOUT; /* -EBUSY ? */
830}
831
c7bdcd0f 832static int cx24116_set_voltage(struct dvb_frontend *fe,
0df289a2 833 enum fe_sec_voltage voltage)
c7bdcd0f
IL
834{
835 struct cx24116_cmd cmd;
836 int ret;
837
838 dprintk("%s: %s\n", __func__,
839 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
840 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
841
842 /* Wait for LNB ready */
843 ret = cx24116_wait_for_lnb(fe);
844 if (ret != 0)
845 return ret;
846
847 /* Wait for voltage/min repeat delay */
848 msleep(100);
849
850 cmd.args[0x00] = CMD_LNBDCLEVEL;
851 cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
852 cmd.len = 0x02;
853
854 /* Min delay time before DiSEqC send */
855 msleep(15);
856
857 return cx24116_cmd_execute(fe, &cmd);
858}
859
f11ec7d4 860static int cx24116_set_tone(struct dvb_frontend *fe,
0df289a2 861 enum fe_sec_tone_mode tone)
0d46748c
ST
862{
863 struct cx24116_cmd cmd;
864 int ret;
865
866 dprintk("%s(%d)\n", __func__, tone);
f11ec7d4 867 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
98c94823 868 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
0d46748c
ST
869 return -EINVAL;
870 }
871
490c8684
DB
872 /* Wait for LNB ready */
873 ret = cx24116_wait_for_lnb(fe);
f11ec7d4 874 if (ret != 0)
490c8684
DB
875 return ret;
876
877 /* Min delay time after DiSEqC send */
878 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
879
0d46748c
ST
880 /* Now we set the tone */
881 cmd.args[0x00] = CMD_SET_TONE;
882 cmd.args[0x01] = 0x00;
883 cmd.args[0x02] = 0x00;
884
885 switch (tone) {
886 case SEC_TONE_ON:
887 dprintk("%s: setting tone on\n", __func__);
888 cmd.args[0x03] = 0x01;
889 break;
890 case SEC_TONE_OFF:
f11ec7d4 891 dprintk("%s: setting tone off\n", __func__);
0d46748c
ST
892 cmd.args[0x03] = 0x00;
893 break;
894 }
f11ec7d4 895 cmd.len = 0x04;
0d46748c 896
490c8684
DB
897 /* Min delay time before DiSEqC send */
898 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
899
0d46748c
ST
900 return cx24116_cmd_execute(fe, &cmd);
901}
902
903/* Initialise DiSEqC */
f11ec7d4 904static int cx24116_diseqc_init(struct dvb_frontend *fe)
0d46748c
ST
905{
906 struct cx24116_state *state = fe->demodulator_priv;
490c8684
DB
907 struct cx24116_cmd cmd;
908 int ret;
909
910 /* Firmware CMD 20: LNB/DiSEqC config */
911 cmd.args[0x00] = CMD_LNBCONFIG;
912 cmd.args[0x01] = 0x00;
913 cmd.args[0x02] = 0x10;
914 cmd.args[0x03] = 0x00;
915 cmd.args[0x04] = 0x8f;
916 cmd.args[0x05] = 0x28;
917 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
918 cmd.args[0x07] = 0x01;
f11ec7d4 919 cmd.len = 0x08;
490c8684
DB
920 ret = cx24116_cmd_execute(fe, &cmd);
921 if (ret != 0)
922 return ret;
923
924 /* Prepare a DiSEqC command */
925 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
926
927 /* DiSEqC burst */
928 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
929
930 /* Unknown */
931 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
932 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
98c94823
ST
933 /* Continuation flag? */
934 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
0d46748c 935
490c8684
DB
936 /* DiSEqC message length */
937 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
938
939 /* Command length */
f11ec7d4 940 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
0d46748c
ST
941
942 return 0;
943}
944
945/* Send DiSEqC message with derived burst (hack) || previous burst */
f11ec7d4
ST
946static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
947 struct dvb_diseqc_master_cmd *d)
0d46748c
ST
948{
949 struct cx24116_state *state = fe->demodulator_priv;
0d46748c
ST
950 int i, ret;
951
1fa2337a
MCC
952 /* Validate length */
953 if (d->msg_len > sizeof(d->msg))
4a3fad70 954 return -EINVAL;
1fa2337a 955
0d46748c
ST
956 /* Dump DiSEqC message */
957 if (debug) {
98c94823 958 printk(KERN_INFO "cx24116: %s(", __func__);
f11ec7d4 959 for (i = 0 ; i < d->msg_len ;) {
98c94823 960 printk(KERN_INFO "0x%02x", d->msg[i]);
f11ec7d4 961 if (++i < d->msg_len)
98c94823 962 printk(KERN_INFO ", ");
f11ec7d4 963 }
490c8684 964 printk(") toneburst=%d\n", toneburst);
0d46748c
ST
965 }
966
0d46748c
ST
967 /* DiSEqC message */
968 for (i = 0; i < d->msg_len; i++)
490c8684
DB
969 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
970
971 /* DiSEqC message length */
972 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
973
974 /* Command length */
f11ec7d4
ST
975 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
976 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
490c8684
DB
977
978 /* DiSEqC toneburst */
f11ec7d4 979 if (toneburst == CX24116_DISEQC_MESGCACHE)
490c8684
DB
980 /* Message is cached */
981 return 0;
982
f11ec7d4 983 else if (toneburst == CX24116_DISEQC_TONEOFF)
490c8684
DB
984 /* Message is sent without burst */
985 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
986
f11ec7d4 987 else if (toneburst == CX24116_DISEQC_TONECACHE) {
490c8684
DB
988 /*
989 * Message is sent with derived else cached burst
990 *
991 * WRITE PORT GROUP COMMAND 38
992 *
993 * 0/A/A: E0 10 38 F0..F3
994 * 1/B/B: E0 10 38 F4..F7
995 * 2/C/A: E0 10 38 F8..FB
996 * 3/D/B: E0 10 38 FC..FF
997 *
7396d3ea 998 * databyte[3]= 8421:8421
490c8684
DB
999 * ABCD:WXYZ
1000 * CLR :SET
1001 *
1002 * WX= PORT SELECT 0..3 (X=TONEBURST)
1003 * Y = VOLTAGE (0=13V, 1=18V)
1004 * Z = BAND (0=LOW, 1=HIGH(22K))
1005 */
f11ec7d4
ST
1006 if (d->msg_len >= 4 && d->msg[2] == 0x38)
1007 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1008 ((d->msg[3] & 4) >> 2);
1009 if (debug)
1010 dprintk("%s burst=%d\n", __func__,
1011 state->dsec_cmd.args[CX24116_DISEQC_BURST]);
490c8684 1012 }
0d46748c 1013
490c8684
DB
1014 /* Wait for LNB ready */
1015 ret = cx24116_wait_for_lnb(fe);
f11ec7d4 1016 if (ret != 0)
490c8684 1017 return ret;
0d46748c 1018
490c8684
DB
1019 /* Wait for voltage/min repeat delay */
1020 msleep(100);
0d46748c 1021
490c8684
DB
1022 /* Command */
1023 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
f11ec7d4 1024 if (ret != 0)
490c8684
DB
1025 return ret;
1026 /*
1027 * Wait for send
0d46748c
ST
1028 *
1029 * Eutelsat spec:
490c8684
DB
1030 * >15ms delay + (XXX determine if FW does this, see set_tone)
1031 * 13.5ms per byte +
1032 * >15ms delay +
1033 * 12.5ms burst +
1034 * >15ms delay (XXX determine if FW does this, see set_tone)
0d46748c 1035 */
f11ec7d4
ST
1036 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1037 ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
0d46748c 1038
490c8684 1039 return 0;
0d46748c
ST
1040}
1041
1042/* Send DiSEqC burst */
f11ec7d4 1043static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
0df289a2 1044 enum fe_sec_mini_cmd burst)
0d46748c
ST
1045{
1046 struct cx24116_state *state = fe->demodulator_priv;
0d46748c
ST
1047 int ret;
1048
f11ec7d4 1049 dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
0d46748c 1050
490c8684 1051 /* DiSEqC burst */
0d46748c 1052 if (burst == SEC_MINI_A)
f11ec7d4
ST
1053 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1054 CX24116_DISEQC_MINI_A;
1055 else if (burst == SEC_MINI_B)
1056 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1057 CX24116_DISEQC_MINI_B;
0d46748c
ST
1058 else
1059 return -EINVAL;
1060
490c8684 1061 /* DiSEqC toneburst */
f11ec7d4 1062 if (toneburst != CX24116_DISEQC_MESGCACHE)
490c8684
DB
1063 /* Burst is cached */
1064 return 0;
0d46748c 1065
490c8684 1066 /* Burst is to be sent with cached message */
0d46748c 1067
490c8684
DB
1068 /* Wait for LNB ready */
1069 ret = cx24116_wait_for_lnb(fe);
f11ec7d4 1070 if (ret != 0)
490c8684 1071 return ret;
0d46748c 1072
490c8684
DB
1073 /* Wait for voltage/min repeat delay */
1074 msleep(100);
0d46748c 1075
490c8684
DB
1076 /* Command */
1077 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
f11ec7d4 1078 if (ret != 0)
490c8684
DB
1079 return ret;
1080
1081 /*
1082 * Wait for send
1083 *
1084 * Eutelsat spec:
1085 * >15ms delay + (XXX determine if FW does this, see set_tone)
1086 * 13.5ms per byte +
1087 * >15ms delay +
1088 * 12.5ms burst +
1089 * >15ms delay (XXX determine if FW does this, see set_tone)
1090 */
f11ec7d4 1091 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
490c8684
DB
1092
1093 return 0;
0d46748c
ST
1094}
1095
f11ec7d4 1096static void cx24116_release(struct dvb_frontend *fe)
0d46748c 1097{
f11ec7d4
ST
1098 struct cx24116_state *state = fe->demodulator_priv;
1099 dprintk("%s\n", __func__);
0d46748c
ST
1100 kfree(state);
1101}
1102
bd336e63 1103static const struct dvb_frontend_ops cx24116_ops;
0d46748c 1104
f11ec7d4
ST
1105struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1106 struct i2c_adapter *i2c)
0d46748c 1107{
d303b7c5 1108 struct cx24116_state *state;
0d46748c
ST
1109 int ret;
1110
f11ec7d4 1111 dprintk("%s\n", __func__);
0d46748c
ST
1112
1113 /* allocate memory for the internal state */
2d3da59f 1114 state = kzalloc(sizeof(*state), GFP_KERNEL);
98c94823 1115 if (state == NULL)
9722e569 1116 return NULL;
0d46748c 1117
0d46748c
ST
1118 state->config = config;
1119 state->i2c = i2c;
1120
1121 /* check if the demod is present */
98c94823
ST
1122 ret = (cx24116_readreg(state, 0xFF) << 8) |
1123 cx24116_readreg(state, 0xFE);
0d46748c 1124 if (ret != 0x0501) {
9722e569 1125 kfree(state);
98c94823 1126 printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
9722e569 1127 return NULL;
0d46748c
ST
1128 }
1129
1130 /* create dvb_frontend */
98c94823
ST
1131 memcpy(&state->frontend.ops, &cx24116_ops,
1132 sizeof(struct dvb_frontend_ops));
0d46748c
ST
1133 state->frontend.demodulator_priv = state;
1134 return &state->frontend;
0d46748c 1135}
f11ec7d4
ST
1136EXPORT_SYMBOL(cx24116_attach);
1137
490c8684
DB
1138/*
1139 * Initialise or wake up device
1140 *
1141 * Power config will reset and load initial firmware if required
1142 */
f11ec7d4 1143static int cx24116_initfe(struct dvb_frontend *fe)
0d46748c 1144{
f11ec7d4 1145 struct cx24116_state *state = fe->demodulator_priv;
490c8684
DB
1146 struct cx24116_cmd cmd;
1147 int ret;
0d46748c 1148
f11ec7d4 1149 dprintk("%s()\n", __func__);
0d46748c 1150
490c8684
DB
1151 /* Power on */
1152 cx24116_writereg(state, 0xe0, 0);
1153 cx24116_writereg(state, 0xe1, 0);
1154 cx24116_writereg(state, 0xea, 0);
0d46748c 1155
490c8684
DB
1156 /* Firmware CMD 36: Power config */
1157 cmd.args[0x00] = CMD_TUNERSLEEP;
1158 cmd.args[0x01] = 0;
f11ec7d4 1159 cmd.len = 0x02;
490c8684 1160 ret = cx24116_cmd_execute(fe, &cmd);
f11ec7d4 1161 if (ret != 0)
490c8684
DB
1162 return ret;
1163
8afe6ad6
IL
1164 ret = cx24116_diseqc_init(fe);
1165 if (ret != 0)
1166 return ret;
1167
1168 /* HVR-4000 needs this */
1169 return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
0d46748c
ST
1170}
1171
490c8684
DB
1172/*
1173 * Put device to sleep
1174 */
f11ec7d4 1175static int cx24116_sleep(struct dvb_frontend *fe)
0d46748c 1176{
f11ec7d4 1177 struct cx24116_state *state = fe->demodulator_priv;
490c8684
DB
1178 struct cx24116_cmd cmd;
1179 int ret;
1180
f11ec7d4 1181 dprintk("%s()\n", __func__);
0d46748c 1182
490c8684
DB
1183 /* Firmware CMD 36: Power config */
1184 cmd.args[0x00] = CMD_TUNERSLEEP;
1185 cmd.args[0x01] = 1;
f11ec7d4 1186 cmd.len = 0x02;
490c8684 1187 ret = cx24116_cmd_execute(fe, &cmd);
f11ec7d4 1188 if (ret != 0)
490c8684
DB
1189 return ret;
1190
1191 /* Power off (Shutdown clocks) */
1192 cx24116_writereg(state, 0xea, 0xff);
1193 cx24116_writereg(state, 0xe1, 1);
1194 cx24116_writereg(state, 0xe0, 1);
1195
1196 return 0;
0d46748c
ST
1197}
1198
0d46748c
ST
1199/* dvb-core told us to tune, the tv property cache will be complete,
1200 * it's safe for is to pull values and use them for tuning purposes.
1201 */
1ac6a854 1202static int cx24116_set_frontend(struct dvb_frontend *fe)
0d46748c
ST
1203{
1204 struct cx24116_state *state = fe->demodulator_priv;
56f0680a 1205 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0d46748c 1206 struct cx24116_cmd cmd;
0df289a2 1207 enum fe_status tunerstat;
2fd93396 1208 int i, status, ret, retune = 1;
0d46748c 1209
f11ec7d4 1210 dprintk("%s()\n", __func__);
0d46748c 1211
f11ec7d4
ST
1212 switch (c->delivery_system) {
1213 case SYS_DVBS:
1214 dprintk("%s: DVB-S delivery system selected\n", __func__);
01a8f038 1215
f11ec7d4
ST
1216 /* Only QPSK is supported for DVB-S */
1217 if (c->modulation != QPSK) {
1218 dprintk("%s: unsupported modulation selected (%d)\n",
1219 __func__, c->modulation);
1220 return -EOPNOTSUPP;
1221 }
01a8f038 1222
f11ec7d4
ST
1223 /* Pilot doesn't exist in DVB-S, turn bit off */
1224 state->dnxt.pilot_val = CX24116_PILOT_OFF;
01a8f038 1225
f11ec7d4
ST
1226 /* DVB-S only supports 0.35 */
1227 if (c->rolloff != ROLLOFF_35) {
1228 dprintk("%s: unsupported rolloff selected (%d)\n",
1229 __func__, c->rolloff);
1230 return -EOPNOTSUPP;
1231 }
1232 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1233 break;
01a8f038 1234
f11ec7d4
ST
1235 case SYS_DVBS2:
1236 dprintk("%s: DVB-S2 delivery system selected\n", __func__);
01a8f038 1237
f11ec7d4
ST
1238 /*
1239 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1240 * but not hardware auto detection
1241 */
1242 if (c->modulation != PSK_8 && c->modulation != QPSK) {
1243 dprintk("%s: unsupported modulation selected (%d)\n",
1244 __func__, c->modulation);
1245 return -EOPNOTSUPP;
1246 }
01a8f038 1247
f11ec7d4
ST
1248 switch (c->pilot) {
1249 case PILOT_AUTO: /* Not supported but emulated */
74563214
CT
1250 state->dnxt.pilot_val = (c->modulation == QPSK)
1251 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
2fd93396 1252 retune++;
74563214 1253 break;
f11ec7d4
ST
1254 case PILOT_OFF:
1255 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1256 break;
1257 case PILOT_ON:
1258 state->dnxt.pilot_val = CX24116_PILOT_ON;
490c8684 1259 break;
f11ec7d4
ST
1260 default:
1261 dprintk("%s: unsupported pilot mode selected (%d)\n",
1262 __func__, c->pilot);
1263 return -EOPNOTSUPP;
1264 }
01a8f038 1265
f11ec7d4
ST
1266 switch (c->rolloff) {
1267 case ROLLOFF_20:
1268 state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1269 break;
1270 case ROLLOFF_25:
1271 state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1272 break;
1273 case ROLLOFF_35:
1274 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1275 break;
1276 case ROLLOFF_AUTO: /* Rolloff must be explicit */
490c8684 1277 default:
f11ec7d4
ST
1278 dprintk("%s: unsupported rolloff selected (%d)\n",
1279 __func__, c->rolloff);
490c8684 1280 return -EOPNOTSUPP;
f11ec7d4
ST
1281 }
1282 break;
1283
1284 default:
1285 dprintk("%s: unsupported delivery system selected (%d)\n",
1286 __func__, c->delivery_system);
1287 return -EOPNOTSUPP;
490c8684 1288 }
3569476d 1289 state->dnxt.delsys = c->delivery_system;
01a8f038
DB
1290 state->dnxt.modulation = c->modulation;
1291 state->dnxt.frequency = c->frequency;
1292 state->dnxt.pilot = c->pilot;
1293 state->dnxt.rolloff = c->rolloff;
490c8684 1294
f11ec7d4
ST
1295 ret = cx24116_set_inversion(state, c->inversion);
1296 if (ret != 0)
0d46748c
ST
1297 return ret;
1298
01a8f038 1299 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
3569476d 1300 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
f11ec7d4 1301 if (ret != 0)
0d46748c
ST
1302 return ret;
1303
f11ec7d4
ST
1304 ret = cx24116_set_symbolrate(state, c->symbol_rate);
1305 if (ret != 0)
0d46748c
ST
1306 return ret;
1307
1308 /* discard the 'current' tuning parameters and prepare to tune */
1309 cx24116_clone_params(fe);
1310
3569476d 1311 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
01a8f038 1312 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
0d46748c 1313 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
01a8f038
DB
1314 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1315 state->dcur.pilot, state->dcur.pilot_val);
1316 dprintk("%s: retune = %d\n", __func__, retune);
1317 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1318 state->dcur.rolloff, state->dcur.rolloff_val);
0d46748c
ST
1319 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1320 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1321 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1322 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1323 state->dcur.inversion, state->dcur.inversion_val);
1324
490c8684 1325 /* This is also done in advise/acquire on HVR4000 but not on LITE */
0d46748c
ST
1326 if (state->config->set_ts_params)
1327 state->config->set_ts_params(fe, 0);
1328
490c8684
DB
1329 /* Set/Reset B/W */
1330 cmd.args[0x00] = CMD_BANDWIDTH;
1331 cmd.args[0x01] = 0x01;
f11ec7d4 1332 cmd.len = 0x02;
490c8684
DB
1333 ret = cx24116_cmd_execute(fe, &cmd);
1334 if (ret != 0)
1335 return ret;
3f8e51ad 1336
0d46748c
ST
1337 /* Prepare a tune request */
1338 cmd.args[0x00] = CMD_TUNEREQUEST;
1339
1340 /* Frequency */
1341 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1342 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1343 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1344
1345 /* Symbol Rate */
1346 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1347 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1348
1349 /* Automatic Inversion */
1350 cmd.args[0x06] = state->dcur.inversion_val;
1351
01a8f038
DB
1352 /* Modulation / FEC / Pilot */
1353 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
0d46748c
ST
1354
1355 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1356 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1357 cmd.args[0x0a] = 0x00;
1358 cmd.args[0x0b] = 0x00;
490c8684 1359 cmd.args[0x0c] = state->dcur.rolloff_val;
0d46748c 1360 cmd.args[0x0d] = state->dcur.fec_mask;
3f8e51ad 1361
490c8684 1362 if (state->dcur.symbol_rate > 30000000) {
3f8e51ad
IL
1363 cmd.args[0x0e] = 0x04;
1364 cmd.args[0x0f] = 0x00;
1365 cmd.args[0x10] = 0x01;
1366 cmd.args[0x11] = 0x77;
1367 cmd.args[0x12] = 0x36;
490c8684
DB
1368 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1369 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
3f8e51ad
IL
1370 } else {
1371 cmd.args[0x0e] = 0x06;
1372 cmd.args[0x0f] = 0x00;
1373 cmd.args[0x10] = 0x00;
1374 cmd.args[0x11] = 0xFA;
1375 cmd.args[0x12] = 0x24;
490c8684
DB
1376 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1377 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
3f8e51ad
IL
1378 }
1379
f11ec7d4 1380 cmd.len = 0x13;
0d46748c
ST
1381
1382 /* We need to support pilot and non-pilot tuning in the
1383 * driver automatically. This is a workaround for because
1384 * the demod does not support autodetect.
1385 */
1386 do {
490c8684 1387 /* Reset status register */
f11ec7d4
ST
1388 status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1389 & CX24116_SIGNAL_MASK;
490c8684 1390 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
0d46748c
ST
1391
1392 /* Tune */
1393 ret = cx24116_cmd_execute(fe, &cmd);
f11ec7d4 1394 if (ret != 0)
0d46748c
ST
1395 break;
1396
490c8684
DB
1397 /*
1398 * Wait for up to 500 ms before retrying
1399 *
1400 * If we are able to tune then generally it occurs within 100ms.
1401 * If it takes longer, try a different toneburst setting.
1402 */
f11ec7d4 1403 for (i = 0; i < 50 ; i++) {
490c8684
DB
1404 cx24116_read_status(fe, &tunerstat);
1405 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
f11ec7d4
ST
1406 if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1407 dprintk("%s: Tuned\n", __func__);
490c8684
DB
1408 goto tuned;
1409 }
1410 msleep(10);
0d46748c 1411 }
490c8684 1412
f11ec7d4 1413 dprintk("%s: Not tuned\n", __func__);
490c8684
DB
1414
1415 /* Toggle pilot bit when in auto-pilot */
f11ec7d4 1416 if (state->dcur.pilot == PILOT_AUTO)
01a8f038 1417 cmd.args[0x07] ^= CX24116_PILOT_ON;
f11ec7d4 1418 } while (--retune);
0d46748c 1419
490c8684
DB
1420tuned: /* Set/Reset B/W */
1421 cmd.args[0x00] = CMD_BANDWIDTH;
1422 cmd.args[0x01] = 0x00;
f11ec7d4 1423 cmd.len = 0x02;
3735edf9 1424 return cx24116_cmd_execute(fe, &cmd);
0d46748c
ST
1425}
1426
7e072221 1427static int cx24116_tune(struct dvb_frontend *fe, bool re_tune,
0df289a2 1428 unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
6639f1e0 1429{
1ac6a854
MCC
1430 /*
1431 * It is safe to discard "params" here, as the DVB core will sync
1432 * fe->dtv_property_cache with fepriv->parameters_in, where the
1433 * DVBv3 params are stored. The only practical usage for it indicate
1434 * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is
1435 * true.
1436 */
1437
6639f1e0 1438 *delay = HZ / 5;
7e072221 1439 if (re_tune) {
1ac6a854 1440 int ret = cx24116_set_frontend(fe);
6639f1e0
DB
1441 if (ret)
1442 return ret;
1443 }
1444 return cx24116_read_status(fe, status);
1445}
1446
8d718e53 1447static enum dvbfe_algo cx24116_get_algo(struct dvb_frontend *fe)
6639f1e0
DB
1448{
1449 return DVBFE_ALGO_HW;
1450}
1451
bd336e63 1452static const struct dvb_frontend_ops cx24116_ops = {
1ac6a854 1453 .delsys = { SYS_DVBS, SYS_DVBS2 },
0d46748c
ST
1454 .info = {
1455 .name = "Conexant CX24116/CX24118",
f1b1eabf
MCC
1456 .frequency_min_hz = 950 * MHz,
1457 .frequency_max_hz = 2150 * MHz,
1458 .frequency_stepsize_hz = 1011 * kHz,
1459 .frequency_tolerance_hz = 5 * MHz,
0d46748c
ST
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 |
faed4aa5 1466 FE_CAN_2G_MODULATION |
0d46748c
ST
1467 FE_CAN_QPSK | FE_CAN_RECOVER
1468 },
1469
1470 .release = cx24116_release,
1471
1472 .init = cx24116_initfe,
490c8684 1473 .sleep = cx24116_sleep,
0d46748c
ST
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,
6639f1e0
DB
1483 .get_frontend_algo = cx24116_get_algo,
1484 .tune = cx24116_tune,
0d46748c 1485
1ac6a854 1486 .set_frontend = cx24116_set_frontend,
0d46748c
ST
1487};
1488
0d46748c
ST
1489MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1490MODULE_AUTHOR("Steven Toth");
1491MODULE_LICENSE("GPL");
1492