[PATCH] si2168: Change from DVB-T to DVB-T/T2 autodetect

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



DVB-T2 support can be a bit lacking in user land, this provides a module
parameter to allow setting the PLP to auto detect DVB-T and DVB-T2
signals after tuning. If a DVB-T2 signal is found the signal is
processed as DVB-T2, otherwise it is left as DVB-T. The detected
signal type is taken into account when reading status.

The module parameter is default disabled, to be backwards compatible
with current behaviour.

Signed-off-by: Brad Love <brad@xxxxxxxxxxxxxxxx>
---
 drivers/media/dvb-frontends/si2168.c | 59 ++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 324493e..4713ee5 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -18,6 +18,10 @@
 
 #include "si2168_priv.h"
 
+static int dvbt_auto_plp;
+module_param(dvbt_auto_plp, int, 0644);
+MODULE_PARM_DESC(dvbt_auto_plp, "if set, the PLP is set to auto detect DVB-T and DVB-T2 signals");
+
 static const struct dvb_frontend_ops si2168_ops;
 
 /* execute firmware command */
@@ -111,7 +115,7 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status)
 	struct i2c_client *client = fe->demodulator_priv;
 	struct si2168_dev *dev = i2c_get_clientdata(client);
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int ret, i;
+	int ret, i, sys;
 	unsigned int utmp, utmp1, utmp2;
 	struct si2168_cmd cmd;
 
@@ -122,7 +126,23 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status)
 		goto err;
 	}
 
-	switch (c->delivery_system) {
+	sys = c->delivery_system;
+
+	/* check if we found DVB-T2 during DVB-T tuning */
+	if (dvbt_auto_plp && sys == SYS_DVBT) {
+		memcpy(cmd.args, "\x87\x01", 2);
+		cmd.wlen = 2;
+		cmd.rlen = 8;
+
+		ret = si2168_cmd_execute(client, &cmd);
+		if (ret)
+			goto err;
+
+		if ((cmd.args[3] & 0x0f) == 7)
+			sys = SYS_DVBT2;
+	}
+
+	switch (sys) {
 	case SYS_DVBT:
 		memcpy(cmd.args, "\xa0\x01", 2);
 		cmd.wlen = 2;
@@ -144,6 +164,24 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status)
 	}
 
 	ret = si2168_cmd_execute(client, &cmd);
+	if (dvbt_auto_plp && (ret == -EREMOTEIO)) {
+		/* In auto-PLP mode it is possible to read 0x8701 while
+		 * the frontend is in switchover transition. This causes
+		 * a status read failure, due to incorrect system. Check
+		 * the other sys if we hit this race condition.
+		 */
+		if (sys == SYS_DVBT) {
+			memcpy(cmd.args, "\x50\x01", 2); /* DVB-T2 */
+			cmd.wlen = 2;
+			cmd.rlen = 14;
+			ret = si2168_cmd_execute(client, &cmd);
+		} else if (sys == SYS_DVBT2) {
+			memcpy(cmd.args, "\xa0\x01", 2); /* DVB-T */
+			cmd.wlen = 2;
+			cmd.rlen = 13;
+			ret = si2168_cmd_execute(client, &cmd);
+		}
+	}
 	if (ret)
 		goto err;
 
@@ -254,7 +292,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 
 	switch (c->delivery_system) {
 	case SYS_DVBT:
-		delivery_system = 0x20;
+		if (dvbt_auto_plp)
+			delivery_system = 0xf0; /* T/T2 auto-detect */
+		else
+			delivery_system = 0x20;
 		break;
 	case SYS_DVBC_ANNEX_A:
 		delivery_system = 0x30;
@@ -324,6 +365,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
+	} else if (dvbt_auto_plp && (c->delivery_system == SYS_DVBT)) {
+		/* select Auto PLP */
+		cmd.args[0] = 0x52;
+		cmd.args[1] = 0;
+		cmd.args[2] = 0; /* Auto PLP */
+		cmd.wlen = 3;
+		cmd.rlen = 1;
+		ret = si2168_cmd_execute(client, &cmd);
+		if (ret)
+			goto err;
 	}
 
 	memcpy(cmd.args, "\x51\x03", 2);
@@ -363,6 +414,8 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 
 	memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
 	cmd.args[4] = delivery_system | bandwidth;
+	if (delivery_system == 0xf0)
+		cmd.args[5] |= 2; /* Auto detect DVB-T/T2 */
 	if (dev->spectral_inversion)
 		cmd.args[5] |= 1;
 	cmd.wlen = 6;
-- 
2.7.4




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux