dvb_frontend.c 66.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * dvb_frontend.c: DVB frontend tuning interface/thread
 *
 *
 * Copyright (C) 1999-2001 Ralph  Metzler
 *			   Marcus Metzler
 *			   Holger Waechtler
 *				      for convergence integrated media GmbH
 *
 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

28 29 30
/* Enables DVBv3 compatibility bits at the headers */
#define __DVB_CORE__

L
Linus Torvalds 已提交
31 32 33 34 35 36
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/poll.h>
37
#include <linux/semaphore.h>
L
Linus Torvalds 已提交
38 39
#include <linux/module.h>
#include <linux/list.h>
40
#include <linux/freezer.h>
41
#include <linux/jiffies.h>
42
#include <linux/kthread.h>
L
Linus Torvalds 已提交
43 44 45 46
#include <asm/processor.h>

#include "dvb_frontend.h"
#include "dvbdev.h"
47
#include <linux/dvb/version.h>
L
Linus Torvalds 已提交
48 49

static int dvb_frontend_debug;
50
static int dvb_shutdown_timeout;
L
Linus Torvalds 已提交
51 52 53
static int dvb_force_auto_inversion;
static int dvb_override_tune_delay;
static int dvb_powerdown_on_sleep = 1;
54
static int dvb_mfe_wait_time = 5;
L
Linus Torvalds 已提交
55 56

module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
57
MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
58
module_param(dvb_shutdown_timeout, int, 0644);
L
Linus Torvalds 已提交
59
MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
60
module_param(dvb_force_auto_inversion, int, 0644);
L
Linus Torvalds 已提交
61
MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
62
module_param(dvb_override_tune_delay, int, 0644);
L
Linus Torvalds 已提交
63
MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
64
module_param(dvb_powerdown_on_sleep, int, 0644);
65
MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
66 67
module_param(dvb_mfe_wait_time, int, 0644);
MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
L
Linus Torvalds 已提交
68 69 70 71 72 73 74 75 76 77 78

#define dprintk if (dvb_frontend_debug) printk

#define FESTATE_IDLE 1
#define FESTATE_RETUNE 2
#define FESTATE_TUNING_FAST 4
#define FESTATE_TUNING_SLOW 8
#define FESTATE_TUNED 16
#define FESTATE_ZIGZAG_FAST 32
#define FESTATE_ZIGZAG_SLOW 64
#define FESTATE_DISEQC 128
79
#define FESTATE_ERROR 256
L
Linus Torvalds 已提交
80 81 82 83
#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
84 85

#define FE_ALGO_HW		1
L
Linus Torvalds 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/*
 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.
 * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress.
 * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower.
 * FESTATE_TUNED. The frontend has successfully locked on.
 * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it.
 * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower.
 * FESTATE_DISEQC. A DISEQC command has just been issued.
 * FESTATE_WAITFORLOCK. When we're waiting for a lock.
 * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan.
 * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan.
 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
 */

101 102 103 104
#define DVB_FE_NO_EXIT	0
#define DVB_FE_NORMAL_EXIT	1
#define DVB_FE_DEVICE_REMOVED	2

105
static DEFINE_MUTEX(frontend_mutex);
L
Linus Torvalds 已提交
106 107 108

struct dvb_frontend_private {

109
	/* thread/frontend values */
L
Linus Torvalds 已提交
110
	struct dvb_device *dvbdev;
111
	struct dvb_frontend_parameters parameters_out;
L
Linus Torvalds 已提交
112 113 114 115
	struct dvb_fe_events events;
	struct semaphore sem;
	struct list_head list_head;
	wait_queue_head_t wait_queue;
116
	struct task_struct *thread;
L
Linus Torvalds 已提交
117
	unsigned long release_jiffies;
118 119
	unsigned int exit;
	unsigned int wakeup;
L
Linus Torvalds 已提交
120
	fe_status_t status;
121
	unsigned long tune_mode_flags;
122
	unsigned int delay;
123
	unsigned int reinitialise;
124 125
	int tone;
	int voltage;
126 127 128 129 130 131 132 133 134 135 136 137 138 139

	/* swzigzag values */
	unsigned int state;
	unsigned int bending;
	int lnb_drift;
	unsigned int inversion;
	unsigned int auto_step;
	unsigned int auto_sub_step;
	unsigned int started_auto_step;
	unsigned int min_delay;
	unsigned int max_drift;
	unsigned int step_size;
	int quality;
	unsigned int check_wrapped;
M
Manu Abraham 已提交
140
	enum dvbfe_search algo_status;
L
Linus Torvalds 已提交
141 142
};

143
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
144 145
static int dtv_get_frontend(struct dvb_frontend *fe,
			    struct dvb_frontend_parameters *p_out);
146 147
static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
					   struct dvb_frontend_parameters *p);
148 149 150

static bool has_get_frontend(struct dvb_frontend *fe)
{
151
	return fe->ops.get_frontend != NULL;
152
}
L
Linus Torvalds 已提交
153

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/*
 * Due to DVBv3 API calls, a delivery system should be mapped into one of
 * the 4 DVBv3 delivery systems (FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC),
 * otherwise, a DVBv3 call will fail.
 */
enum dvbv3_emulation_type {
	DVBV3_UNKNOWN,
	DVBV3_QPSK,
	DVBV3_QAM,
	DVBV3_OFDM,
	DVBV3_ATSC,
};

static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system)
{
	switch (delivery_system) {
	case SYS_DVBC_ANNEX_A:
	case SYS_DVBC_ANNEX_C:
		return DVBV3_QAM;
	case SYS_DVBS:
	case SYS_DVBS2:
	case SYS_TURBO:
	case SYS_ISDBS:
	case SYS_DSS:
		return DVBV3_QPSK;
	case SYS_DVBT:
	case SYS_DVBT2:
	case SYS_ISDBT:
	case SYS_DMBTH:
		return DVBV3_OFDM;
	case SYS_ATSC:
	case SYS_DVBC_ANNEX_B:
		return DVBV3_ATSC;
	case SYS_UNDEFINED:
	case SYS_ISDBC:
	case SYS_DVBH:
	case SYS_DAB:
	case SYS_ATSCMH:
	default:
		/*
		 * Doesn't know how to emulate those types and/or
		 * there's no frontend driver from this type yet
		 * with some emulation code, so, we're not sure yet how
		 * to handle them, or they're not compatible with a DVBv3 call.
		 */
		return DVBV3_UNKNOWN;
	}
}

L
Linus Torvalds 已提交
203 204
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
{
205
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
206 207 208 209
	struct dvb_fe_events *events = &fepriv->events;
	struct dvb_frontend_event *e;
	int wp;

210
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
211

212
	if ((status & FE_HAS_LOCK) && has_get_frontend(fe))
213
		dtv_get_frontend(fe, &fepriv->parameters_out);
L
Linus Torvalds 已提交
214

215
	mutex_lock(&events->mtx);
L
Linus Torvalds 已提交
216

217
	wp = (events->eventw + 1) % MAX_EVENT;
L
Linus Torvalds 已提交
218 219 220 221 222 223
	if (wp == events->eventr) {
		events->overflow = 1;
		events->eventr = (events->eventr + 1) % MAX_EVENT;
	}

	e = &events->events[events->eventw];
224
	e->status = status;
225
	e->parameters = fepriv->parameters_out;
L
Linus Torvalds 已提交
226 227 228

	events->eventw = wp;

229
	mutex_unlock(&events->mtx);
L
Linus Torvalds 已提交
230 231 232 233 234 235 236

	wake_up_interruptible (&events->wait_queue);
}

static int dvb_frontend_get_event(struct dvb_frontend *fe,
			    struct dvb_frontend_event *event, int flags)
{
237
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
238 239
	struct dvb_fe_events *events = &fepriv->events;

240
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264

	if (events->overflow) {
		events->overflow = 0;
		return -EOVERFLOW;
	}

	if (events->eventw == events->eventr) {
		int ret;

		if (flags & O_NONBLOCK)
			return -EWOULDBLOCK;

		up(&fepriv->sem);

		ret = wait_event_interruptible (events->wait_queue,
						events->eventw != events->eventr);

		if (down_interruptible (&fepriv->sem))
			return -ERESTARTSYS;

		if (ret < 0)
			return ret;
	}

265 266
	mutex_lock(&events->mtx);
	*event = events->events[events->eventr];
L
Linus Torvalds 已提交
267
	events->eventr = (events->eventr + 1) % MAX_EVENT;
268
	mutex_unlock(&events->mtx);
L
Linus Torvalds 已提交
269 270 271 272

	return 0;
}

273 274 275 276 277 278 279 280 281 282
static void dvb_frontend_clear_events(struct dvb_frontend *fe)
{
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	struct dvb_fe_events *events = &fepriv->events;

	mutex_lock(&events->mtx);
	events->eventr = events->eventw;
	mutex_unlock(&events->mtx);
}

L
Linus Torvalds 已提交
283 284
static void dvb_frontend_init(struct dvb_frontend *fe)
{
285
	dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
L
Linus Torvalds 已提交
286
		 fe->dvb->num,
287
		 fe->id,
288 289 290 291 292
		 fe->ops.info.name);

	if (fe->ops.init)
		fe->ops.init(fe);
	if (fe->ops.tuner_ops.init) {
293 294
		if (fe->ops.i2c_gate_ctrl)
			fe->ops.i2c_gate_ctrl(fe, 1);
295 296 297
		fe->ops.tuner_ops.init(fe);
		if (fe->ops.i2c_gate_ctrl)
			fe->ops.i2c_gate_ctrl(fe, 0);
298
	}
L
Linus Torvalds 已提交
299 300
}

301 302 303 304 305 306 307 308 309
void dvb_frontend_reinitialise(struct dvb_frontend *fe)
{
	struct dvb_frontend_private *fepriv = fe->frontend_priv;

	fepriv->reinitialise = 1;
	dvb_frontend_wakeup(fe);
}
EXPORT_SYMBOL(dvb_frontend_reinitialise);

310
static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
L
Linus Torvalds 已提交
311
{
312
	int q2;
L
Linus Torvalds 已提交
313

314
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
315

316 317 318 319
	if (locked)
		(fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
	else
		(fepriv->quality) = (fepriv->quality * 220 + 0) / 256;
L
Linus Torvalds 已提交
320

321 322
	q2 = fepriv->quality - 128;
	q2 *= q2;
L
Linus Torvalds 已提交
323

324
	fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128);
L
Linus Torvalds 已提交
325 326 327 328 329 330 331 332 333
}

/**
 * Performs automatic twiddling of frontend parameters.
 *
 * @param fe The frontend concerned.
 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
 * @returns Number of complete iterations that have been performed.
 */
