Index: libs/libmythtv/dvbdiseqc.h
===================================================================
--- libs/libmythtv/dvbdiseqc.h	(revision 10200)
+++ libs/libmythtv/dvbdiseqc.h	(working copy)
@@ -1,120 +0,0 @@
-/*
- *  Copyright (C) Kenneth Aafloy 2003
- *  
- *  Copyright notice is in dvbdiseqc.cpp of the MythTV project.
- */
-
-#ifndef DVBDISEQC_H
-#define DVBDISEQC_H
-
-#include "pthread.h"
-#include "qsqldatabase.h"
-#include "tv_rec.h"
-#include "dvbtypes.h"
-#include <linux/dvb/frontend.h>
-
-#define DISEQC_SHORT_WAIT 15*1000
-#define DISEQC_LONG_WAIT 100*1000
-
-class DVBDiSEqC
-{
-public:
-    DVBDiSEqC(int cardnum, int fd_frontend);
-    ~DVBDiSEqC();
-
-    bool Set(DVBTuning& tuning, bool reset, bool& havetuned);
-    bool DiseqcReset();
-
-private:
-    int cardnum;
-    int fd_frontend;
-    DVBTuning prev_tuning;
-    int repeat;
-
-    
-    bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd);
-    bool SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd);
-    
-    bool ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned);
-    bool ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned);
-    bool LegacyDishSwitch(DVBTuning& tuning, bool reset, bool& havetuned);
-    bool Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned,
-                        uint ports);
-    bool PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned);
-    bool PositionerStore(DVBTuning& tuning);
-    bool PositionerStopMovement();
-    bool PositionerStoreEastLimit();
-    bool PositionerStoreWestLimit();
-    bool PositionerDisableLimits();   
-    bool PositionerDriveEast(int timestep);
-    bool PositionerDriveWest(int timestep);
-    bool PositionerGotoAngular(DVBTuning& tuning, bool reset, 
-                               bool& havetuned);
-
-    // Still need to be written
-    bool Positioner_Status();
-
-    enum diseqc_cmd_bytes {
-        FRAME               = 0x0,
-        ADDRESS             = 0x1,
-        COMMAND             = 0x2,
-        DATA_1              = 0x3,
-        DATA_2              = 0x4,
-        DATA_3              = 0x5
-    };
-
-    enum diseqc_frame_byte {
-        CMD_FIRST           = 0xe0,
-        CMD_REPEAT          = 0xe1,
-        CMD_REPLY_FIRST     = 0xe2,
-        CMD_REPLY_REPEAT    = 0xe3,
-        REPLY_OK            = 0xe4,
-        REPLY_NOSUPPORT     = 0xe5,
-        REPLY_CRCERR_RPT    = 0xe6,
-        REPLY_CMDERR_RPT    = 0xe7
-    };
-        
-    enum diseqc_address {
-        MASTER_TO_ALL        = 0x00,
-        MASTER_TO_LSS        = 0x10,
-        MASTER_TO_LNB        = 0x11,
-        MASTER_TO_SWITCH     = 0x14,
-        MASTER_TO_POSITIONER = 0x31
-    };
-
-
-    enum diseqc_commands {
-        RESET               = 0x00,
-        CLR_RESET           = 0x01,
-        STANDBY             = 0x02,
-        POWERON             = 0x03,
-        SET_LO              = 0x20,
-        SET_VR              = 0x21,
-        SET_POS_A           = 0x22,
-        SET_SO_A            = 0x23,
-        SET_HI              = 0x24,
-        SET_HL              = 0x25,
-        SET_POS_B           = 0x26,
-        SET_SO_B            = 0x27,
-        WRITE_N0            = 0x38,
-        WRITE_N1            = 0x39,
-        WRITE_N2            = 0x3A,
-        WRITE_N3            = 0x3B,
-        READ_LNB_LOF_LO     = 0x52,
-        READ_LNB_LOF_HI     = 0x53,
-
-        HALT                = 0x60,
-        LIMITS_OFF          = 0x63,
-        POS_STAT            = 0x64,
-        LIMIT_E             = 0x66,
-        LIMIT_W             = 0x67,
-        DRIVE_E             = 0x68,
-        DRIVE_W             = 0x69,
-        STORE               = 0x6A,
-        GOTO                = 0x6B,
-        GOTO_ANGULAR        = 0x6E
-    };
-
-};
-
-#endif // DVBDISEQC_H
Index: libs/libmythtv/dvbdiseqc.cpp
===================================================================
--- libs/libmythtv/dvbdiseqc.cpp	(revision 10200)
+++ libs/libmythtv/dvbdiseqc.cpp	(working copy)
@@ -1,785 +0,0 @@
-/*
- *  Class DVBDiSEqC
- *
- *  Copyright (C) Kenneth Aafloy 2003
- *
- *  Description:
- *
- *  Author(s):
- *      Taylor Jacob (rtjacob at earthlink.net)
- *	    - Finished Implimenting Petri's DiSEqC 1.0 - 1.1 code
- *          - DiSEqC 1.2 Positioner control 
- *      Petri Nykanen
- *          - DiSEqC 1.0 - 1.1.
- *      Kenneth Aafloy (ke-aa at frisurf.no)
- *          - Initial framework.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <iostream>
-#include <cmath>
-
-#include "pthread.h"
-#include "qsqldatabase.h"
-
-#include "mythcontext.h"
-#include "tv_rec.h"
-#include "cardutil.h"
-
-#include "dvbtypes.h"
-#include "dvbdiseqc.h"
-
-#define TO_RADS (M_PI / 180.0)
-#define TO_DEC (180.0 / M_PI)
-
-#define LOC QString("DiSEqC(%1): ").arg(cardnum)
-#define LOC_ERR QString("DiSEqC(%1) Error: ").arg(cardnum)
-
-DVBDiSEqC::DVBDiSEqC(int _cardnum, int _fd_frontend):
-    cardnum(_cardnum), fd_frontend(_fd_frontend)
-{
-
-    // Number of repeats for DiSEqC 1.1 devices
-    repeat = 1;
-}
-
-DVBDiSEqC::~DVBDiSEqC()
-{
-}
-
-bool DVBDiSEqC::Set(DVBTuning& tuning, bool reset, bool& havetuned)
-{
-    switch (tuning.diseqc_type)
-    {
-        case DISEQC_MINI_2:
-            if (!ToneSwitch(tuning, reset, havetuned))
-                return false;
-            // fall through
-        case DISEQC_SINGLE:
-            if (!ToneVoltageLnb(tuning, reset, havetuned))
-                return false;
-            break;
-        case DISEQC_SWITCH_2_1_0: // 2 Way v1.0
-        case DISEQC_SWITCH_2_1_1: // 2 Way v1.1
-            if (!Diseqc1xSwitch(tuning, reset, havetuned, 2))
-                return false;
-            break;
-        case DISEQC_SWITCH_4_1_0: // 4 Way v1.0
-        case DISEQC_SWITCH_4_1_1: // 4 Way v1.1
-            if (!Diseqc1xSwitch(tuning, reset, havetuned, 4))
-                return false;
-            break;
-        case DISEQC_POSITIONER_1_2: // 1.2 Positioner (HH Motor)
-            if (!PositionerGoto(tuning,reset,havetuned))
-		return false;
-            break;
-        case DISEQC_POSITIONER_X: // 1.3 Positioner (HH Motor with USALS)
-            if (!PositionerGotoAngular(tuning,reset,havetuned))
-		return false;
-            break;
-        case DISEQC_POSITIONER_1_2_SWITCH_2: // 10 Way v1.1 or v2.1
-            if (!Diseqc1xSwitch(tuning, reset, havetuned, 10))
-                return false;
-            break;
-        case DISEQC_SW21: // Dish Network legacy switch SW21
-        case DISEQC_SW64: // Dish Network legacy switch SW64
-            if (!LegacyDishSwitch(tuning, reset, havetuned))
-                return false;
-            break;
- 
-        default:
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported DiSEqC type("
-                    <<tuning.diseqc_type<<")");
-    }
-    
-    return true;
-}
-
-bool DVBDiSEqC::LegacyDishSwitch(DVBTuning &tuning, bool reset,
-                                 bool &havetuned)
-{
-    VERBOSE(VB_CHANNEL, LOC + "Legacy Dish Switch: " +
-            QString("Port %1").arg(tuning.diseqc_port));
-
-    if (reset ||
-        (prev_tuning.diseqc_port != tuning.diseqc_port ||
-         prev_tuning.tone        != tuning.tone        ||
-         prev_tuning.voltage     != tuning.voltage))
-    {
-        uint8_t cmd = 0x00;
-
-        if (DISEQC_SW21 == tuning.diseqc_type)
-            cmd = (tuning.diseqc_port) ? 0x66 : 0x34;
-        else if (DISEQC_SW64 == tuning.diseqc_type)
-        {
-            if (tuning.diseqc_port == 0)
-                cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x39 : 0x1A;
-            else if (tuning.diseqc_port == 1)
-                cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x4B : 0x5C;
-            else
-                cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x0D : 0x2E;
-        }
-
-        if (tuning.voltage == SEC_VOLTAGE_18)
-            cmd |= 0x80;
-
-#ifdef FE_DISHNETWORK_SEND_LEGACY_CMD
-        if (ioctl(fd_frontend, FE_DISHNETWORK_SEND_LEGACY_CMD, cmd) <0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Legacy Dish Switch: "
-                    "Sending init command failed." + ENO);
-            return false;
-        }
-#else
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Legacy Dish Switch: " +
-                "Linux kernel does not support this switch.");
-#endif
-
-        usleep(DISEQC_SHORT_WAIT);
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-        prev_tuning.tone        = tuning.tone;
-        prev_tuning.voltage     = tuning.voltage;
-        havetuned = true;
-    }
-    return true;
-}
-
-/*****************************************************************************
-                        Backward Compatible Methods
- ****************************************************************************/
-
-bool DVBDiSEqC::ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned)
-{
-    VERBOSE(VB_CHANNEL, LOC + QString("Setting LNB: %1 %2")
-            .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")
-            .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
-
-    if (prev_tuning.tone != tuning.tone || reset)
-    {
-        if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Setting Tone mode failed." + ENO);
-            return false;
-        }
-
-        prev_tuning.tone = tuning.tone;
-    }
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    if (prev_tuning.voltage != tuning.voltage || reset)
-    {
-        if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Setting Polarization failed." + ENO);
-            return false;
-        }
-
-        prev_tuning.voltage = tuning.voltage;
-    }
-
-    havetuned |= ((prev_tuning.voltage == tuning.voltage) &&
-                  (prev_tuning.tone == tuning.tone));
-
-    return true;
-}
-
-bool DVBDiSEqC::ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned)
-{
-    VERBOSE(VB_CHANNEL, LOC + QString("Tone Switch - Port %1/2")
-            .arg(tuning.diseqc_port));
-
-    if (prev_tuning.diseqc_port != tuning.diseqc_port || reset)
-    {
-        if (tuning.diseqc_port > 2)
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Tone Switches only support two ports.");
-
-        if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST,
-                  (tuning.diseqc_port == 1 ? SEC_MINI_A : SEC_MINI_B )) < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Setting Tone Switch failed." + ENO);
-            return false;
-        }
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-    }
-
-    havetuned |= (prev_tuning.diseqc_port == tuning.diseqc_port);
-
-    return true;
-}
-
-/*****************************************************************************
-                    Diseqc 1.x Compatible Methods
- ****************************************************************************/
-
-bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd)
-{
-    // Turn off tone burst
-    if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
-        return false;
-    }
-
-/* 
-   Old version of the code set the voltage to 13V everytime.
-   After looking at the EutelSat specs I saw no reason that
-   this was done. I have tested this with my DiSEqC switch
-   and all is fine. 
-*/
-
-    if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_VOLTAGE failed" + ENO);
-        return false;
-    }   
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
-            .arg(cmd.msg[0], 2, 16)
-            .arg(cmd.msg[1], 2, 16)
-            .arg(cmd.msg[2], 2, 16)
-            .arg(cmd.msg[3], 2, 16));
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-        return false;
-    }
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    // Check to see if its a 1.1 or 1.2 device.
-    // If so repeat the message repeats times.
-    if ((tuning.diseqc_type == DISEQC_SWITCH_2_1_1)   ||
-        (tuning.diseqc_type == DISEQC_SWITCH_4_1_1)   || 
-        (tuning.diseqc_type == DISEQC_POSITIONER_1_2) ||
-        (tuning.diseqc_type == DISEQC_POSITIONER_X)) 
-    {
-
-        int repeats = repeat;
-        while (repeats--) 
-        {
-
-            if (tuning.diseqc_type == DISEQC_POSITIONER_X)
-            {
-                VERBOSE(VB_CHANNEL, LOC +
-                        QString("Sending 1.3 Repeat Command: %1 %2 %3 %4 %5")
-                        .arg(cmd.msg[0],2,16)
-                        .arg(cmd.msg[1],2,16)
-                        .arg(cmd.msg[2],2,16)
-                        .arg(cmd.msg[3],2,16)
-                        .arg(cmd.msg[4],2,16));
-            }
-            else
-            {
-                VERBOSE(VB_CHANNEL, LOC +
-                        QString("Sending 1.1/1.2 Repeat Command: %1 %2 %3 %4")
-                        .arg(cmd.msg[0],2,16)
-                        .arg(cmd.msg[1],2,16)
-                        .arg(cmd.msg[2],2,16)
-                        .arg(cmd.msg[3],2,16));
-            }
-
-            cmd.msg[0] = CMD_REPEAT;      
-            if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-            {
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-                return false;
-            }
-            usleep(DISEQC_SHORT_WAIT);
-     
-            cmd.msg[0] = CMD_FIRST;      
-            if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-            {
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-                return false;
-            }
-            usleep(DISEQC_SHORT_WAIT);
-        }
-    }
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "FE_DISEQC_SEND_BURST failed" + ENO);
-        return false;
-    }
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
-        return false;
-    }
-
-    return true;
-}
-
-
-bool DVBDiSEqC::SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd)
-{
-    // Turn off tone burst
-    if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
-        return false;
-    }
-
-    usleep(DISEQC_SHORT_WAIT);
-
-    VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
-            .arg(cmd.msg[0], 2, 16)
-            .arg(cmd.msg[1], 2, 16)
-            .arg(cmd.msg[2], 2, 16)
-            .arg(cmd.msg[3], 2, 16));
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-        return false;
-    }
-
-    usleep(DISEQC_SHORT_WAIT);
-  
-    int repeats = repeat;
-    while (repeats--) 
-    {
-        VERBOSE(VB_CHANNEL, LOC +
-                QString("Sending 1.1/1.2/1.3 Repeat Command: %1 %2 %3 %4")
-                .arg(cmd.msg[0], 2, 16)
-                .arg(cmd.msg[1], 2, 16)
-                .arg(cmd.msg[2], 2, 16)
-                .arg(cmd.msg[3], 2, 16));
-
-        cmd.msg[0] = CMD_REPEAT;      
-        if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-            return false;
-        }
-        usleep(DISEQC_SHORT_WAIT);
-    
-        cmd.msg[0] = CMD_FIRST;      
-        if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
-            return false;
-        }
-        usleep(DISEQC_SHORT_WAIT); 
-    }
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_DISEQC_SEND_BURST failed" + ENO);
-        return false;
-    }
-
-    return true;
-}
-
-bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset, 
-                               bool& havetuned, uint ports)
-{
-    if (reset) 
-    {
-      	if (!DiseqcReset()) 
-        {
-      	    VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-      	    return false;
-      	}
-    }
-
-    VERBOSE(VB_CHANNEL, LOC +
-            QString("1.1 Switch (%1 ports) - Port %2 - %3 %4")
-            .arg(ports)
-            .arg(tuning.diseqc_port)
-            .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")
-            .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
-
-    if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
-         prev_tuning.tone != tuning.tone                ||
-         prev_tuning.voltage != tuning.voltage        ) || reset)
-    {
-        dvb_diseqc_master_cmd cmd =
-            {{CMD_FIRST, MASTER_TO_LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4};
-
-        if (tuning.diseqc_port >= ports )
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported switch");
-            return false;
-        }
-
-        switch (ports)
-        {
-            case 10:
-                cmd.msg[COMMAND] = WRITE_N1;
-                cmd.msg[DATA_1] = 0xF0 | (tuning.diseqc_port & 0x0F);
-                break;
-            case 4:
-            case 2: 
-                cmd.msg[COMMAND] = WRITE_N0;
-                cmd.msg[DATA_1] =
-                    0xF0 |
-                    (((tuning.diseqc_port) * 4) & 0x0F)          |
-                    ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) |
-                    ((tuning.tone == SEC_TONE_ON) ? 1 : 0);
-                break;
-            default:
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "Unsupported number of ports for DiSEqC 1.1 Switch");
-        }
-
-        if (!SendDiSEqCMessage(tuning,cmd)) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-            return false;
-        }
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-        prev_tuning.tone = tuning.tone;
-        prev_tuning.voltage = tuning.voltage;
-        havetuned = true;
-
-    }
-
-    havetuned |=
-        (prev_tuning.diseqc_port == tuning.diseqc_port) &&
-        (prev_tuning.voltage     == tuning.voltage)     &&
-        (prev_tuning.tone        == tuning.tone);
-
-    return true;
-}
-
-bool DVBDiSEqC::DiseqcReset()
-{
-    struct dvb_diseqc_master_cmd reset_cmd =
-        {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3};
- 
-    struct dvb_diseqc_master_cmd init_cmd =
-        {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3};
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending init command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending reset command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Setup: Sending init command failed." + ENO);
-        return false;
-    }
-    usleep(DISEQC_LONG_WAIT);
-
-    return true;
-}
-
-/*****************************************************************************
-                            Positioner Control
- *****************************************************************************/
-
-bool DVBDiSEqC::PositionerDriveEast(int timestep)
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, DRIVE_E, timestep ,0x00,0x00}, 4};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-    
-    return true;
-}
-
-bool DVBDiSEqC::PositionerDriveWest(int timestep)
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, DRIVE_W, timestep ,0x00,0x00}, 4};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-
-    return true;
-}
-
-bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned)
-{
-    // A reset seems to be required for my positioner to work consistently
-    VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Goto Stored Position %1")
-            .arg(tuning.diseqc_port));
-
-    if ((prev_tuning.diseqc_port != tuning.diseqc_port ||
-         prev_tuning.tone != tuning.tone ||
-         prev_tuning.voltage != tuning.voltage) || reset)
-    {
-        if (!DiseqcReset()) 
-        {
-      	    VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	    return false;
-        }
-        
-        dvb_diseqc_master_cmd cmd = 
-            {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_port, 
-              0x00, 0x00}, 4};
-
-        if (!SendDiSEqCMessage(tuning,cmd)) 
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-            return false;
-        }
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-        prev_tuning.tone = tuning.tone;
-        prev_tuning.voltage = tuning.voltage;
-    }
-
-    havetuned |=
-        (prev_tuning.diseqc_port == tuning.diseqc_port) &&
-        (prev_tuning.voltage     == tuning.voltage)     &&
-        (prev_tuning.tone        == tuning.tone);
-
-    return true;
-}
-
-bool DVBDiSEqC::PositionerStore(DVBTuning& tuning)
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Store Stored Position %1")
-            .arg(tuning.diseqc_port));
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, STORE, tuning.diseqc_port , 0x00, 
-          0x00}, 4};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-
-    return true;
-}
-
-bool DVBDiSEqC::PositionerStoreEastLimit()
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, LIMIT_E, 0x00,0x00,0x00}, 3};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-
-    return true;
-}
-
-bool DVBDiSEqC::PositionerStoreWestLimit()
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, LIMIT_W, 0x00,0x00,0x00}, 3};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-
-    return true;
-}
-
-bool DVBDiSEqC::PositionerStopMovement()
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, HALT, 0x00,0x00,0x00}, 3};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-    return true;
-
-}
-
-bool DVBDiSEqC::Positioner_Status()
-{
-    // Not sure if this function is possible without being DiSEqC >= v2
-    // Someone with a DVB card that supports v2 cards will need to help me out 
-    // here
-    return false;
-}
-
-bool DVBDiSEqC::PositionerDisableLimits()
-{
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, LIMITS_OFF, 0x00,0x00,0x00}, 3};
-
-    if (!SendDiSEqCMessage(cmd)) 
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-        return false;
-    }
-
-    return true;
-}
-
-/*****************************************************************************
-                                Diseqc v1.3 (Goto X)
- ****************************************************************************/
-
-bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset, 
-                                      bool& havetuned) 
-{
-    // TODO: Send information here to FE saying motor is moving and
-    //       to expect a longer than average tuning delay
-    if (prev_tuning.diseqc_pos != tuning.diseqc_pos)
-        VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving");
-
-    if (!DiseqcReset()) 
-    {
-      	VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
-    	return false;
-    }
-
-    VERBOSE(VB_CHANNEL, LOC + QString("1.3 Motor - Goto Angular Position %1")
-            .arg(tuning.diseqc_pos));
-
-    // Equation lifted from VDR rotor plugin by
-    // Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de>
-
-    // Earth Station Latitude and Longitude in radians
-    double P  = gContext->GetSetting("Latitude",  "").toFloat() * TO_RADS;
-    double Ue = gContext->GetSetting("Longitude", "").toFloat() * TO_RADS;
-
-    // Satellite Longitude in radians
-    double Us = tuning.diseqc_pos * TO_RADS;
-
-    double az      = M_PI + atan( tan(Us - Ue) / sin(P) );
-    double x       = acos( cos(Us - Ue) * cos(P) );
-    double el      = atan( (cos(x) - 0.1513) / sin(x) );
-    double tmp_a   = -cos(el) * sin(az);
-    double tmp_b   = (sin(el) * cos(P)) - (cos(el) * sin(P) * cos(az));
-    double azimuth = atan(tmp_a / tmp_b) * TO_DEC;
-
-    // Bytes sent to motor
-    // cmd1 high nibble is 1110b/0xE0 for east or 1101b/0xD0 for west
-    // cmd1 low  nibble is angle / 16
-    // cmd2 high nibble is angle % 16
-    // cmd2 low  nibble is (angle * 16) % 16
-    uint az16 = (unsigned int) (abs(azimuth) * 16.0);
-    uint cmd1 = ((azimuth > 0.0) ? 0xE0 : 0xD0) | ((az16 >> 8) & 0x0f);
-    uint cmd2 = (az16 & 0xff);
-
-    dvb_diseqc_master_cmd cmd = 
-        {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, cmd1, cmd2, 0x00}, 5};
-  
-    if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
-         prev_tuning.tone        != tuning.tone         ||
-         prev_tuning.diseqc_pos  != tuning.diseqc_pos   ||
-         prev_tuning.voltage     != tuning.voltage    ) || reset)
-    {
-        if (!SendDiSEqCMessage(tuning, cmd))
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
-            return false;
-        }
-
-        prev_tuning.diseqc_port = tuning.diseqc_port;
-        prev_tuning.diseqc_pos  = tuning.diseqc_pos;
-        prev_tuning.tone        = tuning.tone;
-        prev_tuning.voltage     = tuning.voltage;
-    }
-
-    havetuned |=
-        (prev_tuning.diseqc_port == tuning.diseqc_port) &&
-        (prev_tuning.diseqc_pos  == tuning.diseqc_pos)  &&
-        (prev_tuning.voltage     == tuning.voltage)     &&
-        (prev_tuning.tone        == tuning.tone);
-
-    return true;
-}
Index: libs/libmythtv/dvbtypes.cpp
===================================================================
--- libs/libmythtv/dvbtypes.cpp	(revision 10200)
+++ libs/libmythtv/dvbtypes.cpp	(working copy)
@@ -416,6 +416,11 @@
     }
 }
 
