* [PATCHv2 0/2] media: tc358743: add support for more IF/Packet types
@ 2025-07-22 7:34 Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 1/2] media: v4l2-core: v4l2-dv-timings: support DRM IFs Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 2/2] media: i2c: tc358743: add support for more infoframe types Hans Verkuil
0 siblings, 2 replies; 3+ messages in thread
From: Hans Verkuil @ 2025-07-22 7:34 UTC (permalink / raw)
To: linux-media; +Cc: Maxime Ripard, Dave Stevenson
The tc358743 HDMI-to-CSI2 bridge is widely available, and it has quite
flexible InfoFrame/Packet Type support, so this makes it a very nice
device to capture such data.
This patch series adds support for SPD, AUDIO, DRM and HDMI InfoFrames.
Also add support for ISRC1 and ISRC2 Packet Types and a programmable
type for both Packet and InfoFrames, which by default is programmed
for DRM InfoFrames.
These changes make the tc358743 very useful when you want to see
what InfoFrames and Packet Types are being transmitted.
Regards,
Hans
Changes since v1:
- Added Packet Type support (ISRC1, ISRC2) and DRM and MPEG
InfoFrame support.
- Added programmable Packet Type (defaults to DRM).
Hans Verkuil (2):
media: v4l2-core: v4l2-dv-timings: support DRM IFs
media: i2c: tc358743: add support for more infoframe types
drivers/media/i2c/tc358743.c | 109 +++++++++++++++++++---
drivers/media/i2c/tc358743_regs.h | 57 +++++++----
drivers/media/v4l2-core/v4l2-dv-timings.c | 4 +
include/media/v4l2-dv-timings.h | 1 +
4 files changed, 140 insertions(+), 31 deletions(-)
--
2.47.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCHv2 1/2] media: v4l2-core: v4l2-dv-timings: support DRM IFs
2025-07-22 7:34 [PATCHv2 0/2] media: tc358743: add support for more IF/Packet types Hans Verkuil
@ 2025-07-22 7:34 ` Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 2/2] media: i2c: tc358743: add support for more infoframe types Hans Verkuil
1 sibling, 0 replies; 3+ messages in thread
From: Hans Verkuil @ 2025-07-22 7:34 UTC (permalink / raw)
To: linux-media; +Cc: Maxime Ripard, Dave Stevenson, Hans Verkuil
Add support for DRM (Dynamic Range and Mastering) InfoFrames.
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
---
drivers/media/v4l2-core/v4l2-dv-timings.c | 4 ++++
include/media/v4l2-dv-timings.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 7710cb26bea0..346d1b0e10ce 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -1226,6 +1226,7 @@ DEBUGFS_FOPS(avi, V4L2_DEBUGFS_IF_AVI);
DEBUGFS_FOPS(audio, V4L2_DEBUGFS_IF_AUDIO);
DEBUGFS_FOPS(spd, V4L2_DEBUGFS_IF_SPD);
DEBUGFS_FOPS(hdmi, V4L2_DEBUGFS_IF_HDMI);
+DEBUGFS_FOPS(drm, V4L2_DEBUGFS_IF_DRM);
struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 if_types,
void *priv,
@@ -1255,6 +1256,9 @@ struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 if_types,
if (if_types & V4L2_DEBUGFS_IF_HDMI)
debugfs_create_file("hdmi", 0400, infoframes->if_dir,
infoframes, &infoframe_hdmi_fops);
+ if (if_types & V4L2_DEBUGFS_IF_DRM)
+ debugfs_create_file("hdr_drm", 0400, infoframes->if_dir,
+ infoframes, &infoframe_drm_fops);
return infoframes;
}
EXPORT_SYMBOL_GPL(v4l2_debugfs_if_alloc);
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 714075c72f77..2b42e5d81f9e 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -275,6 +275,7 @@ int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
#define V4L2_DEBUGFS_IF_AUDIO BIT(1)
#define V4L2_DEBUGFS_IF_SPD BIT(2)
#define V4L2_DEBUGFS_IF_HDMI BIT(3)
+#define V4L2_DEBUGFS_IF_DRM BIT(4)
typedef ssize_t (*v4l2_debugfs_if_read_t)(u32 type, void *priv,
struct file *filp, char __user *ubuf,
--
2.47.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCHv2 2/2] media: i2c: tc358743: add support for more infoframe types
2025-07-22 7:34 [PATCHv2 0/2] media: tc358743: add support for more IF/Packet types Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 1/2] media: v4l2-core: v4l2-dv-timings: support DRM IFs Hans Verkuil
@ 2025-07-22 7:34 ` Hans Verkuil
1 sibling, 0 replies; 3+ messages in thread
From: Hans Verkuil @ 2025-07-22 7:34 UTC (permalink / raw)
To: linux-media; +Cc: Maxime Ripard, Dave Stevenson, Hans Verkuil
Add support for SPD, AUDIO, DRM and HDMI InfoFrames.
Also add support for ISRC1 and ISRC2 Packet Types and a programmable
type for both Packet and InfoFrames.
The tc358743 HDMI-to-CSI2 bridge is widely available, and it has quite
flexible InfoFrame/Packet Type support, so this makes it a very nice
device to capture such data.
The ACP (Audio Content Protection) Packet capture data is chosen as the
programmable type. ACP is typically only used for protected audio, which
is quite rare, so instead it is reprogrammed to capture DRM InfoFrames
by default. This can be changed by using the acp_type module option to
anything you want, and you can change it on the fly as well. It will be
updated whenever VIDIOC_LOG_STATUS is called (it's really a debug feature).
Tested on my Raspberry Pi 5.
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
---
drivers/media/i2c/tc358743.c | 109 ++++++++++++++++++++++++++----
drivers/media/i2c/tc358743_regs.h | 57 +++++++++++-----
2 files changed, 135 insertions(+), 31 deletions(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 1cc7636e446d..6550ec94cb0c 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -38,7 +38,21 @@
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-3)");
+MODULE_PARM_DESC(debug, " debug level (0-3)");
+
+static int acp_type = 0x87;
+module_param(acp_type, int, 0644);
+MODULE_PARM_DESC(acp_type,
+ " ACP Packet Type. Possible values:\n"
+ "\t\t 0x87: DRM InfoFrame (Default).\n"
+ "\t\t 0x01: Audio Clock Regeneration Packet\n"
+ "\t\t 0x02: Audio Sample Packet\n"
+ "\t\t 0x03: General Control Packet\n"
+ "\t\t 0x04: ACP Packet\n"
+ "\t\t 0x07: One Bit Audio Sample Packet\n"
+ "\t\t 0x08: DST Audio Packet\n"
+ "\t\t 0x09: High Bitrate Audio Stream Packet\n"
+ "\t\t 0x0a: Gamut Metadata Packet\n");
MODULE_DESCRIPTION("Toshiba TC358743 HDMI to CSI-2 bridge driver");
MODULE_AUTHOR("Ramakrishnan Muthukrishnan <ram@rkrishnan.org>");
@@ -466,10 +480,29 @@ tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
if (!is_hdmi(sd))
return 0;
- if (type != V4L2_DEBUGFS_IF_AVI)
+ switch (type) {
+ case V4L2_DEBUGFS_IF_AVI:
+ i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_AUDIO:
+ i2c_rd(sd, PK_AUD_0HEAD, buf, PK_AUD_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_SPD:
+ i2c_rd(sd, PK_SPD_0HEAD, buf, PK_SPD_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_HDMI:
+ i2c_rd(sd, PK_VS_0HEAD, buf, PK_VS_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_DRM:
+ i2c_rd(sd, PK_ACP_0HEAD, buf, PK_ACP_LEN);
+ break;
+ default:
return 0;
+ }
+
+ if (!buf[2])
+ return -ENOENT;
- i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
len = buf[2] + 4;
if (len > V4L2_DEBUGFS_IF_MAX_LEN)
len = -ENOENT;
@@ -478,26 +511,69 @@ tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
return len < 0 ? 0 : len;
}
-static void print_avi_infoframe(struct v4l2_subdev *sd)
+static void print_infoframes(struct v4l2_subdev *sd)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
union hdmi_infoframe frame;
- u8 buffer[HDMI_INFOFRAME_SIZE(AVI)] = {};
+ u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+
+ /*
+ * Updating the ACP TYPE here allows for dynamically
+ * changing the type you want to monitor, without having
+ * to reload the driver with a new acp_type module option value.
+ *
+ * Instead you can set it with the new value, then call
+ * VIDIOC_LOG_STATUS.
+ */
+ i2c_wr8(sd, TYP_ACP_SET, acp_type);
if (!is_hdmi(sd)) {
- v4l2_info(sd, "DVI-D signal - AVI infoframe not supported\n");
+ v4l2_info(sd, "DVI-D signal - InfoFrames not supported\n");
return;
}
- i2c_rd(sd, PK_AVI_0HEAD, buffer, HDMI_INFOFRAME_SIZE(AVI));
+ i2c_rd(sd, PK_AVI_0HEAD, buffer, PK_AVI_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
- if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) {
- v4l2_err(sd, "%s: unpack of AVI infoframe failed\n", __func__);
- return;
+ i2c_rd(sd, PK_VS_0HEAD, buffer, PK_VS_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_AUD_0HEAD, buffer, PK_AUD_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_SPD_0HEAD, buffer, PK_SPD_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_ACP_0HEAD, buffer, PK_ACP_LEN);
+ if (buffer[0] == acp_type) {
+ if (acp_type < 0x80)
+ v4l2_info(sd, "Packet: %*ph\n", PK_ACP_LEN, buffer);
+ else if (acp_type != 0x87)
+ v4l2_info(sd, "InfoFrame: %*ph\n", PK_ACP_LEN, buffer);
+ else if (hdmi_infoframe_unpack(&frame, buffer,
+ sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
}
- hdmi_infoframe_log(KERN_INFO, dev, &frame);
+ i2c_rd(sd, PK_MS_0HEAD, buffer, PK_MS_LEN);
+ if (buffer[2] && buffer[2] + 3 <= PK_MS_LEN)
+ v4l2_info(sd, "MPEG Source InfoFrame: %*ph\n",
+ buffer[2] + 3, buffer);
+
+ i2c_rd(sd, PK_ISRC1_0HEAD, buffer, PK_ISRC1_LEN);
+ if (buffer[0] == 0x05)
+ v4l2_info(sd, "ISRC1 Packet: %*ph\n",
+ PK_ISRC1_LEN, buffer);
+
+ i2c_rd(sd, PK_ISRC2_0HEAD, buffer, PK_ISRC2_LEN);
+ if (buffer[0] == 0x06)
+ v4l2_info(sd, "ISRC2 Packet: %*ph\n",
+ PK_ISRC2_LEN, buffer);
}
/* --------------- CTRLS --------------- */
@@ -1375,7 +1451,7 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
v4l2_info(sd, "Deep color mode: %d-bits per channel\n",
deep_color_mode[(i2c_rd8(sd, VI_STATUS1) &
MASK_S_DEEPCOLOR) >> 2]);
- print_avi_infoframe(sd);
+ print_infoframes(sd);
return 0;
}
@@ -2232,10 +2308,15 @@ static int tc358743_probe(struct i2c_client *client)
if (err < 0)
goto err_work_queues;
+ i2c_wr8(sd, TYP_ACP_SET, acp_type);
+ i2c_wr8(sd, PK_AUTO_CLR, 0xff);
+ i2c_wr8(sd, NO_PKT_CLR, MASK_NO_ACP_CLR);
+
state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
- V4L2_DEBUGFS_IF_AVI, sd,
- tc358743_debugfs_if_read);
+ V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+ V4L2_DEBUGFS_IF_SPD | V4L2_DEBUGFS_IF_HDMI |
+ V4L2_DEBUGFS_IF_DRM, sd, tc358743_debugfs_if_read);
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
diff --git a/drivers/media/i2c/tc358743_regs.h b/drivers/media/i2c/tc358743_regs.h
index 2495878dc358..aae288f8add3 100644
--- a/drivers/media/i2c/tc358743_regs.h
+++ b/drivers/media/i2c/tc358743_regs.h
@@ -692,6 +692,8 @@
#define MASK_NCO_F0_MOD_42MHZ 0x00
#define MASK_NCO_F0_MOD_27MHZ 0x01
+#define TYP_ACP_SET 0x8706
+
#define PK_INT_MODE 0x8709
#define MASK_ISRC2_INT_MODE 0x80
#define MASK_ISRC_INT_MODE 0x40
@@ -702,6 +704,8 @@
#define MASK_AUD_INT_MODE 0x02
#define MASK_AVI_INT_MODE 0x01
+#define PK_AUTO_CLR 0x870a
+
#define NO_PKT_LIMIT 0x870B
#define MASK_NO_ACP_LIMIT 0xf0
#define SET_NO_ACP_LIMIT_MS(milliseconds) ((((milliseconds) / 80) << 4) & \
@@ -720,25 +724,44 @@
#define ERR_PK_LIMIT 0x870D
#define NO_PKT_LIMIT2 0x870E
#define PK_AVI_0HEAD 0x8710
-#define PK_AVI_1HEAD 0x8711
-#define PK_AVI_2HEAD 0x8712
#define PK_AVI_0BYTE 0x8713
-#define PK_AVI_1BYTE 0x8714
-#define PK_AVI_2BYTE 0x8715
-#define PK_AVI_3BYTE 0x8716
-#define PK_AVI_4BYTE 0x8717
-#define PK_AVI_5BYTE 0x8718
-#define PK_AVI_6BYTE 0x8719
-#define PK_AVI_7BYTE 0x871A
-#define PK_AVI_8BYTE 0x871B
-#define PK_AVI_9BYTE 0x871C
-#define PK_AVI_10BYTE 0x871D
-#define PK_AVI_11BYTE 0x871E
-#define PK_AVI_12BYTE 0x871F
-#define PK_AVI_13BYTE 0x8720
-#define PK_AVI_14BYTE 0x8721
-#define PK_AVI_15BYTE 0x8722
#define PK_AVI_16BYTE 0x8723
+#define PK_AVI_LEN (PK_AVI_16BYTE - PK_AVI_0HEAD + 1)
+
+#define PK_AUD_0HEAD 0x8730
+#define PK_AUD_0BYTE 0x8733
+#define PK_AUD_10BYTE 0x873d
+#define PK_AUD_LEN (PK_AUD_10BYTE - PK_AUD_0HEAD + 1)
+
+#define PK_MS_0HEAD 0x8740
+#define PK_MS_0BYTE 0x8743
+#define PK_MS_10BYTE 0x874d
+#define PK_MS_LEN (PK_MS_10BYTE - PK_MS_0HEAD + 1)
+
+#define PK_SPD_0HEAD 0x8750
+#define PK_SPD_0BYTE 0x8753
+#define PK_SPD_27BYTE 0x876e
+#define PK_SPD_LEN (PK_SPD_27BYTE - PK_SPD_0HEAD + 1)
+
+#define PK_VS_0HEAD 0x8770
+#define PK_VS_0BYTE 0x8773
+#define PK_VS_27BYTE 0x878e
+#define PK_VS_LEN (PK_VS_27BYTE - PK_VS_0HEAD + 1)
+
+#define PK_ACP_0HEAD 0x8790
+#define PK_ACP_0BYTE 0x8793
+#define PK_ACP_27BYTE 0x87ae
+#define PK_ACP_LEN (PK_ACP_27BYTE - PK_ACP_0HEAD + 1)
+
+#define PK_ISRC1_0HEAD 0x87b0
+#define PK_ISRC1_0BYTE 0x87b3
+#define PK_ISRC1_27BYTE 0x87c2
+#define PK_ISRC1_LEN (PK_ISRC1_27BYTE - PK_ISRC1_0HEAD + 1)
+
+#define PK_ISRC2_0HEAD 0x87d0
+#define PK_ISRC2_0BYTE 0x87d3
+#define PK_ISRC2_27BYTE 0x87ee
+#define PK_ISRC2_LEN (PK_ISRC2_27BYTE - PK_ISRC2_0HEAD + 1)
#define BKSV 0x8800
--
2.47.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-07-22 7:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-22 7:34 [PATCHv2 0/2] media: tc358743: add support for more IF/Packet types Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 1/2] media: v4l2-core: v4l2-dv-timings: support DRM IFs Hans Verkuil
2025-07-22 7:34 ` [PATCHv2 2/2] media: i2c: tc358743: add support for more infoframe types Hans Verkuil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).