^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) * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This code is more or less generated from another driver, please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * excuse some codingstyle oddities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "dib0090.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "dibx000_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define dprintk(fmt, arg...) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) printk(KERN_DEBUG pr_fmt("%s: " fmt), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) __func__, ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CONFIG_SYS_DVBT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CONFIG_SYS_ISDBT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CONFIG_DIB0090_USE_PWM_AGC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define EN_LNA0 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define EN_LNA1 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define EN_LNA2 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define EN_LNA3 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define EN_MIX0 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define EN_MIX1 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define EN_MIX2 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define EN_MIX3 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define EN_IQADC 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define EN_PLL 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define EN_TX 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define EN_BB 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define EN_LO 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define EN_BIAS 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define EN_IQANA 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define EN_CRYSTAL 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define EN_UHF 0x22E9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define EN_VHF 0x44E9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define EN_LBD 0x11E9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define EN_SBD 0x44E9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define EN_CAB 0x88E9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Calibration defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define DC_CAL 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define WBD_CAL 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define TEMP_CAL 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CAPTRIM_CAL 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define KROSUS_PLL_LOCKED 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define KROSUS 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Use those defines to identify SOC version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SOC 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SOC_7090_P1G_11R1 0x82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SOC_7090_P1G_21R1 0x8a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SOC_8090_P1G_11R1 0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SOC_8090_P1G_21R1 0x8e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* else use thos ones to check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define P1A_B 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define P1C 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define P1D_E_F 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define P1G 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define P1G_21R2 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MP001 0x1 /* Single 9090/8096 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MP005 0x4 /* Single Sband */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define MP008 0x6 /* Dual diversity VHF-UHF-LBAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define MP009 0x7 /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define pgm_read_word(w) (*w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct dc_calibration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct dib0090_tuning {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u8 switch_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u8 lna_tune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u16 lna_bias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u16 v2i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u16 mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u16 load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u16 tuner_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct dib0090_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 vco_band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u8 hfdiv_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 hfdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 topresc;
^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) struct dib0090_identity {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 p1g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 in_soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct dib0090_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const struct dib0090_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u8 current_band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) enum frontend_tune_state tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 current_rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 wbd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) s16 wbd_target; /* in dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) s16 current_gain; /* keeps the currently programmed gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u8 agc_step; /* new binary search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u16 gain[2]; /* for channel monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) const u16 *rf_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const u16 *bb_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* for the software AGC ramps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u16 bb_1_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u16 rf_lt_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u16 gain_reg[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* for the captrim/dc-offset search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) s8 step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) s16 adc_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) s16 min_adc_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) s8 captrim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) s8 fcaptrim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) const struct dc_calibration *dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u16 bb6, bb7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const struct dib0090_tuning *current_tune_table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) const struct dib0090_pll *current_pll_table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 tuner_is_tuned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 agc_freeze;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct dib0090_identity identity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 rf_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 current_standard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 calibrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u32 rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u16 bias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) s16 temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 wbd_calibration_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) const struct dib0090_wbd_slope *current_wbd_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u16 wbdmux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* for the I2C transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct i2c_msg msg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 i2c_write_buffer[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 i2c_read_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct mutex i2c_buffer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct dib0090_fw_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct dib0090_identity identity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) const struct dib0090_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* for the I2C transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 i2c_write_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u8 i2c_read_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct mutex i2c_buffer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u16 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) state->i2c_write_buffer[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) state->msg[0].addr = state->config->i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) state->msg[0].len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) state->msg[1].addr = state->config->i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) state->msg[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) state->msg[1].buf = state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) state->msg[1].len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pr_warn("DiB0090 I2C read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = (state->i2c_read_buffer[0] << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) | state->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) state->i2c_write_buffer[0] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) state->i2c_write_buffer[1] = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) state->i2c_write_buffer[2] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) memset(state->msg, 0, sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) state->msg[0].addr = state->config->i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) state->msg[0].len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pr_warn("DiB0090 I2C write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u16 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) state->i2c_write_buffer[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) memset(&state->msg, 0, sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) state->msg.addr = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) state->msg.flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) state->msg.buf = state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) state->msg.len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) pr_warn("DiB0090 I2C read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = (state->i2c_read_buffer[0] << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) | state->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) state->i2c_write_buffer[0] = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) state->i2c_write_buffer[1] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) memset(&state->msg, 0, sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) state->msg.addr = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) state->msg.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) state->msg.buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) state->msg.len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pr_warn("DiB0090 I2C write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^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) #define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #define ADC_TARGET -220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #define GAIN_ALPHA 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define WBD_ALPHA 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define LPF 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dib0090_write_reg(state, r++, *b++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) } while (--c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int dib0090_identify(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u16 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct dib0090_identity *identity = &state->identity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) v = dib0090_read_reg(state, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) identity->p1g = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) identity->in_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dprintk("Tuner identification (Version = 0x%04x)\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* without PLL lock info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) v &= ~KROSUS_PLL_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) identity->version = v & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) identity->product = (v >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (identity->product != KROSUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if ((identity->version & 0x3) == SOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) identity->in_soc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) switch (identity->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case SOC_8090_P1G_11R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dprintk("SOC 8090 P1-G11R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case SOC_8090_P1G_21R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dprintk("SOC 8090 P1-G21R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case SOC_7090_P1G_11R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dprintk("SOC 7090 P1-G11R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case SOC_7090_P1G_21R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dprintk("SOC 7090 P1-G21R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) switch ((identity->version >> 5) & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case MP001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dprintk("MP001 : 9090/8096\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case MP005:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dprintk("MP005 : Single Sband\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case MP008:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dprintk("MP008 : diversity VHF-UHF-LBAND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case MP009:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) switch (identity->version & 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) case P1G_21R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dprintk("P1G_21R2 detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case P1G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dprintk("P1G detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case P1D_E_F:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dprintk("P1D/E/F detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case P1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dprintk("P1C detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case P1A_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) dprintk("P1-A/B detected: driver is deactivated - not available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) goto identification_error;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) identification_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int dib0090_fw_identify(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct dib0090_fw_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct dib0090_identity *identity = &state->identity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u16 v = dib0090_fw_read_reg(state, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) identity->p1g = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) identity->in_soc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dprintk("FE: Tuner identification (Version = 0x%04x)\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* without PLL lock info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) v &= ~KROSUS_PLL_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) identity->version = v & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) identity->product = (v >> 8) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (identity->product != KROSUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if ((identity->version & 0x3) == SOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) identity->in_soc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) switch (identity->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case SOC_8090_P1G_11R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dprintk("SOC 8090 P1-G11R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case SOC_8090_P1G_21R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dprintk("SOC 8090 P1-G21R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case SOC_7090_P1G_11R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dprintk("SOC 7090 P1-G11R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case SOC_7090_P1G_21R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dprintk("SOC 7090 P1-G21R1 Has been detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) switch ((identity->version >> 5) & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case MP001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dprintk("MP001 : 9090/8096\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case MP005:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dprintk("MP005 : Single Sband\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case MP008:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dprintk("MP008 : diversity VHF-UHF-LBAND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case MP009:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) switch (identity->version & 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case P1G_21R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dprintk("P1G_21R2 detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case P1G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dprintk("P1G detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) identity->p1g = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case P1D_E_F:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) dprintk("P1D/E/F detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case P1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dprintk("P1C detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case P1A_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dprintk("P1-A/B detected: driver is deactivated - not available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto identification_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) identification_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) u16 PllCfg, i, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) HARD_RESET(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (cfg->in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* adcClkOutRatio=8->7, release reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (cfg->clkoutdrive != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* Read Pll current config * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) PllCfg = dib0090_read_reg(state, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /** Reconfigure PLL if current setting is different from default setting **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) && !cfg->io.pll_bypass) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* Set Bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) PllCfg |= (1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* Set Reset Pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) PllCfg &= ~(1 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /*** Set new Pll configuration in bypass and reset state ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Remove Reset Pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) PllCfg |= (1 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*** Wait for PLL lock ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) i = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) } while (--i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) dprintk("Pll: Unable to lock Pll\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Finally Remove Bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) PllCfg &= ~(1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (cfg->io.pll_bypass) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) PllCfg |= (cfg->io.pll_bypass << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dib0090_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct dib0090_fw_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) u16 PllCfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u16 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dprintk("fw reset digital\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) HARD_RESET(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) dib0090_fw_write_reg(state, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (cfg->clkoutdrive != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) v |= cfg->clkoutdrive << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) v |= 7 << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) v |= 2 << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dib0090_fw_write_reg(state, 0x23, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Read Pll current config * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) PllCfg = dib0090_fw_read_reg(state, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /** Reconfigure PLL if current setting is different from default setting **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Set Bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) PllCfg |= (1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Set Reset Pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) PllCfg &= ~(1 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /*** Set new Pll configuration in bypass and reset state ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Remove Reset Pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) PllCfg |= (1 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /*** Wait for PLL lock ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) i = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) } while (--i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dprintk("Pll: Unable to lock Pll\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Finally Remove Bypass mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) PllCfg &= ~(1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (cfg->io.pll_bypass) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) PllCfg |= (cfg->io.pll_bypass << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dib0090_fw_write_reg(state, 0x21, PllCfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return dib0090_fw_identify(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static int dib0090_wakeup(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (state->config->sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) state->config->sleep(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* enable dataTX in case we have been restarted in the wrong moment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static int dib0090_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (state->config->sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) state->config->sleep(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (fast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dib0090_write_reg(state, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dib0090_write_reg(state, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) EXPORT_SYMBOL(dib0090_dcc_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static const u16 bb_ramp_pwm_normal_socs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 550, /* max BB gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) (1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) (4 << 9) | 0, /* BB_RAMP3 = 26dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) (0 << 9) | 208, /* BB_RAMP4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) (4 << 9) | 208, /* BB_RAMP5 = 29dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (0 << 9) | 440, /* BB_RAMP6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static const u16 rf_ramp_pwm_cband_7090p[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 280, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 504, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) (29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) (0 << 10) | 504, /* RF_RAMP6, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) (60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) (0 << 10) | 364, /* RF_RAMP8, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) (34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) (0 << 10) | 228, /* GAIN_4_2, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) (37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) (0 << 10) | 109, /* RF_RAMP4, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 186, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 746, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) (10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) (0 << 10) | 746, /* RF_RAMP6, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) (0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) (0 << 10) | 0, /* RF_RAMP8, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) (28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) (0 << 10) | 345, /* GAIN_4_2, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) (20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) (0 << 10) | 200, /* RF_RAMP4, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 86, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 345, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) (0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) (0 << 10) | 0, /* RF_RAMP6, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) (0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) (0 << 10) | 0, /* RF_RAMP8, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) (28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) (0 << 10) | 345, /* GAIN_4_2, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) (20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) (0 << 10) | 200, /* RF_RAMP4, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static const u16 rf_ramp_pwm_cband_8090[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 345, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 1000, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) (35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) (0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) (58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) (0 << 10) | 772, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) (27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) (0 << 10) | 496, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) (40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) (0 << 10) | 200, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static const u16 rf_ramp_pwm_uhf_7090[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 407, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 529, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) (23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) (0 << 10) | 176, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) (63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) (0 << 10) | 529, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) (48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) (0 << 10) | 400, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) (29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) (0 << 10) | 316, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static const u16 rf_ramp_pwm_uhf_8090[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 388, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 1008, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) (11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) (0 << 10) | 369, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) (41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) (0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) (27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) (0 << 10) | 809, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) (14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) (0 << 10) | 659, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* GENERAL PWM ramp definition for all other Krosus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static const u16 bb_ramp_pwm_normal[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 500, /* max BB gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) (2 << 9) | 0, /* BB_RAMP3 = 21dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) (0 << 9) | 168, /* BB_RAMP4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) (2 << 9) | 168, /* BB_RAMP5 = 29dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) (0 << 9) | 400, /* BB_RAMP6 */
^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) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static const u16 bb_ramp_pwm_boost[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 550, /* max BB gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) (2 << 9) | 0, /* BB_RAMP3 = 26dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) (0 << 9) | 208, /* BB_RAMP4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) (2 << 9) | 208, /* BB_RAMP5 = 29dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) (0 << 9) | 440, /* BB_RAMP6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static const u16 rf_ramp_pwm_cband[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 314, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 1023, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) (8 << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) (0 << 10) | 1023, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) (15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) (0 << 10) | 742, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) (9 << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) (0 << 10) | 468, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) (9 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) (0 << 10) | 233, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static const u16 rf_ramp_pwm_vhf[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 398, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 954, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) (7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) (0 << 10) | 290, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) (0 << 10) | 954, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) (17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) (0 << 10) | 699, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) (7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) (0 << 10) | 580, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static const u16 rf_ramp_pwm_uhf[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 398, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 954, /* ramp_max = maximum X used on the ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) (7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) (0 << 10) | 290, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) (16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) (0 << 10) | 954, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) (17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) (0 << 10) | 699, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) (7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) (0 << 10) | 580, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static const u16 rf_ramp_pwm_sband[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 253, /* max RF gain in 10th of dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 961,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) (4 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) (0 << 10) | 508, /* RF_RAMP4, LNA 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) (9 << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) (0 << 10) | 961, /* RF_RAMP6, LNA 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) (0 << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) (0 << 10) | 0, /* RF_RAMP8, LNA 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) (0 << 10) | 0, /* GAIN_4_2, LNA 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct slope {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) s16 range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) s16 slope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) u16 rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u16 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (val > slopes[i].range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) rest = slopes[i].range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) rest = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) ret += (rest * slopes[i].slope) / slopes[i].range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) val -= rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static const struct slope dib0090_wbd_slopes[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {66, 120}, /* -64,-52: offset - 65 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {600, 170}, /* -52,-35: 65 - 665 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {170, 250}, /* -45,-10: 665 - 835 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) wbd &= 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (wbd < state->wbd_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) wbd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) wbd -= state->wbd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* -64dB is the floor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) u16 offset = 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (state->current_band == BAND_VHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) offset = 650;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) #ifndef FIRMWARE_FIREFLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (state->current_band == BAND_VHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) offset = state->config->wbd_vhf_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (state->current_band == BAND_CBAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) offset = state->config->wbd_cband_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static const int gain_reg_addr[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 0x08, 0x0a, 0x0f, 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) u16 rf, bb, ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) u16 i, v, gain_reg[4] = { 0 }, gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) const u16 *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (top_delta < -511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) top_delta = -511;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (top_delta > 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) top_delta = 511;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (force) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) top_delta *= (1 << WBD_ALPHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) gain_delta *= (1 << GAIN_ALPHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) state->rf_gain_limit += top_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (state->rf_gain_limit < 0) /*underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) state->rf_gain_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* use gain as a temporary variable and correct current_gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) state->current_gain = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) state->current_gain += gain_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (state->current_gain < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) state->current_gain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* now split total gain to rf and bb gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) gain = state->current_gain >> GAIN_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) rf = state->rf_gain_limit >> WBD_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) bb = gain - rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (bb > state->bb_ramp[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) bb = state->bb_ramp[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) } else { /* high signal level -> all gains put on RF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) rf = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) bb = 0;
^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) state->gain[0] = rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) state->gain[1] = bb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* software ramp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* Start with RF gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ref = rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (g[0] == 0 || ref < (g[1] - g[0])) /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) v = 0; /* force the gain to write for the current amp to be null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) v = g[2]; /* force this amp to be full gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) else /* compute the value to set to this amp because we are somewhere in his range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (i == 0) /* LNA 1 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) gain_reg[0] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) else if (i == 1) /* LNA 2 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) gain_reg[0] |= v << 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) else if (i == 2) /* LNA 3 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) gain_reg[1] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else if (i == 3) /* LNA 4 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) gain_reg[1] |= v << 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) else if (i == 4) /* CBAND LNA reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) gain_reg[2] = v | state->rf_lt_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) else if (i == 5) /* BB gain 1 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) gain_reg[3] = v << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) else if (i == 6) /* BB gain 2 reg mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) gain_reg[3] |= v << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) g += 3; /* go to next gain bloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* When RF is finished, start with BB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (i == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ref = bb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) gain_reg[3] |= state->bb_1_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) gain_reg[3] |= ((bb % 10) * 100) / 125;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) #ifdef DEBUG_AGC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* Write the amplifier regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) v = gain_reg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (force || state->gain_reg[i] != v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) state->gain_reg[i] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dib0090_write_reg(state, gain_reg_addr[i], v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static void dib0090_set_boost(struct dib0090_state *state, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) state->bb_1_def &= 0xdfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) state->bb_1_def |= onoff << 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) state->rf_ramp = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) state->rf_ramp = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dib0090_write_reg(state, 0x2a, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) dib0090_write_regs(state, 0x2c, cfg + 3, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) dib0090_write_regs(state, 0x3e, cfg + 9, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) state->bb_ramp = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) state->bb_ramp = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) dib0090_write_reg(state, 0x33, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) dib0090_write_regs(state, 0x35, cfg + 3, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) const u16 *bb_ramp = bb_ramp_pwm_normal; /* default baseband config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) const u16 *rf_ramp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) u8 en_pwm_rf_mux = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /* reset the AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (state->config->use_pwm_agc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (state->current_band == BAND_CBAND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) bb_ramp = bb_ramp_pwm_normal_socs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) rf_ramp = rf_ramp_pwm_cband_8090;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (state->config->is_dib7090e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (state->rf_ramp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) rf_ramp = state->rf_ramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) rf_ramp = rf_ramp_pwm_cband_7090p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) rf_ramp = rf_ramp_pwm_cband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (state->current_band == BAND_VHF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) bb_ramp = bb_ramp_pwm_normal_socs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) rf_ramp = rf_ramp_pwm_vhf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) } else if (state->current_band == BAND_UHF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) bb_ramp = bb_ramp_pwm_normal_socs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) rf_ramp = rf_ramp_pwm_uhf_8090;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) rf_ramp = rf_ramp_pwm_uhf_7090;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) rf_ramp = rf_ramp_pwm_uhf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (rf_ramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) dib0090_set_rframp_pwm(state, rf_ramp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dib0090_set_bbramp_pwm(state, bb_ramp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* activate the ramp generator using PWM control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (state->rf_ramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dprintk("ramp RF gain = %d BAND = %s version = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) state->rf_ramp[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) state->identity.version & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) (state->current_band == BAND_CBAND &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) (state->identity.version & 0x1f) <= P1D_E_F))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dprintk("DE-Engage mux for direct gain reg control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) en_pwm_rf_mux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dprintk("Engage mux for PWM control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) dib0090_write_reg(state, 0x04, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dib0090_write_reg(state, 0x04, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) EXPORT_SYMBOL(dib0090_pwm_gain_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (DC_servo_cutoff < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dib0090_write_reg(state, 0x04, DC_servo_cutoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) EXPORT_SYMBOL(dib0090_set_dc_servo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) u16 adc_val = dib0090_read_reg(state, 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) adc_val >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return adc_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) int dib0090_gain_control(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) enum frontend_tune_state *tune_state = &state->tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) int ret = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) u16 wbd_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) u8 apply_gain_immediatly = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) s16 wbd_error = 0, adc_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (*tune_state == CT_AGC_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) state->agc_freeze = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) dib0090_write_reg(state, 0x04, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (state->current_band == BAND_SBAND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) dib0090_set_rframp(state, rf_ramp_sband);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) dib0090_set_bbramp(state, bb_ramp_boost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) #ifdef CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (state->current_band == BAND_VHF && !state->identity.p1g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dib0090_set_rframp(state, rf_ramp_pwm_vhf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dib0090_set_bbramp(state, bb_ramp_pwm_normal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (state->current_band == BAND_CBAND && !state->identity.p1g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dib0090_set_rframp(state, rf_ramp_pwm_cband);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) dib0090_set_bbramp(state, bb_ramp_pwm_normal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) dib0090_set_rframp(state, rf_ramp_pwm_uhf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) dib0090_set_bbramp(state, bb_ramp_pwm_normal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dib0090_write_reg(state, 0x32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dib0090_write_reg(state, 0x39, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) dib0090_wbd_target(state, state->current_rf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) *tune_state = CT_AGC_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) } else if (!state->agc_freeze) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) s16 wbd = 0, i, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) int adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) wbd_val = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (*tune_state == CT_AGC_STEP_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) cnt = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) wbd_val = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) wbd += dib0090_wbd_to_db(state, wbd_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) wbd /= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) wbd_error = state->wbd_target - wbd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (*tune_state == CT_AGC_STEP_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (state->current_band == BAND_CBAND && ltg2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ltg2 >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) state->agc_step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) *tune_state = CT_AGC_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* calc the adc power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) adc = state->config->get_adc_power(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) adc_error = (s16) (((s32) ADC_TARGET) - adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) #ifdef CONFIG_STANDARD_DAB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) adc_error -= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) #ifdef CONFIG_STANDARD_DVBT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) adc_error += 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) #ifdef CONFIG_SYS_ISDBT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ((state->fe->dtv_property_cache.layer[0].modulation ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) QAM_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) || (state->fe->dtv_property_cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) layer[0].modulation == QAM_16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ((state->fe->dtv_property_cache.layer[1].segment_count >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) ((state->fe->dtv_property_cache.layer[1].modulation ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) QAM_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) || (state->fe->dtv_property_cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) layer[1].modulation == QAM_16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) ((state->fe->dtv_property_cache.layer[2].segment_count >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ((state->fe->dtv_property_cache.layer[2].modulation ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) QAM_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) || (state->fe->dtv_property_cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) layer[2].modulation == QAM_16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) adc_error += 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (abs(adc_error) < 50 || state->agc_step++ > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) #ifdef CONFIG_STANDARD_DAB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) dib0090_write_reg(state, 0x04, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) *tune_state = CT_AGC_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* everything higher than or equal to CT_AGC_STOP means tracking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ret = 100; /* 10ms interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) apply_gain_immediatly = 0;
^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) #ifdef DEBUG_AGC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dprintk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* apply gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (!state->agc_freeze)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) EXPORT_SYMBOL(dib0090_gain_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (rf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) *rf = state->gain[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (bb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) *bb = state->gain[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (rf_gain_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) *rf_gain_limit = state->rf_gain_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (rflt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) *rflt = (state->rf_lt_def >> 10) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) EXPORT_SYMBOL(dib0090_get_current_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) s32 current_temp = state->temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) s32 wbd_thot, wbd_tcold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) while (f_MHz > wbd->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) wbd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (current_temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) current_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (current_temp > 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) current_temp = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) state->wbdmux &= ~(7 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (wbd->wbd_gain != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) state->wbdmux |= (wbd->wbd_gain << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) state->wbdmux |= (4 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) dib0090_write_reg(state, 0x10, state->wbdmux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) dprintk("wbd offset applied is %d\n", wbd_tcold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) return state->wbd_offset + wbd_tcold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) EXPORT_SYMBOL(dib0090_get_wbd_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return state->wbd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) EXPORT_SYMBOL(dib0090_get_wbd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) EXPORT_SYMBOL(dib0090_set_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) | ((onoff & 1) << 15));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) EXPORT_SYMBOL(dib0090_set_vga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if ((!state->identity.p1g) || (!state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) || ((state->identity.version != SOC_7090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) && (state->identity.version != SOC_7090_P1G_11R1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) dprintk("%s() function can only be used for dib7090P\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (cfg_sensitivity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) state->rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) state->rf_ramp = rf_ramp_pwm_cband_7090e_aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) dib0090_pwm_gain_reset(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) EXPORT_SYMBOL(dib0090_update_rframp_7090);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static const u16 dib0090_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 25, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 0x99a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 0x6008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 0x8bcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 0x0405,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 0xb802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 0x0300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 0x2d12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 0xbac0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 0x7c00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 0xdbb9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 0x0954,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 0x0743,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 0x0001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 0x0040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 0xe910,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 0x149e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 1, 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 0xff2d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 1, 0x39,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 2, 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 0x07FF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 0x0007,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 1, 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) EN_UHF | EN_CRYSTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 2, 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 0x3ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 0x111,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static const u16 dib0090_p1g_additionnal_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 1, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 0xabcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 1, 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 0x00b4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 1, 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 0xfffd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 1, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 0x108,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) u16 l, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) l = pgm_read_word(n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) while (l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) r = pgm_read_word(n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) dib0090_write_reg(state, r, pgm_read_word(n++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) r++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) } while (--l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) l = pgm_read_word(n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) #define CAP_VALUE_MIN (u8) 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) #define CAP_VALUE_MAX (u8) 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) #define HR_MIN (u8) 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) #define HR_MAX (u8) 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) #define POLY_MIN (u8) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) #define POLY_MAX (u8) 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) static void dib0090_set_EFUSE(struct dib0090_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) u8 c, h, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) u16 e2, e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) u16 cal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) e2 = dib0090_read_reg(state, 0x26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) e4 = dib0090_read_reg(state, 0x28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if ((state->identity.version == P1D_E_F) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) (state->identity.version == P1G) || (e2 == 0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) dib0090_write_reg(state, 0x22, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if ((cal < 670) || (cal == 1023))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) cal = 850;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) n = 165 - ((cal * 10)>>6) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) e2 = e4 = (3<<12) | (34<<6) | (n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (e2 != e4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) e2 &= e4; /* Remove the redundancy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (e2 != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) c = e2 & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) n = (e2 >> 12) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) h = (e2 >> 6) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) c = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) c += 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if ((h >= HR_MAX) || (h <= HR_MIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) h = 34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if ((n >= POLY_MAX) || (n <= POLY_MIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) n = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) dib0090_write_reg(state, 0x13, (h << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) e2 = (n << 11) | ((h >> 2)<<6) | c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static int dib0090_reset(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) dib0090_reset_digital(fe, state->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (dib0090_identify(fe) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (!state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) dib0090_set_default_config(state, dib0090_defaults);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (state->identity.p1g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) dib0090_set_EFUSE(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) /* Congigure in function of the crystal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (state->config->force_crystal_mode != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) dib0090_write_reg(state, 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) state->config->force_crystal_mode & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) else if (state->config->io.clock_khz >= 24000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) dib0090_write_reg(state, 0x14, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) dib0090_write_reg(state, 0x14, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) #define steps(u) (((u) > 15) ? ((u)-16) : (u))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) #define INTERN_WAIT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) int ret = INTERN_WAIT * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) switch (*tune_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) case CT_TUNER_STEP_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* Turns to positive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) dib0090_write_reg(state, 0x1f, 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) *tune_state = CT_TUNER_STEP_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) case CT_TUNER_STEP_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) state->adc_diff = dib0090_read_reg(state, 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) /* Turns to negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) dib0090_write_reg(state, 0x1f, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) *tune_state = CT_TUNER_STEP_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) case CT_TUNER_STEP_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) state->adc_diff -= dib0090_read_reg(state, 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) *tune_state = CT_TUNER_STEP_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct dc_calibration {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) u8 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) u8 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) u8 pga:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) u16 bb1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) u8 i:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static const struct dc_calibration dc_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) static const struct dc_calibration dc_p1g_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) static void dib0090_set_trim(struct dib0090_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) u16 *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (state->dc->addr == 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) val = &state->bb7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) val = &state->bb6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) *val &= ~(0x1f << state->dc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) *val |= state->step << state->dc->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) dib0090_write_reg(state, state->dc->addr, *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) switch (*tune_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) case CT_TUNER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) dprintk("Start DC offset calibration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /* force vcm2 = 0.8V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) state->bb6 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) state->bb7 = 0x040d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /* the LNA AND LO are off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dib0090_write_reg(state, 0x24, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) state->wbdmux = dib0090_read_reg(state, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) state->dc = dc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (state->identity.p1g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) state->dc = dc_p1g_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) case CT_TUNER_STEP_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) dprintk("Start/continue DC calibration for %s path\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) (state->dc->i == 1) ? "I" : "Q");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) dib0090_write_reg(state, 0x01, state->dc->bb1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) state->step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) state->min_adc_diff = 1023;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) *tune_state = CT_TUNER_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) ret = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) case CT_TUNER_STEP_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) dib0090_set_trim(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) *tune_state = CT_TUNER_STEP_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) case CT_TUNER_STEP_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) case CT_TUNER_STEP_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) case CT_TUNER_STEP_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) ret = dib0090_get_offset(state, tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) case CT_TUNER_STEP_5: /* found an offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (state->step == 0 && state->adc_diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) state->min_adc_diff = -1023;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) dprintk("Change of sign of the minimum adc diff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* first turn for this frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (state->step == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (state->dc->pga && state->adc_diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) state->step = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (state->dc->pga == 0 && state->adc_diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) state->step = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) state->step++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) state->min_adc_diff = state->adc_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) *tune_state = CT_TUNER_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) /* the minimum was what we have seen in the step before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (abs(state->adc_diff) > abs(state->min_adc_diff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) state->step--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) dib0090_set_trim(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) dprintk("BB Offset Cal, BBreg=%u,Offset=%d,Value Set=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) state->dc->addr, state->adc_diff, state->step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) state->dc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (state->dc->addr == 0) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) *tune_state = CT_TUNER_STEP_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) case CT_TUNER_STEP_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) dib0090_write_reg(state, 0x1f, 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) state->calibrate &= ~DC_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) u8 wbd_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) switch (*tune_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) case CT_TUNER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) while (state->current_rf / 1000 > wbd->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) wbd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (wbd->wbd_gain != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) wbd_gain = wbd->wbd_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) wbd_gain = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) wbd_gain = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) *tune_state = CT_TUNER_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) state->calibrate &= ~WBD_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) state->wbd_calibration_gain = wbd_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) return 90; /* wait for the WBDMUX to switch and for the ADC to sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) case CT_TUNER_STEP_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) state->wbd_offset = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) dprintk("WBD calibration offset = %d\n", state->wbd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) state->calibrate &= ~WBD_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) static void dib0090_set_bandwidth(struct dib0090_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) tmp = (3 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) tmp = (2 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) tmp = (1 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) tmp = (0 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) state->bb_1_def &= 0x3fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) state->bb_1_def |= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static const struct dib0090_pll dib0090_pll_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) {56000, 0, 9, 48, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {70000, 1, 9, 48, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {87000, 0, 8, 32, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) {105000, 1, 8, 32, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {115000, 0, 7, 24, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) {140000, 1, 7, 24, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {170000, 0, 6, 16, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) #ifdef CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) {200000, 1, 6, 16, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) {230000, 0, 5, 12, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) {280000, 1, 5, 12, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) {340000, 0, 4, 8, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) {380000, 1, 4, 8, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) {450000, 0, 3, 6, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {580000, 1, 3, 6, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) {700000, 0, 2, 4, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {860000, 1, 2, 4, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {1800000, 1, 0, 2, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) {2900000, 0, 14, 1, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) static const struct dib0090_tuning dib0090_tuning_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) #ifdef CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) #ifdef CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) static const struct dib0090_pll dib0090_p1g_pll_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {57000, 0, 11, 48, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {70000, 1, 11, 48, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) {86000, 0, 10, 32, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) {105000, 1, 10, 32, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) {115000, 0, 9, 24, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {140000, 1, 9, 24, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) {170000, 0, 8, 16, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) #ifdef CONFIG_BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) {200000, 1, 8, 16, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) {230000, 0, 7, 12, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) {280000, 1, 7, 12, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) {340000, 0, 6, 8, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) {380000, 1, 6, 8, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {455000, 0, 5, 6, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) {580000, 1, 5, 6, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) {680000, 0, 4, 4, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) {860000, 1, 4, 4, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {1800000, 1, 2, 2, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) {2900000, 0, 1, 1, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) #ifdef CONFIG_BAND_UHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) #ifdef CONFIG_BAND_LBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) #ifdef CONFIG_BAND_SBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) #ifdef CONFIG_BAND_CBAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) u8 cfg_sensitivity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) const struct dib0090_tuning *tune =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) dib0090_tuning_table_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if ((!state->identity.p1g) || (!state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) || ((state->identity.version != SOC_7090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) && (state->identity.version != SOC_7090_P1G_11R1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) dprintk("%s() function can only be used for dib7090\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (cfg_sensitivity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) tune = dib0090_tuning_table_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) tune = dib0090_tuning_table_cband_7090e_aci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) while (state->rf_request > tune->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) tune++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) | (tune->lna_bias & 0x7fff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) | ((tune->lna_tune << 6) & 0x07c0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) u16 lo4 = 0xe900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) s16 adc_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) u16 adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) s8 step_sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) u8 force_soft_search = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) force_soft_search = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (*tune_state == CT_TUNER_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) dprintk("Start Captrim search : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) dib0090_write_reg(state, 0x10, 0x2B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) dib0090_write_reg(state, 0x1e, 0x0032);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) if (!state->tuner_is_tuned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) /* prepare a complete captrim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (!state->identity.p1g || force_soft_search)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) state->step = state->captrim = state->fcaptrim = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) state->current_rf = state->rf_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) } else { /* we are already tuned to this frequency - the configuration is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (!state->identity.p1g || force_soft_search) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /* do a minimal captrim even if the frequency has not changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) state->step = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) state->adc_diff = 3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) } else if (*tune_state == CT_TUNER_STEP_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) if (state->identity.p1g && !force_soft_search) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) u8 ratio = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) dib0090_read_reg(state, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) ret = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) state->step /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) dib0090_write_reg(state, 0x18, lo4 | state->captrim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) ret = 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) *tune_state = CT_TUNER_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) } else if (*tune_state == CT_TUNER_STEP_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (state->identity.p1g && !force_soft_search) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) dib0090_read_reg(state, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) *tune_state = CT_TUNER_STEP_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /* MERGE for all krosus before P1G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) adc = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) adc_target = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) adc_target = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (adc >= adc_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) adc -= adc_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) step_sign = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) adc = adc_target - adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) step_sign = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (adc < state->adc_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) state->adc_diff = adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) state->fcaptrim = state->captrim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) state->captrim += step_sign * state->step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) if (state->step >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) *tune_state = CT_TUNER_STEP_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) ret = 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /*write the final cptrim config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) *tune_state = CT_TUNER_STEP_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) } else if (*tune_state == CT_TUNER_STEP_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) state->calibrate &= ~CAPTRIM_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) int ret = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) s16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) switch (*tune_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) case CT_TUNER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) state->wbdmux = dib0090_read_reg(state, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) state->bias = dib0090_read_reg(state, 0x13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) *tune_state = CT_TUNER_STEP_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) /* wait for the WBDMUX to switch and for the ADC to sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) case CT_TUNER_STEP_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) state->adc_diff = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) *tune_state = CT_TUNER_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) case CT_TUNER_STEP_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) val = dib0090_get_slow_adc_val(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) dprintk("temperature: %d C\n", state->temperature - 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) *tune_state = CT_TUNER_STEP_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) case CT_TUNER_STEP_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) dib0090_write_reg(state, 0x13, state->bias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) *tune_state = CT_TUNER_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) state->calibrate &= ~TEMP_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) if (state->config->analog_output == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) static int dib0090_tune(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) const struct dib0090_tuning *tune = state->current_tune_table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) const struct dib0090_pll *pll = state->current_pll_table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) enum frontend_tune_state *tune_state = &state->tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) u16 lo5, lo6, Den, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) int ret = 10; /* 1ms is the default delay most of the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) u8 c, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /************************* VCO ***************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) /* Default values for FG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* from these are needed : */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /* in any case we first need to do a calibration if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (*tune_state == CT_TUNER_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /* deactivate DataTX before some calibrations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) /* Activate DataTX in case a calibration has been done before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (state->config->analog_output == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (state->calibrate & DC_CAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) return dib0090_dc_offset_calibration(state, tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) else if (state->calibrate & WBD_CAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (state->current_rf == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return dib0090_wbd_calibration(state, tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) } else if (state->calibrate & TEMP_CAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return dib0090_get_temperature(state, tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) else if (state->calibrate & CAPTRIM_CAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) return dib0090_captrim_search(state, tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (*tune_state == CT_TUNER_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if (state->config->use_pwm_agc && state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) tmp = dib0090_read_reg(state, 0x39);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if ((tmp >> 10) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) state->rf_request =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) freq_offset_khz_vhf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) /* in ISDB-T 1seg we shift tuning frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) u8 found_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) u32 margin_khz = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (LUT_offset != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) while (LUT_offset->RF_freq != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) state->rf_request += LUT_offset->offset_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) found_offset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) LUT_offset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (found_offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) state->rf_request += 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) state->tuner_is_tuned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) state->current_rf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) state->current_standard = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) tune = dib0090_tuning_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (state->identity.p1g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) tune = dib0090_p1g_tuning_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) tmp = (state->identity.version >> 5) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if (state->config->force_cband_input) { /* Use the CBAND input for all band */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) || state->current_band & BAND_UHF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) state->current_band = BAND_CBAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if (state->config->is_dib7090e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) tune = dib0090_tuning_table_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) tune = dib0090_tuning_table_cband_7090;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) } else { /* Use the CBAND input for all band under UHF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) state->current_band = BAND_CBAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if (state->config->is_dib7090e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) tune = dib0090_tuning_table_cband_7090e_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) tune = dib0090_tuning_table_cband_7090;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (tmp == 0x4 || tmp == 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) /* CBAND tuner version for VHF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) state->current_band = BAND_CBAND; /* Force CBAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) tune = dib0090_tuning_table_fm_vhf_on_cband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) if (state->identity.p1g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) pll = dib0090_pll_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) if (state->identity.p1g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) pll = dib0090_p1g_pll_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) /* Look for the interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) while (state->rf_request > tune->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) tune++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) while (state->rf_request > pll->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) pll++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) state->current_tune_table_index = tune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) state->current_pll_table_index = pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) FREF = state->config->io.clock_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (state->config->fref_clock_ratio != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) FREF /= state->config->fref_clock_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) FBDiv = (VCOF_kHz / pll->topresc / FREF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) if (Rest < LPF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) Rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) else if (Rest < 2 * LPF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) Rest = 2 * LPF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) else if (Rest > (FREF - LPF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) Rest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) FBDiv += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) } else if (Rest > (FREF - 2 * LPF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) Rest = FREF - 2 * LPF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) Rest = (Rest * 6528) / (FREF / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) state->rest = Rest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) /* external loop filter, otherwise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) * lo6 = 0x0e34 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) if (Rest == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) if (pll->vco_band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) lo5 = 0x049f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) lo5 = 0x041f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (pll->vco_band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) lo5 = 0x049e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) else if (state->config->analog_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) lo5 = 0x041d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) lo5 = 0x041c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) if (state->identity.p1g) { /* Bias is done automatically in P1G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) if (state->identity.in_soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (state->identity.version == SOC_8090_P1G_11R1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) lo5 = 0x46f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) lo5 = 0x42f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) lo5 = 0x42c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (!state->config->io.pll_int_loop_filt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (state->identity.in_soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) lo6 = 0xff98;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) else if (state->identity.p1g || (Rest == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) lo6 = 0xfff8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) lo6 = 0xff28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) lo6 = (state->config->io.pll_int_loop_filt << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) Den = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (Rest > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) lo6 |= (1 << 2) | 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) Den = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) dib0090_write_reg(state, 0x15, (u16) FBDiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) if (state->config->fref_clock_ratio != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) dib0090_write_reg(state, 0x16, (Den << 8) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) dib0090_write_reg(state, 0x17, (u16) Rest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) dib0090_write_reg(state, 0x19, lo5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) dib0090_write_reg(state, 0x1c, lo6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) lo6 = tune->tuner_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if (state->config->analog_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) lo6 = (lo6 & 0xff9f) | 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) state->current_rf = state->rf_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) state->current_standard = state->fe->dtv_property_cache.delivery_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) ret = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) state->calibrate = CAPTRIM_CAL; /* captrim search now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) while (state->current_rf / 1000 > wbd->max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) wbd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) dib0090_write_reg(state, 0x1e, 0x07ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) dprintk("VCO = %d\n", (u32) pll->vco_band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) (u32) dib0090_read_reg(state, 0x1c) & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) c = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) i = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) if (wbd->wbd_gain != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) c = wbd->wbd_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) dib0090_write_reg(state, 0x10, state->wbdmux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) dib0090_write_reg(state, 0x09, tune->lna_bias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) dib0090_write_reg(state, 0x0c, tune->v2i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) dib0090_write_reg(state, 0x0d, tune->mix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) dib0090_write_reg(state, 0x0e, tune->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) *tune_state = CT_TUNER_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) } else if (*tune_state == CT_TUNER_STEP_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) /* initialize the lt gain register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) state->rf_lt_def = 0x7c00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) dib0090_set_bandwidth(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) state->tuner_is_tuned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) state->calibrate |= WBD_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) state->calibrate |= TEMP_CAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) *tune_state = CT_TUNER_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) ret = FE_CALLBACK_TIME_NEVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) static void dib0090_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) kfree(fe->tuner_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) return state->tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) EXPORT_SYMBOL(dib0090_get_tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) state->tune_state = tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) EXPORT_SYMBOL(dib0090_set_tune_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) *frequency = 1000 * state->current_rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) static int dib0090_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) struct dib0090_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) state->tune_state = CT_TUNER_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) ret = dib0090_tune(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (ret == FE_CALLBACK_TIME_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * Despite dib0090_tune returns time at a 0.1 ms range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) * the actual sleep time depends on CONFIG_HZ. The worse case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) * is when CONFIG_HZ=100. In such case, the minimum granularity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) * is 10ms. On some real field tests, the tuner sometimes don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) * lock when this timer is lower than 10ms. So, enforce a 10ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) * granularity and use usleep_range() instead of msleep().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) ret = 10 * (ret + 99)/100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) usleep_range(ret * 1000, (ret + 1) * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) } while (state->tune_state != CT_TUNER_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) static const struct dvb_tuner_ops dib0090_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) .name = "DiBcom DiB0090",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) .frequency_min_hz = 45 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) .frequency_max_hz = 860 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) .frequency_step_hz = 1 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) .release = dib0090_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) .init = dib0090_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) .sleep = dib0090_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) .set_params = dib0090_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) .get_frequency = dib0090_get_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) static const struct dvb_tuner_ops dib0090_fw_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) .name = "DiBcom DiB0090",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) .frequency_min_hz = 45 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) .frequency_max_hz = 860 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) .frequency_step_hz = 1 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) .release = dib0090_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) .init = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) .sleep = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) .set_params = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) .get_frequency = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) {470, 0, 250, 0, 100, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) {860, 51, 866, 21, 375, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) {1700, 0, 800, 0, 850, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) {2900, 0, 250, 0, 100, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) {0xFFFF, 0, 0, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) if (st == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) st->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) st->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) st->fe = fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) mutex_init(&st->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) fe->tuner_priv = st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) if (config->wbd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) st->current_wbd_table = dib0090_wbd_table_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) st->current_wbd_table = config->wbd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) if (dib0090_reset(fe) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) goto free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) pr_info("DiB0090: successfully identified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) free_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) EXPORT_SYMBOL(dib0090_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) if (st == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) st->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) st->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) st->fe = fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) mutex_init(&st->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) fe->tuner_priv = st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) if (dib0090_fw_reset_digital(fe, st->config) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) goto free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) dprintk("DiB0090 FW: successfully identified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) free_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) EXPORT_SYMBOL(dib0090_fw_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) MODULE_LICENSE("GPL");