+char DVBTuning::PolarityChar() const
+{
+    return polariz;
+}
+
 char DVBTuning::TransmissionModeChar() const
 {
     switch (params.u.ofdm.transmission_mode)
@@ -539,6 +544,11 @@
     return coderate(params.u.qam.fec_inner);
 }
 
+QString DVBTuning::QPSKInnerFECString() const
+{
+    return coderate(params.u.qpsk.fec_inner);
+}
+
 QString DVBTuning::GuardIntervalString() const
 {
     //Guard Interval
@@ -584,7 +594,7 @@
         msg = QString("Frequency: %1 Symbol Rate: %2 Pol: %3 Inv: %4")
             .arg(Frequency())
             .arg(QPSKSymbolRate())
-            .arg((voltage == SEC_VOLTAGE_13) ? "V/R" : "H/L")
+            .arg(PolarityChar())
             .arg(InversionString());
     }
     else if (FE_QAM == type)
@@ -676,12 +686,7 @@
 bool DVBTuning::parseDVBS2(
     const QString& frequency,   const QString& inversion,
     const QString& symbol_rate, const QString& fec_inner,
-    const QString& pol,         const QString& _diseqc_type,
-    const QString& _diseqc_port,
-    const QString& _diseqc_pos,
-    const QString& _lnb_lof_switch,
-    const QString& _lnb_lof_hi,
-    const QString& _lnb_lof_lo,
+    const QString& pol,
     const QString &modulation)
 {
     bool ok = true;
@@ -702,35 +707,19 @@
         return false;
     }
 
