static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, u32 freq) { struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; unsigned char *regs = priv->tda18271_regs; int i, ret; u8 tm_current, dc_over_dt, rf_tab; s32 rfcal_comp, approx; /* power up */ ret = tda18271_set_standby_mode(fe, 0, 0, 0); if (tda_fail(ret)) goto fail; /* read die current temperature */ tm_current = tda18271_read_thermometer(fe); /* frequency dependent parameters */ tda18271_calc_rf_cal(fe, &freq); rf_tab = regs[R_EB14]; i = tda18271_lookup_rf_band(fe, &freq, NULL); if (tda_fail(i)) return i; if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab; } else { approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab; } if (approx < 0) approx = 0; if (approx > 255) approx = 255; tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); /* calculate temperature compensation */ rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000; regs[R_EB14] = (unsigned char)(approx + rfcal_comp); ret = tda18271_write_regs(fe, R_EB14, 1); fail: return ret; }
static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, u32 freq, u32 bw) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; int ret; u32 N = 0; /* calculate bp filter */ tda18271_calc_bp_filter(fe, &freq); tda18271_write_regs(fe, R_EP1, 1); regs[R_EB4] &= 0x07; regs[R_EB4] |= 0x60; tda18271_write_regs(fe, R_EB4, 1); regs[R_EB7] = 0x60; tda18271_write_regs(fe, R_EB7, 1); regs[R_EB14] = 0x00; tda18271_write_regs(fe, R_EB14, 1); regs[R_EB20] = 0xcc; tda18271_write_regs(fe, R_EB20, 1); /* set cal mode to RF tracking filter calibration */ regs[R_EP4] |= 0x03; /* calculate cal pll */ switch (priv->mode) { case TDA18271_ANALOG: N = freq - 1250000; break; case TDA18271_DIGITAL: N = freq + bw / 2; break; } tda18271_calc_cal_pll(fe, N); /* calculate main pll */ switch (priv->mode) { case TDA18271_ANALOG: N = freq - 250000; break; case TDA18271_DIGITAL: N = freq + bw / 2 + 1000000; break; } tda18271_calc_main_pll(fe, N); ret = tda18271_write_regs(fe, R_EP3, 11); if (tda_fail(ret)) return ret; msleep(5); /* RF tracking filter calibration initialization */ /* search for K,M,CO for RF calibration */ tda18271_calc_km(fe, &freq); tda18271_write_regs(fe, R_EB13, 1); /* search for rf band */ tda18271_calc_rf_band(fe, &freq); /* search for gain taper */ tda18271_calc_gain_taper(fe, &freq); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EP1, 1); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EP1, 1); regs[R_EB4] &= 0x07; regs[R_EB4] |= 0x40; tda18271_write_regs(fe, R_EB4, 1); regs[R_EB7] = 0x40; tda18271_write_regs(fe, R_EB7, 1); msleep(10); /* pll locking */ regs[R_EB20] = 0xec; tda18271_write_regs(fe, R_EB20, 1); msleep(60); /* RF tracking filter calibration completion */ regs[R_EP4] &= ~0x03; /* set cal mode to normal */ tda18271_write_regs(fe, R_EP4, 1); tda18271_write_regs(fe, R_EP1, 1); /* RF tracking filter correction for VHF_Low band */ if (0 == tda18271_calc_rf_cal(fe, &freq)) tda18271_write_regs(fe, R_EB14, 1); return 0; }
static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) { struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; unsigned char *regs = priv->tda18271_regs; int bcal, rf, i; s32 divisor, dividend; #define RF1 0 #define RF2 1 #define RF3 2 u32 rf_default[3]; u32 rf_freq[3]; s32 prog_cal[3]; s32 prog_tab[3]; i = tda18271_lookup_rf_band(fe, &freq, NULL); if (tda_fail(i)) return i; rf_default[RF1] = 1000 * map[i].rf1_def; rf_default[RF2] = 1000 * map[i].rf2_def; rf_default[RF3] = 1000 * map[i].rf3_def; for (rf = RF1; rf <= RF3; rf++) { if (0 == rf_default[rf]) return 0; tda_cal("freq = %d, rf = %d\n", freq, rf); /* look for optimized calibration frequency */ bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]); if (tda_fail(bcal)) return bcal; tda18271_calc_rf_cal(fe, &rf_freq[rf]); prog_tab[rf] = (s32)regs[R_EB14]; if (1 == bcal) prog_cal[rf] = (s32)tda18271_calibrate_rf(fe, rf_freq[rf]); else prog_cal[rf] = prog_tab[rf]; switch (rf) { case RF1: map[i].rf_a1 = 0; map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]); map[i].rf1 = rf_freq[RF1] / 1000; break; case RF2: dividend = (prog_cal[RF2] - prog_tab[RF2] - prog_cal[RF1] + prog_tab[RF1]); divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; map[i].rf_a1 = (dividend / divisor); map[i].rf2 = rf_freq[RF2] / 1000; break; case RF3: dividend = (prog_cal[RF3] - prog_tab[RF3] - prog_cal[RF2] + prog_tab[RF2]); divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; map[i].rf_a2 = (dividend / divisor); map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]); map[i].rf3 = rf_freq[RF3] / 1000; break; default: BUG(); } } return 0; }
static int tda18271_powerscan(struct dvb_frontend *fe, u32 *freq_in, u32 *freq_out) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; int sgn, bcal, count, wait, ret; u8 cid_target; u16 count_limit; u32 freq; freq = *freq_in; tda18271_calc_rf_band(fe, &freq); tda18271_calc_rf_cal(fe, &freq); tda18271_calc_gain_taper(fe, &freq); tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EB14, 1); /* downconvert frequency */ freq += 1000000; tda18271_calc_main_pll(fe, freq); tda18271_write_regs(fe, R_MPD, 4); msleep(5); /* pll locking */ /* detection mode */ regs[R_EP4] &= ~0x03; regs[R_EP4] |= 0x01; tda18271_write_regs(fe, R_EP4, 1); /* launch power detection measurement */ tda18271_write_regs(fe, R_EP2, 1); /* read power detection info, stored in EB10 */ ret = tda18271_read_extended(fe); if (tda_fail(ret)) return ret; /* algorithm initialization */ sgn = 1; *freq_out = *freq_in; bcal = 0; count = 0; wait = false; while ((regs[R_EB10] & 0x3f) < cid_target) { /* downconvert updated freq to 1 MHz */ freq = *freq_in + (sgn * count) + 1000000; tda18271_calc_main_pll(fe, freq); tda18271_write_regs(fe, R_MPD, 4); if (wait) { msleep(5); /* pll locking */ wait = false; } else udelay(100); /* pll locking */ /* launch power detection measurement */ tda18271_write_regs(fe, R_EP2, 1); /* read power detection info, stored in EB10 */ ret = tda18271_read_extended(fe); if (tda_fail(ret)) return ret; count += 200; if (count <= count_limit) continue; if (sgn <= 0) break; sgn = -1 * sgn; count = 200; wait = true; } if ((regs[R_EB10] & 0x3f) >= cid_target) { bcal = 1; *freq_out = freq - 1000000; } else bcal = 0; tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n", bcal, *freq_in, *freq_out, freq); return bcal; }
static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, u32 freq, u32 bw) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; int ret; u32 N = 0; tda18271_calc_bp_filter(fe, &freq); tda18271_write_regs(fe, R_EP1, 1); regs[R_EB4] &= 0x07; regs[R_EB4] |= 0x60; tda18271_write_regs(fe, R_EB4, 1); regs[R_EB7] = 0x60; tda18271_write_regs(fe, R_EB7, 1); regs[R_EB14] = 0x00; tda18271_write_regs(fe, R_EB14, 1); regs[R_EB20] = 0xcc; tda18271_write_regs(fe, R_EB20, 1); regs[R_EP4] |= 0x03; switch (priv->mode) { case TDA18271_ANALOG: N = freq - 1250000; break; case TDA18271_DIGITAL: N = freq + bw / 2; break; } tda18271_calc_cal_pll(fe, N); switch (priv->mode) { case TDA18271_ANALOG: N = freq - 250000; break; case TDA18271_DIGITAL: N = freq + bw / 2 + 1000000; break; } tda18271_calc_main_pll(fe, N); ret = tda18271_write_regs(fe, R_EP3, 11); if (tda_fail(ret)) return ret; msleep(5); tda18271_calc_km(fe, &freq); tda18271_write_regs(fe, R_EB13, 1); tda18271_calc_rf_band(fe, &freq); tda18271_calc_gain_taper(fe, &freq); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EP1, 1); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EP1, 1); regs[R_EB4] &= 0x07; regs[R_EB4] |= 0x40; tda18271_write_regs(fe, R_EB4, 1); regs[R_EB7] = 0x40; tda18271_write_regs(fe, R_EB7, 1); msleep(10); regs[R_EB20] = 0xec; tda18271_write_regs(fe, R_EB20, 1); msleep(60); regs[R_EP4] &= ~0x03; tda18271_write_regs(fe, R_EP4, 1); tda18271_write_regs(fe, R_EP1, 1); if (0 == tda18271_calc_rf_cal(fe, &freq)) tda18271_write_regs(fe, R_EB14, 1); return 0; }
static int tda18271_powerscan(struct dvb_frontend *fe, u32 *freq_in, u32 *freq_out) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; int sgn, bcal, count, wait, ret; u8 cid_target; u16 count_limit; u32 freq; freq = *freq_in; tda18271_calc_rf_band(fe, &freq); tda18271_calc_rf_cal(fe, &freq); tda18271_calc_gain_taper(fe, &freq); tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit); tda18271_write_regs(fe, R_EP2, 1); tda18271_write_regs(fe, R_EB14, 1); freq += 1000000; tda18271_calc_main_pll(fe, freq); tda18271_write_regs(fe, R_MPD, 4); msleep(5); regs[R_EP4] &= ~0x03; regs[R_EP4] |= 0x01; tda18271_write_regs(fe, R_EP4, 1); tda18271_write_regs(fe, R_EP2, 1); ret = tda18271_read_extended(fe); if (tda_fail(ret)) return ret; sgn = 1; *freq_out = *freq_in; bcal = 0; count = 0; wait = false; while ((regs[R_EB10] & 0x3f) < cid_target) { freq = *freq_in + (sgn * count) + 1000000; tda18271_calc_main_pll(fe, freq); tda18271_write_regs(fe, R_MPD, 4); if (wait) { msleep(5); wait = false; } else udelay(100); tda18271_write_regs(fe, R_EP2, 1); ret = tda18271_read_extended(fe); if (tda_fail(ret)) return ret; count += 200; if (count <= count_limit) continue; if (sgn <= 0) break; sgn = -1 * sgn; count = 200; wait = true; } if ((regs[R_EB10] & 0x3f) >= cid_target) { bcal = 1; *freq_out = freq - 1000000; } else bcal = 0; tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n", bcal, *freq_in, *freq_out, freq); return bcal; }