|
@@ -3843,35 +3843,108 @@ static const struct per_layer_regs per_layer_regs[] = {
|
|
|
{ 556, 581, 583 },
|
|
|
};
|
|
|
|
|
|
+struct linear_segments {
|
|
|
+ unsigned x;
|
|
|
+ signed y;
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Table to estimate signal strength in dBm.
|
|
|
+ * This table was empirically determinated by measuring the signal
|
|
|
+ * strength generated by a DTA-2111 RF generator directly connected into
|
|
|
+ * a dib8076 device (a PixelView PV-D231U stick), using a good quality
|
|
|
+ * 3 meters RC6 cable and good RC6 connectors.
|
|
|
+ * The real value can actually be different on other devices, depending
|
|
|
+ * on several factors, like if LNA is enabled or not, if diversity is
|
|
|
+ * enabled, type of connectors, etc.
|
|
|
+ * Yet, it is better to use this measure in dB than a random non-linear
|
|
|
+ * percentage value, especially for antenna adjustments.
|
|
|
+ * On my tests, the precision of the measure using this table is about
|
|
|
+ * 0.5 dB, with sounds reasonable enough.
|
|
|
+ */
|
|
|
+static struct linear_segments strength_to_db_table[] = {
|
|
|
+ { 55953, 108500 }, /* -22.5 dBm */
|
|
|
+ { 55394, 108000 },
|
|
|
+ { 53834, 107000 },
|
|
|
+ { 52863, 106000 },
|
|
|
+ { 52239, 105000 },
|
|
|
+ { 52012, 104000 },
|
|
|
+ { 51803, 103000 },
|
|
|
+ { 51566, 102000 },
|
|
|
+ { 51356, 101000 },
|
|
|
+ { 51112, 100000 },
|
|
|
+ { 50869, 99000 },
|
|
|
+ { 50600, 98000 },
|
|
|
+ { 50363, 97000 },
|
|
|
+ { 50117, 96000 }, /* -35 dBm */
|
|
|
+ { 49889, 95000 },
|
|
|
+ { 49680, 94000 },
|
|
|
+ { 49493, 93000 },
|
|
|
+ { 49302, 92000 },
|
|
|
+ { 48929, 91000 },
|
|
|
+ { 48416, 90000 },
|
|
|
+ { 48035, 89000 },
|
|
|
+ { 47593, 88000 },
|
|
|
+ { 47282, 87000 },
|
|
|
+ { 46953, 86000 },
|
|
|
+ { 46698, 85000 },
|
|
|
+ { 45617, 84000 },
|
|
|
+ { 44773, 83000 },
|
|
|
+ { 43845, 82000 },
|
|
|
+ { 43020, 81000 },
|
|
|
+ { 42010, 80000 }, /* -51 dBm */
|
|
|
+ { 0, 0 },
|
|
|
+};
|
|
|
+
|
|
|
+static u32 interpolate_value(u32 value, struct linear_segments *segments,
|
|
|
+ unsigned len)
|
|
|
+{
|
|
|
+ u64 tmp64;
|
|
|
+ u32 dx;
|
|
|
+ s32 dy;
|
|
|
+ int i, ret;
|
|
|
+
|
|
|
+ if (value >= segments[0].x)
|
|
|
+ return segments[0].y;
|
|
|
+ if (value < segments[len-1].x)
|
|
|
+ return segments[len-1].y;
|
|
|
+
|
|
|
+ for (i = 1; i < len - 1; i++) {
|
|
|
+ /* If value is identical, no need to interpolate */
|
|
|
+ if (value == segments[i].x)
|
|
|
+ return segments[i].y;
|
|
|
+ if (value > segments[i].x)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Linear interpolation between the two (x,y) points */
|
|
|
+ dy = segments[i - 1].y - segments[i].y;
|
|
|
+ dx = segments[i - 1].x - segments[i].x;
|
|
|
+
|
|
|
+ tmp64 = value - segments[i].x;
|
|
|
+ tmp64 *= dy;
|
|
|
+ do_div(tmp64, dx);
|
|
|
+ ret = segments[i].y + tmp64;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat)
|
|
|
{
|
|
|
struct dib8000_state *state = fe->demodulator_priv;
|
|
|
struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
|
|
|
int i, lock;
|
|
|
- u64 tmp;
|
|
|
u32 snr, val;
|
|
|
+ s32 db;
|
|
|
u16 strength;
|
|
|
|
|
|
/* Get Signal strength */
|
|
|
dib8000_read_signal_strength(fe, &strength);
|
|
|
-
|
|
|
- /*
|
|
|
- * Estimate it in dBm
|
|
|
- * This calculus was empirically determinated by measuring the signal
|
|
|
- * strength generated by a DTA-2111 RF generator directly connected into
|
|
|
- * a dib8076 device. The real value can actually be different on other
|
|
|
- * devices, depending if LNA is enabled or not, if diversity is enabled,
|
|
|
- * etc.
|
|
|
- */
|
|
|
- if (strength == 65535) {
|
|
|
- c->strength.stat[0].svalue = -22000;
|
|
|
- } else {
|
|
|
- tmp = strength * 25000L;
|
|
|
- do_div(tmp, 11646);
|
|
|
- c->strength.stat[0].svalue = tmp - 142569;
|
|
|
- if (c->strength.stat[0].svalue > -22000)
|
|
|
- c->strength.stat[0].svalue = -22000;
|
|
|
- }
|
|
|
+ val = strength;
|
|
|
+ db = interpolate_value(val,
|
|
|
+ strength_to_db_table,
|
|
|
+ ARRAY_SIZE(strength_to_db_table)) - 131000;
|
|
|
+ c->strength.stat[0].svalue = db;
|
|
|
|
|
|
/* Check if 1 second was elapsed */
|
|
|
if (!time_after(jiffies, state->get_stats_time))
|