コード例 #1
0
ファイル: dvb_frontend.c プロジェクト: ivucica/linux
static int dvb_frontend_thread(void *data)
{
	struct dvb_frontend *fe = data;
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	unsigned long timeout;
	char name [15];
	fe_status_t s;
	struct dvb_frontend_parameters *params;

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

	snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);

	lock_kernel();
	daemonize(name);
	sigfillset(&current->blocked);
	unlock_kernel();

	fepriv->check_wrapped = 0;
	fepriv->quality = 0;
	fepriv->delay = 3*HZ;
	fepriv->status = 0;
	fepriv->wakeup = 0;
	fepriv->reinitialise = 0;

	dvb_frontend_init(fe);

	while (1) {
		up(&fepriv->sem);	    /* is locked when we enter the thread... */

		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
							   dvb_frontend_should_wakeup(fe),
							   fepriv->delay);
		if (0 != dvb_frontend_is_exiting(fe)) {
			/* got signal or quitting */
			break;
		}

		try_to_freeze();

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

		if (fepriv->reinitialise) {
			dvb_frontend_init(fe);
			if (fepriv->tone != -1) {
				fe->ops.set_tone(fe, fepriv->tone);
			}
			if (fepriv->voltage != -1) {
				fe->ops.set_voltage(fe, fepriv->voltage);
			}
			fepriv->reinitialise = 0;
		}

		/* do an iteration of the tuning loop */
		if (fe->ops.get_frontend_algo) {
			if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
				/* have we been asked to retune? */
				params = NULL;
				if (fepriv->state & FESTATE_RETUNE) {
					params = &fepriv->parameters;
					fepriv->state = FESTATE_TUNED;
				}

				fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
				if (s != fepriv->status) {
					dvb_frontend_add_event(fe, s);
					fepriv->status = s;
				}
			} else
				dvb_frontend_swzigzag(fe);
		} else
			dvb_frontend_swzigzag(fe);
	}

	if (dvb_shutdown_timeout) {
		if (dvb_powerdown_on_sleep)
			if (fe->ops.set_voltage)
				fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
		if (fe->ops.tuner_ops.sleep) {
			fe->ops.tuner_ops.sleep(fe);
			if (fe->ops.i2c_gate_ctrl)
				fe->ops.i2c_gate_ctrl(fe, 0);
		}
		if (fe->ops.sleep)
			fe->ops.sleep(fe);
	}

	fepriv->thread_pid = 0;
	mb();

	dvb_frontend_wakeup(fe);
	return 0;
}
コード例 #2
0
/*
 * FIXME: use linux/kthread.h
 */
