diff options
Diffstat (limited to 'drivers/media/dvb/dvb-core/dvb_frontend.c')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index d19301d90a0..a8bc84240b5 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -35,12 +35,15 @@ #include <linux/moduleparam.h> #include <linux/list.h> #include <linux/suspend.h> +#include <linux/jiffies.h> #include <asm/processor.h> #include <asm/semaphore.h> #include "dvb_frontend.h" #include "dvbdev.h" +// #define DEBUG_LOCKLOSS 1 + static int dvb_frontend_debug; static int dvb_shutdown_timeout = 5; static int dvb_force_auto_inversion; @@ -112,6 +115,7 @@ struct dvb_frontend_private { int exit; int wakeup; fe_status_t status; + fe_sec_tone_mode_t tone; }; @@ -327,7 +331,8 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) return 1; if (fepriv->dvbdev->writers == 1) - if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ) + if (time_after(jiffies, fepriv->release_jiffies + + dvb_shutdown_timeout * HZ)) return 1; return 0; @@ -389,8 +394,7 @@ static int dvb_frontend_thread(void *data) break; } - if (current->flags & PF_FREEZE) - refrigerator(PF_FREEZE); + try_to_freeze(); if (down_interruptible(&fepriv->sem)) break; @@ -433,9 +437,26 @@ static int dvb_frontend_thread(void *data) /* 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 */ + else { /* if we _WERE_ tuned, but now don't have a lock */ +#ifdef DEBUG_LOCKLOSS + /* first of all try setting the tone again if it was on - this + * sometimes works around problems with noisy power supplies */ + if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) { + fe->ops->set_tone(fe, fepriv->tone); + mdelay(100); + s = 0; + fe->ops->read_status(fe, &s); + if (s & FE_HAS_LOCK) { + printk("DVB%i: Lock was lost, but regained by setting " + "the tone. This may indicate your power supply " + "is noisy/slightly incompatable with this DVB-S " + "adapter\n", fe->dvb->num); + fepriv->state = FESTATE_TUNED; + continue; + } + } +#endif + /* some other reason for losing the lock - start zigzagging */ fepriv->state = FESTATE_ZIGZAG_FAST; fepriv->started_auto_step = fepriv->auto_step; check_wrapped = 0; @@ -625,11 +646,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; } - case FE_READ_STATUS: + case FE_READ_STATUS: { + fe_status_t* status = parg; + + /* if retune was requested but hasn't occured yet, prevent + * that user get signal state from previous tuning */ + if(fepriv->state == FESTATE_RETUNE) { + err=0; + *status = 0; + break; + } + if (fe->ops->read_status) - err = fe->ops->read_status(fe, (fe_status_t*) parg); + err = fe->ops->read_status(fe, status); break; - + } case FE_READ_BER: if (fe->ops->read_ber) err = fe->ops->read_ber(fe, (__u32*) parg); @@ -680,6 +711,7 @@ 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; @@ -882,6 +914,7 @@ 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, |