]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb satconf: voltage settings cleanups, fixes #2566
authorJaroslav Kysela <perex@perex.cz>
Sat, 20 Dec 2014 17:22:34 +0000 (18:22 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sat, 20 Dec 2014 17:22:34 +0000 (18:22 +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 10cbb9dc83b05512de633c321667a8b468b6417b..eb143770566bfd6e1207a5636b1ec03afa939742 100644 (file)
@@ -157,10 +157,10 @@ const idclass_t linuxdvb_en50494_class =
 
 static int
 linuxdvb_en50494_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *sc, int fd )
+  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, int vol )
 {
-  int ret = 0;
-  int i;
+  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;
 
@@ -211,7 +211,7 @@ linuxdvb_en50494_tune
     }
 
     /* use 18V */
-    ret = linuxdvb_diseqc_set_volt(fd, SEC_VOLTAGE_18);
+    ret = linuxdvb_diseqc_set_volt(lsp, 1);
     if (ret) {
       tvherror("en50494", "error setting lnb voltage to 18V");
       break;
@@ -245,7 +245,7 @@ linuxdvb_en50494_tune
     usleep(50000); /* standard: 2ms < x < 60ms */
 
     /* return to 13V */
-    ret = linuxdvb_diseqc_set_volt(fd, SEC_VOLTAGE_13);
+    ret = linuxdvb_diseqc_set_volt(lsp, 0);
     if (ret) {
       tvherror("en50494", "error setting lnb voltage back to 13V");
       break;
index c91bdebccc98fd7b6493312f9fe9b8ec6dc3b175..664f112de470a1b86d064c51319e53a3df3b7ee7 100644 (file)
@@ -110,7 +110,8 @@ linuxdvb_lnb_inverted_pol
 
 static int 
 linuxdvb_lnb_standard_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
 {
   /* en50494 does not use the voltage tune. this is happend in the switch */
   if (ls->lse_en50494)
@@ -119,12 +120,7 @@ linuxdvb_lnb_standard_tune
   /* note: differentiate between linuxdvb_lnb_standard_pol / linuxdvb_lnb_inverted_pol */
   int pol = ((linuxdvb_lnb_t*)ld)->lnb_pol((linuxdvb_lnb_t*)ld, lm);
 
-  if (ls->lse_parent->ls_diseqc_full || ls->lse_parent->ls_last_pol != pol + 1) {
-    ls->lse_parent->ls_last_pol = pol + 1;
-    return linuxdvb_diseqc_set_volt(fd, pol);
-  }
-
-  return 0;
+  return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
 }
 
 /*
@@ -166,7 +162,8 @@ linuxdvb_lnb_bandstack_pol
 
 static int
 linuxdvb_lnb_bandstack_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( 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);
 
@@ -174,11 +171,7 @@ linuxdvb_lnb_bandstack_tune
   if (ls->lse_en50494)
     return 0;
 
-  if (ls->lse_parent->ls_diseqc_full || ls->lse_parent->ls_last_pol != pol + 1) {
-    ls->lse_parent->ls_last_pol = pol + 1;
-    return linuxdvb_diseqc_set_volt(fd, pol);
-  }
-  return 0;
+  return linuxdvb_diseqc_set_volt(ls->lse_parent, pol);
 }
 
 /* **************************************************************************
index c085d1b4b9967dc87689091b0243bc64fe3e50da..6c5814ed95ef7187940aa1bd96325104910eb7ca 100644 (file)
@@ -158,7 +158,7 @@ struct linuxdvb_satconf
    */
   linuxdvb_satconf_ele_list_t ls_elements;
   linuxdvb_satconf_ele_t *ls_last_switch;
-  int                    ls_last_pol;
+  int                    ls_last_vol;
   int                    ls_last_toneburst;
   int                    ls_last_tone_off;
   int                    ls_last_orbital_pos;
@@ -204,9 +204,9 @@ 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_ele_t *ls, int fd);
+                   linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int pol);
   int (*ld_post)  (linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
-                   linuxdvb_satconf_ele_t *ls, int fd);
+                   linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls);
 };
 
 struct linuxdvb_lnb
@@ -309,7 +309,7 @@ void linuxdvb_en50494_init (void);
 int
 linuxdvb_diseqc_send
   (int fd, uint8_t framing, uint8_t addr, uint8_t cmd, uint8_t len, ...);
