diff --git a/mythtv/configure b/mythtv/configure
index 1363586..d231bcb 100755
--- a/mythtv/configure
+++ b/mythtv/configure
@@ -1123,6 +1123,7 @@ HAVE_LIST="
     fast_64bit
     fast_cmov
     fast_unaligned
+    fe_can_2g_modulation
     fork
     freetype2
     ftime
@@ -3382,6 +3383,16 @@ if enabled dvb; then
     fi
 fi
 
+
+enabled dvb && check_cc -I"$dvb_path" <<EOF && enable fe_can_2g_modulation
+#include <linux/dvb/frontend.h>
+int main(void) {
+    if (FE_CAN_2G_MODULATION != 0x10000000)
+        return 1;
+    return 0;
+}
+EOF
+
 # Check that all MythTV build "requirements" are met:
 
 enabled freetype2 ||
@@ -3789,6 +3800,7 @@ if enabled backend; then
   echo "HR-PVR support            ${hdpvr-no}"
   echo "FireWire support          ${firewire-no}"
   echo "DVB support               ${dvb-no} [$dvb_path]"
+  echo "DVB-S2 support            ${fe_can_2g_modulation-no}"
 #  echo "DBox2 support             ${dbox2-no}"
   echo "HDHomeRun support         ${hdhomerun-no}"
   echo "IPTV support              ${iptv-no}"
diff --git a/mythtv/libs/libmythtv/cardutil.cpp b/mythtv/libs/libmythtv/cardutil.cpp
index 6c2cf39..cba395a 100644
--- a/mythtv/libs/libmythtv/cardutil.cpp
+++ b/mythtv/libs/libmythtv/cardutil.cpp
@@ -13,6 +13,7 @@
 #include <QDir>
 
 // MythTV headers
+#include "mythconfig.h"
 #include "cardutil.h"
 #include "videosource.h"
 #include "dvbchannel.h"
@@ -293,6 +294,11 @@ QString CardUtil::ProbeDVBType(const QString &device)
     close(fd_frontend);
 
     DTVTunerType type(info.type);
+#if HAVE_FE_CAN_2G_MODULATION
+    if (type == DTVTunerType::kTunerTypeQPSK &&
+        (info.caps & FE_CAN_2G_MODULATION))
+        type = DTVTunerType::kTunerTypeDVB_S2;
+#endif // HAVE_FE_CAN_2G_MODULATION
     ret = (type.toString() != "UNKNOWN") ? type.toString().toUpper() : ret;
 #endif // USING_DVB
 
@@ -385,7 +391,7 @@ bool CardUtil::IsDVBCardType(const QString card_type)
 {
     QString ct = card_type.toUpper();
     return (ct == "DVB") || (ct == "QAM") || (ct == "QPSK") ||
-        (ct == "OFDM") || (ct == "ATSC");
+        (ct == "OFDM") || (ct == "ATSC") || (ct == "DVB_S2");
 }
 
 QString get_on_cardid(const QString &to_get, uint cardid)
diff --git a/mythtv/libs/libmythtv/cardutil.h b/mythtv/libs/libmythtv/cardutil.h
index 328b341..ea9e54c 100644
--- a/mythtv/libs/libmythtv/cardutil.h
+++ b/mythtv/libs/libmythtv/cardutil.h
@@ -55,6 +55,7 @@ class MPUBLIC CardUtil
         HDHOMERUN = 10,
         FREEBOX   = 11,
         HDPVR     = 12,
+        DVBS2     = 13,
     };
 
     static enum CARD_TYPES toCardType(const QString &name)
@@ -85,6 +86,8 @@ class MPUBLIC CardUtil
             return FREEBOX;
         if ("HDPVR" == name)
             return HDPVR;
+        if ("DVB_S2" == name)
+            return DVBS2;
         return ERROR_UNKNOWN;
     }
 
diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
index 60a6661..49d311c 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
+++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
@@ -1506,15 +1506,13 @@ bool ChannelScanSM::ScanTransportsStartingOn(
     QMap<QString,QString>::const_iterator it;
 
     if (startChan.find("std")        == startChan.end() ||
-        startChan.find("modulation") == startChan.end())
+        startChan.find("type")       == startChan.end())
     {
         return false;
     }
 
     QString std    = *startChan.find("std");
-    QString mod    = (*(startChan.find("modulation"))).toUpper();
     QString si_std = (std.toLower() != "atsc") ? "dvb" : "atsc";
-    QString name   = "";
     bool    ok     = false;
 
     if (scanning)
@@ -1526,16 +1524,7 @@ bool ChannelScanSM::ScanTransportsStartingOn(
     DTVMultiplex tuning;
 
     DTVTunerType type;
-
-    if (std == "dvb") 
-    {
-        ok = type.Parse(mod);
-    }
-    else if (std == "atsc")
-    {
-        type = DTVTunerType::kTunerTypeATSC;
-        ok = true;
-    }
+    ok = type.Parse(startChan["type"]);
 
     if (ok)
     {
@@ -1547,7 +1536,8 @@ bool ChannelScanSM::ScanTransportsStartingOn(
             startChan["coderate_hp"],    startChan["coderate_lp"],
             startChan["constellation"],  startChan["trans_mode"],
             startChan["guard_interval"], startChan["hierarchy"],
-            startChan["modulation"],     startChan["bandwidth"]);
+            startChan["modulation"],     startChan["bandwidth"],
+            startChan["mod_sys"],        startChan["rolloff"]);
     }
 
     if (ok)
diff --git a/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h b/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h
index 855bed7..3b3122c 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h
+++ b/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h
@@ -248,6 +248,32 @@ class ScanHierarchy: public ComboBoxSetting, public TransientStorage
     };
 };
 
+class ScanModSys: public ComboBoxSetting, public TransientStorage
+{
+    public:
+    ScanModSys() : ComboBoxSetting(this)
+    {
+        setLabel(QObject::tr("Mod Sys"));
+        setHelpText(QObject::tr("Modulation system (Default: DVB-S)"));
+        addSelection("DVB-S");
+        addSelection("DVB-S2");
+    };
+};
+
+class ScanRollOff: public ComboBoxSetting, public TransientStorage
+{
+    public:
+    ScanRollOff() : ComboBoxSetting(this)
+    {
+        setLabel(QObject::tr("Rolloff"));
+        setHelpText(QObject::tr("Roll Off factor (Default: 0.35)"));
+        addSelection("0.35");
+        addSelection("0.20");
+        addSelection("0.25");
+        addSelection(QObject::tr("Auto"),"auto");
+    };
+};
+
 class PaneError : public HorizontalConfigurationGroup
 {
   public:
diff --git a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
index b209eed..7bb16fe 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
+++ b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
@@ -157,9 +157,10 @@ void ChannelScanner::Scan(
         ok = sigmonScanner->ScanTransports(
             sourceid, freq_std, mod, tbl, tbl_start, tbl_end);
     }
-    else if ((ScanTypeSetting::NITAddScan_DVBT == scantype) ||
-             (ScanTypeSetting::NITAddScan_DVBS == scantype) ||
-             (ScanTypeSetting::NITAddScan_DVBC == scantype))
+    else if ((ScanTypeSetting::NITAddScan_DVBT  == scantype) ||
+             (ScanTypeSetting::NITAddScan_DVBS  == scantype) ||
+             (ScanTypeSetting::NITAddScan_DVBS2 == scantype) ||
+             (ScanTypeSetting::NITAddScan_DVBC  == scantype))
     {
         VERBOSE(VB_CHANSCAN, LOC + "ScanTransports()");
 
diff --git a/mythtv/libs/libmythtv/channelscan/modulationsetting.h b/mythtv/libs/libmythtv/channelscan/modulationsetting.h
index 88f0254..67e25b2 100644
--- a/mythtv/libs/libmythtv/channelscan/modulationsetting.h
+++ b/mythtv/libs/libmythtv/channelscan/modulationsetting.h
@@ -58,9 +58,6 @@ class ScanModulationSetting: public ComboBoxSetting
     {
         addSelection(QObject::tr("Auto"),"auto",true);
         addSelection("QPSK","qpsk");
-#ifdef FE_GET_EXTENDED_INFO
-        addSelection("8PSK","8psk");
-#endif
         addSelection("QAM 16","qam_16");
         addSelection("QAM 32","qam_32");
         addSelection("QAM 64","qam_64");
@@ -90,5 +87,23 @@ class ScanConstellation: public ScanModulationSetting,
     };
 };
 
+class ScanDVBSModulation: public ComboBoxSetting, public TransientStorage
+{
+  public:
+    ScanDVBSModulation() : ComboBoxSetting(this)
+    {
+
+        addSelection("QPSK",  "qpsk", true);
+        addSelection("8PSK",  "8psk");
+        addSelection("QAM 16","qam_16");
+
+        setLabel(QObject::tr("Modulation"));
+        setHelpText(
+            QObject::tr("Modulation, QPSK, 8PSK, QAM-16") + " " +
+            QObject::tr("Most DVB-S transponders use QPSK, DVB-S2 8PSK "
+                        "QAM-16 is not available for DVB-S2 transports."));
+    }
+};
+
 #endif // _MODULATION_SETTING_H_
 
diff --git a/mythtv/libs/libmythtv/channelscan/panedvbs2.h b/mythtv/libs/libmythtv/channelscan/panedvbs2.h
index fe40ab2..7247b7d 100644
--- a/mythtv/libs/libmythtv/channelscan/panedvbs2.h
+++ b/mythtv/libs/libmythtv/channelscan/panedvbs2.h
@@ -22,9 +22,11 @@ class PaneDVBS2 : public HorizontalConfigurationGroup
         left->addChild( pfrequency  = new ScanFrequency());
         left->addChild( ppolarity   = new ScanPolarity());
         left->addChild( psymbolrate = new ScanSymbolRateDVBS());
+        left->addChild( pmod_sys    = new ScanModSys());
         right->addChild(pfec        = new ScanFec());
-        right->addChild(pmodulation = new ScanModulation());
+        right->addChild(pmodulation = new ScanDVBSModulation());
         right->addChild(pinversion  = new ScanInversion());
+        right->addChild(prolloff    = new ScanRollOff());
         addChild(left);
         addChild(right);     
     }
