static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; u32 N; /* set CAL mode to normal */ regs[R_EP4] &= ~0x03; tda18271_write_regs(fe, R_EP4, 1); /* switch off agc1 */ regs[R_EP3] |= 0x40; /* sm_lt = 1 */ regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */ tda18271_write_regs(fe, R_EB18, 1); /* frequency dependent parameters */ tda18271_calc_bp_filter(fe, &freq); tda18271_calc_gain_taper(fe, &freq); tda18271_calc_rf_band(fe, &freq); tda18271_calc_km(fe, &freq); tda18271_write_regs(fe, R_EP1, 3); tda18271_write_regs(fe, R_EB13, 1); /* main pll charge pump source */ tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1); /* cal pll charge pump source */ tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1); /* force dcdc converter to 0 V */ regs[R_EB14] = 0x00; tda18271_write_regs(fe, R_EB14, 1); /* disable plls lock */ regs[R_EB20] &= ~0x20; tda18271_write_regs(fe, R_EB20, 1); /* set CAL mode to RF tracking filter calibration */ regs[R_EP4] |= 0x03; tda18271_write_regs(fe, R_EP4, 2); /* --------------------------------------------------------------- */ /* set the internal calibration signal */ N = freq; tda18271_calc_cal_pll(fe, N); tda18271_write_regs(fe, R_CPD, 4); /* downconvert internal calibration */ N += 1000000; tda18271_calc_main_pll(fe, N); tda18271_write_regs(fe, R_MPD, 4); msleep(5); 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); /* --------------------------------------------------------------- */ /* normal operation for the main pll */ tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0); /* normal operation for the cal pll */ tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0); msleep(10); /* plls locking */ /* launch the rf tracking filters calibration */ regs[R_EB20] |= 0x20; tda18271_write_regs(fe, R_EB20, 1); msleep(60); /* calibration */ /* --------------------------------------------------------------- */ /* set CAL mode to normal */ regs[R_EP4] &= ~0x03; /* switch on agc1 */ regs[R_EP3] &= ~0x40; /* sm_lt = 0 */ regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */ tda18271_write_regs(fe, R_EB18, 1); tda18271_write_regs(fe, R_EP3, 2); /* synchronization */ tda18271_write_regs(fe, R_EP1, 1); /* get calibration result */ tda18271_read_extended(fe); return regs[R_EB14]; }
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 tda18271_channel_configuration(struct dvb_frontend *fe, struct tda18271_std_map_item *map, u32 freq, u32 bw) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; int ret; u32 N; /* update TV broadcast parameters */ /* set standard */ regs[R_EP3] &= ~0x1f; /* clear std bits */ regs[R_EP3] |= (map->agc_mode << 3) | map->std; if (priv->id == TDA18271HDC2) { /* set rfagc to high speed mode */ regs[R_EP3] &= ~0x04; } /* set cal mode to normal */ regs[R_EP4] &= ~0x03; /* update IF output level */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ regs[R_EP4] |= (map->if_lvl << 2); /* update FM_RFn */ regs[R_EP4] &= ~0x80; regs[R_EP4] |= map->fm_rfn << 7; /* update rf top / if top */ regs[R_EB22] = 0x00; regs[R_EB22] |= map->rfagc_top; ret = tda18271_write_regs(fe, R_EB22, 1); if (tda_fail(ret)) goto fail; /* --------------------------------------------------------------- */ /* disable Power Level Indicator */ regs[R_EP1] |= 0x40; /* make sure thermometer is off */ regs[R_TM] &= ~0x10; /* frequency dependent parameters */ tda18271_calc_ir_measure(fe, &freq); tda18271_calc_bp_filter(fe, &freq); tda18271_calc_rf_band(fe, &freq); tda18271_calc_gain_taper(fe, &freq); /* --------------------------------------------------------------- */ /* dual tuner and agc1 extra configuration */ switch (priv->role) { case TDA18271_MASTER: regs[R_EB1] |= 0x04; /* main vco */ break; case TDA18271_SLAVE: regs[R_EB1] &= ~0x04; /* cal vco */ break; } /* agc1 always active */ regs[R_EB1] &= ~0x02; /* agc1 has priority on agc2 */ regs[R_EB1] &= ~0x01; ret = tda18271_write_regs(fe, R_EB1, 1); if (tda_fail(ret)) goto fail; /* --------------------------------------------------------------- */ N = map->if_freq * 1000 + freq; switch (priv->role) { case TDA18271_MASTER: tda18271_calc_main_pll(fe, N); tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 4); break; case TDA18271_SLAVE: tda18271_calc_cal_pll(fe, N); tda18271_write_regs(fe, R_CPD, 4); regs[R_MPD] = regs[R_CPD] & 0x7f; tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 1); break; } ret = tda18271_write_regs(fe, R_TM, 7); if (tda_fail(ret)) goto fail; /* force charge pump source */ charge_pump_source(fe, 1); msleep(1); /* return pll to normal operation */ charge_pump_source(fe, 0); msleep(20); if (priv->id == TDA18271HDC2) { /* set rfagc to normal speed mode */ if (map->fm_rfn) regs[R_EP3] &= ~0x04; else regs[R_EP3] |= 0x04; ret = tda18271_write_regs(fe, R_EP3, 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; }