diff -ruN vdr-1.5.12.orig/channels.c vdr-1.5.12/channels.c
--- vdr-1.5.12.orig/channels.c	2007-10-12 10:40:53.000000000 -0400
+++ vdr-1.5.12/channels.c	2007-11-28 07:48:59.000000000 -0500
@@ -50,12 +50,21 @@
   };
 
 const tChannelParameterMap ModulationValues[] = {
+  {   0, MOD_QPSK },
   {   0, QPSK },
+  {   8, MOD_8PSK },
+  {  16, MOD_QAM_16 },
   {  16, QAM_16 },
+  {  32, MOD_QAM_32 },
   {  32, QAM_32 },
+  {  64, MOD_QAM_64 },
   {  64, QAM_64 },
+  { 128, MOD_QAM_128 },
   { 128, QAM_128 },
+  { 256, MOD_QAM_256 },
   { 256, QAM_256 },
+  { 512, MOD_BPSK },
+  { 999, MOD_QAM_AUTO },
   { 999, QAM_AUTO },
   { -1 }
   };
@@ -171,7 +180,7 @@
   bandwidth    = BANDWIDTH_AUTO;
   coderateH    = FEC_AUTO;
   coderateL    = FEC_AUTO;
-  modulation   = QAM_AUTO;
+  modulation   = QPSK;
   transmission = TRANSMISSION_MODE_AUTO;
   guard        = GUARD_INTERVAL_AUTO;
   hierarchy    = HIERARCHY_AUTO;
@@ -283,7 +292,7 @@
      }
 }
 
-bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH)
+bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation)
 {
   // Workarounds for broadcaster stupidity:
   // Some providers broadcast the transponder frequency of their channels with two different
@@ -297,7 +306,7 @@
   if (abs(srate - Srate) <= 1)
      Srate = srate;
 
-  if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
+  if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH || modulation != Modulation) {
      if (Number()) {
         dsyslog("changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d", Number(), *cSource::ToString(source), frequency, polarization, srate, coderateH, *cSource::ToString(Source), Frequency, Polarization, Srate, CoderateH);
         modification |= CHANNELMOD_TRANSP;
@@ -308,7 +317,7 @@
      polarization = Polarization;
      srate = Srate;
      coderateH = CoderateH;
-     modulation = QPSK;
+     modulation = Modulation;
      schedule = NULL;
      }
   return true;
@@ -600,7 +609,7 @@
   ST("CST")  q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues));
   ST("CST")  q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues));
   ST("  T")  q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues));
-  ST("C T")  q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
+  ST("CST")  q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
   ST("  T")  q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues));
   ST("  T")  q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
   ST("  T")  q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
diff -ruN vdr-1.5.12.orig/channels.h vdr-1.5.12/channels.h
--- vdr-1.5.12.orig/channels.h	2007-09-02 06:23:11.000000000 -0400
+++ vdr-1.5.12/channels.h	2007-11-28 07:48:59.000000000 -0500
@@ -206,7 +206,7 @@
   bool HasTimer(void) const;
   int Modification(int Mask = CHANNELMOD_ALL);
   void CopyTransponderData(const cChannel *Channel);
-  bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
+  bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation);
   bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
   bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
   void SetId(int Nid, int Tid, int Sid, int Rid = 0);
diff -ruN vdr-1.5.12.orig/dvbdevice.c vdr-1.5.12/dvbdevice.c
--- vdr-1.5.12.orig/dvbdevice.c	2007-10-14 08:56:03.000000000 -0400
+++ vdr-1.5.12/dvbdevice.c	2007-11-28 08:21:10.000000000 -0500
@@ -104,7 +104,7 @@
   lastTimeoutReport = 0;
   diseqcCommands = NULL;
   tunerStatus = tsIdle;
-  if (frontendType == FE_QPSK)
+  if (frontendType == FE_QPSK || frontendType == FE_DVB_S || frontendType == FE_DVB_S2)
      CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
   SetDescription("tuner on device %d", cardIndex + 1);
   Start();