@@ -35,6 +37,8 @@ class PaneDVBS2 : public HorizontalConfigurationGroup
     QString fec(void)        const { return pfec->getValue();        }
     QString polarity(void)   const { return ppolarity->getValue();   }
     QString modulation(void) const { return pmodulation->getValue(); }
+    QString mod_sys(void)    const { return pmod_sys->getValue();    }
+    QString rolloff(void)    const { return prolloff->getValue();    }
 
   protected:
     ScanFrequency  *pfrequency;
@@ -42,7 +46,9 @@ class PaneDVBS2 : public HorizontalConfigurationGroup
     ScanInversion  *pinversion;
     ScanFec        *pfec;
     ScanPolarity   *ppolarity;
-    ScanModulation *pmodulation;
+    ScanDVBSModulation *pmodulation;
+    ScanModSys     *pmod_sys;
+    ScanRollOff    *prolloff;
 };
 
 #endif // _PANE_DVBS2_H_
diff --git a/mythtv/libs/libmythtv/channelscan/scaninfo.cpp b/mythtv/libs/libmythtv/channelscan/scaninfo.cpp
index faeafd5..e01035e 100644
--- a/mythtv/libs/libmythtv/channelscan/scaninfo.cpp
+++ b/mythtv/libs/libmythtv/channelscan/scaninfo.cpp
@@ -81,7 +81,8 @@ ScanDTVTransportList LoadScan(uint scanid)
         "       hp_code_rate,      lp_code_rate,   modulation, "
         "       transmission_mode, guard_interval, hierarchy, "
         "       modulation,        bandwidth,      sistandard, "
-        "       tuner_type,        transportid "
+        "       tuner_type,        transportid,    mod_sys, "
+        "       rolloff "
         "FROM channelscan_dtv_multiplex "
         "WHERE scanid = :SCANID");
     query.bindValue(":SCANID", scanid);
@@ -102,7 +103,8 @@ ScanDTVTransportList LoadScan(uint scanid)
             query.value(6).toString(),  query.value(7).toString(),
             query.value(8).toString(),  query.value(9).toString(),
             query.value(10).toString(), query.value(11).toString(),
-            query.value(12).toString());
+            query.value(12).toString(), query.value(13).toString(),
+            query.value(14).toString());
 
         query2.prepare(
             "SELECT "
diff --git a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
index 2d36ed8..2916021 100644
--- a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
+++ b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp
@@ -140,6 +140,14 @@ void ScanTypeSetting::SetInput(const QString &cardids_inputname)
             addSelection(tr("Import existing scan"),
                          QString::number(ExistingScanImport));
             break;
+        case CardUtil::DVBS2:
+            addSelection(tr("Full Scan (Tuned)"),
+                         QString::number(NITAddScan_DVBS2));
+            addSelection(tr("Import channels.conf"),
+                         QString::number(DVBUtilsImport));
+            addSelection(tr("Import existing scan"),
+                         QString::number(ExistingScanImport));
+            break;
         case CardUtil::QAM:
             addSelection(tr("Full Scan (Tuned)"),
                          QString::number(NITAddScan_DVBC));
@@ -225,6 +233,8 @@ ScanOptionalConfig::ScanOptionalConfig(ScanTypeSetting *_scan_type) :
               paneDVBC);
     addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBS),
               paneDVBS);
+    addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBS2),
+              paneDVBS2);
     addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBT),
               paneDVBT);
     addTarget(QString::number(ScanTypeSetting::FullScan_ATSC),
@@ -353,10 +363,10 @@ QMap<QString,QString> ScanOptionalConfig::GetStartChan(void) const
         const PaneDVBT *pane = paneDVBT;
 
         startChan["std"]            = "dvb";
+        startChan["type"]           = "OFDM";
         startChan["frequency"]      = pane->frequency();
         startChan["inversion"]      = pane->inversion();
         startChan["bandwidth"]      = pane->bandwidth();
-        startChan["modulation"]     = "ofdm";
         startChan["coderate_hp"]    = pane->coderate_hp();
         startChan["coderate_lp"]    = pane->coderate_lp();
         startChan["constellation"]  = pane->constellation();
@@ -369,11 +379,11 @@ QMap<QString,QString> ScanOptionalConfig::GetStartChan(void) const
         const PaneDVBS *pane = paneDVBS;
 
         startChan["std"]        = "dvb";
+        startChan["type"]       = "QPSK";
         startChan["frequency"]  = pane->frequency();
         startChan["inversion"]  = pane->inversion();
         startChan["symbolrate"] = pane->symbolrate();
         startChan["fec"]        = pane->fec();
-        startChan["modulation"] = "qpsk";
         startChan["polarity"]   = pane->polarity();
     }
     else if (ScanTypeSetting::NITAddScan_DVBC == st)
@@ -381,11 +391,27 @@ QMap<QString,QString> ScanOptionalConfig::GetStartChan(void) const
         const PaneDVBC *pane = paneDVBC;
 
         startChan["std"]        = "dvb";
+        startChan["type"]       = "QAM";
+        startChan["frequency"]  = pane->frequency();
+        startChan["inversion"]  = pane->inversion();
+        startChan["symbolrate"] = pane->symbolrate();
+        startChan["fec"]        = pane->fec();
+        startChan["modulation"] = pane->modulation();
+    }
+    else if (ScanTypeSetting::NITAddScan_DVBS2 == st)
+    {
+        const PaneDVBS2 *pane = paneDVBS2;
+
+        startChan["std"]        = "dvb";
+        startChan["type"]       = "DVB_S2";
         startChan["frequency"]  = pane->frequency();
         startChan["inversion"]  = pane->inversion();
         startChan["symbolrate"] = pane->symbolrate();
         startChan["fec"]        = pane->fec();
         startChan["modulation"] = pane->modulation();
+        startChan["polarity"]   = pane->polarity();
+        startChan["mod_sys"]    = pane->mod_sys();
+        startChan["rolloff"]    = pane->rolloff();
     }
 
     return startChan;
diff --git a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h
index d69b1c5..4f4661d 100644
--- a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h
+++ b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h
@@ -66,6 +66,7 @@ class ScanTypeSetting : public ComboBoxSetting, public TransientStorage
         // seen in the Network Information Tables to the scan.
         NITAddScan_DVBT,
         NITAddScan_DVBS,
+        NITAddScan_DVBS2,
         NITAddScan_DVBC,
         // Scan of all transports already in the database
         FullTransportScan,
