summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBradford Love <brad@nextdimension.cc>2026-03-13 00:35:23 +0300
committerHans Verkuil <hverkuil+cisco@kernel.org>2026-03-17 12:50:19 +0300
commit36200241f5a3dd28b95fdefb2885ca9fd52f6387 (patch)
tree41251a18745ee933efa99cea724db363eca7a126
parent9cddeb883bacf82757bf3273c60a2d2e45bf7fe9 (diff)
downloadlinux-36200241f5a3dd28b95fdefb2885ca9fd52f6387.tar.xz
media: cx25840: Fix NTSC-J, PAL-N, and SECAM standards
Formats did not correctly decode prior. Modifications are based off cx25840 datasheet. Signed-off-by: Bradford Love <brad@nextdimension.cc> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index a86306304330..69d5cc648c0f 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -1652,10 +1652,14 @@ static int set_v4lstd(struct i2c_client *client)
struct cx25840_state *state = to_state(i2c_get_clientdata(client));
u8 fmt = 0; /* zero is autodetect */
u8 pal_m = 0;
+ u8 pal_n = 0;
+ u8 ntsc_j = 0;
+ u8 tmp_reg = 0;
/* First tests should be against specific std */
if (state->std == V4L2_STD_NTSC_M_JP) {
fmt = 0x2;
+ ntsc_j = 0x80;
} else if (state->std == V4L2_STD_NTSC_443) {
fmt = 0x3;
} else if (state->std == V4L2_STD_PAL_M) {
@@ -1663,6 +1667,7 @@ static int set_v4lstd(struct i2c_client *client)
fmt = 0x5;
} else if (state->std == V4L2_STD_PAL_N) {
fmt = 0x6;
+ pal_n = 0x40;
} else if (state->std == V4L2_STD_PAL_Nc) {
fmt = 0x7;
} else if (state->std == V4L2_STD_PAL_60) {
@@ -1689,10 +1694,30 @@ static int set_v4lstd(struct i2c_client *client)
/* Set format to NTSC-M */
cx25840_and_or(client, 0x400, ~0xf, 1);
/* Turn off LCOMB */
- cx25840_and_or(client, 0x47b, ~6, 0);
+ cx25840_and_or(client, 0x47b, ~0x6, 0);
+ } else if (fmt == 0xc) { /* SECAM - Step 9c - toggle CKILLEN */
+ tmp_reg = cx25840_read(client, 0x401);
+ cx25840_and_or(client, 0x401, ~0x20, tmp_reg & 0x20 ? 0x00 : 0x20);
+ cx25840_and_or(client, 0x401, ~0x20, tmp_reg & 0x20 ? 0x20 : 0x00);
}
+
cx25840_and_or(client, 0x400, ~0xf, fmt);
- cx25840_and_or(client, 0x403, ~0x3, pal_m);
+
+ if (fmt >= 4 && fmt < 8) {
+ tmp_reg = cx25840_read(client, 0x401);
+ cx25840_and_or(client, 0x401, ~0x40, tmp_reg & 0x40 ? 0x00 : 0x40); /* CAGCEN */
+ cx25840_and_or(client, 0x401, ~0x40, tmp_reg & 0x40 ? 0x40 : 0x00);
+ cx25840_and_or(client, 0x401, ~0x20, tmp_reg & 0x20 ? 0x00 : 0x20); /* CKILLEN */
+ cx25840_and_or(client, 0x401, ~0x20, tmp_reg & 0x20 ? 0x20 : 0x00);
+ }
+
+ if (pal_m)
+ cx25840_and_or(client, 0x403, ~0x3, pal_m);
+ else if (pal_n) /* cx25840 datasheet table 3-19 */
+ cx25840_and_or(client, 0x403, ~0x40, pal_n);
+ else if (ntsc_j) /* cx25840 datasheet table 3-19 */
+ cx25840_and_or(client, 0x403, ~0x80, ntsc_j);
+
if (is_cx23888(state))
cx23888_std_setup(client);
else