@@ -173,7 +173,7 @@
 
 bool cDvbTuner::SetFrontend(void)
 {
-  dvb_frontend_parameters Frontend;
+  dvb_frontend_parameters_new Frontend;
 
   memset(&Frontend, 0, sizeof(Frontend));
 
@@ -244,6 +244,139 @@
          lockTimeout = DVBS_LOCK_TIMEOUT;
          }
          break;
+    case FE_DVB_S: { // DVB-S
+
+         unsigned int frequency = channel.Frequency();
+
+         if (Setup.DiSEqC) {
+            cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+            if (diseqc) {
+               if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+                  cDiseqc::eDiseqcActions da;
+                  for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+                      switch (da) {
+                        case cDiseqc::daNone:      break;
+                        case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+                        case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+                        case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+                        case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+                        case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+                        case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+                        case cDiseqc::daCodes: {
+                             int n = 0;
+                             uchar *codes = diseqc->Codes(n);
+                             if (codes) {
+                                struct dvb_diseqc_master_cmd cmd;
+                                memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+                                cmd.msg_len = n;
+                                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+                                }
+                             }
+                             break;
+                        }
+                      }
+                  diseqcCommands = diseqc->Commands();
+                  }
+               frequency -= diseqc->Lof();
+               }
+            else {
+               esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+               return false;
+               }
+            }
+         else {
+            int tone = SEC_TONE_OFF;
+
+            if (frequency < (unsigned int)Setup.LnbSLOF) {
+               frequency -= Setup.LnbFrequLo;
+               tone = SEC_TONE_OFF;
+               }
+            else {
+               frequency -= Setup.LnbFrequHi;
+               tone = SEC_TONE_ON;
+               }
+            int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+            CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+            CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+            }
+
+         frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+         Frontend.frequency = frequency * 1000UL;
+         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+         Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
+         Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
+
+         tuneTimeout = DVBS_TUNE_TIMEOUT;
+         lockTimeout = DVBS_LOCK_TIMEOUT;
+         }
+         break;
+    case FE_DVB_S2: { // DVB-S
+
+         unsigned int frequency = channel.Frequency();
+
+         if (Setup.DiSEqC) {
+            cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+            if (diseqc) {
+               if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+                  cDiseqc::eDiseqcActions da;
+                  for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+                      switch (da) {
+                        case cDiseqc::daNone:      break;
+                        case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+                        case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+                        case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+                        case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+                        case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+                        case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+                        case cDiseqc::daCodes: {
+                             int n = 0;
+                             uchar *codes = diseqc->Codes(n);
+                             if (codes) {
+                                struct dvb_diseqc_master_cmd cmd;
+                                memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+                                cmd.msg_len = n;
+                                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+                                }
+                             }
+                             break;
+                        }
+                      }
+                  diseqcCommands = diseqc->Commands();
+                  }
+               frequency -= diseqc->Lof();
+               }
+            else {
+               esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+               return false;
+               }
+            }
+         else {
+            int tone = SEC_TONE_OFF;
+
+            if (frequency < (unsigned int)Setup.LnbSLOF) {
+               frequency -= Setup.LnbFrequLo;
+               tone = SEC_TONE_OFF;
+               }
+            else {
+               frequency -= Setup.LnbFrequHi;
+               tone = SEC_TONE_ON;
+               }
+            int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+            CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+            CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+            }
+
+         frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+         Frontend.frequency = frequency * 1000UL;
+         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+         Frontend.u.qpsk2.symbol_rate = channel.Srate() * 1000UL;
+         Frontend.u.qpsk2.fec_inner = fe_code_rate_t(channel.CoderateH());
+         Frontend.u.qpsk2.modulation = fe_modulation_t(channel.Modulation());
+         
+         tuneTimeout = DVBS_TUNE_TIMEOUT;
+         lockTimeout = DVBS_LOCK_TIMEOUT;
+         }
+         break;
     case FE_QAM: { // DVB-C
 
          // Frequency and symbol rate:
@@ -280,10 +413,17 @@
          esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
          return false;
     }