diff --git a/mythtv/libs/libmythtv/channelutil.cpp b/mythtv/libs/libmythtv/channelutil.cpp
index df12092..b100a54 100644
--- a/mythtv/libs/libmythtv/channelutil.cpp
+++ b/mythtv/libs/libmythtv/channelutil.cpp
@@ -127,7 +127,8 @@ static uint insert_dtv_multiplex(
     signed char trans_mode,
     QString     inner_FEC,     QString      constellation,
     signed char hierarchy,     QString      hp_code_rate,
-    QString     lp_code_rate,  QString      guard_interval)
+    QString     lp_code_rate,  QString      guard_interval,
+    QString     mod_sys,       QString      rolloff)
 {
     MSqlQuery query(MSqlQuery::InitCon());
 
@@ -174,6 +175,10 @@ static uint insert_dtv_multiplex(
         "lp_code_rate     = :LP_CODE_RATE, " : "";
     updateStr += (!guard_interval.isNull()) ?
         "guard_interval   = :GUARD_INTERVAL, " : "";
+    updateStr += (!mod_sys.isNull()) ?
+        "mod_sys          = :MOD_SYS, " : "";
+    updateStr += (symbol_rate >= 0) ?
+        "rolloff          = :ROLLOFF, " : "";
     updateStr += (transport_id && !isDVB) ?
         "transportid      = :TRANSPORTID, " : "";
 
@@ -205,6 +210,8 @@ static uint insert_dtv_multiplex(
     insertStr += (!hp_code_rate.isNull())   ? "hp_code_rate, "      : "";
     insertStr += (!lp_code_rate.isNull())   ? "lp_code_rate, "      : "";
     insertStr += (!guard_interval.isNull()) ? "guard_interval, "    : "";
+    insertStr += (!mod_sys.isNull())        ? "mod_sys, "           : "";
+    insertStr += (!rolloff.isNull())        ? "rolloff, "           : "";
     insertStr = insertStr.left(insertStr.length()-2) + ") ";
 
     insertStr +=
@@ -224,6 +231,8 @@ static uint insert_dtv_multiplex(
     insertStr += (!hp_code_rate.isNull())   ? ":HP_CODE_RATE, "     : "";
     insertStr += (!lp_code_rate.isNull())   ? ":LP_CODE_RATE, "     : "";
     insertStr += (!guard_interval.isNull()) ? ":GUARD_INTERVAL, "   : "";
+    insertStr += (!mod_sys.isNull())        ? ":MOD_SYS, "          : "";
+    insertStr += (!rolloff.isNull())        ? ":ROLLOFF, "          : "";
     insertStr = insertStr.left(insertStr.length()-2) + ");";
 
     query.prepare((mplex) ? updateStr : insertStr);
@@ -284,6 +293,10 @@ static uint insert_dtv_multiplex(
         query.bindValue(":LP_CODE_RATE",  lp_code_rate);
     if (!guard_interval.isNull())
         query.bindValue(":GUARD_INTERVAL",guard_interval);
+    if (!mod_sys.isNull())
+        query.bindValue(":MOD_SYS",       mod_sys);
+    if (!rolloff.isNull())
+        query.bindValue(":ROLLOFF",       rolloff);
 
     if (!query.exec() || !query.isActive())
     {
@@ -337,7 +350,8 @@ void handle_transport_desc(vector<uint> &muxes, const MPEGDescriptor &desc,
             cd.TransmissionModeString()[0].toAscii(),
             QString(),                         cd.ConstellationString(),
             cd.HierarchyString()[0].toAscii(), cd.CodeRateHPString(),
-            cd.CodeRateLPString(),             cd.GuardIntervalString());
+            cd.CodeRateLPString(),             cd.GuardIntervalString(),
+            QString(),                         QString());
 
         if (mux)
             muxes.push_back(mux);
@@ -364,7 +378,8 @@ void handle_transport_desc(vector<uint> &muxes, const MPEGDescriptor &desc,
             -1,
             cd.FECInnerString(),  QString(),
             -1,                   QString(),
-            QString(),            QString());
+            QString(),            QString(),
+            cd.ModulationSystemString(), cd.RollOffString());
 
         if (mux)
             muxes.push_back(mux);
@@ -387,6 +402,7 @@ void handle_transport_desc(vector<uint> &muxes, const MPEGDescriptor &desc,
             -1,
             cd.FECInnerString(),  QString::null,
             -1,                   QString::null,
+            QString::null,        QString::null,
             QString::null,        QString::null);
 
         if (mux)
@@ -407,6 +423,7 @@ uint ChannelUtil::CreateMultiplex(int  sourceid,      QString sistandard,
         -1,
         QString::null,      QString::null,
         -1,                 QString::null,
+        QString::null,      QString::null,
         QString::null,      QString::null);
 }
 
@@ -420,7 +437,8 @@ uint ChannelUtil::CreateMultiplex(
     signed char trans_mode,
     QString     inner_FEC,    QString     constellation,
     signed char hierarchy,    QString     hp_code_rate,
-    QString     lp_code_rate, QString     guard_interval)
+    QString     lp_code_rate, QString     guard_interval,
+    QString     mod_sys,      QString     rolloff)
 {
     return insert_dtv_multiplex(
         sourceid,           sistandard,
@@ -432,7 +450,8 @@ uint ChannelUtil::CreateMultiplex(
         trans_mode,
         inner_FEC,          constellation,
         hierarchy,          hp_code_rate,
-        lp_code_rate,       guard_interval);
+        lp_code_rate,       guard_interval,
+        mod_sys,            rolloff);
 }
 
 uint ChannelUtil::CreateMultiplex(uint sourceid, const DTVMultiplex &mux,
@@ -448,7 +467,8 @@ uint ChannelUtil::CreateMultiplex(uint sourceid, const DTVMultiplex &mux,
         mux.trans_mode.toChar().toAscii(),
         mux.fec.toString(),               mux.modulation.toString(),
         mux.hierarchy.toChar().toAscii(), mux.hp_code_rate.toString(),
-        mux.lp_code_rate.toString(),      mux.guard_interval.toString());
+        mux.lp_code_rate.toString(),      mux.guard_interval.toString(),
+        mux.mod_sys.toString(),           mux.rolloff.toString());
 }
 
 
diff --git a/mythtv/libs/libmythtv/channelutil.h b/mythtv/libs/libmythtv/channelutil.h
index ed9fdb4..31de276 100644
--- a/mythtv/libs/libmythtv/channelutil.h
+++ b/mythtv/libs/libmythtv/channelutil.h
@@ -67,7 +67,8 @@ class MPUBLIC ChannelUtil
         signed char trans_mode,
         QString     inner_FEC,    QString     constellation,
         signed char hierarchy,    QString     hp_code_rate,
-        QString     lp_code_rate, QString     guard_interval);
+        QString     lp_code_rate, QString     guard_interval,
+        QString     mod_sys,      QString     rolloff);
 
     static uint    CreateMultiplex(uint sourceid, const DTVMultiplex&,
                                    int transport_id, int network_id);
diff --git a/mythtv/libs/libmythtv/dtvconfparser.cpp b/mythtv/libs/libmythtv/dtvconfparser.cpp
index 1dfedc1..bbaacc7 100644
--- a/mythtv/libs/libmythtv/dtvconfparser.cpp
+++ b/mythtv/libs/libmythtv/dtvconfparser.cpp
@@ -112,7 +112,7 @@ DTVConfParser::return_t DTVConfParser::Parse(void)
         {
             if ((type == OFDM) && (str == "T"))
                 ok &= ParseVDR(list, channelNo);
-            else if ((type == QPSK) && (str == "S"))
+            else if ((type == QPSK || type == DVBS2) && (str == "S"))
                 ok &= ParseVDR(list, channelNo);
             else if ((type == QAM) && (str == "C"))
                 ok &= ParseVDR(list, channelNo);
@@ -121,7 +121,7 @@ DTVConfParser::return_t DTVConfParser::Parse(void)
             ok &= ParseConfOFDM(list);
         else if (type == ATSC)
             ok &= ParseConfATSC(list);
-        else if (type == QPSK)
+        else if (type == QPSK || type == DVBS2)
             ok &= ParseConfQPSK(list);
         else if (type == QAM)
             ok &= ParseConfQAM(list);
@@ -275,6 +275,12 @@ bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
             case 'L':
                 mux.polarity.ParseVDR(ori);
                 break;
+            case 'S':
+                mux.mod_sys.ParseVDR(params);
+                break;
+            case 'O':
+                mux.rolloff.ParseVDR(params);
+                break;
             default:
                 return false;
         }
diff --git a/mythtv/libs/libmythtv/dtvconfparser.h b/mythtv/libs/libmythtv/dtvconfparser.h
index 2795493..a230782 100644
--- a/mythtv/libs/libmythtv/dtvconfparser.h
+++ b/mythtv/libs/libmythtv/dtvconfparser.h
@@ -80,7 +80,7 @@ class DTVConfParser
 {
   public:
     enum return_t   { ERROR_CARDTYPE, ERROR_OPEN, ERROR_PARSE, OK };
-    enum cardtype_t { ATSC, OFDM, QPSK, QAM, UNKNOWN };
+    enum cardtype_t { ATSC, OFDM, QPSK, QAM, DVBS2, UNKNOWN };
 
     DTVConfParser(enum cardtype_t _type, uint sourceid, const QString &_file);
     virtual ~DTVConfParser() { }
diff --git a/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp b/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp
index 697e882..12c974f 100644
--- a/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp
+++ b/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp
@@ -12,7 +12,7 @@ bool DTVParamHelper::ParseParam(const QString &symbol, int &value,
 
     while (!p->symbol.isEmpty())
     {
-        if (p->symbol == symbol.left(p->symbol.length()))
+        if (p->symbol == symbol) //.left(p->symbol.length()))
         {
             //symbol = symbol.mid(p->symbol.length());
             value = p->value;
@@ -155,6 +155,8 @@ const DTVParamHelperStruct DTVCodeRate::confTable[] =
     { "FEC_7_8",  kFEC_7_8  },
     { "FEC_8_9",  kFEC_8_9  },
     { "FEC_NONE", kFECNone },
+    { "FEC_3_5",  kFEC_3_5  },
+    { "FEC_9_10", kFEC_9_10 },
     { NULL,       kFECAuto },
 };
 
@@ -170,6 +172,8 @@ const DTVParamHelperStruct DTVCodeRate::vdrTable[] =
     { "78",  kFEC_7_8 },
     { "89",  kFEC_8_9 },
     { "0",   kFECNone },
+    { "35",  kFEC_3_5 },
+    { "910", kFEC_9_10 },
     { NULL,  kFECAuto }
 };
 
@@ -199,7 +203,9 @@ const char *DTVCodeRate::dbStr[DTVCodeRate::kDBStrCnt] =
      "6/7",  ///< kFEC_6_7
      "7/8",  ///< kFEC_7_8
      "8/9",  ///< kFEC_8_9
-     "auto"  ///< kFECAuto
+     "auto", ///< kFECAuto
+     "3/5",  ///< KFEC_3_5
+     "9/10",  ///< KFEC_9_10
 };
 
 const DTVParamHelperStruct DTVModulation::confTable[] =
@@ -213,26 +219,32 @@ const DTVParamHelperStruct DTVModulation::confTable[] =
    { "QPSK",     kModulationQPSK    },
    { "8VSB",     kModulation8VSB    },
    { "16VSB",    kModulation16VSB   },
-   { "2VSB",     kModulation2VSB    },
-   { "4VSB",     kModulation4VSB    },
-   { "BPSK",     kModulationBPSK    },
+   { "8PSK",     kModulation8PSK    },
    { "16APSK",   kModulation16APSK  },
    { "32APSK",   kModulation32APSK  },
-   { "8PSK",     kModulation8PSK    },
-   { "16PSK",    kModulation16PSK   },
+   { "DQPSK",    kModulationDQPSK   },
+   { "16PSK",    kModulationInvalid },
+   { "2VSB",     kModulationInvalid },
+   { "4VSB",     kModulationInvalid },
+   { "BPSK",     kModulationInvalid },
    { "analog",   kModulationAnalog  },
    { NULL,       kModulationQAMAuto },
 };
 
 const DTVParamHelperStruct DTVModulation::vdrTable[] =
 {
-   { "999", kModulationQAMAuto },
+   { "998", kModulationQAMAuto },
    { "16",  kModulationQAM16   },
    { "32",  kModulationQAM32   },
    { "64",  kModulationQAM64   },
    { "128", kModulationQAM128  },
    { "256", kModulationQAM256  },
-   { "0",   kModulationQPSK    },
+   { "2",   kModulationQPSK    },
+   { "5",   kModulation8PSK    },
+   { "6",   kModulation16APSK  },
+   { "7",   kModulation32APSK  },
+   { "10",  kModulation8VSB    },
+   { "11",  kModulation16VSB   },
    { NULL,  kModulationQAMAuto },
 };
 
