Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/frontends/dib8000.c
15112 views
1
/*
2
* Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3
*
4
* Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License as
8
* published by the Free Software Foundation, version 2.
9
*/
10
#include <linux/kernel.h>
11
#include <linux/slab.h>
12
#include <linux/i2c.h>
13
#include "dvb_math.h"
14
15
#include "dvb_frontend.h"
16
17
#include "dib8000.h"
18
19
#define LAYER_ALL -1
20
#define LAYER_A 1
21
#define LAYER_B 2
22
#define LAYER_C 3
23
24
#define FE_CALLBACK_TIME_NEVER 0xffffffff
25
#define MAX_NUMBER_OF_FRONTENDS 6
26
27
static int debug;
28
module_param(debug, int, 0644);
29
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
30
31
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
32
33
#define FE_STATUS_TUNE_FAILED 0
34
35
struct i2c_device {
36
struct i2c_adapter *adap;
37
u8 addr;
38
u8 *i2c_write_buffer;
39
u8 *i2c_read_buffer;
40
};
41
42
struct dib8000_state {
43
struct dib8000_config cfg;
44
45
struct i2c_device i2c;
46
47
struct dibx000_i2c_master i2c_master;
48
49
u16 wbd_ref;
50
51
u8 current_band;
52
u32 current_bandwidth;
53
struct dibx000_agc_config *current_agc;
54
u32 timf;
55
u32 timf_default;
56
57
u8 div_force_off:1;
58
u8 div_state:1;
59
u16 div_sync_wait;
60
61
u8 agc_state;
62
u8 differential_constellation;
63
u8 diversity_onoff;
64
65
s16 ber_monitored_layer;
66
u16 gpio_dir;
67
u16 gpio_val;
68
69
u16 revision;
70
u8 isdbt_cfg_loaded;
71
enum frontend_tune_state tune_state;
72
u32 status;
73
74
struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
75
76
/* for the I2C transfer */
77
struct i2c_msg msg[2];
78
u8 i2c_write_buffer[4];
79
u8 i2c_read_buffer[2];
80
};
81
82
enum dib8000_power_mode {
83
DIB8000M_POWER_ALL = 0,
84
DIB8000M_POWER_INTERFACE_ONLY,
85
};
86
87
static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
88
{
89
struct i2c_msg msg[2] = {
90
{.addr = i2c->addr >> 1, .flags = 0,
91
.buf = i2c->i2c_write_buffer, .len = 2},
92
{.addr = i2c->addr >> 1, .flags = I2C_M_RD,
93
.buf = i2c->i2c_read_buffer, .len = 2},
94
};
95
96
msg[0].buf[0] = reg >> 8;
97
msg[0].buf[1] = reg & 0xff;
98
99
if (i2c_transfer(i2c->adap, msg, 2) != 2)
100
dprintk("i2c read error on %d", reg);
101
102
return (msg[1].buf[0] << 8) | msg[1].buf[1];
103
}
104
105
static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
106
{
107
state->i2c_write_buffer[0] = reg >> 8;
108
state->i2c_write_buffer[1] = reg & 0xff;
109
110
memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
111
state->msg[0].addr = state->i2c.addr >> 1;
112
state->msg[0].flags = 0;
113
state->msg[0].buf = state->i2c_write_buffer;
114
state->msg[0].len = 2;
115
state->msg[1].addr = state->i2c.addr >> 1;
116
state->msg[1].flags = I2C_M_RD;
117
state->msg[1].buf = state->i2c_read_buffer;
118
state->msg[1].len = 2;
119
120
if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
121
dprintk("i2c read error on %d", reg);
122
123
return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
124
}
125
126
static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
127
{
128
u16 rw[2];
129
130
rw[0] = dib8000_read_word(state, reg + 0);
131
rw[1] = dib8000_read_word(state, reg + 1);
132
133
return ((rw[0] << 16) | (rw[1]));
134
}
135
136
static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
137
{
138
struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
139
.buf = i2c->i2c_write_buffer, .len = 4};
140
int ret = 0;
141
142
msg.buf[0] = (reg >> 8) & 0xff;
143
msg.buf[1] = reg & 0xff;
144
msg.buf[2] = (val >> 8) & 0xff;
145
msg.buf[3] = val & 0xff;
146
147
ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
148
149
return ret;
150
}
151
152
static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
153
{
154
state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
155
state->i2c_write_buffer[1] = reg & 0xff;
156
state->i2c_write_buffer[2] = (val >> 8) & 0xff;
157
state->i2c_write_buffer[3] = val & 0xff;
158
159
memset(&state->msg[0], 0, sizeof(struct i2c_msg));
160
state->msg[0].addr = state->i2c.addr >> 1;
161
state->msg[0].flags = 0;
162
state->msg[0].buf = state->i2c_write_buffer;
163
state->msg[0].len = 4;
164
165
return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
166
}
167
168
static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
169
(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
170
(920 << 5) | 0x09
171
};
172
173
static const s16 coeff_2k_sb_1seg[8] = {
174
(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
175
};
176
177
static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
178
(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
179
(-931 << 5) | 0x0f
180
};
181
182
static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
183
(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
184
(982 << 5) | 0x0c
185
};
186
187
static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
188
(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
189
(-720 << 5) | 0x0d
190
};
191
192
static const s16 coeff_2k_sb_3seg[8] = {
193
(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
194
(-610 << 5) | 0x0a
195
};
196
197
static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
198
(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
199
(-922 << 5) | 0x0d
200
};
201
202
static const s16 coeff_4k_sb_1seg[8] = {
203
(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
204
(-655 << 5) | 0x0a
205
};
206
207
static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
208
(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
209
(-958 << 5) | 0x13
210
};
211
212
static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
213
(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
214
(-568 << 5) | 0x0f
215
};
216
217
static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
218
(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
219
(-848 << 5) | 0x13
220
};
221
222
static const s16 coeff_4k_sb_3seg[8] = {
223
(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
224
(-869 << 5) | 0x13
225
};
226
227
static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
228
(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
229
(-598 << 5) | 0x10
230
};
231
232
static const s16 coeff_8k_sb_1seg[8] = {
233
(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
234
(585 << 5) | 0x0f
235
};
236
237
static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
238
(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
239
(0 << 5) | 0x14
240
};
241
242
static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
243
(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
244
(-877 << 5) | 0x15
245
};
246
247
static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
248
(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
249
(-921 << 5) | 0x14
250
};
251
252
static const s16 coeff_8k_sb_3seg[8] = {
253
(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
254
(690 << 5) | 0x14
255
};
256
257
static const s16 ana_fe_coeff_3seg[24] = {
258
81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
259
};
260
261
static const s16 ana_fe_coeff_1seg[24] = {
262
249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
263
};
264
265
static const s16 ana_fe_coeff_13seg[24] = {
266
396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
267
};
268
269
static u16 fft_to_mode(struct dib8000_state *state)
270
{
271
u16 mode;
272
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
273
case TRANSMISSION_MODE_2K:
274
mode = 1;
275
break;
276
case TRANSMISSION_MODE_4K:
277
mode = 2;
278
break;
279
default:
280
case TRANSMISSION_MODE_AUTO:
281
case TRANSMISSION_MODE_8K:
282
mode = 3;
283
break;
284
}
285
return mode;
286
}
287
288
static void dib8000_set_acquisition_mode(struct dib8000_state *state)
289
{
290
u16 nud = dib8000_read_word(state, 298);
291
nud |= (1 << 3) | (1 << 0);
292
dprintk("acquisition mode activated");
293
dib8000_write_word(state, 298, nud);
294
}
295
static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
296
{
297
struct dib8000_state *state = fe->demodulator_priv;
298
299
u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
300
301
outreg = 0;
302
fifo_threshold = 1792;
303
smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
304
305
dprintk("-I- Setting output mode for demod %p to %d",
306
&state->fe[0], mode);
307
308
switch (mode) {
309
case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
310
outreg = (1 << 10); /* 0x0400 */
311
break;
312
case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
313
outreg = (1 << 10) | (1 << 6); /* 0x0440 */
314
break;
315
case OUTMODE_MPEG2_SERIAL: // STBs with serial input
316
outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
317
break;
318
case OUTMODE_DIVERSITY:
319
if (state->cfg.hostbus_diversity) {
320
outreg = (1 << 10) | (4 << 6); /* 0x0500 */
321
sram &= 0xfdff;
322
} else
323
sram |= 0x0c00;
324
break;
325
case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
326
smo_mode |= (3 << 1);
327
fifo_threshold = 512;
328
outreg = (1 << 10) | (5 << 6);
329
break;
330
case OUTMODE_HIGH_Z: // disable
331
outreg = 0;
332
break;
333
334
case OUTMODE_ANALOG_ADC:
335
outreg = (1 << 10) | (3 << 6);
336
dib8000_set_acquisition_mode(state);
337
break;
338
339
default:
340
dprintk("Unhandled output_mode passed to be set for demod %p",
341
&state->fe[0]);
342
return -EINVAL;
343
}
344
345
if (state->cfg.output_mpeg2_in_188_bytes)
346
smo_mode |= (1 << 5);
347
348
dib8000_write_word(state, 299, smo_mode);
349
dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
350
dib8000_write_word(state, 1286, outreg);
351
dib8000_write_word(state, 1291, sram);
352
353
return 0;
354
}
355
356
static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
357
{
358
struct dib8000_state *state = fe->demodulator_priv;
359
u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
360
361
if (!state->differential_constellation) {
362
dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
363
dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
364
} else {
365
dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
366
dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
367
}
368
state->diversity_onoff = onoff;
369
370
switch (onoff) {
371
case 0: /* only use the internal way - not the diversity input */
372
dib8000_write_word(state, 270, 1);
373
dib8000_write_word(state, 271, 0);
374
break;
375
case 1: /* both ways */
376
dib8000_write_word(state, 270, 6);
377
dib8000_write_word(state, 271, 6);
378
break;
379
case 2: /* only the diversity input */
380
dib8000_write_word(state, 270, 0);
381
dib8000_write_word(state, 271, 1);
382
break;
383
}
384
return 0;
385
}
386
387
static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
388
{
389
/* by default everything is going to be powered off */
390
u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
391
reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
392
reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
393
394
/* now, depending on the requested mode, we power on */
395
switch (mode) {
396
/* power up everything in the demod */
397
case DIB8000M_POWER_ALL:
398
reg_774 = 0x0000;
399
reg_775 = 0x0000;
400
reg_776 = 0x0000;
401
reg_900 &= 0xfffc;
402
reg_1280 &= 0x00ff;
403
break;
404
case DIB8000M_POWER_INTERFACE_ONLY:
405
reg_1280 &= 0x00ff;
406
break;
407
}
408
409
dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
410
dib8000_write_word(state, 774, reg_774);
411
dib8000_write_word(state, 775, reg_775);
412
dib8000_write_word(state, 776, reg_776);
413
dib8000_write_word(state, 900, reg_900);
414
dib8000_write_word(state, 1280, reg_1280);
415
}
416
417
static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
418
{
419
int ret = 0;
420
u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
421
422
switch (no) {
423
case DIBX000_SLOW_ADC_ON:
424
reg_908 |= (1 << 1) | (1 << 0);
425
ret |= dib8000_write_word(state, 908, reg_908);
426
reg_908 &= ~(1 << 1);
427
break;
428
429
case DIBX000_SLOW_ADC_OFF:
430
reg_908 |= (1 << 1) | (1 << 0);
431
break;
432
433
case DIBX000_ADC_ON:
434
reg_907 &= 0x0fff;
435
reg_908 &= 0x0003;
436
break;
437
438
case DIBX000_ADC_OFF: // leave the VBG voltage on
439
reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
440
reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
441
break;
442
443
case DIBX000_VBG_ENABLE:
444
reg_907 &= ~(1 << 15);
445
break;
446
447
case DIBX000_VBG_DISABLE:
448
reg_907 |= (1 << 15);
449
break;
450
451
default:
452
break;
453
}
454
455
ret |= dib8000_write_word(state, 907, reg_907);
456
ret |= dib8000_write_word(state, 908, reg_908);
457
458
return ret;
459
}
460
461
static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
462
{
463
struct dib8000_state *state = fe->demodulator_priv;
464
u32 timf;
465
466
if (bw == 0)
467
bw = 6000;
468
469
if (state->timf == 0) {
470
dprintk("using default timf");
471
timf = state->timf_default;
472
} else {
473
dprintk("using updated timf");
474
timf = state->timf;
475
}
476
477
dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
478
dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
479
480
return 0;
481
}
482
483
static int dib8000_sad_calib(struct dib8000_state *state)
484
{
485
/* internal */
486
dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
487
dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
488
489
/* do the calibration */
490
dib8000_write_word(state, 923, (1 << 0));
491
dib8000_write_word(state, 923, (0 << 0));
492
493
msleep(1);
494
return 0;
495
}
496
497
int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
498
{
499
struct dib8000_state *state = fe->demodulator_priv;
500
if (value > 4095)
501
value = 4095;
502
state->wbd_ref = value;
503
return dib8000_write_word(state, 106, value);
504
}
505
506
EXPORT_SYMBOL(dib8000_set_wbd_ref);
507
static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
508
{
509
dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
510
dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
511
dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
512
dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
513
dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
514
dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
515
516
dib8000_write_word(state, 922, bw->sad_cfg);
517
}
518
519
static void dib8000_reset_pll(struct dib8000_state *state)
520
{
521
const struct dibx000_bandwidth_config *pll = state->cfg.pll;
522
u16 clk_cfg1;
523
524
// clk_cfg0
525
dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
526
527
// clk_cfg1
528
clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
529
(pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
530
(pll->pll_range << 1) | (pll->pll_reset << 0);
531
532
dib8000_write_word(state, 902, clk_cfg1);
533
clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
534
dib8000_write_word(state, 902, clk_cfg1);
535
536
dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
537
538
/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
539
if (state->cfg.pll->ADClkSrc == 0)
540
dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
541
(pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
542
else if (state->cfg.refclksel != 0)
543
dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
544
((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
545
(pll->ADClkSrc << 7) | (0 << 1));
546
else
547
dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
548
549
dib8000_reset_pll_common(state, pll);
550
}
551
552
static int dib8000_reset_gpio(struct dib8000_state *st)
553
{
554
/* reset the GPIOs */
555
dib8000_write_word(st, 1029, st->cfg.gpio_dir);
556
dib8000_write_word(st, 1030, st->cfg.gpio_val);
557
558
/* TODO 782 is P_gpio_od */
559
560
dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
561
562
dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
563
return 0;
564
}
565
566
static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
567
{
568
st->cfg.gpio_dir = dib8000_read_word(st, 1029);
569
st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
570
st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
571
dib8000_write_word(st, 1029, st->cfg.gpio_dir);
572
573
st->cfg.gpio_val = dib8000_read_word(st, 1030);
574
st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
575
st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
576
dib8000_write_word(st, 1030, st->cfg.gpio_val);
577
578
dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
579
580
return 0;
581
}
582
583
int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
584
{
585
struct dib8000_state *state = fe->demodulator_priv;
586
return dib8000_cfg_gpio(state, num, dir, val);
587
}
588
589
EXPORT_SYMBOL(dib8000_set_gpio);
590
static const u16 dib8000_defaults[] = {
591
/* auto search configuration - lock0 by default waiting
592
* for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
593
3, 7,
594
0x0004,
595
0x0400,
596
0x0814,
597
598
12, 11,
599
0x001b,
600
0x7740,
601
0x005b,
602
0x8d80,
603
0x01c9,
604
0xc380,
605
0x0000,
606
0x0080,
607
0x0000,
608
0x0090,
609
0x0001,
610
0xd4c0,
611
612
/*1, 32,
613
0x6680 // P_corm_thres Lock algorithms configuration */
614
615
11, 80, /* set ADC level to -16 */
616
(1 << 13) - 825 - 117,
617
(1 << 13) - 837 - 117,
618
(1 << 13) - 811 - 117,
619
(1 << 13) - 766 - 117,
620
(1 << 13) - 737 - 117,
621
(1 << 13) - 693 - 117,
622
(1 << 13) - 648 - 117,
623
(1 << 13) - 619 - 117,
624
(1 << 13) - 575 - 117,
625
(1 << 13) - 531 - 117,
626
(1 << 13) - 501 - 117,
627
628
4, 108,
629
0,
630
0,
631
0,
632
0,
633
634
1, 175,
635
0x0410,
636
1, 179,
637
8192, // P_fft_nb_to_cut
638
639
6, 181,
640
0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
641
0x2800,
642
0x2800,
643
0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
644
0x2800,
645
0x2800,
646
647
2, 193,
648
0x0666, // P_pha3_thres
649
0x0000, // P_cti_use_cpe, P_cti_use_prog
650
651
2, 205,
652
0x200f, // P_cspu_regul, P_cspu_win_cut
653
0x000f, // P_des_shift_work
654
655
5, 215,
656
0x023d, // P_adp_regul_cnt
657
0x00a4, // P_adp_noise_cnt
658
0x00a4, // P_adp_regul_ext
659
0x7ff0, // P_adp_noise_ext
660
0x3ccc, // P_adp_fil
661
662
1, 230,
663
0x0000, // P_2d_byp_ti_num
664
665
1, 263,
666
0x800, //P_equal_thres_wgn
667
668
1, 268,
669
(2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
670
671
1, 270,
672
0x0001, // P_div_lock0_wait
673
1, 285,
674
0x0020, //p_fec_
675
1, 299,
676
0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
677
678
1, 338,
679
(1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
680
(1 << 10) |
681
(0 << 9) | /* P_ctrl_pre_freq_inh=0 */
682
(3 << 5) | /* P_ctrl_pre_freq_step=3 */
683
(1 << 0), /* P_pre_freq_win_len=1 */
684
685
1, 903,
686
(0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
687
688
0,
689
};
690
691
static u16 dib8000_identify(struct i2c_device *client)
692
{
693
u16 value;
694
695
//because of glitches sometimes
696
value = dib8000_i2c_read16(client, 896);
697
698
if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
699
dprintk("wrong Vendor ID (read=0x%x)", value);
700
return 0;
701
}
702
703
value = dib8000_i2c_read16(client, 897);
704
if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
705
dprintk("wrong Device ID (%x)", value);
706
return 0;
707
}
708
709
switch (value) {
710
case 0x8000:
711
dprintk("found DiB8000A");
712
break;
713
case 0x8001:
714
dprintk("found DiB8000B");
715
break;
716
case 0x8002:
717
dprintk("found DiB8000C");
718
break;
719
}
720
return value;
721
}
722
723
static int dib8000_reset(struct dvb_frontend *fe)
724
{
725
struct dib8000_state *state = fe->demodulator_priv;
726
727
dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
728
729
if ((state->revision = dib8000_identify(&state->i2c)) == 0)
730
return -EINVAL;
731
732
if (state->revision == 0x8000)
733
dprintk("error : dib8000 MA not supported");
734
735
dibx000_reset_i2c_master(&state->i2c_master);
736
737
dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
738
739
/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
740
dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
741
742
/* restart all parts */
743
dib8000_write_word(state, 770, 0xffff);
744
dib8000_write_word(state, 771, 0xffff);
745
dib8000_write_word(state, 772, 0xfffc);
746
dib8000_write_word(state, 898, 0x000c); // sad
747
dib8000_write_word(state, 1280, 0x004d);
748
dib8000_write_word(state, 1281, 0x000c);
749
750
dib8000_write_word(state, 770, 0x0000);
751
dib8000_write_word(state, 771, 0x0000);
752
dib8000_write_word(state, 772, 0x0000);
753
dib8000_write_word(state, 898, 0x0004); // sad
754
dib8000_write_word(state, 1280, 0x0000);
755
dib8000_write_word(state, 1281, 0x0000);
756
757
/* drives */
758
if (state->cfg.drives)
759
dib8000_write_word(state, 906, state->cfg.drives);
760
else {
761
dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
762
dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
763
}
764
765
dib8000_reset_pll(state);
766
767
if (dib8000_reset_gpio(state) != 0)
768
dprintk("GPIO reset was not successful.");
769
770
if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
771
dprintk("OUTPUT_MODE could not be resetted.");
772
773
state->current_agc = NULL;
774
775
// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
776
/* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
777
if (state->cfg.pll->ifreq == 0)
778
dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
779
else
780
dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
781
782
{
783
u16 l = 0, r;
784
const u16 *n;
785
n = dib8000_defaults;
786
l = *n++;
787
while (l) {
788
r = *n++;
789
do {
790
dib8000_write_word(state, r, *n++);
791
r++;
792
} while (--l);
793
l = *n++;
794
}
795
}
796
state->isdbt_cfg_loaded = 0;
797
798
//div_cfg override for special configs
799
if (state->cfg.div_cfg != 0)
800
dib8000_write_word(state, 903, state->cfg.div_cfg);
801
802
/* unforce divstr regardless whether i2c enumeration was done or not */
803
dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
804
805
dib8000_set_bandwidth(fe, 6000);
806
807
dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
808
dib8000_sad_calib(state);
809
dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
810
811
dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
812
813
return 0;
814
}
815
816
static void dib8000_restart_agc(struct dib8000_state *state)
817
{
818
// P_restart_iqc & P_restart_agc
819
dib8000_write_word(state, 770, 0x0a00);
820
dib8000_write_word(state, 770, 0x0000);
821
}
822
823
static int dib8000_update_lna(struct dib8000_state *state)
824
{
825
u16 dyn_gain;
826
827
if (state->cfg.update_lna) {
828
// read dyn_gain here (because it is demod-dependent and not tuner)
829
dyn_gain = dib8000_read_word(state, 390);
830
831
if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
832
dib8000_restart_agc(state);
833
return 1;
834
}
835
}
836
return 0;
837
}
838
839
static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
840
{
841
struct dibx000_agc_config *agc = NULL;
842
int i;
843
if (state->current_band == band && state->current_agc != NULL)
844
return 0;
845
state->current_band = band;
846
847
for (i = 0; i < state->cfg.agc_config_count; i++)
848
if (state->cfg.agc[i].band_caps & band) {
849
agc = &state->cfg.agc[i];
850
break;
851
}
852
853
if (agc == NULL) {
854
dprintk("no valid AGC configuration found for band 0x%02x", band);
855
return -EINVAL;
856
}
857
858
state->current_agc = agc;
859
860
/* AGC */
861
dib8000_write_word(state, 76, agc->setup);
862
dib8000_write_word(state, 77, agc->inv_gain);
863
dib8000_write_word(state, 78, agc->time_stabiliz);
864
dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
865
866
// Demod AGC loop configuration
867
dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
868
dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
869
870
dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
871
state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
872
873
/* AGC continued */
874
if (state->wbd_ref != 0)
875
dib8000_write_word(state, 106, state->wbd_ref);
876
else // use default
877
dib8000_write_word(state, 106, agc->wbd_ref);
878
dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
879
dib8000_write_word(state, 108, agc->agc1_max);
880
dib8000_write_word(state, 109, agc->agc1_min);
881
dib8000_write_word(state, 110, agc->agc2_max);
882
dib8000_write_word(state, 111, agc->agc2_min);
883
dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
884
dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
885
dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
886
dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
887
888
dib8000_write_word(state, 75, agc->agc1_pt3);
889
dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
890
891
return 0;
892
}
893
894
void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
895
{
896
struct dib8000_state *state = fe->demodulator_priv;
897
dib8000_set_adc_state(state, DIBX000_ADC_ON);
898
dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
899
}
900
EXPORT_SYMBOL(dib8000_pwm_agc_reset);
901
902
static int dib8000_agc_soft_split(struct dib8000_state *state)
903
{
904
u16 agc, split_offset;
905
906
if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
907
return FE_CALLBACK_TIME_NEVER;
908
909
// n_agc_global
910
agc = dib8000_read_word(state, 390);
911
912
if (agc > state->current_agc->split.min_thres)
913
split_offset = state->current_agc->split.min;
914
else if (agc < state->current_agc->split.max_thres)
915
split_offset = state->current_agc->split.max;
916
else
917
split_offset = state->current_agc->split.max *
918
(agc - state->current_agc->split.min_thres) /
919
(state->current_agc->split.max_thres - state->current_agc->split.min_thres);
920
921
dprintk("AGC split_offset: %d", split_offset);
922
923
// P_agc_force_split and P_agc_split_offset
924
dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
925
return 5000;
926
}
927
928
static int dib8000_agc_startup(struct dvb_frontend *fe)
929
{
930
struct dib8000_state *state = fe->demodulator_priv;
931
enum frontend_tune_state *tune_state = &state->tune_state;
932
933
int ret = 0;
934
935
switch (*tune_state) {
936
case CT_AGC_START:
937
// set power-up level: interf+analog+AGC
938
939
dib8000_set_adc_state(state, DIBX000_ADC_ON);
940
941
if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
942
*tune_state = CT_AGC_STOP;
943
state->status = FE_STATUS_TUNE_FAILED;
944
break;
945
}
946
947
ret = 70;
948
*tune_state = CT_AGC_STEP_0;
949
break;
950
951
case CT_AGC_STEP_0:
952
//AGC initialization
953
if (state->cfg.agc_control)
954
state->cfg.agc_control(fe, 1);
955
956
dib8000_restart_agc(state);
957
958
// wait AGC rough lock time
959
ret = 50;
960
*tune_state = CT_AGC_STEP_1;
961
break;
962
963
case CT_AGC_STEP_1:
964
// wait AGC accurate lock time
965
ret = 70;
966
967
if (dib8000_update_lna(state))
968
// wait only AGC rough lock time
969
ret = 50;
970
else
971
*tune_state = CT_AGC_STEP_2;
972
break;
973
974
case CT_AGC_STEP_2:
975
dib8000_agc_soft_split(state);
976
977
if (state->cfg.agc_control)
978
state->cfg.agc_control(fe, 0);
979
980
*tune_state = CT_AGC_STOP;
981
break;
982
default:
983
ret = dib8000_agc_soft_split(state);
984
break;
985
}
986
return ret;
987
988
}
989
990
static const s32 lut_1000ln_mant[] =
991
{
992
908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
993
};
994
995
s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
996
{
997
struct dib8000_state *state = fe->demodulator_priv;
998
u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
999
s32 val;
1000
1001
val = dib8000_read32(state, 384);
1002
if (mode) {
1003
tmp_val = val;
1004
while (tmp_val >>= 1)
1005
exp++;
1006
mant = (val * 1000 / (1<<exp));
1007
ix = (u8)((mant-1000)/100); /* index of the LUT */
1008
val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1009
val = (val*256)/1000;
1010
}
1011
return val;
1012
}
1013
EXPORT_SYMBOL(dib8000_get_adc_power);
1014
1015
static void dib8000_update_timf(struct dib8000_state *state)
1016
{
1017
u32 timf = state->timf = dib8000_read32(state, 435);
1018
1019
dib8000_write_word(state, 29, (u16) (timf >> 16));
1020
dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1021
dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1022
}
1023
1024
static const u16 adc_target_16dB[11] = {
1025
(1 << 13) - 825 - 117,
1026
(1 << 13) - 837 - 117,
1027
(1 << 13) - 811 - 117,
1028
(1 << 13) - 766 - 117,
1029
(1 << 13) - 737 - 117,
1030
(1 << 13) - 693 - 117,
1031
(1 << 13) - 648 - 117,
1032
(1 << 13) - 619 - 117,
1033
(1 << 13) - 575 - 117,
1034
(1 << 13) - 531 - 117,
1035
(1 << 13) - 501 - 117
1036
};
1037
static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1038
1039
static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1040
{
1041
u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1042
u8 guard, crate, constellation, timeI;
1043
u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1044
const s16 *ncoeff = NULL, *ana_fe;
1045
u16 tmcc_pow = 0;
1046
u16 coff_pow = 0x2800;
1047
u16 init_prbs = 0xfff;
1048
u16 ana_gain = 0;
1049
1050
if (state->ber_monitored_layer != LAYER_ALL)
1051
dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1052
else
1053
dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1054
1055
i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1056
dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1057
1058
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1059
//compute new dds_freq for the seg and adjust prbs
1060
int seg_offset =
1061
state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1062
(state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1063
(state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1064
int clk = state->cfg.pll->internal;
1065
u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1066
int dds_offset = seg_offset * segtodds;
1067
int new_dds, sub_channel;
1068
if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1069
dds_offset -= (int)(segtodds / 2);
1070
1071
if (state->cfg.pll->ifreq == 0) {
1072
if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1073
dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1074
new_dds = dds_offset;
1075
} else
1076
new_dds = dds_offset;
1077
1078
// We shift tuning frequency if the wanted segment is :
1079
// - the segment of center frequency with an odd total number of segments
1080
// - the segment to the left of center frequency with an even total number of segments
1081
// - the segment to the right of center frequency with an even total number of segments
1082
if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1083
&& (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1084
&& (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1085
&& (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1086
((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1087
|| (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1088
&& (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1089
|| (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1090
&& (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1091
((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1092
)) {
1093
new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1094
}
1095
} else {
1096
if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1097
new_dds = state->cfg.pll->ifreq - dds_offset;
1098
else
1099
new_dds = state->cfg.pll->ifreq + dds_offset;
1100
}
1101
dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1102
dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1103
if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1104
sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1105
else
1106
sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1107
sub_channel -= 6;
1108
1109
if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1110
|| state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1111
dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1112
dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1113
} else {
1114
dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1115
dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1116
}
1117
1118
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1119
case TRANSMISSION_MODE_2K:
1120
switch (sub_channel) {
1121
case -6:
1122
init_prbs = 0x0;
1123
break; // 41, 0, 1
1124
case -5:
1125
init_prbs = 0x423;
1126
break; // 02~04
1127
case -4:
1128
init_prbs = 0x9;
1129
break; // 05~07
1130
case -3:
1131
init_prbs = 0x5C7;
1132
break; // 08~10
1133
case -2:
1134
init_prbs = 0x7A6;
1135
break; // 11~13
1136
case -1:
1137
init_prbs = 0x3D8;
1138
break; // 14~16
1139
case 0:
1140
init_prbs = 0x527;
1141
break; // 17~19
1142
case 1:
1143
init_prbs = 0x7FF;
1144
break; // 20~22
1145
case 2:
1146
init_prbs = 0x79B;
1147
break; // 23~25
1148
case 3:
1149
init_prbs = 0x3D6;
1150
break; // 26~28
1151
case 4:
1152
init_prbs = 0x3A2;
1153
break; // 29~31
1154
case 5:
1155
init_prbs = 0x53B;
1156
break; // 32~34
1157
case 6:
1158
init_prbs = 0x2F4;
1159
break; // 35~37
1160
default:
1161
case 7:
1162
init_prbs = 0x213;
1163
break; // 38~40
1164
}
1165
break;
1166
1167
case TRANSMISSION_MODE_4K:
1168
switch (sub_channel) {
1169
case -6:
1170
init_prbs = 0x0;
1171
break; // 41, 0, 1
1172
case -5:
1173
init_prbs = 0x208;
1174
break; // 02~04
1175
case -4:
1176
init_prbs = 0xC3;
1177
break; // 05~07
1178
case -3:
1179
init_prbs = 0x7B9;
1180
break; // 08~10
1181
case -2:
1182
init_prbs = 0x423;
1183
break; // 11~13
1184
case -1:
1185
init_prbs = 0x5C7;
1186
break; // 14~16
1187
case 0:
1188
init_prbs = 0x3D8;
1189
break; // 17~19
1190
case 1:
1191
init_prbs = 0x7FF;
1192
break; // 20~22
1193
case 2:
1194
init_prbs = 0x3D6;
1195
break; // 23~25
1196
case 3:
1197
init_prbs = 0x53B;
1198
break; // 26~28
1199
case 4:
1200
init_prbs = 0x213;
1201
break; // 29~31
1202
case 5:
1203
init_prbs = 0x29;
1204
break; // 32~34
1205
case 6:
1206
init_prbs = 0xD0;
1207
break; // 35~37
1208
default:
1209
case 7:
1210
init_prbs = 0x48E;
1211
break; // 38~40
1212
}
1213
break;
1214
1215
default:
1216
case TRANSMISSION_MODE_8K:
1217
switch (sub_channel) {
1218
case -6:
1219
init_prbs = 0x0;
1220
break; // 41, 0, 1
1221
case -5:
1222
init_prbs = 0x740;
1223
break; // 02~04
1224
case -4:
1225
init_prbs = 0x069;
1226
break; // 05~07
1227
case -3:
1228
init_prbs = 0x7DD;
1229
break; // 08~10
1230
case -2:
1231
init_prbs = 0x208;
1232
break; // 11~13
1233
case -1:
1234
init_prbs = 0x7B9;
1235
break; // 14~16
1236
case 0:
1237
init_prbs = 0x5C7;
1238
break; // 17~19
1239
case 1:
1240
init_prbs = 0x7FF;
1241
break; // 20~22
1242
case 2:
1243
init_prbs = 0x53B;
1244
break; // 23~25
1245
case 3:
1246
init_prbs = 0x29;
1247
break; // 26~28
1248
case 4:
1249
init_prbs = 0x48E;
1250
break; // 29~31
1251
case 5:
1252
init_prbs = 0x4C4;
1253
break; // 32~34
1254
case 6:
1255
init_prbs = 0x367;
1256
break; // 33~37
1257
default:
1258
case 7:
1259
init_prbs = 0x684;
1260
break; // 38~40
1261
}
1262
break;
1263
}
1264
} else {
1265
dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1266
dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1267
dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1268
}
1269
/*P_mode == ?? */
1270
dib8000_write_word(state, 10, (seq << 4));
1271
// dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1272
1273
switch (state->fe[0]->dtv_property_cache.guard_interval) {
1274
case GUARD_INTERVAL_1_32:
1275
guard = 0;
1276
break;
1277
case GUARD_INTERVAL_1_16:
1278
guard = 1;
1279
break;
1280
case GUARD_INTERVAL_1_8:
1281
guard = 2;
1282
break;
1283
case GUARD_INTERVAL_1_4:
1284
default:
1285
guard = 3;
1286
break;
1287
}
1288
1289
dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1290
1291
max_constellation = DQPSK;
1292
for (i = 0; i < 3; i++) {
1293
switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1294
case DQPSK:
1295
constellation = 0;
1296
break;
1297
case QPSK:
1298
constellation = 1;
1299
break;
1300
case QAM_16:
1301
constellation = 2;
1302
break;
1303
case QAM_64:
1304
default:
1305
constellation = 3;
1306
break;
1307
}
1308
1309
switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1310
case FEC_1_2:
1311
crate = 1;
1312
break;
1313
case FEC_2_3:
1314
crate = 2;
1315
break;
1316
case FEC_3_4:
1317
crate = 3;
1318
break;
1319
case FEC_5_6:
1320
crate = 5;
1321
break;
1322
case FEC_7_8:
1323
default:
1324
crate = 7;
1325
break;
1326
}
1327
1328
if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1329
((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1330
(state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1331
)
1332
timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1333
else
1334
timeI = 0;
1335
dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1336
(crate << 3) | timeI);
1337
if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1338
switch (max_constellation) {
1339
case DQPSK:
1340
case QPSK:
1341
if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1342
state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1343
max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1344
break;
1345
case QAM_16:
1346
if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1347
max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1348
break;
1349
}
1350
}
1351
}
1352
1353
mode = fft_to_mode(state);
1354
1355
//dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1356
1357
dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1358
((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1359
isdbt_sb_mode & 1) << 4));
1360
1361
dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1362
1363
/* signal optimization parameter */
1364
1365
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1366
seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1367
for (i = 1; i < 3; i++)
1368
nbseg_diff +=
1369
(state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1370
for (i = 0; i < nbseg_diff; i++)
1371
seg_diff_mask |= 1 << permu_seg[i + 1];
1372
} else {
1373
for (i = 0; i < 3; i++)
1374
nbseg_diff +=
1375
(state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1376
for (i = 0; i < nbseg_diff; i++)
1377
seg_diff_mask |= 1 << permu_seg[i];
1378
}
1379
dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1380
1381
state->differential_constellation = (seg_diff_mask != 0);
1382
dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1383
1384
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1385
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1386
seg_mask13 = 0x00E0;
1387
else // 1-segment
1388
seg_mask13 = 0x0040;
1389
} else
1390
seg_mask13 = 0x1fff;
1391
1392
// WRITE: Mode & Diff mask
1393
dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1394
1395
if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1396
dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1397
else
1398
dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1399
1400
// ---- SMALL ----
1401
// P_small_seg_diff
1402
dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1403
1404
dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1405
1406
/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1407
1408
// ---- SMALL ----
1409
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1410
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1411
case TRANSMISSION_MODE_2K:
1412
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1413
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1414
ncoeff = coeff_2k_sb_1seg_dqpsk;
1415
else // QPSK or QAM
1416
ncoeff = coeff_2k_sb_1seg;
1417
} else { // 3-segments
1418
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1419
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1420
ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1421
else // QPSK or QAM on external segments
1422
ncoeff = coeff_2k_sb_3seg_0dqpsk;
1423
} else { // QPSK or QAM on central segment
1424
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1425
ncoeff = coeff_2k_sb_3seg_1dqpsk;
1426
else // QPSK or QAM on external segments
1427
ncoeff = coeff_2k_sb_3seg;
1428
}
1429
}
1430
break;
1431
1432
case TRANSMISSION_MODE_4K:
1433
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1434
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1435
ncoeff = coeff_4k_sb_1seg_dqpsk;
1436
else // QPSK or QAM
1437
ncoeff = coeff_4k_sb_1seg;
1438
} else { // 3-segments
1439
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1440
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1441
ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1442
} else { // QPSK or QAM on external segments
1443
ncoeff = coeff_4k_sb_3seg_0dqpsk;
1444
}
1445
} else { // QPSK or QAM on central segment
1446
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1447
ncoeff = coeff_4k_sb_3seg_1dqpsk;
1448
} else // QPSK or QAM on external segments
1449
ncoeff = coeff_4k_sb_3seg;
1450
}
1451
}
1452
break;
1453
1454
case TRANSMISSION_MODE_AUTO:
1455
case TRANSMISSION_MODE_8K:
1456
default:
1457
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1458
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1459
ncoeff = coeff_8k_sb_1seg_dqpsk;
1460
else // QPSK or QAM
1461
ncoeff = coeff_8k_sb_1seg;
1462
} else { // 3-segments
1463
if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1464
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1465
ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1466
} else { // QPSK or QAM on external segments
1467
ncoeff = coeff_8k_sb_3seg_0dqpsk;
1468
}
1469
} else { // QPSK or QAM on central segment
1470
if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1471
ncoeff = coeff_8k_sb_3seg_1dqpsk;
1472
} else // QPSK or QAM on external segments
1473
ncoeff = coeff_8k_sb_3seg;
1474
}
1475
}
1476
break;
1477
}
1478
for (i = 0; i < 8; i++)
1479
dib8000_write_word(state, 343 + i, ncoeff[i]);
1480
}
1481
1482
// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1483
dib8000_write_word(state, 351,
1484
(state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1485
1486
// ---- COFF ----
1487
// Carloff, the most robust
1488
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1489
1490
// P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1491
// P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1492
dib8000_write_word(state, 187,
1493
(4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1494
| 0x3);
1495
1496
/* // P_small_coef_ext_enable = 1 */
1497
/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1498
1499
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1500
1501
// P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1502
if (mode == 3)
1503
dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1504
else
1505
dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1506
// P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1507
// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1508
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1509
// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1510
dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1511
// P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1512
dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1513
1514
// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1515
dib8000_write_word(state, 181, 300);
1516
dib8000_write_word(state, 182, 150);
1517
dib8000_write_word(state, 183, 80);
1518
dib8000_write_word(state, 184, 300);
1519
dib8000_write_word(state, 185, 150);
1520
dib8000_write_word(state, 186, 80);
1521
} else { // Sound Broadcasting mode 3 seg
1522
// P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1523
/* if (mode == 3) */
1524
/* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1525
/* else */
1526
/* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1527
dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1528
1529
// P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1530
// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1531
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1532
// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1533
dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1534
//P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1535
dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1536
1537
// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1538
dib8000_write_word(state, 181, 350);
1539
dib8000_write_word(state, 182, 300);
1540
dib8000_write_word(state, 183, 250);
1541
dib8000_write_word(state, 184, 350);
1542
dib8000_write_word(state, 185, 300);
1543
dib8000_write_word(state, 186, 250);
1544
}
1545
1546
} else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1547
dib8000_write_word(state, 180, (16 << 6) | 9);
1548
dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1549
coff_pow = 0x2800;
1550
for (i = 0; i < 6; i++)
1551
dib8000_write_word(state, 181 + i, coff_pow);
1552
1553
// P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1554
// P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1555
dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1556
1557
// P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1558
dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1559
// P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1560
dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1561
}
1562
// ---- FFT ----
1563
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1564
dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1565
else
1566
dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1567
1568
/* make the cpil_coff_lock more robust but slower p_coff_winlen
1569
* 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1570
*/
1571
/* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1572
dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1573
1574
dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1575
dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1576
dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1577
if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1578
dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1579
else
1580
dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1581
dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1582
//dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1583
if (!autosearching)
1584
dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1585
else
1586
dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1587
dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1588
1589
dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1590
1591
/* offset loop parameters */
1592
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1593
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1594
/* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1595
dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1596
1597
else // Sound Broadcasting mode 3 seg
1598
/* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1599
dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1600
} else
1601
// TODO in 13 seg, timf_alpha can always be the same or not ?
1602
/* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1603
dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1604
1605
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1606
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1607
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1608
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1609
1610
else // Sound Broadcasting mode 3 seg
1611
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1612
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1613
} else
1614
/* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1615
dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1616
1617
/* P_dvsy_sync_wait - reuse mode */
1618
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1619
case TRANSMISSION_MODE_8K:
1620
mode = 256;
1621
break;
1622
case TRANSMISSION_MODE_4K:
1623
mode = 128;
1624
break;
1625
default:
1626
case TRANSMISSION_MODE_2K:
1627
mode = 64;
1628
break;
1629
}
1630
if (state->cfg.diversity_delay == 0)
1631
mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1632
else
1633
mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1634
mode <<= 4;
1635
dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1636
1637
/* channel estimation fine configuration */
1638
switch (max_constellation) {
1639
case QAM_64:
1640
ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1641
coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1642
coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1643
coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1644
coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1645
//if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1646
break;
1647
case QAM_16:
1648
ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1649
coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1650
coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1651
coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1652
coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1653
//if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1654
break;
1655
default:
1656
ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1657
coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1658
coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1659
coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1660
coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1661
break;
1662
}
1663
for (mode = 0; mode < 4; mode++)
1664
dib8000_write_word(state, 215 + mode, coeff[mode]);
1665
1666
// update ana_gain depending on max constellation
1667
dib8000_write_word(state, 116, ana_gain);
1668
// update ADC target depending on ana_gain
1669
if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1670
for (i = 0; i < 10; i++)
1671
dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1672
} else { // set -22dB ADC target for ana_gain=0
1673
for (i = 0; i < 10; i++)
1674
dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1675
}
1676
1677
// ---- ANA_FE ----
1678
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1679
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1680
ana_fe = ana_fe_coeff_3seg;
1681
else // 1-segment
1682
ana_fe = ana_fe_coeff_1seg;
1683
} else
1684
ana_fe = ana_fe_coeff_13seg;
1685
1686
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1687
for (mode = 0; mode < 24; mode++)
1688
dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1689
1690
// ---- CHAN_BLK ----
1691
for (i = 0; i < 13; i++) {
1692
if ((((~seg_diff_mask) >> i) & 1) == 1) {
1693
P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1694
P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1695
}
1696
}
1697
dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1698
dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1699
// "P_cspu_left_edge" not used => do not care
1700
// "P_cspu_right_edge" not used => do not care
1701
1702
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1703
dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1704
dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1705
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1706
&& state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1707
//dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1708
dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1709
}
1710
} else if (state->isdbt_cfg_loaded == 0) {
1711
dib8000_write_word(state, 228, 0); // default value
1712
dib8000_write_word(state, 265, 31); // default value
1713
dib8000_write_word(state, 205, 0x200f); // init value
1714
}
1715
// ---- TMCC ----
1716
for (i = 0; i < 3; i++)
1717
tmcc_pow +=
1718
(((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1719
// Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1720
// Threshold is set at 1/4 of max power.
1721
tmcc_pow *= (1 << (9 - 2));
1722
1723
dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1724
dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1725
dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1726
//dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1727
// ---- PHA3 ----
1728
1729
if (state->isdbt_cfg_loaded == 0)
1730
dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1731
1732
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1733
state->isdbt_cfg_loaded = 0;
1734
else
1735
state->isdbt_cfg_loaded = 1;
1736
1737
}
1738
1739
static int dib8000_autosearch_start(struct dvb_frontend *fe)
1740
{
1741
u8 factor;
1742
u32 value;
1743
struct dib8000_state *state = fe->demodulator_priv;
1744
1745
int slist = 0;
1746
1747
state->fe[0]->dtv_property_cache.inversion = 0;
1748
if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1749
state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1750
state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1751
state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1752
state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1753
1754
//choose the right list, in sb, always do everything
1755
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1756
state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1757
state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1758
slist = 7;
1759
dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1760
} else {
1761
if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1762
if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1763
slist = 7;
1764
dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1765
} else
1766
slist = 3;
1767
} else {
1768
if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1769
slist = 2;
1770
dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1771
} else
1772
slist = 0;
1773
}
1774
1775
if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1776
state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1777
if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1778
state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1779
1780
dprintk("using list for autosearch : %d", slist);
1781
dib8000_set_channel(state, (unsigned char)slist, 1);
1782
//dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1783
1784
factor = 1;
1785
1786
//set lock_mask values
1787
dib8000_write_word(state, 6, 0x4);
1788
dib8000_write_word(state, 7, 0x8);
1789
dib8000_write_word(state, 8, 0x1000);
1790
1791
//set lock_mask wait time values
1792
value = 50 * state->cfg.pll->internal * factor;
1793
dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1794
dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1795
value = 100 * state->cfg.pll->internal * factor;
1796
dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1797
dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1798
value = 1000 * state->cfg.pll->internal * factor;
1799
dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1800
dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1801
1802
value = dib8000_read_word(state, 0);
1803
dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1804
dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1805
dib8000_write_word(state, 0, (u16) value);
1806
1807
}
1808
1809
return 0;
1810
}
1811
1812
static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1813
{
1814
struct dib8000_state *state = fe->demodulator_priv;
1815
u16 irq_pending = dib8000_read_word(state, 1284);
1816
1817
if (irq_pending & 0x1) { // failed
1818
dprintk("dib8000_autosearch_irq failed");
1819
return 1;
1820
}
1821
1822
if (irq_pending & 0x2) { // succeeded
1823
dprintk("dib8000_autosearch_irq succeeded");
1824
return 2;
1825
}
1826
1827
return 0; // still pending
1828
}
1829
1830
static int dib8000_tune(struct dvb_frontend *fe)
1831
{
1832
struct dib8000_state *state = fe->demodulator_priv;
1833
int ret = 0;
1834
u16 value, mode = fft_to_mode(state);
1835
1836
// we are already tuned - just resuming from suspend
1837
if (state == NULL)
1838
return -EINVAL;
1839
1840
dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1841
dib8000_set_channel(state, 0, 0);
1842
1843
// restart demod
1844
ret |= dib8000_write_word(state, 770, 0x4000);
1845
ret |= dib8000_write_word(state, 770, 0x0000);
1846
msleep(45);
1847
1848
/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1849
/* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1850
1851
// never achieved a lock before - wait for timfreq to update
1852
if (state->timf == 0) {
1853
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1854
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1855
msleep(300);
1856
else // Sound Broadcasting mode 3 seg
1857
msleep(500);
1858
} else // 13 seg
1859
msleep(200);
1860
}
1861
if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1862
if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1863
1864
/* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1865
dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1866
//dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1867
1868
/* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1869
ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1870
1871
} else { // Sound Broadcasting mode 3 seg
1872
1873
/* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1874
dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1875
1876
ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1877
}
1878
1879
} else { // 13 seg
1880
/* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1881
dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1882
1883
ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1884
1885
}
1886
1887
// we achieved a coff_cpil_lock - it's time to update the timf
1888
if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1889
dib8000_update_timf(state);
1890
1891
//now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1892
dib8000_write_word(state, 6, 0x200);
1893
1894
if (state->revision == 0x8002) {
1895
value = dib8000_read_word(state, 903);
1896
dib8000_write_word(state, 903, value & ~(1 << 3));
1897
msleep(1);
1898
dib8000_write_word(state, 903, value | (1 << 3));
1899
}
1900
1901
return ret;
1902
}
1903
1904
static int dib8000_wakeup(struct dvb_frontend *fe)
1905
{
1906
struct dib8000_state *state = fe->demodulator_priv;
1907
u8 index_frontend;
1908
int ret;
1909
1910
dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1911
dib8000_set_adc_state(state, DIBX000_ADC_ON);
1912
if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1913
dprintk("could not start Slow ADC");
1914
1915
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1916
ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1917
if (ret < 0)
1918
return ret;
1919
}
1920
1921
return 0;
1922
}
1923
1924
static int dib8000_sleep(struct dvb_frontend *fe)
1925
{
1926
struct dib8000_state *state = fe->demodulator_priv;
1927
u8 index_frontend;
1928
int ret;
1929
1930
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1931
ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1932
if (ret < 0)
1933
return ret;
1934
}
1935
1936
dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1937
dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1938
return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1939
}
1940
1941
enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1942
{
1943
struct dib8000_state *state = fe->demodulator_priv;
1944
return state->tune_state;
1945
}
1946
EXPORT_SYMBOL(dib8000_get_tune_state);
1947
1948
int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1949
{
1950
struct dib8000_state *state = fe->demodulator_priv;
1951
state->tune_state = tune_state;
1952
return 0;
1953
}
1954
EXPORT_SYMBOL(dib8000_set_tune_state);
1955
1956
static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1957
{
1958
struct dib8000_state *state = fe->demodulator_priv;
1959
u16 i, val = 0;
1960
fe_status_t stat;
1961
u8 index_frontend, sub_index_frontend;
1962
1963
fe->dtv_property_cache.bandwidth_hz = 6000000;
1964
1965
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1966
state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1967
if (stat&FE_HAS_SYNC) {
1968
dprintk("TMCC lock on the slave%i", index_frontend);
1969
/* synchronize the cache with the other frontends */
1970
state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1971
for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
1972
if (sub_index_frontend != index_frontend) {
1973
state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
1974
state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
1975
state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1976
state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
1977
state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
1978
for (i = 0; i < 3; i++) {
1979
state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
1980
state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
1981
state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
1982
state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
1983
}
1984
}
1985
}
1986
return 0;
1987
}
1988
}
1989
1990
fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1991
1992
val = dib8000_read_word(state, 570);
1993
fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1994
switch ((val & 0x30) >> 4) {
1995
case 1:
1996
fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1997
break;
1998
case 3:
1999
default:
2000
fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2001
break;
2002
}
2003
2004
switch (val & 0x3) {
2005
case 0:
2006
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
2007
dprintk("dib8000_get_frontend GI = 1/32 ");
2008
break;
2009
case 1:
2010
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
2011
dprintk("dib8000_get_frontend GI = 1/16 ");
2012
break;
2013
case 2:
2014
dprintk("dib8000_get_frontend GI = 1/8 ");
2015
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2016
break;
2017
case 3:
2018
dprintk("dib8000_get_frontend GI = 1/4 ");
2019
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
2020
break;
2021
}
2022
2023
val = dib8000_read_word(state, 505);
2024
fe->dtv_property_cache.isdbt_partial_reception = val & 1;
2025
dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
2026
2027
for (i = 0; i < 3; i++) {
2028
val = dib8000_read_word(state, 493 + i);
2029
fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
2030
dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
2031
2032
val = dib8000_read_word(state, 499 + i);
2033
fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
2034
dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
2035
2036
val = dib8000_read_word(state, 481 + i);
2037
switch (val & 0x7) {
2038
case 1:
2039
fe->dtv_property_cache.layer[i].fec = FEC_1_2;
2040
dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
2041
break;
2042
case 2:
2043
fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2044
dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2045
break;
2046
case 3:
2047
fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2048
dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2049
break;
2050
case 5:
2051
fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2052
dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2053
break;
2054
default:
2055
fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2056
dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2057
break;
2058
}
2059
2060
val = dib8000_read_word(state, 487 + i);
2061
switch (val & 0x3) {
2062
case 0:
2063
dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2064
fe->dtv_property_cache.layer[i].modulation = DQPSK;
2065
break;
2066
case 1:
2067
fe->dtv_property_cache.layer[i].modulation = QPSK;
2068
dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2069
break;
2070
case 2:
2071
fe->dtv_property_cache.layer[i].modulation = QAM_16;
2072
dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2073
break;
2074
case 3:
2075
default:
2076
dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2077
fe->dtv_property_cache.layer[i].modulation = QAM_64;
2078
break;
2079
}
2080
}
2081
2082
/* synchronize the cache with the other frontends */
2083
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2084
state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2085
state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2086
state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2087
state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2088
state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2089
for (i = 0; i < 3; i++) {
2090
state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2091
state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2092
state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2093
state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2094
}
2095
}
2096
return 0;
2097
}
2098
2099
static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2100
{
2101
struct dib8000_state *state = fe->demodulator_priv;
2102
u8 nbr_pending, exit_condition, index_frontend;
2103
s8 index_frontend_success = -1;
2104
int time, ret;
2105
int time_slave = FE_CALLBACK_TIME_NEVER;
2106
2107
if (state->fe[0]->dtv_property_cache.frequency == 0) {
2108
dprintk("dib8000: must at least specify frequency ");
2109
return 0;
2110
}
2111
2112
if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2113
dprintk("dib8000: no bandwidth specified, set to default ");
2114
state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2115
}
2116
2117
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2118
/* synchronization of the cache */
2119
state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2120
memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2121
2122
dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2123
if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2124
state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2125
2126
dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2127
}
2128
2129
/* start up the AGC */
2130
do {
2131
time = dib8000_agc_startup(state->fe[0]);
2132
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2133
time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2134
if (time == FE_CALLBACK_TIME_NEVER)
2135
time = time_slave;
2136
else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2137
time = time_slave;
2138
}
2139
if (time != FE_CALLBACK_TIME_NEVER)
2140
msleep(time / 10);
2141
else
2142
break;
2143
exit_condition = 1;
2144
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2145
if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2146
exit_condition = 0;
2147
break;
2148
}
2149
}
2150
} while (exit_condition == 0);
2151
2152
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2153
dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2154
2155
if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2156
(state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2157
(state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2158
(state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2159
(((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2160
(state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2161
(state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2162
((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2163
(state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2164
(((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2165
(state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2166
(state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2167
((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2168
(state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2169
(((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2170
(state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2171
(state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2172
((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2173
(state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2174
(((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2175
((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2176
((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2177
((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2178
((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2179
int i = 80000;
2180
u8 found = 0;
2181
u8 tune_failed = 0;
2182
2183
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2184
dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2185
dib8000_autosearch_start(state->fe[index_frontend]);
2186
}
2187
2188
do {
2189
msleep(20);
2190
nbr_pending = 0;
2191
exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2192
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2193
if (((tune_failed >> index_frontend) & 0x1) == 0) {
2194
found = dib8000_autosearch_irq(state->fe[index_frontend]);
2195
switch (found) {
2196
case 0: /* tune pending */
2197
nbr_pending++;
2198
break;
2199
case 2:
2200
dprintk("autosearch succeed on the frontend%i", index_frontend);
2201
exit_condition = 2;
2202
index_frontend_success = index_frontend;
2203
break;
2204
default:
2205
dprintk("unhandled autosearch result");
2206
case 1:
2207
dprintk("autosearch failed for the frontend%i", index_frontend);
2208
break;
2209
}
2210
}
2211
}
2212
2213
/* if all tune are done and no success, exit: tune failed */
2214
if ((nbr_pending == 0) && (exit_condition == 0))
2215
exit_condition = 1;
2216
} while ((exit_condition == 0) && i--);
2217
2218
if (exit_condition == 1) { /* tune failed */
2219
dprintk("tune failed");
2220
return 0;
2221
}
2222
2223
dprintk("tune success on frontend%i", index_frontend_success);
2224
2225
dib8000_get_frontend(fe, fep);
2226
}
2227
2228
for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2229
ret = dib8000_tune(state->fe[index_frontend]);
2230
2231
/* set output mode and diversity input */
2232
dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2233
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2234
dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2235
dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2236
}
2237
2238
/* turn off the diversity of the last chip */
2239
dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2240
2241
return ret;
2242
}
2243
2244
static u16 dib8000_read_lock(struct dvb_frontend *fe)
2245
{
2246
struct dib8000_state *state = fe->demodulator_priv;
2247
2248
return dib8000_read_word(state, 568);
2249
}
2250
2251
static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2252
{
2253
struct dib8000_state *state = fe->demodulator_priv;
2254
u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2255
u8 index_frontend;
2256
2257
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2258
lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2259
2260
*stat = 0;
2261
2262
if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2263
*stat |= FE_HAS_SIGNAL;
2264
2265
if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2266
*stat |= FE_HAS_CARRIER;
2267
2268
if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2269
*stat |= FE_HAS_SYNC;
2270
2271
if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2272
*stat |= FE_HAS_LOCK;
2273
2274
if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2275
lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2276
if (lock & 0x01)
2277
*stat |= FE_HAS_VITERBI;
2278
2279
lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2280
if (lock & 0x01)
2281
*stat |= FE_HAS_VITERBI;
2282
2283
lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2284
if (lock & 0x01)
2285
*stat |= FE_HAS_VITERBI;
2286
}
2287
2288
return 0;
2289
}
2290
2291
static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2292
{
2293
struct dib8000_state *state = fe->demodulator_priv;
2294
*ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2295
return 0;
2296
}
2297
2298
static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2299
{
2300
struct dib8000_state *state = fe->demodulator_priv;
2301
*unc = dib8000_read_word(state, 565); // packet error on 13 seg
2302
return 0;
2303
}
2304
2305
static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2306
{
2307
struct dib8000_state *state = fe->demodulator_priv;
2308
u8 index_frontend;
2309
u16 val;
2310
2311
*strength = 0;
2312
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2313
state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2314
if (val > 65535 - *strength)
2315
*strength = 65535;
2316
else
2317
*strength += val;
2318
}
2319
2320
val = 65535 - dib8000_read_word(state, 390);
2321
if (val > 65535 - *strength)
2322
*strength = 65535;
2323
else
2324
*strength += val;
2325
return 0;
2326
}
2327
2328
static u32 dib8000_get_snr(struct dvb_frontend *fe)
2329
{
2330
struct dib8000_state *state = fe->demodulator_priv;
2331
u32 n, s, exp;
2332
u16 val;
2333
2334
val = dib8000_read_word(state, 542);
2335
n = (val >> 6) & 0xff;
2336
exp = (val & 0x3f);
2337
if ((exp & 0x20) != 0)
2338
exp -= 0x40;
2339
n <<= exp+16;
2340
2341
val = dib8000_read_word(state, 543);
2342
s = (val >> 6) & 0xff;
2343
exp = (val & 0x3f);
2344
if ((exp & 0x20) != 0)
2345
exp -= 0x40;
2346
s <<= exp+16;
2347
2348
if (n > 0) {
2349
u32 t = (s/n) << 16;
2350
return t + ((s << 16) - n*t) / n;
2351
}
2352
return 0xffffffff;
2353
}
2354
2355
static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2356
{
2357
struct dib8000_state *state = fe->demodulator_priv;
2358
u8 index_frontend;
2359
u32 snr_master;
2360
2361
snr_master = dib8000_get_snr(fe);
2362
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2363
snr_master += dib8000_get_snr(state->fe[index_frontend]);
2364
2365
if (snr_master != 0) {
2366
snr_master = 10*intlog10(snr_master>>16);
2367
*snr = snr_master / ((1 << 24) / 10);
2368
}
2369
else
2370
*snr = 0;
2371
2372
return 0;
2373
}
2374
2375
int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2376
{
2377
struct dib8000_state *state = fe->demodulator_priv;
2378
u8 index_frontend = 1;
2379
2380
while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2381
index_frontend++;
2382
if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2383
dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2384
state->fe[index_frontend] = fe_slave;
2385
return 0;
2386
}
2387
2388
dprintk("too many slave frontend");
2389
return -ENOMEM;
2390
}
2391
EXPORT_SYMBOL(dib8000_set_slave_frontend);
2392
2393
int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2394
{
2395
struct dib8000_state *state = fe->demodulator_priv;
2396
u8 index_frontend = 1;
2397
2398
while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2399
index_frontend++;
2400
if (index_frontend != 1) {
2401
dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2402
state->fe[index_frontend] = NULL;
2403
return 0;
2404
}
2405
2406
dprintk("no frontend to be removed");
2407
return -ENODEV;
2408
}
2409
EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2410
2411
struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2412
{
2413
struct dib8000_state *state = fe->demodulator_priv;
2414
2415
if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2416
return NULL;
2417
return state->fe[slave_index];
2418
}
2419
EXPORT_SYMBOL(dib8000_get_slave_frontend);
2420
2421
2422
int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2423
{
2424
int k = 0, ret = 0;
2425
u8 new_addr = 0;
2426
struct i2c_device client = {.adap = host };
2427
2428
client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2429
if (!client.i2c_write_buffer) {
2430
dprintk("%s: not enough memory", __func__);
2431
return -ENOMEM;
2432
}
2433
client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2434
if (!client.i2c_read_buffer) {
2435
dprintk("%s: not enough memory", __func__);
2436
ret = -ENOMEM;
2437
goto error_memory;
2438
}
2439
2440
for (k = no_of_demods - 1; k >= 0; k--) {
2441
/* designated i2c address */
2442
new_addr = first_addr + (k << 1);
2443
2444
client.addr = new_addr;
2445
dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2446
if (dib8000_identify(&client) == 0) {
2447
dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2448
client.addr = default_addr;
2449
if (dib8000_identify(&client) == 0) {
2450
dprintk("#%d: not identified", k);
2451
ret = -EINVAL;
2452
goto error;
2453
}
2454
}
2455
2456
/* start diversity to pull_down div_str - just for i2c-enumeration */
2457
dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2458
2459
/* set new i2c address and force divstart */
2460
dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2461
client.addr = new_addr;
2462
dib8000_identify(&client);
2463
2464
dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2465
}
2466
2467
for (k = 0; k < no_of_demods; k++) {
2468
new_addr = first_addr | (k << 1);
2469
client.addr = new_addr;
2470
2471
// unforce divstr
2472
dib8000_i2c_write16(&client, 1285, new_addr << 2);
2473
2474
/* deactivate div - it was just for i2c-enumeration */
2475
dib8000_i2c_write16(&client, 1286, 0);
2476
}
2477
2478
error:
2479
kfree(client.i2c_read_buffer);
2480
error_memory:
2481
kfree(client.i2c_write_buffer);
2482
2483
return ret;
2484
}
2485
2486
EXPORT_SYMBOL(dib8000_i2c_enumeration);
2487
static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2488
{
2489
tune->min_delay_ms = 1000;
2490
tune->step_size = 0;
2491
tune->max_drift = 0;
2492
return 0;
2493
}
2494
2495
static void dib8000_release(struct dvb_frontend *fe)
2496
{
2497
struct dib8000_state *st = fe->demodulator_priv;
2498
u8 index_frontend;
2499
2500
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2501
dvb_frontend_detach(st->fe[index_frontend]);
2502
2503
dibx000_exit_i2c_master(&st->i2c_master);
2504
kfree(st->fe[0]);
2505
kfree(st);
2506
}
2507
2508
struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2509
{
2510
struct dib8000_state *st = fe->demodulator_priv;
2511
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2512
}
2513
2514
EXPORT_SYMBOL(dib8000_get_i2c_master);
2515
2516
int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2517
{
2518
struct dib8000_state *st = fe->demodulator_priv;
2519
u16 val = dib8000_read_word(st, 299) & 0xffef;
2520
val |= (onoff & 0x1) << 4;
2521
2522
dprintk("pid filter enabled %d", onoff);
2523
return dib8000_write_word(st, 299, val);
2524
}
2525
EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2526
2527
int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2528
{
2529
struct dib8000_state *st = fe->demodulator_priv;
2530
dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2531
return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2532
}
2533
EXPORT_SYMBOL(dib8000_pid_filter);
2534
2535
static const struct dvb_frontend_ops dib8000_ops = {
2536
.info = {
2537
.name = "DiBcom 8000 ISDB-T",
2538
.type = FE_OFDM,
2539
.frequency_min = 44250000,
2540
.frequency_max = 867250000,
2541
.frequency_stepsize = 62500,
2542
.caps = FE_CAN_INVERSION_AUTO |
2543
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2544
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2545
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2546
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2547
},
2548
2549
.release = dib8000_release,
2550
2551
.init = dib8000_wakeup,
2552
.sleep = dib8000_sleep,
2553
2554
.set_frontend = dib8000_set_frontend,
2555
.get_tune_settings = dib8000_fe_get_tune_settings,
2556
.get_frontend = dib8000_get_frontend,
2557
2558
.read_status = dib8000_read_status,
2559
.read_ber = dib8000_read_ber,
2560
.read_signal_strength = dib8000_read_signal_strength,
2561
.read_snr = dib8000_read_snr,
2562
.read_ucblocks = dib8000_read_unc_blocks,
2563
};
2564
2565
struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2566
{
2567
struct dvb_frontend *fe;
2568
struct dib8000_state *state;
2569
2570
dprintk("dib8000_attach");
2571
2572
state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2573
if (state == NULL)
2574
return NULL;
2575
fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2576
if (fe == NULL)
2577
goto error;
2578
2579
memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2580
state->i2c.adap = i2c_adap;
2581
state->i2c.addr = i2c_addr;
2582
state->i2c.i2c_write_buffer = state->i2c_write_buffer;
2583
state->i2c.i2c_read_buffer = state->i2c_read_buffer;
2584
state->gpio_val = cfg->gpio_val;
2585
state->gpio_dir = cfg->gpio_dir;
2586
2587
/* Ensure the output mode remains at the previous default if it's
2588
* not specifically set by the caller.
2589
*/
2590
if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2591
state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2592
2593
state->fe[0] = fe;
2594
fe->demodulator_priv = state;
2595
memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2596
2597
state->timf_default = cfg->pll->timf;
2598
2599
if (dib8000_identify(&state->i2c) == 0)
2600
goto error;
2601
2602
dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2603
2604
dib8000_reset(fe);
2605
2606
dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2607
2608
return fe;
2609
2610
error:
2611
kfree(state);
2612
return NULL;
2613
}
2614
2615
EXPORT_SYMBOL(dib8000_attach);
2616
2617
MODULE_AUTHOR("Olivier Grenie <[email protected], " "Patrick Boettcher <[email protected]>");
2618
MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2619
MODULE_LICENSE("GPL");
2620
2621