brintos

brintos / linux-shallow public Read only

0
0
Text · 31.6 KiB · a7e721b Raw
1343 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3    tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner4 5    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>6 7*/8 9#include "tda18271-priv.h"10#include "tda8290.h"11 12#include <linux/delay.h>13#include <linux/videodev2.h>14 15int tda18271_debug;16module_param_named(debug, tda18271_debug, int, 0644);17MODULE_PARM_DESC(debug, "set debug level (info=1, map=2, reg=4, adv=8, cal=16 (or-able))");18 19static int tda18271_cal_on_startup = -1;20module_param_named(cal, tda18271_cal_on_startup, int, 0644);21MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");22 23static DEFINE_MUTEX(tda18271_list_mutex);24static LIST_HEAD(hybrid_tuner_instance_list);25 26/*---------------------------------------------------------------------*/27 28static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)29{30	struct tda18271_priv *priv = fe->tuner_priv;31 32	int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,33			priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,34			priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);35 36	if (tda_fail(ret))37		goto fail;38 39	tda_dbg("%s mode: xtal oscillator %s, slave tuner loop through %s\n",40		standby ? "standby" : "active",41		priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",42		priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");43fail:44	return ret;45}46 47/*---------------------------------------------------------------------*/48 49static inline int charge_pump_source(struct dvb_frontend *fe, int force)50{51	struct tda18271_priv *priv = fe->tuner_priv;52	return tda18271_charge_pump_source(fe,53					   (priv->role == TDA18271_SLAVE) ?54					   TDA18271_CAL_PLL :55					   TDA18271_MAIN_PLL, force);56}57 58static inline void tda18271_set_if_notch(struct dvb_frontend *fe)59{60	struct tda18271_priv *priv = fe->tuner_priv;61	unsigned char *regs = priv->tda18271_regs;62 63	switch (priv->mode) {64	case TDA18271_ANALOG:65		regs[R_MPD]  &= ~0x80; /* IF notch = 0 */66		break;67	case TDA18271_DIGITAL:68		regs[R_MPD]  |= 0x80; /* IF notch = 1 */69		break;70	}71}72 73static int tda18271_channel_configuration(struct dvb_frontend *fe,74					  struct tda18271_std_map_item *map,75					  u32 freq, u32 bw)76{77	struct tda18271_priv *priv = fe->tuner_priv;78	unsigned char *regs = priv->tda18271_regs;79	int ret;80	u32 N;81 82	/* update TV broadcast parameters */83 84	/* set standard */85	regs[R_EP3]  &= ~0x1f; /* clear std bits */86	regs[R_EP3]  |= (map->agc_mode << 3) | map->std;87 88	if (priv->id == TDA18271HDC2) {89		/* set rfagc to high speed mode */90		regs[R_EP3] &= ~0x04;91	}92 93	/* set cal mode to normal */94	regs[R_EP4]  &= ~0x03;95 96	/* update IF output level */97	regs[R_EP4]  &= ~0x1c; /* clear if level bits */98	regs[R_EP4]  |= (map->if_lvl << 2);99 100	/* update FM_RFn */101	regs[R_EP4]  &= ~0x80;102	regs[R_EP4]  |= map->fm_rfn << 7;103 104	/* update rf top / if top */105	regs[R_EB22]  = 0x00;106	regs[R_EB22] |= map->rfagc_top;107	ret = tda18271_write_regs(fe, R_EB22, 1);108	if (tda_fail(ret))109		goto fail;110 111	/* --------------------------------------------------------------- */112 113	/* disable Power Level Indicator */114	regs[R_EP1]  |= 0x40;115 116	/* make sure thermometer is off */117	regs[R_TM]   &= ~0x10;118 119	/* frequency dependent parameters */120 121	tda18271_calc_ir_measure(fe, &freq);122 123	tda18271_calc_bp_filter(fe, &freq);124 125	tda18271_calc_rf_band(fe, &freq);126 127	tda18271_calc_gain_taper(fe, &freq);128 129	/* --------------------------------------------------------------- */130 131	/* dual tuner and agc1 extra configuration */132 133	switch (priv->role) {134	case TDA18271_MASTER:135		regs[R_EB1]  |= 0x04; /* main vco */136		break;137	case TDA18271_SLAVE:138		regs[R_EB1]  &= ~0x04; /* cal vco */139		break;140	}141 142	/* agc1 always active */143	regs[R_EB1]  &= ~0x02;144 145	/* agc1 has priority on agc2 */146	regs[R_EB1]  &= ~0x01;147 148	ret = tda18271_write_regs(fe, R_EB1, 1);149	if (tda_fail(ret))150		goto fail;151 152	/* --------------------------------------------------------------- */153 154	N = map->if_freq * 1000 + freq;155 156	switch (priv->role) {157	case TDA18271_MASTER:158		tda18271_calc_main_pll(fe, N);159		tda18271_set_if_notch(fe);160		tda18271_write_regs(fe, R_MPD, 4);161		break;162	case TDA18271_SLAVE:163		tda18271_calc_cal_pll(fe, N);164		tda18271_write_regs(fe, R_CPD, 4);165 166		regs[R_MPD] = regs[R_CPD] & 0x7f;167		tda18271_set_if_notch(fe);168		tda18271_write_regs(fe, R_MPD, 1);169		break;170	}171 172	ret = tda18271_write_regs(fe, R_TM, 7);173	if (tda_fail(ret))174		goto fail;175 176	/* force charge pump source */177	charge_pump_source(fe, 1);178 179	msleep(1);180 181	/* return pll to normal operation */182	charge_pump_source(fe, 0);183 184	msleep(20);185 186	if (priv->id == TDA18271HDC2) {187		/* set rfagc to normal speed mode */188		if (map->fm_rfn)189			regs[R_EP3] &= ~0x04;190		else191			regs[R_EP3] |= 0x04;192		ret = tda18271_write_regs(fe, R_EP3, 1);193	}194fail:195	return ret;196}197 198static int tda18271_read_thermometer(struct dvb_frontend *fe)199{200	struct tda18271_priv *priv = fe->tuner_priv;201	unsigned char *regs = priv->tda18271_regs;202	int tm;203 204	/* switch thermometer on */205	regs[R_TM]   |= 0x10;206	tda18271_write_regs(fe, R_TM, 1);207 208	/* read thermometer info */209	tda18271_read_regs(fe);210 211	if ((((regs[R_TM] & 0x0f) == 0x00) && ((regs[R_TM] & 0x20) == 0x20)) ||212	    (((regs[R_TM] & 0x0f) == 0x08) && ((regs[R_TM] & 0x20) == 0x00))) {213 214		if ((regs[R_TM] & 0x20) == 0x20)215			regs[R_TM] &= ~0x20;216		else217			regs[R_TM] |= 0x20;218 219		tda18271_write_regs(fe, R_TM, 1);220 221		msleep(10); /* temperature sensing */222 223		/* read thermometer info */224		tda18271_read_regs(fe);225	}226 227	tm = tda18271_lookup_thermometer(fe);228 229	/* switch thermometer off */230	regs[R_TM]   &= ~0x10;231	tda18271_write_regs(fe, R_TM, 1);232 233	/* set CAL mode to normal */234	regs[R_EP4]  &= ~0x03;235	tda18271_write_regs(fe, R_EP4, 1);236 237	return tm;238}239 240/* ------------------------------------------------------------------ */241 242static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,243						     u32 freq)244{245	struct tda18271_priv *priv = fe->tuner_priv;246	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;247	unsigned char *regs = priv->tda18271_regs;248	int i, ret;249	u8 tm_current, dc_over_dt, rf_tab;250	s32 rfcal_comp, approx;251 252	/* power up */253	ret = tda18271_set_standby_mode(fe, 0, 0, 0);254	if (tda_fail(ret))255		goto fail;256 257	/* read die current temperature */258	tm_current = tda18271_read_thermometer(fe);259 260	/* frequency dependent parameters */261 262	tda18271_calc_rf_cal(fe, &freq);263	rf_tab = regs[R_EB14];264 265	i = tda18271_lookup_rf_band(fe, &freq, NULL);266	if (tda_fail(i))267		return i;268 269	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {270		approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +271			map[i].rf_b1 + rf_tab;272	} else {273		approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +274			map[i].rf_b2 + rf_tab;275	}276 277	if (approx < 0)278		approx = 0;279	if (approx > 255)280		approx = 255;281 282	tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);283 284	/* calculate temperature compensation */285	rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;286 287	regs[R_EB14] = (unsigned char)(approx + rfcal_comp);288	ret = tda18271_write_regs(fe, R_EB14, 1);289fail:290	return ret;291}292 293static int tda18271_por(struct dvb_frontend *fe)294{295	struct tda18271_priv *priv = fe->tuner_priv;296	unsigned char *regs = priv->tda18271_regs;297	int ret;298 299	/* power up detector 1 */300	regs[R_EB12] &= ~0x20;301	ret = tda18271_write_regs(fe, R_EB12, 1);302	if (tda_fail(ret))303		goto fail;304 305	regs[R_EB18] &= ~0x80; /* turn agc1 loop on */306	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */307	ret = tda18271_write_regs(fe, R_EB18, 1);308	if (tda_fail(ret))309		goto fail;310 311	regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */312 313	/* POR mode */314	ret = tda18271_set_standby_mode(fe, 1, 0, 0);315	if (tda_fail(ret))316		goto fail;317 318	/* disable 1.5 MHz low pass filter */319	regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */320	regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */321	ret = tda18271_write_regs(fe, R_EB21, 3);322fail:323	return ret;324}325 326static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)327{328	struct tda18271_priv *priv = fe->tuner_priv;329	unsigned char *regs = priv->tda18271_regs;330	u32 N;331 332	/* set CAL mode to normal */333	regs[R_EP4]  &= ~0x03;334	tda18271_write_regs(fe, R_EP4, 1);335 336	/* switch off agc1 */337	regs[R_EP3]  |= 0x40; /* sm_lt = 1 */338 339	regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */340	tda18271_write_regs(fe, R_EB18, 1);341 342	/* frequency dependent parameters */343 344	tda18271_calc_bp_filter(fe, &freq);345	tda18271_calc_gain_taper(fe, &freq);346	tda18271_calc_rf_band(fe, &freq);347	tda18271_calc_km(fe, &freq);348 349	tda18271_write_regs(fe, R_EP1, 3);350	tda18271_write_regs(fe, R_EB13, 1);351 352	/* main pll charge pump source */353	tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);354 355	/* cal pll charge pump source */356	tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1);357 358	/* force dcdc converter to 0 V */359	regs[R_EB14] = 0x00;360	tda18271_write_regs(fe, R_EB14, 1);361 362	/* disable plls lock */363	regs[R_EB20] &= ~0x20;364	tda18271_write_regs(fe, R_EB20, 1);365 366	/* set CAL mode to RF tracking filter calibration */367	regs[R_EP4]  |= 0x03;368	tda18271_write_regs(fe, R_EP4, 2);369 370	/* --------------------------------------------------------------- */371 372	/* set the internal calibration signal */373	N = freq;374 375	tda18271_calc_cal_pll(fe, N);376	tda18271_write_regs(fe, R_CPD, 4);377 378	/* downconvert internal calibration */379	N += 1000000;380 381	tda18271_calc_main_pll(fe, N);382	tda18271_write_regs(fe, R_MPD, 4);383 384	msleep(5);385 386	tda18271_write_regs(fe, R_EP2, 1);387	tda18271_write_regs(fe, R_EP1, 1);388	tda18271_write_regs(fe, R_EP2, 1);389	tda18271_write_regs(fe, R_EP1, 1);390 391	/* --------------------------------------------------------------- */392 393	/* normal operation for the main pll */394	tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);395 396	/* normal operation for the cal pll  */397	tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0);398 399	msleep(10); /* plls locking */400 401	/* launch the rf tracking filters calibration */402	regs[R_EB20]  |= 0x20;403	tda18271_write_regs(fe, R_EB20, 1);404 405	msleep(60); /* calibration */406 407	/* --------------------------------------------------------------- */408 409	/* set CAL mode to normal */410	regs[R_EP4]  &= ~0x03;411 412	/* switch on agc1 */413	regs[R_EP3]  &= ~0x40; /* sm_lt = 0 */414 415	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */416	tda18271_write_regs(fe, R_EB18, 1);417 418	tda18271_write_regs(fe, R_EP3, 2);419 420	/* synchronization */421	tda18271_write_regs(fe, R_EP1, 1);422 423	/* get calibration result */424	tda18271_read_extended(fe);425 426	return regs[R_EB14];427}428 429static int tda18271_powerscan(struct dvb_frontend *fe,430			      u32 *freq_in, u32 *freq_out)431{432	struct tda18271_priv *priv = fe->tuner_priv;433	unsigned char *regs = priv->tda18271_regs;434	int sgn, bcal, count, wait, ret;435	u8 cid_target;436	u16 count_limit;437	u32 freq;438 439	freq = *freq_in;440 441	tda18271_calc_rf_band(fe, &freq);442	tda18271_calc_rf_cal(fe, &freq);443	tda18271_calc_gain_taper(fe, &freq);444	tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit);445 446	tda18271_write_regs(fe, R_EP2, 1);447	tda18271_write_regs(fe, R_EB14, 1);448 449	/* downconvert frequency */450	freq += 1000000;451 452	tda18271_calc_main_pll(fe, freq);453	tda18271_write_regs(fe, R_MPD, 4);454 455	msleep(5); /* pll locking */456 457	/* detection mode */458	regs[R_EP4]  &= ~0x03;459	regs[R_EP4]  |= 0x01;460	tda18271_write_regs(fe, R_EP4, 1);461 462	/* launch power detection measurement */463	tda18271_write_regs(fe, R_EP2, 1);464 465	/* read power detection info, stored in EB10 */466	ret = tda18271_read_extended(fe);467	if (tda_fail(ret))468		return ret;469 470	/* algorithm initialization */471	sgn = 1;472	*freq_out = *freq_in;473	count = 0;474	wait = false;475 476	while ((regs[R_EB10] & 0x3f) < cid_target) {477		/* downconvert updated freq to 1 MHz */478		freq = *freq_in + (sgn * count) + 1000000;479 480		tda18271_calc_main_pll(fe, freq);481		tda18271_write_regs(fe, R_MPD, 4);482 483		if (wait) {484			msleep(5); /* pll locking */485			wait = false;486		} else487			udelay(100); /* pll locking */488 489		/* launch power detection measurement */490		tda18271_write_regs(fe, R_EP2, 1);491 492		/* read power detection info, stored in EB10 */493		ret = tda18271_read_extended(fe);494		if (tda_fail(ret))495			return ret;496 497		count += 200;498 499		if (count <= count_limit)500			continue;501 502		if (sgn <= 0)503			break;504 505		sgn = -1 * sgn;506		count = 200;507		wait = true;508	}509 510	if ((regs[R_EB10] & 0x3f) >= cid_target) {511		bcal = 1;512		*freq_out = freq - 1000000;513	} else514		bcal = 0;515 516	tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n",517		bcal, *freq_in, *freq_out, freq);518 519	return bcal;520}521 522static int tda18271_powerscan_init(struct dvb_frontend *fe)523{524	struct tda18271_priv *priv = fe->tuner_priv;525	unsigned char *regs = priv->tda18271_regs;526	int ret;527 528	/* set standard to digital */529	regs[R_EP3]  &= ~0x1f; /* clear std bits */530	regs[R_EP3]  |= 0x12;531 532	/* set cal mode to normal */533	regs[R_EP4]  &= ~0x03;534 535	/* update IF output level */536	regs[R_EP4]  &= ~0x1c; /* clear if level bits */537 538	ret = tda18271_write_regs(fe, R_EP3, 2);539	if (tda_fail(ret))540		goto fail;541 542	regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */543	ret = tda18271_write_regs(fe, R_EB18, 1);544	if (tda_fail(ret))545		goto fail;546 547	regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */548 549	/* 1.5 MHz low pass filter */550	regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */551	regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */552 553	ret = tda18271_write_regs(fe, R_EB21, 3);554fail:555	return ret;556}557 558static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)559{560	struct tda18271_priv *priv = fe->tuner_priv;561	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;562	unsigned char *regs = priv->tda18271_regs;563	int bcal, rf, i;564	s32 divisor, dividend;565#define RF1 0566#define RF2 1567#define RF3 2568	u32 rf_default[3];569	u32 rf_freq[3];570	s32 prog_cal[3];571	s32 prog_tab[3];572 573	i = tda18271_lookup_rf_band(fe, &freq, NULL);574 575	if (tda_fail(i))576		return i;577 578	rf_default[RF1] = 1000 * map[i].rf1_def;579	rf_default[RF2] = 1000 * map[i].rf2_def;580	rf_default[RF3] = 1000 * map[i].rf3_def;581 582	for (rf = RF1; rf <= RF3; rf++) {583		if (0 == rf_default[rf])584			return 0;585		tda_cal("freq = %d, rf = %d\n", freq, rf);586 587		/* look for optimized calibration frequency */588		bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);589		if (tda_fail(bcal))590			return bcal;591 592		tda18271_calc_rf_cal(fe, &rf_freq[rf]);593		prog_tab[rf] = (s32)regs[R_EB14];594 595		if (1 == bcal)596			prog_cal[rf] =597				(s32)tda18271_calibrate_rf(fe, rf_freq[rf]);598		else599			prog_cal[rf] = prog_tab[rf];600 601		switch (rf) {602		case RF1:603			map[i].rf_a1 = 0;604			map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]);605			map[i].rf1   = rf_freq[RF1] / 1000;606			break;607		case RF2:608			dividend = (prog_cal[RF2] - prog_tab[RF2] -609				    prog_cal[RF1] + prog_tab[RF1]);610			divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;611			map[i].rf_a1 = (dividend / divisor);612			map[i].rf2   = rf_freq[RF2] / 1000;613			break;614		case RF3:615			dividend = (prog_cal[RF3] - prog_tab[RF3] -616				    prog_cal[RF2] + prog_tab[RF2]);617			divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;618			map[i].rf_a2 = (dividend / divisor);619			map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]);620			map[i].rf3   = rf_freq[RF3] / 1000;621			break;622		default:623			BUG();624		}625	}626 627	return 0;628}629 630static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)631{632	struct tda18271_priv *priv = fe->tuner_priv;633	unsigned int i;634	int ret;635 636	tda_info("performing RF tracking filter calibration\n");637 638	/* wait for die temperature stabilization */639	msleep(200);640 641	ret = tda18271_powerscan_init(fe);642	if (tda_fail(ret))643		goto fail;644 645	/* rf band calibration */646	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {647		ret =648		tda18271_rf_tracking_filters_init(fe, 1000 *649						  priv->rf_cal_state[i].rfmax);650		if (tda_fail(ret))651			goto fail;652	}653 654	priv->tm_rfcal = tda18271_read_thermometer(fe);655fail:656	return ret;657}658 659/* ------------------------------------------------------------------ */660 661static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)662{663	struct tda18271_priv *priv = fe->tuner_priv;664	unsigned char *regs = priv->tda18271_regs;665	int ret;666 667	/* test RF_CAL_OK to see if we need init */668	if ((regs[R_EP1] & 0x10) == 0)669		priv->cal_initialized = false;670 671	if (priv->cal_initialized)672		return 0;673 674	ret = tda18271_calc_rf_filter_curve(fe);675	if (tda_fail(ret))676		goto fail;677 678	ret = tda18271_por(fe);679	if (tda_fail(ret))680		goto fail;681 682	tda_info("RF tracking filter calibration complete\n");683 684	priv->cal_initialized = true;685	goto end;686fail:687	tda_info("RF tracking filter calibration failed!\n");688end:689	return ret;690}691 692static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,693						     u32 freq, u32 bw)694{695	struct tda18271_priv *priv = fe->tuner_priv;696	unsigned char *regs = priv->tda18271_regs;697	int ret;698	u32 N = 0;699 700	/* calculate bp filter */701	tda18271_calc_bp_filter(fe, &freq);702	tda18271_write_regs(fe, R_EP1, 1);703 704	regs[R_EB4]  &= 0x07;705	regs[R_EB4]  |= 0x60;706	tda18271_write_regs(fe, R_EB4, 1);707 708	regs[R_EB7]   = 0x60;709	tda18271_write_regs(fe, R_EB7, 1);710 711	regs[R_EB14]  = 0x00;712	tda18271_write_regs(fe, R_EB14, 1);713 714	regs[R_EB20]  = 0xcc;715	tda18271_write_regs(fe, R_EB20, 1);716 717	/* set cal mode to RF tracking filter calibration */718	regs[R_EP4]  |= 0x03;719 720	/* calculate cal pll */721 722	switch (priv->mode) {723	case TDA18271_ANALOG:724		N = freq - 1250000;725		break;726	case TDA18271_DIGITAL:727		N = freq + bw / 2;728		break;729	}730 731	tda18271_calc_cal_pll(fe, N);732 733	/* calculate main pll */734 735	switch (priv->mode) {736	case TDA18271_ANALOG:737		N = freq - 250000;738		break;739	case TDA18271_DIGITAL:740		N = freq + bw / 2 + 1000000;741		break;742	}743 744	tda18271_calc_main_pll(fe, N);745 746	ret = tda18271_write_regs(fe, R_EP3, 11);747	if (tda_fail(ret))748		return ret;749 750	msleep(5); /* RF tracking filter calibration initialization */751 752	/* search for K,M,CO for RF calibration */753	tda18271_calc_km(fe, &freq);754	tda18271_write_regs(fe, R_EB13, 1);755 756	/* search for rf band */757	tda18271_calc_rf_band(fe, &freq);758 759	/* search for gain taper */760	tda18271_calc_gain_taper(fe, &freq);761 762	tda18271_write_regs(fe, R_EP2, 1);763	tda18271_write_regs(fe, R_EP1, 1);764	tda18271_write_regs(fe, R_EP2, 1);765	tda18271_write_regs(fe, R_EP1, 1);766 767	regs[R_EB4]  &= 0x07;768	regs[R_EB4]  |= 0x40;769	tda18271_write_regs(fe, R_EB4, 1);770 771	regs[R_EB7]   = 0x40;772	tda18271_write_regs(fe, R_EB7, 1);773	msleep(10); /* pll locking */774 775	regs[R_EB20]  = 0xec;776	tda18271_write_regs(fe, R_EB20, 1);777	msleep(60); /* RF tracking filter calibration completion */778 779	regs[R_EP4]  &= ~0x03; /* set cal mode to normal */780	tda18271_write_regs(fe, R_EP4, 1);781 782	tda18271_write_regs(fe, R_EP1, 1);783 784	/* RF tracking filter correction for VHF_Low band */785	if (0 == tda18271_calc_rf_cal(fe, &freq))786		tda18271_write_regs(fe, R_EB14, 1);787 788	return 0;789}790 791/* ------------------------------------------------------------------ */792 793static int tda18271_ir_cal_init(struct dvb_frontend *fe)794{795	struct tda18271_priv *priv = fe->tuner_priv;796	unsigned char *regs = priv->tda18271_regs;797	int ret;798 799	ret = tda18271_read_regs(fe);800	if (tda_fail(ret))801		goto fail;802 803	/* test IR_CAL_OK to see if we need init */804	if ((regs[R_EP1] & 0x08) == 0)805		ret = tda18271_init_regs(fe);806fail:807	return ret;808}809 810static int tda18271_init(struct dvb_frontend *fe)811{812	struct tda18271_priv *priv = fe->tuner_priv;813	int ret;814 815	mutex_lock(&priv->lock);816 817	/* full power up */818	ret = tda18271_set_standby_mode(fe, 0, 0, 0);819	if (tda_fail(ret))820		goto fail;821 822	/* initialization */823	ret = tda18271_ir_cal_init(fe);824	if (tda_fail(ret))825		goto fail;826 827	if (priv->id == TDA18271HDC2)828		tda18271c2_rf_cal_init(fe);829fail:830	mutex_unlock(&priv->lock);831 832	return ret;833}834 835static int tda18271_sleep(struct dvb_frontend *fe)836{837	struct tda18271_priv *priv = fe->tuner_priv;838	int ret;839 840	mutex_lock(&priv->lock);841 842	/* enter standby mode, with required output features enabled */843	ret = tda18271_toggle_output(fe, 1);844 845	mutex_unlock(&priv->lock);846 847	return ret;848}849 850/* ------------------------------------------------------------------ */851 852static int tda18271_agc(struct dvb_frontend *fe)853{854	struct tda18271_priv *priv = fe->tuner_priv;855	int ret = 0;856 857	switch (priv->config) {858	case TDA8290_LNA_OFF:859		/* no external agc configuration required */860		if (tda18271_debug & DBG_ADV)861			tda_dbg("no agc configuration provided\n");862		break;863	case TDA8290_LNA_ON_BRIDGE:864		/* switch with GPIO of saa713x */865		tda_dbg("invoking callback\n");866		if (fe->callback)867			ret = fe->callback(priv->i2c_props.adap->algo_data,868					   DVB_FRONTEND_COMPONENT_TUNER,869					   TDA18271_CALLBACK_CMD_AGC_ENABLE,870					   priv->mode);871		break;872	case TDA8290_LNA_GP0_HIGH_ON:873	case TDA8290_LNA_GP0_HIGH_OFF:874	default:875		/* n/a - currently not supported */876		tda_err("unsupported configuration: %d\n", priv->config);877		ret = -EINVAL;878		break;879	}880	return ret;881}882 883static int tda18271_tune(struct dvb_frontend *fe,884			 struct tda18271_std_map_item *map, u32 freq, u32 bw)885{886	struct tda18271_priv *priv = fe->tuner_priv;887	int ret;888 889	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",890		freq, map->if_freq, bw, map->agc_mode, map->std);891 892	ret = tda18271_agc(fe);893	if (tda_fail(ret))894		tda_warn("failed to configure agc\n");895 896	ret = tda18271_init(fe);897	if (tda_fail(ret))898		goto fail;899 900	mutex_lock(&priv->lock);901 902	switch (priv->id) {903	case TDA18271HDC1:904		tda18271c1_rf_tracking_filter_calibration(fe, freq, bw);905		break;906	case TDA18271HDC2:907		tda18271c2_rf_tracking_filters_correction(fe, freq);908		break;909	}910	ret = tda18271_channel_configuration(fe, map, freq, bw);911 912	mutex_unlock(&priv->lock);913fail:914	return ret;915}916 917/* ------------------------------------------------------------------ */918 919static int tda18271_set_params(struct dvb_frontend *fe)920{921	struct dtv_frontend_properties *c = &fe->dtv_property_cache;922	u32 delsys = c->delivery_system;923	u32 bw = c->bandwidth_hz;924	u32 freq = c->frequency;925	struct tda18271_priv *priv = fe->tuner_priv;926	struct tda18271_std_map *std_map = &priv->std;927	struct tda18271_std_map_item *map;928	int ret;929 930	priv->mode = TDA18271_DIGITAL;931 932	switch (delsys) {933	case SYS_ATSC:934		map = &std_map->atsc_6;935		bw = 6000000;936		break;937	case SYS_ISDBT:938	case SYS_DVBT:939	case SYS_DVBT2:940		if (bw <= 6000000) {941			map = &std_map->dvbt_6;942		} else if (bw <= 7000000) {943			map = &std_map->dvbt_7;944		} else {945			map = &std_map->dvbt_8;946		}947		break;948	case SYS_DVBC_ANNEX_B:949		bw = 6000000;950		fallthrough;951	case SYS_DVBC_ANNEX_A:952	case SYS_DVBC_ANNEX_C:953		if (bw <= 6000000) {954			map = &std_map->qam_6;955		} else if (bw <= 7000000) {956			map = &std_map->qam_7;957		} else {958			map = &std_map->qam_8;959		}960		break;961	default:962		tda_warn("modulation type not supported!\n");963		return -EINVAL;964	}965 966	/* When tuning digital, the analog demod must be tri-stated */967	if (fe->ops.analog_ops.standby)968		fe->ops.analog_ops.standby(fe);969 970	ret = tda18271_tune(fe, map, freq, bw);971 972	if (tda_fail(ret))973		goto fail;974 975	priv->if_freq   = map->if_freq;976	priv->frequency = freq;977	priv->bandwidth = bw;978fail:979	return ret;980}981 982static int tda18271_set_analog_params(struct dvb_frontend *fe,983				      struct analog_parameters *params)984{985	struct tda18271_priv *priv = fe->tuner_priv;986	struct tda18271_std_map *std_map = &priv->std;987	struct tda18271_std_map_item *map;988	char *mode;989	int ret;990	u32 freq = params->frequency * 125 *991		((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;992 993	priv->mode = TDA18271_ANALOG;994 995	if (params->mode == V4L2_TUNER_RADIO) {996		map = &std_map->fm_radio;997		mode = "fm";998	} else if (params->std & V4L2_STD_MN) {999		map = &std_map->atv_mn;1000		mode = "MN";1001	} else if (params->std & V4L2_STD_B) {1002		map = &std_map->atv_b;1003		mode = "B";1004	} else if (params->std & V4L2_STD_GH) {1005		map = &std_map->atv_gh;1006		mode = "GH";1007	} else if (params->std & V4L2_STD_PAL_I) {1008		map = &std_map->atv_i;1009		mode = "I";1010	} else if (params->std & V4L2_STD_DK) {1011		map = &std_map->atv_dk;1012		mode = "DK";1013	} else if (params->std & V4L2_STD_SECAM_L) {1014		map = &std_map->atv_l;1015		mode = "L";1016	} else if (params->std & V4L2_STD_SECAM_LC) {1017		map = &std_map->atv_lc;1018		mode = "L'";1019	} else {1020		map = &std_map->atv_i;1021		mode = "xx";1022	}1023 1024	tda_dbg("setting tda18271 to system %s\n", mode);1025 1026	ret = tda18271_tune(fe, map, freq, 0);1027 1028	if (tda_fail(ret))1029		goto fail;1030 1031	priv->if_freq   = map->if_freq;1032	priv->frequency = freq;1033	priv->bandwidth = 0;1034fail:1035	return ret;1036}1037 1038static void tda18271_release(struct dvb_frontend *fe)1039{1040	struct tda18271_priv *priv = fe->tuner_priv;1041 1042	mutex_lock(&tda18271_list_mutex);1043 1044	if (priv)1045		hybrid_tuner_release_state(priv);1046 1047	mutex_unlock(&tda18271_list_mutex);1048 1049	fe->tuner_priv = NULL;1050}1051 1052static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)1053{1054	struct tda18271_priv *priv = fe->tuner_priv;1055	*frequency = priv->frequency;1056	return 0;1057}1058 1059static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)1060{1061	struct tda18271_priv *priv = fe->tuner_priv;1062	*bandwidth = priv->bandwidth;1063	return 0;1064}1065 1066static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)1067{1068	struct tda18271_priv *priv = fe->tuner_priv;1069	*frequency = (u32)priv->if_freq * 1000;1070	return 0;1071}1072 1073/* ------------------------------------------------------------------ */1074 1075#define tda18271_update_std(std_cfg, name) do {				\1076	if (map->std_cfg.if_freq +					\1077		map->std_cfg.agc_mode + map->std_cfg.std +		\1078		map->std_cfg.if_lvl + map->std_cfg.rfagc_top > 0) {	\1079		tda_dbg("Using custom std config for %s\n", name);	\1080		memcpy(&std->std_cfg, &map->std_cfg,			\1081			sizeof(struct tda18271_std_map_item));		\1082	} } while (0)1083 1084#define tda18271_dump_std_item(std_cfg, name) do {			\1085	tda_dbg("(%s) if_freq = %d, agc_mode = %d, std = %d, "		\1086		"if_lvl = %d, rfagc_top = 0x%02x\n",			\1087		name, std->std_cfg.if_freq,				\1088		std->std_cfg.agc_mode, std->std_cfg.std,		\1089		std->std_cfg.if_lvl, std->std_cfg.rfagc_top);		\1090	} while (0)1091 1092static int tda18271_dump_std_map(struct dvb_frontend *fe)1093{1094	struct tda18271_priv *priv = fe->tuner_priv;1095	struct tda18271_std_map *std = &priv->std;1096 1097	tda_dbg("========== STANDARD MAP SETTINGS ==========\n");1098	tda18271_dump_std_item(fm_radio, "  fm  ");1099	tda18271_dump_std_item(atv_b,  "atv b ");1100	tda18271_dump_std_item(atv_dk, "atv dk");1101	tda18271_dump_std_item(atv_gh, "atv gh");1102	tda18271_dump_std_item(atv_i,  "atv i ");1103	tda18271_dump_std_item(atv_l,  "atv l ");1104	tda18271_dump_std_item(atv_lc, "atv l'");1105	tda18271_dump_std_item(atv_mn, "atv mn");1106	tda18271_dump_std_item(atsc_6, "atsc 6");1107	tda18271_dump_std_item(dvbt_6, "dvbt 6");1108	tda18271_dump_std_item(dvbt_7, "dvbt 7");1109	tda18271_dump_std_item(dvbt_8, "dvbt 8");1110	tda18271_dump_std_item(qam_6,  "qam 6 ");1111	tda18271_dump_std_item(qam_7,  "qam 7 ");1112	tda18271_dump_std_item(qam_8,  "qam 8 ");1113 1114	return 0;1115}1116 1117static int tda18271_update_std_map(struct dvb_frontend *fe,1118				   struct tda18271_std_map *map)1119{1120	struct tda18271_priv *priv = fe->tuner_priv;1121	struct tda18271_std_map *std = &priv->std;1122 1123	if (!map)1124		return -EINVAL;1125 1126	tda18271_update_std(fm_radio, "fm");1127	tda18271_update_std(atv_b,  "atv b");1128	tda18271_update_std(atv_dk, "atv dk");1129	tda18271_update_std(atv_gh, "atv gh");1130	tda18271_update_std(atv_i,  "atv i");1131	tda18271_update_std(atv_l,  "atv l");1132	tda18271_update_std(atv_lc, "atv l'");1133	tda18271_update_std(atv_mn, "atv mn");1134	tda18271_update_std(atsc_6, "atsc 6");1135	tda18271_update_std(dvbt_6, "dvbt 6");1136	tda18271_update_std(dvbt_7, "dvbt 7");1137	tda18271_update_std(dvbt_8, "dvbt 8");1138	tda18271_update_std(qam_6,  "qam 6");1139	tda18271_update_std(qam_7,  "qam 7");1140	tda18271_update_std(qam_8,  "qam 8");1141 1142	return 0;1143}1144 1145static int tda18271_get_id(struct dvb_frontend *fe)1146{1147	struct tda18271_priv *priv = fe->tuner_priv;1148	unsigned char *regs = priv->tda18271_regs;1149	char *name;1150	int ret;1151 1152	mutex_lock(&priv->lock);1153	ret = tda18271_read_regs(fe);1154	mutex_unlock(&priv->lock);1155 1156	if (ret) {1157		tda_info("Error reading device ID @ %d-%04x, bailing out.\n",1158			 i2c_adapter_id(priv->i2c_props.adap),1159			 priv->i2c_props.addr);1160		return -EIO;1161	}1162 1163	switch (regs[R_ID] & 0x7f) {1164	case 3:1165		name = "TDA18271HD/C1";1166		priv->id = TDA18271HDC1;1167		break;1168	case 4:1169		name = "TDA18271HD/C2";1170		priv->id = TDA18271HDC2;1171		break;1172	default:1173		tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",1174			 regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),1175			 priv->i2c_props.addr);1176		return -EINVAL;1177	}1178 1179	tda_info("%s detected @ %d-%04x\n", name,1180		 i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);1181 1182	return 0;1183}1184 1185static int tda18271_setup_configuration(struct dvb_frontend *fe,1186					struct tda18271_config *cfg)1187{1188	struct tda18271_priv *priv = fe->tuner_priv;1189 1190	priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;1191	priv->role = (cfg) ? cfg->role : TDA18271_MASTER;1192	priv->config = (cfg) ? cfg->config : 0;1193	priv->small_i2c = (cfg) ?1194		cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;1195	priv->output_opt = (cfg) ?1196		cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;1197 1198	return 0;1199}1200 1201static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)1202{1203	/* tda18271_cal_on_startup == -1 when cal module option is unset */1204	return ((tda18271_cal_on_startup == -1) ?1205		/* honor configuration setting */1206		((cfg) && (cfg->rf_cal_on_startup)) :1207		/* module option overrides configuration setting */1208		(tda18271_cal_on_startup)) ? 1 : 0;1209}1210 1211static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)1212{1213	struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;1214 1215	tda18271_setup_configuration(fe, cfg);1216 1217	if (tda18271_need_cal_on_startup(cfg))1218		tda18271_init(fe);1219 1220	/* override default std map with values in config struct */1221	if ((cfg) && (cfg->std_map))1222		tda18271_update_std_map(fe, cfg->std_map);1223 1224	return 0;1225}1226 1227static const struct dvb_tuner_ops tda18271_tuner_ops = {1228	.info = {1229		.name = "NXP TDA18271HD",1230		.frequency_min_hz  =  45 * MHz,1231		.frequency_max_hz  = 864 * MHz,1232		.frequency_step_hz = 625001233	},1234	.init              = tda18271_init,1235	.sleep             = tda18271_sleep,1236	.set_params        = tda18271_set_params,1237	.set_analog_params = tda18271_set_analog_params,1238	.release           = tda18271_release,1239	.set_config        = tda18271_set_config,1240	.get_frequency     = tda18271_get_frequency,1241	.get_bandwidth     = tda18271_get_bandwidth,1242	.get_if_frequency  = tda18271_get_if_frequency,1243};1244 1245struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,1246				     struct i2c_adapter *i2c,1247				     struct tda18271_config *cfg)1248{1249	struct tda18271_priv *priv = NULL;1250	int instance, ret;1251 1252	mutex_lock(&tda18271_list_mutex);1253 1254	instance = hybrid_tuner_request_state(struct tda18271_priv, priv,1255					      hybrid_tuner_instance_list,1256					      i2c, addr, "tda18271");1257	switch (instance) {1258	case 0:1259		goto fail;1260	case 1:1261		/* new tuner instance */1262		fe->tuner_priv = priv;1263 1264		tda18271_setup_configuration(fe, cfg);1265 1266		priv->cal_initialized = false;1267		mutex_init(&priv->lock);1268 1269		ret = tda18271_get_id(fe);1270		if (tda_fail(ret))1271			goto fail;1272 1273		ret = tda18271_assign_map_layout(fe);1274		if (tda_fail(ret))1275			goto fail;1276 1277		/* if delay_cal is set, delay IR & RF calibration until init()1278		 * module option 'cal' overrides this delay */1279		if ((cfg->delay_cal) && (!tda18271_need_cal_on_startup(cfg)))1280			break;1281 1282		mutex_lock(&priv->lock);1283		tda18271_init_regs(fe);1284 1285		if ((tda18271_need_cal_on_startup(cfg)) &&1286		    (priv->id == TDA18271HDC2))1287			tda18271c2_rf_cal_init(fe);1288 1289		/* enter standby mode, with required output features enabled */1290		ret = tda18271_toggle_output(fe, 1);1291		tda_fail(ret);1292 1293		mutex_unlock(&priv->lock);1294		break;1295	default:1296		/* existing tuner instance */1297		fe->tuner_priv = priv;1298 1299		/* allow dvb driver to override configuration settings */1300		if (cfg) {1301			if (cfg->gate != TDA18271_GATE_ANALOG)1302				priv->gate = cfg->gate;1303			if (cfg->role)1304				priv->role = cfg->role;1305			if (cfg->config)1306				priv->config = cfg->config;1307			if (cfg->small_i2c)1308				priv->small_i2c = cfg->small_i2c;1309			if (cfg->output_opt)1310				priv->output_opt = cfg->output_opt;1311			if (cfg->std_map)1312				tda18271_update_std_map(fe, cfg->std_map);1313		}1314		if (tda18271_need_cal_on_startup(cfg))1315			tda18271_init(fe);1316		break;1317	}1318 1319	/* override default std map with values in config struct */1320	if ((cfg) && (cfg->std_map))1321		tda18271_update_std_map(fe, cfg->std_map);1322 1323	mutex_unlock(&tda18271_list_mutex);1324 1325	memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,1326	       sizeof(struct dvb_tuner_ops));1327 1328	if (tda18271_debug & (DBG_MAP | DBG_ADV))1329		tda18271_dump_std_map(fe);1330 1331	return fe;1332fail:1333	mutex_unlock(&tda18271_list_mutex);1334 1335	tda18271_release(fe);1336	return NULL;1337}1338EXPORT_SYMBOL_GPL(tda18271_attach);1339MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");1340MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");1341MODULE_LICENSE("GPL");1342MODULE_VERSION("0.4");1343