-    voltage = parsePolarity(pol, ok);
-    if (SEC_VOLTAGE_OFF == voltage)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid polarization, aborting.");
-        return false;
-    }
+    if(!pol.isEmpty())
+        polariz = QChar(pol[0]).lower();
 
     p.fec_inner = parseCodeRate(fec_inner, ok);
 
     p.modulation = parseModulation(modulation, ok);
-    diseqc_type = _diseqc_type.toInt();
-    diseqc_port = _diseqc_port.toInt();
-    diseqc_pos  = _diseqc_pos.toFloat();
-    lnb_lof_switch = _lnb_lof_switch.toInt();
-    lnb_lof_hi  = _lnb_lof_hi.toInt();
-    lnb_lof_lo  = _lnb_lof_lo.toInt();
     return true;
 }
 #endif
 
-// TODO: Add in DiseqcPos when diseqc class supports it
 bool DVBTuning::parseQPSK(const QString& frequency,   const QString& inversion,
                           const QString& symbol_rate, const QString& fec_inner,
-                          const QString& pol,         const QString& _diseqc_type,
-                          const QString& _diseqc_port,
-                          const QString& _diseqc_pos,
-                          const QString& _lnb_lof_switch,
-                          const QString& _lnb_lof_hi,
-                          const QString& _lnb_lof_lo)
+                          const QString& pol)
 {
     bool ok = true;
 
@@ -753,22 +742,11 @@
         return false;
     }
 
