diff mbox series

[v3,06/14] si2157: module debug option to wait on signal lock

Message ID 20191114200408.28883-7-brad@nextdimension.cc (mailing list archive)
State New, archived
Headers show
Series si2157: Analog tuning and optimizations | expand

Commit Message

Brad Love Nov. 14, 2019, 8:04 p.m. UTC
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>
---
Since v2:
- Split into two parts, tune completion and signal lock

 drivers/media/tuners/si2157.c | 46 ++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index cac4870017f5..16d7169f46fb 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 @@  static int si2157_sleep(struct dvb_frontend *fe)
 	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:
@@ -644,7 +684,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: