Loading drivers/media/dvb/bt8xx/dst.c +31 −21 Original line number Diff line number Diff line Loading @@ -1341,10 +1341,15 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* p, unsigned int mode_flags, int *delay, fe_status_t *status) { struct dst_state *state = fe->demodulator_priv; if (p != NULL) { dst_set_freq(state, p->frequency); dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); Loading @@ -1364,7 +1369,12 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet dst_set_modulation(state, p->u.qam.modulation); } dst_write_tuna(fe); } if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) dst_read_status(fe, status); *delay = HZ/10; return 0; } Loading Loading @@ -1445,7 +1455,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading @@ -1469,7 +1479,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading @@ -1496,7 +1506,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading drivers/media/dvb/dvb-core/dvb_frontend.c +177 −130 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ static DECLARE_MUTEX(frontend_mutex); struct dvb_frontend_private { /* thread/frontend values */ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters; struct dvb_fe_events events; Loading @@ -100,20 +101,25 @@ struct dvb_frontend_private { wait_queue_head_t wait_queue; pid_t thread_pid; unsigned long release_jiffies; int state; int bending; int lnb_drift; int inversion; int auto_step; int auto_sub_step; int started_auto_step; int min_delay; int max_drift; int step_size; int exit; int wakeup; unsigned int exit; unsigned int wakeup; fe_status_t status; fe_sec_tone_mode_t tone; unsigned int tune_mode_flags; unsigned int delay; /* 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; }; Loading Loading @@ -208,21 +214,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe) fe->ops->init(fe); } static void update_delay(int *quality, int *delay, int min_delay, int locked) static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) { int q2; dprintk ("%s\n", __FUNCTION__); if (locked) (*quality) = (*quality * 220 + 36*256) / 256; (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; else (*quality) = (*quality * 220 + 0) / 256; (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; q2 = *quality - 128; q2 = fepriv->quality - 128; q2 *= q2; *delay = min_delay + q2 * HZ / (128*128); fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); } /** Loading @@ -232,7 +238,7 @@ static void update_delay(int *quality, int *delay, int min_delay, int locked) * @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. */ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) { int autoinversion; int ready = 0; Loading Loading @@ -321,87 +327,28 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) return 0; } static int dvb_frontend_is_exiting(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->exit) return 1; if (fepriv->dvbdev->writers == 1) if (time_after(jiffies, fepriv->release_jiffies + dvb_shutdown_timeout * HZ)) return 1; return 0; } static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->wakeup) { fepriv->wakeup = 0; return 1; } return dvb_frontend_is_exiting(fe); } static void dvb_frontend_wakeup(struct dvb_frontend *fe) static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { fe_status_t s; struct dvb_frontend_private *fepriv = fe->frontend_priv; fepriv->wakeup = 1; wake_up_interruptible(&fepriv->wait_queue); /* if we've got no parameters, just keep idling */ if (fepriv->state & FESTATE_IDLE) { fepriv->delay = 3*HZ; fepriv->quality = 0; return; } /* * 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(¤t->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; /* 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) { if (fe->ops->set_frontend) fe->ops->set_frontend(fe, &fepriv->parameters); fepriv->state = FESTATE_TUNED; } try_to_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; fepriv->delay = 3*HZ; fepriv->quality = 0; return; } /* get the frontend status */ Loading @@ -415,9 +362,10 @@ static int dvb_frontend_thread(void *data) 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); 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 */ Loading @@ -425,20 +373,20 @@ static int dvb_frontend_thread(void *data) (fepriv->parameters.inversion == INVERSION_AUTO)) { fepriv->parameters.inversion = fepriv->inversion; } continue; return; } /* 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); dvb_frontend_swzigzag_update_delay(fepriv, 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 */ 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; check_wrapped = 0; fepriv->check_wrapped = 0; } } Loading @@ -446,16 +394,16 @@ static int dvb_frontend_thread(void *data) * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ if ((fepriv->state & FESTATE_LOSTLOCK) && (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); continue; 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) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); continue; dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); return; } /* if we're in the RETUNE state, set everything up for a brand Loading @@ -466,22 +414,22 @@ static int dvb_frontend_thread(void *data) fepriv->auto_step = 0; fepriv->auto_sub_step = 0; fepriv->started_auto_step = 0; check_wrapped = 0; fepriv->check_wrapped = 0; } /* fast zigzag. */ if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { delay = fepriv->min_delay; fepriv->delay = fepriv->min_delay; /* peform a tune */ if (dvb_frontend_autotune(fe, check_wrapped)) { if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { /* 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; continue; return; } check_wrapped = 1; fepriv->check_wrapped = 1; /* if we've just retuned, enter the ZIGZAG_FAST state. * This ensures we cannot return from an Loading @@ -494,11 +442,105 @@ static int dvb_frontend_thread(void *data) /* slow zigzag */ if (fepriv->state & FESTATE_SEARCHING_SLOW) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 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_autotune(fe, 0); dvb_frontend_swzigzag_autotune(fe, 0); } } static int dvb_frontend_is_exiting(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->exit) return 1; if (fepriv->dvbdev->writers == 1) if (time_after(jiffies, fepriv->release_jiffies + dvb_shutdown_timeout * HZ)) return 1; return 0; } static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->wakeup) { fepriv->wakeup = 0; return 1; } return dvb_frontend_is_exiting(fe); } static void dvb_frontend_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; fepriv->wakeup = 1; wake_up_interruptible(&fepriv->wait_queue); } 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(¤t->blocked); unlock_kernel(); fepriv->check_wrapped = 0; fepriv->quality = 0; fepriv->delay = 3*HZ; 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), fepriv->delay); if (0 != dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ break; } try_to_freeze(); if (down_interruptible(&fepriv->sem)) break; /* do an iteration of the tuning loop */ if (fe->ops->tune) { /* 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); } } Loading Loading @@ -733,7 +775,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; fepriv->tone = (fe_sec_tone_mode_t) parg; } break; Loading Loading @@ -891,6 +932,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); } break; case FE_SET_FRONTEND_TUNE_MODE: fepriv->tune_mode_flags = (unsigned int) parg; break; }; up (&fepriv->sem); Loading Loading @@ -932,6 +977,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; /* normal tune mode when opened R/W */ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; } return ret; Loading Loading @@ -990,7 +1038,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb, init_MUTEX (&fepriv->events.sem); fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; fepriv->tone = SEC_TONE_OFF; printk ("DVB: registering frontend %i (%s)...\n", fe->dvb->num, Loading drivers/media/dvb/dvb-core/dvb_frontend.h +10 −1 Original line number Diff line number Diff line Loading @@ -58,10 +58,19 @@ struct dvb_frontend_ops { int (*init)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe); /* if this is set, it overrides the default swzigzag */ int (*tune)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, unsigned int mode_flags, int *delay, fe_status_t *status); /* these two are only used for the swzigzag code */ int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); int (*read_ber)(struct dvb_frontend* fe, u32* ber); int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); Loading include/linux/dvb/frontend.h +10 −0 Original line number Diff line number Diff line Loading @@ -240,6 +240,15 @@ struct dvb_frontend_event { }; /** * When set, this flag will disable any zigzagging or other "normal" tuning * behaviour. Additionally, there will be no automatic monitoring of the lock * status, and hence no frontend events will be generated. If a frontend device * is closed, this flag will be automatically turned off when the device is * reopened read-write. */ #define FE_TUNE_MODE_ONESHOT 0x01 #define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) Loading @@ -260,6 +269,7 @@ struct dvb_frontend_event { #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) #define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ #define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ Loading Loading
drivers/media/dvb/bt8xx/dst.c +31 −21 Original line number Diff line number Diff line Loading @@ -1341,10 +1341,15 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* p, unsigned int mode_flags, int *delay, fe_status_t *status) { struct dst_state *state = fe->demodulator_priv; if (p != NULL) { dst_set_freq(state, p->frequency); dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); Loading @@ -1364,7 +1369,12 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet dst_set_modulation(state, p->u.qam.modulation); } dst_write_tuna(fe); } if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) dst_read_status(fe, status); *delay = HZ/10; return 0; } Loading Loading @@ -1445,7 +1455,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading @@ -1469,7 +1479,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading @@ -1496,7 +1506,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { .release = dst_release, .init = dst_init, .set_frontend = dst_set_frontend, .tune = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, Loading
drivers/media/dvb/dvb-core/dvb_frontend.c +177 −130 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ static DECLARE_MUTEX(frontend_mutex); struct dvb_frontend_private { /* thread/frontend values */ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters; struct dvb_fe_events events; Loading @@ -100,20 +101,25 @@ struct dvb_frontend_private { wait_queue_head_t wait_queue; pid_t thread_pid; unsigned long release_jiffies; int state; int bending; int lnb_drift; int inversion; int auto_step; int auto_sub_step; int started_auto_step; int min_delay; int max_drift; int step_size; int exit; int wakeup; unsigned int exit; unsigned int wakeup; fe_status_t status; fe_sec_tone_mode_t tone; unsigned int tune_mode_flags; unsigned int delay; /* 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; }; Loading Loading @@ -208,21 +214,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe) fe->ops->init(fe); } static void update_delay(int *quality, int *delay, int min_delay, int locked) static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) { int q2; dprintk ("%s\n", __FUNCTION__); if (locked) (*quality) = (*quality * 220 + 36*256) / 256; (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; else (*quality) = (*quality * 220 + 0) / 256; (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; q2 = *quality - 128; q2 = fepriv->quality - 128; q2 *= q2; *delay = min_delay + q2 * HZ / (128*128); fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); } /** Loading @@ -232,7 +238,7 @@ static void update_delay(int *quality, int *delay, int min_delay, int locked) * @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. */ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) { int autoinversion; int ready = 0; Loading Loading @@ -321,87 +327,28 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) return 0; } static int dvb_frontend_is_exiting(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->exit) return 1; if (fepriv->dvbdev->writers == 1) if (time_after(jiffies, fepriv->release_jiffies + dvb_shutdown_timeout * HZ)) return 1; return 0; } static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->wakeup) { fepriv->wakeup = 0; return 1; } return dvb_frontend_is_exiting(fe); } static void dvb_frontend_wakeup(struct dvb_frontend *fe) static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { fe_status_t s; struct dvb_frontend_private *fepriv = fe->frontend_priv; fepriv->wakeup = 1; wake_up_interruptible(&fepriv->wait_queue); /* if we've got no parameters, just keep idling */ if (fepriv->state & FESTATE_IDLE) { fepriv->delay = 3*HZ; fepriv->quality = 0; return; } /* * 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(¤t->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; /* 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) { if (fe->ops->set_frontend) fe->ops->set_frontend(fe, &fepriv->parameters); fepriv->state = FESTATE_TUNED; } try_to_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; fepriv->delay = 3*HZ; fepriv->quality = 0; return; } /* get the frontend status */ Loading @@ -415,9 +362,10 @@ static int dvb_frontend_thread(void *data) 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); 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 */ Loading @@ -425,20 +373,20 @@ static int dvb_frontend_thread(void *data) (fepriv->parameters.inversion == INVERSION_AUTO)) { fepriv->parameters.inversion = fepriv->inversion; } continue; return; } /* 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); dvb_frontend_swzigzag_update_delay(fepriv, 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 */ 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; check_wrapped = 0; fepriv->check_wrapped = 0; } } Loading @@ -446,16 +394,16 @@ static int dvb_frontend_thread(void *data) * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ if ((fepriv->state & FESTATE_LOSTLOCK) && (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); continue; 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) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); continue; dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); return; } /* if we're in the RETUNE state, set everything up for a brand Loading @@ -466,22 +414,22 @@ static int dvb_frontend_thread(void *data) fepriv->auto_step = 0; fepriv->auto_sub_step = 0; fepriv->started_auto_step = 0; check_wrapped = 0; fepriv->check_wrapped = 0; } /* fast zigzag. */ if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { delay = fepriv->min_delay; fepriv->delay = fepriv->min_delay; /* peform a tune */ if (dvb_frontend_autotune(fe, check_wrapped)) { if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { /* 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; continue; return; } check_wrapped = 1; fepriv->check_wrapped = 1; /* if we've just retuned, enter the ZIGZAG_FAST state. * This ensures we cannot return from an Loading @@ -494,11 +442,105 @@ static int dvb_frontend_thread(void *data) /* slow zigzag */ if (fepriv->state & FESTATE_SEARCHING_SLOW) { update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); 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_autotune(fe, 0); dvb_frontend_swzigzag_autotune(fe, 0); } } static int dvb_frontend_is_exiting(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->exit) return 1; if (fepriv->dvbdev->writers == 1) if (time_after(jiffies, fepriv->release_jiffies + dvb_shutdown_timeout * HZ)) return 1; return 0; } static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv->wakeup) { fepriv->wakeup = 0; return 1; } return dvb_frontend_is_exiting(fe); } static void dvb_frontend_wakeup(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; fepriv->wakeup = 1; wake_up_interruptible(&fepriv->wait_queue); } 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(¤t->blocked); unlock_kernel(); fepriv->check_wrapped = 0; fepriv->quality = 0; fepriv->delay = 3*HZ; 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), fepriv->delay); if (0 != dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ break; } try_to_freeze(); if (down_interruptible(&fepriv->sem)) break; /* do an iteration of the tuning loop */ if (fe->ops->tune) { /* 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); } } Loading Loading @@ -733,7 +775,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; fepriv->tone = (fe_sec_tone_mode_t) parg; } break; Loading Loading @@ -891,6 +932,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); } break; case FE_SET_FRONTEND_TUNE_MODE: fepriv->tune_mode_flags = (unsigned int) parg; break; }; up (&fepriv->sem); Loading Loading @@ -932,6 +977,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; /* normal tune mode when opened R/W */ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; } return ret; Loading Loading @@ -990,7 +1038,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb, init_MUTEX (&fepriv->events.sem); fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; fepriv->tone = SEC_TONE_OFF; printk ("DVB: registering frontend %i (%s)...\n", fe->dvb->num, Loading
drivers/media/dvb/dvb-core/dvb_frontend.h +10 −1 Original line number Diff line number Diff line Loading @@ -58,10 +58,19 @@ struct dvb_frontend_ops { int (*init)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe); /* if this is set, it overrides the default swzigzag */ int (*tune)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, unsigned int mode_flags, int *delay, fe_status_t *status); /* these two are only used for the swzigzag code */ int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); int (*read_ber)(struct dvb_frontend* fe, u32* ber); int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); Loading
include/linux/dvb/frontend.h +10 −0 Original line number Diff line number Diff line Loading @@ -240,6 +240,15 @@ struct dvb_frontend_event { }; /** * When set, this flag will disable any zigzagging or other "normal" tuning * behaviour. Additionally, there will be no automatic monitoring of the lock * status, and hence no frontend events will be generated. If a frontend device * is closed, this flag will be automatically turned off when the device is * reopened read-write. */ #define FE_TUNE_MODE_ONESHOT 0x01 #define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) Loading @@ -260,6 +269,7 @@ struct dvb_frontend_event { #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) #define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ #define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ Loading