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]