aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends
diff options
context:
space:
mode:
authorPatrick Boettcher <pboettcher@kernellabs.com>2013-04-22 11:45:52 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-22 15:58:16 -0400
commit173a64cb3fcff1993b2aa8113e53fd379f6a968f (patch)
treec1836b2c5208456f61cb7acfcf1771ac5bf444ad /drivers/media/dvb-frontends
parent1552fb344d5ddd5178e8774a31fdb08765c668e1 (diff)
[media] dib8000: enhancement
The intend of this patch is to improve the support of the dib8000. Signed-off-by: Olivier Grenie <olivier.grenie@parrot.com> Signed-off-by: Patrick Boettcher <patrick.boettcher@parrot.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends')
-rw-r--r--drivers/media/dvb-frontends/dib8000.c2235
-rw-r--r--drivers/media/dvb-frontends/dib8000.h6
-rw-r--r--drivers/media/dvb-frontends/dibx000_common.h3
3 files changed, 1320 insertions, 924 deletions
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 1f3bcb5a1de8..1d719cce8995 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -23,8 +23,8 @@
23#define LAYER_B 2 23#define LAYER_B 2
24#define LAYER_C 3 24#define LAYER_C 3
25 25
26#define FE_CALLBACK_TIME_NEVER 0xffffffff
27#define MAX_NUMBER_OF_FRONTENDS 6 26#define MAX_NUMBER_OF_FRONTENDS 6
27/* #define DIB8000_AGC_FREEZE */
28 28
29static int debug; 29static int debug;
30module_param(debug, int, 0644); 30module_param(debug, int, 0644);
@@ -32,8 +32,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
32 32
33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) 33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
34 34
35#define FE_STATUS_TUNE_FAILED 0
36
37struct i2c_device { 35struct i2c_device {
38 struct i2c_adapter *adap; 36 struct i2c_adapter *adap;
39 u8 addr; 37 u8 addr;
@@ -42,6 +40,23 @@ struct i2c_device {
42 struct mutex *i2c_buffer_lock; 40 struct mutex *i2c_buffer_lock;
43}; 41};
44 42
43enum param_loop_step {
44 LOOP_TUNE_1,
45 LOOP_TUNE_2
46};
47
48enum dib8000_autosearch_step {
49 AS_START = 0,
50 AS_SEARCHING_FFT,
51 AS_SEARCHING_GUARD,
52 AS_DONE = 100,
53};
54
55enum timeout_mode {
56 SYMBOL_DEPENDENT_OFF = 0,
57 SYMBOL_DEPENDENT_ON,
58};
59
45struct dib8000_state { 60struct dib8000_state {
46 struct dib8000_config cfg; 61 struct dib8000_config cfg;
47 62
@@ -72,7 +87,7 @@ struct dib8000_state {
72 u16 revision; 87 u16 revision;
73 u8 isdbt_cfg_loaded; 88 u8 isdbt_cfg_loaded;
74 enum frontend_tune_state tune_state; 89 enum frontend_tune_state tune_state;
75 u32 status; 90 s32 status;
76 91
77 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; 92 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
78 93
@@ -85,6 +100,30 @@ struct dib8000_state {
85 100
86 u16 tuner_enable; 101 u16 tuner_enable;
87 struct i2c_adapter dib8096p_tuner_adap; 102 struct i2c_adapter dib8096p_tuner_adap;
103 u16 current_demod_bw;
104
105 u16 seg_mask;
106 u16 seg_diff_mask;
107 u16 mode;
108 u8 layer_b_nb_seg;
109 u8 layer_c_nb_seg;
110
111 u8 channel_parameters_set;
112 u16 autosearch_state;
113 u16 found_nfft;
114 u16 found_guard;
115 u8 subchannel;
116 u8 symbol_duration;
117 u32 timeout;
118 u8 longest_intlv_layer;
119 u16 output_mode;
120
121#ifdef DIB8000_AGC_FREEZE
122 u16 agc1_max;
123 u16 agc1_min;
124 u16 agc2_max;
125 u16 agc2_min;
126#endif
88}; 127};
89 128
90enum dib8000_power_mode { 129enum dib8000_power_mode {
@@ -338,9 +377,9 @@ static void dib8000_set_acquisition_mode(struct dib8000_state *state)
338static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) 377static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
339{ 378{
340 struct dib8000_state *state = fe->demodulator_priv; 379 struct dib8000_state *state = fe->demodulator_priv;
341
342 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ 380 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
343 381
382 state->output_mode = mode;
344 outreg = 0; 383 outreg = 0;
345 fifo_threshold = 1792; 384 fifo_threshold = 1792;
346 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); 385 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
@@ -399,8 +438,9 @@ static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
399static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff) 438static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
400{ 439{
401 struct dib8000_state *state = fe->demodulator_priv; 440 struct dib8000_state *state = fe->demodulator_priv;
402 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0; 441 u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0;
403 442
443 dprintk("set diversity input to %i", onoff);
404 if (!state->differential_constellation) { 444 if (!state->differential_constellation) {
405 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1 445 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
406 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2 446 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
@@ -424,6 +464,13 @@ static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
424 dib8000_write_word(state, 271, 1); 464 dib8000_write_word(state, 271, 1);
425 break; 465 break;
426 } 466 }
467
468 if (state->revision == 0x8002) {
469 tmp = dib8000_read_word(state, 903);
470 dib8000_write_word(state, 903, tmp & ~(1 << 3));
471 msleep(30);
472 dib8000_write_word(state, 903, tmp | (1 << 3));
473 }
427 return 0; 474 return 0;
428} 475}
429 476
@@ -468,27 +515,6 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow
468 dib8000_write_word(state, 1280, reg_1280); 515 dib8000_write_word(state, 1280, reg_1280);
469} 516}
470 517
471static int dib8000_init_sdram(struct dib8000_state *state)
472{
473 u16 reg = 0;
474 dprintk("Init sdram");
475
476 reg = dib8000_read_word(state, 274)&0xfff0;
477 /* P_dintlv_delay_ram = 7 because of MobileSdram */
478 dib8000_write_word(state, 274, reg | 0x7);
479
480 dib8000_write_word(state, 1803, (7<<2));
481
482 reg = dib8000_read_word(state, 1280);
483 /* force restart P_restart_sdram */
484 dib8000_write_word(state, 1280, reg | (1<<2));
485
486 /* release restart P_restart_sdram */
487 dib8000_write_word(state, 1280, reg);
488
489 return 0;
490}
491
492static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) 518static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
493{ 519{
494 int ret = 0; 520 int ret = 0;
@@ -584,18 +610,23 @@ static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
584 610
585static int dib8000_sad_calib(struct dib8000_state *state) 611static int dib8000_sad_calib(struct dib8000_state *state)
586{ 612{
613 u8 sad_sel = 3;
614
587 if (state->revision == 0x8090) { 615 if (state->revision == 0x8090) {
588 dprintk("%s: the sad calibration is not needed for the dib8096P", 616 dib8000_write_word(state, 922, (sad_sel << 2));
589 __func__); 617 dib8000_write_word(state, 923, 2048);
590 return 0;
591 }
592 /* internal */
593 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
594 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
595 618
596 /* do the calibration */ 619 dib8000_write_word(state, 922, (sad_sel << 2) | 0x1);
597 dib8000_write_word(state, 923, (1 << 0)); 620 dib8000_write_word(state, 922, (sad_sel << 2));
598 dib8000_write_word(state, 923, (0 << 0)); 621 } else {
622 /* internal */
623 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
624 dib8000_write_word(state, 924, 776);
625
626 /* do the calibration */
627 dib8000_write_word(state, 923, (1 << 0));
628 dib8000_write_word(state, 923, (0 << 0));
629 }
599 630
600 msleep(1); 631 msleep(1);
601 return 0; 632 return 0;
@@ -609,8 +640,8 @@ int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
609 state->wbd_ref = value; 640 state->wbd_ref = value;
610 return dib8000_write_word(state, 106, value); 641 return dib8000_write_word(state, 106, value);
611} 642}
612
613EXPORT_SYMBOL(dib8000_set_wbd_ref); 643EXPORT_SYMBOL(dib8000_set_wbd_ref);
644
614static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) 645static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
615{ 646{
616 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); 647 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
@@ -685,20 +716,23 @@ static void dib8000_reset_pll(struct dib8000_state *state)
685} 716}
686 717
687int dib8000_update_pll(struct dvb_frontend *fe, 718int dib8000_update_pll(struct dvb_frontend *fe,
688 struct dibx000_bandwidth_config *pll) 719 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
689{ 720{
690 struct dib8000_state *state = fe->demodulator_priv; 721 struct dib8000_state *state = fe->demodulator_priv;
691 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856); 722 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
692 u8 loopdiv, prediv; 723 u8 loopdiv, prediv, oldprediv = state->cfg.pll->pll_prediv ;
693 u32 internal, xtal; 724 u32 internal, xtal;
694 725
695 /* get back old values */ 726 /* get back old values */
696 prediv = reg_1856 & 0x3f; 727 prediv = reg_1856 & 0x3f;
697 loopdiv = (reg_1856 >> 6) & 0x3f; 728 loopdiv = (reg_1856 >> 6) & 0x3f;
698 729
699 if ((pll != NULL) && (pll->pll_prediv != prediv || 730 if ((pll == NULL) || (pll->pll_prediv == prediv &&
700 pll->pll_ratio != loopdiv)) { 731 pll->pll_ratio == loopdiv))
701 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); 732 return -EINVAL;
733
734 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
735 if (state->revision == 0x8090) {
702 reg_1856 &= 0xf000; 736 reg_1856 &= 0xf000;
703 reg_1857 = dib8000_read_word(state, 1857); 737 reg_1857 = dib8000_read_word(state, 1857);
704 /* disable PLL */ 738 /* disable PLL */
@@ -729,10 +763,33 @@ int dib8000_update_pll(struct dvb_frontend *fe,
729 reg_1856 = dib8000_read_word(state, 1856); 763 reg_1856 = dib8000_read_word(state, 1856);
730 dprintk("PLL Updated with prediv = %d and loopdiv = %d", 764 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
731 reg_1856&0x3f, (reg_1856>>6)&0x3f); 765 reg_1856&0x3f, (reg_1856>>6)&0x3f);
766 } else {
767 if (bw != state->current_demod_bw) {
768 /** Bandwidth change => force PLL update **/
769 dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv);
770
771 if (state->cfg.pll->pll_prediv != oldprediv) {
772 /** Full PLL change only if prediv is changed **/
773
774 /** full update => bypass and reconfigure **/
775 dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio);
776 dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */
777 dib8000_reset_pll(state);
778 dib8000_write_word(state, 898, 0x0004); /* sad */
779 } else
780 ratio = state->cfg.pll->pll_ratio;
732 781
733 return 0; 782 state->current_demod_bw = bw;
734 } 783 }
735 return -EINVAL; 784
785 if (ratio != 0) {
786 /** ratio update => only change ratio **/
787 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
788 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
789 }
790}
791
792 return 0;
736} 793}
737EXPORT_SYMBOL(dib8000_update_pll); 794EXPORT_SYMBOL(dib8000_update_pll);
738 795
@@ -928,7 +985,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
928 dib8000_set_power_mode(state, DIB8000_POWER_ALL); 985 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
929 986
930 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ 987 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
931 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); 988 dib8000_set_adc_state(state, DIBX000_ADC_OFF);
932 989
933 /* restart all parts */ 990 /* restart all parts */
934 dib8000_write_word(state, 770, 0xffff); 991 dib8000_write_word(state, 770, 0xffff);
@@ -992,12 +1049,11 @@ static int dib8000_reset(struct dvb_frontend *fe)
992 l = *n++; 1049 l = *n++;
993 } 1050 }
994 } 1051 }
995 if (state->revision != 0x8090) 1052
996 dib8000_write_word(state, 903, (0 << 4) | 2);
997 state->isdbt_cfg_loaded = 0; 1053 state->isdbt_cfg_loaded = 0;
998 1054
999 //div_cfg override for special configs 1055 //div_cfg override for special configs
1000 if (state->cfg.div_cfg != 0) 1056 if ((state->revision != 8090) && (state->cfg.div_cfg != 0))
1001 dib8000_write_word(state, 903, state->cfg.div_cfg); 1057 dib8000_write_word(state, 903, state->cfg.div_cfg);
1002 1058
1003 /* unforce divstr regardless whether i2c enumeration was done or not */ 1059 /* unforce divstr regardless whether i2c enumeration was done or not */
@@ -1006,10 +1062,12 @@ static int dib8000_reset(struct dvb_frontend *fe)
1006 dib8000_set_bandwidth(fe, 6000); 1062 dib8000_set_bandwidth(fe, 6000);
1007 1063
1008 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1064 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1009 if (state->revision != 0x8090) { 1065 dib8000_sad_calib(state);
1010 dib8000_sad_calib(state); 1066 if (state->revision != 0x8090)
1011 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 1067 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1012 } 1068
1069 /* ber_rs_len = 3 */
1070 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));
1013 1071
1014 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); 1072 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1015 1073
@@ -1441,6 +1499,7 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1441 u8 prefer_mpeg_mux_use = 1; 1499 u8 prefer_mpeg_mux_use = 1;
1442 int ret = 0; 1500 int ret = 0;
1443 1501
1502 state->output_mode = mode;
1444 dib8096p_host_bus_drive(state, 1); 1503 dib8096p_host_bus_drive(state, 1);
1445 1504
1446 fifo_threshold = 1792; 1505 fifo_threshold = 1792;
@@ -1879,782 +1938,637 @@ static const u16 adc_target_16dB[11] = {
1879}; 1938};
1880static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; 1939static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1881 1940
1882static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) 1941static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
1883{ 1942{
1884 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0; 1943 u8 cr, constellation, time_intlv;
1885 u8 guard, crate, constellation, timeI;
1886 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1887 const s16 *ncoeff = NULL, *ana_fe;
1888 u16 tmcc_pow = 0;
1889 u16 coff_pow = 0x2800;
1890 u16 init_prbs = 0xfff;
1891 u16 ana_gain = 0;
1892
1893 if (state->revision == 0x8090)
1894 dib8000_init_sdram(state);
1895
1896 if (state->ber_monitored_layer != LAYER_ALL)
1897 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1898 else
1899 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1900
1901 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1902 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1903
1904 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1905 //compute new dds_freq for the seg and adjust prbs
1906 int seg_offset =
1907 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1908 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1909 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1910 int clk = state->cfg.pll->internal;
1911 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1912 int dds_offset = seg_offset * segtodds;
1913 int new_dds, sub_channel;
1914 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1915 dds_offset -= (int)(segtodds / 2);
1916
1917 if (state->cfg.pll->ifreq == 0) {
1918 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1919 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1920 new_dds = dds_offset;
1921 } else
1922 new_dds = dds_offset;
1923
1924 // We shift tuning frequency if the wanted segment is :
1925 // - the segment of center frequency with an odd total number of segments
1926 // - the segment to the left of center frequency with an even total number of segments
1927 // - the segment to the right of center frequency with an even total number of segments
1928 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1929 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1930 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1931 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1932 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1933 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1934 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1935 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1936 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1937 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1938 )) {
1939 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1940 }
1941 } else {
1942 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1943 new_dds = state->cfg.pll->ifreq - dds_offset;
1944 else
1945 new_dds = state->cfg.pll->ifreq + dds_offset;
1946 }
1947 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1948 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1949 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1950 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1951 else
1952 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1953 sub_channel -= 6;
1954
1955 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1956 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1957 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1958 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1959 } else {
1960 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1961 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1962 }
1963
1964 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1965 case TRANSMISSION_MODE_2K:
1966 switch (sub_channel) {
1967 case -6:
1968 init_prbs = 0x0;
1969 break; // 41, 0, 1
1970 case -5:
1971 init_prbs = 0x423;
1972 break; // 02~04
1973 case -4:
1974 init_prbs = 0x9;
1975 break; // 05~07
1976 case -3:
1977 init_prbs = 0x5C7;
1978 break; // 08~10
1979 case -2:
1980 init_prbs = 0x7A6;
1981 break; // 11~13
1982 case -1:
1983 init_prbs = 0x3D8;
1984 break; // 14~16
1985 case 0:
1986 init_prbs = 0x527;
1987 break; // 17~19
1988 case 1:
1989 init_prbs = 0x7FF;
1990 break; // 20~22
1991 case 2:
1992 init_prbs = 0x79B;
1993 break; // 23~25
1994 case 3:
1995 init_prbs = 0x3D6;
1996 break; // 26~28
1997 case 4:
1998 init_prbs = 0x3A2;
1999 break; // 29~31
2000 case 5:
2001 init_prbs = 0x53B;
2002 break; // 32~34
2003 case 6:
2004 init_prbs = 0x2F4;
2005 break; // 35~37
2006 default:
2007 case 7:
2008 init_prbs = 0x213;
2009 break; // 38~40
2010 }
2011 break;
2012 1944
2013 case TRANSMISSION_MODE_4K: 1945 switch (state->fe[0]->dtv_property_cache.layer[layer_index].modulation) {
2014 switch (sub_channel) { 1946 case DQPSK:
2015 case -6:
2016 init_prbs = 0x0;
2017 break; // 41, 0, 1
2018 case -5:
2019 init_prbs = 0x208;
2020 break; // 02~04
2021 case -4:
2022 init_prbs = 0xC3;
2023 break; // 05~07
2024 case -3:
2025 init_prbs = 0x7B9;
2026 break; // 08~10
2027 case -2:
2028 init_prbs = 0x423;
2029 break; // 11~13
2030 case -1:
2031 init_prbs = 0x5C7;
2032 break; // 14~16
2033 case 0:
2034 init_prbs = 0x3D8;
2035 break; // 17~19
2036 case 1:
2037 init_prbs = 0x7FF;
2038 break; // 20~22
2039 case 2:
2040 init_prbs = 0x3D6;
2041 break; // 23~25
2042 case 3:
2043 init_prbs = 0x53B;
2044 break; // 26~28
2045 case 4:
2046 init_prbs = 0x213;
2047 break; // 29~31
2048 case 5:
2049 init_prbs = 0x29;
2050 break; // 32~34
2051 case 6:
2052 init_prbs = 0xD0;
2053 break; // 35~37
2054 default:
2055 case 7:
2056 init_prbs = 0x48E;
2057 break; // 38~40
2058 }
2059 break;
2060
2061 default:
2062 case TRANSMISSION_MODE_8K:
2063 switch (sub_channel) {
2064 case -6:
2065 init_prbs = 0x0;
2066 break; // 41, 0, 1
2067 case -5:
2068 init_prbs = 0x740;
2069 break; // 02~04
2070 case -4:
2071 init_prbs = 0x069;
2072 break; // 05~07
2073 case -3:
2074 init_prbs = 0x7DD;
2075 break; // 08~10
2076 case -2:
2077 init_prbs = 0x208;
2078 break; // 11~13
2079 case -1:
2080 init_prbs = 0x7B9;
2081 break; // 14~16
2082 case 0:
2083 init_prbs = 0x5C7;
2084 break; // 17~19
2085 case 1:
2086 init_prbs = 0x7FF;
2087 break; // 20~22
2088 case 2:
2089 init_prbs = 0x53B;
2090 break; // 23~25
2091 case 3:
2092 init_prbs = 0x29;
2093 break; // 26~28
2094 case 4:
2095 init_prbs = 0x48E;
2096 break; // 29~31
2097 case 5:
2098 init_prbs = 0x4C4;
2099 break; // 32~34
2100 case 6:
2101 init_prbs = 0x367;
2102 break; // 33~37
2103 default:
2104 case 7:
2105 init_prbs = 0x684;
2106 break; // 38~40
2107 }
2108 break;
2109 }
2110 } else {
2111 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
2112 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
2113 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
2114 }
2115 /*P_mode == ?? */
2116 dib8000_write_word(state, 10, (seq << 4));
2117 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
2118
2119 switch (state->fe[0]->dtv_property_cache.guard_interval) {
2120 case GUARD_INTERVAL_1_32:
2121 guard = 0;
2122 break;
2123 case GUARD_INTERVAL_1_16:
2124 guard = 1;
2125 break;
2126 case GUARD_INTERVAL_1_8:
2127 guard = 2;
2128 break;
2129 case GUARD_INTERVAL_1_4:
2130 default:
2131 guard = 3;
2132 break;
2133 }
2134
2135 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
2136
2137 max_constellation = DQPSK;
2138 for (i = 0; i < 3; i++) {
2139 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
2140 case DQPSK:
2141 constellation = 0; 1947 constellation = 0;
2142 break; 1948 break;
2143 case QPSK: 1949 case QPSK:
2144 constellation = 1; 1950 constellation = 1;
2145 break; 1951 break;
2146 case QAM_16: 1952 case QAM_16:
2147 constellation = 2; 1953 constellation = 2;
2148 break; 1954 break;
2149 case QAM_64: 1955 case QAM_64:
2150 default: 1956 default:
2151 constellation = 3; 1957 constellation = 3;
2152 break; 1958 break;
2153 } 1959 }
2154 1960
2155 switch (state->fe[0]->dtv_property_cache.layer[i].fec) { 1961 switch (state->fe[0]->dtv_property_cache.layer[layer_index].fec) {
2156 case FEC_1_2: 1962 case FEC_1_2:
2157 crate = 1; 1963 cr = 1;
2158 break; 1964 break;
2159 case FEC_2_3: 1965 case FEC_2_3:
2160 crate = 2; 1966 cr = 2;
2161 break; 1967 break;
2162 case FEC_3_4: 1968 case FEC_3_4:
2163 crate = 3; 1969 cr = 3;
2164 break; 1970 break;
2165 case FEC_5_6: 1971 case FEC_5_6:
2166 crate = 5; 1972 cr = 5;
2167 break; 1973 break;
2168 case FEC_7_8: 1974 case FEC_7_8:
2169 default: 1975 default:
2170 crate = 7; 1976 cr = 7;
2171 break; 1977 break;
2172 } 1978 }
2173 1979
2174 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) && 1980 if ((state->fe[0]->dtv_property_cache.layer[layer_index].interleaving > 0) && ((state->fe[0]->dtv_property_cache.layer[layer_index].interleaving <= 3) || (state->fe[0]->dtv_property_cache.layer[layer_index].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)))
2175 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) || 1981 time_intlv = state->fe[0]->dtv_property_cache.layer[layer_index].interleaving;
2176 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)) 1982 else
2177 ) 1983 time_intlv = 0;
2178 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving; 1984
2179 else 1985 dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
2180 timeI = 0; 1986 if (state->fe[0]->dtv_property_cache.layer[layer_index].segment_count > 0) {
2181 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) | 1987 switch (max_constellation) {
2182 (crate << 3) | timeI); 1988 case DQPSK:
2183 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) { 1989 case QPSK:
2184 switch (max_constellation) { 1990 if (state->fe[0]->dtv_property_cache.layer[layer_index].modulation == QAM_16 || state->fe[0]->dtv_property_cache.layer[layer_index].modulation == QAM_64)
2185 case DQPSK: 1991 max_constellation = state->fe[0]->dtv_property_cache.layer[layer_index].modulation;
2186 case QPSK:
2187 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
2188 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
2189 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
2190 break; 1992 break;
2191 case QAM_16: 1993 case QAM_16:
2192 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) 1994 if (state->fe[0]->dtv_property_cache.layer[layer_index].modulation == QAM_64)
2193 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; 1995 max_constellation = state->fe[0]->dtv_property_cache.layer[layer_index].modulation;
2194 break; 1996 break;
2195 }
2196 } 1997 }
2197 } 1998 }
2198 1999
2199 mode = fft_to_mode(state); 2000 return max_constellation;
2001}
2200 2002
2201 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ 2003static const u16 adp_Q64[4] = {0x0148, 0xfff0, 0x00a4, 0xfff8}; /* P_adp_regul_cnt 0.04, P_adp_noise_cnt -0.002, P_adp_regul_ext 0.02, P_adp_noise_ext -0.001 */
2004static const u16 adp_Q16[4] = {0x023d, 0xffdf, 0x00a4, 0xfff0}; /* P_adp_regul_cnt 0.07, P_adp_noise_cnt -0.004, P_adp_regul_ext 0.02, P_adp_noise_ext -0.002 */
2005static const u16 adp_Qdefault[4] = {0x099a, 0xffae, 0x0333, 0xfff8}; /* P_adp_regul_cnt 0.3, P_adp_noise_cnt -0.01, P_adp_regul_ext 0.1, P_adp_noise_ext -0.002 */
2006static u16 dib8000_adp_fine_tune(struct dib8000_state *state, u16 max_constellation)
2007{
2008 u16 i, ana_gain = 0;
2009 const u16 *adp;
2202 2010
2203 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | 2011 /* channel estimation fine configuration */
2204 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache. 2012 switch (max_constellation) {
2205 isdbt_sb_mode & 1) << 4)); 2013 case QAM_64:
2014 ana_gain = 0x7;
2015 adp = &adp_Q64[0];
2016 break;
2017 case QAM_16:
2018 ana_gain = 0x7;
2019 adp = &adp_Q16[0];
2020 break;
2021 default:
2022 ana_gain = 0;
2023 adp = &adp_Qdefault[0];
2024 break;
2025 }
2206 2026
2207 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval); 2027 for (i = 0; i < 4; i++)
2028 dib8000_write_word(state, 215 + i, adp[i]);
2208 2029
2209 /* signal optimization parameter */ 2030 return ana_gain;
2031}
2210 2032
2211 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) { 2033static void dib8000_update_ana_gain(struct dib8000_state *state, u16 ana_gain)
2212 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; 2034{
2213 for (i = 1; i < 3; i++) 2035 u16 i;
2214 nbseg_diff += 2036
2215 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; 2037 dib8000_write_word(state, 116, ana_gain);
2216 for (i = 0; i < nbseg_diff; i++) 2038
2217 seg_diff_mask |= 1 << permu_seg[i + 1]; 2039 /* update ADC target depending on ana_gain */
2218 } else { 2040 if (ana_gain) { /* set -16dB ADC target for ana_gain=-1 */
2219 for (i = 0; i < 3; i++) 2041 for (i = 0; i < 10; i++)
2220 nbseg_diff += 2042 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2221 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; 2043 } else { /* set -22dB ADC target for ana_gain=0 */
2222 for (i = 0; i < nbseg_diff; i++) 2044 for (i = 0; i < 10; i++)
2223 seg_diff_mask |= 1 << permu_seg[i]; 2045 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2224 } 2046 }
2225 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); 2047}
2226 2048
2227 state->differential_constellation = (seg_diff_mask != 0); 2049static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *ana_fe)
2228 if (state->revision != 0x8090) 2050{
2229 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); 2051 u16 mode = 0;
2230 else
2231 dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
2232 2052
2233 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2053 if (state->isdbt_cfg_loaded == 0)
2234 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) 2054 for (mode = 0; mode < 24; mode++)
2235 seg_mask13 = 0x00E0; 2055 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2236 else // 1-segment 2056}
2237 seg_mask13 = 0x0040; 2057
2238 } else 2058static const u16 lut_prbs_2k[14] = {
2239 seg_mask13 = 0x1fff; 2059 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
2060};
2061static const u16 lut_prbs_4k[14] = {
2062 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
2063};
2064static const u16 lut_prbs_8k[14] = {
2065 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
2066};
2240 2067
2241 // WRITE: Mode & Diff mask 2068static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
2242 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); 2069{
2070 int sub_channel_prbs_group = 0;
2243 2071
2244 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode)) 2072 sub_channel_prbs_group = (subchannel / 3) + 1;
2245 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); 2073 dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
2246 else 2074
2247 dib8000_write_word(state, 268, (2 << 9) | 39); //init value 2075 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2076 case TRANSMISSION_MODE_2K:
2077 return lut_prbs_2k[sub_channel_prbs_group];
2078 case TRANSMISSION_MODE_4K:
2079 return lut_prbs_4k[sub_channel_prbs_group];
2080 default:
2081 case TRANSMISSION_MODE_8K:
2082 return lut_prbs_8k[sub_channel_prbs_group];
2083 }
2084}
2248 2085
2249 // ---- SMALL ---- 2086static void dib8000_set_13seg_channel(struct dib8000_state *state)
2250 // P_small_seg_diff 2087{
2251 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352 2088 u16 i;
2089 u16 coff_pow = 0x2800;
2252 2090
2253 dib8000_write_word(state, 353, seg_mask13); // ADDR 353 2091 state->seg_mask = 0x1fff; /* All 13 segments enabled */
2254 2092
2255/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ 2093 /* ---- COFF ---- Carloff, the most robust --- */
2094 if (state->isdbt_cfg_loaded == 0) { /* if not Sound Broadcasting mode : put default values for 13 segments */
2095 dib8000_write_word(state, 180, (16 << 6) | 9);
2096 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2097 coff_pow = 0x2800;
2098 for (i = 0; i < 6; i++)
2099 dib8000_write_word(state, 181+i, coff_pow);
2100
2101 /* P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1 */
2102 /* P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1 */
2103 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2104
2105 /* P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 */
2106 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2107 /* P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 */
2108 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2109
2110 dib8000_write_word(state, 228, 0); /* default value */
2111 dib8000_write_word(state, 265, 31); /* default value */
2112 dib8000_write_word(state, 205, 0x200f); /* init value */
2113 }
2114
2115 /*
2116 * make the cpil_coff_lock more robust but slower p_coff_winlen
2117 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2118 */
2119
2120 if (state->cfg.pll->ifreq == 0)
2121 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2122
2123 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_13seg);
2124}
2125
2126static void dib8000_set_subchannel_prbs(struct dib8000_state *state, u16 init_prbs)
2127{
2128 u16 reg_1;
2256 2129
2257 // ---- SMALL ---- 2130 reg_1 = dib8000_read_word(state, 1);
2258 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2131 dib8000_write_word(state, 1, (init_prbs << 2) | (reg_1 & 0x3)); /* ADDR 1 */
2132}
2133
2134static void dib8000_small_fine_tune(struct dib8000_state *state)
2135{
2136 u16 i;
2137 const s16 *ncoeff;
2138
2139 dib8000_write_word(state, 352, state->seg_diff_mask);
2140 dib8000_write_word(state, 353, state->seg_mask);
2141
2142 /* P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 */
2143 dib8000_write_word(state, 351, (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
2144
2145 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2146 /* ---- SMALL ---- */
2259 switch (state->fe[0]->dtv_property_cache.transmission_mode) { 2147 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2260 case TRANSMISSION_MODE_2K: 2148 case TRANSMISSION_MODE_2K:
2261 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 2149 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { /* 1-seg */
2262 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 2150 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) /* DQPSK */
2263 ncoeff = coeff_2k_sb_1seg_dqpsk; 2151 ncoeff = coeff_2k_sb_1seg_dqpsk;
2264 else // QPSK or QAM 2152 else /* QPSK or QAM */
2265 ncoeff = coeff_2k_sb_1seg; 2153 ncoeff = coeff_2k_sb_1seg;
2266 } else { // 3-segments 2154 } else { /* 3-segments */
2267 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 2155 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2268 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) 2156 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2269 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; 2157 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2270 else // QPSK or QAM on external segments 2158 else /* QPSK or QAM on external segments */
2271 ncoeff = coeff_2k_sb_3seg_0dqpsk; 2159 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2272 } else { // QPSK or QAM on central segment 2160 } else { /* QPSK or QAM on central segment */
2273 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) 2161 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2274 ncoeff = coeff_2k_sb_3seg_1dqpsk; 2162 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2275 else // QPSK or QAM on external segments 2163 else /* QPSK or QAM on external segments */
2276 ncoeff = coeff_2k_sb_3seg; 2164 ncoeff = coeff_2k_sb_3seg;
2165 }
2277 } 2166 }
2278 } 2167 break;
2279 break;
2280
2281 case TRANSMISSION_MODE_4K: 2168 case TRANSMISSION_MODE_4K:
2282 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 2169 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { /* 1-seg */
2283 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 2170 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) /* DQPSK */
2284 ncoeff = coeff_4k_sb_1seg_dqpsk; 2171 ncoeff = coeff_4k_sb_1seg_dqpsk;
2285 else // QPSK or QAM 2172 else /* QPSK or QAM */
2286 ncoeff = coeff_4k_sb_1seg; 2173 ncoeff = coeff_4k_sb_1seg;
2287 } else { // 3-segments 2174 } else { /* 3-segments */
2288 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 2175 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2289 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 2176 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2290 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; 2177 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2291 } else { // QPSK or QAM on external segments 2178 else /* QPSK or QAM on external segments */
2292 ncoeff = coeff_4k_sb_3seg_0dqpsk; 2179 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2180 } else { /* QPSK or QAM on central segment */
2181 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2182 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2183 else /* QPSK or QAM on external segments */
2184 ncoeff = coeff_4k_sb_3seg;
2293 } 2185 }
2294 } else { // QPSK or QAM on central segment
2295 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2296 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2297 } else // QPSK or QAM on external segments
2298 ncoeff = coeff_4k_sb_3seg;
2299 } 2186 }
2300 } 2187 break;
2301 break;
2302
2303 case TRANSMISSION_MODE_AUTO: 2188 case TRANSMISSION_MODE_AUTO:
2304 case TRANSMISSION_MODE_8K: 2189 case TRANSMISSION_MODE_8K:
2305 default: 2190 default:
2306 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 2191 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { /* 1-seg */
2307 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) 2192 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) /* DQPSK */
2308 ncoeff = coeff_8k_sb_1seg_dqpsk; 2193 ncoeff = coeff_8k_sb_1seg_dqpsk;
2309 else // QPSK or QAM 2194 else /* QPSK or QAM */
2310 ncoeff = coeff_8k_sb_1seg; 2195 ncoeff = coeff_8k_sb_1seg;
2311 } else { // 3-segments 2196 } else { /* 3-segments */
2312 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { 2197 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2313 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { 2198 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2314 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; 2199 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2315 } else { // QPSK or QAM on external segments 2200 else /* QPSK or QAM on external segments */
2316 ncoeff = coeff_8k_sb_3seg_0dqpsk; 2201 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2202 } else { /* QPSK or QAM on central segment */
2203 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) /* DQPSK on external segments */
2204 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2205 else /* QPSK or QAM on external segments */
2206 ncoeff = coeff_8k_sb_3seg;
2317 } 2207 }
2318 } else { // QPSK or QAM on central segment
2319 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2320 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2321 } else // QPSK or QAM on external segments
2322 ncoeff = coeff_8k_sb_3seg;
2323 } 2208 }
2324 } 2209 break;
2325 break;
2326 } 2210 }
2211
2327 for (i = 0; i < 8; i++) 2212 for (i = 0; i < 8; i++)
2328 dib8000_write_word(state, 343 + i, ncoeff[i]); 2213 dib8000_write_word(state, 343 + i, ncoeff[i]);
2329 } 2214 }
2215}
2330 2216
2331 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 2217static const u16 coff_thres_1seg[3] = {300, 150, 80};
2332 dib8000_write_word(state, 351, 2218static const u16 coff_thres_3seg[3] = {350, 300, 250};
2333 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); 2219static void dib8000_set_sb_channel(struct dib8000_state *state)
2220{
2221 const u16 *coff;
2222 u16 i;
2334 2223
2335 // ---- COFF ---- 2224 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
2336 // Carloff, the most robust 2225 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); /* adp_pass =1 */
2337 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2226 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); /* pha3_force_pha_shift = 1 */
2227 } else {
2228 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); /* adp_pass =0 */
2229 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); /* pha3_force_pha_shift = 0 */
2230 }
2338 2231
2339 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 2232 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) /* 3-segments */
2340 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 2233 state->seg_mask = 0x00E0;
2341 dib8000_write_word(state, 187, 2234 else /* 1-segment */
2342 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2) 2235 state->seg_mask = 0x0040;
2343 | 0x3);
2344 2236
2345/* // P_small_coef_ext_enable = 1 */ 2237 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2346/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
2347 2238
2348 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { 2239 /* ---- COFF ---- Carloff, the most robust --- */
2240 /* P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64, P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 */
2241 dib8000_write_word(state, 187, (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2) | 0x3);
2349 2242
2350 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1) 2243 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); /* P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 */
2351 if (mode == 3) 2244 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));/* P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 */
2352 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
2353 else
2354 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
2355 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
2356 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
2357 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2358 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2359 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2360 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2361 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2362
2363 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2364 dib8000_write_word(state, 181, 300);
2365 dib8000_write_word(state, 182, 150);
2366 dib8000_write_word(state, 183, 80);
2367 dib8000_write_word(state, 184, 300);
2368 dib8000_write_word(state, 185, 150);
2369 dib8000_write_word(state, 186, 80);
2370 } else { // Sound Broadcasting mode 3 seg
2371 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
2372 /* if (mode == 3) */
2373 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
2374 /* else */
2375 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
2376 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2377
2378 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
2379 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
2380 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2381 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2382 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2383 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2384 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2385
2386 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2387 dib8000_write_word(state, 181, 350);
2388 dib8000_write_word(state, 182, 300);
2389 dib8000_write_word(state, 183, 250);
2390 dib8000_write_word(state, 184, 350);
2391 dib8000_write_word(state, 185, 300);
2392 dib8000_write_word(state, 186, 250);
2393 }
2394 2245
2395 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments 2246 /* Sound Broadcasting mode 1 seg */
2396 dib8000_write_word(state, 180, (16 << 6) | 9); 2247 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2397 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2); 2248 /* P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width = (P_mode == 3) , P_coff_one_seg_sym = (P_mode-1) */
2398 coff_pow = 0x2800; 2249 if (state->mode == 3)
2399 for (i = 0; i < 6; i++) 2250 dib8000_write_word(state, 180, 0x1fcf | ((state->mode - 1) << 14));
2400 dib8000_write_word(state, 181 + i, coff_pow); 2251 else
2252 dib8000_write_word(state, 180, 0x0fcf | ((state->mode - 1) << 14));
2401 2253
2402 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1, 2254 /* P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4 */
2403 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1 2255 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2404 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1); 2256 coff = &coff_thres_1seg[0];
2257 } else { /* Sound Broadcasting mode 3 seg */
2258 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2259 /* P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4 */
2260 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2261 coff = &coff_thres_3seg[0];
2262 }
2405 2263
2406 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 2264 dib8000_write_word(state, 228, 1); /* P_2d_mode_byp=1 */
2407 dib8000_write_word(state, 340, (8 << 6) | (6 << 0)); 2265 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); /* P_cspu_win_cut = 0 */
2408 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 2266
2409 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 2267 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K)
2268 dib8000_write_word(state, 265, 15); /* P_equal_noise_sel = 15 */
2269
2270 /* Write COFF thres */
2271 for (i = 0 ; i < 3; i++) {
2272 dib8000_write_word(state, 181+i, coff[i]);
2273 dib8000_write_word(state, 184+i, coff[i]);
2410 } 2274 }
2411 // ---- FFT ----
2412 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2413 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
2414 else
2415 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
2416 2275
2417 /* make the cpil_coff_lock more robust but slower p_coff_winlen 2276 /*
2277 * make the cpil_coff_lock more robust but slower p_coff_winlen
2418 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) 2278 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2419 */ 2279 */
2420 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) 2280
2421 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ 2281 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask); /* P_equal_noise_seg_inh */
2422 2282
2423 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ 2283 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2424 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ 2284 dib8000_write_word(state, 178, 64); /* P_fft_powrange = 64 */
2425 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
2426 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
2427 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2428 else
2429 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
2430 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
2431 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
2432 if (!autosearching)
2433 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2434 else 2285 else
2435 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. 2286 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2436 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000); 2287}
2437
2438 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
2439
2440 /* offset loop parameters */
2441 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2442 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2443 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2444 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
2445
2446 else // Sound Broadcasting mode 3 seg
2447 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2448 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
2449 } else
2450 // TODO in 13 seg, timf_alpha can always be the same or not ?
2451 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2452 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
2453
2454 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2455 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2456 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
2457 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
2458
2459 else // Sound Broadcasting mode 3 seg
2460 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2461 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
2462 } else
2463 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2464 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
2465 2288
2466 /* P_dvsy_sync_wait - reuse mode */ 2289static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
2467 switch (state->fe[0]->dtv_property_cache.transmission_mode) { 2290{
2468 case TRANSMISSION_MODE_8K: 2291 u16 p_cfr_left_edge = 0, p_cfr_right_edge = 0;
2469 mode = 256; 2292 u16 tmcc_pow = 0, ana_gain = 0, tmp = 0, i = 0, nbseg_diff = 0 ;
2470 break; 2293 u16 max_constellation = DQPSK;
2471 case TRANSMISSION_MODE_4K: 2294 int init_prbs;
2472 mode = 128; 2295
2473 break; 2296 /* P_mode */
2474 default: 2297 dib8000_write_word(state, 10, (seq << 4));
2475 case TRANSMISSION_MODE_2K: 2298
2476 mode = 64; 2299 /* init mode */
2477 break; 2300 state->mode = fft_to_mode(state);
2301
2302 /* set guard */
2303 tmp = dib8000_read_word(state, 1);
2304 dib8000_write_word(state, 1, (tmp&0xfffc) | (state->fe[0]->dtv_property_cache.guard_interval & 0x3));
2305
2306 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.isdbt_sb_mode & 1) << 4));
2307
2308 /* signal optimization parameter */
2309 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
2310 state->seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
2311 for (i = 1; i < 3; i++)
2312 nbseg_diff += (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2313 for (i = 0; i < nbseg_diff; i++)
2314 state->seg_diff_mask |= 1 << permu_seg[i+1];
2315 } else {
2316 for (i = 0; i < 3; i++)
2317 nbseg_diff += (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2318 for (i = 0; i < nbseg_diff; i++)
2319 state->seg_diff_mask |= 1 << permu_seg[i];
2478 } 2320 }
2479 if (state->cfg.diversity_delay == 0) 2321
2480 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo 2322 if (state->seg_diff_mask)
2323 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2481 else 2324 else
2482 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo 2325 dib8000_write_word(state, 268, (2 << 9) | 39); /*init value */
2483 mode <<= 4;
2484 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
2485 2326
2486 /* channel estimation fine configuration */ 2327 for (i = 0; i < 3; i++)
2487 switch (max_constellation) { 2328 max_constellation = dib8000_set_layer(state, i, max_constellation);
2488 case QAM_64: 2329 if (autosearching == 0) {
2489 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB 2330 state->layer_b_nb_seg = state->fe[0]->dtv_property_cache.layer[1].segment_count;
2490 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 2331 state->layer_c_nb_seg = state->fe[0]->dtv_property_cache.layer[2].segment_count;
2491 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
2492 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2493 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
2494 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
2495 break;
2496 case QAM_16:
2497 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
2498 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
2499 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
2500 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2501 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
2502 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
2503 break;
2504 default:
2505 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
2506 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
2507 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
2508 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
2509 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
2510 break;
2511 } 2332 }
2512 for (mode = 0; mode < 4; mode++)
2513 dib8000_write_word(state, 215 + mode, coeff[mode]);
2514 2333
2515 // update ana_gain depending on max constellation 2334 /* WRITE: Mode & Diff mask */
2516 dib8000_write_word(state, 116, ana_gain); 2335 dib8000_write_word(state, 0, (state->mode << 13) | state->seg_diff_mask);
2517 // update ADC target depending on ana_gain
2518 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
2519 for (i = 0; i < 10; i++)
2520 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2521 } else { // set -22dB ADC target for ana_gain=0
2522 for (i = 0; i < 10; i++)
2523 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2524 }
2525 2336
2526 // ---- ANA_FE ---- 2337 state->differential_constellation = (state->seg_diff_mask != 0);
2338
2339 /* channel estimation fine configuration */
2340 ana_gain = dib8000_adp_fine_tune(state, max_constellation);
2341
2342 /* update ana_gain depending on max constellation */
2343 dib8000_update_ana_gain(state, ana_gain);
2344
2345 /* ---- ANA_FE ---- */
2346 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) /* 3-segments */
2347 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_3seg);
2348 else
2349 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_1seg); /* 1-segment */
2350
2351 /* TSB or ISDBT ? apply it now */
2527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { 2352 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2528 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) 2353 dib8000_set_sb_channel(state);
2529 ana_fe = ana_fe_coeff_3seg; 2354 if (state->fe[0]->dtv_property_cache.isdbt_sb_subchannel != -1)
2530 else // 1-segment 2355 init_prbs = dib8000_get_init_prbs(state, state->fe[0]->dtv_property_cache.isdbt_sb_subchannel);
2531 ana_fe = ana_fe_coeff_1seg; 2356 else
2532 } else 2357 init_prbs = 0;
2533 ana_fe = ana_fe_coeff_13seg; 2358 } else {
2534 2359 dib8000_set_13seg_channel(state);
2535 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) 2360 init_prbs = 0xfff;
2536 for (mode = 0; mode < 24; mode++) 2361 }
2537 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2538 2362
2539 // ---- CHAN_BLK ---- 2363 /* SMALL */
2364 dib8000_small_fine_tune(state);
2365
2366 dib8000_set_subchannel_prbs(state, init_prbs);
2367
2368 /* ---- CHAN_BLK ---- */
2540 for (i = 0; i < 13; i++) { 2369 for (i = 0; i < 13; i++) {
2541 if ((((~seg_diff_mask) >> i) & 1) == 1) { 2370 if ((((~state->seg_diff_mask) >> i) & 1) == 1) {
2542 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0)); 2371 p_cfr_left_edge += (1 << i) * ((i == 0) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i - 1)) & 1) == 0));
2543 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0)); 2372 p_cfr_right_edge += (1 << i) * ((i == 12) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i + 1)) & 1) == 0));
2544 } 2373 }
2545 } 2374 }
2546 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge 2375 dib8000_write_word(state, 222, p_cfr_left_edge); /* p_cfr_left_edge */
2547 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge 2376 dib8000_write_word(state, 223, p_cfr_right_edge); /* p_cfr_right_edge */
2548 // "P_cspu_left_edge" not used => do not care 2377 /* "P_cspu_left_edge" & "P_cspu_right_edge" not used => do not care */
2549 // "P_cspu_right_edge" not used => do not care 2378
2550 2379 dib8000_write_word(state, 189, ~state->seg_mask | state->seg_diff_mask); /* P_lmod4_seg_inh */
2551 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2380 dib8000_write_word(state, 192, ~state->seg_mask | state->seg_diff_mask); /* P_pha3_seg_inh */
2552 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 2381 dib8000_write_word(state, 225, ~state->seg_mask | state->seg_diff_mask); /* P_tac_seg_inh */
2553 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 2382
2554 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 2383 if (!autosearching)
2555 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { 2384 dib8000_write_word(state, 288, (~state->seg_mask | state->seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2556 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 2385 else
2557 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 2386 dib8000_write_word(state, 288, 0x1fff); /*disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. */
2558 } 2387
2559 } else if (state->isdbt_cfg_loaded == 0) { 2388 dib8000_write_word(state, 211, state->seg_mask & (~state->seg_diff_mask)); /* P_des_seg_enabled */
2560 dib8000_write_word(state, 228, 0); // default value 2389 dib8000_write_word(state, 287, ~state->seg_mask | 0x1000); /* P_tmcc_seg_inh */
2561 dib8000_write_word(state, 265, 31); // default value 2390
2562 dib8000_write_word(state, 205, 0x200f); // init value 2391 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2563 } 2392
2564 // ---- TMCC ---- 2393 /* ---- TMCC ---- */
2565 for (i = 0; i < 3; i++) 2394 for (i = 0; i < 3; i++)
2566 tmcc_pow += 2395 tmcc_pow += (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count) ;
2567 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count); 2396
2568 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); 2397 /* Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); */
2569 // Threshold is set at 1/4 of max power. 2398 /* Threshold is set at 1/4 of max power. */
2570 tmcc_pow *= (1 << (9 - 2)); 2399 tmcc_pow *= (1 << (9-2));
2571 2400 dib8000_write_word(state, 290, tmcc_pow); /* P_tmcc_dec_thres_2k */
2572 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k 2401 dib8000_write_word(state, 291, tmcc_pow); /* P_tmcc_dec_thres_4k */
2573 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k 2402 dib8000_write_word(state, 292, tmcc_pow); /* P_tmcc_dec_thres_8k */
2574 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k 2403 /*dib8000_write_word(state, 287, (1 << 13) | 0x1000 ); */
2575 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
2576 // ---- PHA3 ----
2577 2404
2405 /* ---- PHA3 ---- */
2578 if (state->isdbt_cfg_loaded == 0) 2406 if (state->isdbt_cfg_loaded == 0)
2579 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ 2407 dib8000_write_word(state, 250, 3285); /* p_2d_hspeed_thr0 */
2580 2408
2581 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) 2409 state->isdbt_cfg_loaded = 0;
2582 state->isdbt_cfg_loaded = 0; 2410}
2583 else
2584 state->isdbt_cfg_loaded = 1;
2585 2411
2412u32 dib8000_wait_lock(struct dib8000_state *state, u32 internal, u32 wait0_ms, u32 wait1_ms, u32 wait2_ms)
2413{
2414 u32 value;
2415 u16 reg = 11; /* P_search_end0 start addr */
2416
2417 for (reg = 11; reg < 16; reg += 2) {
2418 if (reg == 11) {
2419 if (state->revision == 0x8090)
2420 value = internal * wait1_ms; /* P_search_end0 wait time */
2421 else
2422 value = internal * wait0_ms; /* P_search_end0 wait time */
2423 } else if (reg == 13)
2424 value = internal * wait1_ms; /* P_search_end0 wait time */
2425 else if (reg == 15)
2426 value = internal * wait2_ms; /* P_search_end0 wait time */
2427 dib8000_write_word(state, reg, (u16)((value >> 16) & 0xffff));
2428 dib8000_write_word(state, (reg + 1), (u16)(value & 0xffff));
2429 }
2430 return value;
2586} 2431}
2587 2432
2588static int dib8000_autosearch_start(struct dvb_frontend *fe) 2433static int dib8000_autosearch_start(struct dvb_frontend *fe)
2589{ 2434{
2590 u8 factor;
2591 u32 value;
2592 struct dib8000_state *state = fe->demodulator_priv; 2435 struct dib8000_state *state = fe->demodulator_priv;
2436 u8 slist = 0;
2437 u32 value, internal = state->cfg.pll->internal;
2438
2439 if (state->revision == 0x8090)
2440 internal = dib8000_read32(state, 23) / 1000;
2593 2441
2594 int slist = 0; 2442 if (state->autosearch_state == AS_SEARCHING_FFT) {
2443 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */
2444 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
2595 2445
2596 state->fe[0]->dtv_property_cache.inversion = 0; 2446 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x1fff) | (0 << 13) | (1 << 15)); /* P_mode = 0, P_restart_search=1 */
2597 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode) 2447 dib8000_write_word(state, 1, (dib8000_read_word(state, 1) & 0xfffc) | 0); /* P_guard = 0 */
2598 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13; 2448 dib8000_write_word(state, 6, 0); /* P_lock0_mask = 0 */
2599 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64; 2449 dib8000_write_word(state, 7, 0); /* P_lock1_mask = 0 */
2600 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3; 2450 dib8000_write_word(state, 8, 0); /* P_lock2_mask = 0 */
2601 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0; 2451 dib8000_write_word(state, 10, (dib8000_read_word(state, 10) & 0x200) | (16 << 4) | (0 << 0)); /* P_search_list=16, P_search_maxtrial=0 */
2602 2452
2603 //choose the right list, in sb, always do everything 2453 if (state->revision == 0x8090)
2604 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { 2454 value = dib8000_wait_lock(state, internal, 10, 10, 10); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2455 else
2456 value = dib8000_wait_lock(state, internal, 20, 20, 20); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2457
2458 dib8000_write_word(state, 17, 0);
2459 dib8000_write_word(state, 18, 200); /* P_search_rstst = 200 */
2460 dib8000_write_word(state, 19, 0);
2461 dib8000_write_word(state, 20, 400); /* P_search_rstend = 400 */
2462 dib8000_write_word(state, 21, (value >> 16) & 0xffff); /* P_search_checkst */
2463 dib8000_write_word(state, 22, value & 0xffff);
2464
2465 if (state->revision == 0x8090)
2466 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (0 << 8)); /* P_corm_alpha = 0 */
2467 else
2468 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (9 << 8)); /* P_corm_alpha = 3 */
2469 dib8000_write_word(state, 355, 2); /* P_search_param_max = 2 */
2470
2471 /* P_search_param_select = (1 | 1<<4 | 1 << 8) */
2472 dib8000_write_word(state, 356, 0);
2473 dib8000_write_word(state, 357, 0x111);
2474
2475 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2476 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2477 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
2478 } else if (state->autosearch_state == AS_SEARCHING_GUARD) {
2605 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; 2479 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2606 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; 2480 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2607 slist = 7; 2481 state->fe[0]->dtv_property_cache.inversion = 0;
2608 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); 2482 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
2483 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
2484 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
2485 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
2486
2487 slist = 16;
2488 state->fe[0]->dtv_property_cache.transmission_mode = state->found_nfft;
2489
2490 dib8000_set_isdbt_common_channel(state, slist, 1);
2491
2492 /* set lock_mask values */
2493 dib8000_write_word(state, 6, 0x4);
2494 if (state->revision == 0x8090)
2495 dib8000_write_word(state, 7, ((1 << 12) | (1 << 11) | (1 << 10)));/* tmcc_dec_lock, tmcc_sync_lock, tmcc_data_lock, tmcc_bch_uncor */
2496 else
2497 dib8000_write_word(state, 7, 0x8);
2498 dib8000_write_word(state, 8, 0x1000);
2499
2500 /* set lock_mask wait time values */
2501 if (state->revision == 0x8090)
2502 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2503 else
2504 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2505
2506 dib8000_write_word(state, 355, 3); /* P_search_param_max = 3 */
2507
2508 /* P_search_param_select = 0xf; look for the 4 different guard intervals */
2509 dib8000_write_word(state, 356, 0);
2510 dib8000_write_word(state, 357, 0xf);
2511
2512 value = dib8000_read_word(state, 0);
2513 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2514 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2515 dib8000_write_word(state, 0, (u16)value);
2609 } else { 2516 } else {
2610 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { 2517 state->fe[0]->dtv_property_cache.inversion = 0;
2611 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 2518 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
2612 slist = 7; 2519 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
2613 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2 2520 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
2614 } else 2521 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
2615 slist = 3; 2522 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
2523 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
2524
2525 /* choose the right list, in sb, always do everything */
2526 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2527 slist = 7;
2528 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2616 } else { 2529 } else {
2617 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 2530 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
2618 slist = 2; 2531 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2619 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 2532 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2620 } else 2533 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2621 slist = 0; 2534 slist = 7;
2535 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 to have autosearch start ok with mode2 */
2536 } else {
2537 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2538 slist = 3;
2539 }
2540 } else {
2541 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2542 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2543 slist = 2;
2544 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 */
2545 } else
2546 slist = 0;
2547 }
2622 } 2548 }
2549 dprintk("Using list for autosearch : %d", slist);
2623 2550
2624 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) 2551 dib8000_set_isdbt_common_channel(state, slist, 1);
2625 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2626 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
2627 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2628
2629 dprintk("using list for autosearch : %d", slist);
2630 dib8000_set_channel(state, (unsigned char)slist, 1);
2631 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
2632
2633 factor = 1;
2634 2552
2635 //set lock_mask values 2553 /* set lock_mask values */
2636 dib8000_write_word(state, 6, 0x4); 2554 dib8000_write_word(state, 6, 0x4);
2637 dib8000_write_word(state, 7, 0x8); 2555 if (state->revision == 0x8090)
2556 dib8000_write_word(state, 7, (1 << 12) | (1 << 11) | (1 << 10));
2557 else
2558 dib8000_write_word(state, 7, 0x8);
2638 dib8000_write_word(state, 8, 0x1000); 2559 dib8000_write_word(state, 8, 0x1000);
2639 2560
2640 //set lock_mask wait time values 2561 /* set lock_mask wait time values */
2641 value = 50 * state->cfg.pll->internal * factor; 2562 if (state->revision == 0x8090)
2642 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 2563 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2643 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time 2564 else
2644 value = 100 * state->cfg.pll->internal * factor; 2565 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2645 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
2646 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
2647 value = 1000 * state->cfg.pll->internal * factor;
2648 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
2649 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
2650 2566
2651 value = dib8000_read_word(state, 0); 2567 value = dib8000_read_word(state, 0);
2652 dib8000_write_word(state, 0, (u16) ((1 << 15) | value)); 2568 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2653 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending 2569 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2654 dib8000_write_word(state, 0, (u16) value); 2570 dib8000_write_word(state, 0, (u16)value);
2655
2656 } 2571 }
2657
2658 return 0; 2572 return 0;
2659} 2573}
2660 2574
@@ -2663,96 +2577,623 @@ static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2663 struct dib8000_state *state = fe->demodulator_priv; 2577 struct dib8000_state *state = fe->demodulator_priv;
2664 u16 irq_pending = dib8000_read_word(state, 1284); 2578 u16 irq_pending = dib8000_read_word(state, 1284);
2665 2579
2666 if (irq_pending & 0x1) { // failed 2580 if (state->autosearch_state == AS_SEARCHING_FFT) {
2667 dprintk("dib8000_autosearch_irq failed"); 2581 if (irq_pending & 0x1) {
2668 return 1; 2582 dprintk("dib8000_autosearch_irq: max correlation result available");
2669 } 2583 return 3;
2584 }
2585 } else {
2586 if (irq_pending & 0x1) { /* failed */
2587 dprintk("dib8000_autosearch_irq failed");
2588 return 1;
2589 }
2670 2590
2671 if (irq_pending & 0x2) { // succeeded 2591 if (irq_pending & 0x2) { /* succeeded */
2672 dprintk("dib8000_autosearch_irq succeeded"); 2592 dprintk("dib8000_autosearch_irq succeeded");
2673 return 2; 2593 return 2;
2594 }
2674 } 2595 }
2675 2596
2676 return 0; // still pending 2597 return 0; // still pending
2677} 2598}
2678 2599
2679static int dib8000_tune(struct dvb_frontend *fe) 2600static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
2680{ 2601{
2681 struct dib8000_state *state = fe->demodulator_priv; 2602 u16 tmp;
2682 int ret = 0;
2683 u16 lock, value, mode;
2684 2603
2685 // we are already tuned - just resuming from suspend 2604 tmp = dib8000_read_word(state, 771);
2686 if (state == NULL) 2605 if (onoff) /* start P_restart_chd : channel_decoder */
2687 return -EINVAL; 2606 dib8000_write_word(state, 771, tmp & 0xfffd);
2607 else /* stop P_restart_chd : channel_decoder */
2608 dib8000_write_word(state, 771, tmp | (1<<1));
2609}
2688 2610
2689 mode = fft_to_mode(state); 2611static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
2612{
2613 s16 unit_khz_dds_val;
2614 u32 abs_offset_khz = ABS(offset_khz);
2615 u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
2616 u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
2617 u8 ratio;
2690 2618
2691 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000); 2619 if (state->revision == 0x8090) {
2692 dib8000_set_channel(state, 0, 0); 2620 ratio = 4;
2621 unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
2622 if (offset_khz < 0)
2623 dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
2624 else
2625 dds = (abs_offset_khz * unit_khz_dds_val);
2693 2626
2694 // restart demod 2627 if (invert)
2695 ret |= dib8000_write_word(state, 770, 0x4000); 2628 dds = (1<<26) - dds;
2696 ret |= dib8000_write_word(state, 770, 0x0000); 2629 } else {
2697 msleep(45); 2630 ratio = 2;
2631 unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
2698 2632
2699 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */ 2633 if (offset_khz < 0)
2700 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */ 2634 unit_khz_dds_val *= -1;
2701 2635
2702 // never achieved a lock before - wait for timfreq to update 2636 /* IF tuner */
2703 if (state->timf == 0) { 2637 if (invert)
2704 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2638 dds -= abs_offset_khz * unit_khz_dds_val;
2705 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) 2639 else
2706 msleep(300); 2640 dds += abs_offset_khz * unit_khz_dds_val;
2707 else // Sound Broadcasting mode 3 seg 2641 }
2708 msleep(500); 2642
2709 } else // 13 seg 2643 dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val);
2710 msleep(200); 2644
2645 if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) {
2646 /* Max dds offset is the half of the demod freq */
2647 dib8000_write_word(state, 26, invert);
2648 dib8000_write_word(state, 27, (u16)(dds >> 16) & 0x1ff);
2649 dib8000_write_word(state, 28, (u16)(dds & 0xffff));
2711 } 2650 }
2712 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2651}
2713 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2714 2652
2715 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ 2653static void dib8000_set_frequency_offset(struct dib8000_state *state)
2716 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); 2654{
2717 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80); 2655 int i;
2656 u32 current_rf;
2657 int total_dds_offset_khz;
2718 2658
2719 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */ 2659 if (state->fe[0]->ops.tuner_ops.get_frequency)
2720 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5)); 2660 state->fe[0]->ops.tuner_ops.get_frequency(state->fe[0], &current_rf);
2661 else
2662 current_rf = state->fe[0]->dtv_property_cache.frequency;
2663 current_rf /= 1000;
2664 total_dds_offset_khz = (int)current_rf - (int)state->fe[0]->dtv_property_cache.frequency / 1000;
2721 2665
2722 } else { // Sound Broadcasting mode 3 seg 2666 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2667 state->subchannel = state->fe[0]->dtv_property_cache.isdbt_sb_subchannel;
2723 2668
2724 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */ 2669 i = dib8000_read_word(state, 26) & 1; /* P_dds_invspec */
2725 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60); 2670 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion ^ i);
2726 2671
2727 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5)); 2672 if (state->cfg.pll->ifreq == 0) { /* low if tuner */
2673 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
2674 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
2675 } else {
2676 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
2677 total_dds_offset_khz *= -1;
2728 } 2678 }
2679 }
2729 2680
2730 } else { // 13 seg 2681 dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d", state->fe[0]->dtv_property_cache.frequency - current_rf, state->fe[0]->dtv_property_cache.frequency, current_rf, total_dds_offset_khz);
2731 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
2732 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
2733 2682
2734 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5)); 2683 /* apply dds offset now */
2684 dib8000_set_dds(state, total_dds_offset_khz);
2685}
2686
2687static u16 LUT_isdbt_symbol_duration[4] = { 26, 101, 63 };
2688u32 dib8000_get_symbol_duration(struct dib8000_state *state)
2689{
2690 u16 i;
2735 2691
2692 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2693 case TRANSMISSION_MODE_2K:
2694 i = 0;
2695 break;
2696 case TRANSMISSION_MODE_4K:
2697 i = 2;
2698 break;
2699 default:
2700 case TRANSMISSION_MODE_AUTO:
2701 case TRANSMISSION_MODE_8K:
2702 i = 1;
2703 break;
2736 } 2704 }
2737 2705
2738 // we achieved a coff_cpil_lock - it's time to update the timf 2706 return (LUT_isdbt_symbol_duration[i] / (state->fe[0]->dtv_property_cache.bandwidth_hz / 1000)) + 1;
2739 if (state->revision != 0x8090) 2707}
2740 lock = dib8000_read_word(state, 568); 2708
2709static void dib8000_set_isdbt_loop_params(struct dib8000_state *state, enum param_loop_step loop_step)
2710{
2711 u16 reg_32 = 0, reg_37 = 0;
2712
2713 switch (loop_step) {
2714 case LOOP_TUNE_1:
2715 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2716 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2717 reg_32 = ((11 - state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x40 */
2718 reg_37 = (3 << 5) | (0 << 4) | (10 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2719 } else { /* Sound Broadcasting mode 3 seg */
2720 reg_32 = ((10 - state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x60 */
2721 reg_37 = (3 << 5) | (0 << 4) | (9 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (9-P_mode) */
2722 }
2723 } else { /* 13-seg start conf offset loop parameters */
2724 reg_32 = ((9 - state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2725 reg_37 = (3 << 5) | (0 << 4) | (8 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2726 }
2727 break;
2728 case LOOP_TUNE_2:
2729 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2730 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { /* Sound Broadcasting mode 1 seg */
2731 reg_32 = ((13-state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40*/
2732 reg_37 = (12-state->mode) | ((5 + state->mode) << 5);
2733 } else { /* Sound Broadcasting mode 3 seg */
2734 reg_32 = ((12-state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 */
2735 reg_37 = (11-state->mode) | ((5 + state->mode) << 5);
2736 }
2737 } else { /* 13 seg */
2738 reg_32 = ((11-state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 */
2739 reg_37 = ((5+state->mode) << 5) | (10 - state->mode);
2740 }
2741 break;
2742 }
2743 dib8000_write_word(state, 32, reg_32);
2744 dib8000_write_word(state, 37, reg_37);
2745}
2746
2747static void dib8000_demod_restart(struct dib8000_state *state)
2748{
2749 dib8000_write_word(state, 770, 0x4000);
2750 dib8000_write_word(state, 770, 0x0000);
2751 return;
2752}
2753
2754static void dib8000_set_sync_wait(struct dib8000_state *state)
2755{
2756 u16 sync_wait = 64;
2757
2758 /* P_dvsy_sync_wait - reuse mode */
2759 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2760 case TRANSMISSION_MODE_8K:
2761 sync_wait = 256;
2762 break;
2763 case TRANSMISSION_MODE_4K:
2764 sync_wait = 128;
2765 break;
2766 default:
2767 case TRANSMISSION_MODE_2K:
2768 sync_wait = 64;
2769 break;
2770 }
2771
2772 if (state->cfg.diversity_delay == 0)
2773 sync_wait = (sync_wait * (1 << (state->fe[0]->dtv_property_cache.guard_interval)) * 3) / 2 + 48; /* add 50% SFN margin + compensate for one DVSY-fifo */
2774 else
2775 sync_wait = (sync_wait * (1 << (state->fe[0]->dtv_property_cache.guard_interval)) * 3) / 2 + state->cfg.diversity_delay; /* add 50% SFN margin + compensate for DVSY-fifo */
2776
2777 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
2778}
2779
2780static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
2781{
2782 if (mode == SYMBOL_DEPENDENT_ON)
2783 return systime() + (delay * state->symbol_duration);
2741 else 2784 else
2742 lock = dib8000_read_word(state, 570); 2785 return systime() + delay;
2743 if ((lock >> 11) & 0x1) 2786}
2744 dib8000_update_timf(state);
2745 2787
2746 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start 2788static s32 dib8000_get_status(struct dvb_frontend *fe)
2747 dib8000_write_word(state, 6, 0x200); 2789{
2790 struct dib8000_state *state = fe->demodulator_priv;
2791 return state->status;
2792}
2748 2793
2749 if (state->revision == 0x8002) { 2794enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2750 value = dib8000_read_word(state, 903); 2795{
2751 dib8000_write_word(state, 903, value & ~(1 << 3)); 2796 struct dib8000_state *state = fe->demodulator_priv;
2752 msleep(1); 2797 return state->tune_state;
2753 dib8000_write_word(state, 903, value | (1 << 3)); 2798}
2799EXPORT_SYMBOL(dib8000_get_tune_state);
2800
2801int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2802{
2803 struct dib8000_state *state = fe->demodulator_priv;
2804
2805 state->tune_state = tune_state;
2806 return 0;
2807}
2808EXPORT_SYMBOL(dib8000_set_tune_state);
2809
2810static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
2811{
2812 struct dib8000_state *state = fe->demodulator_priv;
2813
2814 state->status = FE_STATUS_TUNE_PENDING;
2815 state->tune_state = CT_DEMOD_START;
2816 return 0;
2817}
2818
2819static u16 dib8000_read_lock(struct dvb_frontend *fe)
2820{
2821 struct dib8000_state *state = fe->demodulator_priv;
2822
2823 if (state->revision == 0x8090)
2824 return dib8000_read_word(state, 570);
2825 return dib8000_read_word(state, 568);
2826}
2827
2828static int dib8090p_init_sdram(struct dib8000_state *state)
2829{
2830 u16 reg = 0;
2831 dprintk("init sdram");
2832
2833 reg = dib8000_read_word(state, 274) & 0xfff0;
2834 dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */
2835
2836 dib8000_write_word(state, 1803, (7 << 2));
2837
2838 reg = dib8000_read_word(state, 1280);
2839 dib8000_write_word(state, 1280, reg | (1 << 2)); /* force restart P_restart_sdram */
2840 dib8000_write_word(state, 1280, reg); /* release restart P_restart_sdram */
2841
2842 return 0;
2843}
2844
2845static int dib8000_tune(struct dvb_frontend *fe)
2846{
2847 struct dib8000_state *state = fe->demodulator_priv;
2848 enum frontend_tune_state *tune_state = &state->tune_state;
2849
2850 u16 locks, deeper_interleaver = 0, i;
2851 int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
2852
2853 u32 *timeout = &state->timeout;
2854 u32 now = systime();
2855#ifdef DIB8000_AGC_FREEZE
2856 u16 agc1, agc2;
2857#endif
2858
2859 u32 corm[4] = {0, 0, 0, 0};
2860 u8 find_index, max_value;
2861
2862#if 0
2863 if (*tune_state < CT_DEMOD_STOP)
2864 dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
2865#endif
2866
2867 switch (*tune_state) {
2868 case CT_DEMOD_START: /* 30 */
2869 if (state->revision == 0x8090)
2870 dib8090p_init_sdram(state);
2871 state->status = FE_STATUS_TUNE_PENDING;
2872 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2873 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2874 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2875 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2876 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2877 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2878 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2879 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2880 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2881 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2882 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2883 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2884 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2885 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2886 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2887 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2888 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2889 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2890 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2891 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2892 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2893 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2894 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2895 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0))))
2896 state->channel_parameters_set = 0; /* auto search */
2897 else
2898 state->channel_parameters_set = 1; /* channel parameters are known */
2899
2900 dib8000_viterbi_state(state, 0); /* force chan dec in restart */
2901
2902 /* Layer monit */
2903 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
2904
2905 dib8000_set_frequency_offset(state);
2906 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
2907
2908 if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
2909#ifdef DIB8000_AGC_FREEZE
2910 if (state->revision != 0x8090) {
2911 state->agc1_max = dib8000_read_word(state, 108);
2912 state->agc1_min = dib8000_read_word(state, 109);
2913 state->agc2_max = dib8000_read_word(state, 110);
2914 state->agc2_min = dib8000_read_word(state, 111);
2915 agc1 = dib8000_read_word(state, 388);
2916 agc2 = dib8000_read_word(state, 389);
2917 dib8000_write_word(state, 108, agc1);
2918 dib8000_write_word(state, 109, agc1);
2919 dib8000_write_word(state, 110, agc2);
2920 dib8000_write_word(state, 111, agc2);
2921 }
2922#endif
2923 state->autosearch_state = AS_SEARCHING_FFT;
2924 state->found_nfft = TRANSMISSION_MODE_AUTO;
2925 state->found_guard = GUARD_INTERVAL_AUTO;
2926 *tune_state = CT_DEMOD_SEARCH_NEXT;
2927 } else { /* we already know the channel struct so TUNE only ! */
2928 state->autosearch_state = AS_DONE;
2929 *tune_state = CT_DEMOD_STEP_3;
2930 }
2931 state->symbol_duration = dib8000_get_symbol_duration(state);
2932 break;
2933
2934 case CT_DEMOD_SEARCH_NEXT: /* 51 */
2935 dib8000_autosearch_start(fe);
2936 if (state->revision == 0x8090)
2937 ret = 50;
2938 else
2939 ret = 15;
2940 *tune_state = CT_DEMOD_STEP_1;
2941 break;
2942
2943 case CT_DEMOD_STEP_1: /* 31 */
2944 switch (dib8000_autosearch_irq(fe)) {
2945 case 1: /* fail */
2946 state->status = FE_STATUS_TUNE_FAILED;
2947 state->autosearch_state = AS_DONE;
2948 *tune_state = CT_DEMOD_STOP; /* else we are done here */
2949 break;
2950 case 2: /* Succes */
2951 state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
2952 *tune_state = CT_DEMOD_STEP_3;
2953 if (state->autosearch_state == AS_SEARCHING_GUARD)
2954 *tune_state = CT_DEMOD_STEP_2;
2955 else
2956 state->autosearch_state = AS_DONE;
2957 break;
2958 case 3: /* Autosearch FFT max correlation endded */
2959 *tune_state = CT_DEMOD_STEP_2;
2960 break;
2961 }
2962 break;
2963
2964 case CT_DEMOD_STEP_2:
2965 switch (state->autosearch_state) {
2966 case AS_SEARCHING_FFT:
2967 /* searching for the correct FFT */
2968 if (state->revision == 0x8090) {
2969 corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2970 corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2971 corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
2972 } else {
2973 corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
2974 corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2975 corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2976 }
2977 /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
2978
2979 max_value = 0;
2980 for (find_index = 1 ; find_index < 3 ; find_index++) {
2981 if (corm[max_value] < corm[find_index])
2982 max_value = find_index ;
2983 }
2984
2985 switch (max_value) {
2986 case 0:
2987 state->found_nfft = TRANSMISSION_MODE_2K;
2988 break;
2989 case 1:
2990 state->found_nfft = TRANSMISSION_MODE_4K;
2991 break;
2992 case 2:
2993 default:
2994 state->found_nfft = TRANSMISSION_MODE_8K;
2995 break;
2996 }
2997 /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
2998
2999 *tune_state = CT_DEMOD_SEARCH_NEXT;
3000 state->autosearch_state = AS_SEARCHING_GUARD;
3001 if (state->revision == 0x8090)
3002 ret = 50;
3003 else
3004 ret = 10;
3005 break;
3006 case AS_SEARCHING_GUARD:
3007 /* searching for the correct guard interval */
3008 if (state->revision == 0x8090)
3009 state->found_guard = dib8000_read_word(state, 572) & 0x3;
3010 else
3011 state->found_guard = dib8000_read_word(state, 570) & 0x3;
3012 /* dprintk("guard interval found=%i", state->found_guard); */
3013
3014 *tune_state = CT_DEMOD_STEP_3;
3015 break;
3016 default:
3017 /* the demod should never be in this state */
3018 state->status = FE_STATUS_TUNE_FAILED;
3019 state->autosearch_state = AS_DONE;
3020 *tune_state = CT_DEMOD_STOP; /* else we are done here */
3021 break;
3022 }
3023 break;
3024
3025 case CT_DEMOD_STEP_3: /* 33 */
3026 state->symbol_duration = dib8000_get_symbol_duration(state);
3027 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
3028 dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
3029 *tune_state = CT_DEMOD_STEP_4;
3030 break;
3031
3032 case CT_DEMOD_STEP_4: /* (34) */
3033 dib8000_demod_restart(state);
3034
3035 dib8000_set_sync_wait(state);
3036 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
3037
3038 locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
3039 /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
3040 *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
3041 *tune_state = CT_DEMOD_STEP_5;
3042 break;
3043
3044 case CT_DEMOD_STEP_5: /* (35) */
3045 locks = dib8000_read_lock(fe);
3046 if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
3047 dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
3048 if (!state->differential_constellation) {
3049 /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
3050 *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
3051 *tune_state = CT_DEMOD_STEP_7;
3052 } else {
3053 *tune_state = CT_DEMOD_STEP_8;
3054 }
3055 } else if (now > *timeout) {
3056 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3057 }
3058 break;
3059
3060 case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
3061 if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
3062 /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
3063 if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
3064 *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
3065 else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
3066 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3067 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3068 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3069 state->status = FE_STATUS_TUNE_FAILED;
3070 }
3071 } else {
3072 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3073 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3074 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3075 state->status = FE_STATUS_TUNE_FAILED;
3076 }
3077 break;
3078
3079 case CT_DEMOD_STEP_7: /* 37 */
3080 locks = dib8000_read_lock(fe);
3081 if (locks & (1<<10)) { /* lmod4_lock */
3082 ret = 14; /* wait for 14 symbols */
3083 *tune_state = CT_DEMOD_STEP_8;
3084 } else if (now > *timeout)
3085 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3086 break;
3087
3088 case CT_DEMOD_STEP_8: /* 38 */
3089 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3090 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3091
3092 /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
3093 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode && state->fe[0]->dtv_property_cache.isdbt_sb_subchannel == -1 && !state->differential_constellation) {
3094 state->subchannel = 0;
3095 *tune_state = CT_DEMOD_STEP_11;
3096 } else {
3097 *tune_state = CT_DEMOD_STEP_9;
3098 state->status = FE_STATUS_LOCKED;
3099 }
3100 break;
3101
3102 case CT_DEMOD_STEP_9: /* 39 */
3103 if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
3104 /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
3105 for (i = 0; i < 3; i++) {
3106 if (state->fe[0]->dtv_property_cache.layer[i].interleaving >= deeper_interleaver) {
3107 dprintk("layer%i: time interleaver = %d ", i, state->fe[0]->dtv_property_cache.layer[i].interleaving);
3108 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) { /* valid layer */
3109 deeper_interleaver = state->fe[0]->dtv_property_cache.layer[0].interleaving;
3110 state->longest_intlv_layer = i;
3111 }
3112 }
3113 }
3114
3115 if (deeper_interleaver == 0)
3116 locks = 2; /* locks is the tmp local variable name */
3117 else if (deeper_interleaver == 3)
3118 locks = 8;
3119 else
3120 locks = 2 * deeper_interleaver;
3121
3122 if (state->diversity_onoff != 0) /* because of diversity sync */
3123 locks *= 2;
3124
3125 *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
3126 dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
3127
3128 *tune_state = CT_DEMOD_STEP_10;
3129 } else
3130 *tune_state = CT_DEMOD_STOP;
3131 break;
3132
3133 case CT_DEMOD_STEP_10: /* 40 */
3134 locks = dib8000_read_lock(fe);
3135 if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
3136 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3137 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode && state->fe[0]->dtv_property_cache.isdbt_sb_subchannel == -1 && !state->differential_constellation)
3138 /* signal to the upper layer, that there was a channel found and the parameters can be read */
3139 state->status = FE_STATUS_DEMOD_SUCCESS;
3140 else
3141 state->status = FE_STATUS_DATA_LOCKED;
3142 *tune_state = CT_DEMOD_STOP;
3143 } else if (now > *timeout) {
3144 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode && state->fe[0]->dtv_property_cache.isdbt_sb_subchannel == -1 && !state->differential_constellation) { /* continue to try init prbs autosearch */
3145 state->subchannel += 3;
3146 *tune_state = CT_DEMOD_STEP_11;
3147 } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
3148 if (locks & (0x7<<5)) {
3149 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3150 state->status = FE_STATUS_DATA_LOCKED;
3151 } else
3152 state->status = FE_STATUS_TUNE_FAILED;
3153 *tune_state = CT_DEMOD_STOP;
3154 }
3155 }
3156 break;
3157
3158 case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
3159 if (state->subchannel <= 41) {
3160 dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
3161 *tune_state = CT_DEMOD_STEP_9;
3162 } else {
3163 *tune_state = CT_DEMOD_STOP;
3164 state->status = FE_STATUS_TUNE_FAILED;
3165 }
3166 break;
3167
3168 default:
3169 break;
3170 }
3171
3172 /* tuning is finished - cleanup the demod */
3173 switch (*tune_state) {
3174 case CT_DEMOD_STOP: /* (42) */
3175#ifdef DIB8000_AGC_FREEZE
3176 if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
3177 dib8000_write_word(state, 108, state->agc1_max);
3178 dib8000_write_word(state, 109, state->agc1_min);
3179 dib8000_write_word(state, 110, state->agc2_max);
3180 dib8000_write_word(state, 111, state->agc2_min);
3181 state->agc1_max = 0;
3182 state->agc1_min = 0;
3183 state->agc2_max = 0;
3184 state->agc2_min = 0;
3185 }
3186#endif
3187 ret = FE_CALLBACK_TIME_NEVER;
3188 break;
3189 default:
3190 break;
2754 } 3191 }
2755 3192
3193 if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
3194 return ret * state->symbol_duration;
3195 if ((ret > 0) && (ret < state->symbol_duration))
3196 return state->symbol_duration; /* at least one symbol */
2756 return ret; 3197 return ret;
2757} 3198}
2758 3199
@@ -2767,7 +3208,7 @@ static int dib8000_wakeup(struct dvb_frontend *fe)
2767 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) 3208 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
2768 dprintk("could not start Slow ADC"); 3209 dprintk("could not start Slow ADC");
2769 3210
2770 if (state->revision != 0x8090) 3211 if (state->revision == 0x8090)
2771 dib8000_sad_calib(state); 3212 dib8000_sad_calib(state);
2772 3213
2773 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 3214 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
@@ -2797,21 +3238,6 @@ static int dib8000_sleep(struct dvb_frontend *fe)
2797 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); 3238 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
2798} 3239}
2799 3240
2800enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2801{
2802 struct dib8000_state *state = fe->demodulator_priv;
2803 return state->tune_state;
2804}
2805EXPORT_SYMBOL(dib8000_get_tune_state);
2806
2807int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2808{
2809 struct dib8000_state *state = fe->demodulator_priv;
2810 state->tune_state = tune_state;
2811 return 0;
2812}
2813EXPORT_SYMBOL(dib8000_set_tune_state);
2814
2815static int dib8000_get_frontend(struct dvb_frontend *fe) 3241static int dib8000_get_frontend(struct dvb_frontend *fe)
2816{ 3242{
2817 struct dib8000_state *state = fe->demodulator_priv; 3243 struct dib8000_state *state = fe->demodulator_priv;
@@ -2961,10 +3387,9 @@ static int dib8000_get_frontend(struct dvb_frontend *fe)
2961static int dib8000_set_frontend(struct dvb_frontend *fe) 3387static int dib8000_set_frontend(struct dvb_frontend *fe)
2962{ 3388{
2963 struct dib8000_state *state = fe->demodulator_priv; 3389 struct dib8000_state *state = fe->demodulator_priv;
2964 u8 nbr_pending, exit_condition, index_frontend; 3390 int l, i, active, time, ret, time_slave = FE_CALLBACK_TIME_NEVER;
2965 s8 index_frontend_success = -1; 3391 u8 exit_condition, index_frontend;
2966 int time, ret; 3392 u32 delay, callback_time;
2967 int time_slave = FE_CALLBACK_TIME_NEVER;
2968 3393
2969 if (state->fe[0]->dtv_property_cache.frequency == 0) { 3394 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2970 dprintk("dib8000: must at least specify frequency "); 3395 dprintk("dib8000: must at least specify frequency ");
@@ -2981,18 +3406,36 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
2981 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; 3406 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2982 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); 3407 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2983 3408
2984 if (state->revision != 0x8090) 3409 /* set output mode and diversity input */
2985 dib8000_set_output_mode(state->fe[index_frontend], 3410 if (state->revision != 0x8090) {
2986 OUTMODE_HIGH_Z); 3411 dib8000_set_diversity_in(state->fe[index_frontend], 1);
2987 else 3412 if (index_frontend != 0)
2988 dib8096p_set_output_mode(state->fe[index_frontend], 3413 dib8000_set_output_mode(state->fe[index_frontend],
2989 OUTMODE_HIGH_Z); 3414 OUTMODE_DIVERSITY);
3415 else
3416 dib8000_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3417 } else {
3418 dib8096p_set_diversity_in(state->fe[index_frontend], 1);
3419 if (index_frontend != 0)
3420 dib8096p_set_output_mode(state->fe[index_frontend],
3421 OUTMODE_DIVERSITY);
3422 else
3423 dib8096p_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3424 }
3425
3426 /* tune the tuner */
2990 if (state->fe[index_frontend]->ops.tuner_ops.set_params) 3427 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2991 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]); 3428 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
2992 3429
2993 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START); 3430 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2994 } 3431 }
2995 3432
3433 /* turn off the diversity of the last chip */
3434 if (state->revision != 0x8090)
3435 dib8000_set_diversity_in(state->fe[index_frontend - 1], 0);
3436 else
3437 dib8096p_set_diversity_in(state->fe[index_frontend - 1], 0);
3438
2996 /* start up the AGC */ 3439 /* start up the AGC */
2997 do { 3440 do {
2998 time = dib8000_agc_startup(state->fe[0]); 3441 time = dib8000_agc_startup(state->fe[0]);
@@ -3019,139 +3462,88 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
3019 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 3462 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3020 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START); 3463 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3021 3464
3022 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) || 3465 active = 1;
3023 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) || 3466 do {
3024 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) || 3467 callback_time = FE_CALLBACK_TIME_NEVER;
3025 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
3026 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
3027 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
3028 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
3029 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
3030 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
3031 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
3032 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
3033 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
3034 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
3035 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
3036 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
3037 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
3038 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
3039 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
3040 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
3041 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
3042 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
3043 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
3044 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
3045 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
3046 int i = 100;
3047 u8 found = 0;
3048 u8 tune_failed = 0;
3049
3050 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 3468 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3051 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000); 3469 delay = dib8000_tune(state->fe[index_frontend]);
3052 dib8000_autosearch_start(state->fe[index_frontend]); 3470 if (delay != FE_CALLBACK_TIME_NEVER)
3053 } 3471 delay += systime();
3054 3472
3055 do { 3473 /* we are in autosearch */
3056 msleep(20); 3474 if (state->channel_parameters_set == 0) { /* searching */
3057 nbr_pending = 0; 3475 if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) {
3058 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ 3476 dprintk("autosearch succeeded on fe%i", index_frontend);
3059 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 3477 dib8000_get_frontend(state->fe[index_frontend]); /* we read the channel parameters from the frontend which was successful */
3060 if (((tune_failed >> index_frontend) & 0x1) == 0) { 3478 state->channel_parameters_set = 1;
3061 found = dib8000_autosearch_irq(state->fe[index_frontend]); 3479
3062 switch (found) { 3480 for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
3063 case 0: /* tune pending */ 3481 if (l != index_frontend) { /* and for all frontend except the successful one */
3064 nbr_pending++; 3482 dib8000_tune_restart_from_demod(state->fe[l]);
3065 break; 3483
3066 case 2: 3484 state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3067 dprintk("autosearch succeed on the frontend%i", index_frontend); 3485 state->fe[l]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3068 exit_condition = 2; 3486 state->fe[l]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3069 index_frontend_success = index_frontend; 3487 state->fe[l]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3070 break; 3488 state->fe[l]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3071 default: 3489 for (i = 0; i < 3; i++) {
3072 dprintk("unhandled autosearch result"); 3490 state->fe[l]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3073 case 1: 3491 state->fe[l]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3074 tune_failed |= (1 << index_frontend); 3492 state->fe[l]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3075 dprintk("autosearch failed for the frontend%i", index_frontend); 3493 state->fe[l]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3076 break; 3494 }
3495
3496 }
3077 } 3497 }
3078 } 3498 }
3079 } 3499 }
3080 3500 if (delay < callback_time)
3081 /* if all tune are done and no success, exit: tune failed */ 3501 callback_time = delay;
3082 if ((nbr_pending == 0) && (exit_condition == 0)) 3502 }
3083 exit_condition = 1; 3503 /* tuning is done when the master frontend is done (failed or success) */
3084 } while ((exit_condition == 0) && i--); 3504 if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
3085 3505 dib8000_get_status(state->fe[0]) == FE_STATUS_LOCKED ||
3086 if (exit_condition == 1) { /* tune failed */ 3506 dib8000_get_status(state->fe[0]) == FE_STATUS_DATA_LOCKED) {
3087 dprintk("tune failed"); 3507 active = 0;
3088 return 0; 3508 /* we need to wait for all frontends to be finished */
3509 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3510 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_DEMOD_STOP)
3511 active = 1;
3512 }
3513 if (active == 0)
3514 dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
3089 } 3515 }
3090 3516
3091 dprintk("tune success on frontend%i", index_frontend_success); 3517 if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
3092 3518 dprintk("strange callback time something went wrong");
3093 dib8000_get_frontend(fe); 3519 active = 0;
3094 } 3520 }
3095 3521
3096 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 3522 while ((active == 1) && (systime() < callback_time))
3097 ret = dib8000_tune(state->fe[index_frontend]); 3523 msleep(100);
3524 } while (active);
3098 3525
3099 /* set output mode and diversity input */ 3526 /* set output mode */
3100 if (state->revision != 0x8090) { 3527 if (state->revision != 0x8090)
3101 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); 3528 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3102 for (index_frontend = 1; 3529 else {
3103 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3104 (state->fe[index_frontend] != NULL);
3105 index_frontend++) {
3106 dib8000_set_output_mode(state->fe[index_frontend],
3107 OUTMODE_DIVERSITY);
3108 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
3109 }
3110
3111 /* turn off the diversity of the last chip */
3112 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
3113 } else {
3114 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode); 3530 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3115 if (state->cfg.enMpegOutput == 0) { 3531 if (state->cfg.enMpegOutput == 0) {
3116 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX); 3532 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3117 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); 3533 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3118 } 3534 }
3119 for (index_frontend = 1;
3120 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3121 (state->fe[index_frontend] != NULL);
3122 index_frontend++) {
3123 dib8096p_set_output_mode(state->fe[index_frontend],
3124 OUTMODE_DIVERSITY);
3125 dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
3126 }
3127
3128 /* turn off the diversity of the last chip */
3129 dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
3130 } 3535 }
3131 3536
3132 return ret; 3537 return ret;
3133} 3538}
3134 3539
3135static u16 dib8000_read_lock(struct dvb_frontend *fe)
3136{
3137 struct dib8000_state *state = fe->demodulator_priv;
3138
3139 if (state->revision == 0x8090)
3140 return dib8000_read_word(state, 570);
3141 return dib8000_read_word(state, 568);
3142}
3143
3144static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) 3540static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3145{ 3541{
3146 struct dib8000_state *state = fe->demodulator_priv; 3542 struct dib8000_state *state = fe->demodulator_priv;
3147 u16 lock_slave = 0, lock; 3543 u16 lock_slave = 0, lock;
3148 u8 index_frontend; 3544 u8 index_frontend;
3149 3545
3150 if (state->revision == 0x8090) 3546 lock = dib8000_read_lock(fe);
3151 lock = dib8000_read_word(state, 570);
3152 else
3153 lock = dib8000_read_word(state, 568);
3154
3155 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 3547 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3156 lock_slave |= dib8000_read_lock(state->fe[index_frontend]); 3548 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3157 3549
@@ -3545,10 +3937,11 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
3545 dib8000_reset(fe); 3937 dib8000_reset(fe);
3546 3938
3547 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */ 3939 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
3940 state->current_demod_bw = 6000;
3548 3941
3549 return fe; 3942 return fe;
3550 3943
3551 error: 3944error:
3552 kfree(state); 3945 kfree(state);
3553 return NULL; 3946 return NULL;
3554} 3947}
diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h
index 9e7a2b170d55..b8c11e52c512 100644
--- a/drivers/media/dvb-frontends/dib8000.h
+++ b/drivers/media/dvb-frontends/dib8000.h
@@ -33,6 +33,8 @@ struct dib8000_config {
33 u8 output_mode; 33 u8 output_mode;
34 u8 refclksel; 34 u8 refclksel;
35 u8 enMpegOutput:1; 35 u8 enMpegOutput:1;
36
37 struct dibx000_bandwidth_config *plltable;
36}; 38};
37 39
38#define DEFAULT_DIB8000_I2C_ADDRESS 18 40#define DEFAULT_DIB8000_I2C_ADDRESS 18
@@ -58,7 +60,7 @@ extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
58extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe, 60extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
59 uint8_t op, uint32_t timf); 61 uint8_t op, uint32_t timf);
60extern int dib8000_update_pll(struct dvb_frontend *fe, 62extern int dib8000_update_pll(struct dvb_frontend *fe,
61 struct dibx000_bandwidth_config *pll); 63 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
62extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); 64extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
63extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); 65extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
64extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); 66extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
@@ -147,7 +149,7 @@ static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
147 return 0; 149 return 0;
148} 150}
149static inline int dib8000_update_pll(struct dvb_frontend *fe, 151static inline int dib8000_update_pll(struct dvb_frontend *fe,
150 struct dibx000_bandwidth_config *pll) 152 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
151{ 153{
152 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 154 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
153 return -ENODEV; 155 return -ENODEV;
diff --git a/drivers/media/dvb-frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h
index 5f484881d7b1..b538e0555c95 100644
--- a/drivers/media/dvb-frontends/dibx000_common.h
+++ b/drivers/media/dvb-frontends/dibx000_common.h
@@ -193,7 +193,8 @@ enum frontend_tune_state {
193 CT_DEMOD_STEP_8, 193 CT_DEMOD_STEP_8,
194 CT_DEMOD_STEP_9, 194 CT_DEMOD_STEP_9,
195 CT_DEMOD_STEP_10, 195 CT_DEMOD_STEP_10,
196 CT_DEMOD_SEARCH_NEXT = 41, 196 CT_DEMOD_STEP_11,
197 CT_DEMOD_SEARCH_NEXT = 51,
197 CT_DEMOD_STEP_LOCKED, 198 CT_DEMOD_STEP_LOCKED,
198 CT_DEMOD_STOP, 199 CT_DEMOD_STOP,
199 200