From patchwork Tue Dec 17 15:30:43 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 3363901 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 11AF4C0D4A for ; Tue, 17 Dec 2013 18:34:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B1152201BF for ; Tue, 17 Dec 2013 18:34:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6D510201C0 for ; Tue, 17 Dec 2013 18:34:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932090Ab3LQSdw (ORCPT ); Tue, 17 Dec 2013 13:33:52 -0500 Received: from bombadil.infradead.org ([198.137.202.9]:41991 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756232Ab3LQSds (ORCPT ); Tue, 17 Dec 2013 13:33:48 -0500 Received: from [177.143.133.66] (helo=smtp.w2.samsung.com) by bombadil.infradead.org with esmtpsa (Exim 4.80.1 #2 (Red Hat Linux)) id 1VszSk-0001w2-VO; Tue, 17 Dec 2013 18:33:48 +0000 Received: from mchehab by smtp.w2.samsung.com with local (Exim 4.80.1) (envelope-from ) id 1Vswbf-0002eb-Tb; Tue, 17 Dec 2013 13:30:47 -0200 From: Mauro Carvalho Chehab Cc: Mauro Carvalho Chehab , Linux Media Mailing List , Mauro Carvalho Chehab Subject: [PATCH 3/6] [media] dib8000: make a better estimation for dBm Date: Tue, 17 Dec 2013 13:30:43 -0200 Message-Id: <1387294246-10155-4-git-send-email-m.chehab@samsung.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1387294246-10155-1-git-send-email-m.chehab@samsung.com> References: <1387294246-10155-1-git-send-email-m.chehab@samsung.com> To: unlisted-recipients:; (no To-header on input) Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use multiple linear segments to better interpolate the dBm for the signal strength. The table that converts from linear strength to dB was empirically determinated with the help of a signal generator (DTA-2111). The entries from -35dBm to -22.5dBm were taken using just the signal generator and the board. For the entries from -36dBm to -51dBm, a 16 dB tap was used, in order to extend its range. Signals below to -51dBm are just linearly interpolated. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib8000.c | 111 ++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index faf469d1d437..7b10b73befbe 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -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))