Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Patrick Boettcher and committed by
Mauro Carvalho Chehab
173a64cb 1552fb34

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