@@ -247,13 +259,10 @@ const DTVParamHelperStruct DTVModulation::parseTable[] =
    { "qpsk",     kModulationQPSK    },
    { "8vsb",     kModulation8VSB    },
    { "16vsb",    kModulation16VSB   },
-   { "2vsb",     kModulation2VSB    },
-   { "4vsb",     kModulation4VSB    },
-   { "bpsk",     kModulationBPSK    },
+   { "8psk",     kModulation8PSK    },
    { "16apsk",   kModulation16APSK  },
    { "32apsk",   kModulation32APSK  },
-   { "8psk",     kModulation8PSK    },
-   { "16psk",    kModulation16PSK   },
+   { "dqpsk",    kModulationDQPSK   },
    // alternates
    { "a",        kModulationQAMAuto },
    { "qam_auto", kModulationQAMAuto },
@@ -265,13 +274,18 @@ const DTVParamHelperStruct DTVModulation::parseTable[] =
    // qpsk, no alternative
    { "8-vsb",    kModulation8VSB    },
    { "16-vsb",   kModulation16VSB   },
-   { "2-vsb",    kModulation2VSB    },
-   { "4-vsb",    kModulation4VSB    },
    // bpsk, no alternative
    { "16-apsk",  kModulation16APSK  },
    { "32-apsk",  kModulation32APSK  },
    { "8-psk",    kModulation8PSK    },
-   { "16-psk",   kModulation16PSK   },
+   // removed modulations and alternatives
+   { "bpsk",     kModulationInvalid },
+   { "2vsb",     kModulationInvalid },
+   { "2-vsb",    kModulationInvalid },
+   { "4vsb",     kModulationInvalid },
+   { "4-vsb",    kModulationInvalid },
+   { "16psk",    kModulationInvalid },
+   { "16-psk",   kModulationInvalid },
    { NULL,       kModulationQAMAuto },
 };
 
@@ -286,13 +300,10 @@ const char *DTVModulation::dbStr[DTVModulation::kDBStrCnt] =
     "auto",    ///< kModulationQAMAuto
     "8vsb",    ///< kModulation8VSB
     "16vsb",   ///< kModulation16VSB
-    "2vsb",    ///< kModulation2VSB
-    "4vsb",    ///< kModulation4VSB
-    "bpsk",    ///< kModulationBPSK
+    "8psk",    ///< kModulation8PSK
     "16apsk",  ///< kModulation16APSK
     "32apsk",  ///< kModulation32APSK
-    "8psk",    ///< kModulation8PSK
-    "16psk",   ///< kModulation16PSK
+    "dqpsk"    ///< kModulationDQPSK
 };
 
 const DTVParamHelperStruct DTVTransmitMode::confTable[] =
@@ -420,3 +431,106 @@ const char *DTVPolarity::dbStr[DTVPolarity::kDBStrCnt] =
    "r", ///< kPolarityRight
    "l"  ///< kPolarityLeft
 };
+
+const DTVParamHelperStruct DTVModulationSystem::confTable[] =
+{
+    { "SYS_UNDEFINED",     kModulationSystem_UNDEFINED     },
+    { "SYS_DVBC_ANNEX_AC", kModulationSystem_DVBC_ANNEX_AC },
+    { "SYS_DVBC_ANNEX_B",  kModulationSystem_DVBC_ANNEX_B  },
+    { "SYS_DVBT",          kModulationSystem_DVBT          },
+    { "SYS_DSS",           kModulationSystem_DSS           },
+    { "SYS_DVBS",          kModulationSystem_DVBS          },
+    { "SYS_DVBS2",         kModulationSystem_DVBS2         },
+    { "SYS_DVBH",          kModulationSystem_DVBH          },
+    { "SYS_ISDBT",         kModulationSystem_ISDBT         },
+    { "SYS_ISDBS",         kModulationSystem_ISDBS         },
+    { "SYS_ISDBC",         kModulationSystem_ISDBC         },
+    { "SYS_ATSC",          kModulationSystem_ATSC          },
+    { "SYS_ATSCMH",        kModulationSystem_ATSCMH        },
+    { "SYS_DMBTH",         kModulationSystem_DMBTH         },
+    { "SYS_CMMB",          kModulationSystem_CMMB          },
+    { "SYS_DAB",           kModulationSystem_DAB           },
+    { NULL,                kModulationSystem_UNDEFINED     },
+};
+
+const DTVParamHelperStruct DTVModulationSystem::vdrTable[] =
+{
+    { "0",  kModulationSystem_DVBS      },
+    { "1",  kModulationSystem_DVBS2     },
+    { NULL, kModulationSystem_UNDEFINED },
+};
+
+const DTVParamHelperStruct DTVModulationSystem::parseTable[] =
+{
+    { "UNDEFINED", kModulationSystem_UNDEFINED     },
+    { "DVBC_AC",   kModulationSystem_DVBC_ANNEX_AC },
+    { "DVBC_B",    kModulationSystem_DVBC_ANNEX_B  },
+    { "DVBT",      kModulationSystem_DVBT          },
+    { "DSS",       kModulationSystem_DSS           },
+    { "DVB-S",     kModulationSystem_DVBS          },
+    { "DVB-S2",    kModulationSystem_DVBS2         },
+    { "DVBH",      kModulationSystem_DVBH          },
+    { "ISDBT",     kModulationSystem_ISDBT         },
+    { "ISDBS",     kModulationSystem_ISDBS         },
+    { "ISDBC",     kModulationSystem_ISDBC         },
+    { "ATSC",      kModulationSystem_ATSC          },
+    { "ATSCMH",    kModulationSystem_ATSCMH        },
+    { "DMBTH",     kModulationSystem_DMBTH         },
+    { "CMMB",      kModulationSystem_CMMB          },
+    { "DAB",       kModulationSystem_DAB           },
+    { NULL,        kModulationSystem_UNDEFINED    },
+};
+
+const char *DTVModulationSystem::dbStr[DTVModulationSystem::kDBStrCnt] =
+{
+    "UNDEFINED", ///< kModulationSystem_UNDEFINED
+    "DVBCAC",    ///< kModulationSystem_DVBC_ANNEX_AC
+    "DVBC_B",    ///< kModulationSystem_DVBC_ANNEX_B
+    "DVBT",      ///< kModulationSystem_DVBT
+    "DSS",       ///< kModulationSystem_DSS
+    "DVB-S",     ///< kModulationSystem_DVBS
+    "DVB-S2",    ///< kModulationSystem_DVBS2
+    "DVBH",      ///< kModulationSystem_DVBH
+    "ISDBT",     ///< kModulationSystem_ISDBT
+    "ISDBS",     ///< kModulationSystem_ISDBS
+    "ISDBC",     ///< kModulationSystem_ISDBC
+    "ATSC",      ///< kModulationSystem_ATSC
+    "ATSCMH",    ///< kModulationSystem_ATSCMH
+    "DMBTH",     ///< kModulationSystem_DMBTH
+    "CMMB",      ///< kModulationSystem_CMMB
+    "DAB",       ///< kModulationSystem_DAB
+};
+
+const DTVParamHelperStruct DTVRollOff::confTable[] =
+{
+   { "ROLLOFF_35",   kRollOff_35   },
+   { "ROLLOFF_20",   kRollOff_20   },
+   { "ROLLOFF_25",   kRollOff_25   },
+   { "ROLLOFF_AUTO", kRollOff_Auto },
+   { NULL,           kRollOff_35 },
+};
+
+const DTVParamHelperStruct DTVRollOff::vdrTable[] =
+{
+   { "35",   kRollOff_35   },
+   { "20",   kRollOff_20   },
+   { "25",   kRollOff_25   },
+   { "0",    kRollOff_Auto },
+   { NULL,   kRollOff_35   },
+};
+const DTVParamHelperStruct DTVRollOff::parseTable[] =
+{
+   { "0.35", kRollOff_35   },
+   { "0.20", kRollOff_20   },
+   { "0.25", kRollOff_25   },
+   { "auto", kRollOff_Auto },
+   { NULL,   kRollOff_35   },
+};
+
+const char *DTVRollOff::dbStr[DTVRollOff::kDBStrCnt] =
+{
+   "0.35",   ///< kRollOff_35
+   "0.20",   ///< kRollOff_20
+   "0.25",   ///< kRollOff_25
+   "auto", ///< kRollOff_Auto
+};
diff --git a/mythtv/libs/libmythtv/dtvconfparserhelpers.h b/mythtv/libs/libmythtv/dtvconfparserhelpers.h
index c9f3a1c..d33fdb7 100644
--- a/mythtv/libs/libmythtv/dtvconfparserhelpers.h
+++ b/mythtv/libs/libmythtv/dtvconfparserhelpers.h
@@ -201,7 +201,7 @@ class DTVCodeRate : public DTVParamHelper
     static const DTVParamHelperStruct confTable[];
     static const DTVParamHelperStruct vdrTable[];
     static const DTVParamHelperStruct parseTable[];
