Pull acpica into release branch
[pandora-kernel.git] / drivers / media / dvb / dvb-core / dvb_frontend.c
index 22e96cf..a051790 100644 (file)
@@ -49,13 +49,13 @@ static int dvb_powerdown_on_sleep = 1;
 
 module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
 MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
-module_param(dvb_shutdown_timeout, int, 0444);
+module_param(dvb_shutdown_timeout, int, 0644);
 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
-module_param(dvb_force_auto_inversion, int, 0444);
+module_param(dvb_force_auto_inversion, int, 0644);
 MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
-module_param(dvb_override_tune_delay, int, 0444);
+module_param(dvb_override_tune_delay, int, 0644);
 MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
-module_param(dvb_powerdown_on_sleep, int, 0444);
+module_param(dvb_powerdown_on_sleep, int, 0644);
 MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)");
 
 #define dprintk if (dvb_frontend_debug) printk
@@ -105,6 +105,9 @@ struct dvb_frontend_private {
        fe_status_t status;
        unsigned long tune_mode_flags;
        unsigned int delay;
+       unsigned int reinitialise;
+       int tone;
+       int voltage;
 
        /* swzigzag values */
        unsigned int state;
@@ -121,6 +124,7 @@ struct dvb_frontend_private {
        unsigned int check_wrapped;
 };
 
+static void dvb_frontend_wakeup(struct dvb_frontend *fe);
 
 static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 {
@@ -213,6 +217,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
                fe->ops->init(fe);
 }
 
+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);
+
 static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
 {
        int q2;
@@ -505,8 +518,8 @@ static int dvb_frontend_thread(void *data)
        fepriv->quality = 0;
        fepriv->delay = 3*HZ;
        fepriv->status = 0;
-       dvb_frontend_init(fe);
        fepriv->wakeup = 0;
+       fepriv->reinitialise = 1;
 
        while (1) {
                up(&fepriv->sem);           /* is locked when we enter the thread... */
@@ -524,6 +537,17 @@ static int dvb_frontend_thread(void *data)
                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->tune) {
                        /* have we been asked to retune? */
@@ -772,6 +796,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_SET_TONE:
                if (fe->ops->set_tone) {
                        err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
+                       fepriv->tone = (fe_sec_tone_mode_t) parg;
                        fepriv->state = FESTATE_DISEQC;
                        fepriv->status = 0;
                }
@@ -780,6 +805,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_SET_VOLTAGE:
                if (fe->ops->set_voltage) {
                        err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
+                       fepriv->voltage = (fe_sec_voltage_t) parg;
                        fepriv->state = FESTATE_DISEQC;
                        fepriv->status = 0;
                }
@@ -979,6 +1005,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
                /* normal tune mode when opened R/W */
                fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
+               fepriv->tone = -1;
+               fepriv->voltage = -1;
        }
 
        return ret;