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