334
static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped)
L
Linus Torvalds 已提交
335 336 337
{
	int autoinversion;
	int ready = 0;
338
	int fe_set_err = 0;
339
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
340 341 342
	struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
	int original_inversion = c->inversion;
	u32 original_frequency = c->frequency;
L
Linus Torvalds 已提交
343 344

	/* are we using autoinversion? */
345
	autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
346
			 (c->inversion == INVERSION_AUTO));
L
Linus Torvalds 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407

	/* setup parameters correctly */
	while(!ready) {
		/* calculate the lnb_drift */
		fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size;

		/* wrap the auto_step if we've exceeded the maximum drift */
		if (fepriv->lnb_drift > fepriv->max_drift) {
			fepriv->auto_step = 0;
			fepriv->auto_sub_step = 0;
			fepriv->lnb_drift = 0;
		}

		/* perform inversion and +/- zigzag */
		switch(fepriv->auto_sub_step) {
		case 0:
			/* try with the current inversion and current drift setting */
			ready = 1;
			break;

		case 1:
			if (!autoinversion) break;

			fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
			ready = 1;
			break;

		case 2:
			if (fepriv->lnb_drift == 0) break;

			fepriv->lnb_drift = -fepriv->lnb_drift;
			ready = 1;
			break;

		case 3:
			if (fepriv->lnb_drift == 0) break;
			if (!autoinversion) break;

			fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
			fepriv->lnb_drift = -fepriv->lnb_drift;
			ready = 1;
			break;

		default:
			fepriv->auto_step++;
			fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
			break;
		}

		if (!ready) fepriv->auto_sub_step++;
	}

	/* if this attempt would hit where we started, indicate a complete
	 * iteration has occurred */
	if ((fepriv->auto_step == fepriv->started_auto_step) &&
	    (fepriv->auto_sub_step == 0) && check_wrapped) {
		return 1;
	}

	dprintk("%s: drift:%i inversion:%i auto_step:%i "
		"auto_sub_step:%i started_auto_step:%i\n",
408
		__func__, fepriv->lnb_drift, fepriv->inversion,
L
Linus Torvalds 已提交
409 410 411
		fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);

	/* set the frontend itself */
412
	c->frequency += fepriv->lnb_drift;
L
Linus Torvalds 已提交
413
	if (autoinversion)
414 415
		c->inversion = fepriv->inversion;
	tmp = *c;
416
	if (fe->ops.set_frontend)
417
		fe_set_err = fe->ops.set_frontend(fe);
418
	*c = tmp;
419 420 421 422
	if (fe_set_err < 0) {
		fepriv->state = FESTATE_ERROR;
		return fe_set_err;
	}
L
Linus Torvalds 已提交
423

424 425
	c->frequency = original_frequency;
	c->inversion = original_inversion;
L
Linus Torvalds 已提交
426 427 428 429 430

	fepriv->auto_sub_step++;
	return 0;
}

431 432
static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
{
433
	fe_status_t s = 0;
434
	int retval = 0;
435
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
436
	struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
437 438 439 440 441 442 443 444 445 446 447

	/* if we've got no parameters, just keep idling */
	if (fepriv->state & FESTATE_IDLE) {
		fepriv->delay = 3*HZ;
		fepriv->quality = 0;
		return;
	}

	/* in SCAN mode, we just set the frontend when asked and leave it alone */
	if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
		if (fepriv->state & FESTATE_RETUNE) {
448
			tmp = *c;
449
			if (fe->ops.set_frontend)
450
				retval = fe->ops.set_frontend(fe);
451
			*c = tmp;
452 453 454 455
			if (retval < 0)
				fepriv->state = FESTATE_ERROR;
			else
				fepriv->state = FESTATE_TUNED;
456 457 458 459 460 461 462 463 464 465
		}
		fepriv->delay = 3*HZ;
		fepriv->quality = 0;
		return;
	}

	/* get the frontend status */
	if (fepriv->state & FESTATE_RETUNE) {
		s = 0;
	} else {
466 467
		if (fe->ops.read_status)
			fe->ops.read_status(fe, &s);
468 469 470 471 472 473 474 475 476 477 478 479
		if (s != fepriv->status) {
			dvb_frontend_add_event(fe, s);
			fepriv->status = s;
		}
	}

	/* if we're not tuned, and we have a lock, move to the TUNED state */
	if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
		fepriv->state = FESTATE_TUNED;

		/* if we're tuned, then we have determined the correct inversion */
480
		if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
481 482
		    (c->inversion == INVERSION_AUTO)) {
			c->inversion = fepriv->inversion;
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
		}
		return;
	}

	/* if we are tuned already, check we're still locked */
	if (fepriv->state & FESTATE_TUNED) {
		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);

		/* we're tuned, and the lock is still good... */
		if (s & FE_HAS_LOCK) {
			return;
		} else { /* if we _WERE_ tuned, but now don't have a lock */
			fepriv->state = FESTATE_ZIGZAG_FAST;
			fepriv->started_auto_step = fepriv->auto_step;
			fepriv->check_wrapped = 0;
		}
	}

	/* don't actually do anything if we're in the LOSTLOCK state,
	 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
	if ((fepriv->state & FESTATE_LOSTLOCK) &&
504
	    (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
		return;
	}

	/* don't do anything if we're in the DISEQC state, since this
	 * might be someone with a motorized dish controlled by DISEQC.
	 * If its actually a re-tune, there will be a SET_FRONTEND soon enough.	*/
	if (fepriv->state & FESTATE_DISEQC) {
		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
		return;
	}

	/* if we're in the RETUNE state, set everything up for a brand
	 * new scan, keeping the current inversion setting, as the next
	 * tune is _very_ likely to require the same */
	if (fepriv->state & FESTATE_RETUNE) {
		fepriv->lnb_drift = 0;
		fepriv->auto_step = 0;
		fepriv->auto_sub_step = 0;
		fepriv->started_auto_step = 0;
		fepriv->check_wrapped = 0;
	}

	/* fast zigzag. */
	if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
		fepriv->delay = fepriv->min_delay;

532
		/* perform a tune */
533 534 535 536 537
		retval = dvb_frontend_swzigzag_autotune(fe,
							fepriv->check_wrapped);
		if (retval < 0) {
			return;
		} else if (retval) {
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
			/* OK, if we've run out of trials at the fast speed.
			 * Drop back to slow for the _next_ attempt */
			fepriv->state = FESTATE_SEARCHING_SLOW;
			fepriv->started_auto_step = fepriv->auto_step;
			return;
		}
		fepriv->check_wrapped = 1;

		/* if we've just retuned, enter the ZIGZAG_FAST state.
		 * This ensures we cannot return from an
		 * FE_SET_FRONTEND ioctl before the first frontend tune
		 * occurs */
		if (fepriv->state & FESTATE_RETUNE) {
			fepriv->state = FESTATE_TUNING_FAST;
		}
	}

	/* slow zigzag */
	if (fepriv->state & FESTATE_SEARCHING_SLOW) {
		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);

		/* Note: don't bother checking for wrapping; we stay in this
		 * state until we get a lock */
		dvb_frontend_swzigzag_autotune(fe, 0);
	}
}

L
Linus Torvalds 已提交
565 566
static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
{
567
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
568

569
	if (fepriv->exit != DVB_FE_NO_EXIT)
L
Linus Torvalds 已提交
570 571 572
		return 1;

	if (fepriv->dvbdev->writers == 1)
573
		if (time_after_eq(jiffies, fepriv->release_jiffies +
574
				  dvb_shutdown_timeout * HZ))
L
Linus Torvalds 已提交
575 576 577 578 579 580 581
			return 1;

	return 0;
}

static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
{
582
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
583 584 585 586 587 588 589 590 591 592

	if (fepriv->wakeup) {
		fepriv->wakeup = 0;
		return 1;
	}
	return dvb_frontend_is_exiting(fe);
}

static void dvb_frontend_wakeup(struct dvb_frontend *fe)
{
593
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
594 595 596 597 598 599 600

	fepriv->wakeup = 1;
	wake_up_interruptible(&fepriv->wait_queue);
}

static int dvb_frontend_thread(void *data)
{
601 602
	struct dvb_frontend *fe = data;
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
603
	fe_status_t s;
M
Manu Abraham 已提交
604 605
	enum dvbfe_algo algo;

606
	bool re_tune = false;
L
Linus Torvalds 已提交
607

608
	dprintk("%s\n", __func__);
L
Linus Torvalds 已提交
609

610 611 612
	fepriv->check_wrapped = 0;
	fepriv->quality = 0;
	fepriv->delay = 3*HZ;
L
Linus Torvalds 已提交
613 614
	fepriv->status = 0;
	fepriv->wakeup = 0;
615 616 617
	fepriv->reinitialise = 0;

	dvb_frontend_init(fe);
L
Linus Torvalds 已提交
618

619
	set_freezable();
L
Linus Torvalds 已提交
620 621
	while (1) {
		up(&fepriv->sem);	    /* is locked when we enter the thread... */
622
restart:
623
		wait_event_interruptible_timeout(fepriv->wait_queue,
624 625
			dvb_frontend_should_wakeup(fe) || kthread_should_stop()
				|| freezing(current),
626 627 628
			fepriv->delay);

		if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
L
Linus Torvalds 已提交
629
			/* got signal or quitting */
630
			fepriv->exit = DVB_FE_NORMAL_EXIT;
L
Linus Torvalds 已提交
631 632 633
			break;
		}

634
		if (try_to_freeze())
635
			goto restart;
L
Linus Torvalds 已提交
636 637 638 639

		if (down_interruptible(&fepriv->sem))
			break;

640 641
		if (fepriv->reinitialise) {
			dvb_frontend_init(fe);
642
			if (fe->ops.set_tone && fepriv->tone != -1)
643
				fe->ops.set_tone(fe, fepriv->tone);
644
			if (fe->ops.set_voltage && fepriv->voltage != -1)
645
				fe->ops.set_voltage(fe, fepriv->voltage);
646 647 648
			fepriv->reinitialise = 0;
		}

649
		/* do an iteration of the tuning loop */
650
		if (fe->ops.get_frontend_algo) {
M
Manu Abraham 已提交
651 652 653 654 655
			algo = fe->ops.get_frontend_algo(fe);
			switch (algo) {
			case DVBFE_ALGO_HW:
				dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);

656
				if (fepriv->state & FESTATE_RETUNE) {
M
Manu Abraham 已提交
657
					dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
658
					re_tune = true;
659
					fepriv->state = FESTATE_TUNED;
660 661
				} else {
					re_tune = false;
662 663
				}

M
Manu Abraham 已提交
664
				if (fe->ops.tune)
665
					fe->ops.tune(fe, re_tune, fepriv->tune_mode_flags, &fepriv->delay, &s);
M
Manu Abraham 已提交
666

667
				if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
M
Manu Abraham 已提交
668
					dprintk("%s: state changed, adding current state\n", __func__);
669 670 671
					dvb_frontend_add_event(fe, s);
					fepriv->status = s;
				}
M
Manu Abraham 已提交
672 673 674
				break;
			case DVBFE_ALGO_SW:
				dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
675
				dvb_frontend_swzigzag(fe);
M
Manu Abraham 已提交
676 677 678 679 680 681 682 683 684 685 686 687
				break;
			case DVBFE_ALGO_CUSTOM:
				dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
				if (fepriv->state & FESTATE_RETUNE) {
					dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
					fepriv->state = FESTATE_TUNED;
				}
				/* Case where we are going to search for a carrier
				 * User asked us to retune again for some reason, possibly
				 * requesting a search with a new set of parameters
				 */
				if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
688
					if (fe->ops.search) {
689
						fepriv->algo_status = fe->ops.search(fe);
M
Manu Abraham 已提交
690 691 692
						/* We did do a search as was requested, the flags are
						 * now unset as well and has the flags wrt to search.
						 */
693 694 695
					} else {
						fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
					}
M
Manu Abraham 已提交
696 697
				}
				/* Track the carrier if the search was successful */
