Lines Matching refs:state

200 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
204 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
209 state->i2c_write_buffer[0] = reg;
211 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
212 state->msg[0].addr = state->config->i2c_address;
213 state->msg[0].flags = 0;
214 state->msg[0].buf = state->i2c_write_buffer;
215 state->msg[0].len = 1;
216 state->msg[1].addr = state->config->i2c_address;
217 state->msg[1].flags = I2C_M_RD;
218 state->msg[1].buf = state->i2c_read_buffer;
219 state->msg[1].len = 2;
221 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
225 ret = (state->i2c_read_buffer[0] << 8)
226 | state->i2c_read_buffer[1];
228 mutex_unlock(&state->i2c_buffer_lock);
232 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
236 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
241 state->i2c_write_buffer[0] = reg & 0xff;
242 state->i2c_write_buffer[1] = val >> 8;
243 state->i2c_write_buffer[2] = val & 0xff;
245 memset(state->msg, 0, sizeof(struct i2c_msg));
246 state->msg[0].addr = state->config->i2c_address;
247 state->msg[0].flags = 0;
248 state->msg[0].buf = state->i2c_write_buffer;
249 state->msg[0].len = 3;
251 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
257 mutex_unlock(&state->i2c_buffer_lock);
261 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
265 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
270 state->i2c_write_buffer[0] = reg;
272 memset(&state->msg, 0, sizeof(struct i2c_msg));
273 state->msg.addr = reg;
274 state->msg.flags = I2C_M_RD;
275 state->msg.buf = state->i2c_read_buffer;
276 state->msg.len = 2;
277 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
281 ret = (state->i2c_read_buffer[0] << 8)
282 | state->i2c_read_buffer[1];
284 mutex_unlock(&state->i2c_buffer_lock);
288 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
292 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
297 state->i2c_write_buffer[0] = val >> 8;
298 state->i2c_write_buffer[1] = val & 0xff;
300 memset(&state->msg, 0, sizeof(struct i2c_msg));
301 state->msg.addr = reg;
302 state->msg.flags = 0;
303 state->msg.buf = state->i2c_write_buffer;
304 state->msg.len = 2;
305 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
311 mutex_unlock(&state->i2c_buffer_lock);
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)
320 static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
323 dib0090_write_reg(state, r++, *b++);
329 struct dib0090_state *state = fe->tuner_priv;
331 struct dib0090_identity *identity = &state->identity;
333 v = dib0090_read_reg(state, 0x1a);
421 struct dib0090_fw_state *state = fe->tuner_priv;
422 struct dib0090_identity *identity = &state->identity;
424 u16 v = dib0090_fw_read_reg(state, 0x1a);
511 struct dib0090_state *state = fe->tuner_priv;
514 HARD_RESET(state);
515 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
519 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
521 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
523 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
526 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
530 PllCfg = dib0090_read_reg(state, 0x21);
538 dib0090_write_reg(state, 0x21, PllCfg);
542 dib0090_write_reg(state, 0x21, PllCfg);
544 /*** Set new Pll configuration in bypass and reset state ***/
546 dib0090_write_reg(state, 0x21, PllCfg);
550 dib0090_write_reg(state, 0x21, PllCfg);
555 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
567 dib0090_write_reg(state, 0x21, PllCfg);
572 dib0090_write_reg(state, 0x21, PllCfg);
578 struct dib0090_fw_state *state = fe->tuner_priv;
584 HARD_RESET(state);
586 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
587 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
589 dib0090_fw_write_reg(state, 0x20,
599 dib0090_fw_write_reg(state, 0x23, v);
602 PllCfg = dib0090_fw_read_reg(state, 0x21);
609 dib0090_fw_write_reg(state, 0x21, PllCfg);
613 dib0090_fw_write_reg(state, 0x21, PllCfg);
615 /*** Set new Pll configuration in bypass and reset state ***/
617 dib0090_fw_write_reg(state, 0x21, PllCfg);
621 dib0090_fw_write_reg(state, 0x21, PllCfg);
626 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
638 dib0090_fw_write_reg(state, 0x21, PllCfg);
643 dib0090_fw_write_reg(state, 0x21, PllCfg);
651 struct dib0090_state *state = fe->tuner_priv;
652 if (state->config->sleep)
653 state->config->sleep(fe, 0);
656 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
662 struct dib0090_state *state = fe->tuner_priv;
663 if (state->config->sleep)
664 state->config->sleep(fe, 1);
670 struct dib0090_state *state = fe->tuner_priv;
672 dib0090_write_reg(state, 0x04, 0);
674 dib0090_write_reg(state, 0x04, 1);
882 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
885 if (wbd < state->wbd_offset)
888 wbd -= state->wbd_offset;
893 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
899 if (state->current_band == BAND_VHF)
902 if (state->current_band == BAND_VHF)
903 offset = state->config->wbd_vhf_offset;
904 if (state->current_band == BAND_CBAND)
905 offset = state->config->wbd_cband_offset;
908 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
909 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
916 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
932 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */
933 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
935 state->rf_gain_limit += top_delta;
937 if (state->rf_gain_limit < 0) /*underflow */
938 state->rf_gain_limit = 0;
941 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
942 if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */
943 state->current_gain = gain;
945 state->current_gain += gain_delta;
947 if (state->current_gain < 0)
948 state->current_gain = 0;
951 gain = state->current_gain >> GAIN_ALPHA;
954 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
955 rf = state->rf_gain_limit >> WBD_ALPHA;
957 if (bb > state->bb_ramp[0])
958 bb = state->bb_ramp[0];
964 state->gain[0] = rf;
965 state->gain[1] = bb;
969 g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
988 gain_reg[2] = v | state->rf_lt_def;
998 g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
1002 gain_reg[3] |= state->bb_1_def;
1013 if (force || state->gain_reg[i] != v) {
1014 state->gain_reg[i] = v;
1015 dib0090_write_reg(state, gain_reg_addr[i], v);
1020 static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1022 state->bb_1_def &= 0xdfff;
1023 state->bb_1_def |= onoff << 13;
1026 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1028 state->rf_ramp = cfg;
1031 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1033 state->rf_ramp = cfg;
1035 dib0090_write_reg(state, 0x2a, 0xffff);
1037 dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1039 dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1040 dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1043 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1045 state->bb_ramp = cfg;
1046 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1049 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1051 state->bb_ramp = cfg;
1053 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1055 dib0090_write_reg(state, 0x33, 0xffff);
1056 dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1057 dib0090_write_regs(state, 0x35, cfg + 3, 4);
1062 struct dib0090_state *state = fe->tuner_priv;
1068 if (state->config->use_pwm_agc) {
1069 if (state->current_band == BAND_CBAND) {
1070 if (state->identity.in_soc) {
1072 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1074 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
1075 if (state->config->is_dib7090e) {
1076 if (state->rf_ramp == NULL)
1079 rf_ramp = state->rf_ramp;
1087 if (state->current_band == BAND_VHF) {
1088 if (state->identity.in_soc) {
1093 } else if (state->current_band == BAND_UHF) {
1094 if (state->identity.in_soc) {
1096 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1098 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1104 dib0090_set_rframp_pwm(state, rf_ramp);
1105 dib0090_set_bbramp_pwm(state, bb_ramp);
1108 if (state->rf_ramp)
1110 state->rf_ramp[0],
1111 (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
1112 state->identity.version & 0x1f);
1114 if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) ||
1115 (state->current_band == BAND_CBAND &&
1116 (state->identity.version & 0x1f) <= P1D_E_F))) {
1122 dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
1125 if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1126 dib0090_write_reg(state, 0x04, 3);
1128 dib0090_write_reg(state, 0x04, 1);
1129 dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
1136 struct dib0090_state *state = fe->tuner_priv;
1138 dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1142 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1144 u16 adc_val = dib0090_read_reg(state, 0x1d);
1145 if (state->identity.in_soc)
1152 struct dib0090_state *state = fe->tuner_priv;
1153 enum frontend_tune_state *tune_state = &state->tune_state;
1161 state->agc_freeze = 0;
1162 dib0090_write_reg(state, 0x04, 0x0);
1165 if (state->current_band == BAND_SBAND) {
1166 dib0090_set_rframp(state, rf_ramp_sband);
1167 dib0090_set_bbramp(state, bb_ramp_boost);
1171 if (state->current_band == BAND_VHF && !state->identity.p1g) {
1172 dib0090_set_rframp(state, rf_ramp_pwm_vhf);
1173 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1177 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1178 dib0090_set_rframp(state, rf_ramp_pwm_cband);
1179 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1182 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1183 dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
1184 dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
1186 dib0090_set_rframp(state, rf_ramp_pwm_uhf);
1187 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1190 dib0090_write_reg(state, 0x32, 0);
1191 dib0090_write_reg(state, 0x39, 0);
1193 dib0090_wbd_target(state, state->current_rf);
1195 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1196 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1199 } else if (!state->agc_freeze) {
1203 wbd_val = dib0090_get_slow_adc_val(state);
1211 wbd_val = dib0090_get_slow_adc_val(state);
1212 wbd += dib0090_wbd_to_db(state, wbd_val);
1215 wbd_error = state->wbd_target - wbd;
1218 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1221 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1222 if (state->current_band == BAND_CBAND && ltg2) {
1224 state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
1228 state->agc_step = 0;
1233 adc = state->config->get_adc_power(fe);
1238 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1242 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1243 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1247 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1250 ((state->fe->dtv_property_cache.layer[0].modulation ==
1252 || (state->fe->dtv_property_cache.
1255 ((state->fe->dtv_property_cache.layer[1].segment_count >
1258 ((state->fe->dtv_property_cache.layer[1].modulation ==
1260 || (state->fe->dtv_property_cache.
1263 ((state->fe->dtv_property_cache.layer[2].segment_count >
1266 ((state->fe->dtv_property_cache.layer[2].modulation ==
1268 || (state->fe->dtv_property_cache.
1276 if (abs(adc_error) < 50 || state->agc_step++ > 5) {
1279 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1280 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1281 dib0090_write_reg(state, 0x04, 0x0);
1285 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1286 dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1299 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1301 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1306 if (!state->agc_freeze)
1307 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1315 struct dib0090_state *state = fe->tuner_priv;
1317 *rf = state->gain[0];
1319 *bb = state->gain[1];
1321 *rf_gain_limit = state->rf_gain_limit;
1323 *rflt = (state->rf_lt_def >> 10) & 0x7;
1330 struct dib0090_state *state = fe->tuner_priv;
1331 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1332 s32 current_temp = state->temperature;
1334 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1346 state->wbdmux &= ~(7 << 13);
1348 state->wbdmux |= (wbd->wbd_gain << 13);
1350 state->wbdmux |= (4 << 13);
1352 dib0090_write_reg(state, 0x10, state->wbdmux);
1359 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1360 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
1363 return state->wbd_offset + wbd_tcold;
1369 struct dib0090_state *state = fe->tuner_priv;
1370 return state->wbd_offset;
1376 struct dib0090_state *state = fe->tuner_priv;
1378 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1387 struct dib0090_state *state = fe->tuner_priv;
1389 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1397 struct dib0090_state *state = fe->tuner_priv;
1399 if ((!state->identity.p1g) || (!state->identity.in_soc)
1400 || ((state->identity.version != SOC_7090_P1G_21R1)
1401 && (state->identity.version != SOC_7090_P1G_11R1))) {
1407 state->rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
1409 state->rf_ramp = rf_ramp_pwm_cband_7090e_aci;
1479 static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1487 dib0090_write_reg(state, r, pgm_read_word(n++));
1501 static void dib0090_set_EFUSE(struct dib0090_state *state)
1507 e2 = dib0090_read_reg(state, 0x26);
1508 e4 = dib0090_read_reg(state, 0x28);
1510 if ((state->identity.version == P1D_E_F) ||
1511 (state->identity.version == P1G) || (e2 == 0xffff)) {
1513 dib0090_write_reg(state, 0x22, 0x10);
1514 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1539 dib0090_write_reg(state, 0x13, (h << 10));
1541 dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
1547 struct dib0090_state *state = fe->tuner_priv;
1549 dib0090_reset_digital(fe, state->config);
1554 if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */
1558 if (!state->identity.in_soc) {
1559 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1560 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1562 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1565 dib0090_set_default_config(state, dib0090_defaults);
1567 if (state->identity.in_soc)
1568 dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */
1570 if (state->identity.p1g)
1571 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1574 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1575 dib0090_set_EFUSE(state);
1578 if (state->config->force_crystal_mode != 0)
1579 dib0090_write_reg(state, 0x14,
1580 state->config->force_crystal_mode & 3);
1581 else if (state->config->io.clock_khz >= 24000)
1582 dib0090_write_reg(state, 0x14, 1);
1584 dib0090_write_reg(state, 0x14, 2);
1585 dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1587 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
1594 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1601 dib0090_write_reg(state, 0x1f, 0x7);
1606 state->adc_diff = dib0090_read_reg(state, 0x1d);
1609 dib0090_write_reg(state, 0x1f, 0x4);
1614 state->adc_diff -= dib0090_read_reg(state, 0x1d);
1655 static void dib0090_set_trim(struct dib0090_state *state)
1659 if (state->dc->addr == 0x07)
1660 val = &state->bb7;
1662 val = &state->bb6;
1664 *val &= ~(0x1f << state->dc->offset);
1665 *val |= state->step << state->dc->offset;
1667 dib0090_write_reg(state, state->dc->addr, *val);
1670 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1680 state->bb6 = 0;
1681 state->bb7 = 0x040d;
1684 reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */
1685 dib0090_write_reg(state, 0x24, reg);
1687 state->wbdmux = dib0090_read_reg(state, 0x10);
1688 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1689 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1691 state->dc = dc_table;
1693 if (state->identity.p1g)
1694 state->dc = dc_p1g_table;
1699 (state->dc->i == 1) ? "I" : "Q");
1700 dib0090_write_reg(state, 0x01, state->dc->bb1);
1701 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1703 state->step = 0;
1704 state->min_adc_diff = 1023;
1710 dib0090_set_trim(state);
1717 ret = dib0090_get_offset(state, tune_state);
1721 dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step);
1722 if (state->step == 0 && state->adc_diff < 0) {
1723 state->min_adc_diff = -1023;
1727 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step);
1730 if (state->step == 0) {
1731 if (state->dc->pga && state->adc_diff < 0)
1732 state->step = 0x10;
1733 if (state->dc->pga == 0 && state->adc_diff > 0)
1734 state->step = 0x10;
1738 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1740 state->step++;
1741 state->min_adc_diff = state->adc_diff;
1745 if (abs(state->adc_diff) > abs(state->min_adc_diff)) {
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);
1747 state->step--;
1750 dib0090_set_trim(state);
1752 state->dc->addr, state->adc_diff, state->step);
1754 state->dc++;
1755 if (state->dc->addr == 0) /* done */
1764 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1765 dib0090_write_reg(state, 0x1f, 0x7);
1767 state->calibrate &= ~DC_CAL;
1776 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1779 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1783 while (state->current_rf / 1000 > wbd->max_freq)
1790 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1795 if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */
1797 state->calibrate &= ~WBD_CAL;
1801 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1803 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1805 state->wbd_calibration_gain = wbd_gain;
1809 state->wbd_offset = dib0090_get_slow_adc_val(state);
1810 dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1812 state->calibrate &= ~WBD_CAL;
1821 static void dib0090_set_bandwidth(struct dib0090_state *state)
1825 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1827 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1829 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1834 state->bb_1_def &= 0x3fff;
1835 state->bb_1_def |= tmp;
1837 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
1839 dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1840 dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1841 if (state->identity.in_soc) {
1842 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 */
1844 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */
1845 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 */
2043 struct dib0090_state *state = fe->tuner_priv;
2052 if ((!state->identity.p1g) || (!state->identity.in_soc)
2053 || ((state->identity.version != SOC_7090_P1G_21R1)
2054 && (state->identity.version != SOC_7090_P1G_11R1))) {
2064 while (state->rf_request > tune->max_freq)
2067 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2069 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2075 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2085 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2091 dib0090_write_reg(state, 0x10, 0x2B1);
2092 dib0090_write_reg(state, 0x1e, 0x0032);
2094 if (!state->tuner_is_tuned) {
2096 if (!state->identity.p1g || force_soft_search)
2097 state->step = state->captrim = state->fcaptrim = 64;
2099 state->current_rf = state->rf_request;
2101 if (!state->identity.p1g || force_soft_search) {
2103 state->step = 4;
2104 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2107 state->adc_diff = 3000;
2111 if (state->identity.p1g && !force_soft_search) {
2114 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2115 dib0090_read_reg(state, 0x40);
2118 state->step /= 2;
2119 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2121 if (state->identity.in_soc)
2127 if (state->identity.p1g && !force_soft_search) {
2128 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2129 dib0090_read_reg(state, 0x40);
2131 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2132 dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2137 adc = dib0090_get_slow_adc_val(state);
2138 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2140 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 !!! */
2153 if (adc < state->adc_diff) {
2154 dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2155 state->adc_diff = adc;
2156 state->fcaptrim = state->captrim;
2159 state->captrim += step_sign * state->step;
2160 if (state->step >= 1)
2169 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2174 state->calibrate &= ~CAPTRIM_CAL;
2181 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2188 state->wbdmux = dib0090_read_reg(state, 0x10);
2189 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2191 state->bias = dib0090_read_reg(state, 0x13);
2192 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2199 state->adc_diff = dib0090_get_slow_adc_val(state);
2200 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2205 val = dib0090_get_slow_adc_val(state);
2206 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2208 dprintk("temperature: %d C\n", state->temperature - 30);
2214 dib0090_write_reg(state, 0x13, state->bias);
2215 dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */
2218 state->calibrate &= ~TEMP_CAL;
2219 if (state->config->analog_output == 0)
2220 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2234 struct dib0090_state *state = fe->tuner_priv;
2235 const struct dib0090_tuning *tune = state->current_tune_table_index;
2236 const struct dib0090_pll *pll = state->current_pll_table_index;
2237 enum frontend_tune_state *tune_state = &state->tune_state;
2252 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2253 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2256 if (state->config->analog_output == 0)
2257 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2260 if (state->calibrate & DC_CAL)
2261 return dib0090_dc_offset_calibration(state, tune_state);
2262 else if (state->calibrate & WBD_CAL) {
2263 if (state->current_rf == 0)
2264 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2265 return dib0090_wbd_calibration(state, tune_state);
2266 } else if (state->calibrate & TEMP_CAL)
2267 return dib0090_get_temperature(state, tune_state);
2268 else if (state->calibrate & CAPTRIM_CAL)
2269 return dib0090_captrim_search(state, tune_state);
2273 if (state->config->use_pwm_agc && state->identity.in_soc) {
2274 tmp = dib0090_read_reg(state, 0x39);
2276 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2279 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2280 state->rf_request =
2281 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2282 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2286 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2287 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2288 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2294 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2295 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2296 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2297 state->rf_request += LUT_offset->offset_khz;
2306 state->rf_request += 400;
2308 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2309 state->tuner_is_tuned = 0;
2310 state->current_rf = 0;
2311 state->current_standard = 0;
2314 if (state->identity.p1g)
2317 tmp = (state->identity.version >> 5) & 0x7;
2319 if (state->identity.in_soc) {
2320 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2321 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2322 || state->current_band & BAND_UHF) {
2323 state->current_band = BAND_CBAND;
2324 if (state->config->is_dib7090e)
2330 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2331 state->current_band = BAND_CBAND;
2332 if (state->config->is_dib7090e)
2341 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2342 state->current_band = BAND_CBAND; /* Force CBAND */
2345 if (state->identity.p1g)
2351 if (state->identity.p1g)
2355 while (state->rf_request > tune->max_freq)
2357 while (state->rf_request > pll->max_freq)
2360 state->current_tune_table_index = tune;
2361 state->current_pll_table_index = pll;
2363 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2365 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2367 FREF = state->config->io.clock_khz;
2368 if (state->config->fref_clock_ratio != 0)
2369 FREF /= state->config->fref_clock_ratio;
2384 state->rest = Rest;
2398 else if (state->config->analog_output)
2404 if (state->identity.p1g) { /* Bias is done automatically in P1G */
2405 if (state->identity.in_soc) {
2406 if (state->identity.version == SOC_8090_P1G_11R1)
2416 if (!state->config->io.pll_int_loop_filt) {
2417 if (state->identity.in_soc)
2419 else if (state->identity.p1g || (Rest == 0))
2424 lo6 = (state->config->io.pll_int_loop_filt << 3);
2432 dib0090_write_reg(state, 0x15, (u16) FBDiv);
2433 if (state->config->fref_clock_ratio != 0)
2434 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2436 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2437 dib0090_write_reg(state, 0x17, (u16) Rest);
2438 dib0090_write_reg(state, 0x19, lo5);
2439 dib0090_write_reg(state, 0x1c, lo6);
2442 if (state->config->analog_output)
2445 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2449 state->current_rf = state->rf_request;
2450 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2453 state->calibrate = CAPTRIM_CAL; /* captrim search now */
2456 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 */
2457 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2459 while (state->current_rf / 1000 > wbd->max_freq)
2462 dib0090_write_reg(state, 0x1e, 0x07ff);
2463 dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2466 dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2467 dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2468 dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2469 dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2470 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2479 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2480 dib0090_write_reg(state, 0x10, state->wbdmux);
2482 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2484 dib0090_write_reg(state, 0x09, tune->lna_bias);
2485 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2487 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2489 dib0090_write_reg(state, 0x0c, tune->v2i);
2490 dib0090_write_reg(state, 0x0d, tune->mix);
2491 dib0090_write_reg(state, 0x0e, tune->load);
2496 state->rf_lt_def = 0x7c00;
2498 dib0090_set_bandwidth(state);
2499 state->tuner_is_tuned = 1;
2501 state->calibrate |= WBD_CAL;
2502 state->calibrate |= TEMP_CAL;
2517 struct dib0090_state *state = fe->tuner_priv;
2519 return state->tune_state;
2526 struct dib0090_state *state = fe->tuner_priv;
2528 state->tune_state = tune_state;
2536 struct dib0090_state *state = fe->tuner_priv;
2538 *frequency = 1000 * state->current_rf;
2544 struct dib0090_state *state = fe->tuner_priv;
2547 state->tune_state = CT_TUNER_START;
2564 } while (state->tune_state != CT_TUNER_STOP);