-    static const uint kDBStrCnt = 10;
+    static const uint kDBStrCnt = 12;
     static const char *dbStr[kDBStrCnt];
 
   public:
@@ -217,6 +217,8 @@ class DTVCodeRate : public DTVParamHelper
         kFEC_7_8,
         kFEC_8_9,
         kFECAuto,
+        kFEC_3_5,
+        kFEC_9_10,
     };
 
     DTVCodeRate(int _default = kFECAuto) : DTVParamHelper(_default) { }
@@ -245,29 +247,27 @@ class DTVModulation : public DTVParamHelper
     static const DTVParamHelperStruct confTable[];
     static const DTVParamHelperStruct vdrTable[];
     static const DTVParamHelperStruct parseTable[];
-    static const uint kDBStrCnt = 17;
+    static const uint kDBStrCnt = 13;
     static const char *dbStr[kDBStrCnt];
 
   public:
     enum
     {
-        kModulationQPSK    = 0,
-        kModulationQAM16   = 1,
-        kModulationQAM32   = 2,
-        kModulationQAM64   = 3,
-        kModulationQAM128  = 4,
-        kModulationQAM256  = 5,
-        kModulationQAMAuto = 6,
-        kModulation8VSB    = 7,
-        kModulation16VSB   = 8,
-        kModulation2VSB    = 9,
-        kModulation4VSB    = 10,
-        kModulationBPSK    = 11,
-        kModulation16APSK  = 12,
-        kModulation32APSK  = 13,
-        kModulation8PSK    = 14,
-        kModulation16PSK   = 15,
-        kModulationAnalog  = 16, /* for analog channel scanner */
+        kModulationQPSK,
+        kModulationQAM16,
+        kModulationQAM32,
+        kModulationQAM64,
+        kModulationQAM128,
+        kModulationQAM256,
+        kModulationQAMAuto,
+        kModulation8VSB,
+        kModulation16VSB,
+        kModulation8PSK,
+        kModulation16APSK,
+        kModulation32APSK,
+        kModulationDQPSK,
+        kModulationInvalid = 0x100, /* for removed modulations */
+        kModulationAnalog  = 0x200, /* for analog channel scanner */
     };
 
     DTVModulation(int _default = kModulationQAMAuto)
@@ -449,4 +449,89 @@ class DTVPolarity : public DTVParamHelper
         { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
 };
 
+class DTVModulationSystem : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 16;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kModulationSystem_UNDEFINED,
+        kModulationSystem_DVBC_ANNEX_AC,
+        kModulationSystem_DVBC_ANNEX_B,
+        kModulationSystem_DVBT,
+        kModulationSystem_DSS,
+        kModulationSystem_DVBS,
+        kModulationSystem_DVBS2,
+        kModulationSystem_DVBH,
+        kModulationSystem_ISDBT,
+        kModulationSystem_ISDBS,
+        kModulationSystem_ISDBC,
+        kModulationSystem_ATSC,
+        kModulationSystem_ATSCMH,
+        kModulationSystem_DMBTH,
+        kModulationSystem_CMMB,
+        kModulationSystem_DAB,
+    };
+
+    DTVModulationSystem(int _default = kModulationSystem_UNDEFINED)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVRollOff : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 4;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kRollOff_35,
+        kRollOff_20,
+        kRollOff_25,
+        kRollOff_Auto,
+    };
+
+    DTVRollOff(int _default = kRollOff_35)
+        : DTVParamHelper(_default) { }
+
+    bool IsCompatible(const DTVRollOff &other) const
+        { return value == other.value || value == kRollOff_Auto ||
+                other.value == kRollOff_Auto;
+        }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
 #endif // _DTVCONFPARSERHELPERS_H_
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.cpp b/mythtv/libs/libmythtv/dtvmultiplex.cpp
index cd1dc81..9ca2310 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.cpp
+++ b/mythtv/libs/libmythtv/dtvmultiplex.cpp
@@ -22,6 +22,8 @@ DTVMultiplex &DTVMultiplex::operator=(const DTVMultiplex &other)
     hierarchy      = other.hierarchy;
     polarity       = other.polarity;
     fec            = other.fec;
+    mod_sys        = other.mod_sys;
+    rolloff        = other.rolloff;
     mplex          = other.mplex;
     sistandard     = other.sistandard;
     sistandard.detach();
@@ -39,6 +41,8 @@ bool DTVMultiplex::operator==(const DTVMultiplex &m) const
             (trans_mode == m.trans_mode) &&
             (guard_interval == m.guard_interval) &&
             (fec == m.fec) &&
+            (mod_sys  == m.mod_sys)  &&
+            (rolloff  == m.rolloff)  &&
             (polarity == m.polarity) &&
             (hierarchy == m.hierarchy));
 }
@@ -56,6 +60,8 @@ QString DTVMultiplex::toString() const
         .arg(bandwidth.toString()).arg(trans_mode.toString())
         .arg(guard_interval.toString()).arg(hierarchy.toString())
         .arg(polarity.toString());
+    ret += QString(" msys: %1 rolloff: %2")
+        .arg(mod_sys.toString()).arg(rolloff.toString());
 
     return ret;
 }
@@ -117,17 +123,20 @@ bool DTVMultiplex::IsEqual(DTVTunerType type, const DTVMultiplex &other,
     if ((DTVTunerType::kTunerTypeDVB_S2 == type) ||
         (DTVTunerType::kTunerTypeQPSK   == type))
     {
+        bool ret =
+            (symbolrate == other.symbolrate)        &&
+            (polarity   == other.polarity)          &&
+            (mod_sys    == other.mod_sys);
+
         if (fuzzy)
-            return
+            return ret &&
                 inversion.IsCompatible(other.inversion) &&
-                (symbolrate == other.symbolrate)        &&
-                (polarity   == other.polarity)          &&
-                fec.IsCompatible(other.fec);
-        return
+                fec.IsCompatible(other.fec)             &&
+                rolloff.IsCompatible(other.rolloff);
+        return ret &&
             (inversion  == other.inversion)  &&
-            (symbolrate == other.symbolrate) &&
-            (polarity   == other.polarity)   &&
-            (fec        == other.fec);
+            (fec        == other.fec)        &&
+            (rolloff    == other.rolloff);
     }
 
     return false;
@@ -220,13 +229,36 @@ bool DTVMultiplex::ParseDVB_S_and_C(
     return ok;
 }
 
+bool DTVMultiplex::ParseDVB_S2(
+    const QString &_frequency,   const QString &_inversion,
+    const QString &_symbol_rate, const QString &_fec_inner,
+    const QString &_modulation,  const QString &_polarity,
+    const QString &_mod_sys,     const QString &_rolloff)
+{
+    bool ok = ParseDVB_S_and_C(_frequency, _inversion, _symbol_rate,
+                               _fec_inner, _modulation, _polarity);
+
+    if (!mod_sys.Parse(_mod_sys))
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid S2 modulation system " +
+                QString("parameter '%1', aborting.").arg(_mod_sys));
+        return false;
+    }
+
+    if (!_rolloff.isEmpty())
+        ok &= rolloff.Parse(_rolloff);
+
+    return ok;
+}
+
 bool DTVMultiplex::ParseTuningParams(
     DTVTunerType type,
     QString _frequency,    QString _inversion,      QString _symbolrate,
     QString _fec,          QString _polarity,
     QString _hp_code_rate, QString _lp_code_rate,   QString _ofdm_modulation,
     QString _trans_mode,   QString _guard_interval, QString _hierarchy,
-    QString _modulation,   QString _bandwidth)
+    QString _modulation,   QString _bandwidth,
+    QString _mod_sys,      QString _rolloff)
 {
     if (DTVTunerType::kTunerTypeOFDM == type)
     {
@@ -237,7 +269,6 @@ bool DTVMultiplex::ParseTuningParams(
     }
 
     if ((DTVTunerType::kTunerTypeQPSK   == type) ||
-        (DTVTunerType::kTunerTypeDVB_S2 == type) ||
         (DTVTunerType::kTunerTypeQAM    == type))
     {
         return ParseDVB_S_and_C(
@@ -245,6 +276,12 @@ bool DTVMultiplex::ParseTuningParams(
             _fec,             _modulation,    _polarity);
     }
 
+    if (DTVTunerType::kTunerTypeDVB_S2 == type)
+        return ParseDVB_S2(
+            _frequency,       _inversion,     _symbolrate,
+            _fec,             _modulation,    _polarity,
+            _mod_sys,         _rolloff);
+
     if (DTVTunerType::kTunerTypeATSC == type)
         return ParseATSC(_frequency, _modulation);
 
@@ -263,7 +300,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid)
         "       fec,               polarity, "
         "       hp_code_rate,      lp_code_rate,   constellation, "
         "       transmission_mode, guard_interval, hierarchy, "
-        "       modulation,        bandwidth,      sistandard "
+        "       modulation,        bandwidth,      sistandard, "
+        "       mod_sys,           rolloff "
         "FROM dtv_multiplex "
         "WHERE dtv_multiplex.mplexid = :MPLEXID");
     query.bindValue(":MPLEXID", mplexid);
@@ -296,7 +334,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid)
         query.value(6).toString(),  query.value(7).toString(),
         query.value(8).toString(),  query.value(9).toString(),
         query.value(10).toString(), query.value(11).toString(),