698
				if (fepriv->algo_status != DVBFE_ALGO_SEARCH_SUCCESS) {
699 700 701
					fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
					fepriv->delay = HZ / 2;
				}
702
				dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
703 704 705 706 707 708 709 710 711 712
				fe->ops.read_status(fe, &s);
				if (s != fepriv->status) {
					dvb_frontend_add_event(fe, s); /* update event list */
					fepriv->status = s;
					if (!(s & FE_HAS_LOCK)) {
						fepriv->delay = HZ / 10;
						fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
					} else {
						fepriv->delay = 60 * HZ;
					}
M
Manu Abraham 已提交
713 714 715 716 717 718 719
				}
				break;
			default:
				dprintk("%s: UNDEFINED ALGO !\n", __func__);
				break;
			}
		} else {
720
			dvb_frontend_swzigzag(fe);
M
Manu Abraham 已提交
721
		}
L
Linus Torvalds 已提交
722 723
	}

724 725 726
	if (dvb_powerdown_on_sleep) {
		if (fe->ops.set_voltage)
			fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
727
		if (fe->ops.tuner_ops.sleep) {
728 729
			if (fe->ops.i2c_gate_ctrl)
				fe->ops.i2c_gate_ctrl(fe, 1);
730 731 732
			fe->ops.tuner_ops.sleep(fe);
			if (fe->ops.i2c_gate_ctrl)
				fe->ops.i2c_gate_ctrl(fe, 0);
733
		}
734 735
		if (fe->ops.sleep)
			fe->ops.sleep(fe);
L
Linus Torvalds 已提交
736 737
	}

738
	fepriv->thread = NULL;
739 740 741 742
	if (kthread_should_stop())
		fepriv->exit = DVB_FE_DEVICE_REMOVED;
	else
		fepriv->exit = DVB_FE_NO_EXIT;
L
Linus Torvalds 已提交
743 744 745 746 747 748 749 750
	mb();

	dvb_frontend_wakeup(fe);
	return 0;
}

static void dvb_frontend_stop(struct dvb_frontend *fe)
{
751
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
752

753
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
754

755
	fepriv->exit = DVB_FE_NORMAL_EXIT;
L
Linus Torvalds 已提交
756 757
	mb();

758
	if (!fepriv->thread)
L
Linus Torvalds 已提交
759 760
		return;

761
	kthread_stop(fepriv->thread);
762

763
	sema_init(&fepriv->sem, 1);
L
Linus Torvalds 已提交
764 765 766
	fepriv->state = FESTATE_IDLE;

	/* paranoia check in case a signal arrived */
767 768 769
	if (fepriv->thread)
		printk("dvb_frontend_stop: warning: thread %p won't exit\n",
				fepriv->thread);
L
Linus Torvalds 已提交
770 771
}

772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
{
	return ((curtime.tv_usec < lasttime.tv_usec) ?
		1000000 - lasttime.tv_usec + curtime.tv_usec :
		curtime.tv_usec - lasttime.tv_usec);
}
EXPORT_SYMBOL(timeval_usec_diff);

static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
{
	curtime->tv_usec += add_usec;
	if (curtime->tv_usec >= 1000000) {
		curtime->tv_usec -= 1000000;
		curtime->tv_sec++;
	}
}

/*
 * Sleep until gettimeofday() > waketime + add_usec
 * This needs to be as precise as possible, but as the delay is
 * usually between 2ms and 32ms, it is done using a scheduled msleep
 * followed by usleep (normally a busy-wait loop) for the remainder
 */
void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
{
	struct timeval lasttime;
	s32 delta, newdelta;

	timeval_usec_add(waketime, add_usec);

	do_gettimeofday(&lasttime);
	delta = timeval_usec_diff(lasttime, *waketime);
	if (delta > 2500) {
		msleep((delta - 1500) / 1000);
		do_gettimeofday(&lasttime);
		newdelta = timeval_usec_diff(lasttime, *waketime);
		delta = (newdelta > delta) ? 0 : newdelta;
	}
	if (delta > 0)
		udelay(delta);
}
EXPORT_SYMBOL(dvb_frontend_sleep_until);

L
Linus Torvalds 已提交
815 816 817
static int dvb_frontend_start(struct dvb_frontend *fe)
{
	int ret;
818
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
819
	struct task_struct *fe_thread;
L
Linus Torvalds 已提交
820

821
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
822

823
	if (fepriv->thread) {
824
		if (fepriv->exit == DVB_FE_NO_EXIT)
L
Linus Torvalds 已提交
825 826 827 828 829 830 831 832 833 834 835
			return 0;
		else
			dvb_frontend_stop (fe);
	}

	if (signal_pending(current))
		return -EINTR;
	if (down_interruptible (&fepriv->sem))
		return -EINTR;

	fepriv->state = FESTATE_IDLE;
836
	fepriv->exit = DVB_FE_NO_EXIT;
837
	fepriv->thread = NULL;
L
Linus Torvalds 已提交
838 839
	mb();

840
	fe_thread = kthread_run(dvb_frontend_thread, fe,
841
		"kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
842 843 844
	if (IS_ERR(fe_thread)) {
		ret = PTR_ERR(fe_thread);
		printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
L
Linus Torvalds 已提交
845 846 847
		up(&fepriv->sem);
		return ret;
	}
848
	fepriv->thread = fe_thread;
L
Linus Torvalds 已提交
849 850 851
	return 0;
}

852
static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
853 854 855 856 857 858 859 860 861 862 863 864
					u32 *freq_min, u32 *freq_max)
{
	*freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min);

	if (fe->ops.info.frequency_max == 0)
		*freq_max = fe->ops.tuner_ops.info.frequency_max;
	else if (fe->ops.tuner_ops.info.frequency_max == 0)
		*freq_max = fe->ops.info.frequency_max;
	else
		*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);

	if (*freq_min == 0 || *freq_max == 0)
865 866
		printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
		       fe->dvb->num,fe->id);
867 868
}

869
static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
870
{
871
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
872 873 874
	u32 freq_min;
	u32 freq_max;

875
	/* range check: frequency */
876
	dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max);
877 878
	if ((freq_min && c->frequency < freq_min) ||
	    (freq_max && c->frequency > freq_max)) {
879
		printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
880
		       fe->dvb->num, fe->id, c->frequency, freq_min, freq_max);
881 882 883 884
		return -EINVAL;
	}

	/* range check: symbol rate */
885 886 887 888 889 890
	switch (c->delivery_system) {
	case SYS_DVBS:
	case SYS_DVBS2:
	case SYS_TURBO:
	case SYS_DVBC_ANNEX_A:
	case SYS_DVBC_ANNEX_C:
891
		if ((fe->ops.info.symbol_rate_min &&
892
		     c->symbol_rate < fe->ops.info.symbol_rate_min) ||
893
		    (fe->ops.info.symbol_rate_max &&
894
		     c->symbol_rate > fe->ops.info.symbol_rate_max)) {
895
			printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
896 897 898
			       fe->dvb->num, fe->id, c->symbol_rate,
			       fe->ops.info.symbol_rate_min,
			       fe->ops.info.symbol_rate_max);
899 900
			return -EINVAL;
		}
901 902
	default:
		break;
903 904 905 906 907
	}

	return 0;
}

908 909
static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
{
910
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
911
	int i;
912
	u32 delsys;
913

914
	delsys = c->delivery_system;
915
	memset(c, 0, sizeof(struct dtv_frontend_properties));
916
	c->delivery_system = delsys;
917 918

	c->state = DTV_CLEAR;
919

920 921
	dprintk("%s() Clearing cache for delivery system %d\n", __func__,
		c->delivery_system);
922

923
	c->transmission_mode = TRANSMISSION_MODE_AUTO;
924
	c->bandwidth_hz = 0;	/* AUTO */
925 926
	c->guard_interval = GUARD_INTERVAL_AUTO;
	c->hierarchy = HIERARCHY_AUTO;
927
	c->symbol_rate = 0;
928 929
	c->code_rate_HP = FEC_AUTO;
	c->code_rate_LP = FEC_AUTO;
930
	c->fec_inner = FEC_AUTO;
931
	c->rolloff = ROLLOFF_AUTO;
932 933 934
	c->voltage = SEC_VOLTAGE_OFF;
	c->sectone = SEC_TONE_OFF;
	c->pilot = PILOT_AUTO;
935

936 937 938 939 940 941
	c->isdbt_partial_reception = 0;
	c->isdbt_sb_mode = 0;
	c->isdbt_sb_subchannel = 0;
	c->isdbt_sb_segment_idx = 0;
	c->isdbt_sb_segment_count = 0;
	c->isdbt_layer_enabled = 0;
942
	for (i = 0; i < 3; i++) {
943 944
		c->layer[i].fec = FEC_AUTO;
		c->layer[i].modulation = QAM_AUTO;
945 946
		c->layer[i].interleaving = 0;
		c->layer[i].segment_count = 0;
947 948
	}

949 950 951
	c->isdbs_ts_id = 0;
	c->dvbt2_plp_id = 0;

952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
	switch (c->delivery_system) {
	case SYS_DVBS:
	case SYS_DVBS2:
	case SYS_TURBO:
		c->modulation = QPSK;   /* implied for DVB-S in legacy API */
		c->rolloff = ROLLOFF_35;/* implied for DVB-S */
		break;
	case SYS_ATSC:
		c->modulation = VSB_8;
		break;
	default:
		c->modulation = QAM_AUTO;
		break;
	}

967 968 969 970 971 972 973 974 975 976 977
	return 0;
}

#define _DTV_CMD(n, s, b) \
[n] = { \
	.name = #n, \
	.cmd  = n, \
	.set  = s,\
	.buffer = b \
}

978
static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
979 980
	_DTV_CMD(DTV_TUNE, 1, 0),
	_DTV_CMD(DTV_CLEAR, 1, 0),