-int linuxdvb_diseqc_set_volt (int fd, int volt);
+int linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int volt );
 
 /*
  * Satconf
@@ -340,9 +340,11 @@ void linuxdvb_satconf_post_stop_mux( linuxdvb_satconf_t *ls );
 int linuxdvb_satconf_start_mux
   ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi );
 
-int linuxdvb_satconf_tone_off( linuxdvb_satconf_ele_t *ls, int fd, int delay );
+int linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol );
 
-void linuxdvb_satconf_reset
-  ( linuxdvb_satconf_t *ls );
+void linuxdvb_satconf_reset ( linuxdvb_satconf_t *ls );
+
+static inline int linuxdvb_satconf_fe_fd ( linuxdvb_satconf_t *ls )
+  { return ((linuxdvb_frontend_t *)ls->ls_frontend)->lfe_fe_fd; }
 
 #endif /* __TVH_LINUXDVB_PRIVATE_H__ */
index adbb85202262b02e727acf2ff5ce633684c66b4a..4b59f60c3e15ec565984517f45780a82f8354210 100644 (file)
@@ -346,9 +346,10 @@ linuxdvb_rotor_check_orbital_pos
 /* GotoX */
 static int
 linuxdvb_rotor_gotox_tune
-  ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( linuxdvb_rotor_t *lr, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
 {
-  int i;
+  int i, fd = linuxdvb_satconf_fe_fd(lsp);
 
   for (i = 0; i <= ls->lse_parent->ls_diseqc_repeats; i++) {
     if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6B, 1, (int)lr->lr_position)) {
@@ -366,13 +367,13 @@ linuxdvb_rotor_gotox_tune
 /* USALS */
 static int
 linuxdvb_rotor_usals_tune
-  ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( linuxdvb_rotor_t *lr, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
 {
   static const uint8_t xtable[10] =
          { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
 
-  linuxdvb_satconf_t *lsp = ls->lse_parent;
-  int i, angle = sat_angle(lr, ls);
+  int i, angle = sat_angle(lr, ls), fd = linuxdvb_satconf_fe_fd(lsp);
   uint32_t cmd = 0xE000;
 
   if (angle < 0) {
@@ -399,39 +400,34 @@ linuxdvb_rotor_usals_tune
 
 static int
 linuxdvb_rotor_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol )
 {
   linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
 
   if (linuxdvb_rotor_check_orbital_pos(lr, lm, ls))
     return 0;
 
-  if (linuxdvb_satconf_tone_off(ls, fd, 1))
-    return -1;
-
   /* Force to 18v (quicker movement) */
-  if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18)) {
-    tvherror("diseqc", "failed to set 18v for rotor movement");
+  if (linuxdvb_satconf_start(lsp, 1, 1))
     return -1;
-  }
-  usleep(15000);
-  ls->lse_parent->ls_last_pol = 2;
 
   /* GotoX */
   if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_gotox_class))
-    return linuxdvb_rotor_gotox_tune(lr, lm, ls, fd);
+    return linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls);
 
   /* USALS */
-  return linuxdvb_rotor_usals_tune(lr, lm, ls, fd);
+  return linuxdvb_rotor_usals_tune(lr, lm, lsp, ls);
 }
 
 static int
 linuxdvb_rotor_post
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls, int fd )
+  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
 {
   linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
 
-  ls->lse_parent->ls_last_orbital_pos = pos_to_integer(lr->lr_sat_lon);
+  lsp->ls_last_orbital_pos = pos_to_integer(lr->lr_sat_lon);
   return 0;
 }
 
index a785124b78a8eb3166764fcce44878de4bc662b8..9f8dc556885526b0b9a2659d6b7cf36ae8c9fe9e 100644 (file)
@@ -657,8 +657,7 @@ linuxdvb_satconf_post_stop_mux
 {
   gtimer_disarm(&ls->ls_diseqc_timer);
   if (ls->ls_frontend && ls->ls_lnb_poweroff) {
-    linuxdvb_diseqc_set_volt(
-        ((linuxdvb_frontend_t *)ls->ls_frontend)->lfe_fe_fd, -1);
+    linuxdvb_diseqc_set_volt(ls, -1);
     linuxdvb_satconf_reset(ls);
   }
 }
@@ -689,13 +688,14 @@ linuxdvb_satconf_get_grace
 }
 
 int
-linuxdvb_satconf_tone_off ( linuxdvb_satconf_ele_t *lse, int fd, int delay )
+linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol )
 {
-  linuxdvb_satconf_t *ls = lse->lse_parent;
+  if (vol >= 0 && linuxdvb_diseqc_set_volt(ls, vol))
+    return -1;
 
   if (ls->ls_last_tone_off != 1) {
     tvhtrace("diseqc", "initial tone off");
-    if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF)) {
+    if (ioctl(linuxdvb_satconf_fe_fd(ls), FE_SET_TONE, SEC_TONE_OFF)) {
       tvherror("diseqc", "failed to disable tone");
       return -1;
     }
@@ -728,6 +728,12 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
     (linuxdvb_diseqc_t*)lse->lse_lnb
   };
 