-        query.value(12).toString());
+        query.value(12).toString(), query.value(14).toString(),
+        query.value(15).toString());
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -364,6 +403,7 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
         "    symbolrate,         fec,             polarity,   "
         "    hp_code_rate,       lp_code_rate,    modulation, "
         "    transmission_mode,  guard_interval,  hierarchy,  "
+        "    mod_sys,            rolloff,                     "
         "    bandwidth,          sistandard,      tuner_type  "
         " ) "
         "VALUES "
@@ -372,6 +412,7 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
         "   :SYMBOLRATE,        :FEC,            :POLARITY,   "
         "   :HP_CODE_RATE,      :LP_CODE_RATE,   :MODULATION, "
         "   :TRANSMISSION_MODE, :GUARD_INTERVAL, :HIERARCHY,  "
+        "   :MOD_SYS,           :ROLLOFF,                     "
         "   :BANDWIDTH,         :SISTANDARD,     :TUNER_TYPE  "
         " );");
 
@@ -388,6 +429,8 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
     query.bindValue(":TRANSMISSION_MODE", trans_mode.toString());
     query.bindValue(":GUARD_INTERVAL", guard_interval.toString());
     query.bindValue(":HIERARCHY", hierarchy.toString());
+    query.bindValue(":MOD_SYS", mod_sys.toString());
+    query.bindValue(":ROLLOFF", rolloff.toString());
     query.bindValue(":BANDWIDTH", bandwidth.toString());
     query.bindValue(":SISTANDARD", sistandard);
     query.bindValue(":TUNER_TYPE", (uint)tuner_type);
@@ -419,7 +462,8 @@ bool ScanDTVTransport::ParseTuningParams(
     QString _fec,          QString _polarity,
     QString _hp_code_rate, QString _lp_code_rate,   QString _ofdm_modulation,
     QString _trans_mode,   QString _guard_interval, QString _hierarchy,
-    QString _modulation,   QString _bandwidth)
+    QString _modulation,   QString _bandwidth,      QString _mod_sys,
+    QString _rolloff)
 {
     tuner_type = type;
 
@@ -429,7 +473,8 @@ bool ScanDTVTransport::ParseTuningParams(
         _fec,           _polarity,
         _hp_code_rate,  _lp_code_rate,    _ofdm_modulation,
         _trans_mode,    _guard_interval,  _hierarchy,
-        _modulation,    _bandwidth);
+        _modulation,    _bandwidth,       _mod_sys,
+        _rolloff);
 }
 
 
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.h b/mythtv/libs/libmythtv/dtvmultiplex.h
index 0f1d076..db5bcd9 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.h
+++ b/mythtv/libs/libmythtv/dtvmultiplex.h
@@ -49,13 +49,20 @@ class DTVMultiplex
         const QString &symbol_rate,  const QString &fec_inner,
         const QString &modulation,   const QString &polarity);
 
+    bool ParseDVB_S2(
+        const QString &frequency,    const QString &inversion,
+        const QString &symbol_rate,  const QString &fec_inner,
+        const QString &modulation,   const QString &polarity,
+        const QString &mod_sys,      const QString &rolloff);
+
     bool ParseTuningParams(
         DTVTunerType type,
         QString frequency,    QString inversion,      QString symbolrate,
         QString fec,          QString polarity,
         QString hp_code_rate, QString lp_code_rate,   QString constellation,
         QString trans_mode,   QString guard_interval, QString hierarchy,
-        QString modulation,   QString bandwidth);
+        QString modulation,   QString bandwidth,      QString mod_sys,
+        QString rolloff);
 
     QString toString() const;
 
@@ -74,6 +81,8 @@ class DTVMultiplex
     DTVHierarchy     hierarchy;
     DTVPolarity      polarity;
     DTVCodeRate      fec; ///< Inner Forward Error Correction rate
+    DTVModulationSystem mod_sys; ///< modulation system (only DVB-S or DVB-S2 atm)
+    DTVRollOff       rolloff;
 
     // Optional additional info
     uint             mplex;
@@ -99,7 +108,8 @@ class ScanDTVTransport : public DTVMultiplex
         QString fec,          QString polarity,
         QString hp_code_rate, QString lp_code_rate,   QString constellation,
         QString trans_mode,   QString guard_interval, QString hierarchy,
-        QString modulation,   QString bandwidth);
+        QString modulation,   QString bandwidth,
+        QString mod_sys,      QString rolloff);
 
   public:
     DTVTunerType          tuner_type;
diff --git a/mythtv/libs/libmythtv/dvbchannel.cpp b/mythtv/libs/libmythtv/dvbchannel.cpp
index 5ed8f60..846e9ea 100644
--- a/mythtv/libs/libmythtv/dvbchannel.cpp
+++ b/mythtv/libs/libmythtv/dvbchannel.cpp
@@ -40,6 +40,7 @@
 #include <sys/types.h>
 
 // MythTV headers
+#include "mythconfig.h"
 #include "mythdb.h"
 #include "cardutil.h"
 #include "channelutil.h"
@@ -49,10 +50,10 @@
 
 static void drain_dvb_events(int fd);
 static bool wait_for_backend(int fd, int timeout_ms);
-static struct dvb_fe_params dtvmultiplex_to_dvbparams(
-    DTVTunerType, const DTVMultiplex&);
+static struct dvb_frontend_parameters dtvmultiplex_to_dvbparams(
+    DTVTunerType, const DTVMultiplex&, int intermediate_freq, bool can_fec_auto);
 static DTVMultiplex dvbparams_to_dtvmultiplex(
-    DTVTunerType, const dvb_fe_params&);
+    DTVTunerType, const dvb_frontend_parameters&);
 
 #define LOC QString("DVBChan(%1:%2): ").arg(GetCardID()).arg(device)
 #define LOC_WARN QString("DVBChan(%1:%2) Warning: ") \
@@ -210,51 +211,13 @@ bool DVBChannel::Open(DVBChannel *who)
         return false;
     }
 
-#ifdef FE_GET_EXTENDED_INFO
-    if (info.caps & FE_HAS_EXTENDED_INFO)
-    {
-        bool ok = true;
-        dvb_fe_caps_extended extinfo;
-        bzero(&extinfo, sizeof(extinfo));
-        if (ioctl(fd_frontend, FE_GET_EXTENDED_INFO, &extinfo) < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Failed to get frontend extended information." + ENO);
-
-            ok = false;
-        }
-
-        if (ok && (extinfo.modulations & MOD_8PSK))
-        {
-            if (ioctl(fd_frontend, FE_SET_STANDARD, FE_DVB_S2) < 0)
-            {
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "Failed to set frontend standard to DVB-S2." + ENO);
-
-                ok = false;
-            }
-            else if (ioctl(fd_frontend, FE_GET_INFO, &info) < 0)
-            {
-                VERBOSE(VB_IMPORTANT, LOC_ERR +
-                        "Failed to get frontend information." + ENO);
-
-                ok = false;
-            }
-        }
-
-        if (!ok)
-        {
-            close(fd_frontend);
-            fd_frontend = -1;
-            return false;
-        }
-
-        ext_modulations   = extinfo.modulations;
-    }
-#endif
-
     frontend_name       = info.name;
     card_type           = info.type;
+#if HAVE_FE_CAN_2G_MODULATION
+    if (card_type == DTVTunerType::kTunerTypeQPSK &&
+        (info.caps & FE_CAN_2G_MODULATION))
+        card_type = DTVTunerType::kTunerTypeDVB_S2;
+#endif // HAVE_FE_CAN_2G_MODULATION
     capabilities        = info.caps;
     frequency_minimum   = info.frequency_min;
     frequency_maximum   = info.frequency_max;