981 982

	/* Set */
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
	_DTV_CMD(DTV_FREQUENCY, 1, 0),
	_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
	_DTV_CMD(DTV_MODULATION, 1, 0),
	_DTV_CMD(DTV_INVERSION, 1, 0),
	_DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
	_DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
	_DTV_CMD(DTV_INNER_FEC, 1, 0),
	_DTV_CMD(DTV_VOLTAGE, 1, 0),
	_DTV_CMD(DTV_TONE, 1, 0),
	_DTV_CMD(DTV_PILOT, 1, 0),
	_DTV_CMD(DTV_ROLLOFF, 1, 0),
	_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
	_DTV_CMD(DTV_HIERARCHY, 1, 0),
	_DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
	_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
	_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
	_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
1000 1001 1002 1003 1004 1005

	_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
	_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
	_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
1006
	_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
	_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
	_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),

1020
	_DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
1021
	_DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0),
1022

1023
	/* Get */
1024 1025 1026 1027 1028 1029 1030
	_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
	_DTV_CMD(DTV_API_VERSION, 0, 0),
	_DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
	_DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
	_DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
	_DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
	_DTV_CMD(DTV_HIERARCHY, 0, 0),
1031 1032

	_DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
1033 1034
};

1035
static void dtv_property_dump(struct dtv_property *tvp)
1036 1037 1038
{
	int i;

1039
	if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
1040
		printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n",
1041 1042 1043 1044
			__func__, tvp->cmd);
		return;
	}

1045 1046
	dprintk("%s() tvp.cmd    = 0x%08x (%s)\n"
		,__func__
1047
		,tvp->cmd
1048
		,dtv_cmds[ tvp->cmd ].name);
1049

1050
	if(dtv_cmds[ tvp->cmd ].buffer) {
1051

1052 1053
		dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
			,__func__
1054 1055 1056
			,tvp->u.buffer.len);

		for(i = 0; i < tvp->u.buffer.len; i++)
1057 1058
			dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
				,__func__
1059 1060 1061 1062
				,i
				,tvp->u.buffer.data[i]);

	} else
1063
		dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data);
1064 1065
}

1066 1067 1068 1069
/* Synchronise the legacy tuning parameters into the cache, so that demodulator
 * drivers can use a single set_frontend tuning function, regardless of whether
 * it's being used for the legacy or new API, reducing code and complexity.
 */
1070 1071 1072
static int dtv_property_cache_sync(struct dvb_frontend *fe,
				   struct dtv_frontend_properties *c,
				   const struct dvb_frontend_parameters *p)
1073 1074 1075 1076
{
	c->frequency = p->frequency;
	c->inversion = p->inversion;

1077 1078 1079
	switch (dvbv3_type(c->delivery_system)) {
	case DVBV3_QPSK:
		dprintk("%s() Preparing QPSK req\n", __func__);
1080 1081 1082
		c->symbol_rate = p->u.qpsk.symbol_rate;
		c->fec_inner = p->u.qpsk.fec_inner;
		break;
1083 1084
	case DVBV3_QAM:
		dprintk("%s() Preparing QAM req\n", __func__);
1085 1086 1087 1088
		c->symbol_rate = p->u.qam.symbol_rate;
		c->fec_inner = p->u.qam.fec_inner;
		c->modulation = p->u.qam.modulation;
		break;
1089 1090
	case DVBV3_OFDM:
		dprintk("%s() Preparing OFDM req\n", __func__);
1091 1092 1093 1094 1095
		switch (p->u.ofdm.bandwidth) {
		case BANDWIDTH_10_MHZ:
			c->bandwidth_hz = 10000000;
			break;
		case BANDWIDTH_8_MHZ:
1096
			c->bandwidth_hz = 8000000;
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
			break;
		case BANDWIDTH_7_MHZ:
			c->bandwidth_hz = 7000000;
			break;
		case BANDWIDTH_6_MHZ:
			c->bandwidth_hz = 6000000;
			break;
		case BANDWIDTH_5_MHZ:
			c->bandwidth_hz = 5000000;
			break;
		case BANDWIDTH_1_712_MHZ:
			c->bandwidth_hz = 1712000;
			break;
		case BANDWIDTH_AUTO:
1111
			c->bandwidth_hz = 0;
1112 1113
		}

1114 1115 1116 1117 1118 1119 1120
		c->code_rate_HP = p->u.ofdm.code_rate_HP;
		c->code_rate_LP = p->u.ofdm.code_rate_LP;
		c->modulation = p->u.ofdm.constellation;
		c->transmission_mode = p->u.ofdm.transmission_mode;
		c->guard_interval = p->u.ofdm.guard_interval;
		c->hierarchy = p->u.ofdm.hierarchy_information;
		break;
1121 1122
	case DVBV3_ATSC:
		dprintk("%s() Preparing ATSC req\n", __func__);
1123
		c->modulation = p->u.vsb.modulation;
1124 1125 1126 1127
		if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
			c->delivery_system = SYS_ATSC;
		else
			c->delivery_system = SYS_DVBC_ANNEX_B;
1128
		break;
1129 1130 1131 1132 1133
	case DVBV3_UNKNOWN:
		printk(KERN_ERR
		       "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
		       __func__, c->delivery_system);
		return -EINVAL;
1134
	}
1135 1136

	return 0;
1137 1138
}

1139 1140 1141
/* Ensure the cached values are set correctly in the frontend
 * legacy tuning structures, for the advanced tuning API.
 */
1142
static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
1143
					    struct dvb_frontend_parameters *p)
1144
{
1145
	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1146

1147 1148
	p->frequency = c->frequency;
	p->inversion = c->inversion;
1149

1150 1151 1152 1153 1154 1155 1156
	switch (dvbv3_type(c->delivery_system)) {
	case DVBV3_UNKNOWN:
		printk(KERN_ERR
		       "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
		       __func__, c->delivery_system);
		return -EINVAL;
	case DVBV3_QPSK:
1157
		dprintk("%s() Preparing QPSK req\n", __func__);
1158 1159 1160
		p->u.qpsk.symbol_rate = c->symbol_rate;
		p->u.qpsk.fec_inner = c->fec_inner;
		break;
1161
	case DVBV3_QAM:
1162
		dprintk("%s() Preparing QAM req\n", __func__);
1163 1164 1165 1166
		p->u.qam.symbol_rate = c->symbol_rate;
		p->u.qam.fec_inner = c->fec_inner;
		p->u.qam.modulation = c->modulation;
		break;
1167
	case DVBV3_OFDM:
1168
		dprintk("%s() Preparing OFDM req\n", __func__);
1169

1170 1171 1172 1173 1174
		switch (c->bandwidth_hz) {
		case 10000000:
			p->u.ofdm.bandwidth = BANDWIDTH_10_MHZ;
			break;
		case 8000000:
1175
			p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
			break;
		case 7000000:
			p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
			break;
		case 6000000:
			p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
			break;
		case 5000000:
			p->u.ofdm.bandwidth = BANDWIDTH_5_MHZ;
			break;
		case 1712000:
			p->u.ofdm.bandwidth = BANDWIDTH_1_712_MHZ;
			break;
		case 0:
		default:
1191
			p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1192
		}
1193 1194 1195 1196 1197 1198 1199
		p->u.ofdm.code_rate_HP = c->code_rate_HP;
		p->u.ofdm.code_rate_LP = c->code_rate_LP;
		p->u.ofdm.constellation = c->modulation;
		p->u.ofdm.transmission_mode = c->transmission_mode;
		p->u.ofdm.guard_interval = c->guard_interval;
		p->u.ofdm.hierarchy_information = c->hierarchy;
		break;
1200
	case DVBV3_ATSC:
1201
		dprintk("%s() Preparing VSB req\n", __func__);
1202 1203 1204
		p->u.vsb.modulation = c->modulation;
		break;
	}
1205
	return 0;
1206 1207
}

1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
/**
 * dtv_get_frontend - calls a callback for retrieving DTV parameters
 * @fe:		struct dvb_frontend pointer
 * @c:		struct dtv_frontend_properties pointer (DVBv5 cache)
 * @p_out	struct dvb_frontend_parameters pointer (DVBv3 FE struct)
 *
 * This routine calls either the DVBv3 or DVBv5 get_frontend call.
 * If c is not null, it will update the DVBv5 cache struct pointed by it.
 * If p_out is not null, it will update the DVBv3 params pointed by it.
 */
static int dtv_get_frontend(struct dvb_frontend *fe,
			    struct dvb_frontend_parameters *p_out)
{
	int r;

	if (fe->ops.get_frontend) {
1224
		r = fe->ops.get_frontend(fe);
1225 1226
		if (unlikely(r < 0))
			return r;
1227
		if (p_out)
1228 1229 1230 1231
			dtv_property_legacy_params_sync(fe, p_out);
		return 0;
	}

1232
	/* As everything is in cache, get_frontend fops are always supported */
1233
	return 0;
1234 1235
}

1236
static int dvb_frontend_ioctl_legacy(struct file *file,
1237
			unsigned int cmd, void *parg);
1238
static int dvb_frontend_ioctl_properties(struct file *file,
1239 1240
			unsigned int cmd, void *parg);

1241
static int dtv_property_process_get(struct dvb_frontend *fe,
1242
				    const struct dtv_frontend_properties *c,
1243
				    struct dtv_property *tvp,
1244
				    struct file *file)
