File Index
Files and directories
Sign in
FILE

tda18271-fe.c

File preview with syntax highlighting.

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