static int dvb_frontend_thread(void *data)
{
	struct dvb_frontend *fe = data;
	struct dvb_frontend_private *fepriv = fe->frontend_priv;
	unsigned long timeout;
	char name [15];
	int quality = 0, delay = 3*HZ;
	fe_status_t s;
	int check_wrapped = 0;

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

	snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);

        lock_kernel();
        daemonize(name);
        sigfillset(&current->blocked);
        unlock_kernel();

	fepriv->status = 0;
	dvb_frontend_init(fe);
	fepriv->wakeup = 0;

	while (1) {
		up(&fepriv->sem);	    /* is locked when we enter the thread... */

		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
							   dvb_frontend_should_wakeup(fe),
							   delay);
		if (0 != dvb_frontend_is_exiting(fe)) {
			/* got signal or quitting */
			break;
		}

		if (current->flags & PF_FREEZE)
			refrigerator(PF_FREEZE);

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

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

		/* get the frontend status */
		if (fepriv->state & FESTATE_RETUNE) {
			s = 0;
		} else {
			if (fe->ops->read_status)
				fe->ops->read_status(fe, &s);
			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)) {
			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
			fepriv->state = FESTATE_TUNED;

			/* if we're tuned, then we have determined the correct inversion */
			if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
			    (fepriv->parameters.inversion == INVERSION_AUTO)) {
				fepriv->parameters.inversion = fepriv->inversion;
			}
			continue;
		}

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

			/* we're tuned, and the lock is still good... */
			if (s & FE_HAS_LOCK){
				delay = HZ >> 1;    /* kevin_add for speed up update speed */
				continue;
			}
			else {
コード例 #3
0
/*
 * FIXME: use linux/kthread.h
 */
static int dvb_frontend_thread (void *data)
{
	struct dvb_frontend *fe = (struct dvb_frontend *) data;
	unsigned long timeout;
	char name [15];
	int quality = 0, delay = 3*HZ;
	fe_status_t s;
	int check_wrapped = 0;

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

	snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);

        lock_kernel ();
        daemonize (name);
        sigfillset (&current->blocked);
        unlock_kernel ();

	fe->status = 0;
	dvb_frontend_init (fe);
	fe->wakeup = 0;

	while (1) {
		up (&fe->sem);      /* is locked when we enter the thread... */

		timeout = wait_event_interruptible_timeout(fe->wait_queue,
							   dvb_frontend_should_wakeup(fe),
							   delay);
		if (0 != dvb_frontend_is_exiting (fe)) {
			/* got signal or quitting */
			break;
		}

		if (current->flags & PF_FREEZE)
			refrigerator(PF_FREEZE);

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

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

retune:
		/* get the frontend status */
		if (fe->state & FESTATE_RETUNE) {
			s = 0;
		} else {
			if (fe->ops->read_status)
				fe->ops->read_status(fe, &s);
			if (s != fe->status) {
			dvb_frontend_add_event (fe, s);
				fe->status = s;
			}
		}
		/* if we're not tuned, and we have a lock, move to the TUNED state */
		if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
			fe->state = FESTATE_TUNED;

			/* if we're tuned, then we have determined the correct inversion */
			if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
			    (fe->parameters.inversion == INVERSION_AUTO)) {
				fe->parameters.inversion = fe->inversion;
			}
			continue;
		}

		/* if we are tuned already, check we're still locked */
		if (fe->state & FESTATE_TUNED) {
			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);

			/* we're tuned, and the lock is still good... */
			if (s & FE_HAS_LOCK)
				continue;
			else {
				/* if we _WERE_ tuned, but now don't have a lock,
				 * need to zigzag */
				fe->state = FESTATE_ZIGZAG_FAST;
				fe->started_auto_step = fe->auto_step;
				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 ((fe->state & FESTATE_LOSTLOCK) && 
		    (fe->ops->info.caps & FE_CAN_RECOVER) && (fe->max_drift == 0)) {
			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
						continue;
				}
	    
		/* 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 (fe->state & FESTATE_DISEQC) {
			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
			continue;
				}

		/* 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 (fe->state & FESTATE_RETUNE) {
			fe->lnb_drift = 0;
			fe->auto_step = 0;
			fe->auto_sub_step = 0;
			fe->started_auto_step = 0;
			check_wrapped = 0;
		}

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

			/* peform a tune */
			if (dvb_frontend_autotune(fe, check_wrapped)) {
				/* OK, if we've run out of trials at the fast speed.
				 * Drop back to slow for the _next_ attempt */
				fe->state = FESTATE_SEARCHING_SLOW;
				fe->started_auto_step = fe->auto_step;
				continue;
			}
			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 (fe->state & FESTATE_RETUNE) {
				fe->state = FESTATE_TUNING_FAST;
				goto retune;
			}
		}

		/* slow zigzag */
		if (fe->state & FESTATE_SEARCHING_SLOW) {
			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
		    
			/* Note: don't bother checking for wrapping; we stay in this
			 * state until we get a lock */
			dvb_frontend_autotune(fe, 0);
		}
	}

	if (dvb_shutdown_timeout) {
		if (dvb_powerdown_on_sleep)
			if (fe->ops->set_voltage)
				fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF);
		if (fe->ops->sleep)
			fe->ops->sleep(fe);
	}

	fe->thread_pid = 0;
	mb();

	dvb_frontend_wakeup(fe);
	return 0;
}
コード例 #4
0
ファイル: dvb_frontend.c プロジェクト: 274914765/C
static int dvb_frontend_thread(void *data)
{
    struct dvb_frontend *fe = data;
    struct dvb_frontend_private *fepriv = fe->frontend_priv;
    unsigned long timeout;
    fe_status_t s;
    struct dvb_frontend_parameters *params;

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

    fepriv->check_wrapped = 0;
    fepriv->quality = 0;
    fepriv->delay = 3*HZ;
    fepriv->status = 0;
    fepriv->wakeup = 0;
    fepriv->reinitialise = 0;

    dvb_frontend_init(fe);

    set_freezable();
    while (1) {
        up(&fepriv->sem);        /* is locked when we enter the thread... */
restart:
        timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
            dvb_frontend_should_wakeup(fe) || kthread_should_stop()
                || freezing(current),
            fepriv->delay);

        if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
            /* got signal or quitting */
            break;
        }

        if (try_to_freeze())
            goto restart;

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

        if (fepriv->reinitialise) {
            dvb_frontend_init(fe);
            if (fepriv->tone != -1) {
                fe->ops.set_tone(fe, fepriv->tone);
            }
            if (fepriv->voltage != -1) {
                fe->ops.set_voltage(fe, fepriv->voltage);
            }
            fepriv->reinitialise = 0;
        }

        /* do an iteration of the tuning loop */
        if (fe->ops.get_frontend_algo) {
            if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
                /* have we been asked to retune? */
                params = NULL;
                if (fepriv->state & FESTATE_RETUNE) {
                    params = &fepriv->parameters;
                    fepriv->state = FESTATE_TUNED;
                }

                fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
                if (s != fepriv->status) {
                    dvb_frontend_add_event(fe, s);
                    fepriv->status = s;
                }
            } else
                dvb_frontend_swzigzag(fe);
        } else
            dvb_frontend_swzigzag(fe);
    }

    if (dvb_powerdown_on_sleep) {
        if (fe->ops.set_voltage)
            fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
        if (fe->ops.tuner_ops.sleep) {
            fe->ops.tuner_ops.sleep(fe);
            if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0);
        }
        if (fe->ops.sleep)
            fe->ops.sleep(fe);
    }

    fepriv->thread = NULL;
    mb();

    dvb_frontend_wakeup(fe);
    return 0;
}