1245
{
1246
	int r, ncaps;
1247

1248
	switch(tvp->cmd) {
1249
	case DTV_ENUM_DELSYS:
1250 1251 1252 1253 1254 1255
		ncaps = 0;
		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
			tvp->u.buffer.data[ncaps] = fe->ops.delsys[ncaps];
			ncaps++;
		}
		tvp->u.buffer.len = ncaps;
1256
		break;
1257
	case DTV_FREQUENCY:
1258
		tvp->u.data = c->frequency;
1259 1260
		break;
	case DTV_MODULATION:
1261
		tvp->u.data = c->modulation;
1262
		break;
1263
	case DTV_BANDWIDTH_HZ:
1264
		tvp->u.data = c->bandwidth_hz;
1265 1266
		break;
	case DTV_INVERSION:
1267
		tvp->u.data = c->inversion;
1268 1269
		break;
	case DTV_SYMBOL_RATE:
1270
		tvp->u.data = c->symbol_rate;
1271 1272
		break;
	case DTV_INNER_FEC:
1273
		tvp->u.data = c->fec_inner;
1274 1275
		break;
	case DTV_PILOT:
1276
		tvp->u.data = c->pilot;
1277 1278
		break;
	case DTV_ROLLOFF:
1279
		tvp->u.data = c->rolloff;
1280 1281
		break;
	case DTV_DELIVERY_SYSTEM:
1282
		tvp->u.data = c->delivery_system;
1283 1284
		break;
	case DTV_VOLTAGE:
1285
		tvp->u.data = c->voltage;
1286 1287
		break;
	case DTV_TONE:
1288
		tvp->u.data = c->sectone;
1289
		break;
1290 1291 1292
	case DTV_API_VERSION:
		tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
		break;
1293
	case DTV_CODE_RATE_HP:
1294
		tvp->u.data = c->code_rate_HP;
1295 1296
		break;
	case DTV_CODE_RATE_LP:
1297
		tvp->u.data = c->code_rate_LP;
1298
		break;
1299
	case DTV_GUARD_INTERVAL:
1300
		tvp->u.data = c->guard_interval;
1301 1302
		break;
	case DTV_TRANSMISSION_MODE:
1303
		tvp->u.data = c->transmission_mode;
1304
		break;
1305
	case DTV_HIERARCHY:
1306
		tvp->u.data = c->hierarchy;
1307
		break;
1308 1309 1310

	/* ISDB-T Support here */
	case DTV_ISDBT_PARTIAL_RECEPTION:
1311
		tvp->u.data = c->isdbt_partial_reception;
1312 1313
		break;
	case DTV_ISDBT_SOUND_BROADCASTING:
1314
		tvp->u.data = c->isdbt_sb_mode;
1315 1316
		break;
	case DTV_ISDBT_SB_SUBCHANNEL_ID:
1317
		tvp->u.data = c->isdbt_sb_subchannel;
1318 1319
		break;
	case DTV_ISDBT_SB_SEGMENT_IDX:
1320
		tvp->u.data = c->isdbt_sb_segment_idx;
1321 1322
		break;
	case DTV_ISDBT_SB_SEGMENT_COUNT:
1323
		tvp->u.data = c->isdbt_sb_segment_count;
1324
		break;
1325
	case DTV_ISDBT_LAYER_ENABLED:
1326
		tvp->u.data = c->isdbt_layer_enabled;
1327
		break;
1328
	case DTV_ISDBT_LAYERA_FEC:
1329
		tvp->u.data = c->layer[0].fec;
1330 1331
		break;
	case DTV_ISDBT_LAYERA_MODULATION:
1332
		tvp->u.data = c->layer[0].modulation;
1333 1334
		break;
	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1335
		tvp->u.data = c->layer[0].segment_count;
1336 1337
		break;
	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1338
		tvp->u.data = c->layer[0].interleaving;
1339 1340
		break;
	case DTV_ISDBT_LAYERB_FEC:
1341
		tvp->u.data = c->layer[1].fec;
1342 1343
		break;
	case DTV_ISDBT_LAYERB_MODULATION:
1344
		tvp->u.data = c->layer[1].modulation;
1345 1346
		break;
	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1347
		tvp->u.data = c->layer[1].segment_count;
1348 1349
		break;
	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1350
		tvp->u.data = c->layer[1].interleaving;
1351 1352
		break;
	case DTV_ISDBT_LAYERC_FEC:
1353
		tvp->u.data = c->layer[2].fec;
1354 1355
		break;
	case DTV_ISDBT_LAYERC_MODULATION:
1356
		tvp->u.data = c->layer[2].modulation;
1357 1358
		break;
	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1359
		tvp->u.data = c->layer[2].segment_count;
1360 1361
		break;
	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1362
		tvp->u.data = c->layer[2].interleaving;
1363
		break;
1364
	case DTV_ISDBS_TS_ID:
1365
		tvp->u.data = c->isdbs_ts_id;
1366
		break;
1367
	case DTV_DVBT2_PLP_ID:
1368
		tvp->u.data = c->dvbt2_plp_id;
1369
		break;
1370
	default:
1371
		return -EINVAL;
1372 1373
	}

1374 1375 1376 1377 1378 1379 1380
	/* Allow the frontend to override outgoing properties */
	if (fe->ops.get_property) {
		r = fe->ops.get_property(fe, tvp);
		if (r < 0)
			return r;
	}

1381 1382
	dtv_property_dump(tvp);

1383
	return 0;
1384 1385
}

1386 1387
static int dtv_set_frontend(struct dvb_frontend *fe);

1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
static bool is_dvbv3_delsys(u32 delsys)
{
	bool status;

	status = (delsys == SYS_DVBT) || (delsys == SYS_DVBC_ANNEX_A) ||
		 (delsys == SYS_DVBS) || (delsys == SYS_ATSC);

	return status;
}

static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
{
	int ncaps, i;
	u32 delsys = SYS_UNDEFINED;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	enum dvbv3_emulation_type type;

1405 1406 1407 1408 1409 1410 1411 1412 1413
	/*
	 * It was reported that some old DVBv5 applications were
	 * filling delivery_system with SYS_UNDEFINED. If this happens,
	 * assume that the application wants to use the first supported
	 * delivery system.
	 */
	if (c->delivery_system == SYS_UNDEFINED)
	        c->delivery_system = fe->ops.delsys[0];

1414 1415 1416
	if (desired_system == SYS_UNDEFINED) {
		/*
		 * A DVBv3 call doesn't know what's the desired system.
1417 1418 1419 1420 1421 1422 1423
		 * Also, DVBv3 applications don't know that ops.info->type
		 * could be changed, and they simply dies when it doesn't
		 * match.
		 * So, don't change the current delivery system, as it
		 * may be trying to do the wrong thing, like setting an
		 * ISDB-T frontend as DVB-T. Instead, find the closest
		 * DVBv3 system that matches the delivery system.
1424 1425 1426 1427 1428 1429 1430 1431 1432
		 */
		if (is_dvbv3_delsys(c->delivery_system)) {
			dprintk("%s() Using delivery system to %d\n",
				__func__, c->delivery_system);
			return 0;
		}
		type = dvbv3_type(c->delivery_system);
		switch (type) {
		case DVBV3_QPSK:
1433
			desired_system = SYS_DVBS;
1434 1435
			break;
		case DVBV3_QAM:
1436
			desired_system = SYS_DVBC_ANNEX_A;
1437 1438
			break;
		case DVBV3_ATSC:
1439
			desired_system = SYS_ATSC;
1440 1441
			break;
		case DVBV3_OFDM:
1442
			desired_system = SYS_DVBT;
1443 1444 1445 1446 1447 1448
			break;
		default:
			dprintk("%s(): This frontend doesn't support DVBv3 calls\n",
				__func__);
			return -EINVAL;
		}
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
		/*
		 * Get a delivery system that is compatible with DVBv3
		 * NOTE: in order for this to work with softwares like Kaffeine that
		 *	uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
		 *	DVB-S, drivers that support both should put the SYS_DVBS entry
		 *	before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
		 *	The real fix is that userspace applications should not use DVBv3
		 *	and not trust on calling FE_SET_FRONTEND to switch the delivery
		 *	system.
		 */
		ncaps = 0;
		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
			if (fe->ops.delsys[ncaps] == desired_system) {
				delsys = desired_system;
				break;
			}
			ncaps++;
		}
		if (delsys == SYS_UNDEFINED) {
			dprintk("%s() Couldn't find a delivery system that matches %d\n",
				__func__, desired_system);
		}
1471 1472
	} else {
		/*
1473 1474
		 * This is a DVBv5 call. So, it likely knows the supported
		 * delivery systems.
1475
		 */
1476 1477

		/* Check if the desired delivery system is supported */
1478 1479 1480 1481 1482 1483 1484 1485
		ncaps = 0;
		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
			if (fe->ops.delsys[ncaps] == desired_system) {
				c->delivery_system = desired_system;
				dprintk("%s() Changing delivery system to %d\n",
					__func__, desired_system);
				return 0;
			}
1486
			ncaps++;
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520
		}
		type = dvbv3_type(desired_system);

		/*
		 * The delivery system is not supported. See if it can be
		 * emulated.
		 * The emulation only works if the desired system is one of the
		 * DVBv3 delivery systems
		 */
		if (!is_dvbv3_delsys(desired_system)) {
			dprintk("%s() can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n",
				__func__);
			return -EINVAL;
		}

		/*
		 * Get the last non-DVBv3 delivery system that has the same type
		 * of the desired system
		 */
		ncaps = 0;
		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
			if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) &&
			    !is_dvbv3_delsys(fe->ops.delsys[ncaps]))
				delsys = fe->ops.delsys[ncaps];
			ncaps++;
		}
		/* There's nothing compatible with the desired delivery system */
		if (delsys == SYS_UNDEFINED) {
			dprintk("%s() Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n",
				__func__);
			return -EINVAL;
		}
	}

1521 1522
	c->delivery_system = delsys;

1523
	/*
1524 1525 1526
	 * The DVBv3 or DVBv5 call is requesting a different system. So,
	 * emulation is needed.
	 *
1527 1528 1529 1530 1531 1532 1533 1534 1535
	 * Emulate newer delivery systems like ISDBT, DVBT and DMBTH
	 * for older DVBv5 applications. The emulation will try to use
	 * the auto mode for most things, and will assume that the desired
	 * delivery system is the last one at the ops.delsys[] array
	 */
	dprintk("%s() Using delivery system %d emulated as if it were a %d\n",
		__func__, delsys, desired_system);

	/*
1536 1537
	 * For now, handles ISDB-T calls. More code may be needed here for the
	 * other emulated stuff
1538 1539
	 */
	if (type == DVBV3_OFDM) {
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
		if (c->delivery_system == SYS_ISDBT) {
			dprintk("%s() Using defaults for SYS_ISDBT\n",
				__func__);
			if (!c->bandwidth_hz)
				c->bandwidth_hz = 6000000;

			c->isdbt_partial_reception = 0;
			c->isdbt_sb_mode = 0;
			c->isdbt_sb_subchannel = 0;
			c->isdbt_sb_segment_idx = 0;
			c->isdbt_sb_segment_count = 0;
			c->isdbt_layer_enabled = 0;
			for (i = 0; i < 3; i++) {
				c->layer[i].fec = FEC_AUTO;
				c->layer[i].modulation = QAM_AUTO;
				c->layer[i].interleaving = 0;
				c->layer[i].segment_count = 0;
			}
1558 1559
		}
	}
1560 1561
	dprintk("change delivery system on cache to %d\n", c->delivery_system);

1562 1563 1564
	return 0;
}

1565 1566 1567
static int dtv_property_process_set(struct dvb_frontend *fe,
				    struct dtv_property *tvp,
				    struct file *file)
