media: si2157: add on-demand rf strength func
authorBrad Love <brad@nextdimension.cc>
Thu, 14 Nov 2019 20:04:06 +0000 (21:04 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 21 Apr 2020 14:50:35 +0000 (16:50 +0200)
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>
drivers/media/tuners/si2157.c

index 94db661..6b45256 100644 (file)
@@ -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)