summaryrefslogtreecommitdiff
path: root/drivers/media/tuners
diff options
context:
space:
mode:
authorBrad Love <brad@nextdimension.cc>2019-11-14 23:04:06 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-04-21 17:50:35 +0300
commitd99846cb1c0ecba0856276da5b8c2368dd402623 (patch)
tree153bb9d3e0defdce36a4bca73dccb217c5bddbac /drivers/media/tuners
parent3c1ccbad80802fa8bf807725db75a92d0887c9f2 (diff)
downloadlinux-d99846cb1c0ecba0856276da5b8c2368dd402623.tar.xz
media: si2157: add on-demand rf strength func
Add get_rf_strength callback to get RSSI from the tuner. DVBv5 stat cache is updated. get_rf_strength is called by tuner_core for analog tuners and is also used by some bridge drivers to obtain RSSI directly from the tuner. Signed-off-by: Brad Love <brad@nextdimension.cc> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r--drivers/media/tuners/si2157.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 94db66107b98..6b452565dedb 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -726,6 +726,42 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
return 0;
}
+static int si2157_get_rf_strength(struct dvb_frontend *fe, u16 *rssi)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct si2157_cmd cmd;
+ int ret;
+ int strength;
+
+ dev_dbg(&client->dev, "\n");
+
+ memcpy(cmd.args, "\x42\x00", 2);
+ cmd.wlen = 2;
+ cmd.rlen = 12;
+ ret = si2157_cmd_execute(client, &cmd);
+ if (ret)
+ goto err;
+
+ c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ c->strength.stat[0].svalue = (s8)cmd.args[3] * 1000;
+
+ /* normalize values based on Silicon Labs reference
+ * add 100, then anything > 80 is 100% signal
+ */
+ strength = (s8)cmd.args[3] + 100;
+ strength = clamp_val(strength, 0, 80);
+ *rssi = (u16)(strength * 0xffff / 80);
+
+ dev_dbg(&client->dev, "strength=%d rssi=%u\n",
+ (s8)cmd.args[3], *rssi);
+
+ return 0;
+err:
+ dev_dbg(&client->dev, "failed=%d\n", ret);
+ return ret;
+}
+
static const struct dvb_tuner_ops si2157_ops = {
.info = {
.name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
@@ -739,7 +775,9 @@ static const struct dvb_tuner_ops si2157_ops = {
.set_analog_params = si2157_set_analog_params,
.get_frequency = si2157_get_frequency,
.get_bandwidth = si2157_get_bandwidth,
- .get_if_frequency = si2157_get_if_frequency,
+ .get_if_frequency = si2157_get_if_frequency,
+
+ .get_rf_strength = si2157_get_rf_strength,
};
static void si2157_stat_work(struct work_struct *work)