dvb_frontend.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
1/* 2 * dvb_frontend.c: DVB frontend tuning interface/thread 3 * 4 * 5 * Copyright (C) 1999-2001 Ralph Metzler 6 * Marcus Metzler 7 * Holger Waechtler 8 * for convergence integrated media GmbH 9 * 10 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup) 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 */ 27 28#include <linux/string.h> 29#include <linux/kernel.h> 30#include <linux/sched.h> 31#include <linux/wait.h> 32#include <linux/slab.h> 33#include <linux/poll.h> 34#include <linux/module.h> 35#include <linux/moduleparam.h> 36#include <linux/list.h> 37#include <linux/suspend.h> 38#include <asm/processor.h> 39#include <asm/semaphore.h> 40 41#include "dvb_frontend.h" 42#include "dvbdev.h" 43 44static int dvb_frontend_debug; 45static int dvb_shutdown_timeout = 5; 46static int dvb_force_auto_inversion; 47static int dvb_override_tune_delay; 48static int dvb_powerdown_on_sleep = 1; 49 50module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); 51MODULE_PARM_DESC(dvb_frontend_debug, "Turn on/off frontend core debugging (default:off)."); 52module_param(dvb_shutdown_timeout, int, 0444); 53MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); 54module_param(dvb_force_auto_inversion, int, 0444); 55MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); 56module_param(dvb_override_tune_delay, int, 0444); 57MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); 58module_param(dvb_powerdown_on_sleep, int, 0444); 59MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); 60 61#define dprintk if (dvb_frontend_debug) printk 62 63#define FESTATE_IDLE 1 64#define FESTATE_RETUNE 2 65#define FESTATE_TUNING_FAST 4 66#define FESTATE_TUNING_SLOW 8 67#define FESTATE_TUNED 16 68#define FESTATE_ZIGZAG_FAST 32 69#define FESTATE_ZIGZAG_SLOW 64 70#define FESTATE_DISEQC 128 71#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) 72#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) 73#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) 74#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) 75/* 76 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. 77 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. 78 * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress. 79 * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower. 80 * FESTATE_TUNED. The frontend has successfully locked on. 81 * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it. 82 * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower. 83 * FESTATE_DISEQC. A DISEQC command has just been issued. 84 * FESTATE_WAITFORLOCK. When we're waiting for a lock. 85 * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan. 86 * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan. 87 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. 88 */ 89 90static DECLARE_MUTEX(frontend_mutex); 91 92struct dvb_frontend_private { 93 94 struct dvb_device *dvbdev; 95 struct dvb_frontend_parameters parameters; 96 struct dvb_fe_events events; 97 struct semaphore sem; 98 struct list_head list_head; 99 wait_queue_head_t wait_queue; 100 pid_t thread_pid; 101 unsigned long release_jiffies; 102 int state; 103 int bending; 104 int lnb_drift; 105 int inversion; 106 int auto_step; 107 int auto_sub_step; 108 int started_auto_step; 109 int min_delay; 110 int max_drift; 111 int step_size; 112 int exit; 113 int wakeup; 114 fe_status_t status; 115}; 116 117 118static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) 119{ 120 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 121 struct dvb_fe_events *events = &fepriv->events; 122 struct dvb_frontend_event *e; 123 int wp; 124 125 dprintk ("%s\n", __FUNCTION__); 126 127 if (down_interruptible (&events->sem)) 128 return; 129 130 wp = (events->eventw + 1) % MAX_EVENT; 131 132 if (wp == events->eventr) { 133 events->overflow = 1; 134 events->eventr = (events->eventr + 1) % MAX_EVENT; 135 } 136 137 e = &events->events[events->eventw]; 138 139 memcpy (&e->parameters, &fepriv->parameters, 140 sizeof (struct dvb_frontend_parameters)); 141 142 if (status & FE_HAS_LOCK) 143 if (fe->ops->get_frontend) 144 fe->ops->get_frontend(fe, &e->parameters); 145 146 events->eventw = wp; 147 148 up (&events->sem); 149 150 e->status = status; 151 152 wake_up_interruptible (&events->wait_queue); 153} 154 155static int dvb_frontend_get_event(struct dvb_frontend *fe, 156 struct dvb_frontend_event *event, int flags) 157{ 158 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 159 struct dvb_fe_events *events = &fepriv->events; 160 161 dprintk ("%s\n", __FUNCTION__); 162 163 if (events->overflow) { 164 events->overflow = 0; 165 return -EOVERFLOW; 166 } 167 168 if (events->eventw == events->eventr) { 169 int ret; 170 171 if (flags & O_NONBLOCK) 172 return -EWOULDBLOCK; 173 174 up(&fepriv->sem); 175 176 ret = wait_event_interruptible (events->wait_queue, 177 events->eventw != events->eventr); 178 179 if (down_interruptible (&fepriv->sem)) 180 return -ERESTARTSYS; 181 182 if (ret < 0) 183 return ret; 184 } 185 186 if (down_interruptible (&events->sem)) 187 return -ERESTARTSYS; 188 189 memcpy (event, &events->events[events->eventr], 190 sizeof(struct dvb_frontend_event)); 191 192 events->eventr = (events->eventr + 1) % MAX_EVENT; 193 194 up (&events->sem); 195 196 return 0; 197} 198 199static void dvb_frontend_init(struct dvb_frontend *fe) 200{ 201 dprintk ("DVB: initialising frontend %i (%s)...\n", 202 fe->dvb->num, 203 fe->ops->info.name); 204 205 if (fe->ops->init) 206 fe->ops->init(fe); 207} 208 209static void update_delay(int *quality, int *delay, int min_delay, int locked) 210{ 211 int q2; 212 213 dprintk ("%s\n", __FUNCTION__); 214 215 if (locked) 216 (*quality) = (*quality * 220 + 36*256) / 256; 217 else 218 (*quality) = (*quality * 220 + 0) / 256; 219 220 q2 = *quality - 128; 221 q2 *= q2; 222 223 *delay = min_delay + q2 * HZ / (128*128); 224} 225 226/** 227 * Performs automatic twiddling of frontend parameters. 228 * 229 * @param fe The frontend concerned. 230 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT 231 * @returns Number of complete iterations that have been performed. 232 */ 233static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) 234{ 235 int autoinversion; 236 int ready = 0; 237 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 238 int original_inversion = fepriv->parameters.inversion; 239 u32 original_frequency = fepriv->parameters.frequency; 240 241 /* are we using autoinversion? */ 242 autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && 243 (fepriv->parameters.inversion == INVERSION_AUTO)); 244 245 /* setup parameters correctly */ 246 while(!ready) { 247 /* calculate the lnb_drift */ 248 fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size; 249 250 /* wrap the auto_step if we've exceeded the maximum drift */ 251 if (fepriv->lnb_drift > fepriv->max_drift) { 252 fepriv->auto_step = 0; 253 fepriv->auto_sub_step = 0; 254 fepriv->lnb_drift = 0; 255 } 256 257 /* perform inversion and +/- zigzag */ 258 switch(fepriv->auto_sub_step) { 259 case 0: 260 /* try with the current inversion and current drift setting */ 261 ready = 1; 262 break; 263 264 case 1: 265 if (!autoinversion) break; 266 267 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; 268 ready = 1; 269 break; 270 271 case 2: 272 if (fepriv->lnb_drift == 0) break; 273 274 fepriv->lnb_drift = -fepriv->lnb_drift; 275 ready = 1; 276 break; 277 278 case 3: 279 if (fepriv->lnb_drift == 0) break; 280 if (!autoinversion) break; 281 282 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; 283 fepriv->lnb_drift = -fepriv->lnb_drift; 284 ready = 1; 285 break; 286 287 default: 288 fepriv->auto_step++; 289 fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */ 290 break; 291 } 292 293 if (!ready) fepriv->auto_sub_step++; 294 } 295 296 /* if this attempt would hit where we started, indicate a complete 297 * iteration has occurred */ 298 if ((fepriv->auto_step == fepriv->started_auto_step) && 299 (fepriv->auto_sub_step == 0) && check_wrapped) { 300 return 1; 301 } 302 303 dprintk("%s: drift:%i inversion:%i auto_step:%i " 304 "auto_sub_step:%i started_auto_step:%i\n", 305 __FUNCTION__, fepriv->lnb_drift, fepriv->inversion, 306 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); 307 308 /* set the frontend itself */ 309 fepriv->parameters.frequency += fepriv->lnb_drift; 310 if (autoinversion) 311 fepriv->parameters.inversion = fepriv->inversion; 312 if (fe->ops->set_frontend) 313 fe->ops->set_frontend(fe, &fepriv->parameters); 314 315 fepriv->parameters.frequency = original_frequency; 316 fepriv->parameters.inversion = original_inversion; 317 318 fepriv->auto_sub_step++; 319 return 0; 320} 321 322static int dvb_frontend_is_exiting(struct dvb_frontend *fe) 323{ 324 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 325 326 if (fepriv->exit) 327 return 1; 328 329 if (fepriv->dvbdev->writers == 1) 330 if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ) 331 return 1; 332 333 return 0; 334} 335 336static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) 337{ 338 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 339 340 if (fepriv->wakeup) { 341 fepriv->wakeup = 0; 342 return 1; 343 } 344 return dvb_frontend_is_exiting(fe); 345} 346 347static void dvb_frontend_wakeup(struct dvb_frontend *fe) 348{ 349 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 350 351 fepriv->wakeup = 1; 352 wake_up_interruptible(&fepriv->wait_queue); 353} 354 355/* 356 * FIXME: use linux/kthread.h 357 */ 358static int dvb_frontend_thread(void *data) 359{ 360 struct dvb_frontend *fe = (struct dvb_frontend *) data; 361 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 362 unsigned long timeout; 363 char name [15]; 364 int quality = 0, delay = 3*HZ; 365 fe_status_t s; 366 int check_wrapped = 0; 367 368 dprintk("%s\n", __FUNCTION__); 369 370 snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num); 371 372 lock_kernel(); 373 daemonize(name); 374 sigfillset(¤t->blocked); 375 unlock_kernel(); 376 377 fepriv->status = 0; 378 dvb_frontend_init(fe); 379 fepriv->wakeup = 0; 380 381 while (1) { 382 up(&fepriv->sem); /* is locked when we enter the thread... */ 383 384 timeout = wait_event_interruptible_timeout(fepriv->wait_queue, 385 dvb_frontend_should_wakeup(fe), 386 delay); 387 if (0 != dvb_frontend_is_exiting(fe)) { 388 /* got signal or quitting */ 389 break; 390 } 391 392 if (current->flags & PF_FREEZE) 393 refrigerator(PF_FREEZE); 394 395 if (down_interruptible(&fepriv->sem)) 396 break; 397 398 /* if we've got no parameters, just keep idling */ 399 if (fepriv->state & FESTATE_IDLE) { 400 delay = 3*HZ; 401 quality = 0; 402 continue; 403 } 404 405 /* get the frontend status */ 406 if (fepriv->state & FESTATE_RETUNE) { 407 s = 0; 408 } else { 409 if (fe->ops->read_status) 410 fe->ops->read_status(fe, &s); 411 if (s != fepriv->status) { 412 dvb_frontend_add_event(fe, s); 413 fepriv->status = s; 414 } 415 } 416 /* if we're not tuned, and we have a lock, move to the TUNED state */ 417 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { 418 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 419 fepriv->state = FESTATE_TUNED; 420 421 /* if we're tuned, then we have determined the correct inversion */ 422 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && 423 (fepriv->parameters.inversion == INVERSION_AUTO)) { 424 fepriv->parameters.inversion = fepriv->inversion; 425 } 426 continue; 427 } 428 429 /* if we are tuned already, check we're still locked */ 430 if (fepriv->state & FESTATE_TUNED) { 431 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 432 433 /* we're tuned, and the lock is still good... */ 434 if (s & FE_HAS_LOCK) 435 continue; 436 else { 437 /* if we _WERE_ tuned, but now don't have a lock, 438 * need to zigzag */ 439 fepriv->state = FESTATE_ZIGZAG_FAST; 440 fepriv->started_auto_step = fepriv->auto_step; 441 check_wrapped = 0; 442 } 443 } 444 445 /* don't actually do anything if we're in the LOSTLOCK state, 446 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ 447 if ((fepriv->state & FESTATE_LOSTLOCK) && 448 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { 449 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 450 continue; 451 } 452 453 /* don't do anything if we're in the DISEQC state, since this 454 * might be someone with a motorized dish controlled by DISEQC. 455 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ 456 if (fepriv->state & FESTATE_DISEQC) { 457 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 458 continue; 459 } 460 461 /* if we're in the RETUNE state, set everything up for a brand 462 * new scan, keeping the current inversion setting, as the next 463 * tune is _very_ likely to require the same */ 464 if (fepriv->state & FESTATE_RETUNE) { 465 fepriv->lnb_drift = 0; 466 fepriv->auto_step = 0; 467 fepriv->auto_sub_step = 0; 468 fepriv->started_auto_step = 0; 469 check_wrapped = 0; 470 } 471 472 /* fast zigzag. */ 473 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { 474 delay = fepriv->min_delay; 475 476 /* peform a tune */ 477 if (dvb_frontend_autotune(fe, check_wrapped)) { 478 /* OK, if we've run out of trials at the fast speed. 479 * Drop back to slow for the _next_ attempt */ 480 fepriv->state = FESTATE_SEARCHING_SLOW; 481 fepriv->started_auto_step = fepriv->auto_step; 482 continue; 483 } 484 check_wrapped = 1; 485 486 /* if we've just retuned, enter the ZIGZAG_FAST state. 487 * This ensures we cannot return from an 488 * FE_SET_FRONTEND ioctl before the first frontend tune 489 * occurs */ 490 if (fepriv->state & FESTATE_RETUNE) { 491 fepriv->state = FESTATE_TUNING_FAST; 492 } 493 } 494 495 /* slow zigzag */ 496 if (fepriv->state & FESTATE_SEARCHING_SLOW) { 497 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 498 499 /* Note: don't bother checking for wrapping; we stay in this 500 * state until we get a lock */ 501 dvb_frontend_autotune(fe, 0); 502 } 503 } 504 505 if (dvb_shutdown_timeout) { 506 if (dvb_powerdown_on_sleep) 507 if (fe->ops->set_voltage) 508 fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF); 509 if (fe->ops->sleep) 510 fe->ops->sleep(fe); 511 } 512 513 fepriv->thread_pid = 0; 514 mb(); 515 516 dvb_frontend_wakeup(fe); 517 return 0; 518} 519 520static void dvb_frontend_stop(struct dvb_frontend *fe) 521{ 522 unsigned long ret; 523 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 524 525 dprintk ("%s\n", __FUNCTION__); 526 527 fepriv->exit = 1; 528 mb(); 529 530 if (!fepriv->thread_pid) 531 return; 532 533 /* check if the thread is really alive */ 534 if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { 535 printk("dvb_frontend_stop: thread PID %d already died\n", 536 fepriv->thread_pid); 537 /* make sure the mutex was not held by the thread */ 538 init_MUTEX (&fepriv->sem); 539 return; 540 } 541 542 /* wake up the frontend thread, so it notices that fe->exit == 1 */ 543 dvb_frontend_wakeup(fe); 544 545 /* wait until the frontend thread has exited */ 546 ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid); 547 if (-ERESTARTSYS != ret) { 548 fepriv->state = FESTATE_IDLE; 549 return; 550 } 551 fepriv->state = FESTATE_IDLE; 552 553 /* paranoia check in case a signal arrived */ 554 if (fepriv->thread_pid) 555 printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", 556 fepriv->thread_pid); 557} 558 559static int dvb_frontend_start(struct dvb_frontend *fe) 560{ 561 int ret; 562 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 563 564 dprintk ("%s\n", __FUNCTION__); 565 566 if (fepriv->thread_pid) { 567 if (!fepriv->exit) 568 return 0; 569 else 570 dvb_frontend_stop (fe); 571 } 572 573 if (signal_pending(current)) 574 return -EINTR; 575 if (down_interruptible (&fepriv->sem)) 576 return -EINTR; 577 578 fepriv->state = FESTATE_IDLE; 579 fepriv->exit = 0; 580 fepriv->thread_pid = 0; 581 mb(); 582 583 ret = kernel_thread (dvb_frontend_thread, fe, 0); 584 585 if (ret < 0) { 586 printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); 587 up(&fepriv->sem); 588 return ret; 589 } 590 fepriv->thread_pid = ret; 591 592 return 0; 593} 594 595static int dvb_frontend_ioctl(struct inode *inode, struct file *file, 596 unsigned int cmd, void *parg) 597{ 598 struct dvb_device *dvbdev = file->private_data; 599 struct dvb_frontend *fe = dvbdev->priv; 600 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 601 int err = -EOPNOTSUPP; 602 603 dprintk ("%s\n", __FUNCTION__); 604 605 if (!fe || fepriv->exit) 606 return -ENODEV; 607 608 if ((file->f_flags & O_ACCMODE) == O_RDONLY && 609 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT || 610 cmd == FE_DISEQC_RECV_SLAVE_REPLY)) 611 return -EPERM; 612 613 if (down_interruptible (&fepriv->sem)) 614 return -ERESTARTSYS; 615 616 switch (cmd) { 617 case FE_GET_INFO: { 618 struct dvb_frontend_info* info = (struct dvb_frontend_info*) parg; 619 memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); 620 621 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't 622 * do it, it is done for it. */ 623 info->caps |= FE_CAN_INVERSION_AUTO; 624 err = 0; 625 break; 626 } 627 628 case FE_READ_STATUS: 629 if (fe->ops->read_status) 630 err = fe->ops->read_status(fe, (fe_status_t*) parg); 631 break; 632 633 case FE_READ_BER: 634 if (fe->ops->read_ber) 635 err = fe->ops->read_ber(fe, (__u32*) parg); 636 break; 637 638 case FE_READ_SIGNAL_STRENGTH: 639 if (fe->ops->read_signal_strength) 640 err = fe->ops->read_signal_strength(fe, (__u16*) parg); 641 break; 642 643 case FE_READ_SNR: 644 if (fe->ops->read_snr) 645 err = fe->ops->read_snr(fe, (__u16*) parg); 646 break; 647 648 case FE_READ_UNCORRECTED_BLOCKS: 649 if (fe->ops->read_ucblocks) 650 err = fe->ops->read_ucblocks(fe, (__u32*) parg); 651 break; 652 653 654 case FE_DISEQC_RESET_OVERLOAD: 655 if (fe->ops->diseqc_reset_overload) { 656 err = fe->ops->diseqc_reset_overload(fe); 657 fepriv->state = FESTATE_DISEQC; 658 fepriv->status = 0; 659 } 660 break; 661 662 case FE_DISEQC_SEND_MASTER_CMD: 663 if (fe->ops->diseqc_send_master_cmd) { 664 err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); 665 fepriv->state = FESTATE_DISEQC; 666 fepriv->status = 0; 667 } 668 break; 669 670 case FE_DISEQC_SEND_BURST: 671 if (fe->ops->diseqc_send_burst) { 672 err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); 673 fepriv->state = FESTATE_DISEQC; 674 fepriv->status = 0; 675 } 676 break; 677 678 case FE_SET_TONE: 679 if (fe->ops->set_tone) { 680 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); 681 fepriv->state = FESTATE_DISEQC; 682 fepriv->status = 0; 683 } 684 break; 685 686 case FE_SET_VOLTAGE: 687 if (fe->ops->set_voltage) { 688 err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); 689 fepriv->state = FESTATE_DISEQC; 690 fepriv->status = 0; 691 } 692 break; 693 694 case FE_DISHNETWORK_SEND_LEGACY_CMD: 695 if (fe->ops->dishnetwork_send_legacy_command) { 696 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 697 fepriv->state = FESTATE_DISEQC; 698 fepriv->status = 0; 699 } 700 break; 701 702 case FE_DISEQC_RECV_SLAVE_REPLY: 703 if (fe->ops->diseqc_recv_slave_reply) 704 err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); 705 break; 706 707 case FE_ENABLE_HIGH_LNB_VOLTAGE: 708 if (fe->ops->enable_high_lnb_voltage) 709 err = fe->ops->enable_high_lnb_voltage(fe, (int) parg); 710 break; 711 712 case FE_SET_FRONTEND: { 713 struct dvb_frontend_tune_settings fetunesettings; 714 715 memcpy (&fepriv->parameters, parg, 716 sizeof (struct dvb_frontend_parameters)); 717 718 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); 719 memcpy(&fetunesettings.parameters, parg, 720 sizeof (struct dvb_frontend_parameters)); 721 722 /* force auto frequency inversion if requested */ 723 if (dvb_force_auto_inversion) { 724 fepriv->parameters.inversion = INVERSION_AUTO; 725 fetunesettings.parameters.inversion = INVERSION_AUTO; 726 } 727 if (fe->ops->info.type == FE_OFDM) { 728 /* without hierachical coding code_rate_LP is irrelevant, 729 * so we tolerate the otherwise invalid FEC_NONE setting */ 730 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && 731 fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) 732 fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO; 733 } 734 735 /* get frontend-specific tuning settings */ 736 if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) { 737 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; 738 fepriv->max_drift = fetunesettings.max_drift; 739 fepriv->step_size = fetunesettings.step_size; 740 } else { 741 /* default values */ 742 switch(fe->ops->info.type) { 743 case FE_QPSK: 744 fepriv->min_delay = HZ/20; 745 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; 746 fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000; 747 break; 748 749 case FE_QAM: 750 fepriv->min_delay = HZ/20; 751 fepriv->step_size = 0; /* no zigzag */ 752 fepriv->max_drift = 0; 753 break; 754 755 case FE_OFDM: 756 fepriv->min_delay = HZ/20; 757 fepriv->step_size = fe->ops->info.frequency_stepsize * 2; 758 fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1; 759 break; 760 case FE_ATSC: 761 printk("dvb-core: FE_ATSC not handled yet.\n"); 762 break; 763 } 764 } 765 if (dvb_override_tune_delay > 0) 766 fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; 767 768 fepriv->state = FESTATE_RETUNE; 769 dvb_frontend_wakeup(fe); 770 dvb_frontend_add_event(fe, 0); 771 fepriv->status = 0; 772 err = 0; 773 break; 774 } 775 776 case FE_GET_EVENT: 777 err = dvb_frontend_get_event (fe, parg, file->f_flags); 778 break; 779 780 case FE_GET_FRONTEND: 781 if (fe->ops->get_frontend) { 782 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); 783 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); 784 } 785 break; 786 }; 787 788 up (&fepriv->sem); 789 return err; 790} 791 792static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) 793{ 794 struct dvb_device *dvbdev = file->private_data; 795 struct dvb_frontend *fe = dvbdev->priv; 796 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 797 798 dprintk ("%s\n", __FUNCTION__); 799 800 poll_wait (file, &fepriv->events.wait_queue, wait); 801 802 if (fepriv->events.eventw != fepriv->events.eventr) 803 return (POLLIN | POLLRDNORM | POLLPRI); 804 805 return 0; 806} 807 808static int dvb_frontend_open(struct inode *inode, struct file *file) 809{ 810 struct dvb_device *dvbdev = file->private_data; 811 struct dvb_frontend *fe = dvbdev->priv; 812 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 813 int ret; 814 815 dprintk ("%s\n", __FUNCTION__); 816 817 if ((ret = dvb_generic_open (inode, file)) < 0) 818 return ret; 819 820 if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 821 ret = dvb_frontend_start (fe); 822 if (ret) 823 dvb_generic_release (inode, file); 824 825 /* empty event queue */ 826 fepriv->events.eventr = fepriv->events.eventw = 0; 827 } 828 829 return ret; 830} 831 832static int dvb_frontend_release(struct inode *inode, struct file *file) 833{ 834 struct dvb_device *dvbdev = file->private_data; 835 struct dvb_frontend *fe = dvbdev->priv; 836 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 837 838 dprintk ("%s\n", __FUNCTION__); 839 840 if ((file->f_flags & O_ACCMODE) != O_RDONLY) 841 fepriv->release_jiffies = jiffies; 842 843 return dvb_generic_release (inode, file); 844} 845 846static struct file_operations dvb_frontend_fops = { 847 .owner = THIS_MODULE, 848 .ioctl = dvb_generic_ioctl, 849 .poll = dvb_frontend_poll, 850 .open = dvb_frontend_open, 851 .release = dvb_frontend_release 852}; 853 854int dvb_register_frontend(struct dvb_adapter* dvb, 855 struct dvb_frontend* fe) 856{ 857 struct dvb_frontend_private *fepriv; 858 static const struct dvb_device dvbdev_template = { 859 .users = ~0, 860 .writers = 1, 861 .readers = (~0)-1, 862 .fops = &dvb_frontend_fops, 863 .kernel_ioctl = dvb_frontend_ioctl 864 }; 865 866 dprintk ("%s\n", __FUNCTION__); 867 868 if (down_interruptible (&frontend_mutex)) 869 return -ERESTARTSYS; 870 871 fe->frontend_priv = kmalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); 872 if (fe->frontend_priv == NULL) { 873 up(&frontend_mutex); 874 return -ENOMEM; 875 } 876 fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 877 memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private)); 878 879 init_MUTEX (&fepriv->sem); 880 init_waitqueue_head (&fepriv->wait_queue); 881 init_waitqueue_head (&fepriv->events.wait_queue); 882 init_MUTEX (&fepriv->events.sem); 883 fe->dvb = dvb; 884 fepriv->inversion = INVERSION_OFF; 885 886 printk ("DVB: registering frontend %i (%s)...\n", 887 fe->dvb->num, 888 fe->ops->info.name); 889 890 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, 891 fe, DVB_DEVICE_FRONTEND); 892 893 up (&frontend_mutex); 894 return 0; 895} 896EXPORT_SYMBOL(dvb_register_frontend); 897 898int dvb_unregister_frontend(struct dvb_frontend* fe) 899{ 900 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; 901 dprintk ("%s\n", __FUNCTION__); 902 903 down (&frontend_mutex); 904 dvb_unregister_device (fepriv->dvbdev); 905 dvb_frontend_stop (fe); 906 if (fe->ops->release) 907 fe->ops->release(fe); 908 else 909 printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); 910 /* fe is invalid now */ 911 kfree(fepriv); 912 up (&frontend_mutex); 913 return 0; 914} 915EXPORT_SYMBOL(dvb_unregister_frontend); 916