^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) STB0899 Multistandard Frontend driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Copyright (C) Manu Abraham (abraham.manu@gmail.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) Copyright (C) ST Microelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "stb0899_drv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "stb0899_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "stb0899_reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static inline u32 stb0899_do_div(u64 n, u32 d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* wrap do_div() for ease of use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) do_div(n, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* These functions are currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * stb0899_calc_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Compute symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* srate = (SFR * master_clk) >> 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* sfr is of size 20 bit, stored with an offset of 4 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) tmp &= ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) tmp *= master_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) tmp >>= 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * stb0899_get_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Get the current symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static u32 stb0899_get_srate(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 sfr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return stb0899_calc_srate(internal->master_clk, sfr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * stb0899_set_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Set symbol frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * MasterClock: master clock frequency (hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * SymbolRate: symbol rate (bauds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * return symbol frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u8 sfr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dprintk(state->verbose, FE_DEBUG, 1, "-->");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * in order to have the maximum precision, the symbol rate entered into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * the chip is computed as the closest value of the "true value".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * In this purpose, the symbol rate value is rounded (1 is added on the bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * below the LSB )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * srate = (SFR * master_clk) >> 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * <=>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * SFR = srate << 20 / master_clk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * rounded:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * SFR = (srate << 21 + master_clk) / (2 * master_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * stored as 20 bit number with an offset of 4 bit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * sfr = SFR << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) tmp <<= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) sfr[0] = tmp >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sfr[1] = tmp >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sfr[2] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return srate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * stb0899_calc_derot_time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Compute the amount of time needed by the derotator to lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * SymbolRate: Symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * return: derotator time constant (ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static long stb0899_calc_derot_time(long srate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (srate > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return (100000 / (srate / 1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * stb0899_carr_width
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Compute the width of the carrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * return: width of carrier (kHz or Mhz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) long stb0899_carr_width(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return (internal->srate + (internal->srate * internal->rolloff) / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * stb0899_first_subrange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Compute the first subrange of the search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void stb0899_first_subrange(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 bandwidth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (config->tuner_get_bandwidth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) stb0899_i2c_gate_ctrl(&state->frontend, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) config->tuner_get_bandwidth(&state->frontend, &bandwidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) stb0899_i2c_gate_ctrl(&state->frontend, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) range = bandwidth - stb0899_carr_width(state) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (range > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) internal->sub_range = min(internal->srch_range, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) internal->sub_range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) internal->freq = params->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) internal->tuner_offst = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) internal->sub_dir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * stb0899_check_tmg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * check for timing lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * internal.Ttiming: time to wait for loop lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) s8 timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) msleep(internal->t_derot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) stb0899_write_reg(state, STB0899_RTF, 0xf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) reg = stb0899_read_reg(state, STB0899_TLIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) timing = stb0899_read_reg(state, STB0899_RTF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (lock >= 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if ((lock > 48) && (abs(timing) >= 110)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) internal->status = ANALOGCARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) internal->status = TIMINGOK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) internal->status = NOTIMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * stb0899_search_tmg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * perform a fs/2 zig-zag to find timing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 cfr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) internal->status = NOTIMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* timing loop computation & symbol rate optimisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) derot_limit = (internal->sub_range / 2L) / internal->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) derot_step = (params->srate / 2L) / internal->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (abs(derot_freq) > derot_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) next_loop--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (next_loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) internal->direction = -internal->direction; /* Change zigzag direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (internal->status == TIMINGOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * stb0899_check_carrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Check for carrier found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) msleep(internal->t_derot); /* wait for derotator ok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) reg = stb0899_read_reg(state, STB0899_DSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) internal->status = CARRIEROK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) internal->status = NOCARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * stb0899_search_carrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Search for a QPSK carrier with the derotator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u8 cfr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) internal->status = NOCARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) derot_limit = (internal->sub_range / 2L) / internal->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) derot_freq = internal->derot_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (stb0899_check_carrier(state) == NOCARRIER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) last_derot_freq = derot_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if(abs(derot_freq) > derot_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) next_loop--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (next_loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) internal->direction = -internal->direction; /* Change zigzag direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) } while ((internal->status != CARRIEROK) && next_loop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (internal->status == CARRIEROK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) internal->derot_freq = last_derot_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * stb0899_check_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Check for data found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int lock = 0, index = 0, dataTime = 500, loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) internal->status = NODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* RESET FEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) STB0899_SETFIELD_VAL(FRESACS, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) STB0899_SETFIELD_VAL(FRESACS, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (params->srate <= 2000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dataTime = 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) else if (params->srate <= 5000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dataTime = 1500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else if (params->srate <= 15000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dataTime = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dataTime = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* clear previous failed END_LOOPVIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) stb0899_read_reg(state, STB0899_VSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) reg = stb0899_read_reg(state, STB0899_VSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (lock || loop || (index > dataTime))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (lock) { /* DATA LOCK indicator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) internal->status = DATAOK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * stb0899_search_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Search for a QPSK carrier with the derotator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) short int derot_freq, derot_step, derot_limit, next_loop = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u8 cfr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) derot_step = (params->srate / 4L) / internal->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) derot_limit = (internal->sub_range / 2L) / internal->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) derot_freq = internal->derot_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (abs(derot_freq) > derot_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) next_loop--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (next_loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) stb0899_check_carrier(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) internal->direction = -internal->direction; /* change zig zag direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) } while ((internal->status != DATAOK) && next_loop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (internal->status == DATAOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* store autodetected IQ swapping as default for DVB-S2 tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) reg = stb0899_read_reg(state, STB0899_IQSWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (STB0899_GETFIELD(SYM, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) internal->inversion = IQ_SWAP_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) internal->inversion = IQ_SWAP_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * stb0899_check_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * check if the found frequency is in the correct range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int range_offst, tp_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) range_offst = internal->srch_range / 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) tp_freq = internal->freq - (internal->derot_freq * internal->mclk) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) internal->status = RANGEOK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) internal->status = OUTOFRANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * NextSubRange
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Compute the next subrange of the search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static void next_sub_range(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) long old_sub_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (internal->sub_dir > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) old_sub_range = internal->sub_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) internal->sub_range = min((internal->srch_range / 2) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) (internal->tuner_offst + internal->sub_range / 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) internal->sub_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (internal->sub_range < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) internal->sub_range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) internal->sub_dir = -internal->sub_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * stb0899_dvbs_algo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Search for a signal, timing, carrier and data for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * given frequency in a given range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct stb0899_params *params = &state->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u8 bclc, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u8 cfr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) u8 eq_const[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) s32 clnI = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) u32 bandwidth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* BETA values rated @ 99MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) s32 betaTab[5][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* 5 10 20 30MBps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) { 37, 34, 32, 31 }, /* QPSK 1/2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) { 37, 35, 33, 31 }, /* QPSK 2/3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { 37, 35, 33, 31 }, /* QPSK 3/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { 37, 36, 33, 32 }, /* QPSK 5/6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { 37, 36, 33, 32 } /* QPSK 7/8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) internal->direction = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) stb0899_set_srate(state, internal->master_clk, params->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* Carrier loop optimization versus symbol rate for acquisition*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (params->srate <= 5000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) stb0899_write_reg(state, STB0899_ACLC, 0x89);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) bclc = stb0899_read_reg(state, STB0899_BCLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) stb0899_write_reg(state, STB0899_BCLC, bclc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) clnI = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) } else if (params->srate <= 15000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) stb0899_write_reg(state, STB0899_ACLC, 0xc9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) bclc = stb0899_read_reg(state, STB0899_BCLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) stb0899_write_reg(state, STB0899_BCLC, bclc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) clnI = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) } else if(params->srate <= 25000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) stb0899_write_reg(state, STB0899_ACLC, 0x89);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) bclc = stb0899_read_reg(state, STB0899_BCLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) stb0899_write_reg(state, STB0899_BCLC, bclc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) clnI = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) stb0899_write_reg(state, STB0899_ACLC, 0xc8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) bclc = stb0899_read_reg(state, STB0899_BCLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) stb0899_write_reg(state, STB0899_BCLC, bclc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) clnI = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* Set the timing loop to acquisition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) stb0899_write_reg(state, STB0899_RTC, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) stb0899_write_reg(state, STB0899_CFD, 0xee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* !! WARNING !!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * Do not read any status variables while acquisition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * If any needed, read before the acquisition starts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * querying status while acquiring causes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * acquisition to go bad and hence no locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) internal->derot_percent, params->srate, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Initial calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) internal->t_derot = stb0899_calc_derot_time(params->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) internal->t_data = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* RESET Stream merger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) STB0899_SETFIELD_VAL(FRESRS, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Set KDIVIDER to an intermediate value between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * 1/2 and 7/8 for acquisition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) stb0899_first_subrange(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Initialisations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cfr[0] = cfr[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) stb0899_write_reg(state, STB0899_RTF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) internal->derot_freq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) internal->status = NOAGC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* enable tuner I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) stb0899_i2c_gate_ctrl(&state->frontend, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* Move tuner to frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (state->config->tuner_set_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) state->config->tuner_set_frequency(&state->frontend, internal->freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (state->config->tuner_get_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) state->config->tuner_get_frequency(&state->frontend, &internal->freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) internal->status = AGC1OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* There is signal in the band */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (config->tuner_get_bandwidth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) config->tuner_get_bandwidth(&state->frontend, &bandwidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* disable tuner I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) stb0899_i2c_gate_ctrl(&state->frontend, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (params->srate <= bandwidth / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) stb0899_search_tmg(state); /* For low rates (SCPC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) stb0899_check_tmg(state); /* For high rates (MCPC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (internal->status == TIMINGOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) "TIMING OK ! Derot freq=%d, mclk=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) internal->derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "CARRIER OK ! Derot freq=%d, mclk=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) internal->derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (stb0899_search_data(state) == DATAOK) { /* Check for data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) "DATA OK ! Derot freq=%d, mclk=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) internal->derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (stb0899_check_range(state) == RANGEOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) "RANGE OK ! derot freq=%d, mclk=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) internal->derot_freq, internal->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) internal->freq = params->freq - ((internal->derot_freq * internal->mclk) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) reg = stb0899_read_reg(state, STB0899_PLPARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) "freq=%d, internal resultant freq=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) params->freq, internal->freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) dprintk(state->verbose, FE_DEBUG, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) "internal puncture rate=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) internal->fecrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (internal->status != RANGEOK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) next_sub_range(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) } while (internal->sub_range && internal->status != RANGEOK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Set the timing loop to tracking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) stb0899_write_reg(state, STB0899_RTC, 0x33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) stb0899_write_reg(state, STB0899_CFD, 0xf7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* if locked and range ok, set Kdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (internal->status == RANGEOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Carrier loop optimization versus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * symbol Rate/Puncture Rate for Tracking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) reg = stb0899_read_reg(state, STB0899_BCLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) switch (internal->fecrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case STB0899_FEC_1_2: /* 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) stb0899_write_reg(state, STB0899_BCLC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case STB0899_FEC_2_3: /* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) stb0899_write_reg(state, STB0899_BCLC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case STB0899_FEC_3_4: /* 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) stb0899_write_reg(state, STB0899_BCLC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case STB0899_FEC_5_6: /* 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) stb0899_write_reg(state, STB0899_BCLC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case STB0899_FEC_6_7: /* 25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) stb0899_write_reg(state, STB0899_ACLC, 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) stb0899_write_reg(state, STB0899_BCLC, 0x9a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case STB0899_FEC_7_8: /* 26 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) stb0899_write_reg(state, STB0899_BCLC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* release stream merger RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) STB0899_SETFIELD_VAL(FRESRS, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* disable carrier detector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) reg = stb0899_read_reg(state, STB0899_CFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) stb0899_write_reg(state, STB0899_CFD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * stb0899_dvbs2_config_uwp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Configure UWP state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) u32 uwp1, uwp2, uwp3, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * stb0899_dvbs2_config_csm_auto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * Set CSM to AUTO mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static long Log2Int(int number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) while ((1 << i) <= abs(number))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (number == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * stb0899_dvbs2_calc_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * compute BTR_NOM_FREQ for the symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) u32 master_clk, srate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dec_rate = Log2Int(dec_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) decim = 1 << dec_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) master_clk = internal->master_clk / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) srate = internal->srate / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (decim <= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return btr_nom_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * stb0899_dvbs2_calc_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * compute the correction to be applied to symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) u32 dec_ratio, correction, master_clk, srate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) master_clk = internal->master_clk / 1000; /* for integer Calculation*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) srate = internal->srate / 1000; /* for integer Calculation*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) correction = (512 * master_clk) / (2 * dec_ratio * srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return correction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * stb0899_dvbs2_set_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * Set DVBS2 symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) u32 correction, freq_adj, band_lim, decim_cntrl, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) u8 anti_alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /*set decimation to 1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dec_rate = Log2Int(dec_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) win_sel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (dec_rate >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) win_sel = dec_rate - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) decim = (1 << dec_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* (FSamp/Fsymbol *100) for integer Calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (f_sym <= 2250) /* don't band limit signal going into btr block*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) band_lim = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) band_lim = 0; /* band limit signal going into btr block*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (f_sym <= 3450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) anti_alias = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) else if (f_sym <= 4250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) anti_alias = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) anti_alias = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) btr_nom_freq = stb0899_dvbs2_calc_srate(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) correction = stb0899_dvbs2_calc_dev(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* scale UWP+CSM frequency to sample rate*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) freq_adj = internal->srate / (internal->master_clk / 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * stb0899_dvbs2_set_btr_loopbw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * set bit timing loop bandwidth as a percentage of the symbol rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) u32 decim, K, wn, k_direct, k_indirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) dec_rate = Log2Int(dec_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) decim = (1 << dec_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) sym_peak *= 576000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (K != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) K = sym_peak / K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) wn = (4 * zeta * zeta) + 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) k_indirect = (wn * wn) / K; /*kindirect = kindirect 10^-6*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) k_direct *= 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) k_btr1 = k_direct / (1 << k_direct_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) k_btr1 /= 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) k_btr0 = k_indirect * (1 << (-k_indirect_shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) k_btr0 /= 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) k_btr2_rshft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (k_btr0_rshft > 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) k_btr2_rshft = k_btr0_rshft - 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) k_btr0_rshft = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * stb0899_dvbs2_set_carr_freq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * set nominal frequency for carrier search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) s32 crl_nom_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) crl_nom_freq *= carr_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * stb0899_dvbs2_init_calc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * Initialize DVBS2 UWP, CSM, carrier and timing loops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) s32 steps, step_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) u32 range, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* config uwp and csm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) stb0899_dvbs2_config_uwp(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) stb0899_dvbs2_config_csm_auto(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* initialize BTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) stb0899_dvbs2_set_srate(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) stb0899_dvbs2_set_btr_loopbw(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (internal->srate / 1000000 >= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) step_size = (1 << 17) / 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) else if (internal->srate / 1000000 >= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) step_size = (1 << 17) / 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else if (internal->srate / 1000000 >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) step_size = (1 << 17) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) step_size = (1 << 17) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) range = internal->srch_range / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) steps = (steps + 6) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) steps = (steps == 0) ? 1 : steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (steps % 2 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) (internal->step_size * (internal->srate / 20000000)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) (internal->master_clk) / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /*Set Carrier Search params (zigzag, num steps and freq step size*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * stb0899_dvbs2_btr_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * initialize the timing loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* set enable BTR loopback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* fix btr freq accum at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* fix btr freq accum at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * stb0899_dvbs2_reacquire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * trigger a DVB-S2 acquisition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) u32 reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /* demod soft reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /*Reset Timing Loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) stb0899_dvbs2_btr_init(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* reset Carrier loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /*release demod soft reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* start acquisition process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* equalizer Init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /*Start equilizer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /* RESET Packet delineator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * stb0899_dvbs2_get_dmd_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * get DVB-S2 Demod LOCK status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) int time = -10, lock = 0, uwp, csm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) uwp = STB0899_GETFIELD(UWP_LOCK, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) csm = STB0899_GETFIELD(CSM_LOCK, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (uwp && csm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) lock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) time += 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) } while ((!lock) && (time <= timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (lock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return DVBS2_DEMOD_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return DVBS2_DEMOD_NOLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * stb0899_dvbs2_get_data_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * get FEC status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) int time = 0, lock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) while ((!lock) && (time < timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) time++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * stb0899_dvbs2_get_fec_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * get DVB-S2 FEC LOCK status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int time = 0, Locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) Locked = stb0899_dvbs2_get_data_lock(state, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) time++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) } while ((!Locked) && (time < timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (Locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return DVBS2_FEC_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return DVBS2_FEC_NOLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * stb0899_dvbs2_init_csm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * set parameters for manual mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) u32 csm1, csm2, csm3, csm4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) switch (modcod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) case STB0899_QPSK_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) gamma_acq = 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) gamma_rho_acq = 2700;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) gamma_trk = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) gamma_rho_trk = 180;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) case STB0899_QPSK_35:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) gamma_acq = 38;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) gamma_rho_acq = 7182;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) gamma_trk = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) gamma_rho_trk = 308;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) case STB0899_QPSK_23:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) gamma_acq = 42;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) gamma_rho_acq = 9408;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) gamma_trk = 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) gamma_rho_trk = 476;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) case STB0899_QPSK_34:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) gamma_acq = 53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) gamma_rho_acq = 16642;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) gamma_trk = 19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) gamma_rho_trk = 646;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) case STB0899_QPSK_45:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) gamma_acq = 53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) gamma_rho_acq = 17119;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) gamma_trk = 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) gamma_rho_trk = 880;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) case STB0899_QPSK_56:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) gamma_acq = 55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) gamma_rho_acq = 19250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) gamma_trk = 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) gamma_rho_trk = 989;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) case STB0899_QPSK_89:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) gamma_acq = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) gamma_rho_acq = 24240;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) gamma_trk = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) gamma_rho_trk = 1176;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) case STB0899_QPSK_910:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) gamma_acq = 66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) gamma_rho_acq = 29634;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) gamma_trk = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) gamma_rho_trk = 1176;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) gamma_acq = 66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) gamma_rho_acq = 29634;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) gamma_trk = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) gamma_rho_trk = 1176;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) lock_count_thr = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * stb0899_dvbs2_get_srate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * get DVB-S2 Symbol Rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) struct stb0899_config *config = state->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int div1, div2, rem1, rem2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) div1 = config->btr_nco_bits / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) div2 = config->btr_nco_bits - div1 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) decimRate = (1 << decimRate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) intval1 = internal->master_clk / (1 << div1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) intval2 = bTrNomFreq / (1 << div2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) rem1 = internal->master_clk % (1 << div1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) rem2 = bTrNomFreq % (1 << div2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* only for integer calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return srate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * stb0899_dvbs2_algo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * Search for signal, timing, carrier and data for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * frequency in a given range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct stb0899_internal *internal = &state->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) enum stb0899_modcod modcod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) u32 reg, csm1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (internal->srate <= 2000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) } else if (internal->srate <= 5000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) } else if (internal->srate <= 10000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } else if (internal->srate <= 15000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) } else if (internal->srate <= 20000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) } else if (internal->srate <= 25000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /* Maintain Stream Merger in reset during acquisition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) STB0899_SETFIELD_VAL(FRESRS, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) /* enable tuner I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) stb0899_i2c_gate_ctrl(&state->frontend, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* Move tuner to frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (state->config->tuner_set_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) state->config->tuner_set_frequency(&state->frontend, internal->freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (state->config->tuner_get_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) state->config->tuner_get_frequency(&state->frontend, &internal->freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /* disable tuner I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) stb0899_i2c_gate_ctrl(&state->frontend, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /* Set IF AGC to acquisition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) /* Initialisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) stb0899_dvbs2_init_calc(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) switch (internal->inversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) case IQ_SWAP_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) case IQ_SWAP_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) stb0899_dvbs2_reacquire(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* Wait for demod lock (UWP and CSM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (internal->status == DVBS2_DEMOD_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /* Demod Locked, check FEC status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) /* Read the frequency offset*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) stb0899_dvbs2_reacquire(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (internal->status != DVBS2_FEC_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* IQ Spectrum Inversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* start acquistion process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) stb0899_dvbs2_reacquire(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /* Wait for demod lock (UWP and CSM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (internal->status == DVBS2_DEMOD_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* Demod Locked, check FEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /* Read the frequency offset*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) stb0899_dvbs2_reacquire(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pParams->IQLocked = !iqSpectrum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (internal->status == DVBS2_FEC_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) (pilots == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) stb0899_dvbs2_init_csm(state, pilots, modcod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* Wait for UWP,CSM and data LOCK 20ms max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) (pilots == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /* Equalizer Disable update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /* slow down the Equalizer once locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /* Store signal parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) offsetfreq = sign_extend32(offsetfreq, 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) offsetfreq = offsetfreq / ((1 << 30) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) offsetfreq *= (internal->master_clk / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* store current inversion for next run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) internal->inversion = IQ_SWAP_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) internal->inversion = IQ_SWAP_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) internal->freq = internal->freq + offsetfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) internal->srate = stb0899_dvbs2_get_srate(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* Set IF AGC to tracking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /* Release Stream Merger Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) reg = stb0899_read_reg(state, STB0899_TSTRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) STB0899_SETFIELD_VAL(FRESRS, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) stb0899_write_reg(state, STB0899_TSTRES, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return internal->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }