]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb: improve diseqc switch handling, cleanups
authorJaroslav Kysela <perex@perex.cz>
Sun, 22 Mar 2015 15:40:58 +0000 (16:40 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 22 Mar 2015 15:40:58 +0000 (16:40 +0100)
src/input/mpegts/linuxdvb/linuxdvb_en50494.c
src/input/mpegts/linuxdvb/linuxdvb_lnb.c
src/input/mpegts/linuxdvb/linuxdvb_private.h
src/input/mpegts/linuxdvb/linuxdvb_rotor.c
src/input/mpegts/linuxdvb/linuxdvb_satconf.c
src/input/mpegts/linuxdvb/linuxdvb_switch.c

index eb143770566bfd6e1207a5636b1ec03afa939742..08702bb3bad8ac01741b6c53d46e2fdd62c05d10 100644 (file)
@@ -158,16 +158,11 @@ const idclass_t linuxdvb_en50494_class =
 static int
 linuxdvb_en50494_tune
   ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, int vol )
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc,
+    int vol, int pol, int band, int freq )
 {
   int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp);
   linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld;
-  linuxdvb_lnb_t *lnb = sc->lse_lnb;
-
-  /* band & polarization */
-  uint8_t  pol  = lnb->lnb_pol(lnb, lm);
-  uint8_t  band = lnb->lnb_band(lnb, lm);
-  uint32_t freq = lnb->lnb_freq(lnb, lm);
 
   /* transponder value - t*/
   uint16_t t = round((( (freq / 1000) + 2 + le->le_frequency) / 4) - 350);
index 664f112de470a1b86d064c51319e53a3df3b7ee7..f8d5878b46eda8815d05e58dd4d8a97f92ae7b8a 100644 (file)
@@ -111,16 +111,10 @@ linuxdvb_lnb_inverted_pol
 static int 
 linuxdvb_lnb_standard_tune
   ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
+    int vol, int pol, int band, int freq )
 {
-  /* en50494 does not use the voltage tune. this is happend in the switch */
-  if (ls->lse_en50494)
-    return 0;
-
-  /* note: differentiate between linuxdvb_lnb_standard_pol / linuxdvb_lnb_inverted_pol */
-  int pol = ((linuxdvb_lnb_t*)ld)->lnb_pol((linuxdvb_lnb_t*)ld, lm);
-
-  return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
+  return linuxdvb_diseqc_set_volt(ls->lse_parent, vol);
 }
 
 /*
@@ -160,20 +154,6 @@ linuxdvb_lnb_bandstack_pol
   return 0;
 }
 
-static int
-linuxdvb_lnb_bandstack_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
-{
-  int pol = linuxdvb_lnb_bandstack_pol((linuxdvb_lnb_t*)ld, lm);
-
-  /* en50494 does not use the voltage tune. this is happend in the switch */
-  if (ls->lse_en50494)
-    return 0;
-
-  return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
-}
-
 /* **************************************************************************
  * Static list
  * *************************************************************************/
@@ -312,7 +292,7 @@ struct linuxdvb_lnb_conf linuxdvb_lnb_all[] = {
   {
     { {
       .ld_type    = "DBS Bandstack",
-      .ld_tune    = linuxdvb_lnb_bandstack_tune,
+      .ld_tune    = linuxdvb_lnb_standard_tune,
       },
       .lnb_freq   = linuxdvb_lnb_bandstack_freq,
       .lnb_band   = linuxdvb_lnb_bandstack_band,
index 8115dc163c188f18373bd74023c7066029094278..d829a336713bf33a062f3f4d01f9c0901ac911ba 100644 (file)
@@ -168,6 +168,8 @@ struct linuxdvb_satconf
    */
   linuxdvb_satconf_ele_list_t ls_elements;
   linuxdvb_satconf_ele_t *ls_last_switch;
+  int                    ls_last_switch_pol;
+  int                    ls_last_switch_band;
   int                    ls_last_vol;
   int                    ls_last_toneburst;
   int                    ls_last_tone_off;
@@ -214,7 +216,8 @@ struct linuxdvb_diseqc
   linuxdvb_satconf_ele_t   *ld_satconf;
   int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm);
   int (*ld_tune)  (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-                   linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int pol);
+                   linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
+                   int vol, int pol, int band, int freq);
   int (*ld_post)  (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
                    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls);
 };
index 4b59f60c3e15ec565984517f45780a82f8354210..2fcb2ce5e7eb09fb8418bc758fe778ec96e2c54e 100644 (file)
@@ -401,7 +401,8 @@ linuxdvb_rotor_usals_tune
 static int
 linuxdvb_rotor_tune
   ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls,
+    int vol, int pol, int band, int freq )
 {
   linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
 
index 93b7647bc5537775479f2c5a3bf660fe3aac6775..b704a2b447188fd574f4806d9fe02b9e0cbdf2af 100644 (file)
@@ -720,7 +720,7 @@ static void linuxdvb_satconf_ele_tune_cb ( void *o );
 static int
 linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
 {
-  int r, i, b, pol;
+  int r, i, vol, pol, band, freq;
   uint32_t f;
   linuxdvb_satconf_t *ls = lse->lse_parent;
 
@@ -737,10 +737,18 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
     (linuxdvb_diseqc_t*)lse->lse_lnb
   };
 
+  if (lse->lse_lnb) {
+    pol  = lse->lse_lnb->lnb_pol (lse->lse_lnb, lm) & 0x1;
+    band = lse->lse_lnb->lnb_band(lse->lse_lnb, lm) & 0x1;
+    freq = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
+  } else {
+    tvherror("linuxdvb", "LNB is not defined!!!");
+    return -1;
+  }
   if (!lse->lse_en50494) {
-    pol = (lse->lse_lnb) ? lse->lse_lnb->lnb_pol(lse->lse_lnb, lm) & 0x1 : 0;
+    vol = pol;
   } else {
-    pol = 0; /* 13V */
+    vol  = 0; /* 13V */
   }
 
   /*
@@ -753,7 +761,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
   if (!lse->lse_en50494 || lse->lse_switch || lse->lse_rotor) {
     if (ls->ls_diseqc_full) {
       ls->ls_last_tone_off = 0; /* force */
-      if (linuxdvb_satconf_start(ls, 0, pol))
+      if (linuxdvb_satconf_start(ls, 0, vol))
         return -1;
     }
   }
@@ -761,7 +769,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
   /* Diseqc */  
   for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) {
     if (!lds[i]) continue;
-    r = lds[i]->ld_tune(lds[i], lm, ls, lse, pol);
+    r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq);
 
     /* Error */
     if (r < 0) return r;
@@ -781,23 +789,21 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
 
   /* LNB settings */
   /* EN50494 devices have another mechanism to select polarization */
-  if (!lse->lse_en50494) {
-    /* Set the voltage */
-    if (linuxdvb_diseqc_set_volt(ls, pol))
-      return -1;
-  }
+
+  /* Set the voltage */
+  if (linuxdvb_diseqc_set_volt(ls, vol))
+    return -1;
 
   /* Set the tone (en50494 don't use tone) */
   if (!lse->lse_en50494) {
-    b = lse->lse_lnb->lnb_band(lse->lse_lnb, lm);
-    if (ls->ls_diseqc_full || ls->ls_last_tone_off != b + 1) {
+    if (ls->ls_last_tone_off != band + 1) {
       ls->ls_last_tone_off = 0;
-      tvhtrace("diseqc", "set diseqc tone %s", b ? "on" : "off");
-      if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, b ? SEC_TONE_ON : SEC_TONE_OFF)) {
+      tvhtrace("diseqc", "set diseqc tone %s", band ? "on" : "off");
+      if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, band ? SEC_TONE_ON : SEC_TONE_OFF)) {
         tvherror("diseqc", "failed to set diseqc tone (e=%s)", strerror(errno));
         return -1;
       }
-      ls->ls_last_tone_off = b + 1;
+      ls->ls_last_tone_off = band + 1;
       usleep(20000); // Allow LNB to settle before tuning
     }
   }
@@ -806,7 +812,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
   /* use en50494 tuning frequency, if needed (not channel frequency) */
   f = lse->lse_en50494
     ? ((linuxdvb_en50494_t*)lse->lse_en50494)->le_tune_freq
-    : lse->lse_lnb->lnb_freq(lse->lse_lnb, lm);
+    : freq;
   return linuxdvb_frontend_tune1(lfe, mmi, f);
 }
 
index 53cffda64f676076322b30af7050c4217e44ee6c..28753d0527f39a6a28d9e4f525b78e4e9134f769 100644 (file)
@@ -43,6 +43,8 @@ typedef struct linuxdvb_switch
   int ls_toneburst;
   int ls_committed;
   int ls_uncommitted;
