On Tue Mar 24 13:25:02 2026 -0500, Bradford Love wrote:
> 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 <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/tuners/si2157.c      | 207 ++++++++++++++++++++++++++++---------
 drivers/media/tuners/si2157_priv.h |   3 +-
 2 files changed, 162 insertions(+), 48 deletions(-)

---

diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index b041cd854732..4d67e347c22f 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -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 */
diff --git a/drivers/media/tuners/si2157_priv.h 
b/drivers/media/tuners/si2157_priv.h
index 8579e80f7af7..aaada2bb0f21 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -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"
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to