@@ -596,15 +559,6 @@ bool DVBChannel::CheckModulation(DTVModulation modulation) const
     const DTVModulation m = modulation;
     const uint64_t      c = capabilities;
 
-#ifdef FE_GET_EXTENDED_INFO
-    if ((c & FE_HAS_EXTENDED_INFO)            &&
-        (DTVModulation::kModulation8PSK == m) &&
-        (ext_modulations & DTVModulation::kModulation8PSK))
-    {
-        return true;
-    }
-#endif // FE_GET_EXTENDED_INFO
-
     return
         ((DTVModulation::kModulationQPSK    == m) && (c & FE_CAN_QPSK))     ||
         ((DTVModulation::kModulationQAM16   == m) && (c & FE_CAN_QAM_16))   ||
@@ -649,6 +603,95 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning, QString inputname)
     return Tune(tuning, inputid, false, false);
 }
 
+#if DVB_API_VERSION >= 5
+static struct dtv_properties *dtvmultiplex_to_dtvproperties(
+    DTVTunerType tuner_type, const DTVMultiplex &tuning, int intermediate_freq,
+    bool can_fec_auto, bool do_tune = true)
+{
+    uint c = 0;
+    struct dtv_properties *cmdseq = (struct dtv_properties*) calloc(1, sizeof(*cmdseq));
+    if (!cmdseq)
+        return NULL;
+
+    cmdseq->props = (struct dtv_property*) calloc(11, sizeof(*(cmdseq->props)));
+    if (!(cmdseq->props))
+    {
+        free(cmdseq);
+        return NULL;
+    }
+
+    if (tuner_type == DTVTunerType::kTunerTypeDVB_S2)
+    {
+        cmdseq->props[c].cmd      = DTV_DELIVERY_SYSTEM;
+        cmdseq->props[c++].u.data = tuning.mod_sys;
+    }
+
+    if (tuning.mod_sys == DTVModulationSystem::kModulationSystem_DVBS2)
+    {
+        cmdseq->props[c].cmd      = DTV_PILOT;
+        cmdseq->props[c++].u.data = PILOT_AUTO;
+        cmdseq->props[c].cmd      = DTV_ROLLOFF;
+        cmdseq->props[c++].u.data = tuning.rolloff;
+    }
+
+    cmdseq->props[c].cmd      = DTV_FREQUENCY;
+    cmdseq->props[c++].u.data = intermediate_freq ? intermediate_freq : tuning.frequency;
+    cmdseq->props[c].cmd      = DTV_MODULATION;
+    cmdseq->props[c++].u.data = tuning.modulation;
+    cmdseq->props[c].cmd      = DTV_INVERSION;
+    cmdseq->props[c++].u.data = tuning.inversion;
+
+    if (tuner_type.IsFECVariable())
+    {
+        cmdseq->props[c].cmd      = DTV_INNER_FEC;
+        cmdseq->props[c++].u.data = can_fec_auto ? FEC_AUTO : tuning.fec;
+    }
+
+    if (tuner_type == DTVTunerType::kTunerTypeQPSK   ||
+        tuner_type == DTVTunerType::kTunerTypeDVB_S2 ||
+        tuner_type == DTVTunerType::kTunerTypeQAM)
+    {
+        cmdseq->props[c].cmd      = DTV_SYMBOL_RATE;
+        cmdseq->props[c++].u.data = tuning.symbolrate;
+    }
+    else if (tuner_type == DTVTunerType::kTunerTypeOFDM)
+    {
+        cmdseq->props[c].cmd      = DTV_BANDWIDTH_HZ;
+        cmdseq->props[c++].u.data = (8-tuning.bandwidth) * 1000000;
+        cmdseq->props[c].cmd      = DTV_CODE_RATE_HP;
+        cmdseq->props[c++].u.data = tuning.hp_code_rate;
+        cmdseq->props[c].cmd      = DTV_CODE_RATE_LP;
+        cmdseq->props[c++].u.data = tuning.lp_code_rate;
+        cmdseq->props[c].cmd      = DTV_TRANSMISSION_MODE;
+        cmdseq->props[c++].u.data = tuning.trans_mode;
+        cmdseq->props[c].cmd      = DTV_GUARD_INTERVAL;
+        cmdseq->props[c++].u.data = tuning.guard_interval;
+        cmdseq->props[c].cmd      = DTV_HIERARCHY;
+        cmdseq->props[c++].u.data = tuning.hierarchy;
+    }
+    else
+    {
+        VERBOSE(VB_IMPORTANT, "Unknown tuner type." + ENO);
+        return NULL;
+    }
+
+    if (do_tune)
+        cmdseq->props[c++].cmd    = DTV_TUNE;
+
+    cmdseq->num = c;
+
+#if 0
+    for (int i = 0; i < cmdseq->num; i++)
+    {
+        cerr << "prop " << i << ": cmd = " <<  cmdseq->props[i].cmd
+             << " data = " << cmdseq->props[i].u.data << endl;
+    }
+#endif
+    return cmdseq;
+}
+#endif
+
+
 /*****************************************************************************
            Tuning functions for each of the four types of cards.
  *****************************************************************************/
@@ -679,8 +722,9 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning,
         return master->Tune(tuning, inputid, force_reset, false);
     }
 
+    int intermediate_freq = 0;
+    bool can_fec_auto = false;
     bool reset = (force_reset || first_tune);
-    struct dvb_fe_params params = dtvmultiplex_to_dvbparams(card_type, tuning);
 
     bool is_dvbs = (DTVTunerType::kTunerTypeQPSK   == card_type ||
                     DTVTunerType::kTunerTypeDVB_S2 == card_type);
@@ -738,12 +782,12 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning,
             reset = first_tune = true;
         }
         
-        params.frequency = lnb->GetIntermediateFrequency(
+        intermediate_freq = lnb->GetIntermediateFrequency(
             diseqc_settings, tuning);
 
         // if card can auto-FEC, use it -- sometimes NITs are inaccurate
         if (capabilities & FE_CAN_FEC_AUTO)
-            params.u.qpsk.fec_inner = FEC_AUTO;
+            can_fec_auto = true;
     }
 
     VERBOSE(VB_CHANNEL, LOC + "Old Params: " +
@@ -758,21 +802,34 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning,
     if (reset || !prev_tuning.IsEqual(card_type, tuning, 500 * freq_mult))
     {
         VERBOSE(VB_CHANNEL, LOC + QString("Tune(): Tuning to %1%2")
-                .arg(params.frequency).arg(suffix));
+                .arg(intermediate_freq ? intermediate_freq : tuning.frequency)
+                .arg(suffix));
 
-#ifdef FE_GET_EXTENDED_INFO
-        if (card_type == DTVTunerType::kTunerTypeDVB_S2)
+#if DVB_API_VERSION >=5
+        if (DTVTunerType::kTunerTypeDVB_S2 == card_type)
         {
-            if (ioctl(fd_frontend, FE_SET_FRONTEND2, &params) < 0)
+            struct dtv_properties *cmds = dtvmultiplex_to_dtvproperties(
+                card_type, tuning,  intermediate_freq, can_fec_auto);
+
+            if (!cmds)
+                return false;
+
+            if (ioctl(fd_frontend, FE_SET_PROPERTY, cmds) < 0)
             {
                 VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): " +
-                        "Setting Frontend(2) tuning parameters failed." + ENO);
+                        "Setting Frontend tuning parameters failed." + ENO);
                 return false;
             }
+            free(cmds->props);
+            free(cmds);
         }
         else
-#endif // FE_GET_EXTENDED_INFO
+#endif
         {
+            struct dvb_frontend_parameters params = dtvmultiplex_to_dvbparams(card_type, tuning,
+                                                                              intermediate_freq,
+                                                                              can_fec_auto);
+
             if (ioctl(fd_frontend, FE_SET_FRONTEND, &params) < 0)
             {
                 VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): " +
@@ -835,7 +892,7 @@ bool DVBChannel::IsTuningParamsProbeSupported(void) const
         return false;
     }
 
-    dvb_fe_params params;
+    dvb_frontend_parameters params;
     return ioctl(fd_frontend, FE_GET_FRONTEND, &params) >= 0;
 }
 
@@ -868,7 +925,13 @@ bool DVBChannel::ProbeTuningParams(DTVMultiplex &tuning) const
         return false;
     }
 
-    dvb_fe_params params;
+    if (card_type == DTVTunerType::kTunerTypeDVB_S2)
+    {
+        // TODO implement probing of tuning parameters with FE_GET_PROPERTY
+        return false;
+    }
+
+    dvb_frontend_parameters params;
     if (ioctl(fd_frontend, FE_GET_FRONTEND, &params) < 0)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR +
@@ -1094,10 +1157,11 @@ static bool wait_for_backend(int fd, int timeout_ms)
     return true;
 }
 
