aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-13 16:43:28 -0200
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-28 15:46:06 -0200
commitd982b0d03b1f929269104bb716c9d4b50c945125 (patch)
tree1553727fc981cb135d519789b4f76a937c74747e
parent08800efa4371e051b82494440ad28a83679a6979 (diff)
dvb-sat: change the LNBf logic to make it more generic
There are some new LNBf models with more than two frequency ranges. Change the logic there to allow adding those new LNBf types. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r--lib/include/libdvbv5/dvb-sat.h14
-rw-r--r--lib/libdvbv5/dvb-fe.c5
-rw-r--r--lib/libdvbv5/dvb-sat.c213
3 files changed, 137 insertions, 95 deletions
diff --git a/lib/include/libdvbv5/dvb-sat.h b/lib/include/libdvbv5/dvb-sat.h
index 7f83369f..424c4f45 100644
--- a/lib/include/libdvbv5/dvb-sat.h
+++ b/lib/include/libdvbv5/dvb-sat.h
@@ -132,6 +132,20 @@ const char *dvb_sat_get_lnb_name(int index);
*/
int dvb_sat_set_parms(struct dvb_v5_fe_parms *parms);
+/**
+ * @brief return the real satellite frequency
+ * @ingroup satellite
+ *
+ * @param parms struct dvb_v5_fe_parms pointer.
+ *
+ * This function is called internally by the library to get the satellite
+ * frequency, considering the LO frequency.
+ *
+ * @return frequency.
+ */
+int dvb_sat_real_freq(struct dvb_v5_fe_parms *p, int freq);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/libdvbv5/dvb-fe.c b/lib/libdvbv5/dvb-fe.c
index b0b8f595..1e29c9f0 100644
--- a/lib/libdvbv5/dvb-fe.c
+++ b/lib/libdvbv5/dvb-fe.c
@@ -705,9 +705,8 @@ int __dvb_fe_get_parms(struct dvb_v5_fe_parms *p)
/* copy back params from temporary fe_prop */
for (i = 0; i < n; i++) {
- if (dvb_fe_is_satellite(p->current_sys)
- && fe_prop[i].cmd == DTV_FREQUENCY)
- fe_prop[i].u.data += parms->freq_offset;
+ if (fe_prop[i].cmd == DTV_FREQUENCY)
+ fe_prop[i].u.data = dvb_sat_real_freq(p, fe_prop[i].u.data);
dvb_fe_store_parm(&parms->p, fe_prop[i].cmd, fe_prop[i].u.data);
}
diff --git a/lib/libdvbv5/dvb-sat.c b/lib/libdvbv5/dvb-sat.c
index 254a1e2c..bde0cfa3 100644
--- a/lib/libdvbv5/dvb-sat.c
+++ b/lib/libdvbv5/dvb-sat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
+ * Copyright (c) 2011-2016 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -39,19 +39,15 @@
# define N_(string) string
struct dvbsat_freqrange {
- unsigned low, high;
+ unsigned low, high, int_freq, rangeswitch;
+ enum dvb_sat_polarization pol;
};
struct dvb_sat_lnb_priv {
struct dvb_sat_lnb desc;
/* Private members used internally */
-
- unsigned lowfreq, highfreq;
-
- unsigned rangeswitch;
-
- struct dvbsat_freqrange freqrange[2];
+ struct dvbsat_freqrange freqrange[4];
};
static const struct dvb_sat_lnb_priv lnb[] = {
@@ -60,107 +56,92 @@ static const struct dvb_sat_lnb_priv lnb[] = {
.name = N_("Universal, Europe"),
.alias = "UNIVERSAL",
},
- .lowfreq = 9750,
- .highfreq = 10600,
- .rangeswitch = 11700,
.freqrange = {
- { 10800, 11800 },
- { 11600, 12700 },
+ { 10800, 11800, 9750, 11700 },
+ { 11600, 12700, 10600, 0 },
}
}, {
.desc = {
.name = N_("Expressvu, North America"),
.alias = "DBS",
},
- .lowfreq = 11250,
.freqrange = {
- { 12200, 12700 }
+ { 12200, 12700, 11250 }
}
}, {
.desc = {
.name = N_("Astra 1E, European Universal Ku (extended)"),
.alias = "EXTENDED",
},
- .lowfreq = 9750,
- .highfreq = 10600,
- .rangeswitch = 11700,
.freqrange = {
- { 10700, 11700 },
- { 11700, 12750 },
+ { 10700, 11700, 9750, 11700},
+ { 11700, 12750, 10600, 0 },
}
}, {
.desc = {
.name = N_("Standard"),
.alias = "STANDARD",
},
- .lowfreq = 10000,
.freqrange = {
- { 10945, 11450 }
+ { 10945, 11450, 10000, 0 }
},
}, {
.desc = {
.name = N_("L10700"),
.alias = "L10700",
},
- .lowfreq = 10700,
.freqrange = {
- { 11750, 12750 }
+ { 11750, 12750, 10700, 0 }
},
}, {
.desc = {
.name = N_("L11300"),
.alias = "L11300",
},
- .lowfreq = 11300,
.freqrange = {
- { 12250, 12750 }
+ { 12250, 12750, 11300, 0 }
},
}, {
.desc = {
.name = N_("Astra"),
.alias = "ENHANCED",
},
- .lowfreq = 9750,
.freqrange = {
- { 10700, 11700 }
+ { 10700, 11700, 9750, 0 }
},
}, {
.desc = {
.name = N_("Big Dish - Monopoint LNBf"),
.alias = "C-BAND",
},
- .lowfreq = 5150,
.freqrange = {
- { 3700, 4200 }
+ { 3700, 4200, 5150, 0 }
},
}, {
.desc = {
.name = N_("Big Dish - Multipoint LNBf"),
.alias = "C-MULT",
},
- .lowfreq = 5150,
- .highfreq = 5750,
.freqrange = {
- { 3700, 4200 }
+ { 3700, 4200, 5150, 0, POLARIZATION_R },
+ { 3700, 4200, 5750, 0, POLARIZATION_L }
},
}, {
.desc = {
.name = N_("DishPro LNBf"),
.alias = "DISHPRO",
},
- .lowfreq = 11250,
- .highfreq = 14350,
.freqrange = {
- { 12200, 12700 }
+ { 12200, 12700, 11250, 0, POLARIZATION_V },
+ { 12200, 12700, 14350, 0, POLARIZATION_H }
}
}, {
.desc = {
.name = N_("Japan 110BS/CS LNBf"),
.alias = "110BS",
},
- .lowfreq = 10678,
.freqrange = {
- { 11710, 12751 }
+ { 11710, 12751, 10678, 0 }
}
},
};
@@ -176,29 +157,31 @@ int dvb_sat_search_lnb(const char *name)
return -1;
}
+static char *pol_name[] = {
+ [POLARIZATION_OFF] = "",
+ [POLARIZATION_H] = N_("Horizontal: "),
+ [POLARIZATION_V] = N_("Vertical : "),
+ [POLARIZATION_L] = N_("Left : "),
+ [POLARIZATION_R] = N_("Right : "),
+};
+
int dvb_print_lnb(int i)
{
+ int j;
+
if (i < 0 || i >= ARRAY_SIZE(lnb))
return -1;
- printf("%s\n\t%s\n", lnb[i].desc.alias, dvb_sat_get_lnb_name(i));
- printf(_("\t%d to %d MHz"),
- lnb[i].freqrange[0].low, lnb[i].freqrange[0].high);
- if (lnb[i].freqrange[1].low)
- printf(_(" and %d to %d MHz"),
- lnb[i].freqrange[1].low, lnb[i].freqrange[1].high);
- printf("\n\t%s LO, ", lnb[i].highfreq ? _("Dual") : _("Single"));
- if (!lnb[i].highfreq) {
- printf("IF = %d MHz\n", lnb[i].lowfreq);
- return 0;
- }
- if (!lnb[i].rangeswitch) {
- printf(_("Bandstacking, LO POL_R %d MHZ, LO POL_L %d MHz\n"),
- lnb[i].lowfreq, lnb[i].highfreq);
- return 0;
+ printf("%s\n\t%s%s\n", lnb[i].desc.alias, dvb_sat_get_lnb_name(i),
+ lnb[i].freqrange[0].pol ? _(" (bandstacking)") : "");
+
+ for (j = 0; j < ARRAY_SIZE(lnb[i].freqrange) && lnb[i].freqrange[j].low; j++) {
+ printf(_("\t%s%d to %d MHz, LO: %d MHz\n"),
+ _(pol_name[lnb[i].freqrange[j].pol]),
+ lnb[i].freqrange[j].low,
+ lnb[i].freqrange[j].high,
+ lnb[i].freqrange[j].int_freq);
}
- printf(_("IF = lowband %d MHz, highband %d MHz\n"),
- lnb[i].lowfreq, lnb[i].highfreq);
return 0;
}
@@ -376,7 +359,7 @@ static int dvbsat_diseqc_set_input(struct dvb_v5_fe_parms_priv *parms,
int mini_b = 0;
struct diseqc_cmd cmd;
- if (!lnb->rangeswitch) {
+ if (!lnb->freqrange[0].rangeswitch) {
/*
* Bandstacking switches don't use 2 bands nor use
* DISEqC for setting the polarization. It also doesn't
@@ -430,62 +413,108 @@ static int dvbsat_diseqc_set_input(struct dvb_v5_fe_parms_priv *parms,
return rc;
}
+int dvb_sat_real_freq(struct dvb_v5_fe_parms *p, int freq)
+{
+ struct dvb_v5_fe_parms_priv *parms = (void *)p;
+ int new_freq, i;
+
+ if (!dvb_fe_is_satellite(p->current_sys))
+ return freq;
+
+ new_freq = freq + parms->freq_offset;
+ for (i = 0; i < ARRAY_SIZE(lnb->freqrange) && lnb->freqrange[i].low; i++) {
+ if (freq < lnb->freqrange[i].low * 1000 || freq > lnb->freqrange[i].high * 1000)
+ continue;
+
+ return new_freq;
+ }
+
+ return parms->freq_offset - freq;
+}
+
+
/*
* DVB satellite get/set params hooks
*/
-int dvb_sat_set_parms(struct dvb_v5_fe_parms *p)
+static int dvb_sat_get_freq(struct dvb_v5_fe_parms *p, uint16_t *t)
{
struct dvb_v5_fe_parms_priv *parms = (void *)p;
const struct dvb_sat_lnb_priv *lnb = (void *)p->lnb;
enum dvb_sat_polarization pol;
- dvb_fe_retrieve_parm(&parms->p, DTV_POLARIZATION, &pol);
uint32_t freq;
- uint16_t t = 0;
- int rc;
-
- parms->high_band = 0;
- dvb_fe_retrieve_parm(&parms->p, DTV_FREQUENCY, &freq);
+ int j;
if (!lnb) {
dvb_logerr(_("Need a LNBf to work"));
- return -EINVAL;
+ return 0;
}
- /* Simple case: LNBf with just Single LO */
- if (!lnb->highfreq) {
- parms->freq_offset = lnb->lowfreq * 1000;
- goto ret;
- }
+ parms->high_band = 0;
+ parms->freq_offset = 0;
- /* polarization-controlled multi LNBf */
- if (!lnb->rangeswitch) {
- if ((pol == POLARIZATION_V) || (pol == POLARIZATION_R))
- parms->freq_offset = lnb->lowfreq * 1000;
- else
- parms->freq_offset = lnb->highfreq * 1000;
- goto ret;
+ dvb_fe_retrieve_parm(&parms->p, DTV_FREQUENCY, &freq);
+
+ if (!lnb->freqrange[1].low) {
+ /* Trivial case: LNBf with a single local oscilator(LO) */
+ parms->freq_offset = lnb->freqrange[0].int_freq * 1000;
+ return freq;
}
- /* Voltage-controlled multiband switch */
- parms->high_band = (freq > lnb->rangeswitch * 1000) ? 1 : 0;
-
- /* Adjust frequency */
- if (parms->high_band)
- parms->freq_offset = lnb->highfreq * 1000;
- else
- parms->freq_offset = lnb->lowfreq * 1000;
-
- /* For SCR/Unicable setups */
- if (parms->p.freq_bpf) {
- t = (((freq / 1000) + parms->p.freq_bpf + 2) / 4) - 350;
- parms->freq_offset += ((t + 350) * 4) * 1000;
- if (parms->p.verbose)
- dvb_log("BPF: %d KHz", parms->p.freq_bpf);
+ if (lnb->freqrange[0].pol) {
+ /* polarization-controlled multi-LO multipoint LNBf (bandstacking) */
+ dvb_fe_retrieve_parm(&parms->p, DTV_POLARIZATION, &pol);
+
+ for (j = 0; j < ARRAY_SIZE(lnb->freqrange) && lnb->freqrange[j].low; j++) {
+ if (freq < lnb->freqrange[j].low * 1000 ||
+ freq > lnb->freqrange[j].high * 1000 ||
+ pol != lnb->freqrange[j].pol)
+ continue;
+
+ parms->freq_offset = lnb->freqrange[j].int_freq * 1000;
+ return freq;
+ }
+ } else {
+ /* Multi-LO (dual-band) LNBf using DiSEqC */
+ for (j = 0; j < ARRAY_SIZE(lnb->freqrange) && lnb->freqrange[j].low; j++) {
+ if (freq < lnb->freqrange[j].low * 1000 || freq > lnb->freqrange[j].high * 1000)
+ continue;
+ if (freq > lnb->freqrange[j].rangeswitch * 1000)
+ j++;
+
+ /* Sets DiSEqC to high_band if not low band */
+ if (j)
+ parms->high_band = 1;
+
+ if (parms->p.freq_bpf) {
+ /* For SCR/Unicable setups */
+ *t = (((freq / 1000) + parms->p.freq_bpf + 2) / 4) - 350;
+ parms->freq_offset += ((*t + 350) * 4) * 1000;
+ if (parms->p.verbose)
+ dvb_log("BPF: %d KHz", parms->p.freq_bpf);
+ } else {
+ parms->freq_offset = lnb->freqrange[j].int_freq * 1000;
+ }
+ return freq;
+ }
}
+ dvb_logerr("frequency: %.2f MHz is out of LNBf range\n",
+ freq / 1000.);
+ return 0;
+}
+
+int dvb_sat_set_parms(struct dvb_v5_fe_parms *p)
+{
+ struct dvb_v5_fe_parms_priv *parms = (void *)p;
+ uint32_t freq;
+ uint16_t t = 0;
+ int rc;
+
+ freq = dvb_sat_get_freq(p, &t);
+ if (!freq)
+ return -EINVAL;
-ret:
if (parms->p.verbose)
dvb_log("frequency: %.2f MHz, high_band: %d", freq / 1000., parms->high_band);

Privacy Policy