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