aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib3000mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/dib3000mc.c')
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c192
1 files changed, 121 insertions, 71 deletions
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 054d7e6d9662..edae0be063f5 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator. 2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 * 3 *
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/) 4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 * 6 *
7 * This code is partially based on the previous dib3000mc.c . 7 * This code is partially based on the previous dib3000mc.c .
@@ -13,10 +13,6 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/i2c.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 16
21#include "dvb_frontend.h" 17#include "dvb_frontend.h"
22 18
@@ -26,7 +22,11 @@ static int debug;
26module_param(debug, int, 0644); 22module_param(debug, int, 0644);
27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 23MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
28 24
29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0) 25static int buggy_sfn_workaround;
26module_param(buggy_sfn_workaround, int, 0644);
27MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
28
29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
30 30
31struct dib3000mc_state { 31struct dib3000mc_state {
32 struct dvb_frontend demod; 32 struct dvb_frontend demod;
@@ -42,6 +42,8 @@ struct dib3000mc_state {
42 fe_bandwidth_t current_bandwidth; 42 fe_bandwidth_t current_bandwidth;
43 43
44 u16 dev_id; 44 u16 dev_id;
45
46 u8 sfn_workaround_active :1;
45}; 47};
46 48
47static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) 49static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
@@ -71,7 +73,6 @@ static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
71 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 73 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
72} 74}
73 75
74
75static int dib3000mc_identify(struct dib3000mc_state *state) 76static int dib3000mc_identify(struct dib3000mc_state *state)
76{ 77{
77 u16 value; 78 u16 value;
@@ -92,7 +93,7 @@ static int dib3000mc_identify(struct dib3000mc_state *state)
92 return 0; 93 return 0;
93} 94}
94 95
95static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset) 96static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
96{ 97{
97 u32 timf; 98 u32 timf;
98 99
@@ -103,7 +104,7 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw,
103 } else 104 } else
104 timf = state->timf; 105 timf = state->timf;
105 106
106 timf *= (BW_INDEX_TO_KHZ(bw) / 1000); 107 timf *= (bw / 1000);
107 108
108 if (update_offset) { 109 if (update_offset) {
109 s16 tim_offs = dib3000mc_read_word(state, 416); 110 s16 tim_offs = dib3000mc_read_word(state, 416);
@@ -111,17 +112,17 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw,
111 if (tim_offs & 0x2000) 112 if (tim_offs & 0x2000)
112 tim_offs -= 0x4000; 113 tim_offs -= 0x4000;
113 114
114 if (nfft == 0) 115 if (nfft == TRANSMISSION_MODE_2K)
115 tim_offs *= 4; 116 tim_offs *= 4;
116 117
117 timf += tim_offs; 118 timf += tim_offs;
118 state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000); 119 state->timf = timf / (bw / 1000);
119 } 120 }
120 121
121 dprintk("timf: %d\n", timf); 122 dprintk("timf: %d\n", timf);
122 123
123 dib3000mc_write_word(state, 23, timf >> 16); 124 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
124 dib3000mc_write_word(state, 24, timf & 0xffff); 125 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
125 126
126 return 0; 127 return 0;
127} 128}
@@ -209,31 +210,30 @@ static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
209 return ret; 210 return ret;
210} 211}
211 212
212static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw) 213static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
213{ 214{
214 struct dib3000mc_state *state = demod->demodulator_priv;
215 u16 bw_cfg[6] = { 0 }; 215 u16 bw_cfg[6] = { 0 };
216 u16 imp_bw_cfg[3] = { 0 }; 216 u16 imp_bw_cfg[3] = { 0 };
217 u16 reg; 217 u16 reg;
218 218
219/* settings here are for 27.7MHz */ 219/* settings here are for 27.7MHz */
220 switch (bw) { 220 switch (bw) {
221 case BANDWIDTH_8_MHZ: 221 case 8000:
222 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; 222 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
223 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; 223 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
224 break; 224 break;
225 225
226 case BANDWIDTH_7_MHZ: 226 case 7000:
227 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; 227 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
228 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; 228 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
229 break; 229 break;
230 230
231 case BANDWIDTH_6_MHZ: 231 case 6000:
232 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; 232 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
233 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; 233 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
234 break; 234 break;
235 235
236 case 255 /* BANDWIDTH_5_MHZ */: 236 case 5000:
237 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; 237 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
238 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; 238 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
239 break; 239 break;
@@ -257,7 +257,7 @@ static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
257 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); 257 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
258 258
259 // Timing configuration 259 // Timing configuration
260 dib3000mc_set_timing(state, 0, bw, 0); 260 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
261 261
262 return 0; 262 return 0;
263} 263}
@@ -276,7 +276,7 @@ static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode,
276 for (i = 58; i < 87; i++) 276 for (i = 58; i < 87; i++)
277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]); 277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
278 278
279 if (nfft == 1) { 279 if (nfft == TRANSMISSION_MODE_8K) {
280 dib3000mc_write_word(state, 58, 0x3b); 280 dib3000mc_write_word(state, 58, 0x3b);
281 dib3000mc_write_word(state, 84, 0x00); 281 dib3000mc_write_word(state, 84, 0x00);
282 dib3000mc_write_word(state, 85, 0x8200); 282 dib3000mc_write_word(state, 85, 0x8200);
@@ -376,7 +376,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
376 // P_search_maxtrial=1 376 // P_search_maxtrial=1
377 dib3000mc_write_word(state, 5, 1); 377 dib3000mc_write_word(state, 5, 1);
378 378
379 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ); 379 dib3000mc_set_bandwidth(state, 8000);
380 380
381 // div_lock_mask 381 // div_lock_mask
382 dib3000mc_write_word(state, 4, 0x814); 382 dib3000mc_write_word(state, 4, 0x814);
@@ -397,7 +397,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
397 dib3000mc_write_word(state, 180, 0x2FF0); 397 dib3000mc_write_word(state, 180, 0x2FF0);
398 398
399 // Impulse noise configuration 399 // Impulse noise configuration
400 dib3000mc_set_impulse_noise(state, 0, 1); 400 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
401 401
402 // output mode set-up 402 // output mode set-up
403 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); 403 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
@@ -423,13 +423,13 @@ static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
423{ 423{
424 u16 cfg[4] = { 0 },reg; 424 u16 cfg[4] = { 0 },reg;
425 switch (qam) { 425 switch (qam) {
426 case 0: 426 case QPSK:
427 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; 427 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
428 break; 428 break;
429 case 1: 429 case QAM_16:
430 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; 430 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
431 break; 431 break;
432 case 2: 432 case QAM_64:
433 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; 433 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
434 break; 434 break;
435 } 435 }
@@ -437,11 +437,11 @@ static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
437 dib3000mc_write_word(state, reg, cfg[reg - 129]); 437 dib3000mc_write_word(state, reg, cfg[reg - 129]);
438} 438}
439 439
440static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq) 440static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
441{ 441{
442 u16 tmp; 442 u16 value;
443 443 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
444 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0); 444 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
445 445
446// if (boost) 446// if (boost)
447// dib3000mc_write_word(state, 100, (11 << 6) + 6); 447// dib3000mc_write_word(state, 100, (11 << 6) + 6);
@@ -455,7 +455,7 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx
455 dib3000mc_write_word(state, 26, 0x6680); 455 dib3000mc_write_word(state, 26, 0x6680);
456 dib3000mc_write_word(state, 29, 0x1273); 456 dib3000mc_write_word(state, 29, 0x1273);
457 dib3000mc_write_word(state, 33, 5); 457 dib3000mc_write_word(state, 33, 5);
458 dib3000mc_set_adp_cfg(state, 1); 458 dib3000mc_set_adp_cfg(state, QAM_16);
459 dib3000mc_write_word(state, 133, 15564); 459 dib3000mc_write_word(state, 133, 15564);
460 460
461 dib3000mc_write_word(state, 12 , 0x0); 461 dib3000mc_write_word(state, 12 , 0x0);
@@ -470,52 +470,98 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx
470 dib3000mc_write_word(state, 97,0); 470 dib3000mc_write_word(state, 97,0);
471 dib3000mc_write_word(state, 98,0); 471 dib3000mc_write_word(state, 98,0);
472 472
473 dib3000mc_set_impulse_noise(state, 0, chan->nfft); 473 dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
474
475 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
476 dib3000mc_write_word(state, 0, tmp);
477 474
475 value = 0;
476 switch (ch->u.ofdm.transmission_mode) {
477 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
478 default:
479 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
480 }
481 switch (ch->u.ofdm.guard_interval) {
482 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
483 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
484 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
485 default:
486 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
487 }
488 switch (ch->u.ofdm.constellation) {
489 case QPSK: value |= (0 << 3); break;
490 case QAM_16: value |= (1 << 3); break;
491 default:
492 case QAM_64: value |= (2 << 3); break;
493 }
494 switch (HIERARCHY_1) {
495 case HIERARCHY_2: value |= 2; break;
496 case HIERARCHY_4: value |= 4; break;
497 default:
498 case HIERARCHY_1: value |= 1; break;
499 }
500 dib3000mc_write_word(state, 0, value);
478 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); 501 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
479 502
480 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp); 503 value = 0;
481 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp)) 504 if (ch->u.ofdm.hierarchy_information == 1)
482 tmp |= chan->vit_code_rate_hp << 1; 505 value |= (1 << 4);
483 else 506 if (1 == 1)
484 tmp |= chan->vit_code_rate_lp << 1; 507 value |= 1;
485 dib3000mc_write_word(state, 181, tmp); 508 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
509 case FEC_2_3: value |= (2 << 1); break;
510 case FEC_3_4: value |= (3 << 1); break;
511 case FEC_5_6: value |= (5 << 1); break;
512 case FEC_7_8: value |= (7 << 1); break;
513 default:
514 case FEC_1_2: value |= (1 << 1); break;
515 }
516 dib3000mc_write_word(state, 181, value);
486 517
487 // diversity synchro delay 518 // diversity synchro delay add 50% SFN margin
488 tmp = dib3000mc_read_word(state, 180) & 0x000f; 519 switch (ch->u.ofdm.transmission_mode) {
489 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin 520 case TRANSMISSION_MODE_8K: value = 256; break;
490 dib3000mc_write_word(state, 180, tmp); 521 case TRANSMISSION_MODE_2K:
522 default: value = 64; break;
523 }
524 switch (ch->u.ofdm.guard_interval) {
525 case GUARD_INTERVAL_1_16: value *= 2; break;
526 case GUARD_INTERVAL_1_8: value *= 4; break;
527 case GUARD_INTERVAL_1_4: value *= 8; break;
528 default:
529 case GUARD_INTERVAL_1_32: value *= 1; break;
530 }
531 value <<= 4;
532 value |= dib3000mc_read_word(state, 180) & 0x000f;
533 dib3000mc_write_word(state, 180, value);
491 534
492 // restart demod 535 // restart demod
493 tmp = dib3000mc_read_word(state, 0); 536 value = dib3000mc_read_word(state, 0);
494 dib3000mc_write_word(state, 0, tmp | (1 << 9)); 537 dib3000mc_write_word(state, 0, value | (1 << 9));
495 dib3000mc_write_word(state, 0, tmp); 538 dib3000mc_write_word(state, 0, value);
496 539
497 msleep(30); 540 msleep(30);
498 541
499 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft); 542 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
500} 543}
501 544
502static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan) 545static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
503{ 546{
504 struct dib3000mc_state *state = demod->demodulator_priv; 547 struct dib3000mc_state *state = demod->demodulator_priv;
505 u16 reg; 548 u16 reg;
506// u32 val; 549// u32 val;
507 struct dibx000_ofdm_channel fchan; 550 struct dvb_frontend_parameters schan;
508 551
509 INIT_OFDM_CHANNEL(&fchan); 552 schan = *chan;
510 fchan = *chan;
511 553
554 /* TODO what is that ? */
512 555
513 /* a channel for autosearch */ 556 /* a channel for autosearch */
514 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2; 557 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
515 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2; 558 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
516 fchan.vit_hrch = 0; fchan.vit_select_hp = 1; 559 schan.u.ofdm.constellation = QAM_64;
560 schan.u.ofdm.code_rate_HP = FEC_2_3;
561 schan.u.ofdm.code_rate_LP = FEC_2_3;
562 schan.u.ofdm.hierarchy_information = 0;
517 563
518 dib3000mc_set_channel_cfg(state, &fchan, 11); 564 dib3000mc_set_channel_cfg(state, &schan, 11);
519 565
520 reg = dib3000mc_read_word(state, 0); 566 reg = dib3000mc_read_word(state, 0);
521 dib3000mc_write_word(state, 0, reg | (1 << 8)); 567 dib3000mc_write_word(state, 0, reg | (1 << 8));
@@ -539,7 +585,7 @@ static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
539 return 0; // still pending 585 return 0; // still pending
540} 586}
541 587
542static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 588static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
543{ 589{
544 struct dib3000mc_state *state = demod->demodulator_priv; 590 struct dib3000mc_state *state = demod->demodulator_priv;
545 591
@@ -547,11 +593,17 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channe
547 dib3000mc_set_channel_cfg(state, ch, 0); 593 dib3000mc_set_channel_cfg(state, ch, 0);
548 594
549 // activates isi 595 // activates isi
550 dib3000mc_write_word(state, 29, 0x1073); 596 if (state->sfn_workaround_active) {
551 597 dprintk("SFN workaround is active\n");
552 dib3000mc_set_adp_cfg(state, (u8)ch->nqam); 598 dib3000mc_write_word(state, 29, 0x1273);
599 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
600 } else {
601 dib3000mc_write_word(state, 29, 0x1073);
602 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
603 }
553 604
554 if (ch->nfft == 1) { 605 dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
606 if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
555 dib3000mc_write_word(state, 26, 38528); 607 dib3000mc_write_word(state, 26, 38528);
556 dib3000mc_write_word(state, 33, 8); 608 dib3000mc_write_word(state, 33, 8);
557 } else { 609 } else {
@@ -560,7 +612,7 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channe
560 } 612 }
561 613
562 if (dib3000mc_read_word(state, 509) & 0x80) 614 if (dib3000mc_read_word(state, 509) & 0x80)
563 dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1); 615 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
564 616
565 return 0; 617 return 0;
566} 618}
@@ -632,13 +684,12 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
632 struct dvb_frontend_parameters *fep) 684 struct dvb_frontend_parameters *fep)
633{ 685{
634 struct dib3000mc_state *state = fe->demodulator_priv; 686 struct dib3000mc_state *state = fe->demodulator_priv;
635 struct dibx000_ofdm_channel ch;
636
637 INIT_OFDM_CHANNEL(&ch);
638 FEP2DIB(fep,&ch);
639 687
640 state->current_bandwidth = fep->u.ofdm.bandwidth; 688 state->current_bandwidth = fep->u.ofdm.bandwidth;
641 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth); 689 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
690
691 /* maybe the parameter has been changed */
692 state->sfn_workaround_active = buggy_sfn_workaround;
642 693
643 if (fe->ops.tuner_ops.set_params) { 694 if (fe->ops.tuner_ops.set_params) {
644 fe->ops.tuner_ops.set_params(fe, fep); 695 fe->ops.tuner_ops.set_params(fe, fep);
@@ -651,7 +702,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
651 fep->u.ofdm.code_rate_HP == FEC_AUTO) { 702 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
652 int i = 100, found; 703 int i = 100, found;
653 704
654 dib3000mc_autosearch_start(fe, &ch); 705 dib3000mc_autosearch_start(fe, fep);
655 do { 706 do {
656 msleep(1); 707 msleep(1);
657 found = dib3000mc_autosearch_is_irq(fe); 708 found = dib3000mc_autosearch_is_irq(fe);
@@ -662,13 +713,12 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
662 return 0; // no channel found 713 return 0; // no channel found
663 714
664 dib3000mc_get_frontend(fe, fep); 715 dib3000mc_get_frontend(fe, fep);
665 FEP2DIB(fep,&ch);
666 } 716 }
667 717
668 /* make this a config parameter */ 718 /* make this a config parameter */
669 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); 719 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
670 720
671 return dib3000mc_tune(fe, &ch); 721 return dib3000mc_tune(fe, fep);
672} 722}
673 723
674static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) 724static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)