Loading drivers/media/i2c/adv7511-v4l2.c +74 −17 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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 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 }, }; static void adv7511_log_infoframes(struct v4l2_subdev *sd) { int i; for (i = 0; i < ARRAY_SIZE(cri); i++) Loading Loading @@ -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); Loading @@ -1700,16 +1746,27 @@ 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; } 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) { 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 Loading
drivers/media/i2c/adv7511-v4l2.c +74 −17 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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 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 }, }; static void adv7511_log_infoframes(struct v4l2_subdev *sd) { int i; for (i = 0; i < ARRAY_SIZE(cri); i++) Loading Loading @@ -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); Loading @@ -1700,16 +1746,27 @@ 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; } 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) { 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