+  if (!lse->lse_en50494) {
+    pol = (lse->lse_lnb) ? lse->lse_lnb->lnb_pol(lse->lse_lnb, lm) & 0x1 : 0;
+  } else {
+    pol = 0; /* 13V */
+  }
+
   /*
    * Disable tone (en50494 don't use tone)
    * The 22khz tone is used for signalling band (universal LNB)
@@ -738,7 +744,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_tone_off(lse, lfe->lfe_fe_fd, 0))
+      if (linuxdvb_satconf_start(ls, 0, pol))
         return -1;
     }
   }
@@ -746,7 +752,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, lse, lfe->lfe_fe_fd);
+    r = lds[i]->ld_tune(lds[i], lm, ls, lse, pol);
 
     /* Error */
     if (r < 0) return r;
@@ -762,24 +768,14 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse )
 
   /* Do post things (store position for rotor) */
   if (lse->lse_rotor)
-    lse->lse_rotor->ld_post(lse->lse_rotor, lm, lse, lfe->lfe_fe_fd);
+    lse->lse_rotor->ld_post(lse->lse_rotor, lm, ls, lse);
 
   /* LNB settings */
-  pol  = (lse->lse_lnb) ? lse->lse_lnb->lnb_pol (lse->lse_lnb, lm) & 0x1 : 0;
-
-  if (ls->ls_diseqc_full || ls->ls_last_pol != pol + 1) {
-
-    ls->ls_last_pol = 0;
-
-    /* EN50494 devices have another mechanism to select polarization */
-    if (!lse->lse_en50494) {
-
-      /* Set the voltage */
-      if (linuxdvb_diseqc_set_volt(lfe->lfe_fe_fd, pol))
-        return -1;
-
-      ls->ls_last_pol = pol + 1;
-    }
+  /* 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 tone (en50494 don't use tone) */
@@ -867,7 +863,7 @@ linuxdvb_satconf_reset
   ( linuxdvb_satconf_t *ls )
 {
   ls->ls_last_switch = NULL;
-  ls->ls_last_pol = 0;
+  ls->ls_last_vol = 0;
   ls->ls_last_toneburst = 0;
   ls->ls_last_tone_off = 0;
 }
@@ -1438,17 +1434,22 @@ linuxdvb_diseqc_send
 }
 
 int
-linuxdvb_diseqc_set_volt ( int fd, int vol )
+linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int vol )
 {
+  /* Already set ? */
+  if (vol >= 0 && ls->ls_last_vol == vol + 1)
+    return 0;
   /* Set voltage */
   tvhtrace("diseqc", "set voltage %dV", vol ? (vol < 0 ? 0 : 18) : 13);
-  if (ioctl(fd, FE_SET_VOLTAGE,
-        vol ? (vol < 0 ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_18) : SEC_VOLTAGE_13)) {
+  if (ioctl(linuxdvb_satconf_fe_fd(ls), FE_SET_VOLTAGE,
+            vol ? (vol < 0 ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_18) : SEC_VOLTAGE_13)) {
     tvherror("diseqc", "failed to set voltage (e=%s)", strerror(errno));
+    ls->ls_last_vol = 0;
     return -1;
   }
   if (vol >= 0)
     usleep(15000);
+  ls->ls_last_vol = vol ? (vol < 0 ? 0 : 2) : 1;
   return 0;
 }
 
index 8b524e783d579b087d76be796710050bb29b2f5b..53cffda64f676076322b30af7050c4217e44ee6c 100644 (file)
@@ -144,18 +144,19 @@ const idclass_t linuxdvb_switch_class =
 
 static int
 linuxdvb_switch_tune
-  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_ele_t *sc, int fd )
+  ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp,
+    linuxdvb_satconf_ele_t *sc, int vol )
 {
   int i, com, r1 = 0, r2 = 0;
   int pol, band;
+  int fd = linuxdvb_satconf_fe_fd(lsp);
   linuxdvb_switch_t *ls = (linuxdvb_switch_t*)ld;
-  linuxdvb_satconf_t *lsp = sc->lse_parent;
 
   if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc) {
 
     lsp->ls_last_switch = NULL;
 
-    if (linuxdvb_satconf_tone_off(sc, fd, 1))
+    if (linuxdvb_satconf_start(lsp, 1, vol))
       return -1;
 
     pol  = (sc->lse_lnb) ? sc->lse_lnb->lnb_pol (sc->lse_lnb, lm) & 0x1 : 0;
@@ -204,7 +205,7 @@ linuxdvb_switch_tune
   if (ls->ls_toneburst >= 0 &&
       (lsp->ls_diseqc_full || lsp->ls_last_toneburst != ls->ls_toneburst + 1)) {
 
-    if (linuxdvb_satconf_tone_off(sc, fd, 1))
+    if (linuxdvb_satconf_start(lsp, 1, vol))
       return -1;
 
     lsp->ls_last_toneburst = 0;