1568 1569
{
	int r = 0;
1570
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1571

1572
	/* Allow the frontend to validate incoming properties */
1573
	if (fe->ops.set_property) {
1574
		r = fe->ops.set_property(fe, tvp);
1575 1576 1577
		if (r < 0)
			return r;
	}
1578

1579
	switch(tvp->cmd) {
1580
	case DTV_CLEAR:
1581 1582
		/*
		 * Reset a cache of data specific to the frontend here. This does
1583 1584
		 * not effect hardware.
		 */
1585
		dvb_frontend_clear_cache(fe);
1586
		break;
1587
	case DTV_TUNE:
1588
		/* interpret the cache of data, build either a traditional frontend
1589 1590
		 * tunerequest so we can pass validation in the FE_SET_FRONTEND
		 * ioctl.
1591
		 */
1592
		c->state = tvp->cmd;
1593
		dprintk("%s() Finalised property cache\n", __func__);
1594

1595
		r = dtv_set_frontend(fe);
1596
		break;
1597
	case DTV_FREQUENCY:
1598
		c->frequency = tvp->u.data;
1599
		break;
1600
	case DTV_MODULATION:
1601
		c->modulation = tvp->u.data;
1602
		break;
1603
	case DTV_BANDWIDTH_HZ:
1604
		c->bandwidth_hz = tvp->u.data;
1605
		break;
1606
	case DTV_INVERSION:
1607
		c->inversion = tvp->u.data;
1608
		break;
1609
	case DTV_SYMBOL_RATE:
1610
		c->symbol_rate = tvp->u.data;
1611
		break;
1612
	case DTV_INNER_FEC:
1613
		c->fec_inner = tvp->u.data;
1614
		break;
1615
	case DTV_PILOT:
1616
		c->pilot = tvp->u.data;
1617
		break;
1618
	case DTV_ROLLOFF:
1619
		c->rolloff = tvp->u.data;
1620
		break;
1621
	case DTV_DELIVERY_SYSTEM:
1622
		r = set_delivery_system(fe, tvp->u.data);
1623
		break;
1624
	case DTV_VOLTAGE:
1625
		c->voltage = tvp->u.data;
1626
		r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
1627
			(void *)c->voltage);
1628
		break;
1629
	case DTV_TONE:
1630
		c->sectone = tvp->u.data;
1631
		r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
1632
			(void *)c->sectone);
1633
		break;
1634
	case DTV_CODE_RATE_HP:
1635
		c->code_rate_HP = tvp->u.data;
1636 1637
		break;
	case DTV_CODE_RATE_LP:
1638
		c->code_rate_LP = tvp->u.data;
1639
		break;
1640
	case DTV_GUARD_INTERVAL:
1641
		c->guard_interval = tvp->u.data;
1642 1643
		break;
	case DTV_TRANSMISSION_MODE:
1644
		c->transmission_mode = tvp->u.data;
1645
		break;
1646
	case DTV_HIERARCHY:
1647
		c->hierarchy = tvp->u.data;
1648
		break;
1649 1650 1651

	/* ISDB-T Support here */
	case DTV_ISDBT_PARTIAL_RECEPTION:
1652
		c->isdbt_partial_reception = tvp->u.data;
1653 1654
		break;
	case DTV_ISDBT_SOUND_BROADCASTING:
1655
		c->isdbt_sb_mode = tvp->u.data;
1656 1657
		break;
	case DTV_ISDBT_SB_SUBCHANNEL_ID:
1658
		c->isdbt_sb_subchannel = tvp->u.data;
1659 1660
		break;
	case DTV_ISDBT_SB_SEGMENT_IDX:
1661
		c->isdbt_sb_segment_idx = tvp->u.data;
1662 1663
		break;
	case DTV_ISDBT_SB_SEGMENT_COUNT:
1664
		c->isdbt_sb_segment_count = tvp->u.data;
1665
		break;
1666
	case DTV_ISDBT_LAYER_ENABLED:
1667
		c->isdbt_layer_enabled = tvp->u.data;
1668
		break;
1669
	case DTV_ISDBT_LAYERA_FEC:
1670
		c->layer[0].fec = tvp->u.data;
1671 1672
		break;
	case DTV_ISDBT_LAYERA_MODULATION:
1673
		c->layer[0].modulation = tvp->u.data;
1674 1675
		break;
	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1676
		c->layer[0].segment_count = tvp->u.data;
1677 1678
		break;
	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1679
		c->layer[0].interleaving = tvp->u.data;
1680 1681
		break;
	case DTV_ISDBT_LAYERB_FEC:
1682
		c->layer[1].fec = tvp->u.data;
1683 1684
		break;
	case DTV_ISDBT_LAYERB_MODULATION:
1685
		c->layer[1].modulation = tvp->u.data;
1686 1687
		break;
	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1688
		c->layer[1].segment_count = tvp->u.data;
1689 1690
		break;
	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1691
		c->layer[1].interleaving = tvp->u.data;
1692 1693
		break;
	case DTV_ISDBT_LAYERC_FEC:
1694
		c->layer[2].fec = tvp->u.data;
1695 1696
		break;
	case DTV_ISDBT_LAYERC_MODULATION:
1697
		c->layer[2].modulation = tvp->u.data;
1698 1699
		break;
	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1700
		c->layer[2].segment_count = tvp->u.data;
1701 1702
		break;
	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1703
		c->layer[2].interleaving = tvp->u.data;
1704
		break;
1705
	case DTV_ISDBS_TS_ID:
1706
		c->isdbs_ts_id = tvp->u.data;
1707 1708
		break;
	case DTV_DVBT2_PLP_ID:
1709
		c->dvbt2_plp_id = tvp->u.data;
1710
		break;
1711
	default:
1712
		return -EINVAL;
1713 1714
	}

1715
	return r;
1716 1717
}

1718
static int dvb_frontend_ioctl(struct file *file,
L
Linus Torvalds 已提交
1719 1720 1721 1722
			unsigned int cmd, void *parg)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
1723
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1724
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
1725 1726
	int err = -EOPNOTSUPP;

1727
	dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
L
Linus Torvalds 已提交
1728

1729
	if (fepriv->exit != DVB_FE_NO_EXIT)
L
Linus Torvalds 已提交
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739
		return -ENODEV;

	if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
	    (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
	     cmd == FE_DISEQC_RECV_SLAVE_REPLY))
		return -EPERM;

	if (down_interruptible (&fepriv->sem))
		return -ERESTARTSYS;

1740
	if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1741
		err = dvb_frontend_ioctl_properties(file, cmd, parg);
1742
	else {
1743
		c->state = DTV_UNDEFINED;
1744
		err = dvb_frontend_ioctl_legacy(file, cmd, parg);
1745
	}
1746 1747 1748 1749 1750

	up(&fepriv->sem);
	return err;
}

1751
static int dvb_frontend_ioctl_properties(struct file *file,
1752 1753 1754 1755
			unsigned int cmd, void *parg)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
1756
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
1757
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1758
	int err = 0;
1759 1760 1761 1762

	struct dtv_properties *tvps = NULL;
	struct dtv_property *tvp = NULL;
	int i;
1763 1764 1765

	dprintk("%s\n", __func__);

1766
	if(cmd == FE_SET_PROPERTY) {
1767
		tvps = (struct dtv_properties __user *)parg;
1768

1769 1770
		dprintk("%s() properties.num = %d\n", __func__, tvps->num);
		dprintk("%s() properties.props = %p\n", __func__, tvps->props);
1771 1772 1773

		/* Put an arbitrary limit on the number of messages that can
		 * be sent at once */
1774
		if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1775 1776
			return -EINVAL;

1777
		tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1778 1779 1780
		if (!tvp) {
			err = -ENOMEM;
			goto out;
1781 1782
		}

1783 1784 1785 1786 1787
		if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
			err = -EFAULT;
			goto out;
		}

1788
		for (i = 0; i < tvps->num; i++) {
1789 1790 1791 1792
			err = dtv_property_process_set(fe, tvp + i, file);
			if (err < 0)
				goto out;
			(tvp + i)->result = err;
1793
		}
1794

1795
		if (c->state == DTV_TUNE)
1796
			dprintk("%s() Property cache is full, tuning\n", __func__);
1797

1798 1799 1800 1801
	} else
	if(cmd == FE_GET_PROPERTY) {
		tvps = (struct dtv_properties __user *)parg;

1802 1803
		dprintk("%s() properties.num = %d\n", __func__, tvps->num);
		dprintk("%s() properties.props = %p\n", __func__, tvps->props);
1804 1805 1806

		/* Put an arbitrary limit on the number of messages that can
		 * be sent at once */
1807
		if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1808 1809
			return -EINVAL;

1810
		tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
		if (!tvp) {
			err = -ENOMEM;
			goto out;
		}

		if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
			err = -EFAULT;
			goto out;
		}

1821 1822
		/*
		 * Fills the cache out struct with the cache contents, plus
1823 1824
		 * the data retrieved from get_frontend, if the frontend
		 * is not idle. Otherwise, returns the cached content
1825
		 */
1826 1827 1828 1829 1830
		if (fepriv->state != FESTATE_IDLE) {
			err = dtv_get_frontend(fe, NULL);
			if (err < 0)
				goto out;
		}
1831
		for (i = 0; i < tvps->num; i++) {
1832
			err = dtv_property_process_get(fe, c, tvp + i, file);
1833 1834 1835
			if (err < 0)
				goto out;
			(tvp + i)->result = err;
1836
		}
1837 1838 1839 1840 1841 1842 1843 1844 1845

		if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
			err = -EFAULT;
			goto out;
		}

	} else
		err = -EOPNOTSUPP;

1846 1847
out:
	kfree(tvp);
1848 1849 1850
	return err;
}

1851
static int dtv_set_frontend(struct dvb_frontend *fe)
1852 1853 1854 1855
{
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct dvb_frontend_tune_settings fetunesettings;
1856
	u32 rolloff = 0;
1857

1858 1859
	if (dvb_frontend_check_parameters(fe) < 0)
		return -EINVAL;
1860

1861 1862 1863 1864 1865 1866 1867
	/*
	 * Initialize output parameters to match the values given by
	 * the user. FE_SET_FRONTEND triggers an initial frontend event
	 * with status = 0, which copies output parameters to userspace.
	 */
	dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);

1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902
	/*
	 * Be sure that the bandwidth will be filled for all
	 * non-satellite systems, as tuners need to know what
	 * low pass/Nyquist half filter should be applied, in
	 * order to avoid inter-channel noise.
	 *
	 * ISDB-T and DVB-T/T2 already sets bandwidth.
	 * ATSC and DVB-C don't set, so, the core should fill it.
	 *
	 * On DVB-C Annex A and C, the bandwidth is a function of
	 * the roll-off and symbol rate. Annex B defines different
	 * roll-off factors depending on the modulation. Fortunately,
	 * Annex B is only used with 6MHz, so there's no need to
	 * calculate it.
	 *
	 * While not officially supported, a side effect of handling it at
	 * the cache level is that a program could retrieve the bandwidth
	 * via DTV_BANDWIDTH_HZ, which may be useful for test programs.
	 */
	switch (c->delivery_system) {
	case SYS_ATSC:
	case SYS_DVBC_ANNEX_B:
		c->bandwidth_hz = 6000000;
		break;
	case SYS_DVBC_ANNEX_A:
		rolloff = 115;
		break;
	case SYS_DVBC_ANNEX_C:
		rolloff = 113;
		break;
	default:
		break;
	}
	if (rolloff)
		c->bandwidth_hz = (c->symbol_rate * rolloff) / 100;