-    voltage = parsePolarity(pol, ok);
-    if (SEC_VOLTAGE_OFF == voltage)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid polarization, aborting.");
+    if(!pol.isEmpty())
+        polariz = QChar(pol[0]).lower();
 
-        return false;
-    }
-
     p.fec_inner = parseCodeRate(fec_inner, ok);
 
-    diseqc_type = _diseqc_type.toInt();
-    diseqc_port = _diseqc_port.toInt();
-    diseqc_pos  = _diseqc_pos.toFloat();
-    lnb_lof_switch = _lnb_lof_switch.toInt();
-    lnb_lof_hi  = _lnb_lof_hi.toInt();
-    lnb_lof_lo  = _lnb_lof_lo.toInt();
     return true;
 }
 
@@ -823,20 +801,6 @@
     return BANDWIDTH_AUTO;
 }
 
-fe_sec_voltage DVBTuning::parsePolarity(const QString &pol, bool &ok)
-{
-    char polarity = QChar(pol[0]).lower();
-    ok = true;
-    switch (polarity)
-    {
-        case 'v':
-        case 'r': return SEC_VOLTAGE_13;
-        case 'h':
-        case 'l': return SEC_VOLTAGE_18;
-        default: return SEC_VOLTAGE_OFF;
-    }
-}
-
 fe_guard_interval DVBTuning::parseGuardInterval(const QString &gi, bool &ok)
 {
     QString guard_interval = gi.lower();
@@ -1015,7 +979,7 @@
 {
     switch (coderate)
     {
-        case FEC_NONE: return "None";
+        case FEC_NONE: return "none";
         case FEC_1_2:  return "1/2";
         case FEC_2_3:  return "2/3";
         case FEC_3_4:  return "3/4";
@@ -1024,7 +988,7 @@
         case FEC_6_7:  return "6/7";
         case FEC_7_8:  return "7/8";
         case FEC_8_9:  return "8/9";
-        default:       return "Auto";
+        default:       return "auto";
     }
 }
 
Index: libs/libmythtv/dvbtypes.h
===================================================================
--- libs/libmythtv/dvbtypes.h	(revision 10200)
+++ libs/libmythtv/dvbtypes.h	(working copy)
@@ -318,22 +318,13 @@
 {
   public:
     DVBTuning()
-      : voltage(SEC_VOLTAGE_OFF), tone(SEC_TONE_OFF), 
-        diseqc_type(0), diseqc_port(0), diseqc_pos(0.0f),
-        lnb_lof_switch(0), lnb_lof_hi(0), lnb_lof_lo(0)
+        : polariz('v')
     {
         bzero(&params, sizeof(dvb_fe_params));
     }
 
     struct dvb_fe_params params;
-    fe_sec_voltage_t    voltage;
-    fe_sec_tone_mode_t  tone;
-    unsigned int        diseqc_type;
-    unsigned int        diseqc_port;
-    float               diseqc_pos;
-    unsigned int        lnb_lof_switch;
-    unsigned int        lnb_lof_hi;
-    unsigned int        lnb_lof_lo;
+    char                 polariz;
 
     bool equalQPSK(const DVBTuning& other, uint range = 0) const
         { return equal_qpsk(params, other.params, range);  }
@@ -348,6 +339,7 @@
 
     // Helper functions to get the paramaters as DB friendly strings
     char InversionChar() const;
+    char PolarityChar() const;
     char TransmissionModeChar() const;
     char BandwidthChar() const;
     char HierarchyChar() const;
@@ -356,7 +348,6 @@
 
     // Helper functions to parse params from DB friendly strings
     static fe_bandwidth      parseBandwidth(    const QString&, bool &ok);
-    static fe_sec_voltage    parsePolarity(     const QString&, bool &ok);
     static fe_guard_interval parseGuardInterval(const QString&, bool &ok);
     static fe_transmit_mode  parseTransmission( const QString&, bool &ok);
     static fe_hierarchy      parseHierarchy(    const QString&, bool &ok);
@@ -375,6 +366,7 @@
     QString HPCodeRateString() const;
     QString LPCodeRateString() const;
     QString QAMInnerFECString() const;
+    QString QPSKInnerFECString() const;
     QString ModulationString() const;
     QString ConstellationString() const;
     QString HierarchyString() const;
@@ -390,10 +382,7 @@
 
     bool parseQPSK(const QString& frequency,      const QString& inversion,
                    const QString& symbol_rate,    const QString& fec_inner,
-                   const QString& pol,            const QString& diseqc_type,
-                   const QString& diseqc_port,    const QString& diseqc_pos,
-                   const QString& lnb_lof_switch, const QString& lnb_lof_hi,
-                   const QString& lnb_lof_lo);
+                   const QString& pol);
 
     bool parseQAM(const QString& frequency,       const QString& inversion,
                   const QString& symbol_rate,     const QString& fec_inner,
@@ -405,10 +394,7 @@
     uint DVBS2SymbolRate() const { return params.u.qpsk2.symbol_rate; }
     bool parseDVBS2(const QString& frequency,      const QString& inversion,
                    const QString& symbol_rate,    const QString& fec_inner,
-                   const QString& pol,            const QString& diseqc_type,
-                   const QString& diseqc_port,    const QString& diseqc_pos,
-                   const QString& lnb_lof_switch, const QString& lnb_lof_hi,
-                   const QString& lnb_lof_lo,     const QString& modulation);
+                   const QString& pol);
 #endif
 };
 
