Index: libs/libmythtv/dvbsignalmonitor.h
===================================================================
--- libs/libmythtv/dvbsignalmonitor.h	(revision 10200)
+++ libs/libmythtv/dvbsignalmonitor.h	(working copy)
@@ -10,6 +10,8 @@
 
 typedef QMap<uint,int> FilterMap;
 
+#define RETUNE_TIMEOUT 5000
+
 class DVBSignalMonitor: public DTVSignalMonitor
 {
     Q_OBJECT
@@ -30,6 +32,7 @@
     void StatusSignalToNoise(const SignalMonitorValue&);
     void StatusBitErrorRate(const SignalMonitorValue&);
     void StatusUncorrectedBlocks(const SignalMonitorValue&);
+    void StatusRotorPosition(const SignalMonitorValue&);
 
   protected:
     DVBSignalMonitor(void);
@@ -38,6 +41,7 @@
     virtual void UpdateValues(void);
     void EmitDVBSignals(void);
 
+    void RetuneMonitor(void);
     static void *TableMonitorThread(void *param);
     void RunTableMonitor(void);
     void RunTableMonitorTS(void);
@@ -52,12 +56,15 @@
     SignalMonitorValue signalToNoise;
     SignalMonitorValue bitErrorRate;
     SignalMonitorValue uncorrectedBlocks;
+    SignalMonitorValue rotorPosition;
 
     bool               useSectionReader;
     bool               dtvMonitorRunning;
     pthread_t          table_monitor_thread;
 
     FilterMap          filters; ///< PID filters for table monitoring
+
+    bool               is_rotor_done;
 };
 
 #endif // DVBSIGNALMONITOR_H
Index: libs/libmythtv/signalmonitor.h
===================================================================
--- libs/libmythtv/signalmonitor.h	(revision 10200)
+++ libs/libmythtv/signalmonitor.h	(working copy)
@@ -55,6 +55,7 @@
     kDVBSigMon_WaitForSNR = 0x01000000,
     kDVBSigMon_WaitForBER = 0x02000000,
     kDVBSigMon_WaitForUB  = 0x04000000,
+    kDVBSigMon_WaitForPos = 0x08000000, ///< Wait for rotor
 };
 
 inline QString sm_flags_to_string(uint);
Index: libs/libmythtv/dvbsignalmonitor.cpp
===================================================================
--- libs/libmythtv/dvbsignalmonitor.cpp	(revision 10200)
+++ libs/libmythtv/dvbsignalmonitor.cpp	(working copy)
@@ -19,6 +19,7 @@
 
 #include "dvbchannel.h"
 #include "dvbrecorder.h"
+#include "dvbdevtree.h"
 
 #undef DBG_SM
 #define DBG_SM(FUNC, MSG) VERBOSE(VB_CHANNEL, \
@@ -54,8 +55,11 @@
                         65535,  false,     0, 65535, 0),
       uncorrectedBlocks(tr("Uncorrected Blocks"), "ucb",
                         65535,  false,     0, 65535, 0),
+      rotorPosition    (tr("Rotor Progress"), "pos",
+                        100,  true,      0, 100, 0),
       useSectionReader(false),
-      dtvMonitorRunning(false)
+      dtvMonitorRunning(false),
+      is_rotor_done(true)
 {
     // These two values should probably come from the database...
     int wait = 3000; // timeout when waiting on signal
@@ -151,6 +155,8 @@
         list<<bitErrorRate.GetName()<<bitErrorRate.GetStatus();
     if (HasFlags(kDVBSigMon_WaitForUB))
         list<<uncorrectedBlocks.GetName()<<uncorrectedBlocks.GetStatus();
+    if (HasFlags(kDVBSigMon_WaitForPos))
+        list<<rotorPosition.GetName()<<rotorPosition.GetStatus();
     statusLock.unlock();
     return list;
 }
@@ -332,6 +338,7 @@
     FD_SET (dvr_fd, &fd_select_set);
     while (dtvMonitorRunning && GetStreamData())
     {
+        RetuneMonitor();
         UpdateFiltersFromStreamData();
 
         // timeout gets reset by select, so we need to create new one
@@ -391,6 +398,7 @@
 
     while (dtvMonitorRunning && GetStreamData())
     {
+        RetuneMonitor();
         UpdateFiltersFromStreamData();
 
         bool readSomething = false;
@@ -479,6 +487,56 @@
     return supports_ts;
 }
 
+void DVBSignalMonitor::RetuneMonitor(void)
+{
+    DVBChannel* dvbchan = dynamic_cast<DVBChannel*>(channel);
+    int fd_frontend = dvbchan->GetFd();
+
+    // Get lock status
+    bool is_locked = true;
+    fe_status_t status;
+    if(ioctl(fd_frontend, FE_READ_STATUS, &status) != -1)
+    {
+        is_locked = (status & FE_HAS_LOCK);
+        signalLock.SetValue(is_locked ? 1 : 0);
+    }
+
+    // Rotor position
+    const DVBDevRotor* rotor = dvbchan->GetRotor();
+    if(rotor)
+    {
+        if(rotor->IsPositionKnown())
+        {
+            double progress = rotor->Progress();
+            if(progress >= 1.0 && !is_rotor_done)
+            {
+                DBG_SM("UpdateValues", "Retuning for rotor completion");
+                dvbchan->Retune();
+                is_rotor_done = true;
+            }
+            else if(progress < 1.0)
+            {
+                if(is_rotor_done)
+                    DBG_SM("UpdateValues", "Rotor is moving");
+                is_rotor_done = false;
+            }
+
+            if (HasFlags(kDVBSigMon_WaitForPos))
+                rotorPosition.SetValue((int)(progress * 100));
+        }
+    }
+    else if (HasFlags(kDVBSigMon_WaitForPos))
+        rotorPosition.SetValue(100);
+
+    // Periodically retune if card can't recover
+    if(!dvbchan->CanRecover() && !is_locked &&
+       dvbchan->ElapsedSinceTune() > RETUNE_TIMEOUT)
+    {
+        DBG_SM("UpdateValues", "Retuning for lock loss");
+        dvbchan->Retune();
+    }
+}
+
 void DVBSignalMonitor::RunTableMonitor(void)
 {
     dtvMonitorRunning = true;
@@ -515,6 +573,8 @@
         return;
     }
 
+    RetuneMonitor();
+
     bool wasLocked = false, isLocked = false;
     // We use uint16_t for sig & snr because this is correct for DVB API 4.0,
     // and works better than the correct int16_t for the 3.x API
@@ -569,6 +629,7 @@
     // Start table monitoring if we are waiting on any table
     // and we have a lock.
     if (isLocked && GetStreamData() &&
+        (!HasFlags(kDVBSigMon_WaitForPos) || rotorPosition.IsGood()) &&
         HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
                    kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
                    kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT))
@@ -605,6 +666,8 @@
         EMIT(StatusBitErrorRate, bitErrorRate);
     if (HasFlags(kDVBSigMon_WaitForUB))
         EMIT(StatusUncorrectedBlocks, uncorrectedBlocks);
+    if (HasFlags(kDVBSigMon_WaitForPos))
+        EMIT(StatusRotorPosition, rotorPosition);
 }
 
 #undef EMIT
