Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/frontends/cx24116.c
15112 views
1
/*
2
Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4
Copyright (C) 2006-2008 Steven Toth <[email protected]>
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.
21
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.
26
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.
31
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.
35
*/
36
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>
43
44
#include "dvb_frontend.h"
45
#include "cx24116.h"
46
47
static int debug;
48
module_param(debug, int, 0644);
49
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
50
51
#define dprintk(args...) \
52
do { \
53
if (debug) \
54
printk(KERN_INFO "cx24116: " args); \
55
} while (0)
56
57
#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
58
#define CX24116_SEARCH_RANGE_KHZ 5000
59
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)
78
79
/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
80
#define CX24116_REG_FECSTATUS (0x9c)
81
82
/* FECSTATUS bits */
83
/* mask to determine configured fec (not tuned) or actual fec (tuned) */
84
#define CX24116_FEC_FECMASK (0x1f)
85
86
/* Select DVB-S demodulator, else DVB-S2 */
87
#define CX24116_FEC_DVBS (0x20)
88
#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
89
90
/* Pilot mode requested when tuning else always reset when tuned */
91
#define CX24116_FEC_PILOT (0x80)
92
93
/* arg buffer size */
94
#define CX24116_ARGLEN (0x1e)
95
96
/* rolloff */
97
#define CX24116_ROLLOFF_020 (0x00)
98
#define CX24116_ROLLOFF_025 (0x01)
99
#define CX24116_ROLLOFF_035 (0x02)
100
101
/* pilot bit */
102
#define CX24116_PILOT_OFF (0x00)
103
#define CX24116_PILOT_ON (0x40)
104
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)
114
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 */
118
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)
126
127
/* DiSEqC burst */
128
#define CX24116_DISEQC_MINI_A (0)
129
#define CX24116_DISEQC_MINI_B (1)
130
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)");
136
137
/* SNR measurements */
138
static int esno_snr;
139
module_param(esno_snr, int, 0644);
140
MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
141
"1=ESNO(db * 10) (default:0)");
142
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 */
157
};
158
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;
165
166
fe_delivery_system_t delsys;
167
fe_modulation_t modulation;
168
fe_pilot_t pilot;
169
fe_rolloff_t rolloff;
170
171
/* Demod values */
172
u8 fec_val;
173
u8 fec_mask;
174
u8 inversion_val;
175
u8 pilot_val;
176
u8 rolloff_val;
177
};
178
179
/* Basic commands that are sent to the firmware */
180
struct cx24116_cmd {
181
u8 len;
182
u8 args[CX24116_ARGLEN];
183
};
184
185
struct cx24116_state {
186
struct i2c_adapter *i2c;
187
const struct cx24116_config *config;
188
189
struct dvb_frontend frontend;
190
191
struct cx24116_tuning dcur;
192
struct cx24116_tuning dnxt;
193
194
u8 skip_fw_load;
195
u8 burst;
196
struct cx24116_cmd dsec_cmd;
197
};
198
199
static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
200
{
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;
205
206
if (debug > 1)
207
printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
208
__func__, reg, data);
209
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;
215
}
216
217
return 0;
218
}
219
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)
223
{
224
int ret = -EREMOTEIO;
225
struct i2c_msg msg;
226
u8 *buf;
227
228
buf = kmalloc(len + 1, GFP_KERNEL);
229
if (buf == NULL) {
230
printk("Unable to kmalloc\n");
231
ret = -ENOMEM;
232
goto error;
233
}
234
235
*(buf) = reg;
236
memcpy(buf + 1, data, len);
237
238
msg.addr = state->config->demod_address;
239
msg.flags = 0;
240
msg.buf = buf;
241
msg.len = len + 1;
242
243
if (debug > 1)
244
printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
245
__func__, reg, len);
246
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;
252
}
253
254
error:
255
kfree(buf);
256
257
return ret;
258
}
259
260
static int cx24116_readreg(struct cx24116_state *state, u8 reg)
261
{
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 }
270
};
271
272
ret = i2c_transfer(state->i2c, msg, 2);
273
274
if (ret != 2) {
275
printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
276
__func__, reg, ret);
277
return ret;
278
}
279
280
if (debug > 1)
281
printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
282
reg, b1[0]);
283
284
return b1[0];
285
}
286
287
static int cx24116_set_inversion(struct cx24116_state *state,
288
fe_spectral_inversion_t inversion)
289
{
290
dprintk("%s(%d)\n", __func__, inversion);
291
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;
304
}
305
306
state->dnxt.inversion = inversion;
307
308
return 0;
309
}
310
311
/*
312
* modfec (modulation and FEC)
313
* ===========================
314
*
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
326
*
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).
332
*
333
* Eg.(2/3) szap "Zone Horror"
334
*
335
* mask/val = 0x04, 0x20
336
* status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
337
*
338
* mask/val = 0x04, 0x30
339
* status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
340
*
341
* After tuning FECSTATUS contains actual FEC
342
* in use numbered 1 through to 8 for 1/2 .. 2/3 etc
343
*
344
* NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
345
*
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
354
*
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
361
*
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.
369
*/
370
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.
374
*/
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 */
383
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 },
411
/*
412
* `val' can be found in the FECSTATUS register when tuning.
413
* FECSTATUS will give the actual FEC in use if tuning was successful.
414
*/
415
};
416
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)
419
{
420
int i, ret = -EOPNOTSUPP;
421
422
dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
423
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;
430
}
431
}
432
433
return ret;
434
}
435
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)
438
{
439
int ret = 0;
440
441
dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
442
443
ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
444
445
if (ret < 0)
446
return ret;
447
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);
453
454
return 0;
455
}
456
457
static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
458
{
459
dprintk("%s(%d)\n", __func__, rate);
460
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;
466
}
467
468
state->dnxt.symbol_rate = rate;
469
dprintk("%s() symbol_rate = %d\n", __func__, rate);
470
471
return 0;
472
}
473
474
static int cx24116_load_firmware(struct dvb_frontend *fe,
475
const struct firmware *fw);
476
477
static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
478
{
479
struct cx24116_state *state = fe->demodulator_priv;
480
const struct firmware *fw;
481
int ret = 0;
482
483
dprintk("%s()\n", __func__);
484
485
if (cx24116_readreg(state, 0x20) > 0) {
486
487
if (state->skip_fw_load)
488
return 0;
489
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;
502
}
503
504
/* Make sure we don't recurse back through here
505
* during loading */
506
state->skip_fw_load = 1;
507
508
ret = cx24116_load_firmware(fe, fw);
509
if (ret)
510
printk(KERN_ERR "%s: Writing firmware to device failed\n",
511
__func__);
512
513
release_firmware(fw);
514
515
printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
516
ret == 0 ? "complete" : "failed");
517
518
/* Ensure firmware is always loaded if required */
519
state->skip_fw_load = 0;
520
}
521
522
return ret;
523
}
524
525
/* Take a basic firmware command structure, format it
526
* and forward it for processing
527
*/
528
static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
529
{
530
struct cx24116_state *state = fe->demodulator_priv;
531
int i, ret;
532
533
dprintk("%s()\n", __func__);
534
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;
541
}
542
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]);
547
}
548
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;
559
}
560
}
561
return 0;
562
}
563
564
static int cx24116_load_firmware(struct dvb_frontend *fe,
565
const struct firmware *fw)
566
{
567
struct cx24116_state *state = fe->demodulator_priv;
568
struct cx24116_cmd cmd;
569
int i, ret, len, max, remaining;
570
unsigned char vers[4];
571
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]);
579
580
/* Toggle 88x SRST pin to reset demod */
581
if (state->config->reset_device)
582
state->config->reset_device(fe);
583
584
/* Begin the firmware load process */
585
/* Prepare the demod, load the firmware, cleanup after load */
586
587
/* Init PLL */
588
cx24116_writereg(state, 0xE5, 0x00);
589
cx24116_writereg(state, 0xF1, 0x08);
590
cx24116_writereg(state, 0xF2, 0x13);
591
592
/* Start PLL */
593
cx24116_writereg(state, 0xe0, 0x03);
594
cx24116_writereg(state, 0xe0, 0x00);
595
596
/* Unknown */
597
cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
598
cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
599
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);
605
606
/* Split firmware to the max I2C write len and write.
607
* Writes whole firmware as one write when i2c_wr_max is set to 0. */
608
if (state->config->i2c_wr_max)
609
max = state->config->i2c_wr_max;
610
else
611
max = INT_MAX; /* enough for 32k firmware */
612
613
for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
614
len = remaining;
615
if (len > max - 1)
616
len = max - 1;
617
618
cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
619
len);
620
}
621
622
cx24116_writereg(state, 0xF4, 0x10);
623
cx24116_writereg(state, 0xF0, 0x00);
624
cx24116_writereg(state, 0xF8, 0x06);
625
626
/* Firmware CMD 10: VCO config */
627
cmd.args[0x00] = CMD_SET_VCO;
628
cmd.args[0x01] = 0x05;
629
cmd.args[0x02] = 0xdc;
630
cmd.args[0x03] = 0xda;
631
cmd.args[0x04] = 0xae;
632
cmd.args[0x05] = 0xaa;
633
cmd.args[0x06] = 0x04;
634
cmd.args[0x07] = 0x9d;
635
cmd.args[0x08] = 0xfc;
636
cmd.args[0x09] = 0x06;
637
cmd.len = 0x0a;
638
ret = cx24116_cmd_execute(fe, &cmd);
639
if (ret != 0)
640
return ret;
641
642
cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
643
644
/* Firmware CMD 14: Tuner config */
645
cmd.args[0x00] = CMD_TUNERINIT;
646
cmd.args[0x01] = 0x00;
647
cmd.args[0x02] = 0x00;
648
cmd.len = 0x03;
649
ret = cx24116_cmd_execute(fe, &cmd);
650
if (ret != 0)
651
return ret;
652
653
cx24116_writereg(state, 0xe5, 0x00);
654
655
/* Firmware CMD 13: MPEG config */
656
cmd.args[0x00] = CMD_MPEGCONFIG;
657
cmd.args[0x01] = 0x01;
658
cmd.args[0x02] = 0x75;
659
cmd.args[0x03] = 0x00;
660
if (state->config->mpg_clk_pos_pol)
661
cmd.args[0x04] = state->config->mpg_clk_pos_pol;
662
else
663
cmd.args[0x04] = 0x02;
664
cmd.args[0x05] = 0x00;
665
cmd.len = 0x06;
666
ret = cx24116_cmd_execute(fe, &cmd);
667
if (ret != 0)
668
return ret;
669
670
/* Firmware CMD 35: Get firmware version */
671
cmd.args[0x00] = CMD_UPDFWVERS;
672
cmd.len = 0x02;
673
for (i = 0; i < 4; i++) {
674
cmd.args[0x01] = i;
675
ret = cx24116_cmd_execute(fe, &cmd);
676
if (ret != 0)
677
return ret;
678
vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
679
}
680
printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
681
vers[0], vers[1], vers[2], vers[3]);
682
683
return 0;
684
}
685
686
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
687
{
688
struct cx24116_state *state = fe->demodulator_priv;
689
690
int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
691
CX24116_STATUS_MASK;
692
693
dprintk("%s: status = 0x%02x\n", __func__, lock);
694
695
*status = 0;
696
697
if (lock & CX24116_HAS_SIGNAL)
698
*status |= FE_HAS_SIGNAL;
699
if (lock & CX24116_HAS_CARRIER)
700
*status |= FE_HAS_CARRIER;
701
if (lock & CX24116_HAS_VITERBI)
702
*status |= FE_HAS_VITERBI;
703
if (lock & CX24116_HAS_SYNCLOCK)
704
*status |= FE_HAS_SYNC | FE_HAS_LOCK;
705
706
return 0;
707
}
708
709
static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
710
{
711
struct cx24116_state *state = fe->demodulator_priv;
712
713
dprintk("%s()\n", __func__);
714
715
*ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
716
(cx24116_readreg(state, CX24116_REG_BER16) << 16) |
717
(cx24116_readreg(state, CX24116_REG_BER8) << 8) |
718
cx24116_readreg(state, CX24116_REG_BER0);
719
720
return 0;
721
}
722
723
/* TODO Determine function and scale appropriately */
724
static int cx24116_read_signal_strength(struct dvb_frontend *fe,
725
u16 *signal_strength)
726
{
727
struct cx24116_state *state = fe->demodulator_priv;
728
struct cx24116_cmd cmd;
729
int ret;
730
u16 sig_reading;
731
732
dprintk("%s()\n", __func__);
733
734
/* Firmware CMD 19: Get AGC */
735
cmd.args[0x00] = CMD_GETAGC;
736
cmd.len = 0x01;
737
ret = cx24116_cmd_execute(fe, &cmd);
738
if (ret != 0)
739
return ret;
740
741
sig_reading =
742
(cx24116_readreg(state,
743
CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
744
(cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
745
*signal_strength = 0 - sig_reading;
746
747
dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
748
__func__, sig_reading, *signal_strength);
749
750
return 0;
751
}
752
753
/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
754
static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
755
{
756
struct cx24116_state *state = fe->demodulator_priv;
757
u8 snr_reading;
758
static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
759
0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
760
0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
761
0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
762
0x18000 };
763
764
dprintk("%s()\n", __func__);
765
766
snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
767
768
if (snr_reading >= 0xa0 /* 100% */)
769
*snr = 0xffff;
770
else
771
*snr = snr_tab[(snr_reading & 0xf0) >> 4] +
772
(snr_tab[(snr_reading & 0x0f)] >> 4);
773
774
dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
775
snr_reading, *snr);
776
777
return 0;
778
}
779
780
/* The reelbox patches show the value in the registers represents
781
* ESNO, from 0->30db (values 0->300). We provide this value by
782
* default.
783
*/
784
static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
785
{
786
struct cx24116_state *state = fe->demodulator_priv;
787
788
dprintk("%s()\n", __func__);
789
790
*snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
791
cx24116_readreg(state, CX24116_REG_QUALITY0);
792
793
dprintk("%s: raw 0x%04x\n", __func__, *snr);
794
795
return 0;
796
}
797
798
static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
799
{
800
if (esno_snr == 1)
801
return cx24116_read_snr_esno(fe, snr);
802
else
803
return cx24116_read_snr_pct(fe, snr);
804
}
805
806
static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
807
{
808
struct cx24116_state *state = fe->demodulator_priv;
809
810
dprintk("%s()\n", __func__);
811
812
*ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
813
cx24116_readreg(state, CX24116_REG_UCB0);
814
815
return 0;
816
}
817
818
/* Overwrite the current tuning params, we are about to tune */
819
static void cx24116_clone_params(struct dvb_frontend *fe)
820
{
821
struct cx24116_state *state = fe->demodulator_priv;
822
memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
823
}
824
825
/* Wait for LNB */
826
static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
827
{
828
struct cx24116_state *state = fe->demodulator_priv;
829
int i;
830
831
dprintk("%s() qstatus = 0x%02x\n", __func__,
832
cx24116_readreg(state, CX24116_REG_QSTATUS));
833
834
/* Wait for up to 300 ms */
835
for (i = 0; i < 30 ; i++) {
836
if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
837
return 0;
838
msleep(10);
839
}
840
841
dprintk("%s(): LNB not ready\n", __func__);
842
843
return -ETIMEDOUT; /* -EBUSY ? */
844
}
845
846
static int cx24116_set_voltage(struct dvb_frontend *fe,
847
fe_sec_voltage_t voltage)
848
{
849
struct cx24116_cmd cmd;
850
int ret;
851
852
dprintk("%s: %s\n", __func__,
853
voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
854
voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
855
856
/* Wait for LNB ready */
857
ret = cx24116_wait_for_lnb(fe);
858
if (ret != 0)
859
return ret;
860
861
/* Wait for voltage/min repeat delay */
862
msleep(100);
863
864
cmd.args[0x00] = CMD_LNBDCLEVEL;
865
cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
866
cmd.len = 0x02;
867
868
/* Min delay time before DiSEqC send */
869
msleep(15);
870
871
return cx24116_cmd_execute(fe, &cmd);
872
}
873
874
static int cx24116_set_tone(struct dvb_frontend *fe,
875
fe_sec_tone_mode_t tone)
876
{
877
struct cx24116_cmd cmd;
878
int ret;
879
880
dprintk("%s(%d)\n", __func__, tone);
881
if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
882
printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
883
return -EINVAL;
884
}
885
886
/* Wait for LNB ready */
887
ret = cx24116_wait_for_lnb(fe);
888
if (ret != 0)
889
return ret;
890
891
/* Min delay time after DiSEqC send */
892
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
893
894
/* Now we set the tone */
895
cmd.args[0x00] = CMD_SET_TONE;
896
cmd.args[0x01] = 0x00;
897
cmd.args[0x02] = 0x00;
898
899
switch (tone) {
900
case SEC_TONE_ON:
901
dprintk("%s: setting tone on\n", __func__);
902
cmd.args[0x03] = 0x01;
903
break;
904
case SEC_TONE_OFF:
905
dprintk("%s: setting tone off\n", __func__);
906
cmd.args[0x03] = 0x00;
907
break;
908
}
909
cmd.len = 0x04;
910
911
/* Min delay time before DiSEqC send */
912
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
913
914
return cx24116_cmd_execute(fe, &cmd);
915
}
916
917
/* Initialise DiSEqC */
918
static int cx24116_diseqc_init(struct dvb_frontend *fe)
919
{
920
struct cx24116_state *state = fe->demodulator_priv;
921
struct cx24116_cmd cmd;
922
int ret;
923
924
/* Firmware CMD 20: LNB/DiSEqC config */
925
cmd.args[0x00] = CMD_LNBCONFIG;
926
cmd.args[0x01] = 0x00;
927
cmd.args[0x02] = 0x10;
928
cmd.args[0x03] = 0x00;
929
cmd.args[0x04] = 0x8f;
930
cmd.args[0x05] = 0x28;
931
cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
932
cmd.args[0x07] = 0x01;
933
cmd.len = 0x08;
934
ret = cx24116_cmd_execute(fe, &cmd);
935
if (ret != 0)
936
return ret;
937
938
/* Prepare a DiSEqC command */
939
state->dsec_cmd.args[0x00] = CMD_LNBSEND;
940
941
/* DiSEqC burst */
942
state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
943
944
/* Unknown */
945
state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
946
state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
947
/* Continuation flag? */
948
state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
949
950
/* DiSEqC message length */
951
state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
952
953
/* Command length */
954
state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
955
956
return 0;
957
}
958
959
/* Send DiSEqC message with derived burst (hack) || previous burst */
960
static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
961
struct dvb_diseqc_master_cmd *d)
962
{
963
struct cx24116_state *state = fe->demodulator_priv;
964
int i, ret;
965
966
/* Dump DiSEqC message */
967
if (debug) {
968
printk(KERN_INFO "cx24116: %s(", __func__);
969
for (i = 0 ; i < d->msg_len ;) {
970
printk(KERN_INFO "0x%02x", d->msg[i]);
971
if (++i < d->msg_len)
972
printk(KERN_INFO ", ");
973
}
974
printk(") toneburst=%d\n", toneburst);
975
}
976
977
/* Validate length */
978
if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
979
return -EINVAL;
980
981
/* DiSEqC message */
982
for (i = 0; i < d->msg_len; i++)
983
state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
984
985
/* DiSEqC message length */
986
state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
987
988
/* Command length */
989
state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
990
state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
991
992
/* DiSEqC toneburst */
993
if (toneburst == CX24116_DISEQC_MESGCACHE)
994
/* Message is cached */
995
return 0;
996
997
else if (toneburst == CX24116_DISEQC_TONEOFF)
998
/* Message is sent without burst */
999
state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
1000
1001
else if (toneburst == CX24116_DISEQC_TONECACHE) {
1002
/*
1003
* Message is sent with derived else cached burst
1004
*
1005
* WRITE PORT GROUP COMMAND 38
1006
*
1007
* 0/A/A: E0 10 38 F0..F3
1008
* 1/B/B: E0 10 38 F4..F7
1009
* 2/C/A: E0 10 38 F8..FB
1010
* 3/D/B: E0 10 38 FC..FF
1011
*
1012
* databyte[3]= 8421:8421
1013
* ABCD:WXYZ
1014
* CLR :SET
1015
*
1016
* WX= PORT SELECT 0..3 (X=TONEBURST)
1017
* Y = VOLTAGE (0=13V, 1=18V)
1018
* Z = BAND (0=LOW, 1=HIGH(22K))
1019
*/
1020
if (d->msg_len >= 4 && d->msg[2] == 0x38)
1021
state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1022
((d->msg[3] & 4) >> 2);
1023
if (debug)
1024
dprintk("%s burst=%d\n", __func__,
1025
state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1026
}
1027
1028
/* Wait for LNB ready */
1029
ret = cx24116_wait_for_lnb(fe);
1030
if (ret != 0)
1031
return ret;
1032
1033
/* Wait for voltage/min repeat delay */
1034
msleep(100);
1035
1036
/* Command */
1037
ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1038
if (ret != 0)
1039
return ret;
1040
/*
1041
* Wait for send
1042
*
1043
* Eutelsat spec:
1044
* >15ms delay + (XXX determine if FW does this, see set_tone)
1045
* 13.5ms per byte +
1046
* >15ms delay +
1047
* 12.5ms burst +
1048
* >15ms delay (XXX determine if FW does this, see set_tone)
1049
*/
1050
msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1051
((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1052
1053
return 0;
1054
}
1055
1056
/* Send DiSEqC burst */
1057
static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
1058
fe_sec_mini_cmd_t burst)
1059
{
1060
struct cx24116_state *state = fe->demodulator_priv;
1061
int ret;
1062
1063
dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1064
1065
/* DiSEqC burst */
1066
if (burst == SEC_MINI_A)
1067
state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1068
CX24116_DISEQC_MINI_A;
1069
else if (burst == SEC_MINI_B)
1070
state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1071
CX24116_DISEQC_MINI_B;
1072
else
1073
return -EINVAL;
1074
1075
/* DiSEqC toneburst */
1076
if (toneburst != CX24116_DISEQC_MESGCACHE)
1077
/* Burst is cached */
1078
return 0;
1079
1080
/* Burst is to be sent with cached message */
1081
1082
/* Wait for LNB ready */
1083
ret = cx24116_wait_for_lnb(fe);
1084
if (ret != 0)
1085
return ret;
1086
1087
/* Wait for voltage/min repeat delay */
1088
msleep(100);
1089
1090
/* Command */
1091
ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1092
if (ret != 0)
1093
return ret;
1094
1095
/*
1096
* Wait for send
1097
*
1098
* Eutelsat spec:
1099
* >15ms delay + (XXX determine if FW does this, see set_tone)
1100
* 13.5ms per byte +
1101
* >15ms delay +
1102
* 12.5ms burst +
1103
* >15ms delay (XXX determine if FW does this, see set_tone)
1104
*/
1105
msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1106
1107
return 0;
1108
}
1109
1110
static void cx24116_release(struct dvb_frontend *fe)
1111
{
1112
struct cx24116_state *state = fe->demodulator_priv;
1113
dprintk("%s\n", __func__);
1114
kfree(state);
1115
}
1116
1117
static struct dvb_frontend_ops cx24116_ops;
1118
1119
struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1120
struct i2c_adapter *i2c)
1121
{
1122
struct cx24116_state *state = NULL;
1123
int ret;
1124
1125
dprintk("%s\n", __func__);
1126
1127
/* allocate memory for the internal state */
1128
state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1129
if (state == NULL)
1130
goto error1;
1131
1132
state->config = config;
1133
state->i2c = i2c;
1134
1135
/* check if the demod is present */
1136
ret = (cx24116_readreg(state, 0xFF) << 8) |
1137
cx24116_readreg(state, 0xFE);
1138
if (ret != 0x0501) {
1139
printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1140
goto error2;
1141
}
1142
1143
/* create dvb_frontend */
1144
memcpy(&state->frontend.ops, &cx24116_ops,
1145
sizeof(struct dvb_frontend_ops));
1146
state->frontend.demodulator_priv = state;
1147
return &state->frontend;
1148
1149
error2: kfree(state);
1150
error1: return NULL;
1151
}
1152
EXPORT_SYMBOL(cx24116_attach);
1153
1154
/*
1155
* Initialise or wake up device
1156
*
1157
* Power config will reset and load initial firmware if required
1158
*/
1159
static int cx24116_initfe(struct dvb_frontend *fe)
1160
{
1161
struct cx24116_state *state = fe->demodulator_priv;
1162
struct cx24116_cmd cmd;
1163
int ret;
1164
1165
dprintk("%s()\n", __func__);
1166
1167
/* Power on */
1168
cx24116_writereg(state, 0xe0, 0);
1169
cx24116_writereg(state, 0xe1, 0);
1170
cx24116_writereg(state, 0xea, 0);
1171
1172
/* Firmware CMD 36: Power config */
1173
cmd.args[0x00] = CMD_TUNERSLEEP;
1174
cmd.args[0x01] = 0;
1175
cmd.len = 0x02;
1176
ret = cx24116_cmd_execute(fe, &cmd);
1177
if (ret != 0)
1178
return ret;
1179
1180
ret = cx24116_diseqc_init(fe);
1181
if (ret != 0)
1182
return ret;
1183
1184
/* HVR-4000 needs this */
1185
return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
1186
}
1187
1188
/*
1189
* Put device to sleep
1190
*/
1191
static int cx24116_sleep(struct dvb_frontend *fe)
1192
{
1193
struct cx24116_state *state = fe->demodulator_priv;
1194
struct cx24116_cmd cmd;
1195
int ret;
1196
1197
dprintk("%s()\n", __func__);
1198
1199
/* Firmware CMD 36: Power config */
1200
cmd.args[0x00] = CMD_TUNERSLEEP;
1201
cmd.args[0x01] = 1;
1202
cmd.len = 0x02;
1203
ret = cx24116_cmd_execute(fe, &cmd);
1204
if (ret != 0)
1205
return ret;
1206
1207
/* Power off (Shutdown clocks) */
1208
cx24116_writereg(state, 0xea, 0xff);
1209
cx24116_writereg(state, 0xe1, 1);
1210
cx24116_writereg(state, 0xe0, 1);
1211
1212
return 0;
1213
}
1214
1215
static int cx24116_set_property(struct dvb_frontend *fe,
1216
struct dtv_property *tvp)
1217
{
1218
dprintk("%s(..)\n", __func__);
1219
return 0;
1220
}
1221
1222
static int cx24116_get_property(struct dvb_frontend *fe,
1223
struct dtv_property *tvp)
1224
{
1225
dprintk("%s(..)\n", __func__);
1226
return 0;
1227
}
1228
1229
/* dvb-core told us to tune, the tv property cache will be complete,
1230
* it's safe for is to pull values and use them for tuning purposes.
1231
*/
1232
static int cx24116_set_frontend(struct dvb_frontend *fe,
1233
struct dvb_frontend_parameters *p)
1234
{
1235
struct cx24116_state *state = fe->demodulator_priv;
1236
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1237
struct cx24116_cmd cmd;
1238
fe_status_t tunerstat;
1239
int i, status, ret, retune = 1;
1240
1241
dprintk("%s()\n", __func__);
1242
1243
switch (c->delivery_system) {
1244
case SYS_DVBS:
1245
dprintk("%s: DVB-S delivery system selected\n", __func__);
1246
1247
/* Only QPSK is supported for DVB-S */
1248
if (c->modulation != QPSK) {
1249
dprintk("%s: unsupported modulation selected (%d)\n",
1250
__func__, c->modulation);
1251
return -EOPNOTSUPP;
1252
}
1253
1254
/* Pilot doesn't exist in DVB-S, turn bit off */
1255
state->dnxt.pilot_val = CX24116_PILOT_OFF;
1256
1257
/* DVB-S only supports 0.35 */
1258
if (c->rolloff != ROLLOFF_35) {
1259
dprintk("%s: unsupported rolloff selected (%d)\n",
1260
__func__, c->rolloff);
1261
return -EOPNOTSUPP;
1262
}
1263
state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1264
break;
1265
1266
case SYS_DVBS2:
1267
dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1268
1269
/*
1270
* NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1271
* but not hardware auto detection
1272
*/
1273
if (c->modulation != PSK_8 && c->modulation != QPSK) {
1274
dprintk("%s: unsupported modulation selected (%d)\n",
1275
__func__, c->modulation);
1276
return -EOPNOTSUPP;
1277
}
1278
1279
switch (c->pilot) {
1280
case PILOT_AUTO: /* Not supported but emulated */
1281
state->dnxt.pilot_val = (c->modulation == QPSK)
1282
? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1283
retune++;
1284
break;
1285
case PILOT_OFF:
1286
state->dnxt.pilot_val = CX24116_PILOT_OFF;
1287
break;
1288
case PILOT_ON:
1289
state->dnxt.pilot_val = CX24116_PILOT_ON;
1290
break;
1291
default:
1292
dprintk("%s: unsupported pilot mode selected (%d)\n",
1293
__func__, c->pilot);
1294
return -EOPNOTSUPP;
1295
}
1296
1297
switch (c->rolloff) {
1298
case ROLLOFF_20:
1299
state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1300
break;
1301
case ROLLOFF_25:
1302
state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1303
break;
1304
case ROLLOFF_35:
1305
state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1306
break;
1307
case ROLLOFF_AUTO: /* Rolloff must be explicit */
1308
default:
1309
dprintk("%s: unsupported rolloff selected (%d)\n",
1310
__func__, c->rolloff);
1311
return -EOPNOTSUPP;
1312
}
1313
break;
1314
1315
default:
1316
dprintk("%s: unsupported delivery system selected (%d)\n",
1317
__func__, c->delivery_system);
1318
return -EOPNOTSUPP;
1319
}
1320
state->dnxt.delsys = c->delivery_system;
1321
state->dnxt.modulation = c->modulation;
1322
state->dnxt.frequency = c->frequency;
1323
state->dnxt.pilot = c->pilot;
1324
state->dnxt.rolloff = c->rolloff;
1325
1326
ret = cx24116_set_inversion(state, c->inversion);
1327
if (ret != 0)
1328
return ret;
1329
1330
/* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1331
ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1332
if (ret != 0)
1333
return ret;
1334
1335
ret = cx24116_set_symbolrate(state, c->symbol_rate);
1336
if (ret != 0)
1337
return ret;
1338
1339
/* discard the 'current' tuning parameters and prepare to tune */
1340
cx24116_clone_params(fe);
1341
1342
dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
1343
dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1344
dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1345
dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1346
state->dcur.pilot, state->dcur.pilot_val);
1347
dprintk("%s: retune = %d\n", __func__, retune);
1348
dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1349
state->dcur.rolloff, state->dcur.rolloff_val);
1350
dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1351
dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1352
state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1353
dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1354
state->dcur.inversion, state->dcur.inversion_val);
1355
1356
/* This is also done in advise/acquire on HVR4000 but not on LITE */
1357
if (state->config->set_ts_params)
1358
state->config->set_ts_params(fe, 0);
1359
1360
/* Set/Reset B/W */
1361
cmd.args[0x00] = CMD_BANDWIDTH;
1362
cmd.args[0x01] = 0x01;
1363
cmd.len = 0x02;
1364
ret = cx24116_cmd_execute(fe, &cmd);
1365
if (ret != 0)
1366
return ret;
1367
1368
/* Prepare a tune request */
1369
cmd.args[0x00] = CMD_TUNEREQUEST;
1370
1371
/* Frequency */
1372
cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1373
cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1374
cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1375
1376
/* Symbol Rate */
1377
cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1378
cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1379
1380
/* Automatic Inversion */
1381
cmd.args[0x06] = state->dcur.inversion_val;
1382
1383
/* Modulation / FEC / Pilot */
1384
cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1385
1386
cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1387
cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1388
cmd.args[0x0a] = 0x00;
1389
cmd.args[0x0b] = 0x00;
1390
cmd.args[0x0c] = state->dcur.rolloff_val;
1391
cmd.args[0x0d] = state->dcur.fec_mask;
1392
1393
if (state->dcur.symbol_rate > 30000000) {
1394
cmd.args[0x0e] = 0x04;
1395
cmd.args[0x0f] = 0x00;
1396
cmd.args[0x10] = 0x01;
1397
cmd.args[0x11] = 0x77;
1398
cmd.args[0x12] = 0x36;
1399
cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1400
cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1401
} else {
1402
cmd.args[0x0e] = 0x06;
1403
cmd.args[0x0f] = 0x00;
1404
cmd.args[0x10] = 0x00;
1405
cmd.args[0x11] = 0xFA;
1406
cmd.args[0x12] = 0x24;
1407
cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1408
cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1409
}
1410
1411
cmd.len = 0x13;
1412
1413
/* We need to support pilot and non-pilot tuning in the
1414
* driver automatically. This is a workaround for because
1415
* the demod does not support autodetect.
1416
*/
1417
do {
1418
/* Reset status register */
1419
status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1420
& CX24116_SIGNAL_MASK;
1421
cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1422
1423
/* Tune */
1424
ret = cx24116_cmd_execute(fe, &cmd);
1425
if (ret != 0)
1426
break;
1427
1428
/*
1429
* Wait for up to 500 ms before retrying
1430
*
1431
* If we are able to tune then generally it occurs within 100ms.
1432
* If it takes longer, try a different toneburst setting.
1433
*/
1434
for (i = 0; i < 50 ; i++) {
1435
cx24116_read_status(fe, &tunerstat);
1436
status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1437
if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1438
dprintk("%s: Tuned\n", __func__);
1439
goto tuned;
1440
}
1441
msleep(10);
1442
}
1443
1444
dprintk("%s: Not tuned\n", __func__);
1445
1446
/* Toggle pilot bit when in auto-pilot */
1447
if (state->dcur.pilot == PILOT_AUTO)
1448
cmd.args[0x07] ^= CX24116_PILOT_ON;
1449
} while (--retune);
1450
1451
tuned: /* Set/Reset B/W */
1452
cmd.args[0x00] = CMD_BANDWIDTH;
1453
cmd.args[0x01] = 0x00;
1454
cmd.len = 0x02;
1455
ret = cx24116_cmd_execute(fe, &cmd);
1456
if (ret != 0)
1457
return ret;
1458
1459
return ret;
1460
}
1461
1462
static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
1463
unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
1464
{
1465
*delay = HZ / 5;
1466
if (params) {
1467
int ret = cx24116_set_frontend(fe, params);
1468
if (ret)
1469
return ret;
1470
}
1471
return cx24116_read_status(fe, status);
1472
}
1473
1474
static int cx24116_get_algo(struct dvb_frontend *fe)
1475
{
1476
return DVBFE_ALGO_HW;
1477
}
1478
1479
static struct dvb_frontend_ops cx24116_ops = {
1480
1481
.info = {
1482
.name = "Conexant CX24116/CX24118",
1483
.type = FE_QPSK,
1484
.frequency_min = 950000,
1485
.frequency_max = 2150000,
1486
.frequency_stepsize = 1011, /* kHz for QPSK frontends */
1487
.frequency_tolerance = 5000,
1488
.symbol_rate_min = 1000000,
1489
.symbol_rate_max = 45000000,
1490
.caps = FE_CAN_INVERSION_AUTO |
1491
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1492
FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1493
FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1494
FE_CAN_2G_MODULATION |
1495
FE_CAN_QPSK | FE_CAN_RECOVER
1496
},
1497
1498
.release = cx24116_release,
1499
1500
.init = cx24116_initfe,
1501
.sleep = cx24116_sleep,
1502
.read_status = cx24116_read_status,
1503
.read_ber = cx24116_read_ber,
1504
.read_signal_strength = cx24116_read_signal_strength,
1505
.read_snr = cx24116_read_snr,
1506
.read_ucblocks = cx24116_read_ucblocks,
1507
.set_tone = cx24116_set_tone,
1508
.set_voltage = cx24116_set_voltage,
1509
.diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1510
.diseqc_send_burst = cx24116_diseqc_send_burst,
1511
.get_frontend_algo = cx24116_get_algo,
1512
.tune = cx24116_tune,
1513
1514
.set_property = cx24116_set_property,
1515
.get_property = cx24116_get_property,
1516
.set_frontend = cx24116_set_frontend,
1517
};
1518
1519
MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1520
MODULE_AUTHOR("Steven Toth");
1521
MODULE_LICENSE("GPL");
1522
1523
1524