Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/frontends/dib7000p.c
15112 views
1
/*
2
* Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
3
*
4
* Copyright (C) 2005-7 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
14
#include "dvb_math.h"
15
#include "dvb_frontend.h"
16
17
#include "dib7000p.h"
18
19
static int debug;
20
module_param(debug, int, 0644);
21
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
22
23
static int buggy_sfn_workaround;
24
module_param(buggy_sfn_workaround, int, 0644);
25
MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
26
27
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28
29
struct i2c_device {
30
struct i2c_adapter *i2c_adap;
31
u8 i2c_addr;
32
};
33
34
struct dib7000p_state {
35
struct dvb_frontend demod;
36
struct dib7000p_config cfg;
37
38
u8 i2c_addr;
39
struct i2c_adapter *i2c_adap;
40
41
struct dibx000_i2c_master i2c_master;
42
43
u16 wbd_ref;
44
45
u8 current_band;
46
u32 current_bandwidth;
47
struct dibx000_agc_config *current_agc;
48
u32 timf;
49
50
u8 div_force_off:1;
51
u8 div_state:1;
52
u16 div_sync_wait;
53
54
u8 agc_state;
55
56
u16 gpio_dir;
57
u16 gpio_val;
58
59
u8 sfn_workaround_active:1;
60
61
#define SOC7090 0x7090
62
u16 version;
63
64
u16 tuner_enable;
65
struct i2c_adapter dib7090_tuner_adap;
66
67
/* for the I2C transfer */
68
struct i2c_msg msg[2];
69
u8 i2c_write_buffer[4];
70
u8 i2c_read_buffer[2];
71
};
72
73
enum dib7000p_power_mode {
74
DIB7000P_POWER_ALL = 0,
75
DIB7000P_POWER_ANALOG_ADC,
76
DIB7000P_POWER_INTERFACE_ONLY,
77
};
78
79
static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
80
static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
81
82
static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
83
{
84
state->i2c_write_buffer[0] = reg >> 8;
85
state->i2c_write_buffer[1] = reg & 0xff;
86
87
memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
88
state->msg[0].addr = state->i2c_addr >> 1;
89
state->msg[0].flags = 0;
90
state->msg[0].buf = state->i2c_write_buffer;
91
state->msg[0].len = 2;
92
state->msg[1].addr = state->i2c_addr >> 1;
93
state->msg[1].flags = I2C_M_RD;
94
state->msg[1].buf = state->i2c_read_buffer;
95
state->msg[1].len = 2;
96
97
if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
98
dprintk("i2c read error on %d", reg);
99
100
return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
101
}
102
103
static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
104
{
105
state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
106
state->i2c_write_buffer[1] = reg & 0xff;
107
state->i2c_write_buffer[2] = (val >> 8) & 0xff;
108
state->i2c_write_buffer[3] = val & 0xff;
109
110
memset(&state->msg[0], 0, 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 = 4;
115
116
return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
117
}
118
119
static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
120
{
121
u16 l = 0, r, *n;
122
n = buf;
123
l = *n++;
124
while (l) {
125
r = *n++;
126
127
do {
128
dib7000p_write_word(state, r, *n++);
129
r++;
130
} while (--l);
131
l = *n++;
132
}
133
}
134
135
static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
136
{
137
int ret = 0;
138
u16 outreg, fifo_threshold, smo_mode;
139
140
outreg = 0;
141
fifo_threshold = 1792;
142
smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
143
144
dprintk("setting output mode for demod %p to %d", &state->demod, mode);
145
146
switch (mode) {
147
case OUTMODE_MPEG2_PAR_GATED_CLK:
148
outreg = (1 << 10); /* 0x0400 */
149
break;
150
case OUTMODE_MPEG2_PAR_CONT_CLK:
151
outreg = (1 << 10) | (1 << 6); /* 0x0440 */
152
break;
153
case OUTMODE_MPEG2_SERIAL:
154
outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
155
break;
156
case OUTMODE_DIVERSITY:
157
if (state->cfg.hostbus_diversity)
158
outreg = (1 << 10) | (4 << 6); /* 0x0500 */
159
else
160
outreg = (1 << 11);
161
break;
162
case OUTMODE_MPEG2_FIFO:
163
smo_mode |= (3 << 1);
164
fifo_threshold = 512;
165
outreg = (1 << 10) | (5 << 6);
166
break;
167
case OUTMODE_ANALOG_ADC:
168
outreg = (1 << 10) | (3 << 6);
169
break;
170
case OUTMODE_HIGH_Z:
171
outreg = 0;
172
break;
173
default:
174
dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
175
break;
176
}
177
178
if (state->cfg.output_mpeg2_in_188_bytes)
179
smo_mode |= (1 << 5);
180
181
ret |= dib7000p_write_word(state, 235, smo_mode);
182
ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
183
if (state->version != SOC7090)
184
ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
185
186
return ret;
187
}
188
189
static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
190
{
191
struct dib7000p_state *state = demod->demodulator_priv;
192
193
if (state->div_force_off) {
194
dprintk("diversity combination deactivated - forced by COFDM parameters");
195
onoff = 0;
196
dib7000p_write_word(state, 207, 0);
197
} else
198
dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
199
200
state->div_state = (u8) onoff;
201
202
if (onoff) {
203
dib7000p_write_word(state, 204, 6);
204
dib7000p_write_word(state, 205, 16);
205
/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
206
} else {
207
dib7000p_write_word(state, 204, 1);
208
dib7000p_write_word(state, 205, 0);
209
}
210
211
return 0;
212
}
213
214
static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
215
{
216
/* by default everything is powered off */
217
u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
218
219
/* now, depending on the requested mode, we power on */
220
switch (mode) {
221
/* power up everything in the demod */
222
case DIB7000P_POWER_ALL:
223
reg_774 = 0x0000;
224
reg_775 = 0x0000;
225
reg_776 = 0x0;
226
reg_899 = 0x0;
227
if (state->version == SOC7090)
228
reg_1280 &= 0x001f;
229
else
230
reg_1280 &= 0x01ff;
231
break;
232
233
case DIB7000P_POWER_ANALOG_ADC:
234
/* dem, cfg, iqc, sad, agc */
235
reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
236
/* nud */
237
reg_776 &= ~((1 << 0));
238
/* Dout */
239
if (state->version != SOC7090)
240
reg_1280 &= ~((1 << 11));
241
reg_1280 &= ~(1 << 6);
242
/* fall through wanted to enable the interfaces */
243
244
/* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
245
case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
246
if (state->version == SOC7090)
247
reg_1280 &= ~((1 << 7) | (1 << 5));
248
else
249
reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
250
break;
251
252
/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
253
}
254
255
dib7000p_write_word(state, 774, reg_774);
256
dib7000p_write_word(state, 775, reg_775);
257
dib7000p_write_word(state, 776, reg_776);
258
dib7000p_write_word(state, 899, reg_899);
259
dib7000p_write_word(state, 1280, reg_1280);
260
261
return 0;
262
}
263
264
static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
265
{
266
u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
267
u16 reg;
268
269
switch (no) {
270
case DIBX000_SLOW_ADC_ON:
271
if (state->version == SOC7090) {
272
reg = dib7000p_read_word(state, 1925);
273
274
dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
275
276
reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
277
msleep(200);
278
dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
279
280
reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
281
dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
282
} else {
283
reg_909 |= (1 << 1) | (1 << 0);
284
dib7000p_write_word(state, 909, reg_909);
285
reg_909 &= ~(1 << 1);
286
}
287
break;
288
289
case DIBX000_SLOW_ADC_OFF:
290
if (state->version == SOC7090) {
291
reg = dib7000p_read_word(state, 1925);
292
dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
293
} else
294
reg_909 |= (1 << 1) | (1 << 0);
295
break;
296
297
case DIBX000_ADC_ON:
298
reg_908 &= 0x0fff;
299
reg_909 &= 0x0003;
300
break;
301
302
case DIBX000_ADC_OFF:
303
reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
304
reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
305
break;
306
307
case DIBX000_VBG_ENABLE:
308
reg_908 &= ~(1 << 15);
309
break;
310
311
case DIBX000_VBG_DISABLE:
312
reg_908 |= (1 << 15);
313
break;
314
315
default:
316
break;
317
}
318
319
// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
320
321
reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
322
reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
323
324
dib7000p_write_word(state, 908, reg_908);
325
dib7000p_write_word(state, 909, reg_909);
326
}
327
328
static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
329
{
330
u32 timf;
331
332
// store the current bandwidth for later use
333
state->current_bandwidth = bw;
334
335
if (state->timf == 0) {
336
dprintk("using default timf");
337
timf = state->cfg.bw->timf;
338
} else {
339
dprintk("using updated timf");
340
timf = state->timf;
341
}
342
343
timf = timf * (bw / 50) / 160;
344
345
dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
346
dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
347
348
return 0;
349
}
350
351
static int dib7000p_sad_calib(struct dib7000p_state *state)
352
{
353
/* internal */
354
dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
355
356
if (state->version == SOC7090)
357
dib7000p_write_word(state, 74, 2048);
358
else
359
dib7000p_write_word(state, 74, 776);
360
361
/* do the calibration */
362
dib7000p_write_word(state, 73, (1 << 0));
363
dib7000p_write_word(state, 73, (0 << 0));
364
365
msleep(1);
366
367
return 0;
368
}
369
370
int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
371
{
372
struct dib7000p_state *state = demod->demodulator_priv;
373
if (value > 4095)
374
value = 4095;
375
state->wbd_ref = value;
376
return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
377
}
378
EXPORT_SYMBOL(dib7000p_set_wbd_ref);
379
380
static void dib7000p_reset_pll(struct dib7000p_state *state)
381
{
382
struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
383
u16 clk_cfg0;
384
385
if (state->version == SOC7090) {
386
dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
387
388
while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
389
;
390
391
dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
392
} else {
393
/* force PLL bypass */
394
clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
395
(bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
396
397
dib7000p_write_word(state, 900, clk_cfg0);
398
399
/* P_pll_cfg */
400
dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
401
clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
402
dib7000p_write_word(state, 900, clk_cfg0);
403
}
404
405
dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
406
dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
407
dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
408
dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
409
410
dib7000p_write_word(state, 72, bw->sad_cfg);
411
}
412
413
static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
414
{
415
u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
416
internal |= (u32) dib7000p_read_word(state, 19);
417
internal /= 1000;
418
419
return internal;
420
}
421
422
int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
423
{
424
struct dib7000p_state *state = fe->demodulator_priv;
425
u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
426
u8 loopdiv, prediv;
427
u32 internal, xtal;
428
429
/* get back old values */
430
prediv = reg_1856 & 0x3f;
431
loopdiv = (reg_1856 >> 6) & 0x3f;
432
433
if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
434
dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
435
reg_1856 &= 0xf000;
436
reg_1857 = dib7000p_read_word(state, 1857);
437
dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
438
439
dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
440
441
/* write new system clk into P_sec_len */
442
internal = dib7000p_get_internal_freq(state);
443
xtal = (internal / loopdiv) * prediv;
444
internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
445
dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
446
dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
447
448
dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
449
450
while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
451
dprintk("Waiting for PLL to lock");
452
453
return 0;
454
}
455
return -EIO;
456
}
457
EXPORT_SYMBOL(dib7000p_update_pll);
458
459
static int dib7000p_reset_gpio(struct dib7000p_state *st)
460
{
461
/* reset the GPIOs */
462
dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
463
464
dib7000p_write_word(st, 1029, st->gpio_dir);
465
dib7000p_write_word(st, 1030, st->gpio_val);
466
467
/* TODO 1031 is P_gpio_od */
468
469
dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
470
471
dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
472
return 0;
473
}
474
475
static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
476
{
477
st->gpio_dir = dib7000p_read_word(st, 1029);
478
st->gpio_dir &= ~(1 << num); /* reset the direction bit */
479
st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
480
dib7000p_write_word(st, 1029, st->gpio_dir);
481
482
st->gpio_val = dib7000p_read_word(st, 1030);
483
st->gpio_val &= ~(1 << num); /* reset the direction bit */
484
st->gpio_val |= (val & 0x01) << num; /* set the new value */
485
dib7000p_write_word(st, 1030, st->gpio_val);
486
487
return 0;
488
}
489
490
int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
491
{
492
struct dib7000p_state *state = demod->demodulator_priv;
493
return dib7000p_cfg_gpio(state, num, dir, val);
494
}
495
EXPORT_SYMBOL(dib7000p_set_gpio);
496
497
static u16 dib7000p_defaults[] = {
498
// auto search configuration
499
3, 2,
500
0x0004,
501
0x1000,
502
0x0814, /* Equal Lock */
503
504
12, 6,
505
0x001b,
506
0x7740,
507
0x005b,
508
0x8d80,
509
0x01c9,
510
0xc380,
511
0x0000,
512
0x0080,
513
0x0000,
514
0x0090,
515
0x0001,
516
0xd4c0,
517
518
1, 26,
519
0x6680,
520
521
/* set ADC level to -16 */
522
11, 79,
523
(1 << 13) - 825 - 117,
524
(1 << 13) - 837 - 117,
525
(1 << 13) - 811 - 117,
526
(1 << 13) - 766 - 117,
527
(1 << 13) - 737 - 117,
528
(1 << 13) - 693 - 117,
529
(1 << 13) - 648 - 117,
530
(1 << 13) - 619 - 117,
531
(1 << 13) - 575 - 117,
532
(1 << 13) - 531 - 117,
533
(1 << 13) - 501 - 117,
534
535
1, 142,
536
0x0410,
537
538
/* disable power smoothing */
539
8, 145,
540
0,
541
0,
542
0,
543
0,
544
0,
545
0,
546
0,
547
0,
548
549
1, 154,
550
1 << 13,
551
552
1, 168,
553
0x0ccd,
554
555
1, 183,
556
0x200f,
557
558
1, 212,
559
0x169,
560
561
5, 187,
562
0x023d,
563
0x00a4,
564
0x00a4,
565
0x7ff0,
566
0x3ccc,
567
568
1, 198,
569
0x800,
570
571
1, 222,
572
0x0010,
573
574
1, 235,
575
0x0062,
576
577
2, 901,
578
0x0006,
579
(3 << 10) | (1 << 6),
580
581
1, 905,
582
0x2c8e,
583
584
0,
585
};
586
587
static int dib7000p_demod_reset(struct dib7000p_state *state)
588
{
589
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
590
591
if (state->version == SOC7090)
592
dibx000_reset_i2c_master(&state->i2c_master);
593
594
dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
595
596
/* restart all parts */
597
dib7000p_write_word(state, 770, 0xffff);
598
dib7000p_write_word(state, 771, 0xffff);
599
dib7000p_write_word(state, 772, 0x001f);
600
dib7000p_write_word(state, 898, 0x0003);
601
dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
602
603
dib7000p_write_word(state, 770, 0);
604
dib7000p_write_word(state, 771, 0);
605
dib7000p_write_word(state, 772, 0);
606
dib7000p_write_word(state, 898, 0);
607
dib7000p_write_word(state, 1280, 0);
608
609
/* default */
610
dib7000p_reset_pll(state);
611
612
if (dib7000p_reset_gpio(state) != 0)
613
dprintk("GPIO reset was not successful.");
614
615
if (state->version == SOC7090) {
616
dib7000p_write_word(state, 899, 0);
617
618
/* impulse noise */
619
dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
620
dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
621
dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
622
dib7000p_write_word(state, 273, (1<<6) | 30);
623
}
624
if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
625
dprintk("OUTPUT_MODE could not be reset.");
626
627
dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
628
dib7000p_sad_calib(state);
629
dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
630
631
/* unforce divstr regardless whether i2c enumeration was done or not */
632
dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
633
634
dib7000p_set_bandwidth(state, 8000);
635
636
if (state->version == SOC7090) {
637
dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
638
} else {
639
if (state->cfg.tuner_is_baseband)
640
dib7000p_write_word(state, 36, 0x0755);
641
else
642
dib7000p_write_word(state, 36, 0x1f55);
643
}
644
645
dib7000p_write_tab(state, dib7000p_defaults);
646
647
dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
648
649
return 0;
650
}
651
652
static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
653
{
654
u16 tmp = 0;
655
tmp = dib7000p_read_word(state, 903);
656
dib7000p_write_word(state, 903, (tmp | 0x1));
657
tmp = dib7000p_read_word(state, 900);
658
dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
659
}
660
661
static void dib7000p_restart_agc(struct dib7000p_state *state)
662
{
663
// P_restart_iqc & P_restart_agc
664
dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
665
dib7000p_write_word(state, 770, 0x0000);
666
}
667
668
static int dib7000p_update_lna(struct dib7000p_state *state)
669
{
670
u16 dyn_gain;
671
672
if (state->cfg.update_lna) {
673
dyn_gain = dib7000p_read_word(state, 394);
674
if (state->cfg.update_lna(&state->demod, dyn_gain)) {
675
dib7000p_restart_agc(state);
676
return 1;
677
}
678
}
679
680
return 0;
681
}
682
683
static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
684
{
685
struct dibx000_agc_config *agc = NULL;
686
int i;
687
if (state->current_band == band && state->current_agc != NULL)
688
return 0;
689
state->current_band = band;
690
691
for (i = 0; i < state->cfg.agc_config_count; i++)
692
if (state->cfg.agc[i].band_caps & band) {
693
agc = &state->cfg.agc[i];
694
break;
695
}
696
697
if (agc == NULL) {
698
dprintk("no valid AGC configuration found for band 0x%02x", band);
699
return -EINVAL;
700
}
701
702
state->current_agc = agc;
703
704
/* AGC */
705
dib7000p_write_word(state, 75, agc->setup);
706
dib7000p_write_word(state, 76, agc->inv_gain);
707
dib7000p_write_word(state, 77, agc->time_stabiliz);
708
dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
709
710
// Demod AGC loop configuration
711
dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
712
dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
713
714
/* AGC continued */
715
dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
716
state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
717
718
if (state->wbd_ref != 0)
719
dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
720
else
721
dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
722
723
dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
724
725
dib7000p_write_word(state, 107, agc->agc1_max);
726
dib7000p_write_word(state, 108, agc->agc1_min);
727
dib7000p_write_word(state, 109, agc->agc2_max);
728
dib7000p_write_word(state, 110, agc->agc2_min);
729
dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
730
dib7000p_write_word(state, 112, agc->agc1_pt3);
731
dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
732
dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
733
dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
734
return 0;
735
}
736
737
static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
738
{
739
u32 internal = dib7000p_get_internal_freq(state);
740
s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
741
u32 abs_offset_khz = ABS(offset_khz);
742
u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
743
u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
744
745
dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
746
747
if (offset_khz < 0)
748
unit_khz_dds_val *= -1;
749
750
/* IF tuner */
751
if (invert)
752
dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
753
else
754
dds += (abs_offset_khz * unit_khz_dds_val);
755
756
if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
757
dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
758
dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
759
}
760
}
761
762
static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
763
{
764
struct dib7000p_state *state = demod->demodulator_priv;
765
int ret = -1;
766
u8 *agc_state = &state->agc_state;
767
u8 agc_split;
768
u16 reg;
769
u32 upd_demod_gain_period = 0x1000;
770
771
switch (state->agc_state) {
772
case 0:
773
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
774
if (state->version == SOC7090) {
775
reg = dib7000p_read_word(state, 0x79b) & 0xff00;
776
dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
777
dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
778
779
/* enable adc i & q */
780
reg = dib7000p_read_word(state, 0x780);
781
dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
782
} else {
783
dib7000p_set_adc_state(state, DIBX000_ADC_ON);
784
dib7000p_pll_clk_cfg(state);
785
}
786
787
if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
788
return -1;
789
790
dib7000p_set_dds(state, 0);
791
ret = 7;
792
(*agc_state)++;
793
break;
794
795
case 1:
796
if (state->cfg.agc_control)
797
state->cfg.agc_control(&state->demod, 1);
798
799
dib7000p_write_word(state, 78, 32768);
800
if (!state->current_agc->perform_agc_softsplit) {
801
/* we are using the wbd - so slow AGC startup */
802
/* force 0 split on WBD and restart AGC */
803
dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
804
(*agc_state)++;
805
ret = 5;
806
} else {
807
/* default AGC startup */
808
(*agc_state) = 4;
809
/* wait AGC rough lock time */
810
ret = 7;
811
}
812
813
dib7000p_restart_agc(state);
814
break;
815
816
case 2: /* fast split search path after 5sec */
817
dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
818
dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
819
(*agc_state)++;
820
ret = 14;
821
break;
822
823
case 3: /* split search ended */
824
agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
825
dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
826
827
dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
828
dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
829
830
dib7000p_restart_agc(state);
831
832
dprintk("SPLIT %p: %hd", demod, agc_split);
833
834
(*agc_state)++;
835
ret = 5;
836
break;
837
838
case 4: /* LNA startup */
839
ret = 7;
840
841
if (dib7000p_update_lna(state))
842
ret = 5;
843
else
844
(*agc_state)++;
845
break;
846
847
case 5:
848
if (state->cfg.agc_control)
849
state->cfg.agc_control(&state->demod, 0);
850
(*agc_state)++;
851
break;
852
default:
853
break;
854
}
855
return ret;
856
}
857
858
static void dib7000p_update_timf(struct dib7000p_state *state)
859
{
860
u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
861
state->timf = timf * 160 / (state->current_bandwidth / 50);
862
dib7000p_write_word(state, 23, (u16) (timf >> 16));
863
dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
864
dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
865
866
}
867
868
u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
869
{
870
struct dib7000p_state *state = fe->demodulator_priv;
871
switch (op) {
872
case DEMOD_TIMF_SET:
873
state->timf = timf;
874
break;
875
case DEMOD_TIMF_UPDATE:
876
dib7000p_update_timf(state);
877
break;
878
case DEMOD_TIMF_GET:
879
break;
880
}
881
dib7000p_set_bandwidth(state, state->current_bandwidth);
882
return state->timf;
883
}
884
EXPORT_SYMBOL(dib7000p_ctrl_timf);
885
886
static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
887
{
888
u16 value, est[4];
889
890
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
891
892
/* nfft, guard, qam, alpha */
893
value = 0;
894
switch (ch->u.ofdm.transmission_mode) {
895
case TRANSMISSION_MODE_2K:
896
value |= (0 << 7);
897
break;
898
case TRANSMISSION_MODE_4K:
899
value |= (2 << 7);
900
break;
901
default:
902
case TRANSMISSION_MODE_8K:
903
value |= (1 << 7);
904
break;
905
}
906
switch (ch->u.ofdm.guard_interval) {
907
case GUARD_INTERVAL_1_32:
908
value |= (0 << 5);
909
break;
910
case GUARD_INTERVAL_1_16:
911
value |= (1 << 5);
912
break;
913
case GUARD_INTERVAL_1_4:
914
value |= (3 << 5);
915
break;
916
default:
917
case GUARD_INTERVAL_1_8:
918
value |= (2 << 5);
919
break;
920
}
921
switch (ch->u.ofdm.constellation) {
922
case QPSK:
923
value |= (0 << 3);
924
break;
925
case QAM_16:
926
value |= (1 << 3);
927
break;
928
default:
929
case QAM_64:
930
value |= (2 << 3);
931
break;
932
}
933
switch (HIERARCHY_1) {
934
case HIERARCHY_2:
935
value |= 2;
936
break;
937
case HIERARCHY_4:
938
value |= 4;
939
break;
940
default:
941
case HIERARCHY_1:
942
value |= 1;
943
break;
944
}
945
dib7000p_write_word(state, 0, value);
946
dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
947
948
/* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
949
value = 0;
950
if (1 != 0)
951
value |= (1 << 6);
952
if (ch->u.ofdm.hierarchy_information == 1)
953
value |= (1 << 4);
954
if (1 == 1)
955
value |= 1;
956
switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
957
case FEC_2_3:
958
value |= (2 << 1);
959
break;
960
case FEC_3_4:
961
value |= (3 << 1);
962
break;
963
case FEC_5_6:
964
value |= (5 << 1);
965
break;
966
case FEC_7_8:
967
value |= (7 << 1);
968
break;
969
default:
970
case FEC_1_2:
971
value |= (1 << 1);
972
break;
973
}
974
dib7000p_write_word(state, 208, value);
975
976
/* offset loop parameters */
977
dib7000p_write_word(state, 26, 0x6680);
978
dib7000p_write_word(state, 32, 0x0003);
979
dib7000p_write_word(state, 29, 0x1273);
980
dib7000p_write_word(state, 33, 0x0005);
981
982
/* P_dvsy_sync_wait */
983
switch (ch->u.ofdm.transmission_mode) {
984
case TRANSMISSION_MODE_8K:
985
value = 256;
986
break;
987
case TRANSMISSION_MODE_4K:
988
value = 128;
989
break;
990
case TRANSMISSION_MODE_2K:
991
default:
992
value = 64;
993
break;
994
}
995
switch (ch->u.ofdm.guard_interval) {
996
case GUARD_INTERVAL_1_16:
997
value *= 2;
998
break;
999
case GUARD_INTERVAL_1_8:
1000
value *= 4;
1001
break;
1002
case GUARD_INTERVAL_1_4:
1003
value *= 8;
1004
break;
1005
default:
1006
case GUARD_INTERVAL_1_32:
1007
value *= 1;
1008
break;
1009
}
1010
if (state->cfg.diversity_delay == 0)
1011
state->div_sync_wait = (value * 3) / 2 + 48;
1012
else
1013
state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1014
1015
/* deactive the possibility of diversity reception if extended interleaver */
1016
state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1017
dib7000p_set_diversity_in(&state->demod, state->div_state);
1018
1019
/* channel estimation fine configuration */
1020
switch (ch->u.ofdm.constellation) {
1021
case QAM_64:
1022
est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1023
est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1024
est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1025
est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1026
break;
1027
case QAM_16:
1028
est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1029
est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1030
est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1031
est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1032
break;
1033
default:
1034
est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1035
est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1036
est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1037
est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1038
break;
1039
}
1040
for (value = 0; value < 4; value++)
1041
dib7000p_write_word(state, 187 + value, est[value]);
1042
}
1043
1044
static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1045
{
1046
struct dib7000p_state *state = demod->demodulator_priv;
1047
struct dvb_frontend_parameters schan;
1048
u32 value, factor;
1049
u32 internal = dib7000p_get_internal_freq(state);
1050
1051
schan = *ch;
1052
schan.u.ofdm.constellation = QAM_64;
1053
schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1054
schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1055
schan.u.ofdm.code_rate_HP = FEC_2_3;
1056
schan.u.ofdm.code_rate_LP = FEC_3_4;
1057
schan.u.ofdm.hierarchy_information = 0;
1058
1059
dib7000p_set_channel(state, &schan, 7);
1060
1061
factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1062
if (factor >= 5000)
1063
factor = 1;
1064
else
1065
factor = 6;
1066
1067
value = 30 * internal * factor;
1068
dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1069
dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1070
value = 100 * internal * factor;
1071
dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1072
dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1073
value = 500 * internal * factor;
1074
dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1075
dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1076
1077
value = dib7000p_read_word(state, 0);
1078
dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1079
dib7000p_read_word(state, 1284);
1080
dib7000p_write_word(state, 0, (u16) value);
1081
1082
return 0;
1083
}
1084
1085
static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1086
{
1087
struct dib7000p_state *state = demod->demodulator_priv;
1088
u16 irq_pending = dib7000p_read_word(state, 1284);
1089
1090
if (irq_pending & 0x1)
1091
return 1;
1092
1093
if (irq_pending & 0x2)
1094
return 2;
1095
1096
return 0;
1097
}
1098
1099
static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1100
{
1101
static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1102
static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1103
24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1104
53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1105
82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1106
107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1107
128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1108
147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1109
166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1110
183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1111
199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1112
213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1113
225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1114
235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1115
244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1116
250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1117
254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1118
255, 255, 255, 255, 255, 255
1119
};
1120
1121
u32 xtal = state->cfg.bw->xtal_hz / 1000;
1122
int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1123
int k;
1124
int coef_re[8], coef_im[8];
1125
int bw_khz = bw;
1126
u32 pha;
1127
1128
dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1129
1130
if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1131
return;
1132
1133
bw_khz /= 100;
1134
1135
dib7000p_write_word(state, 142, 0x0610);
1136
1137
for (k = 0; k < 8; k++) {
1138
pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1139
1140
if (pha == 0) {
1141
coef_re[k] = 256;
1142
coef_im[k] = 0;
1143
} else if (pha < 256) {
1144
coef_re[k] = sine[256 - (pha & 0xff)];
1145
coef_im[k] = sine[pha & 0xff];
1146
} else if (pha == 256) {
1147
coef_re[k] = 0;
1148
coef_im[k] = 256;
1149
} else if (pha < 512) {
1150
coef_re[k] = -sine[pha & 0xff];
1151
coef_im[k] = sine[256 - (pha & 0xff)];
1152
} else if (pha == 512) {
1153
coef_re[k] = -256;
1154
coef_im[k] = 0;
1155
} else if (pha < 768) {
1156
coef_re[k] = -sine[256 - (pha & 0xff)];
1157
coef_im[k] = -sine[pha & 0xff];
1158
} else if (pha == 768) {
1159
coef_re[k] = 0;
1160
coef_im[k] = -256;
1161
} else {
1162
coef_re[k] = sine[pha & 0xff];
1163
coef_im[k] = -sine[256 - (pha & 0xff)];
1164
}
1165
1166
coef_re[k] *= notch[k];
1167
coef_re[k] += (1 << 14);
1168
if (coef_re[k] >= (1 << 24))
1169
coef_re[k] = (1 << 24) - 1;
1170
coef_re[k] /= (1 << 15);
1171
1172
coef_im[k] *= notch[k];
1173
coef_im[k] += (1 << 14);
1174
if (coef_im[k] >= (1 << 24))
1175
coef_im[k] = (1 << 24) - 1;
1176
coef_im[k] /= (1 << 15);
1177
1178
dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1179
1180
dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1181
dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1182
dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1183
}
1184
dib7000p_write_word(state, 143, 0);
1185
}
1186
1187
static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1188
{
1189
struct dib7000p_state *state = demod->demodulator_priv;
1190
u16 tmp = 0;
1191
1192
if (ch != NULL)
1193
dib7000p_set_channel(state, ch, 0);
1194
else
1195
return -EINVAL;
1196
1197
// restart demod
1198
dib7000p_write_word(state, 770, 0x4000);
1199
dib7000p_write_word(state, 770, 0x0000);
1200
msleep(45);
1201
1202
/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1203
tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1204
if (state->sfn_workaround_active) {
1205
dprintk("SFN workaround is active");
1206
tmp |= (1 << 9);
1207
dib7000p_write_word(state, 166, 0x4000);
1208
} else {
1209
dib7000p_write_word(state, 166, 0x0000);
1210
}
1211
dib7000p_write_word(state, 29, tmp);
1212
1213
// never achieved a lock with that bandwidth so far - wait for osc-freq to update
1214
if (state->timf == 0)
1215
msleep(200);
1216
1217
/* offset loop parameters */
1218
1219
/* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1220
tmp = (6 << 8) | 0x80;
1221
switch (ch->u.ofdm.transmission_mode) {
1222
case TRANSMISSION_MODE_2K:
1223
tmp |= (2 << 12);
1224
break;
1225
case TRANSMISSION_MODE_4K:
1226
tmp |= (3 << 12);
1227
break;
1228
default:
1229
case TRANSMISSION_MODE_8K:
1230
tmp |= (4 << 12);
1231
break;
1232
}
1233
dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1234
1235
/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1236
tmp = (0 << 4);
1237
switch (ch->u.ofdm.transmission_mode) {
1238
case TRANSMISSION_MODE_2K:
1239
tmp |= 0x6;
1240
break;
1241
case TRANSMISSION_MODE_4K:
1242
tmp |= 0x7;
1243
break;
1244
default:
1245
case TRANSMISSION_MODE_8K:
1246
tmp |= 0x8;
1247
break;
1248
}
1249
dib7000p_write_word(state, 32, tmp);
1250
1251
/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1252
tmp = (0 << 4);
1253
switch (ch->u.ofdm.transmission_mode) {
1254
case TRANSMISSION_MODE_2K:
1255
tmp |= 0x6;
1256
break;
1257
case TRANSMISSION_MODE_4K:
1258
tmp |= 0x7;
1259
break;
1260
default:
1261
case TRANSMISSION_MODE_8K:
1262
tmp |= 0x8;
1263
break;
1264
}
1265
dib7000p_write_word(state, 33, tmp);
1266
1267
tmp = dib7000p_read_word(state, 509);
1268
if (!((tmp >> 6) & 0x1)) {
1269
/* restart the fec */
1270
tmp = dib7000p_read_word(state, 771);
1271
dib7000p_write_word(state, 771, tmp | (1 << 1));
1272
dib7000p_write_word(state, 771, tmp);
1273
msleep(40);
1274
tmp = dib7000p_read_word(state, 509);
1275
}
1276
// we achieved a lock - it's time to update the osc freq
1277
if ((tmp >> 6) & 0x1) {
1278
dib7000p_update_timf(state);
1279
/* P_timf_alpha += 2 */
1280
tmp = dib7000p_read_word(state, 26);
1281
dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1282
}
1283
1284
if (state->cfg.spur_protect)
1285
dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1286
1287
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1288
return 0;
1289
}
1290
1291
static int dib7000p_wakeup(struct dvb_frontend *demod)
1292
{
1293
struct dib7000p_state *state = demod->demodulator_priv;
1294
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1295
dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1296
if (state->version == SOC7090)
1297
dib7000p_sad_calib(state);
1298
return 0;
1299
}
1300
1301
static int dib7000p_sleep(struct dvb_frontend *demod)
1302
{
1303
struct dib7000p_state *state = demod->demodulator_priv;
1304
if (state->version == SOC7090)
1305
return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1306
return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1307
}
1308
1309
static int dib7000p_identify(struct dib7000p_state *st)
1310
{
1311
u16 value;
1312
dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1313
1314
if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1315
dprintk("wrong Vendor ID (read=0x%x)", value);
1316
return -EREMOTEIO;
1317
}
1318
1319
if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1320
dprintk("wrong Device ID (%x)", value);
1321
return -EREMOTEIO;
1322
}
1323
1324
return 0;
1325
}
1326
1327
static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1328
{
1329
struct dib7000p_state *state = fe->demodulator_priv;
1330
u16 tps = dib7000p_read_word(state, 463);
1331
1332
fep->inversion = INVERSION_AUTO;
1333
1334
fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1335
1336
switch ((tps >> 8) & 0x3) {
1337
case 0:
1338
fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1339
break;
1340
case 1:
1341
fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1342
break;
1343
/* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1344
}
1345
1346
switch (tps & 0x3) {
1347
case 0:
1348
fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1349
break;
1350
case 1:
1351
fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1352
break;
1353
case 2:
1354
fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1355
break;
1356
case 3:
1357
fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1358
break;
1359
}
1360
1361
switch ((tps >> 14) & 0x3) {
1362
case 0:
1363
fep->u.ofdm.constellation = QPSK;
1364
break;
1365
case 1:
1366
fep->u.ofdm.constellation = QAM_16;
1367
break;
1368
case 2:
1369
default:
1370
fep->u.ofdm.constellation = QAM_64;
1371
break;
1372
}
1373
1374
/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1375
/* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1376
1377
fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1378
switch ((tps >> 5) & 0x7) {
1379
case 1:
1380
fep->u.ofdm.code_rate_HP = FEC_1_2;
1381
break;
1382
case 2:
1383
fep->u.ofdm.code_rate_HP = FEC_2_3;
1384
break;
1385
case 3:
1386
fep->u.ofdm.code_rate_HP = FEC_3_4;
1387
break;
1388
case 5:
1389
fep->u.ofdm.code_rate_HP = FEC_5_6;
1390
break;
1391
case 7:
1392
default:
1393
fep->u.ofdm.code_rate_HP = FEC_7_8;
1394
break;
1395
1396
}
1397
1398
switch ((tps >> 2) & 0x7) {
1399
case 1:
1400
fep->u.ofdm.code_rate_LP = FEC_1_2;
1401
break;
1402
case 2:
1403
fep->u.ofdm.code_rate_LP = FEC_2_3;
1404
break;
1405
case 3:
1406
fep->u.ofdm.code_rate_LP = FEC_3_4;
1407
break;
1408
case 5:
1409
fep->u.ofdm.code_rate_LP = FEC_5_6;
1410
break;
1411
case 7:
1412
default:
1413
fep->u.ofdm.code_rate_LP = FEC_7_8;
1414
break;
1415
}
1416
1417
/* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1418
1419
return 0;
1420
}
1421
1422
static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1423
{
1424
struct dib7000p_state *state = fe->demodulator_priv;
1425
int time, ret;
1426
1427
if (state->version == SOC7090) {
1428
dib7090_set_diversity_in(fe, 0);
1429
dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1430
} else
1431
dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1432
1433
/* maybe the parameter has been changed */
1434
state->sfn_workaround_active = buggy_sfn_workaround;
1435
1436
if (fe->ops.tuner_ops.set_params)
1437
fe->ops.tuner_ops.set_params(fe, fep);
1438
1439
/* start up the AGC */
1440
state->agc_state = 0;
1441
do {
1442
time = dib7000p_agc_startup(fe, fep);
1443
if (time != -1)
1444
msleep(time);
1445
} while (time != -1);
1446
1447
if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1448
fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1449
int i = 800, found;
1450
1451
dib7000p_autosearch_start(fe, fep);
1452
do {
1453
msleep(1);
1454
found = dib7000p_autosearch_is_irq(fe);
1455
} while (found == 0 && i--);
1456
1457
dprintk("autosearch returns: %d", found);
1458
if (found == 0 || found == 1)
1459
return 0;
1460
1461
dib7000p_get_frontend(fe, fep);
1462
}
1463
1464
ret = dib7000p_tune(fe, fep);
1465
1466
/* make this a config parameter */
1467
if (state->version == SOC7090)
1468
dib7090_set_output_mode(fe, state->cfg.output_mode);
1469
else
1470
dib7000p_set_output_mode(state, state->cfg.output_mode);
1471
1472
return ret;
1473
}
1474
1475
static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1476
{
1477
struct dib7000p_state *state = fe->demodulator_priv;
1478
u16 lock = dib7000p_read_word(state, 509);
1479
1480
*stat = 0;
1481
1482
if (lock & 0x8000)
1483
*stat |= FE_HAS_SIGNAL;
1484
if (lock & 0x3000)
1485
*stat |= FE_HAS_CARRIER;
1486
if (lock & 0x0100)
1487
*stat |= FE_HAS_VITERBI;
1488
if (lock & 0x0010)
1489
*stat |= FE_HAS_SYNC;
1490
if ((lock & 0x0038) == 0x38)
1491
*stat |= FE_HAS_LOCK;
1492
1493
return 0;
1494
}
1495
1496
static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1497
{
1498
struct dib7000p_state *state = fe->demodulator_priv;
1499
*ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1500
return 0;
1501
}
1502
1503
static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1504
{
1505
struct dib7000p_state *state = fe->demodulator_priv;
1506
*unc = dib7000p_read_word(state, 506);
1507
return 0;
1508
}
1509
1510
static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1511
{
1512
struct dib7000p_state *state = fe->demodulator_priv;
1513
u16 val = dib7000p_read_word(state, 394);
1514
*strength = 65535 - val;
1515
return 0;
1516
}
1517
1518
static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1519
{
1520
struct dib7000p_state *state = fe->demodulator_priv;
1521
u16 val;
1522
s32 signal_mant, signal_exp, noise_mant, noise_exp;
1523
u32 result = 0;
1524
1525
val = dib7000p_read_word(state, 479);
1526
noise_mant = (val >> 4) & 0xff;
1527
noise_exp = ((val & 0xf) << 2);
1528
val = dib7000p_read_word(state, 480);
1529
noise_exp += ((val >> 14) & 0x3);
1530
if ((noise_exp & 0x20) != 0)
1531
noise_exp -= 0x40;
1532
1533
signal_mant = (val >> 6) & 0xFF;
1534
signal_exp = (val & 0x3F);
1535
if ((signal_exp & 0x20) != 0)
1536
signal_exp -= 0x40;
1537
1538
if (signal_mant != 0)
1539
result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1540
else
1541
result = intlog10(2) * 10 * signal_exp - 100;
1542
1543
if (noise_mant != 0)
1544
result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1545
else
1546
result -= intlog10(2) * 10 * noise_exp - 100;
1547
1548
*snr = result / ((1 << 24) / 10);
1549
return 0;
1550
}
1551
1552
static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1553
{
1554
tune->min_delay_ms = 1000;
1555
return 0;
1556
}
1557
1558
static void dib7000p_release(struct dvb_frontend *demod)
1559
{
1560
struct dib7000p_state *st = demod->demodulator_priv;
1561
dibx000_exit_i2c_master(&st->i2c_master);
1562
i2c_del_adapter(&st->dib7090_tuner_adap);
1563
kfree(st);
1564
}
1565
1566
int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1567
{
1568
u8 *tx, *rx;
1569
struct i2c_msg msg[2] = {
1570
{.addr = 18 >> 1, .flags = 0, .len = 2},
1571
{.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1572
};
1573
int ret = 0;
1574
1575
tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1576
if (!tx)
1577
return -ENOMEM;
1578
rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1579
if (!rx) {
1580
goto rx_memory_error;
1581
ret = -ENOMEM;
1582
}
1583
1584
msg[0].buf = tx;
1585
msg[1].buf = rx;
1586
1587
tx[0] = 0x03;
1588
tx[1] = 0x00;
1589
1590
if (i2c_transfer(i2c_adap, msg, 2) == 2)
1591
if (rx[0] == 0x01 && rx[1] == 0xb3) {
1592
dprintk("-D- DiB7000PC detected");
1593
return 1;
1594
}
1595
1596
msg[0].addr = msg[1].addr = 0x40;
1597
1598
if (i2c_transfer(i2c_adap, msg, 2) == 2)
1599
if (rx[0] == 0x01 && rx[1] == 0xb3) {
1600
dprintk("-D- DiB7000PC detected");
1601
return 1;
1602
}
1603
1604
dprintk("-D- DiB7000PC not detected");
1605
1606
kfree(rx);
1607
rx_memory_error:
1608
kfree(tx);
1609
return ret;
1610
}
1611
EXPORT_SYMBOL(dib7000pc_detection);
1612
1613
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1614
{
1615
struct dib7000p_state *st = demod->demodulator_priv;
1616
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1617
}
1618
EXPORT_SYMBOL(dib7000p_get_i2c_master);
1619
1620
int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1621
{
1622
struct dib7000p_state *state = fe->demodulator_priv;
1623
u16 val = dib7000p_read_word(state, 235) & 0xffef;
1624
val |= (onoff & 0x1) << 4;
1625
dprintk("PID filter enabled %d", onoff);
1626
return dib7000p_write_word(state, 235, val);
1627
}
1628
EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1629
1630
int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1631
{
1632
struct dib7000p_state *state = fe->demodulator_priv;
1633
dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1634
return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1635
}
1636
EXPORT_SYMBOL(dib7000p_pid_filter);
1637
1638
int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1639
{
1640
struct dib7000p_state *dpst;
1641
int k = 0;
1642
u8 new_addr = 0;
1643
1644
dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1645
if (!dpst)
1646
return -ENOMEM;
1647
1648
dpst->i2c_adap = i2c;
1649
1650
for (k = no_of_demods - 1; k >= 0; k--) {
1651
dpst->cfg = cfg[k];
1652
1653
/* designated i2c address */
1654
if (cfg[k].default_i2c_addr != 0)
1655
new_addr = cfg[k].default_i2c_addr + (k << 1);
1656
else
1657
new_addr = (0x40 + k) << 1;
1658
dpst->i2c_addr = new_addr;
1659
dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1660
if (dib7000p_identify(dpst) != 0) {
1661
dpst->i2c_addr = default_addr;
1662
dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1663
if (dib7000p_identify(dpst) != 0) {
1664
dprintk("DiB7000P #%d: not identified\n", k);
1665
kfree(dpst);
1666
return -EIO;
1667
}
1668
}
1669
1670
/* start diversity to pull_down div_str - just for i2c-enumeration */
1671
dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1672
1673
/* set new i2c address and force divstart */
1674
dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1675
1676
dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1677
}
1678
1679
for (k = 0; k < no_of_demods; k++) {
1680
dpst->cfg = cfg[k];
1681
if (cfg[k].default_i2c_addr != 0)
1682
dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1683
else
1684
dpst->i2c_addr = (0x40 + k) << 1;
1685
1686
// unforce divstr
1687
dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1688
1689
/* deactivate div - it was just for i2c-enumeration */
1690
dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1691
}
1692
1693
kfree(dpst);
1694
return 0;
1695
}
1696
EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1697
1698
static const s32 lut_1000ln_mant[] = {
1699
6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1700
};
1701
1702
static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1703
{
1704
struct dib7000p_state *state = fe->demodulator_priv;
1705
u32 tmp_val = 0, exp = 0, mant = 0;
1706
s32 pow_i;
1707
u16 buf[2];
1708
u8 ix = 0;
1709
1710
buf[0] = dib7000p_read_word(state, 0x184);
1711
buf[1] = dib7000p_read_word(state, 0x185);
1712
pow_i = (buf[0] << 16) | buf[1];
1713
dprintk("raw pow_i = %d", pow_i);
1714
1715
tmp_val = pow_i;
1716
while (tmp_val >>= 1)
1717
exp++;
1718
1719
mant = (pow_i * 1000 / (1 << exp));
1720
dprintk(" mant = %d exp = %d", mant / 1000, exp);
1721
1722
ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1723
dprintk(" ix = %d", ix);
1724
1725
pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1726
pow_i = (pow_i << 8) / 1000;
1727
dprintk(" pow_i = %d", pow_i);
1728
1729
return pow_i;
1730
}
1731
1732
static int map_addr_to_serpar_number(struct i2c_msg *msg)
1733
{
1734
if ((msg->buf[0] <= 15))
1735
msg->buf[0] -= 1;
1736
else if (msg->buf[0] == 17)
1737
msg->buf[0] = 15;
1738
else if (msg->buf[0] == 16)
1739
msg->buf[0] = 17;
1740
else if (msg->buf[0] == 19)
1741
msg->buf[0] = 16;
1742
else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1743
msg->buf[0] -= 3;
1744
else if (msg->buf[0] == 28)
1745
msg->buf[0] = 23;
1746
else
1747
return -EINVAL;
1748
return 0;
1749
}
1750
1751
static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1752
{
1753
struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1754
u8 n_overflow = 1;
1755
u16 i = 1000;
1756
u16 serpar_num = msg[0].buf[0];
1757
1758
while (n_overflow == 1 && i) {
1759
n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1760
i--;
1761
if (i == 0)
1762
dprintk("Tuner ITF: write busy (overflow)");
1763
}
1764
dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1765
dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1766
1767
return num;
1768
}
1769
1770
static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1771
{
1772
struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1773
u8 n_overflow = 1, n_empty = 1;
1774
u16 i = 1000;
1775
u16 serpar_num = msg[0].buf[0];
1776
u16 read_word;
1777
1778
while (n_overflow == 1 && i) {
1779
n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1780
i--;
1781
if (i == 0)
1782
dprintk("TunerITF: read busy (overflow)");
1783
}
1784
dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1785
1786
i = 1000;
1787
while (n_empty == 1 && i) {
1788
n_empty = dib7000p_read_word(state, 1984) & 0x1;
1789
i--;
1790
if (i == 0)
1791
dprintk("TunerITF: read busy (empty)");
1792
}
1793
read_word = dib7000p_read_word(state, 1987);
1794
msg[1].buf[0] = (read_word >> 8) & 0xff;
1795
msg[1].buf[1] = (read_word) & 0xff;
1796
1797
return num;
1798
}
1799
1800
static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1801
{
1802
if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1803
if (num == 1) { /* write */
1804
return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1805
} else { /* read */
1806
return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1807
}
1808
}
1809
return num;
1810
}
1811
1812
int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1813
{
1814
struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1815
u16 word;
1816
1817
if (num == 1) { /* write */
1818
dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1819
} else {
1820
word = dib7000p_read_word(state, apb_address);
1821
msg[1].buf[0] = (word >> 8) & 0xff;
1822
msg[1].buf[1] = (word) & 0xff;
1823
}
1824
1825
return num;
1826
}
1827
1828
static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1829
{
1830
struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1831
1832
u16 apb_address = 0, word;
1833
int i = 0;
1834
switch (msg[0].buf[0]) {
1835
case 0x12:
1836
apb_address = 1920;
1837
break;
1838
case 0x14:
1839
apb_address = 1921;
1840
break;
1841
case 0x24:
1842
apb_address = 1922;
1843
break;
1844
case 0x1a:
1845
apb_address = 1923;
1846
break;
1847
case 0x22:
1848
apb_address = 1924;
1849
break;
1850
case 0x33:
1851
apb_address = 1926;
1852
break;
1853
case 0x34:
1854
apb_address = 1927;
1855
break;
1856
case 0x35:
1857
apb_address = 1928;
1858
break;
1859
case 0x36:
1860
apb_address = 1929;
1861
break;
1862
case 0x37:
1863
apb_address = 1930;
1864
break;
1865
case 0x38:
1866
apb_address = 1931;
1867
break;
1868
case 0x39:
1869
apb_address = 1932;
1870
break;
1871
case 0x2a:
1872
apb_address = 1935;
1873
break;
1874
case 0x2b:
1875
apb_address = 1936;
1876
break;
1877
case 0x2c:
1878
apb_address = 1937;
1879
break;
1880
case 0x2d:
1881
apb_address = 1938;
1882
break;
1883
case 0x2e:
1884
apb_address = 1939;
1885
break;
1886
case 0x2f:
1887
apb_address = 1940;
1888
break;
1889
case 0x30:
1890
apb_address = 1941;
1891
break;
1892
case 0x31:
1893
apb_address = 1942;
1894
break;
1895
case 0x32:
1896
apb_address = 1943;
1897
break;
1898
case 0x3e:
1899
apb_address = 1944;
1900
break;
1901
case 0x3f:
1902
apb_address = 1945;
1903
break;
1904
case 0x40:
1905
apb_address = 1948;
1906
break;
1907
case 0x25:
1908
apb_address = 914;
1909
break;
1910
case 0x26:
1911
apb_address = 915;
1912
break;
1913
case 0x27:
1914
apb_address = 916;
1915
break;
1916
case 0x28:
1917
apb_address = 917;
1918
break;
1919
case 0x1d:
1920
i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1921
word = dib7000p_read_word(state, 384 + i);
1922
msg[1].buf[0] = (word >> 8) & 0xff;
1923
msg[1].buf[1] = (word) & 0xff;
1924
return num;
1925
case 0x1f:
1926
if (num == 1) { /* write */
1927
word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1928
word &= 0x3;
1929
word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1930
dib7000p_write_word(state, 72, word); /* Set the proper input */
1931
return num;
1932
}
1933
}
1934
1935
if (apb_address != 0) /* R/W acces via APB */
1936
return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1937
else /* R/W access via SERPAR */
1938
return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1939
1940
return 0;
1941
}
1942
1943
static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1944
{
1945
return I2C_FUNC_I2C;
1946
}
1947
1948
static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1949
.master_xfer = dib7090_tuner_xfer,
1950
.functionality = dib7000p_i2c_func,
1951
};
1952
1953
struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1954
{
1955
struct dib7000p_state *st = fe->demodulator_priv;
1956
return &st->dib7090_tuner_adap;
1957
}
1958
EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1959
1960
static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1961
{
1962
u16 reg;
1963
1964
/* drive host bus 2, 3, 4 */
1965
reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1966
reg |= (drive << 12) | (drive << 6) | drive;
1967
dib7000p_write_word(state, 1798, reg);
1968
1969
/* drive host bus 5,6 */
1970
reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1971
reg |= (drive << 8) | (drive << 2);
1972
dib7000p_write_word(state, 1799, reg);
1973
1974
/* drive host bus 7, 8, 9 */
1975
reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1976
reg |= (drive << 12) | (drive << 6) | drive;
1977
dib7000p_write_word(state, 1800, reg);
1978
1979
/* drive host bus 10, 11 */
1980
reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1981
reg |= (drive << 8) | (drive << 2);
1982
dib7000p_write_word(state, 1801, reg);
1983
1984
/* drive host bus 12, 13, 14 */
1985
reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1986
reg |= (drive << 12) | (drive << 6) | drive;
1987
dib7000p_write_word(state, 1802, reg);
1988
1989
return 0;
1990
}
1991
1992
static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1993
{
1994
u32 quantif = 3;
1995
u32 nom = (insertExtSynchro * P_Kin + syncSize);
1996
u32 denom = P_Kout;
1997
u32 syncFreq = ((nom << quantif) / denom);
1998
1999
if ((syncFreq & ((1 << quantif) - 1)) != 0)
2000
syncFreq = (syncFreq >> quantif) + 1;
2001
else
2002
syncFreq = (syncFreq >> quantif);
2003
2004
if (syncFreq != 0)
2005
syncFreq = syncFreq - 1;
2006
2007
return syncFreq;
2008
}
2009
2010
static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2011
{
2012
u8 index_buf;
2013
u16 rx_copy_buf[22];
2014
2015
dprintk("Configure DibStream Tx");
2016
for (index_buf = 0; index_buf < 22; index_buf++)
2017
rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2018
2019
dib7000p_write_word(state, 1615, 1);
2020
dib7000p_write_word(state, 1603, P_Kin);
2021
dib7000p_write_word(state, 1605, P_Kout);
2022
dib7000p_write_word(state, 1606, insertExtSynchro);
2023
dib7000p_write_word(state, 1608, synchroMode);
2024
dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2025
dib7000p_write_word(state, 1610, syncWord & 0xffff);
2026
dib7000p_write_word(state, 1612, syncSize);
2027
dib7000p_write_word(state, 1615, 0);
2028
2029
for (index_buf = 0; index_buf < 22; index_buf++)
2030
dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2031
2032
return 0;
2033
}
2034
2035
static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2036
u32 dataOutRate)
2037
{
2038
u32 syncFreq;
2039
2040
dprintk("Configure DibStream Rx");
2041
if ((P_Kin != 0) && (P_Kout != 0)) {
2042
syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2043
dib7000p_write_word(state, 1542, syncFreq);
2044
}
2045
dib7000p_write_word(state, 1554, 1);
2046
dib7000p_write_word(state, 1536, P_Kin);
2047
dib7000p_write_word(state, 1537, P_Kout);
2048
dib7000p_write_word(state, 1539, synchroMode);
2049
dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2050
dib7000p_write_word(state, 1541, syncWord & 0xffff);
2051
dib7000p_write_word(state, 1543, syncSize);
2052
dib7000p_write_word(state, 1544, dataOutRate);
2053
dib7000p_write_word(state, 1554, 0);
2054
2055
return 0;
2056
}
2057
2058
static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2059
{
2060
u16 reg;
2061
2062
dprintk("Enable Diversity on host bus");
2063
reg = (1 << 8) | (1 << 5);
2064
dib7000p_write_word(state, 1288, reg);
2065
2066
return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2067
}
2068
2069
static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2070
{
2071
u16 reg;
2072
2073
dprintk("Enable ADC on host bus");
2074
reg = (1 << 7) | (1 << 5);
2075
dib7000p_write_word(state, 1288, reg);
2076
2077
return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2078
}
2079
2080
static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2081
{
2082
u16 reg;
2083
2084
dprintk("Enable Mpeg on host bus");
2085
reg = (1 << 9) | (1 << 5);
2086
dib7000p_write_word(state, 1288, reg);
2087
2088
return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2089
}
2090
2091
static int dib7090_enMpegInput(struct dib7000p_state *state)
2092
{
2093
dprintk("Enable Mpeg input");
2094
return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2095
}
2096
2097
static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2098
{
2099
u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2100
2101
dprintk("Enable Mpeg mux");
2102
dib7000p_write_word(state, 1287, reg);
2103
2104
reg &= ~(1 << 7);
2105
dib7000p_write_word(state, 1287, reg);
2106
2107
reg = (1 << 4);
2108
dib7000p_write_word(state, 1288, reg);
2109
2110
return 0;
2111
}
2112
2113
static int dib7090_disableMpegMux(struct dib7000p_state *state)
2114
{
2115
u16 reg;
2116
2117
dprintk("Disable Mpeg mux");
2118
dib7000p_write_word(state, 1288, 0);
2119
2120
reg = dib7000p_read_word(state, 1287);
2121
reg &= ~(1 << 7);
2122
dib7000p_write_word(state, 1287, reg);
2123
2124
return 0;
2125
}
2126
2127
static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2128
{
2129
struct dib7000p_state *state = fe->demodulator_priv;
2130
2131
switch (mode) {
2132
case INPUT_MODE_DIVERSITY:
2133
dprintk("Enable diversity INPUT");
2134
dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2135
break;
2136
case INPUT_MODE_MPEG:
2137
dprintk("Enable Mpeg INPUT");
2138
dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2139
break;
2140
case INPUT_MODE_OFF:
2141
default:
2142
dprintk("Disable INPUT");
2143
dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2144
break;
2145
}
2146
return 0;
2147
}
2148
2149
static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2150
{
2151
switch (onoff) {
2152
case 0: /* only use the internal way - not the diversity input */
2153
dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2154
break;
2155
case 1: /* both ways */
2156
case 2: /* only the diversity input */
2157
dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2158
break;
2159
}
2160
2161
return 0;
2162
}
2163
2164
static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2165
{
2166
struct dib7000p_state *state = fe->demodulator_priv;
2167
2168
u16 outreg, smo_mode, fifo_threshold;
2169
u8 prefer_mpeg_mux_use = 1;
2170
int ret = 0;
2171
2172
dib7090_host_bus_drive(state, 1);
2173
2174
fifo_threshold = 1792;
2175
smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2176
outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2177
2178
switch (mode) {
2179
case OUTMODE_HIGH_Z:
2180
outreg = 0;
2181
break;
2182
2183
case OUTMODE_MPEG2_SERIAL:
2184
if (prefer_mpeg_mux_use) {
2185
dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2186
dib7090_enMpegOnHostBus(state);
2187
dib7090_enMpegInput(state);
2188
if (state->cfg.enMpegOutput == 1)
2189
dib7090_enMpegMux(state, 3, 1, 1);
2190
2191
} else { /* Use Smooth block */
2192
dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2193
dib7090_disableMpegMux(state);
2194
dib7000p_write_word(state, 1288, (1 << 6));
2195
outreg |= (2 << 6) | (0 << 1);
2196
}
2197
break;
2198
2199
case OUTMODE_MPEG2_PAR_GATED_CLK:
2200
if (prefer_mpeg_mux_use) {
2201
dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2202
dib7090_enMpegOnHostBus(state);
2203
dib7090_enMpegInput(state);
2204
if (state->cfg.enMpegOutput == 1)
2205
dib7090_enMpegMux(state, 2, 0, 0);
2206
} else { /* Use Smooth block */
2207
dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2208
dib7090_disableMpegMux(state);
2209
dib7000p_write_word(state, 1288, (1 << 6));
2210
outreg |= (0 << 6);
2211
}
2212
break;
2213
2214
case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2215
dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2216
dib7090_disableMpegMux(state);
2217
dib7000p_write_word(state, 1288, (1 << 6));
2218
outreg |= (1 << 6);
2219
break;
2220
2221
case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2222
dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2223
dib7090_disableMpegMux(state);
2224
dib7000p_write_word(state, 1288, (1 << 6));
2225
outreg |= (5 << 6);
2226
smo_mode |= (3 << 1);
2227
fifo_threshold = 512;
2228
break;
2229
2230
case OUTMODE_DIVERSITY:
2231
dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2232
dib7090_disableMpegMux(state);
2233
dib7090_enDivOnHostBus(state);
2234
break;
2235
2236
case OUTMODE_ANALOG_ADC:
2237
dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2238
dib7090_enAdcOnHostBus(state);
2239
break;
2240
}
2241
2242
if (state->cfg.output_mpeg2_in_188_bytes)
2243
smo_mode |= (1 << 5);
2244
2245
ret |= dib7000p_write_word(state, 235, smo_mode);
2246
ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2247
ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2248
2249
return ret;
2250
}
2251
2252
int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2253
{
2254
struct dib7000p_state *state = fe->demodulator_priv;
2255
u16 en_cur_state;
2256
2257
dprintk("sleep dib7090: %d", onoff);
2258
2259
en_cur_state = dib7000p_read_word(state, 1922);
2260
2261
if (en_cur_state > 0xff)
2262
state->tuner_enable = en_cur_state;
2263
2264
if (onoff)
2265
en_cur_state &= 0x00ff;
2266
else {
2267
if (state->tuner_enable != 0)
2268
en_cur_state = state->tuner_enable;
2269
}
2270
2271
dib7000p_write_word(state, 1922, en_cur_state);
2272
2273
return 0;
2274
}
2275
EXPORT_SYMBOL(dib7090_tuner_sleep);
2276
2277
int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2278
{
2279
dprintk("AGC restart callback: %d", restart);
2280
return 0;
2281
}
2282
EXPORT_SYMBOL(dib7090_agc_restart);
2283
2284
int dib7090_get_adc_power(struct dvb_frontend *fe)
2285
{
2286
return dib7000p_get_adc_power(fe);
2287
}
2288
EXPORT_SYMBOL(dib7090_get_adc_power);
2289
2290
int dib7090_slave_reset(struct dvb_frontend *fe)
2291
{
2292
struct dib7000p_state *state = fe->demodulator_priv;
2293
u16 reg;
2294
2295
reg = dib7000p_read_word(state, 1794);
2296
dib7000p_write_word(state, 1794, reg | (4 << 12));
2297
2298
dib7000p_write_word(state, 1032, 0xffff);
2299
return 0;
2300
}
2301
EXPORT_SYMBOL(dib7090_slave_reset);
2302
2303
static struct dvb_frontend_ops dib7000p_ops;
2304
struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2305
{
2306
struct dvb_frontend *demod;
2307
struct dib7000p_state *st;
2308
st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2309
if (st == NULL)
2310
return NULL;
2311
2312
memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2313
st->i2c_adap = i2c_adap;
2314
st->i2c_addr = i2c_addr;
2315
st->gpio_val = cfg->gpio_val;
2316
st->gpio_dir = cfg->gpio_dir;
2317
2318
/* Ensure the output mode remains at the previous default if it's
2319
* not specifically set by the caller.
2320
*/
2321
if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2322
st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2323
2324
demod = &st->demod;
2325
demod->demodulator_priv = st;
2326
memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2327
2328
dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2329
2330
if (dib7000p_identify(st) != 0)
2331
goto error;
2332
2333
st->version = dib7000p_read_word(st, 897);
2334
2335
/* FIXME: make sure the dev.parent field is initialized, or else
2336
request_firmware() will hit an OOPS (this should be moved somewhere
2337
more common) */
2338
2339
dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2340
2341
/* init 7090 tuner adapter */
2342
strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2343
st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2344
st->dib7090_tuner_adap.algo_data = NULL;
2345
st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2346
i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2347
i2c_add_adapter(&st->dib7090_tuner_adap);
2348
2349
dib7000p_demod_reset(st);
2350
2351
if (st->version == SOC7090) {
2352
dib7090_set_output_mode(demod, st->cfg.output_mode);
2353
dib7090_set_diversity_in(demod, 0);
2354
}
2355
2356
return demod;
2357
2358
error:
2359
kfree(st);
2360
return NULL;
2361
}
2362
EXPORT_SYMBOL(dib7000p_attach);
2363
2364
static struct dvb_frontend_ops dib7000p_ops = {
2365
.info = {
2366
.name = "DiBcom 7000PC",
2367
.type = FE_OFDM,
2368
.frequency_min = 44250000,
2369
.frequency_max = 867250000,
2370
.frequency_stepsize = 62500,
2371
.caps = FE_CAN_INVERSION_AUTO |
2372
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2373
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2374
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2375
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2376
},
2377
2378
.release = dib7000p_release,
2379
2380
.init = dib7000p_wakeup,
2381
.sleep = dib7000p_sleep,
2382
2383
.set_frontend = dib7000p_set_frontend,
2384
.get_tune_settings = dib7000p_fe_get_tune_settings,
2385
.get_frontend = dib7000p_get_frontend,
2386
2387
.read_status = dib7000p_read_status,
2388
.read_ber = dib7000p_read_ber,
2389
.read_signal_strength = dib7000p_read_signal_strength,
2390
.read_snr = dib7000p_read_snr,
2391
.read_ucblocks = dib7000p_read_unc_blocks,
2392
};
2393
2394
MODULE_AUTHOR("Olivier Grenie <[email protected]>");
2395
MODULE_AUTHOR("Patrick Boettcher <[email protected]>");
2396
MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2397
MODULE_LICENSE("GPL");
2398
2399