]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: si2157: Include support for si2177 chip
authorBradford Love <brad@nextdimension.cc>
Tue, 24 Mar 2026 18:25:02 +0000 (13:25 -0500)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Wed, 25 Mar 2026 17:27:25 +0000 (18:27 +0100)
The si2177 is very closely related to si2157, with slight differences
when doing analog operations. Digital is left as is, but analog needs
to be configured specially because the signal is internally demodulated
and CVBS video is output directly from the tuner.

Verified locked and working with all supported standards.

Signed-off-by: Bradford Love <brad@nextdimension.cc>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/tuners/si2157.c
drivers/media/tuners/si2157_priv.h

index b041cd854732451d84f769b9e77de597899cf3fd..4d67e347c22f01ba0eb3ebab721e61f9905617d1 100644 (file)
@@ -687,60 +687,103 @@ static int si2157_set_analog_params(struct dvb_frontend *fe,
                params->mode, system, std, params->frequency,
                freq, if_frequency, bandwidth);
 
-       /* set analog IF port */
-       memcpy(cmd.args, "\x14\x00\x03\x06\x08\x02", 6);
-       /* in using dev->if_port, we assume analog and digital IF's */
-       /*   are always on different ports */
-       /* assumes if_port definition is 0 or 1 for digital out */
-       cmd.args[4] = (dev->if_port == 1) ? 8 : 10;
-       /* Analog AGC assumed external */
-       cmd.args[5] = (dev->if_port == 1) ? 2 : 1;
-       cmd.wlen = 6;
-       cmd.rlen = 4;
-       ret = si2157_cmd_execute(client, &cmd);
-       if (ret)
-               goto err;
+       if (dev->part_id != SI2177) {
+               /* AGC speed */
+               memcpy(cmd.args, "\x14\x00\x11\x06\x00\x00", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
 
-       /* set analog IF output config */
-       memcpy(cmd.args, "\x14\x00\x0d\x06\x94\x64", 6);
-       cmd.wlen = 6;
-       cmd.rlen = 4;
-       ret = si2157_cmd_execute(client, &cmd);
-       if (ret)
-               goto err;
+               /* set analog IF port */
+               memcpy(cmd.args, "\x14\x00\x03\x06\x08\x02", 6);
+               /* in using dev->if_port, we assume analog and digital IF's */
+               /*   are always on different ports */
+               /* assumes if_port definition is 0 or 1 for digital out */
+               cmd.args[4] = (dev->if_port == 1) ? 8 : 10;
+               /* Analog AGC assumed external */
+               cmd.args[5] = (dev->if_port == 1) ? 2 : 1;
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
 
-       /* make this distinct from a digital IF */
-       dev->if_frequency = if_frequency | 1;
+               /* set analog IF output config */
+               memcpy(cmd.args, "\x14\x00\x0d\x06\x94\x64", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
 
-       /* calc and set tuner analog if center frequency */
-       if_frequency = if_frequency + 1250000 - (bandwidth / 2);
-       dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency);
+               /* make this distinct from a digital IF */
+               dev->if_frequency = if_frequency | 1;
 
-       memcpy(cmd.args, "\x14\x00\x0C\x06", 4);
-       cmd.args[4] = (if_frequency / 1000) & 0xff;
-       cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff;
-       cmd.wlen = 6;
-       cmd.rlen = 4;
-       ret = si2157_cmd_execute(client, &cmd);
-       if (ret)
-               goto err;
+               /* calc and set tuner analog if center frequency */
+               if_frequency = if_frequency + 1250000 - (bandwidth / 2);
+               dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency);
 
-       /* set analog AGC config */
-       memcpy(cmd.args, "\x14\x00\x07\x06\x32\xc8", 6);
-       cmd.wlen = 6;
-       cmd.rlen = 4;
-       ret = si2157_cmd_execute(client, &cmd);
-       if (ret)
-               goto err;
+               memcpy(cmd.args, "\x14\x00\x0C\x06", 4);
+               cmd.args[4] = (if_frequency / 1000) & 0xff;
+               cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff;
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* set analog AGC config */
+               memcpy(cmd.args, "\x14\x00\x07\x06\x32\xc8", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* set analog video mode */
+               memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6);
+               cmd.args[4] = system | color;
+               /* can use dev->inversion if assumed applies to both digital/analog */
+               if (invert_analog)
+                       cmd.args[5] |= 0x02;
+               cmd.wlen = 6;
+               cmd.rlen = 1;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+       } else {
+               /* analog video equalizer - Si2177_ATV_VIDEO_EQUALIZER_PROP */
+               memcpy(cmd.args, "\x14\x00\x08\x06\xf8\x00", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* analog CVBS output properties - Si2177_ATV_CVBS_OUT_FINE_PROP */
+               memcpy(cmd.args, "\x14\x00\x14\x06\x00\x64", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
 
-       /* set analog video mode */
-       memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6);
-       cmd.args[4] = system | color;
-       /* can use dev->inversion if assumed applies to both digital/analog */
-       if (invert_analog)
-               cmd.args[5] |= 0x02;
+               dev_err(&client->dev, "%s() Settings HSYNC\n", __func__);
+               /* HSYNC output - Si2177_ATV_HSYNC_OUT_PROP */
+               memcpy(cmd.args, "\x14\x00\x27\x06\xa8\x00", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+       }
+
+       /* AFC qcuisition range 1.5MHz */
+       memcpy(cmd.args, "\x14\x00\x10\x06\xdc\x05", 6);
        cmd.wlen = 6;
-       cmd.rlen = 1;
+       cmd.rlen = 4;
        ret = si2157_cmd_execute(client, &cmd);
        if (ret)
                goto err;
@@ -757,6 +800,76 @@ static int si2157_set_analog_params(struct dvb_frontend *fe,
        if (ret)
                goto err;
 
+       if (dev->part_id == SI2177) {
+               /* Ref driver tunes, resets registers, then retunes, leaving steps as is */
+               /* set analog video mode - Si2158_ATV_VIDEO_MODE_PROP */
+               memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6);
+               cmd.args[4] = system | color;
+               /* can use dev->inversion if assumed applies to both digital/analog */
+               if (invert_analog)
+                       cmd.args[5] |= 0x02;
+
+               cmd.wlen = 6;
+               cmd.rlen = 1;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* Si2177_ATV_AUDIO_MODE_PROP */
+               memcpy(cmd.args, "\x14\x00\x02\x06\x20\x0f", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* af out - Si2177_ATV_AF_OUT_PROP */                   /* BRL */
+               memcpy(cmd.args, "\x14\x00\x0b\x06\x30\x00", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* analog CVBS output enable - Si2177_ATV_CVBS_OUT_PROP */
+               memcpy(cmd.args, "\x14\x00\x09\x06\x19\x99", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* analog video equalizer - Si2177_ATV_VIDEO_EQUALIZER_PROP */
+               memcpy(cmd.args, "\x14\x00\x08\x06\xf8\x00", 6);
+               cmd.wlen = 6;
+               cmd.rlen = 4;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /* ATV restart */
+               memcpy(cmd.args, "\x51\x00", 2);
+               cmd.wlen = 2;
+               cmd.rlen = 1;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               usleep_range(10000, 11000);
+
+               /* set analog frequency */
+               memcpy(cmd.args, "\x41\x01\x00\x00\x00\x00\x00\x00", 8);
+               cmd.args[4] = (freq >>  0) & 0xff;
+               cmd.args[5] = (freq >>  8) & 0xff;
+               cmd.args[6] = (freq >> 16) & 0xff;
+               cmd.args[7] = (freq >> 24) & 0xff;
+               cmd.wlen = 8;
+               cmd.rlen = 1;
+               ret = si2157_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+       }
+
        dev->bandwidth = bandwidth;
 
        si2157_tune_wait(client, 0); /* wait to complete, ignore any errors */
index 8579e80f7af70b51e381cf276614f6b72fd3dd11..aaada2bb0f21b370397d3c56be00f698fed96ad6 100644 (file)
@@ -72,7 +72,8 @@ struct si2157_cmd {
                               ((dev)->part_id == SI2177))
 
 #define SUPPORTS_ATV_IF(dev) (((dev)->part_id == SI2157) || \
-                             ((dev)->part_id == SI2158))
+                             ((dev)->part_id == SI2158) || \
+                             ((dev)->part_id == SI2177))
 
 /* Old firmware namespace */
 #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"