Index: libs/libmythtv/channelutil.h
===================================================================
--- libs/libmythtv/channelutil.h	(revision 10200)
+++ libs/libmythtv/channelutil.h	(working copy)
@@ -145,6 +145,7 @@
     static QString GetServiceName(int chanid);
     static int     GetSourceID(int mplexid);
     static QString GetInputName(int sourceid);
+    static int     GetInputID(int sourceid, int cardid);
     static QString GetDTVPrivateType(uint networkid, const QString &key,
                                      const QString sitype = "dvb");
 
Index: libs/libmythtv/channelutil.cpp
===================================================================
--- libs/libmythtv/channelutil.cpp	(revision 10200)
+++ libs/libmythtv/channelutil.cpp	(working copy)
@@ -231,7 +231,7 @@
             // DVB specific
             tsid,                 netid,
             cd.SymbolRateHz(),    -1,
-            QChar(cd.PolarizationString()[0]), -1,
+            QChar(cd.PolarizationString()[0]), 'a',
             -1,
             cd.FECInnerString(),  QString::null,
             -1,                   QString::null,
@@ -670,6 +670,24 @@
     return inputname;
 }
 
+int ChannelUtil::GetInputID(int source_id, int card_id)
+{
+    int input_id = -1;
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT cardinputid"
+                  " FROM cardinput"
+                  " WHERE sourceid = :SOURCEID"
+                  " AND cardid = :CARDID");
+    query.bindValue(":SOURCEID", source_id);
+    query.bindValue(":CARDID", card_id);
+
+    if (query.exec() && query.isActive() && query.next())
+        input_id = query.value(0).toInt();
+
+    return input_id;
+}
+
 QString ChannelUtil::GetChannelValueStr(const QString &channel_field,
                                         uint           cardid,
                                         const QString &input,
Index: libs/libmythtv/dvbchannel.h
===================================================================
--- libs/libmythtv/dvbchannel.h	(revision 10200)
+++ libs/libmythtv/dvbchannel.h	(working copy)
@@ -19,18 +19,19 @@
 
 #ifdef USING_DVB
 #include "dvbtypes.h"
+#include "dvbdevtree.h"
 #else // if !USING_DVB
 typedef int fe_type_t;
 typedef int fe_modulation_t;
 typedef int fe_code_rate_t;
 typedef int DVBTuning;
+typedef void DVBDevRotor;
 typedef struct { QString name; fe_type_t type; } dvb_frontend_info;
 #endif //!USING_DVB
 
 class TVRec;
 class DVBCam;
 class DVBRecorder;
-class DVBDiSEqC;
 
 class DVBChannel : public ChannelBase
 {
@@ -64,15 +65,30 @@
     bool SwitchToInput(const QString &inputname, const QString &chan);
     bool SwitchToInput(int newcapchannel, bool setstarting);
     bool SetChannelByString(const QString &chan);
-    bool Tune(const DVBTuning &tuning, bool force_reset = false);
-    bool TuneMultiplex(uint mplexid);
 
+    // Tuning
+    bool Tune(const DVBTuning &tuning,
+              bool force_reset = false,
+              int sourceid = -1,
+              bool same_input = false);
+    bool TuneMultiplex(uint mplexid, int sourceid = -1);
+    bool Retune();
+
     bool GetTuningParams(DVBTuning &tuning) const;
 
     // PID caching
     void SaveCachedPids(const pid_cache_t&) const;
     void GetCachedPids(pid_cache_t&) const;
 
+    // Returns rotor object (or NULL)
+    const DVBDevRotor* GetRotor() const;
+
+    // If false, card needs retuning when lock is lost
+    bool CanRecover() const;
+
+    // Amount of time since last tuning request
+    int ElapsedSinceTune() const;
+
   private:
     int  GetChanID(void) const;
     bool GetTransportOptions(int mplexid);
@@ -85,16 +101,18 @@
     bool ParseTuningParams(
         fe_type_t type,
         QString frequency,    QString inversion,      QString symbolrate,
-        QString fec,          QString polarity,       QString dvb_diseqc_type,
-        QString diseqc_port,  QString diseqc_pos,     QString lnb_lof_switch,
-        QString lnb_lof_hi,   QString lnb_lof_lo,     QString _sistandard,
+        QString fec,          QString polarity,       QString _sistandard,
         QString hp_code_rate, QString lp_code_rate,   QString constellation,
         QString trans_mode,   QString guard_interval, QString hierarchy,
         QString modulation,   QString bandwidth,      QString _input_id);
 
   private:
+#ifdef USING_DVB
     // Data
-    DVBDiSEqC        *diseqc; ///< Used to send commands to external devices
+    DVBDev            dvbdev;
+    DVBDevTree*       devtree;
+    DVBDevSettings    devset;
+#endif
     DVBCam           *dvbcam; ///< Used to decrypt encrypted streams
 
     // Tuning State
@@ -113,6 +131,9 @@
     int               cardnum;     ///< DVB Card number
     bool              has_crc_bug; ///< true iff our driver munges PMT
     int               nextInputID; ///< Signal an input change
+
+    QTime             tune_time;
+    QMutex            tune_lock;
 };
 
 #endif
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp	(revision 10200)
+++ libs/libmythtv/dvbchannel.cpp	(working copy)
@@ -52,17 +52,16 @@
 #include "mythdbcon.h"
 #include "tv_rec.h"
 #include "cardutil.h"
+#include "channelutil.h"
 
 #include "dvbtypes.h"
 #include "dvbchannel.h"
 #include "dvbrecorder.h"
-#include "dvbdiseqc.h"
+#include "dvbdevtree.h"
 #include "dvbcam.h"
 
-static uint tuned_frequency(const DVBTuning&, fe_type_t, fe_sec_tone_mode_t *);
 static void drain_dvb_events(int fd);
 static bool wait_for_backend(int fd, int timeout_ms);
-static bool handle_diseq(const DVBTuning&, DVBDiSEqC*, bool reset);
 
 #define LOC QString("DVBChan(%1): ").arg(cardnum)
 #define LOC_WARN QString("DVBChan(%1) Warning: ").arg(cardnum)
@@ -76,7 +75,8 @@
 DVBChannel::DVBChannel(int aCardNum, TVRec *parent)
     : ChannelBase(parent),
       // Helper classes
-      diseqc(NULL),                 dvbcam(NULL),
+      devtree(NULL),
+      dvbcam(NULL),
       // Tuning
       tuning_delay(0),              sigmon_delay(25),
       first_tune(true),
@@ -93,11 +93,8 @@
 DVBChannel::~DVBChannel()
 {
     Close();
-    if (dvbcam)
-    {
-        delete dvbcam;
-        dvbcam = NULL;
-    }
+    delete dvbcam;
+    dvbcam = NULL;
 }
 
 void DVBChannel::Close()
@@ -106,16 +103,13 @@
 
     if (fd_frontend >= 0)
     {
+        if(devtree)
+            devtree->Close();
+
         close(fd_frontend);
         fd_frontend = -1;
 
         dvbcam->Stop();
-
-        if (diseqc)
-        {
-            delete diseqc;
-            diseqc = NULL;
-        }
     }
 }
 
