diff mbox series

si2168: Change from DVB-T to DVB-T/T2 autodetect

Message ID 1546106418-18474-1-git-send-email-brad@nextdimension.cc (mailing list archive)
State New, archived
Headers show
Series si2168: Change from DVB-T to DVB-T/T2 autodetect | expand

Commit Message

Brad Love Dec. 29, 2018, 6 p.m. UTC
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@nextdimension.cc>
---
 drivers/media/dvb-frontends/si2168.c | 59 ++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 3 deletions(-)

Comments

Sean Young April 5, 2019, 9:51 a.m. UTC | #1
Hi Brad,

On Sat, Dec 29, 2018 at 12:00:18PM -0600, Brad Love wrote:
> 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.

You're changing the uapi through a module parameter, for user space that
hasn't been updated for DVB-T2. In addition, this uapi change is only for
specific frontend.

If there is something to be said for a DVB-T/T2 autodetect mode, this should
be done through the existing uapi and not through module parameters. We
would like the uapi to generic for all devices not lots of device-specific
parameters.


Sean

> 
> Signed-off-by: Brad Love <brad@nextdimension.cc>
> ---
>  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
diff mbox series

Patch

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;