mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 06:01:53 +02:00
media: i2c: adv7511-v4l2: export InfoFrames to debugfs
Export InfoFrames to debugfs. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
01c76fc995
commit
c6a38df916
|
|
@ -116,6 +116,9 @@ struct adv7511_state {
|
|||
unsigned edid_detect_counter;
|
||||
struct workqueue_struct *work_queue;
|
||||
struct delayed_work edid_handler; /* work entry */
|
||||
|
||||
struct dentry *debugfs_dir;
|
||||
struct v4l2_debugfs_if *infoframes;
|
||||
};
|
||||
|
||||
static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd);
|
||||
|
|
@ -483,27 +486,25 @@ static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
|
|||
return 256 - csum;
|
||||
}
|
||||
|
||||
static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_infoframe *cri)
|
||||
static int read_infoframe(struct v4l2_subdev *sd,
|
||||
const struct adv7511_cfg_read_infoframe *cri,
|
||||
u8 *buffer)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct device *dev = &client->dev;
|
||||
union hdmi_infoframe frame;
|
||||
u8 buffer[32];
|
||||
u8 len;
|
||||
int i;
|
||||
|
||||
if (!(adv7511_rd(sd, cri->present_reg) & cri->present_mask)) {
|
||||
v4l2_info(sd, "%s infoframe not transmitted\n", cri->desc);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buffer, cri->header, sizeof(cri->header));
|
||||
|
||||
len = buffer[2];
|
||||
|
||||
if (len + 4 > sizeof(buffer)) {
|
||||
if (len + 4 > V4L2_DEBUGFS_IF_MAX_LEN) {
|
||||
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cri->payload_addr >= 0x100) {
|
||||
|
|
@ -516,21 +517,38 @@ static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_
|
|||
buffer[3] = 0;
|
||||
buffer[3] = hdmi_infoframe_checksum(buffer, len + 4);
|
||||
|
||||
if (hdmi_infoframe_unpack(&frame, buffer, len + 4) < 0) {
|
||||
v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc);
|
||||
return len + 4;
|
||||
}
|
||||
|
||||
static void log_infoframe(struct v4l2_subdev *sd,
|
||||
const struct adv7511_cfg_read_infoframe *cri)
|
||||
{
|
||||
union hdmi_infoframe frame;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct device *dev = &client->dev;
|
||||
u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
|
||||
int len = read_infoframe(sd, cri, buffer);
|
||||
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) {
|
||||
v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
|
||||
__func__, cri->desc);
|
||||
return;
|
||||
}
|
||||
|
||||
hdmi_infoframe_log(KERN_INFO, dev, &frame);
|
||||
}
|
||||
|
||||
static const struct adv7511_cfg_read_infoframe cri[] = {
|
||||
{ "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
|
||||
{ "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
|
||||
{ "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
|
||||
};
|
||||
|
||||
static void adv7511_log_infoframes(struct v4l2_subdev *sd)
|
||||
{
|
||||
static const struct adv7511_cfg_read_infoframe cri[] = {
|
||||
{ "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
|
||||
{ "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
|
||||
{ "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cri); i++)
|
||||
|
|
@ -1693,6 +1711,34 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
|
|||
return false;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
adv7511_debugfs_if_read(u32 type, void *priv,
|
||||
struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
|
||||
struct v4l2_subdev *sd = priv;
|
||||
int index;
|
||||
int len;
|
||||
|
||||
switch (type) {
|
||||
case V4L2_DEBUGFS_IF_AVI:
|
||||
index = 0;
|
||||
break;
|
||||
case V4L2_DEBUGFS_IF_AUDIO:
|
||||
index = 1;
|
||||
break;
|
||||
case V4L2_DEBUGFS_IF_SPD:
|
||||
index = 2;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
len = read_infoframe(sd, &cri[index], buf);
|
||||
if (len > 0)
|
||||
len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
|
||||
return len < 0 ? 0 : len;
|
||||
}
|
||||
|
||||
static int adv7511_registered(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7511_state *state = get_adv7511_state(sd);
|
||||
|
|
@ -1700,9 +1746,16 @@ static int adv7511_registered(struct v4l2_subdev *sd)
|
|||
int err;
|
||||
|
||||
err = cec_register_adapter(state->cec_adap, &client->dev);
|
||||
if (err)
|
||||
if (err) {
|
||||
cec_delete_adapter(state->cec_adap);
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
|
||||
state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
|
||||
state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
|
||||
V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
|
||||
V4L2_DEBUGFS_IF_SPD, sd, adv7511_debugfs_if_read);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adv7511_unregistered(struct v4l2_subdev *sd)
|
||||
|
|
@ -1710,6 +1763,10 @@ static void adv7511_unregistered(struct v4l2_subdev *sd)
|
|||
struct adv7511_state *state = get_adv7511_state(sd);
|
||||
|
||||
cec_unregister_adapter(state->cec_adap);
|
||||
v4l2_debugfs_if_free(state->infoframes);
|
||||
state->infoframes = NULL;
|
||||
debugfs_remove_recursive(state->debugfs_dir);
|
||||
state->debugfs_dir = NULL;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops adv7511_int_ops = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user