1903 1904

	/* force auto frequency inversion if requested */
1905
	if (dvb_force_auto_inversion)
1906
		c->inversion = INVERSION_AUTO;
1907 1908 1909 1910 1911 1912 1913

	/*
	 * without hierarchical coding code_rate_LP is irrelevant,
	 * so we tolerate the otherwise invalid FEC_NONE setting
	 */
	if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
		c->code_rate_LP = FEC_AUTO;
1914 1915

	/* get frontend-specific tuning settings */
1916
	memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
1917 1918 1919 1920 1921 1922
	if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
		fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
		fepriv->max_drift = fetunesettings.max_drift;
		fepriv->step_size = fetunesettings.step_size;
	} else {
		/* default values */
1923 1924 1925 1926
		switch (c->delivery_system) {
		case SYS_DVBC_ANNEX_A:
		case SYS_DVBC_ANNEX_C:
			fepriv->min_delay = HZ / 20;
1927 1928 1929
			fepriv->step_size = c->symbol_rate / 16000;
			fepriv->max_drift = c->symbol_rate / 2000;
			break;
1930 1931 1932 1933 1934
		case SYS_DVBT:
		case SYS_DVBT2:
		case SYS_ISDBT:
		case SYS_DMBTH:
			fepriv->min_delay = HZ / 20;
1935 1936 1937
			fepriv->step_size = fe->ops.info.frequency_stepsize * 2;
			fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
			break;
1938 1939 1940 1941 1942 1943 1944
		default:
			/*
			 * FIXME: This sounds wrong! if freqency_stepsize is
			 * defined by the frontend, why not use it???
			 */
			fepriv->min_delay = HZ / 20;
			fepriv->step_size = 0; /* no zigzag */
1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
			fepriv->max_drift = 0;
			break;
		}
	}
	if (dvb_override_tune_delay > 0)
		fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;

	fepriv->state = FESTATE_RETUNE;

	/* Request the search algorithm to search */
	fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;

	dvb_frontend_clear_events(fe);
	dvb_frontend_add_event(fe, 0);
	dvb_frontend_wakeup(fe);
	fepriv->status = 0;

	return 0;
}


1966
static int dvb_frontend_ioctl_legacy(struct file *file,
1967 1968 1969 1970 1971
			unsigned int cmd, void *parg)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
1972
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
	int cb_err, err = -EOPNOTSUPP;

	if (fe->dvb->fe_ioctl_override) {
		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
						    DVB_FE_IOCTL_PRE);
		if (cb_err < 0)
			return cb_err;
		if (cb_err > 0)
			return 0;
		/* fe_ioctl_override returning 0 allows
		 * dvb-core to continue handling the ioctl */
	}
1985

L
Linus Torvalds 已提交
1986 1987
	switch (cmd) {
	case FE_GET_INFO: {
1988
		struct dvb_frontend_info* info = parg;
1989

1990
		memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
1991
		dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max);
L
Linus Torvalds 已提交
1992

1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005
		/*
		 * Associate the 4 delivery systems supported by DVBv3
		 * API with their DVBv5 counterpart. For the other standards,
		 * use the closest type, assuming that it would hopefully
		 * work with a DVBv3 application.
		 * It should be noticed that, on multi-frontend devices with
		 * different types (terrestrial and cable, for example),
		 * a pure DVBv3 application won't be able to use all delivery
		 * systems. Yet, changing the DVBv5 cache to the other delivery
		 * system should be enough for making it work.
		 */
		switch (dvbv3_type(c->delivery_system)) {
		case DVBV3_QPSK:
2006
			info->type = FE_QPSK;
2007 2008
			break;
		case DVBV3_ATSC:
2009
			info->type = FE_ATSC;
2010 2011
			break;
		case DVBV3_QAM:
2012
			info->type = FE_QAM;
2013 2014
			break;
		case DVBV3_OFDM:
2015
			info->type = FE_OFDM;
2016 2017 2018 2019 2020 2021 2022
			break;
		default:
			printk(KERN_ERR
			       "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
			       __func__, c->delivery_system);
			fe->ops.info.type = FE_OFDM;
		}
2023 2024
		dprintk("current delivery system on cache: %d, V3 type: %d\n",
			c->delivery_system, fe->ops.info.type);
2025

L
Linus Torvalds 已提交
2026 2027 2028 2029 2030 2031 2032
		/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
		 * do it, it is done for it. */
		info->caps |= FE_CAN_INVERSION_AUTO;
		err = 0;
		break;
	}

2033 2034 2035
	case FE_READ_STATUS: {
		fe_status_t* status = parg;

L
Lucas De Marchi 已提交
2036
		/* if retune was requested but hasn't occurred yet, prevent
2037
		 * that user get signal state from previous tuning */
2038 2039
		if (fepriv->state == FESTATE_RETUNE ||
		    fepriv->state == FESTATE_ERROR) {
2040 2041 2042 2043 2044
			err=0;
			*status = 0;
			break;
		}

2045 2046
		if (fe->ops.read_status)
			err = fe->ops.read_status(fe, status);
L
Linus Torvalds 已提交
2047
		break;
2048
	}
L
Linus Torvalds 已提交
2049
	case FE_READ_BER:
2050 2051
		if (fe->ops.read_ber)
			err = fe->ops.read_ber(fe, (__u32*) parg);
L
Linus Torvalds 已提交
2052 2053 2054
		break;

	case FE_READ_SIGNAL_STRENGTH:
2055 2056
		if (fe->ops.read_signal_strength)
			err = fe->ops.read_signal_strength(fe, (__u16*) parg);
L
Linus Torvalds 已提交
2057 2058 2059
		break;

	case FE_READ_SNR:
2060 2061
		if (fe->ops.read_snr)
			err = fe->ops.read_snr(fe, (__u16*) parg);
L
Linus Torvalds 已提交
2062 2063 2064
		break;

	case FE_READ_UNCORRECTED_BLOCKS:
2065 2066
		if (fe->ops.read_ucblocks)
			err = fe->ops.read_ucblocks(fe, (__u32*) parg);
L
Linus Torvalds 已提交
2067 2068 2069 2070
		break;


	case FE_DISEQC_RESET_OVERLOAD:
2071 2072
		if (fe->ops.diseqc_reset_overload) {
			err = fe->ops.diseqc_reset_overload(fe);
L
Linus Torvalds 已提交
2073 2074 2075 2076 2077 2078
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
		}
		break;

	case FE_DISEQC_SEND_MASTER_CMD:
2079 2080
		if (fe->ops.diseqc_send_master_cmd) {
			err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
L
Linus Torvalds 已提交
2081 2082 2083 2084 2085 2086
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
		}
		break;

	case FE_DISEQC_SEND_BURST:
2087 2088
		if (fe->ops.diseqc_send_burst) {
			err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
L
Linus Torvalds 已提交
2089 2090 2091 2092 2093 2094
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
		}
		break;

	case FE_SET_TONE:
2095 2096
		if (fe->ops.set_tone) {
			err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg);
2097
			fepriv->tone = (fe_sec_tone_mode_t) parg;
L
Linus Torvalds 已提交
2098 2099 2100 2101 2102 2103
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
		}
		break;

	case FE_SET_VOLTAGE:
2104 2105
		if (fe->ops.set_voltage) {
			err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg);
2106
			fepriv->voltage = (fe_sec_voltage_t) parg;
L
Linus Torvalds 已提交
2107 2108 2109 2110 2111 2112
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
		}
		break;

	case FE_DISHNETWORK_SEND_LEGACY_CMD:
2113 2114
		if (fe->ops.dishnetwork_send_legacy_command) {
			err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg);
L
Linus Torvalds 已提交
2115 2116
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
2117
		} else if (fe->ops.set_voltage) {
2118 2119 2120 2121 2122
			/*
			 * NOTE: This is a fallback condition.  Some frontends
			 * (stv0299 for instance) take longer than 8msec to
			 * respond to a set_voltage command.  Those switches
			 * need custom routines to switch properly.  For all
2123
			 * other frontends, the following should work ok.
2124 2125 2126
			 * Dish network legacy switches (as used by Dish500)
			 * are controlled by sending 9-bit command words
			 * spaced 8msec apart.
L
Lucas De Marchi 已提交
2127
			 * the actual command word is switch/port dependent
2128 2129 2130 2131 2132 2133
			 * so it is up to the userspace application to send
			 * the right command.
			 * The command must always start with a '0' after
			 * initialization, so parg is 8 bits and does not
			 * include the initialization or start bit
			 */
2134
			unsigned long swcmd = ((unsigned long) parg) << 1;
2135 2136 2137 2138 2139
			struct timeval nexttime;
			struct timeval tv[10];
			int i;
			u8 last = 1;
			if (dvb_frontend_debug)
2140
				printk("%s switch command: 0x%04lx\n", __func__, swcmd);
2141 2142 2143 2144 2145 2146
			do_gettimeofday(&nexttime);
			if (dvb_frontend_debug)
				memcpy(&tv[0], &nexttime, sizeof(struct timeval));
			/* before sending a command, initialize by sending
			 * a 32ms 18V to the switch
			 */
2147
			fe->ops.set_voltage(fe, SEC_VOLTAGE_18);
2148 2149 2150 2151 2152
			dvb_frontend_sleep_until(&nexttime, 32000);

			for (i = 0; i < 9; i++) {
				if (dvb_frontend_debug)
					do_gettimeofday(&tv[i + 1]);
2153
				if ((swcmd & 0x01) != last) {
2154
					/* set voltage to (last ? 13V : 18V) */
2155
					fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
2156 2157
					last = (last) ? 0 : 1;
				}
2158
				swcmd = swcmd >> 1;
2159 2160 2161 2162 2163
				if (i != 8)
					dvb_frontend_sleep_until(&nexttime, 8000);
			}
			if (dvb_frontend_debug) {
				printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
2164
					__func__, fe->dvb->num);
2165 2166 2167 2168 2169 2170
				for (i = 1; i < 10; i++)
					printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
			}
			err = 0;
			fepriv->state = FESTATE_DISEQC;
			fepriv->status = 0;
L
Linus Torvalds 已提交
2171 2172 2173 2174
		}
		break;

	case FE_DISEQC_RECV_SLAVE_REPLY:
2175 2176
		if (fe->ops.diseqc_recv_slave_reply)
			err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
L
Linus Torvalds 已提交
2177 2178 2179
		break;

	case FE_ENABLE_HIGH_LNB_VOLTAGE:
2180 2181
		if (fe->ops.enable_high_lnb_voltage)
			err = fe->ops.enable_high_lnb_voltage(fe, (long) parg);
L
Linus Torvalds 已提交
2182 2183
		break;

2184
	case FE_SET_FRONTEND:
2185 2186 2187 2188
		err = set_delivery_system(fe, SYS_UNDEFINED);
		if (err)
			break;

