Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/frontends/dib3000mc.c
15112 views
1
/*
2
* Driver for DiBcom DiB3000MC/P-demodulator.
3
*
4
* Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
5
* Copyright (C) 2004-5 Patrick Boettcher ([email protected])
6
*
7
* This code is partially based on the previous dib3000mc.c .
8
*
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License as
11
* published by the Free Software Foundation, version 2.
12
*/
13
14
#include <linux/kernel.h>
15
#include <linux/slab.h>
16
#include <linux/i2c.h>
17
18
#include "dvb_frontend.h"
19
20
#include "dib3000mc.h"
21
22
static int debug;
23
module_param(debug, int, 0644);
24
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
25
26
static int buggy_sfn_workaround;
27
module_param(buggy_sfn_workaround, int, 0644);
28
MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
29
30
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
31
32
struct dib3000mc_state {
33
struct dvb_frontend demod;
34
struct dib3000mc_config *cfg;
35
36
u8 i2c_addr;
37
struct i2c_adapter *i2c_adap;
38
39
struct dibx000_i2c_master i2c_master;
40
41
u32 timf;
42
43
fe_bandwidth_t current_bandwidth;
44
45
u16 dev_id;
46
47
u8 sfn_workaround_active :1;
48
};
49
50
static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
51
{
52
u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
53
u8 rb[2];
54
struct i2c_msg msg[2] = {
55
{ .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
56
{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
57
};
58
59
if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
60
dprintk("i2c read error on %d\n",reg);
61
62
return (rb[0] << 8) | rb[1];
63
}
64
65
static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
66
{
67
u8 b[4] = {
68
(reg >> 8) & 0xff, reg & 0xff,
69
(val >> 8) & 0xff, val & 0xff,
70
};
71
struct i2c_msg msg = {
72
.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
73
};
74
return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
75
}
76
77
static int dib3000mc_identify(struct dib3000mc_state *state)
78
{
79
u16 value;
80
if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
81
dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
82
return -EREMOTEIO;
83
}
84
85
value = dib3000mc_read_word(state, 1026);
86
if (value != 0x3001 && value != 0x3002) {
87
dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
88
return -EREMOTEIO;
89
}
90
state->dev_id = value;
91
92
dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
93
94
return 0;
95
}
96
97
static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
98
{
99
u32 timf;
100
101
if (state->timf == 0) {
102
timf = 1384402; // default value for 8MHz
103
if (update_offset)
104
msleep(200); // first time we do an update
105
} else
106
timf = state->timf;
107
108
timf *= (bw / 1000);
109
110
if (update_offset) {
111
s16 tim_offs = dib3000mc_read_word(state, 416);
112
113
if (tim_offs & 0x2000)
114
tim_offs -= 0x4000;
115
116
if (nfft == TRANSMISSION_MODE_2K)
117
tim_offs *= 4;
118
119
timf += tim_offs;
120
state->timf = timf / (bw / 1000);
121
}
122
123
dprintk("timf: %d\n", timf);
124
125
dib3000mc_write_word(state, 23, (u16) (timf >> 16));
126
dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
127
128
return 0;
129
}
130
131
static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
132
{
133
u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
134
if (state->cfg->pwm3_inversion) {
135
reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136
reg_52 |= (1 << 2);
137
} else {
138
reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139
reg_52 |= (1 << 8);
140
}
141
dib3000mc_write_word(state, 51, reg_51);
142
dib3000mc_write_word(state, 52, reg_52);
143
144
if (state->cfg->use_pwm3)
145
dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
146
else
147
dib3000mc_write_word(state, 245, 0);
148
149
dib3000mc_write_word(state, 1040, 0x3);
150
return 0;
151
}
152
153
static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
154
{
155
int ret = 0;
156
u16 fifo_threshold = 1792;
157
u16 outreg = 0;
158
u16 outmode = 0;
159
u16 elecout = 1;
160
u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
161
162
dprintk("-I- Setting output mode for demod %p to %d\n",
163
&state->demod, mode);
164
165
switch (mode) {
166
case OUTMODE_HIGH_Z: // disable
167
elecout = 0;
168
break;
169
case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
170
outmode = 0;
171
break;
172
case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
173
outmode = 1;
174
break;
175
case OUTMODE_MPEG2_SERIAL: // STBs with serial input
176
outmode = 2;
177
break;
178
case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
179
elecout = 3;
180
/*ADDR @ 206 :
181
P_smo_error_discard [1;6:6] = 0
182
P_smo_rs_discard [1;5:5] = 0
183
P_smo_pid_parse [1;4:4] = 0
184
P_smo_fifo_flush [1;3:3] = 0
185
P_smo_mode [2;2:1] = 11
186
P_smo_ovf_prot [1;0:0] = 0
187
*/
188
smo_reg |= 3 << 1;
189
fifo_threshold = 512;
190
outmode = 5;
191
break;
192
case OUTMODE_DIVERSITY:
193
outmode = 4;
194
elecout = 1;
195
break;
196
default:
197
dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
198
outmode = 0;
199
break;
200
}
201
202
if ((state->cfg->output_mpeg2_in_188_bytes))
203
smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
204
205
outreg = dib3000mc_read_word(state, 244) & 0x07FF;
206
outreg |= (outmode << 11);
207
ret |= dib3000mc_write_word(state, 244, outreg);
208
ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
209
ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
210
ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
211
return ret;
212
}
213
214
static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
215
{
216
u16 bw_cfg[6] = { 0 };
217
u16 imp_bw_cfg[3] = { 0 };
218
u16 reg;
219
220
/* settings here are for 27.7MHz */
221
switch (bw) {
222
case 8000:
223
bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
224
imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
225
break;
226
227
case 7000:
228
bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
229
imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
230
break;
231
232
case 6000:
233
bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
234
imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
235
break;
236
237
case 5000:
238
bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
239
imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
240
break;
241
242
default: return -EINVAL;
243
}
244
245
for (reg = 6; reg < 12; reg++)
246
dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
247
dib3000mc_write_word(state, 12, 0x0000);
248
dib3000mc_write_word(state, 13, 0x03e8);
249
dib3000mc_write_word(state, 14, 0x0000);
250
dib3000mc_write_word(state, 15, 0x03f2);
251
dib3000mc_write_word(state, 16, 0x0001);
252
dib3000mc_write_word(state, 17, 0xb0d0);
253
// P_sec_len
254
dib3000mc_write_word(state, 18, 0x0393);
255
dib3000mc_write_word(state, 19, 0x8700);
256
257
for (reg = 55; reg < 58; reg++)
258
dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
259
260
// Timing configuration
261
dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
262
263
return 0;
264
}
265
266
static u16 impulse_noise_val[29] =
267
268
{
269
0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
270
0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
271
0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
272
};
273
274
static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
275
{
276
u16 i;
277
for (i = 58; i < 87; i++)
278
dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
279
280
if (nfft == TRANSMISSION_MODE_8K) {
281
dib3000mc_write_word(state, 58, 0x3b);
282
dib3000mc_write_word(state, 84, 0x00);
283
dib3000mc_write_word(state, 85, 0x8200);
284
}
285
286
dib3000mc_write_word(state, 34, 0x1294);
287
dib3000mc_write_word(state, 35, 0x1ff8);
288
if (mode == 1)
289
dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
290
}
291
292
static int dib3000mc_init(struct dvb_frontend *demod)
293
{
294
struct dib3000mc_state *state = demod->demodulator_priv;
295
struct dibx000_agc_config *agc = state->cfg->agc;
296
297
// Restart Configuration
298
dib3000mc_write_word(state, 1027, 0x8000);
299
dib3000mc_write_word(state, 1027, 0x0000);
300
301
// power up the demod + mobility configuration
302
dib3000mc_write_word(state, 140, 0x0000);
303
dib3000mc_write_word(state, 1031, 0);
304
305
if (state->cfg->mobile_mode) {
306
dib3000mc_write_word(state, 139, 0x0000);
307
dib3000mc_write_word(state, 141, 0x0000);
308
dib3000mc_write_word(state, 175, 0x0002);
309
dib3000mc_write_word(state, 1032, 0x0000);
310
} else {
311
dib3000mc_write_word(state, 139, 0x0001);
312
dib3000mc_write_word(state, 141, 0x0000);
313
dib3000mc_write_word(state, 175, 0x0000);
314
dib3000mc_write_word(state, 1032, 0x012C);
315
}
316
dib3000mc_write_word(state, 1033, 0x0000);
317
318
// P_clk_cfg
319
dib3000mc_write_word(state, 1037, 0x3130);
320
321
// other configurations
322
323
// P_ctrl_sfreq
324
dib3000mc_write_word(state, 33, (5 << 0));
325
dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
326
327
// Phase noise control
328
// P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
329
dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
330
331
if (state->cfg->phase_noise_mode == 0)
332
dib3000mc_write_word(state, 111, 0x00);
333
else
334
dib3000mc_write_word(state, 111, 0x02);
335
336
// P_agc_global
337
dib3000mc_write_word(state, 50, 0x8000);
338
339
// agc setup misc
340
dib3000mc_setup_pwm_state(state);
341
342
// P_agc_counter_lock
343
dib3000mc_write_word(state, 53, 0x87);
344
// P_agc_counter_unlock
345
dib3000mc_write_word(state, 54, 0x87);
346
347
/* agc */
348
dib3000mc_write_word(state, 36, state->cfg->max_time);
349
dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
350
dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
351
dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
352
353
// set_agc_loop_Bw
354
dib3000mc_write_word(state, 40, 0x0179);
355
dib3000mc_write_word(state, 41, 0x03f0);
356
357
dib3000mc_write_word(state, 42, agc->agc1_max);
358
dib3000mc_write_word(state, 43, agc->agc1_min);
359
dib3000mc_write_word(state, 44, agc->agc2_max);
360
dib3000mc_write_word(state, 45, agc->agc2_min);
361
dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
362
dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
363
dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
364
dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
365
366
// Begin: TimeOut registers
367
// P_pha3_thres
368
dib3000mc_write_word(state, 110, 3277);
369
// P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
370
dib3000mc_write_word(state, 26, 0x6680);
371
// lock_mask0
372
dib3000mc_write_word(state, 1, 4);
373
// lock_mask1
374
dib3000mc_write_word(state, 2, 4);
375
// lock_mask2
376
dib3000mc_write_word(state, 3, 0x1000);
377
// P_search_maxtrial=1
378
dib3000mc_write_word(state, 5, 1);
379
380
dib3000mc_set_bandwidth(state, 8000);
381
382
// div_lock_mask
383
dib3000mc_write_word(state, 4, 0x814);
384
385
dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
386
dib3000mc_write_word(state, 22, 0x463d);
387
388
// Spurious rm cfg
389
// P_cspu_regul, P_cspu_win_cut
390
dib3000mc_write_word(state, 120, 0x200f);
391
// P_adp_selec_monit
392
dib3000mc_write_word(state, 134, 0);
393
394
// Fec cfg
395
dib3000mc_write_word(state, 195, 0x10);
396
397
// diversity register: P_dvsy_sync_wait..
398
dib3000mc_write_word(state, 180, 0x2FF0);
399
400
// Impulse noise configuration
401
dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
402
403
// output mode set-up
404
dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
405
406
/* close the i2c-gate */
407
dib3000mc_write_word(state, 769, (1 << 7) );
408
409
return 0;
410
}
411
412
static int dib3000mc_sleep(struct dvb_frontend *demod)
413
{
414
struct dib3000mc_state *state = demod->demodulator_priv;
415
416
dib3000mc_write_word(state, 1031, 0xFFFF);
417
dib3000mc_write_word(state, 1032, 0xFFFF);
418
dib3000mc_write_word(state, 1033, 0xFFF0);
419
420
return 0;
421
}
422
423
static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
424
{
425
u16 cfg[4] = { 0 },reg;
426
switch (qam) {
427
case QPSK:
428
cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
429
break;
430
case QAM_16:
431
cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
432
break;
433
case QAM_64:
434
cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
435
break;
436
}
437
for (reg = 129; reg < 133; reg++)
438
dib3000mc_write_word(state, reg, cfg[reg - 129]);
439
}
440
441
static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
442
{
443
u16 value;
444
dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
445
dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
446
447
// if (boost)
448
// dib3000mc_write_word(state, 100, (11 << 6) + 6);
449
// else
450
dib3000mc_write_word(state, 100, (16 << 6) + 9);
451
452
dib3000mc_write_word(state, 1027, 0x0800);
453
dib3000mc_write_word(state, 1027, 0x0000);
454
455
//Default cfg isi offset adp
456
dib3000mc_write_word(state, 26, 0x6680);
457
dib3000mc_write_word(state, 29, 0x1273);
458
dib3000mc_write_word(state, 33, 5);
459
dib3000mc_set_adp_cfg(state, QAM_16);
460
dib3000mc_write_word(state, 133, 15564);
461
462
dib3000mc_write_word(state, 12 , 0x0);
463
dib3000mc_write_word(state, 13 , 0x3e8);
464
dib3000mc_write_word(state, 14 , 0x0);
465
dib3000mc_write_word(state, 15 , 0x3f2);
466
467
dib3000mc_write_word(state, 93,0);
468
dib3000mc_write_word(state, 94,0);
469
dib3000mc_write_word(state, 95,0);
470
dib3000mc_write_word(state, 96,0);
471
dib3000mc_write_word(state, 97,0);
472
dib3000mc_write_word(state, 98,0);
473
474
dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
475
476
value = 0;
477
switch (ch->u.ofdm.transmission_mode) {
478
case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
479
default:
480
case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
481
}
482
switch (ch->u.ofdm.guard_interval) {
483
case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
484
case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
485
case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
486
default:
487
case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
488
}
489
switch (ch->u.ofdm.constellation) {
490
case QPSK: value |= (0 << 3); break;
491
case QAM_16: value |= (1 << 3); break;
492
default:
493
case QAM_64: value |= (2 << 3); break;
494
}
495
switch (HIERARCHY_1) {
496
case HIERARCHY_2: value |= 2; break;
497
case HIERARCHY_4: value |= 4; break;
498
default:
499
case HIERARCHY_1: value |= 1; break;
500
}
501
dib3000mc_write_word(state, 0, value);
502
dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
503
504
value = 0;
505
if (ch->u.ofdm.hierarchy_information == 1)
506
value |= (1 << 4);
507
if (1 == 1)
508
value |= 1;
509
switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
510
case FEC_2_3: value |= (2 << 1); break;
511
case FEC_3_4: value |= (3 << 1); break;
512
case FEC_5_6: value |= (5 << 1); break;
513
case FEC_7_8: value |= (7 << 1); break;
514
default:
515
case FEC_1_2: value |= (1 << 1); break;
516
}
517
dib3000mc_write_word(state, 181, value);
518
519
// diversity synchro delay add 50% SFN margin
520
switch (ch->u.ofdm.transmission_mode) {
521
case TRANSMISSION_MODE_8K: value = 256; break;
522
case TRANSMISSION_MODE_2K:
523
default: value = 64; break;
524
}
525
switch (ch->u.ofdm.guard_interval) {
526
case GUARD_INTERVAL_1_16: value *= 2; break;
527
case GUARD_INTERVAL_1_8: value *= 4; break;
528
case GUARD_INTERVAL_1_4: value *= 8; break;
529
default:
530
case GUARD_INTERVAL_1_32: value *= 1; break;
531
}
532
value <<= 4;
533
value |= dib3000mc_read_word(state, 180) & 0x000f;
534
dib3000mc_write_word(state, 180, value);
535
536
// restart demod
537
value = dib3000mc_read_word(state, 0);
538
dib3000mc_write_word(state, 0, value | (1 << 9));
539
dib3000mc_write_word(state, 0, value);
540
541
msleep(30);
542
543
dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
544
}
545
546
static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
547
{
548
struct dib3000mc_state *state = demod->demodulator_priv;
549
u16 reg;
550
// u32 val;
551
struct dvb_frontend_parameters schan;
552
553
schan = *chan;
554
555
/* TODO what is that ? */
556
557
/* a channel for autosearch */
558
schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
559
schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
560
schan.u.ofdm.constellation = QAM_64;
561
schan.u.ofdm.code_rate_HP = FEC_2_3;
562
schan.u.ofdm.code_rate_LP = FEC_2_3;
563
schan.u.ofdm.hierarchy_information = 0;
564
565
dib3000mc_set_channel_cfg(state, &schan, 11);
566
567
reg = dib3000mc_read_word(state, 0);
568
dib3000mc_write_word(state, 0, reg | (1 << 8));
569
dib3000mc_read_word(state, 511);
570
dib3000mc_write_word(state, 0, reg);
571
572
return 0;
573
}
574
575
static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
576
{
577
struct dib3000mc_state *state = demod->demodulator_priv;
578
u16 irq_pending = dib3000mc_read_word(state, 511);
579
580
if (irq_pending & 0x1) // failed
581
return 1;
582
583
if (irq_pending & 0x2) // succeeded
584
return 2;
585
586
return 0; // still pending
587
}
588
589
static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
590
{
591
struct dib3000mc_state *state = demod->demodulator_priv;
592
593
// ** configure demod **
594
dib3000mc_set_channel_cfg(state, ch, 0);
595
596
// activates isi
597
if (state->sfn_workaround_active) {
598
dprintk("SFN workaround is active\n");
599
dib3000mc_write_word(state, 29, 0x1273);
600
dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
601
} else {
602
dib3000mc_write_word(state, 29, 0x1073);
603
dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
604
}
605
606
dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
607
if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
608
dib3000mc_write_word(state, 26, 38528);
609
dib3000mc_write_word(state, 33, 8);
610
} else {
611
dib3000mc_write_word(state, 26, 30336);
612
dib3000mc_write_word(state, 33, 6);
613
}
614
615
if (dib3000mc_read_word(state, 509) & 0x80)
616
dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
617
618
return 0;
619
}
620
621
struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
622
{
623
struct dib3000mc_state *st = demod->demodulator_priv;
624
return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
625
}
626
627
EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
628
629
static int dib3000mc_get_frontend(struct dvb_frontend* fe,
630
struct dvb_frontend_parameters *fep)
631
{
632
struct dib3000mc_state *state = fe->demodulator_priv;
633
u16 tps = dib3000mc_read_word(state,458);
634
635
fep->inversion = INVERSION_AUTO;
636
637
fep->u.ofdm.bandwidth = state->current_bandwidth;
638
639
switch ((tps >> 8) & 0x1) {
640
case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
641
case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
642
}
643
644
switch (tps & 0x3) {
645
case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
646
case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
647
case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
648
case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
649
}
650
651
switch ((tps >> 13) & 0x3) {
652
case 0: fep->u.ofdm.constellation = QPSK; break;
653
case 1: fep->u.ofdm.constellation = QAM_16; break;
654
case 2:
655
default: fep->u.ofdm.constellation = QAM_64; break;
656
}
657
658
/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
659
/* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
660
661
fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
662
switch ((tps >> 5) & 0x7) {
663
case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
664
case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
665
case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
666
case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
667
case 7:
668
default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
669
670
}
671
672
switch ((tps >> 2) & 0x7) {
673
case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
674
case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
675
case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
676
case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
677
case 7:
678
default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
679
}
680
681
return 0;
682
}
683
684
static int dib3000mc_set_frontend(struct dvb_frontend* fe,
685
struct dvb_frontend_parameters *fep)
686
{
687
struct dib3000mc_state *state = fe->demodulator_priv;
688
int ret;
689
690
dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
691
692
state->current_bandwidth = fep->u.ofdm.bandwidth;
693
dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
694
695
/* maybe the parameter has been changed */
696
state->sfn_workaround_active = buggy_sfn_workaround;
697
698
if (fe->ops.tuner_ops.set_params) {
699
fe->ops.tuner_ops.set_params(fe, fep);
700
msleep(100);
701
}
702
703
if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
704
fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
705
fep->u.ofdm.constellation == QAM_AUTO ||
706
fep->u.ofdm.code_rate_HP == FEC_AUTO) {
707
int i = 1000, found;
708
709
dib3000mc_autosearch_start(fe, fep);
710
do {
711
msleep(1);
712
found = dib3000mc_autosearch_is_irq(fe);
713
} while (found == 0 && i--);
714
715
dprintk("autosearch returns: %d\n",found);
716
if (found == 0 || found == 1)
717
return 0; // no channel found
718
719
dib3000mc_get_frontend(fe, fep);
720
}
721
722
ret = dib3000mc_tune(fe, fep);
723
724
/* make this a config parameter */
725
dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
726
return ret;
727
}
728
729
static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
730
{
731
struct dib3000mc_state *state = fe->demodulator_priv;
732
u16 lock = dib3000mc_read_word(state, 509);
733
734
*stat = 0;
735
736
if (lock & 0x8000)
737
*stat |= FE_HAS_SIGNAL;
738
if (lock & 0x3000)
739
*stat |= FE_HAS_CARRIER;
740
if (lock & 0x0100)
741
*stat |= FE_HAS_VITERBI;
742
if (lock & 0x0010)
743
*stat |= FE_HAS_SYNC;
744
if (lock & 0x0008)
745
*stat |= FE_HAS_LOCK;
746
747
return 0;
748
}
749
750
static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
751
{
752
struct dib3000mc_state *state = fe->demodulator_priv;
753
*ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
754
return 0;
755
}
756
757
static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
758
{
759
struct dib3000mc_state *state = fe->demodulator_priv;
760
*unc = dib3000mc_read_word(state, 508);
761
return 0;
762
}
763
764
static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
765
{
766
struct dib3000mc_state *state = fe->demodulator_priv;
767
u16 val = dib3000mc_read_word(state, 392);
768
*strength = 65535 - val;
769
return 0;
770
}
771
772
static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
773
{
774
*snr = 0x0000;
775
return 0;
776
}
777
778
static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
779
{
780
tune->min_delay_ms = 1000;
781
return 0;
782
}
783
784
static void dib3000mc_release(struct dvb_frontend *fe)
785
{
786
struct dib3000mc_state *state = fe->demodulator_priv;
787
dibx000_exit_i2c_master(&state->i2c_master);
788
kfree(state);
789
}
790
791
int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
792
{
793
struct dib3000mc_state *state = fe->demodulator_priv;
794
dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
795
return 0;
796
}
797
EXPORT_SYMBOL(dib3000mc_pid_control);
798
799
int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
800
{
801
struct dib3000mc_state *state = fe->demodulator_priv;
802
u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
803
tmp |= (onoff << 4);
804
return dib3000mc_write_word(state, 206, tmp);
805
}
806
EXPORT_SYMBOL(dib3000mc_pid_parse);
807
808
void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
809
{
810
struct dib3000mc_state *state = fe->demodulator_priv;
811
state->cfg = cfg;
812
}
813
EXPORT_SYMBOL(dib3000mc_set_config);
814
815
int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
816
{
817
struct dib3000mc_state *dmcst;
818
int k;
819
u8 new_addr;
820
821
static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
822
823
dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
824
if (dmcst == NULL)
825
return -ENOMEM;
826
827
dmcst->i2c_adap = i2c;
828
829
for (k = no_of_demods-1; k >= 0; k--) {
830
dmcst->cfg = &cfg[k];
831
832
/* designated i2c address */
833
new_addr = DIB3000MC_I2C_ADDRESS[k];
834
dmcst->i2c_addr = new_addr;
835
if (dib3000mc_identify(dmcst) != 0) {
836
dmcst->i2c_addr = default_addr;
837
if (dib3000mc_identify(dmcst) != 0) {
838
dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
839
kfree(dmcst);
840
return -ENODEV;
841
}
842
}
843
844
dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
845
846
// set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
847
dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
848
dmcst->i2c_addr = new_addr;
849
}
850
851
for (k = 0; k < no_of_demods; k++) {
852
dmcst->cfg = &cfg[k];
853
dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
854
855
dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
856
857
/* turn off data output */
858
dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
859
}
860
861
kfree(dmcst);
862
return 0;
863
}
864
EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
865
866
static struct dvb_frontend_ops dib3000mc_ops;
867
868
struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
869
{
870
struct dvb_frontend *demod;
871
struct dib3000mc_state *st;
872
st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
873
if (st == NULL)
874
return NULL;
875
876
st->cfg = cfg;
877
st->i2c_adap = i2c_adap;
878
st->i2c_addr = i2c_addr;
879
880
demod = &st->demod;
881
demod->demodulator_priv = st;
882
memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
883
884
if (dib3000mc_identify(st) != 0)
885
goto error;
886
887
dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
888
889
dib3000mc_write_word(st, 1037, 0x3130);
890
891
return demod;
892
893
error:
894
kfree(st);
895
return NULL;
896
}
897
EXPORT_SYMBOL(dib3000mc_attach);
898
899
static struct dvb_frontend_ops dib3000mc_ops = {
900
.info = {
901
.name = "DiBcom 3000MC/P",
902
.type = FE_OFDM,
903
.frequency_min = 44250000,
904
.frequency_max = 867250000,
905
.frequency_stepsize = 62500,
906
.caps = FE_CAN_INVERSION_AUTO |
907
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
908
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
909
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
910
FE_CAN_TRANSMISSION_MODE_AUTO |
911
FE_CAN_GUARD_INTERVAL_AUTO |
912
FE_CAN_RECOVER |
913
FE_CAN_HIERARCHY_AUTO,
914
},
915
916
.release = dib3000mc_release,
917
918
.init = dib3000mc_init,
919
.sleep = dib3000mc_sleep,
920
921
.set_frontend = dib3000mc_set_frontend,
922
.get_tune_settings = dib3000mc_fe_get_tune_settings,
923
.get_frontend = dib3000mc_get_frontend,
924
925
.read_status = dib3000mc_read_status,
926
.read_ber = dib3000mc_read_ber,
927
.read_signal_strength = dib3000mc_read_signal_strength,
928
.read_snr = dib3000mc_read_snr,
929
.read_ucblocks = dib3000mc_read_unc_blocks,
930
};
931
932
MODULE_AUTHOR("Patrick Boettcher <[email protected]>");
933
MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
934
MODULE_LICENSE("GPL");
935
936