V4L/DVB: Complete rewrite of the DiB3000mc-driver
[pandora-kernel.git] / drivers / media / dvb / frontends / dib3000mc.c
1 /*
2  * Driver for DiBcom DiB3000MC/P-demodulator.
3  *
4  * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6  *
7  * This code is partially based on the previous dib3000mc.c .
8  *
9  * This program is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU General Public License as
11  *      published by the Free Software Foundation, version 2.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/i2c.h>
16 //#include <linux/init.h>
17 //#include <linux/delay.h>
18 //#include <linux/string.h>
19 //#include <linux/slab.h>
20
21 #include "dvb_frontend.h"
22
23 #include "dib3000mc.h"
24
25 static int debug;
26 module_param(debug, int, 0644);
27 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
28
29 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
30
31 struct dib3000mc_state {
32         struct dvb_frontend demod;
33         struct dib3000mc_config *cfg;
34
35         u8 i2c_addr;
36         struct i2c_adapter *i2c_adap;
37
38         struct dibx000_i2c_master i2c_master;
39
40         fe_bandwidth_t current_bandwidth;
41
42         u16 dev_id;
43 };
44
45 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
46 {
47         u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
48         u8 rb[2];
49         struct i2c_msg msg[2] = {
50                 { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
51                 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
52         };
53
54         if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
55                 dprintk("i2c read error on %d\n",reg);
56
57         return (rb[0] << 8) | rb[1];
58 }
59
60 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
61 {
62         u8 b[4] = {
63                 (reg >> 8) & 0xff, reg & 0xff,
64                 (val >> 8) & 0xff, val & 0xff,
65         };
66         struct i2c_msg msg = {
67                 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
68         };
69         return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
70 }
71
72 static void dump_fep(struct dibx000_ofdm_channel *cd)
73 {
74         printk(KERN_DEBUG "DiB3000MC: ");
75         switch (cd->nfft) {
76                 case 1: printk("8K "); break;
77                 case 2: printk("4K "); break;
78                 case 0: printk("2K "); break;
79                 default: printk("FFT_UNK "); break;
80         }
81
82         printk("1/%i  ", 32 / (1 << cd->guard));
83         switch (cd->nqam) {
84                 case 0: printk("QPSK "); break;
85                 case 1: printk("16QAM "); break;
86                 case 2: printk("64QAM "); break;
87                 default: printk("QAM_UNK "); break;
88         }
89         printk("ALPHA %i ", cd->vit_alpha);
90         printk("Code Rate HP %i/%i ", cd->vit_code_rate_hp, cd->vit_code_rate_hp + 1);
91         printk("Code Rate LP %i/%i ", cd->vit_code_rate_lp, cd->vit_code_rate_lp + 1);
92         printk("HRCH %i\n", cd->vit_hrch);
93 }
94
95
96 static int dib3000mc_identify(struct dib3000mc_state *state)
97 {
98         u16 value;
99         if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
100                 dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
101                 return -EREMOTEIO;
102         }
103
104         value = dib3000mc_read_word(state, 1026);
105         if (value != 0x3001 && value != 0x3002) {
106                 dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
107                 return -EREMOTEIO;
108         }
109         state->dev_id = value;
110
111         dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);
112
113         return 0;
114 }
115
116 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
117 {
118 /*
119         u32 timf_msb, timf_lsb, i;
120         int tim_sgn ;
121         LUInt comp1, comp2, comp ;
122 //      u32 tim_offset ;
123         comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
124         timf_msb = (comp >> 16) & 0x00FF;
125         timf_lsb =  comp        & 0xFFFF;
126
127         // Update the timing offset ;
128         if (update_offset) {
129                 if (state->timing_offset_comp_done == 0) {
130                         usleep(200000);
131                         state->timing_offset_comp_done = 1;
132                 }
133                 tim_offset = dib3000mc_read_word(state, 416);
134                 if ((tim_offset & 0x2000) == 0x2000)
135                         tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
136
137                 if (nfft == 0)
138                         tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
139                 state->timing_offset += tim_offset;
140         }
141         tim_offset = state->timing_offset;
142
143         if (tim_offset < 0) {
144                 tim_sgn = 1;
145                 tim_offset = -tim_offset;
146         } else
147                 tim_sgn = 0;
148
149         comp1 = tim_offset * timf_lsb;
150         comp2 = tim_offset * timf_msb;
151         comp  = ((comp1 >> 16) + comp2) >> 7;
152
153         if (tim_sgn == 0)
154                 comp = timf_msb * (1<<16) + timf_lsb + comp;
155         else
156                 comp = timf_msb * (1<<16) + timf_lsb - comp;
157
158         timf_msb = (comp>>16)&0xFF ;
159         timf_lsb = comp&0xFFFF;
160 */
161         u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
162
163         dib3000mc_write_word(state, 23, timf >> 16);
164         dib3000mc_write_word(state, 24, timf & 0xffff);
165
166         return 0;
167 }
168
169 static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
170 {
171     if (state->cfg->pwm3_inversion) {
172                 dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
173                 dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
174         } else {
175                 dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
176                 dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
177         }
178
179     if (state->cfg->use_pwm3)
180                 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
181         else
182                 dib3000mc_write_word(state, 245, 0);
183
184     dib3000mc_write_word(state, 1040, 0x3);
185         return 0;
186 }
187
188 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
189 {
190         int    ret = 0;
191         u16 fifo_threshold = 1792;
192         u16 outreg = 0;
193         u16 outmode = 0;
194         u16 elecout = 1;
195         u16 smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 1) | 0 ; //smo_mode = 1
196
197         dprintk("-I-  Setting output mode for demod %p to %d\n",
198                         &state->demod, mode);
199
200         switch (mode) {
201                 case OUTMODE_HIGH_Z:  // disable
202                         elecout = 0;
203                         break;
204                 case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
205                         outmode = 0;
206                         break;
207                 case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
208                         outmode = 1;
209                         break;
210                 case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
211                         outmode = 2;
212                         break;
213                 case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
214                         elecout = 3;
215                         /*ADDR @ 206 :
216                         P_smo_error_discard  [1;6:6] = 0
217                         P_smo_rs_discard     [1;5:5] = 0
218                         P_smo_pid_parse      [1;4:4] = 0
219                         P_smo_fifo_flush     [1;3:3] = 0
220                         P_smo_mode           [2;2:1] = 11
221                         P_smo_ovf_prot       [1;0:0] = 0
222                         */
223                         smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) |(3 << 1) | 0;
224                         fifo_threshold = 512;
225                         outmode = 5;
226                         break;
227                 case OUTMODE_DIVERSITY:
228                         outmode = 4;
229                         elecout = 1;
230                         break;
231                 default:
232                         dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
233                         outmode = 0;
234                         break;
235         }
236
237         if ((state->cfg->output_mpeg2_in_188_bytes))
238                 smo_reg |= (1 << 5) ; //P_smo_rs_discard     [1;5:5] = 1
239
240         outreg = dib3000mc_read_word(state, 244) & 0x07FF;
241         outreg |= (outmode << 11);
242         ret |= dib3000mc_write_word(state,  244, outreg);
243         ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
244         ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
245         ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
246         return ret;
247 }
248
249 static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
250 {
251         struct dib3000mc_state *state = demod->demodulator_priv;
252         u16 bw_cfg[6] = { 0 };
253         u16 imp_bw_cfg[3] = { 0 };
254         u16 reg;
255
256 /* settings here are for 27.7MHz */
257         switch (bw) {
258                 case BANDWIDTH_8_MHZ:
259                         bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
260                         imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
261                         break;
262
263                 case BANDWIDTH_7_MHZ:
264                         bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
265                         imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
266                         break;
267
268                 case BANDWIDTH_6_MHZ:
269                         bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
270                         imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
271                         break;
272
273                 case 255 /* BANDWIDTH_5_MHZ */:
274                         bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
275                         imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
276                         break;
277
278                 default: return -EINVAL;
279         }
280
281         for (reg = 6; reg < 12; reg++)
282                 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
283         dib3000mc_write_word(state, 12, 0x0000);
284         dib3000mc_write_word(state, 13, 0x03e8);
285         dib3000mc_write_word(state, 14, 0x0000);
286         dib3000mc_write_word(state, 15, 0x03f2);
287         dib3000mc_write_word(state, 16, 0x0001);
288         dib3000mc_write_word(state, 17, 0xb0d0);
289         // P_sec_len
290         dib3000mc_write_word(state, 18, 0x0393);
291         dib3000mc_write_word(state, 19, 0x8700);
292
293         for (reg = 55; reg < 58; reg++)
294                 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
295
296         // Timing configuration
297         dib3000mc_set_timing(state, 0, bw, 0);
298
299         return 0;
300 }
301
302 static u16 impulse_noise_val[29] =
303
304 {
305         0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
306         0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
307         0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
308 };
309
310 static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
311 {
312         u16 i;
313         for (i = 58; i < 87; i++)
314                 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
315
316         if (nfft == 1) {
317                 dib3000mc_write_word(state, 58, 0x3b);
318                 dib3000mc_write_word(state, 84, 0x00);
319                 dib3000mc_write_word(state, 85, 0x8200);
320         }
321
322         dib3000mc_write_word(state, 34, 0x1294);
323         dib3000mc_write_word(state, 35, 0x1ff8);
324         if (mode == 1)
325                 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
326 }
327
328 static int dib3000mc_init(struct dvb_frontend *demod)
329 {
330         struct dib3000mc_state *state = demod->demodulator_priv;
331         struct dibx000_agc_config *agc = state->cfg->agc;
332
333         // Restart Configuration
334         dib3000mc_write_word(state, 1027, 0x8000);
335         dib3000mc_write_word(state, 1027, 0x0000);
336
337         // power up the demod + mobility configuration
338         dib3000mc_write_word(state, 140, 0x0000);
339         dib3000mc_write_word(state, 1031, 0);
340
341         if (state->cfg->mobile_mode) {
342                 dib3000mc_write_word(state, 139,  0x0000);
343                 dib3000mc_write_word(state, 141,  0x0000);
344                 dib3000mc_write_word(state, 175,  0x0002);
345                 dib3000mc_write_word(state, 1032, 0x0000);
346         } else {
347                 dib3000mc_write_word(state, 139,  0x0001);
348                 dib3000mc_write_word(state, 141,  0x0000);
349                 dib3000mc_write_word(state, 175,  0x0000);
350                 dib3000mc_write_word(state, 1032, 0x012C);
351         }
352         dib3000mc_write_word(state, 1033, 0);
353
354         // P_clk_cfg
355         dib3000mc_write_word(state, 1037, 12592);
356
357         // other configurations
358
359         // P_ctrl_sfreq
360         dib3000mc_write_word(state, 33, (5 << 0));
361         dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
362
363         // Phase noise control
364         // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
365         dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
366
367         if (state->cfg->phase_noise_mode == 0)
368                 dib3000mc_write_word(state, 111, 0x00);
369         else
370                 dib3000mc_write_word(state, 111, 0x02);
371
372         // P_agc_global
373         dib3000mc_write_word(state, 50, 0x8000);
374
375         // agc setup misc
376         dib3000mc_setup_pwm3_state(state);
377
378         // P_agc_counter_lock
379         dib3000mc_write_word(state, 53, 0x87);
380         // P_agc_counter_unlock
381         dib3000mc_write_word(state, 54, 0x87);
382
383         /* agc */
384         dib3000mc_write_word(state, 36, state->cfg->max_time);
385         dib3000mc_write_word(state, 37, agc->setup);
386         dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
387         dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
388
389         // set_agc_loop_Bw
390         dib3000mc_write_word(state, 40, 0x0179);
391         dib3000mc_write_word(state, 41, 0x03f0);
392
393         dib3000mc_write_word(state, 42, agc->agc1_max);
394         dib3000mc_write_word(state, 43, agc->agc1_min);
395         dib3000mc_write_word(state, 44, agc->agc2_max);
396         dib3000mc_write_word(state, 45, agc->agc2_min);
397         dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
398         dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
399         dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
400         dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
401
402 // Begin: TimeOut registers
403         // P_pha3_thres
404         dib3000mc_write_word(state, 110, 3277);
405         // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
406         dib3000mc_write_word(state,  26, 0x6680);
407         // lock_mask0
408         dib3000mc_write_word(state, 1, 4);
409         // lock_mask1
410         dib3000mc_write_word(state, 2, 4);
411         // lock_mask2
412         dib3000mc_write_word(state, 3, 0x1000);
413         // P_search_maxtrial=1
414         dib3000mc_write_word(state, 5, 1);
415
416         dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
417
418         // div_lock_mask
419         dib3000mc_write_word(state,  4, 0x814);
420
421         dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
422         dib3000mc_write_word(state, 22, 0x463d);
423
424         // Spurious rm cfg
425         // P_cspu_regul, P_cspu_win_cut
426         dib3000mc_write_word(state, 120, 0x200f);
427         // P_adp_selec_monit
428         dib3000mc_write_word(state, 134, 0);
429
430         // Fec cfg
431         dib3000mc_write_word(state, 195, 0x10);
432
433         // diversity register: P_dvsy_sync_wait..
434         dib3000mc_write_word(state, 180, 0x2FF0);
435
436         // Impulse noise configuration
437         dib3000mc_set_impulse_noise(state, 0, 1);
438
439         // output mode set-up
440         dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
441
442         /* close the i2c-gate */
443         dib3000mc_write_word(state, 769, (1 << 7) );
444
445         return 0;
446 }
447
448 static int dib3000mc_sleep(struct dvb_frontend *demod)
449 {
450         struct dib3000mc_state *state = demod->demodulator_priv;
451
452         dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
453         dib3000mc_write_word(state, 1031, 0xFFFF);
454         dib3000mc_write_word(state, 1032, 0xFFFF);
455         dib3000mc_write_word(state, 1033, 0xFFF4);   // ****  Bin2
456
457     return 0;
458 }
459
460 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
461 {
462         u16 cfg[4] = { 0 },reg;
463         switch (qam) {
464                 case 0:
465                         cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
466                         break;
467                 case 1:
468                         cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
469                         break;
470                 case 2:
471                         cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
472                         break;
473         }
474         for (reg = 129; reg < 133; reg++)
475                 dib3000mc_write_word(state, reg, cfg[reg - 129]);
476 }
477
478 static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
479 {
480         u16 tmp;
481
482         dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
483
484 //      if (boost)
485 //              dib3000mc_write_word(state, 100, (11 << 6) + 6);
486 //      else
487                 dib3000mc_write_word(state, 100, (16 << 6) + 9);
488
489         dib3000mc_write_word(state, 1027, 0x0800);
490         dib3000mc_write_word(state, 1027, 0x0000);
491
492         //Default cfg isi offset adp
493         dib3000mc_write_word(state, 26,  0x6680);
494         dib3000mc_write_word(state, 29,  0x1273);
495         dib3000mc_write_word(state, 33,       5);
496         dib3000mc_set_adp_cfg(state, 1);
497         dib3000mc_write_word(state, 133,  15564);
498
499         dib3000mc_write_word(state, 12 , 0x0);
500         dib3000mc_write_word(state, 13 , 0x3e8);
501         dib3000mc_write_word(state, 14 , 0x0);
502         dib3000mc_write_word(state, 15 , 0x3f2);
503
504         dib3000mc_write_word(state, 93,0);
505         dib3000mc_write_word(state, 94,0);
506         dib3000mc_write_word(state, 95,0);
507         dib3000mc_write_word(state, 96,0);
508         dib3000mc_write_word(state, 97,0);
509         dib3000mc_write_word(state, 98,0);
510
511         dib3000mc_set_impulse_noise(state, 0, chan->nfft);
512
513         tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
514         dib3000mc_write_word(state, 0, tmp);
515
516         dib3000mc_write_word(state, 5, seq);
517
518         tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
519         if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
520                 tmp |= chan->vit_code_rate_hp << 1;
521         else
522                 tmp |= chan->vit_code_rate_lp << 1;
523         dib3000mc_write_word(state, 181, tmp);
524
525         // diversity synchro delay
526         tmp = dib3000mc_read_word(state, 180) & 0x000f;
527         tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
528         dib3000mc_write_word(state, 180, tmp);
529
530         // restart demod
531         tmp = dib3000mc_read_word(state, 0);
532         dib3000mc_write_word(state, 0, tmp | (1 << 9));
533         dib3000mc_write_word(state, 0, tmp);
534
535         msleep(30);
536
537         dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
538 }
539
540 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
541 {
542         struct dib3000mc_state *state = demod->demodulator_priv;
543         u16 reg;
544 //      u32 val;
545         struct dibx000_ofdm_channel fchan;
546
547         INIT_OFDM_CHANNEL(&fchan);
548         fchan = *chan;
549
550
551         /* a channel for autosearch */
552         reg = 0;
553         if (chan->nfft == -1 && chan->guard == -1) reg = 7;
554         if (chan->nfft == -1 && chan->guard != -1) reg = 2;
555         if (chan->nfft != -1 && chan->guard == -1) reg = 3;
556
557         fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
558         fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
559         fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
560
561         dib3000mc_set_channel_cfg(state, &fchan, reg);
562
563         reg = dib3000mc_read_word(state, 0);
564         dib3000mc_write_word(state, 0, reg | (1 << 8));
565         dib3000mc_write_word(state, 0, reg);
566
567         return 0;
568 }
569
570 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
571 {
572         struct dib3000mc_state *state = demod->demodulator_priv;
573         u16 irq_pending = dib3000mc_read_word(state, 511);
574
575         if (irq_pending & 0x1) // failed
576                 return 1;
577
578         if (irq_pending & 0x2) // succeeded
579                 return 2;
580
581         return 0; // still pending
582 }
583
584 static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
585 {
586         struct dib3000mc_state *state = demod->demodulator_priv;
587
588         // ** configure demod **
589         dib3000mc_set_channel_cfg(state, ch, 0);
590
591         // activates isi
592         dib3000mc_write_word(state, 29, 0x1073);
593
594         dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
595
596         if (ch->nfft == 1) {
597                 dib3000mc_write_word(state, 26, 38528);
598                 dib3000mc_write_word(state, 33, 8);
599         } else {
600                 dib3000mc_write_word(state, 26, 30336);
601                 dib3000mc_write_word(state, 33, 6);
602         }
603
604         // if (lock)
605         //      dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
606
607         return 0;
608 }
609
610 static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
611 {
612         struct dib3000mc_state *state = demod->demodulator_priv;
613         return dib3000mc_set_output_mode(state, mode);
614 }
615
616 static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
617 {
618         struct dib3000mc_state *st;
619         int k,ret=0;
620         u8 new_addr;
621
622         static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
623
624         for (k = no_of_demods-1; k >= 0; k--) {
625                 st = demod[k]->demodulator_priv;
626
627                 /* designated i2c address */
628                 new_addr          = DIB3000MC_I2C_ADDRESS[k];
629
630                 st->i2c_addr = new_addr;
631                 if (dib3000mc_identify(st) != 0) {
632                         st->i2c_addr = default_addr;
633                         if (dib3000mc_identify(st) != 0) {
634                                 dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
635                                 return -EINVAL;
636                         }
637                 }
638
639                 /* turn on div_out */
640                 dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
641
642                 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
643                 ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
644                 st->i2c_addr = new_addr;
645         }
646
647         for (k = 0; k < no_of_demods; k++) {
648                 st = demod[k]->demodulator_priv;
649
650                 ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
651
652                 /* turn off data output */
653                 dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
654                 dib3000mc_write_word(st, 769, (1 << 7) );
655
656         }
657         return 0;
658 }
659
660 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
661 {
662         struct dib3000mc_state *st = demod->demodulator_priv;
663         return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
664 }
665
666 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
667
668 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
669                                 struct dvb_frontend_parameters *fep)
670 {
671         struct dib3000mc_state *state = fe->demodulator_priv;
672         u16 tps = dib3000mc_read_word(state,458);
673
674         fep->inversion = INVERSION_AUTO;
675
676         fep->u.ofdm.bandwidth = state->current_bandwidth;
677
678         switch ((tps >> 8) & 0x1) {
679                 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
680                 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
681         }
682
683         switch (tps & 0x3) {
684                 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
685                 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
686                 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
687                 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
688         }
689
690         switch ((tps >> 13) & 0x3) {
691                 case 0: fep->u.ofdm.constellation = QPSK; break;
692                 case 1: fep->u.ofdm.constellation = QAM_16; break;
693                 case 2:
694                 default: fep->u.ofdm.constellation = QAM_64; break;
695         }
696
697         /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
698         /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
699
700         fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
701         switch ((tps >> 5) & 0x7) {
702                 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
703                 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
704                 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
705                 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
706                 case 7:
707                 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
708
709         }
710
711         switch ((tps >> 2) & 0x7) {
712                 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
713                 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
714                 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
715                 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
716                 case 7:
717                 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
718         }
719
720         return 0;
721 }
722
723 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
724                                 struct dvb_frontend_parameters *fep)
725 {
726         struct dib3000mc_state *state = fe->demodulator_priv;
727         struct dibx000_ofdm_channel ch;
728
729         INIT_OFDM_CHANNEL(&ch);
730         FEP2DIB(fep,&ch);
731
732         dump_fep(&ch);
733
734         state->current_bandwidth = fep->u.ofdm.bandwidth;
735         dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
736
737         if (fe->ops.tuner_ops.set_params) {
738                 fe->ops.tuner_ops.set_params(fe, fep);
739                 msleep(100);
740         }
741
742         if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
743                 fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
744                 fep->u.ofdm.constellation     == QAM_AUTO ||
745                 fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
746                 int i = 100, found;
747
748                 dib3000mc_autosearch_start(fe, &ch);
749                 do {
750                         msleep(1);
751                         found = dib3000mc_autosearch_is_irq(fe);
752                 } while (found == 0 && i--);
753
754                 dprintk("autosearch returns: %d\n",found);
755                 if (found == 0 || found == 1)
756                         return 0; // no channel found
757
758                 dib3000mc_get_frontend(fe, fep);
759                 FEP2DIB(fep,&ch);
760         }
761
762         /* make this a config parameter */
763         dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
764
765         return dib3000mc_tune(fe, &ch);
766 }
767
768 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
769 {
770         struct dib3000mc_state *state = fe->demodulator_priv;
771         u16 lock = dib3000mc_read_word(state, 509);
772
773         *stat = 0;
774
775         if (lock & 0x8000)
776                 *stat |= FE_HAS_SIGNAL;
777         if (lock & 0x3000)
778                 *stat |= FE_HAS_CARRIER;
779         if (lock & 0x0100)
780                 *stat |= FE_HAS_VITERBI;
781         if (lock & 0x0010)
782                 *stat |= FE_HAS_SYNC;
783         if (lock & 0x0008)
784                 *stat |= FE_HAS_LOCK;
785
786         return 0;
787 }
788
789 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
790 {
791         struct dib3000mc_state *state = fe->demodulator_priv;
792         *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
793         return 0;
794 }
795
796 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
797 {
798         struct dib3000mc_state *state = fe->demodulator_priv;
799         *unc = dib3000mc_read_word(state, 508);
800         return 0;
801 }
802
803 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
804 {
805         struct dib3000mc_state *state = fe->demodulator_priv;
806         u16 val = dib3000mc_read_word(state, 392);
807         *strength = 65535 - val;
808         return 0;
809 }
810
811 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
812 {
813         *snr = 0x0000;
814         return 0;
815 }
816
817 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
818 {
819         tune->min_delay_ms = 1000;
820         return 0;
821 }
822
823 static void dib3000mc_release(struct dvb_frontend *fe)
824 {
825         struct dib3000mc_state *state = fe->demodulator_priv;
826         dibx000_exit_i2c_master(&state->i2c_master);
827         kfree(state);
828 }
829
830 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
831 {
832         struct dib3000mc_state *state = fe->demodulator_priv;
833         dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
834         return 0;
835 }
836 EXPORT_SYMBOL(dib3000mc_pid_control);
837
838 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
839 {
840         struct dib3000mc_state *state = fe->demodulator_priv;
841         u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
842         tmp |= (onoff << 4);
843         return dib3000mc_write_word(state, 206, tmp);
844 }
845 EXPORT_SYMBOL(dib3000mc_pid_parse);
846
847 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
848 {
849         struct dib3000mc_state *state = fe->demodulator_priv;
850         state->cfg = cfg;
851 }
852 EXPORT_SYMBOL(dib3000mc_set_config);
853
854 static struct dvb_frontend_ops dib3000mc_ops;
855
856 int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,                           u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
857 {
858         struct dib3000mc_state *st;
859         int k, num=0;
860
861         if (no_of_demods < 1)
862                 return -EINVAL;
863
864         for (k = 0; k < no_of_demods; k++) {
865                 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
866                 if (st == NULL)
867                         goto error;
868
869                 num++;
870
871                 st->cfg = &cfg[k];
872         //      st->gpio_val = cfg[k].gpio_val;
873         //      st->gpio_dir = cfg[k].gpio_dir;
874                 st->i2c_adap = i2c_adap;
875
876                 demod[k]           = &st->demod;
877                 demod[k]->demodulator_priv     = st;
878                 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
879
880 //              INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
881 //              demod[k]->register_access = &st->register_access;
882         }
883
884         if (do_i2c_enum) {
885                 if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
886                         goto error;
887         } else {
888                 st = demod[0]->demodulator_priv;
889                 st->i2c_addr = default_addr;
890                 if (dib3000mc_identify(st) != 0)
891                         goto error;
892         }
893
894         for (k = 0; k < num; k++) {
895                 st = demod[k]->demodulator_priv;
896                 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
897         }
898
899         return 0;
900
901 error:
902         for (k = 0; k < num; k++)
903                 kfree(demod[k]->demodulator_priv);
904
905         return -EINVAL;
906 }
907
908 EXPORT_SYMBOL(dib3000mc_attach);
909
910 static struct dvb_frontend_ops dib3000mc_ops = {
911         .info = {
912                 .name = "DiBcom 3000MC/P",
913                 .type = FE_OFDM,
914                 .frequency_min      = 44250000,
915                 .frequency_max      = 867250000,
916                 .frequency_stepsize = 62500,
917                 .caps = FE_CAN_INVERSION_AUTO |
918                         FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
919                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
920                         FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
921                         FE_CAN_TRANSMISSION_MODE_AUTO |
922                         FE_CAN_GUARD_INTERVAL_AUTO |
923                         FE_CAN_RECOVER |
924                         FE_CAN_HIERARCHY_AUTO,
925         },
926
927         .release              = dib3000mc_release,
928
929         .init                 = dib3000mc_init,
930         .sleep                = dib3000mc_sleep,
931
932         .set_frontend         = dib3000mc_set_frontend,
933         .get_tune_settings    = dib3000mc_fe_get_tune_settings,
934         .get_frontend         = dib3000mc_get_frontend,
935
936         .read_status          = dib3000mc_read_status,
937         .read_ber             = dib3000mc_read_ber,
938         .read_signal_strength = dib3000mc_read_signal_strength,
939         .read_snr             = dib3000mc_read_snr,
940         .read_ucblocks        = dib3000mc_read_unc_blocks,
941 };
942
943 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
944 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
945 MODULE_LICENSE("GPL");