-  if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
-     esyslog("ERROR: frontend %d: %m", cardIndex);
-     return false;
+  if (frontendType == FE_DVB_S2) {
+     if (ioctl(fd_frontend, FE_SET_FRONTEND2, &Frontend) == -1) {
+        esyslog("ERROR: frontend %d: %m", cardIndex);
+        return false;
+     }
+  } else {
+     if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) == -1) {
+        esyslog("ERROR: frontend %d: %m", cardIndex);
+        return false;
      }
+  }
   return true;
 }
 
@@ -419,7 +559,16 @@
   if (fd_frontend >= 0) {
      dvb_frontend_info feinfo;
      if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
-        frontendType = feinfo.type;
+	frontendType = feinfo.type;
+	if ( ((feinfo.type == FE_QPSK) || (feinfo.type == FE_DVB_S2)) && (feinfo.caps & FE_HAS_EXTENDED_INFO) ) {
+	   dvb_fe_caps_extended feextinfo;
+	   if (ioctl(fd_frontend, FE_GET_EXTENDED_INFO, &feextinfo) >= 0) {
+              if (feextinfo.standards & FE_DVB_S2) {
+	         CHECK(ioctl(fd_frontend, FE_SET_STANDARD, FE_DVB_S2));
+		 frontendType = FE_DVB_S2;
+	      }
+	   }
+	}
         dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
         }
      else
@@ -745,6 +894,8 @@
   return type == cSource::stNone
       || type == cSource::stCable && frontendType == FE_QAM
       || type == cSource::stSat   && frontendType == FE_QPSK
+      || type == cSource::stSat   && frontendType == FE_DVB_S
+      || type == cSource::stSat   && frontendType == FE_DVB_S2
       || type == cSource::stTerr  && frontendType == FE_OFDM;
 }
 
diff -ruN vdr-1.5.12.orig/nit.c vdr-1.5.12/nit.c
--- vdr-1.5.12.orig/nit.c	2007-08-17 10:02:45.000000000 -0400
+++ vdr-1.5.12/nit.c	2007-11-28 07:48:59.000000000 -0500
@@ -129,6 +129,8 @@
                  char Polarization = Polarizations[sd->getPolarization()];
                  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
+                 static int Modulations[] = { MOD_QPSK, QPSK, MOD_QAM_16, QAM_16, MOD_QAM_32, QAM_32, MOD_QAM_64, QAM_64, MOD_QAM_128, QAM_128, MOD_QAM_256, QAM_256, MOD_QAM_AUTO, QAM_AUTO, MOD_BPSK, MOD_8PSK };
+                 int Modulation = Modulations[min(sd->getModulationType(), 15)];
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
                     for (int n = 0; n < NumFrequencies; n++) {
@@ -154,7 +156,7 @@
                                   }
                               }
                            if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder
-                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
+                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate, Modulation);
                            }
                         found = true;
                         }
@@ -162,7 +164,7 @@
                        for (int n = 0; n < NumFrequencies; n++) {
                            cChannel *Channel = new cChannel;
                            Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                           if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate))
+                           if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate, Modulation))
                               EITScanner.AddTransponder(Channel);
                            else
                               delete Channel;
@@ -178,8 +180,8 @@
                  //XXX FEC_outer???
                  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
-                 static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
-                 int Modulation = Modulations[min(sd->getModulation(), 6)];
+                 static int Modulations[] = { MOD_QPSK, MOD_8PSK, MOD_QAM_16, MOD_QAM_32, MOD_QAM_64, MOD_QAM_128, MOD_QAM_256, MOD_QAM_AUTO };
+                 int Modulation = Modulations[min(sd->getModulation(), 7)];
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
                     for (int n = 0; n < NumFrequencies; n++) {
