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