diff options
author | Brad Love <brad@nextdimension.cc> | 2019-11-14 23:04:00 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2020-04-21 17:47:36 +0300 |
commit | e4361015a4aa2960f1441482241520cf095d2de9 (patch) | |
tree | 87d5288af69984bf9b07a32f1b929ace9f9a07e1 /drivers/media/tuners | |
parent | 578147e968bd0cf6d74f4f04eee5a1f9b7e007da (diff) |
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')
-rw-r--r-- | drivers/media/tuners/si2157.c | 46 |
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: |