+  int ls_uncommitted_first;
+  int ls_sleep_time; /* in ms */
 
 } linuxdvb_switch_t;
 
@@ -134,6 +136,18 @@ const idclass_t linuxdvb_switch_class =
       .off    = offsetof(linuxdvb_switch_t, ls_toneburst),
       .list   = linuxdvb_switch_class_toneburst_list
     },
+    {
+      .type   = PT_BOOL,
+      .id     = "preferun",
+      .name   = "Uncommited First",
+      .off    = offsetof(linuxdvb_switch_t, ls_uncommitted_first),
+    },
+    {
+      .type   = PT_INT,
+      .id     = "sleeptime",
+      .name   = "Cmd Delay Time (ms) (10-500)",
+      .off    = offsetof(linuxdvb_switch_t, ls_sleep_time)
+    },
     {}
   }
 };
@@ -145,60 +159,66 @@ const idclass_t linuxdvb_switch_class =
 static int
 linuxdvb_switch_tune
   ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp,
-    linuxdvb_satconf_ele_t *sc, int vol )
+    linuxdvb_satconf_ele_t *sc, int vol, int pol, int band, int freq )
 {
-  int i, com, r1 = 0, r2 = 0;
-  int pol, band;
+  int i, com, r1 = 0, r2 = 0, slp;
   int fd = linuxdvb_satconf_fe_fd(lsp);
   linuxdvb_switch_t *ls = (linuxdvb_switch_t*)ld;
 
-  if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc) {
+  if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc ||
+      (ls->ls_committed >= 0 &&
+        (pol + 1 != lsp->ls_last_switch_pol ||
+         band + 1 != lsp->ls_last_switch_band))) {
 
     lsp->ls_last_switch = NULL;
 
-    if (linuxdvb_satconf_start(lsp, 1, vol))
+    if (linuxdvb_satconf_start(lsp, 1, pol))
       return -1;
 
-    pol  = (sc->lse_lnb) ? sc->lse_lnb->lnb_pol (sc->lse_lnb, lm) & 0x1 : 0;
-    band = (sc->lse_lnb) ? sc->lse_lnb->lnb_band(sc->lse_lnb, lm) & 0x1 : 0;
-    com  = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band;
-
-    /* Single committed (before repeats) */
-    if (ls->ls_committed >= 0) {
-      if (lsp->ls_diseqc_repeats > 0) {
-        r2 = 1;
-        if (linuxdvb_diseqc_send(fd, 0xE0, 0x10, 0x38, 1, com))
-          return -1;
-        usleep(25000); // 25ms
-      }
-    }
+    com = 0xF0 | (ls->ls_committed << 2) | (pol << 1) | band;
+    slp = ls->ls_sleep_time > 10 ?
+            MAX(500, MIN(25, ls->ls_sleep_time)) * 1000 :
+            25000;
 
     /* Repeats */
     for (i = 0; i <= lsp->ls_diseqc_repeats; i++) {
 
-      /* Uncommitted */
-      if (ls->ls_uncommitted >= 0) {
-        if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x39, 1,
-                                 0xF0 | ls->ls_uncommitted))
-          return -1;
-        usleep(25000);
-      }
+      if (ls->ls_uncommitted_first)
+        /* Uncommitted */
+        if (ls->ls_uncommitted >= 0) {
+          if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1,
+                                   0xF0 | ls->ls_uncommitted))
+            return -1;
+          usleep(slp);
+        }
 
       /* Committed */
       if (ls->ls_committed >= 0) {
-        if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x38, 1, com))
+        if (linuxdvb_diseqc_send(fd, 0xE0 | r1, 0x10, 0x38, 1, com))
           return -1;
-        usleep(25000);
+        usleep(slp);
+      }
+
+      if (!ls->ls_uncommitted_first) {
+        /* Uncommitted */
+        if (ls->ls_uncommitted >= 0) {
+          if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1,
+                                   0xF0 | ls->ls_uncommitted))
+            return -1;
+          usleep(slp);
+        }
       }
 
       /* repeat flag */
       r1 = r2 = 1;
     }
 
-    lsp->ls_last_switch = sc;
+    lsp->ls_last_switch      = sc;
+    lsp->ls_last_switch_pol  = pol + 1;
+    lsp->ls_last_switch_band = band + 1;
 
     /* port was changed, new LNB has not received toneburst yet */
-    lsp->ls_last_toneburst = 0;
+    lsp->ls_last_toneburst   = 0;
   }
 
   /* Tone burst */