-static struct dvb_fe_params dtvmultiplex_to_dvbparams(
-    DTVTunerType tuner_type, const DTVMultiplex &tuning)
+static struct dvb_frontend_parameters dtvmultiplex_to_dvbparams(
+    DTVTunerType tuner_type, const DTVMultiplex &tuning,
+    int intermediate_freq, bool can_fec_auto)
 {
-    dvb_fe_params params;
+    dvb_frontend_parameters params;
     bzero(&params, sizeof(params));
 
     params.frequency = tuning.frequency;
@@ -1105,20 +1169,16 @@ static struct dvb_fe_params dtvmultiplex_to_dvbparams(
 
     if (DTVTunerType::kTunerTypeQPSK == tuner_type)
     {
+        params.frequency = intermediate_freq;
         params.u.qpsk.symbol_rate = tuning.symbolrate;
-        params.u.qpsk.fec_inner   = (fe_code_rate_t) (int) tuning.fec;
+        params.u.qpsk.fec_inner   = can_fec_auto ? FEC_AUTO
+            : (fe_code_rate_t) (int) tuning.fec;
     }
 
     if (DTVTunerType::kTunerTypeDVB_S2 == tuner_type)
     {
-#ifdef FE_GET_EXTENDED_INFO
-        params.u.qpsk2.symbol_rate = tuning.symbolrate;
-        params.u.qpsk2.fec_inner   = (fe_code_rate_t) (int) tuning.fec;
-        params.u.qpsk2.modulation  = (fe_modulation_t) (int) tuning.modulation;
-#else // if !FE_GET_EXTENDED_INFO
         VERBOSE(VB_IMPORTANT, "DVBChan Error, MythTV was compiled without "
                 "DVB-S2 headers being present so DVB-S2 tuning will fail.");
-#endif // !FE_GET_EXTENDED_INFO
     }
 
     if (DTVTunerType::kTunerTypeQAM  == tuner_type)
@@ -1148,17 +1208,15 @@ static struct dvb_fe_params dtvmultiplex_to_dvbparams(
 
     if (DTVTunerType::kTunerTypeATSC == tuner_type)
     {
-#ifdef USE_ATSC
         params.u.vsb.modulation   =
             (fe_modulation_t) (int) tuning.modulation;
-#endif // USE_ATSC
     }
 
     return params;
 }
 
 static DTVMultiplex dvbparams_to_dtvmultiplex(
-    DTVTunerType tuner_type, const dvb_fe_params &params)
+    DTVTunerType tuner_type, const dvb_frontend_parameters &params)
 {
     DTVMultiplex tuning;
 
@@ -1192,9 +1250,7 @@ static DTVMultiplex dvbparams_to_dtvmultiplex(
 
     if (DTVTunerType::kTunerTypeATSC == tuner_type)
     {
-#ifdef USE_ATSC
         tuning.modulation     = params.u.vsb.modulation;
-#endif // USE_ATSC
     }
 
     return tuning;
diff --git a/mythtv/libs/libmythtv/dvbtypes.h b/mythtv/libs/libmythtv/dvbtypes.h
index bc15a22..94a8882 100644
--- a/mythtv/libs/libmythtv/dvbtypes.h
+++ b/mythtv/libs/libmythtv/dvbtypes.h
@@ -19,30 +19,12 @@
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/dmx.h>
 
-#if (DVB_API_VERSION != 3 && DVB_API_VERSION != 5)
-#    error "DVB driver includes with API version 3 not found!"
-#endif
-
 #ifndef DVB_API_VERSION_MINOR
-#    define DVB_API_VERSION_MINOR 0
-#endif
-
-#if ((DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1) || (DVB_API_VERSION > 3))
-#    define USE_ATSC
-#else
-#warning DVB API version < 3.1
-#warning ATSC will not be supported using the Linux DVB drivers
-#    define FE_ATSC       (FE_OFDM+1)
-#    define FE_CAN_8VSB   0x200000
-#    define FE_CAN_16VSB  0x400000
-#    define VSB_8         (fe_modulation)(QAM_AUTO+1)
-#    define VSB_16        (fe_modulation)(QAM_AUTO+2)
+#define DVB_API_VERSION_MINOR 0
 #endif
 
-#ifdef FE_GET_EXTENDED_INFO
-  #define dvb_fe_params dvb_frontend_parameters_new
-#else
-  #define dvb_fe_params dvb_frontend_parameters
+#if !(DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1) && DVB_API_VERSION != 5
+#    error "DVB driver includes with API version 3.1 or later not found!"
 #endif
 
 class QString;
diff --git a/mythtv/libs/libmythtv/frequencytables.cpp b/mythtv/libs/libmythtv/frequencytables.cpp
index 6773dd9..e3c940f 100644
--- a/mythtv/libs/libmythtv/frequencytables.cpp
+++ b/mythtv/libs/libmythtv/frequencytables.cpp
@@ -72,7 +72,8 @@ TransportScanItem::TransportScanItem(uint                _sourceid,
         _tuning.lp_code_rate.toString(),     _tuning.modulation.toString(),
         _tuning.trans_mode.toString(),       _tuning.guard_interval.toString(),
         _tuning.hierarchy.toString(),        _tuning.modulation.toString(),
-        _tuning.bandwidth.toString());
+        _tuning.bandwidth.toString(),        _tuning.mod_sys.toString(),
+        _tuning.rolloff.toString());
 }
 
 TransportScanItem::TransportScanItem(uint sourceid,
diff --git a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
index 64a802d..e8fb9e5 100644
--- a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
+++ b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
@@ -770,19 +770,40 @@ class SatelliteDeliverySystemDescriptor : public MPEGDescriptor
     bool IsLinearPolarization()   const { return !((_data[8]>>6)&0x1); }
     bool IsHorizontalLeftPolarization() const { return (_data[8]>>5)&0x1; }
     bool IsVerticalRightPolarization() const { return !((_data[8]>>5)&0x1); }
-    // modulation               5   8.3
+    // roll off                 2   8.3
+    enum
+    {
+        kRollOff_35,
+        kRollOff_20,
+        kRollOff_25,
+        kRollOff_Auto,
+    };
+    uint RollOff() const { return (_data[8]>>3)&0x3; }
+    QString RollOffString() const
+    {
+        static QString ro[] = { "0.35", "0.20", "0.25", "auto" };
+        return ro[RollOff()];
+    }
+    // modulation system        1   8.5
+    uint ModulationSystem() const { return (_data[8]>>2)&0x1; }
+    QString ModulationSystemString() const
+    {
+        return ModulationSystem() ? "DVB-S2" : "DVB-S";
+    }
+    // modulation               2   8.6
     enum
     {
         kModulationQPSK_NS = 0x0, // Non standard QPSK for Bell ExpressVu
+        // should be "auto" according to DVB SI standard
         kModulationQPSK   = 0x1,
         kModulation8PSK   = 0x2,
         kModulationQAM16  = 0x3,
     };
-    uint Modulation() const { return _data[8]&0x1f; }
+    uint Modulation() const { return _data[8]&0x03; }
     QString ModulationString() const
     {
         static QString ms[] = { "qpsk", "qpsk", "8psk", "qam_16" };
-        return (Modulation() <= kModulationQAM16) ? ms[Modulation()] : "auto";
+        return ms[Modulation()];
     }
     // symbol_rate             28   9.0
     uint SymbolRate() const
diff --git a/mythtv/libs/libmythtv/scanwizard.cpp b/mythtv/libs/libmythtv/scanwizard.cpp
index 1847fdb..c829b36 100644
--- a/mythtv/libs/libmythtv/scanwizard.cpp
+++ b/mythtv/libs/libmythtv/scanwizard.cpp
@@ -100,6 +100,11 @@ void ScanWizard::SetPage(const QString &pageTitle)
         start_chan = configPane->GetStartChan();
         parse_type = DTVTunerType::kTunerTypeQPSK;
     }
+    else if (scantype == ScanTypeSetting::NITAddScan_DVBS2)
+    {
+        start_chan = configPane->GetStartChan();
+        parse_type = DTVTunerType::kTunerTypeDVB_S2;
+    }
     else if (scantype == ScanTypeSetting::NITAddScan_DVBC)
     {
         start_chan = configPane->GetStartChan();
@@ -162,7 +167,8 @@ void ScanWizard::SetPage(const QString &pageTitle)
             start_chan["coderate_hp"],    start_chan["coderate_lp"],
             start_chan["constellation"],  start_chan["trans_mode"],
             start_chan["guard_interval"], start_chan["hierarchy"],
-            start_chan["modulation"],     start_chan["bandwidth"]))
+            start_chan["modulation"],     start_chan["bandwidth"],
+            start_chan["mod_sys"],        start_chan["rolloff"]))
     {
         MythPopupBox::showOkPopup(
             gContext->GetMainWindow(), tr("ScanWizard"),
diff --git a/mythtv/libs/libmythtv/videosource.cpp b/mythtv/libs/libmythtv/videosource.cpp
index bc10656..9b4f3a8 100644
--- a/mythtv/libs/libmythtv/videosource.cpp
+++ b/mythtv/libs/libmythtv/videosource.cpp
@@ -3341,6 +3341,12 @@ void DVBConfigurationGroup::probeCard(const QString &videodevice)
             signal_timeout->setValue(60000);
             channel_timeout->setValue(62500);
             break;
+        case CardUtil::DVBS2:
+            cardtype->setValue("DVB-S2");
+            cardname->setValue(frontend_name);
+            signal_timeout->setValue(60000);
+            channel_timeout->setValue(62500);
+            break;
         case CardUtil::QAM:
             cardtype->setValue("DVB-C");
             cardname->setValue(frontend_name);