@@ -189,23 +183,9 @@
     if (info.type == FE_QPSK)
 #endif
     {
-        if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) < 0)
-        {
-            VERBOSE(VB_GENERAL, LOC_WARN +
-                    "Initial Tone setting failed." + ENO);
-        }
-
-        if (ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13) < 0)
-        {
-            VERBOSE(VB_GENERAL, LOC_WARN +
-                    "Initial Voltage setting failed." + ENO);
-        }
-
-        if (diseqc == NULL)
-        {
-            diseqc = new DVBDiSEqC(cardnum, fd_frontend);
-            diseqc->DiseqcReset();
-        }
+        devtree = dvbdev.FindTree(GetCardID());
+        if(devtree)
+            devtree->Open(fd_frontend);
     }
     
     dvbcam->Start();
@@ -228,7 +208,7 @@
  *
  *   mplexid is how the db indexes each transport
  */
-bool DVBChannel::TuneMultiplex(uint mplexid)
+bool DVBChannel::TuneMultiplex(uint mplexid, int sourceid)
 {
     if (!GetTransportOptions(mplexid))
         return false;
@@ -236,7 +216,7 @@
     CheckOptions();
     VERBOSE(VB_CHANNEL, LOC + cur_tuning.toString(info.type));
 
-    if (!Tune(cur_tuning))
+    if (!Tune(cur_tuning, false, sourceid))
         return false;
 
     return true;
@@ -406,9 +386,7 @@
     // Query for our DVBTuning params
     query.prepare(
         "SELECT frequency,         inversion,      symbolrate, "
-        "       fec,               polarity,       dvb_diseqc_type, "
-        "       diseqc_port,       diseqc_pos,     lnb_lof_switch, "
-        "       lnb_lof_hi,        lnb_lof_lo,     sistandard, "
+        "       fec,               polarity,       sistandard, "
         "       hp_code_rate,      lp_code_rate,   constellation, "
         "       transmission_mode, guard_interval, hierarchy, "
         "       modulation,        bandwidth,      cardinputid "
@@ -444,18 +422,13 @@
         query.value(8).toString(),  query.value(9).toString(),
         query.value(10).toString(), query.value(11).toString(),
         query.value(12).toString(), query.value(13).toString(),
-        query.value(14).toString(), query.value(15).toString(),
-        query.value(16).toString(), query.value(17).toString(),
-        query.value(18).toString(), query.value(19).toString(),
-        query.value(20).toString());
+        query.value(14).toString());
 }
 
 bool DVBChannel::ParseTuningParams(
     fe_type_t type,
     QString frequency,    QString inversion,      QString symbolrate,
-    QString fec,          QString polarity,       QString dvb_diseqc_type,
-    QString diseqc_port,  QString diseqc_pos,     QString lnb_lof_switch,
-    QString lnb_lof_hi,   QString lnb_lof_lo,     QString _sistandard,
+    QString fec,          QString polarity,       QString _sistandard,
     QString hp_code_rate, QString lp_code_rate,   QString constellation,
     QString trans_mode,   QString guard_interval, QString hierarchy,
     QString modulation,   QString bandwidth,      QString _input_id)
@@ -465,9 +438,7 @@
 
     if (FE_QPSK == type)
         return cur_tuning.parseQPSK(
-            frequency,       inversion,     symbolrate,   fec,   polarity,
-            dvb_diseqc_type, diseqc_port,   diseqc_pos,
-            lnb_lof_switch,  lnb_lof_hi,    lnb_lof_lo);
+            frequency,       inversion,     symbolrate,   fec,   polarity);
     else if (FE_QAM == type)
         return cur_tuning.parseQAM(
             frequency,       inversion,     symbolrate,   fec,   modulation);
@@ -506,7 +477,13 @@
         t.params.inversion = INVERSION_OFF;
     }
 
-    uint frequency = tuned_frequency(t, info.type, NULL);
+    uint frequency = t.params.frequency;
+    if(devtree)
+    {
+        DVBDevLnb* lnb = devtree->FindLNB(devset);
+        if(lnb)
+            frequency = lnb->GetIF(devset, t);
+    }
 
     if ((info.frequency_min > 0 && info.frequency_max > 0) &&
        (frequency < info.frequency_min || frequency > info.frequency_max))
@@ -697,18 +674,33 @@
  *  \param channel     Info on transport to tune to
  *  \param force_reset If true, frequency tuning is done
  *                     even if it should not be needed.
+ *  \param source_id   Optional, forces specific sourceid (for diseqc setup).
+ *  \param same_input  Optional, doesn't change input (for retuning).
  *  \return true on success, false on failure
  */
-bool DVBChannel::Tune(const DVBTuning &tuning, bool force_reset)
+bool DVBChannel::Tune(const DVBTuning &tuning,
+                      bool force_reset,
+                      int source_id,
+                      bool same_input)
 {
-    bool reset = (force_reset || first_tune);
-    bool has_diseq = (FE_QPSK == info.type) && diseqc;
-    struct dvb_fe_params params = tuning.params;
+    QMutexLocker lock(&tune_lock);
 
+    bool reset = (force_reset || first_tune);
+    bool is_dvbs = (FE_QPSK == info.type);
 #ifdef FE_GET_EXTENDED_INFO
-    has_diseq |= (FE_DVB_S2 == info.type) && diseqc;
+    is_dvbs |= (FE_DVB_S2 == info.type);
 #endif // FE_GET_EXTENDED_INFO
+    bool has_diseqc = (devtree != NULL);
+    struct dvb_fe_params params = tuning.params;
 
+    tune_time.start();
+
+    if(is_dvbs && !has_diseqc)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "DVB-S needs device tree");
+        return false;
+    }
+
     if (fd_frontend < 0)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): Card not open!");
@@ -719,13 +711,37 @@
     // Remove any events in queue before tuning.
     drain_dvb_events(fd_frontend);
 
-    // Send DisEq commands to external hardware if we need to.
-    if (has_diseq && !handle_diseq(tuning, diseqc, reset))
+    // send DVB-S setup
+    if (is_dvbs)
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
-                "Failed to transmit DisEq commands");
+        // configure for new input
+        if(!same_input)
+        {
+            devset.Load(source_id == -1 ? nextInputID :
+                        ChannelUtil::GetInputID(source_id, GetCardID()));
+        }
+            
+        // execute diseqc commands
+        if(!devtree->Execute(devset, tuning))
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
+                    "Failed to setup DiSEqC devices");
+            return false;
+        }
 
-        return false;
+        // retrieve actual intermediate frequency
+        DVBDevLnb* lnb = devtree->FindLNB(devset);
+        if(!lnb)
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
+                    "No LNB for this configuration");
+            return false;
+        }
+        params.frequency = lnb->GetIF(devset, tuning);
+
+        // if card can auto-FEC, use it -- sometimes NITs are inaccurate
+        if(info.caps & FE_CAN_FEC_AUTO)
+            params.u.qpsk.fec_inner = FEC_AUTO;
     }
 
     VERBOSE(VB_CHANNEL, LOC + "Old Params: " +
@@ -733,11 +749,15 @@
             "\n\t\t\t" + LOC + "New Params: " +
             tuning.toString(info.type));
 
-    if (reset || !prev_tuning.equal(info.type, tuning, 500000))
-    {
-        // Adjust for Satelite recievers which offset the frequency.
-        params.frequency = tuned_frequency(tuning, info.type, NULL);
+    // DVB-S is in kHz, other DVB is in Hz
+    int freq_mult = is_dvbs ? 1 : 1000;
+    const char* suffix = is_dvbs ? "kHz" : "Hz";
 
+    if (reset || !prev_tuning.equal(info.type, tuning, 500 * freq_mult))
+    {
+        VERBOSE(VB_CHANNEL, LOC + QString("Tune(): Tuning to %1%2")
+                .arg(params.frequency)
+                .arg(suffix));
 #ifdef FE_GET_EXTENDED_INFO
         if (info.type == FE_DVB_S2)
         {
@@ -774,6 +794,11 @@
     return true;
 }
 
+bool DVBChannel::Retune()
+{
+    return Tune(prev_tuning, true, -1, true);
+}
+
 /** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
  *  \brief Fetches DVBTuning params from driver
  *  \return true on success, false on failure
@@ -843,6 +868,22 @@
         ChannelBase::GetCachedPids(chanid, pid_cache);
 }
 
+const DVBDevRotor* DVBChannel::GetRotor() const
+{
+    const DVBDevRotor* rotor = devtree ? devtree->FindRotor(devset) : NULL;
+    return rotor;
+}
+
+bool DVBChannel::CanRecover() const
+{
+    return info.caps & FE_CAN_RECOVER;
+}
+
+int DVBChannel::ElapsedSinceTune() const
+{
+    return first_tune ? 0 : tune_time.elapsed();
+}
+
 /** \fn drain_dvb_events(int)
  *  \brief Reads all the events off the queue, so we can use select
  *         in wait_for_backend(int,int).
@@ -853,28 +894,6 @@
     while (ioctl(fd, FE_GET_EVENT, &event) == 0);
 }
 
-static uint tuned_frequency(const DVBTuning &tuning, fe_type_t type,
-                            fe_sec_tone_mode_t *p_tone)
-{
-#ifdef FE_GET_EXTENDED_INFO
-    if (FE_QPSK != type && FE_DVB_S2 != type)
-        return tuning.Frequency();
-#else
-    if (FE_QPSK != type)
-        return tuning.Frequency();
-#endif
-
-    uint freq   = tuning.Frequency();
-    bool tone   = freq >= tuning.lnb_lof_switch;
-    uint lnb_hi = (uint) abs((int)freq - (int)tuning.lnb_lof_hi);
-    uint lnb_lo = (uint) abs((int)freq - (int)tuning.lnb_lof_lo);
-
-    if (p_tone)
-        *p_tone = (tone) ? SEC_TONE_ON : SEC_TONE_OFF;
-
-    return (tone) ? lnb_hi : lnb_lo;
-}
-
 /** \fn wait_for_backend(int,int)
  *  \brief Waits for backend to get tune message.
  *
@@ -923,26 +942,3 @@
             .arg(toString(status)));
     return true;
 }
-
-/** \fn handle_diseq(const DVBTuning&, DVBDiSEqC*, bool)
- *  \brief Sends DisEq commands to external hardware.
- *
- */
-static bool handle_diseq(const DVBTuning &ct, DVBDiSEqC *diseqc, bool reset)
-{
-    if (!diseqc)
-        return false;
-
-    bool tuned  = false;
-    DVBTuning t = ct;
-    t.params.frequency = tuned_frequency(ct, FE_QPSK, &t.tone);
-
-    for (uint i = 0; i < 64 && !tuned; i++)
-        if (!diseqc->Set(t, reset, tuned))
-            return false;
-
-    // Wait 10 ms, recommended by Marcus Metzler, see #1552
-    usleep(10 * 1000);
-
-    return true;
-}
Index: libs/libmythtv/siscan.cpp
===================================================================
--- libs/libmythtv/siscan.cpp	(revision 10200)
+++ libs/libmythtv/siscan.cpp	(working copy)
@@ -376,7 +376,7 @@
                                   bool wait_until_complete)
 {
     const DVBStreamData &dsd = (const DVBStreamData &)(*sd);
-    if (wait_until_complete && !dsd.HasCachedSDT() && !dsd.HasCachedAllNIT())
+    if (wait_until_complete && (!dsd.HasCachedSDT() || !dsd.HasCachedAllNIT()))
         return;
 
     emit ServiceScanUpdateText(tr("Updating Services"));
@@ -619,15 +619,18 @@
     // Tune to multiplex
     if (GetDVBChannel())
     {
+        // always wait for rotor to finish
+        GetDVBSignalMonitor()->AddFlags(kDVBSigMon_WaitForPos);
+
         if (item.mplexid > 0)
         {
-            ok = GetDVBChannel()->TuneMultiplex(item.mplexid);
+            ok = GetDVBChannel()->TuneMultiplex(item.mplexid, item.SourceID);
         }
         else
         {
             DVBTuning tuning = item.tuning;
             tuning.params.frequency = freq;
-            ok = GetDVBChannel()->Tune(tuning, true);
+            ok = GetDVBChannel()->Tune(tuning, true, item.SourceID);
         }
     }
 #endif // USING_DVB
@@ -827,10 +830,7 @@
         ok = tuning.parseQPSK(
             startChan["frequency"],   startChan["inversion"],
             startChan["symbolrate"],  startChan["fec"],
-            startChan["polarity"],
-            startChan["diseqc_type"], startChan["diseqc_port"],
-            startChan["diseqc_pos"],  startChan["lnb_lof_switch"],
-            startChan["lnb_lof_hi"],  startChan["lnb_lof_lo"]);
+            startChan["polarity"]);
     }
     else if (std == "dvb" && mod.left(3) == "qam")
     {
@@ -1340,6 +1340,30 @@
                 QString::null /*inner FEC*/,tuning.ConstellationDB(),
                 tuning.HierarchyChar(),     tuning.HPCodeRateString(),
                 tuning.LPCodeRateString(),  tuning.GuardIntervalString());
