summaryrefslogtreecommitdiff
path: root/drivers/media/tuners/si2157.c
diff options
context:
space:
mode:
authorBrad Love <brad@nextdimension.cc>2019-11-14 23:04:00 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-04-21 17:47:36 +0300
commite4361015a4aa2960f1441482241520cf095d2de9 (patch)
tree87d5288af69984bf9b07a32f1b929ace9f9a07e1 /drivers/media/tuners/si2157.c
parent578147e968bd0cf6d74f4f04eee5a1f9b7e007da (diff)
downloadlinux-e4361015a4aa2960f1441482241520cf095d2de9.tar.xz
media: si2157: module debug option to wait on signal lock
In some debugging cases it is useful to know how long it took signal lock to happen after tuning. This can help diagnose line issues. 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/si2157.c')
-rw-r--r--drivers/media/tuners/si2157.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index b22441522921..94db66107b98 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -9,6 +9,10 @@
static const struct dvb_tuner_ops si2157_ops;
+static int tuner_lock_debug;
+module_param(tuner_lock_debug, int, 0644);
+MODULE_PARM_DESC(tuner_lock_debug, "if set, signal lock is briefly waited on after setting params");
+
/* execute firmware command */
static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
{
@@ -301,14 +305,22 @@ err:
return ret;
}
-static int si2157_tune_wait(struct i2c_client *client)
+static int si2157_tune_wait(struct i2c_client *client, u8 is_digital)
{
#define TUN_TIMEOUT 40
+#define DIG_TIMEOUT 30
+#define ANALOG_TIMEOUT 150
struct si2157_dev *dev = i2c_get_clientdata(client);
int ret;
unsigned long timeout;
unsigned long start_time;
u8 wait_status;
+ u8 tune_lock_mask;
+
+ if (is_digital)
+ tune_lock_mask = 0x04;
+ else
+ tune_lock_mask = 0x02;
mutex_lock(&dev->i2c_mutex);
@@ -335,6 +347,34 @@ static int si2157_tune_wait(struct i2c_client *client)
jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time),
wait_status);
+ /* if we tuned ok, wait a bit for tuner lock */
+ if (tuner_lock_debug && (wait_status & 0x81) == 0x81) {
+ if (is_digital)
+ timeout = jiffies + msecs_to_jiffies(DIG_TIMEOUT);
+ else
+ timeout = jiffies + msecs_to_jiffies(ANALOG_TIMEOUT);
+
+ while (!time_after(jiffies, timeout)) {
+ ret = i2c_master_recv(client, &wait_status,
+ sizeof(wait_status));
+ if (ret < 0) {
+ goto err_mutex_unlock;
+ } else if (ret != sizeof(wait_status)) {
+ ret = -EREMOTEIO;
+ goto err_mutex_unlock;
+ }
+
+ /* tuner locked? */
+ if (wait_status & tune_lock_mask)
+ break;
+ usleep_range(5000, 10000);
+ }
+
+ dev_dbg(&client->dev, "tuning+lock took %d ms, status=0x%x\n",
+ jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time),
+ wait_status);
+ }
+
if ((wait_status & 0xc0) != 0x80) {
ret = -ETIMEDOUT;
goto err_mutex_unlock;
@@ -448,7 +488,7 @@ static int si2157_set_params(struct dvb_frontend *fe)
dev->bandwidth = bandwidth;
dev->frequency = c->frequency;
- si2157_tune_wait(client); /* wait to complete, ignore any errors */
+ si2157_tune_wait(client, 1); /* wait to complete, ignore any errors */
return 0;
err:
@@ -645,7 +685,7 @@ static int si2157_set_analog_params(struct dvb_frontend *fe,
dev->bandwidth = bandwidth;
- si2157_tune_wait(client); /* wait to complete, ignore any errors */
+ si2157_tune_wait(client, 0); /* wait to complete, ignore any errors */
return 0;
err: