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 <b...@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

Reply via email to