+        else if (FE_QPSK == GetDVBChannel()->GetCardType())
+            mplexid = ChannelUtil::CreateMultiplex(
+                (*transport).SourceID,      (*transport).standard,
+                tuning.Frequency(),         (*transport).ModulationDB(),
+                sm->GetDetectedTransportID(),
+                sm->GetDetectedNetworkID(),
+                tuning.QPSKSymbolRate(),    -1,
+                tuning.PolarityChar(),      tuning.InversionChar(),
+                -1,
+                tuning.QPSKInnerFECString(),QString::null,
+                -1,                         QString::null,
+                QString::null,              QString::null);
+        else if (FE_QAM == GetDVBChannel()->GetCardType())
+            mplexid = ChannelUtil::CreateMultiplex(
+                (*transport).SourceID,      (*transport).standard,
+                tuning.Frequency(),         tuning.ModulationString(),
+                sm->GetDetectedTransportID(),
+                sm->GetDetectedNetworkID(),
+                tuning.QAMSymbolRate(),     -1,
+                -1,                         -1,
+                -1,
+                tuning.QAMInnerFECString(), QString::null,
+                -1,                         QString::null,
+                QString::null,              QString::null);
         else
             mplexid = ChannelUtil::CreateMultiplex(
                 (*transport).SourceID,      (*transport).standard,
Index: libs/libmythtv/scanwizardscanner.cpp
===================================================================
--- libs/libmythtv/scanwizardscanner.cpp	(revision 10200)
+++ libs/libmythtv/scanwizardscanner.cpp	(working copy)
@@ -269,41 +269,6 @@
     popupProgress = NULL;
 }
 
-static bool get_diseqc(uint cardid, uint sourceid,
-                       QMap<QString,QString> &startChan)
-{
-    // SQL code to get the disqec paramters HERE
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(
-        "SELECT dvb_diseqc_type, diseqc_port,  diseqc_pos, "
-        "       lnb_lof_switch,  lnb_lof_hi,   lnb_lof_lo "
-        "FROM cardinput, capturecard "
-        "WHERE cardinput.cardid   = capturecard.cardid AND "
-        "      cardinput.cardid   = :CARDID            AND "
-        "      cardinput.sourceid = :SOURCEID ");
-    query.bindValue(":CARDID",   cardid);
-    query.bindValue(":SOURCEID", sourceid);
-
-    if (!query.exec() || !query.isActive())
-    {
-        MythContext::DBError("ScanWizardScanner::scan()", query);
-        return false;
-    }
-
-    if (query.next())
-    {
-        startChan["diseqc_type"]    = query.value(0).toString();
-        startChan["diseqc_port"]    = query.value(1).toString();
-        startChan["diseqc_pos"]     = query.value(2).toString();
-        startChan["lnb_lof_switch"] = query.value(3).toString();
-        startChan["lnb_lof_hi"]     = query.value(4).toString();
-        startChan["lnb_lof_lo"]     = query.value(5).toString();
-        return true;
-    }
-
-    return false;
-}
-
 // full scan of existing transports broken
 // existing transport scan broken
 void ScanWizardScanner::scan()
@@ -375,8 +340,6 @@
         startChan["modulation"] = "qpsk";
         startChan["polarity"]   = pane->polarity();
 
-        nit_scan_parse_failed = !get_diseqc(cardid, nVideoSource, startChan);
-
 #ifdef USING_DVB
         if (!nit_scan_parse_failed)
         {
@@ -384,10 +347,7 @@
             nit_scan_parse_failed = !tuning.parseQPSK(
                 startChan["frequency"],   startChan["inversion"],
                 startChan["symbolrate"],  startChan["fec"],
-                startChan["polarity"],
-                startChan["diseqc_type"], startChan["diseqc_port"],
-                startChan["diseqc_pos"],  startChan["lnb_lof_switch"],
-                startChan["lnb_lof_hi"],  startChan["lnb_lof_lo"]);
+                startChan["polarity"]);
         }
 #endif // USING_DVB
     }
Index: libs/libmythtv/dbcheck.cpp
===================================================================
--- libs/libmythtv/dbcheck.cpp	(revision 10200)
+++ libs/libmythtv/dbcheck.cpp	(working copy)
@@ -8,6 +8,9 @@
 
 #include "mythcontext.h"
 #include "mythdbcon.h"
+#ifdef USING_DVB
+#include "dvbdevtree.h"
+#endif
 
 /// This is the DB schema version expected by the running MythTV instance.
 const QString currentDatabaseVersion = "1143";
@@ -419,6 +422,15 @@
  */
 bool UpgradeTVDatabaseSchema(void)
 {
+#ifdef USING_DVB
+    // TODO: The code in DatabaseDiseqcUpgrade (just sequence of SQL queries)
+    // should be versioned and added to the database creation/upgrade functions as
+    // normal. DatabaseDiseqcImport() should be called as part of that upgrade
+    // process as well.
+    if(DatabaseDiseqcUpgrade())
+        DatabaseDiseqcImport();
+#endif
+
     QString dbver = gContext->GetSetting("DBSchemaVer");
 
     VERBOSE(VB_IMPORTANT, QString("Current Schema Version: %1").arg(dbver));