2189
		err = dtv_property_cache_sync(fe, c, parg);
2190 2191 2192
		if (err)
			break;
		err = dtv_set_frontend(fe);
L
Linus Torvalds 已提交
2193 2194 2195 2196 2197 2198
		break;
	case FE_GET_EVENT:
		err = dvb_frontend_get_event (fe, parg, file->f_flags);
		break;

	case FE_GET_FRONTEND:
2199
		err = dtv_get_frontend(fe, parg);
L
Linus Torvalds 已提交
2200
		break;
2201 2202

	case FE_SET_FRONTEND_TUNE_MODE:
2203
		fepriv->tune_mode_flags = (unsigned long) parg;
2204
		err = 0;
2205
		break;
L
Linus Torvalds 已提交
2206 2207
	};

2208 2209 2210 2211 2212 2213 2214
	if (fe->dvb->fe_ioctl_override) {
		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
						    DVB_FE_IOCTL_POST);
		if (cb_err < 0)
			return cb_err;
	}

L
Linus Torvalds 已提交
2215 2216 2217
	return err;
}

2218

L
Linus Torvalds 已提交
2219 2220 2221 2222
static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
2223
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
2224

2225
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238

	poll_wait (file, &fepriv->events.wait_queue, wait);

	if (fepriv->events.eventw != fepriv->events.eventr)
		return (POLLIN | POLLRDNORM | POLLPRI);

	return 0;
}

static int dvb_frontend_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
2239
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
2240
	struct dvb_adapter *adapter = fe->dvb;
L
Linus Torvalds 已提交
2241 2242
	int ret;

2243
	dprintk ("%s\n", __func__);
2244 2245
	if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
		return -ENODEV;
L
Linus Torvalds 已提交
2246

2247 2248
	if (adapter->mfe_shared) {
		mutex_lock (&adapter->mfe_lock);
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267

		if (adapter->mfe_dvbdev == NULL)
			adapter->mfe_dvbdev = dvbdev;

		else if (adapter->mfe_dvbdev != dvbdev) {
			struct dvb_device
				*mfedev = adapter->mfe_dvbdev;
			struct dvb_frontend
				*mfe = mfedev->priv;
			struct dvb_frontend_private
				*mfepriv = mfe->frontend_priv;
			int mferetry = (dvb_mfe_wait_time << 1);

			mutex_unlock (&adapter->mfe_lock);
			while (mferetry-- && (mfedev->users != -1 ||
					mfepriv->thread != NULL)) {
				if(msleep_interruptible(500)) {
					if(signal_pending(current))
						return -EINTR;
2268
				}
2269 2270 2271 2272
			}

			mutex_lock (&adapter->mfe_lock);
			if(adapter->mfe_dvbdev != dvbdev) {
2273 2274 2275
				mfedev = adapter->mfe_dvbdev;
				mfe = mfedev->priv;
				mfepriv = mfe->frontend_priv;
2276 2277 2278 2279
				if (mfedev->users != -1 ||
						mfepriv->thread != NULL) {
					mutex_unlock (&adapter->mfe_lock);
					return -EBUSY;
2280
				}
2281
				adapter->mfe_dvbdev = dvbdev;
2282 2283 2284 2285
			}
		}
	}

2286 2287
	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
		if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
2288
			goto err0;
2289 2290 2291 2292 2293 2294 2295 2296

		/* If we took control of the bus, we need to force
		   reinitialization.  This is because many ts_bus_ctrl()
		   functions strobe the RESET pin on the demod, and if the
		   frontend thread already exists then the dvb_init() routine
		   won't get called (which is what usually does initial
		   register configuration). */
		fepriv->reinitialise = 1;
2297 2298
	}

2299 2300
	if ((ret = dvb_generic_open (inode, file)) < 0)
		goto err1;
2301

2302
	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
2303 2304 2305 2306 2307
		/* normal tune mode when opened R/W */
		fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
		fepriv->tone = -1;
		fepriv->voltage = -1;

L
Linus Torvalds 已提交
2308 2309
		ret = dvb_frontend_start (fe);
		if (ret)
2310
			goto err2;
L
Linus Torvalds 已提交
2311 2312 2313 2314 2315

		/*  empty event queue */
		fepriv->events.eventr = fepriv->events.eventw = 0;
	}

2316 2317
	if (adapter->mfe_shared)
		mutex_unlock (&adapter->mfe_lock);
L
Linus Torvalds 已提交
2318
	return ret;
2319 2320 2321 2322 2323 2324

err2:
	dvb_generic_release(inode, file);
err1:
	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
		fe->ops.ts_bus_ctrl(fe, 0);
2325 2326 2327
err0:
	if (adapter->mfe_shared)
		mutex_unlock (&adapter->mfe_lock);
2328
	return ret;
L
Linus Torvalds 已提交
2329 2330 2331 2332 2333 2334
}

static int dvb_frontend_release(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_frontend *fe = dvbdev->priv;
2335
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
2336
	int ret;
L
Linus Torvalds 已提交
2337

2338
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
2339

2340
	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
L
Linus Torvalds 已提交
2341
		fepriv->release_jiffies = jiffies;
2342 2343
		mb();
	}
L
Linus Torvalds 已提交
2344

2345 2346
	ret = dvb_generic_release (inode, file);

2347
	if (dvbdev->users == -1) {
2348
		wake_up(&fepriv->wait_queue);
2349
		if (fepriv->exit != DVB_FE_NO_EXIT) {
2350 2351 2352 2353 2354 2355
			fops_put(file->f_op);
			file->f_op = NULL;
			wake_up(&dvbdev->wait_queue);
		}
		if (fe->ops.ts_bus_ctrl)
			fe->ops.ts_bus_ctrl(fe, 0);
2356
	}
2357

2358
	return ret;
L
Linus Torvalds 已提交
2359 2360
}

2361
static const struct file_operations dvb_frontend_fops = {
L
Linus Torvalds 已提交
2362
	.owner		= THIS_MODULE,
2363
	.unlocked_ioctl	= dvb_generic_ioctl,
L
Linus Torvalds 已提交
2364 2365
	.poll		= dvb_frontend_poll,
	.open		= dvb_frontend_open,
2366 2367
	.release	= dvb_frontend_release,
	.llseek		= noop_llseek,
L
Linus Torvalds 已提交
2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381
};

int dvb_register_frontend(struct dvb_adapter* dvb,
			  struct dvb_frontend* fe)
{
	struct dvb_frontend_private *fepriv;
	static const struct dvb_device dvbdev_template = {
		.users = ~0,
		.writers = 1,
		.readers = (~0)-1,
		.fops = &dvb_frontend_fops,
		.kernel_ioctl = dvb_frontend_ioctl
	};

2382
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
2383

2384
	if (mutex_lock_interruptible(&frontend_mutex))
L
Linus Torvalds 已提交
2385 2386
		return -ERESTARTSYS;

P
 
Panagiotis Issaris 已提交
2387
	fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
L
Linus Torvalds 已提交
2388
	if (fe->frontend_priv == NULL) {
2389
		mutex_unlock(&frontend_mutex);
L
Linus Torvalds 已提交
2390 2391
		return -ENOMEM;
	}
2392
	fepriv = fe->frontend_priv;
L
Linus Torvalds 已提交
2393

2394
	sema_init(&fepriv->sem, 1);
L
Linus Torvalds 已提交
2395 2396
	init_waitqueue_head (&fepriv->wait_queue);
	init_waitqueue_head (&fepriv->events.wait_queue);
2397
	mutex_init(&fepriv->events.mtx);
L
Linus Torvalds 已提交
2398 2399 2400
	fe->dvb = dvb;
	fepriv->inversion = INVERSION_OFF;

2401
	printk ("DVB: registering adapter %i frontend %i (%s)...\n",
L
Linus Torvalds 已提交
2402
		fe->dvb->num,
2403
		fe->id,
2404
		fe->ops.info.name);
L
Linus Torvalds 已提交
2405 2406 2407 2408

	dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
			     fe, DVB_DEVICE_FRONTEND);

2409 2410 2411 2412
	/*
	 * Initialize the cache to the proper values according with the
	 * first supported delivery system (ops->delsys[0])
	 */
2413 2414

        fe->dtv_property_cache.delivery_system = fe->ops.delsys[0];
2415 2416
	dvb_frontend_clear_cache(fe);

2417
	mutex_unlock(&frontend_mutex);
L
Linus Torvalds 已提交
2418 2419 2420 2421 2422 2423
	return 0;
}
EXPORT_SYMBOL(dvb_register_frontend);

int dvb_unregister_frontend(struct dvb_frontend* fe)
{
2424
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
2425
	dprintk ("%s\n", __func__);
L
Linus Torvalds 已提交
2426

2427
	mutex_lock(&frontend_mutex);
2428
	dvb_frontend_stop (fe);
2429 2430 2431 2432 2433 2434
	mutex_unlock(&frontend_mutex);

	if (fepriv->dvbdev->users < -1)
		wait_event(fepriv->dvbdev->wait_queue,
				fepriv->dvbdev->users==-1);

2435
	mutex_lock(&frontend_mutex);
L
Linus Torvalds 已提交
2436
	dvb_unregister_device (fepriv->dvbdev);
2437

L
Linus Torvalds 已提交
2438 2439
	/* fe is invalid now */
	kfree(fepriv);
2440
	mutex_unlock(&frontend_mutex);
L
Linus Torvalds 已提交
2441 2442 2443
	return 0;
}
EXPORT_SYMBOL(dvb_unregister_frontend);
2444

2445
#ifdef CONFIG_MEDIA_ATTACH
2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457
void dvb_frontend_detach(struct dvb_frontend* fe)
{
	void *ptr;

	if (fe->ops.release_sec) {
		fe->ops.release_sec(fe);
		symbol_put_addr(fe->ops.release_sec);
	}
	if (fe->ops.tuner_ops.release) {
		fe->ops.tuner_ops.release(fe);
		symbol_put_addr(fe->ops.tuner_ops.release);
	}
2458 2459 2460 2461
	if (fe->ops.analog_ops.release) {
		fe->ops.analog_ops.release(fe);
		symbol_put_addr(fe->ops.analog_ops.release);
	}
2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474
	ptr = (void*)fe->ops.release;
	if (ptr) {
		fe->ops.release(fe);
		symbol_put_addr(ptr);
	}
}
#else
void dvb_frontend_detach(struct dvb_frontend* fe)
{
	if (fe->ops.release_sec)
		fe->ops.release_sec(fe);
	if (fe->ops.tuner_ops.release)
		fe->ops.tuner_ops.release(fe);
2475 2476
	if (fe->ops.analog_ops.release)
		fe->ops.analog_ops.release(fe);
2477 2478 2479 2480 2481
	if (fe->ops.release)
		fe->ops.release(fe);
}
#endif
EXPORT_SYMBOL(dvb_frontend_detach);