Loading drivers/media/i2c/adv7842.c +88 −32 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ struct adv7842_state { bool restart_stdi_once; bool hdmi_port_a; struct dentry *debugfs_dir; struct v4l2_debugfs_if *infoframes; /* i2c clients */ struct i2c_client *i2c_sdp_io; struct i2c_client *i2c_sdp; Loading Loading @@ -2565,58 +2568,65 @@ struct adv7842_cfg_read_infoframe { u8 payload_addr; }; static void log_infoframe(struct v4l2_subdev *sd, const struct adv7842_cfg_read_infoframe *cri) static const struct adv7842_cfg_read_infoframe adv7842_cri[] = { { "AVI", 0x01, 0xe0, 0x00 }, { "Audio", 0x02, 0xe3, 0x1c }, { "SDP", 0x04, 0xe6, 0x2a }, { "Vendor", 0x10, 0xec, 0x54 } }; static int adv7842_read_infoframe_buf(struct v4l2_subdev *sd, int index, u8 buf[V4L2_DEBUGFS_IF_MAX_LEN]) { int i; u8 buffer[32]; union hdmi_infoframe frame; u8 len; struct i2c_client *client = v4l2_get_subdevdata(sd); struct device *dev = &client->dev; const struct adv7842_cfg_read_infoframe *cri = &adv7842_cri[index]; int len, i; if (!(io_read(sd, 0x60) & cri->present_mask)) { v4l2_info(sd, "%s infoframe not received\n", cri->desc); return; v4l2_dbg(1, debug, sd, "%s infoframe not received\n", cri->desc); return -ENOENT; } for (i = 0; i < 3; i++) buffer[i] = infoframe_read(sd, cri->head_addr + i); buf[i] = infoframe_read(sd, cri->head_addr + i); len = buffer[2] + 1; len = buf[2] + 1; if (len + 3 > sizeof(buffer)) { v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len); return; if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) { v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len); return -ENOENT; } for (i = 0; i < len; i++) buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i); if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } hdmi_infoframe_log(KERN_INFO, dev, &frame); buf[i + 3] = infoframe_read(sd, cri->payload_addr + i); return len + 3; } static void adv7842_log_infoframes(struct v4l2_subdev *sd) { int i; static const struct adv7842_cfg_read_infoframe cri[] = { { "AVI", 0x01, 0xe0, 0x00 }, { "Audio", 0x02, 0xe3, 0x1c }, { "SDP", 0x04, 0xe6, 0x2a }, { "Vendor", 0x10, 0xec, 0x54 } }; struct i2c_client *client = v4l2_get_subdevdata(sd); struct device *dev = &client->dev; union hdmi_infoframe frame; u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {}; int len, i; if (!(hdmi_read(sd, 0x05) & 0x80)) { v4l2_info(sd, "receive DVI-D signal, no infoframes\n"); return; } for (i = 0; i < ARRAY_SIZE(cri); i++) log_infoframe(sd, &cri[i]); for (i = 0; i < ARRAY_SIZE(adv7842_cri); i++) { len = adv7842_read_infoframe_buf(sd, i, buffer); if (len < 0) continue; if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, adv7842_cri[i].desc); else hdmi_infoframe_log(KERN_INFO, dev, &frame); } } #if 0 Loading Loading @@ -3263,6 +3273,41 @@ static int adv7842_subscribe_event(struct v4l2_subdev *sd, } } static ssize_t adv7842_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; if (!is_hdmi(sd)) return 0; 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; case V4L2_DEBUGFS_IF_HDMI: index = 3; break; default: return 0; } len = adv7842_read_infoframe_buf(sd, index, buf); if (len > 0) len = simple_read_from_buffer(ubuf, count, ppos, buf, len); return len < 0 ? 0 : len; } static int adv7842_registered(struct v4l2_subdev *sd) { struct adv7842_state *state = to_state(sd); Loading @@ -3270,8 +3315,15 @@ static int adv7842_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); } else { 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 | V4L2_DEBUGFS_IF_HDMI, sd, adv7842_debugfs_if_read); } return err; } Loading @@ -3280,6 +3332,10 @@ static void adv7842_unregistered(struct v4l2_subdev *sd) struct adv7842_state *state = to_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; } /* ----------------------------------------------------------------------- */ Loading Loading
drivers/media/i2c/adv7842.c +88 −32 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ struct adv7842_state { bool restart_stdi_once; bool hdmi_port_a; struct dentry *debugfs_dir; struct v4l2_debugfs_if *infoframes; /* i2c clients */ struct i2c_client *i2c_sdp_io; struct i2c_client *i2c_sdp; Loading Loading @@ -2565,58 +2568,65 @@ struct adv7842_cfg_read_infoframe { u8 payload_addr; }; static void log_infoframe(struct v4l2_subdev *sd, const struct adv7842_cfg_read_infoframe *cri) static const struct adv7842_cfg_read_infoframe adv7842_cri[] = { { "AVI", 0x01, 0xe0, 0x00 }, { "Audio", 0x02, 0xe3, 0x1c }, { "SDP", 0x04, 0xe6, 0x2a }, { "Vendor", 0x10, 0xec, 0x54 } }; static int adv7842_read_infoframe_buf(struct v4l2_subdev *sd, int index, u8 buf[V4L2_DEBUGFS_IF_MAX_LEN]) { int i; u8 buffer[32]; union hdmi_infoframe frame; u8 len; struct i2c_client *client = v4l2_get_subdevdata(sd); struct device *dev = &client->dev; const struct adv7842_cfg_read_infoframe *cri = &adv7842_cri[index]; int len, i; if (!(io_read(sd, 0x60) & cri->present_mask)) { v4l2_info(sd, "%s infoframe not received\n", cri->desc); return; v4l2_dbg(1, debug, sd, "%s infoframe not received\n", cri->desc); return -ENOENT; } for (i = 0; i < 3; i++) buffer[i] = infoframe_read(sd, cri->head_addr + i); buf[i] = infoframe_read(sd, cri->head_addr + i); len = buffer[2] + 1; len = buf[2] + 1; if (len + 3 > sizeof(buffer)) { v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len); return; if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) { v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len); return -ENOENT; } for (i = 0; i < len; i++) buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i); if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } hdmi_infoframe_log(KERN_INFO, dev, &frame); buf[i + 3] = infoframe_read(sd, cri->payload_addr + i); return len + 3; } static void adv7842_log_infoframes(struct v4l2_subdev *sd) { int i; static const struct adv7842_cfg_read_infoframe cri[] = { { "AVI", 0x01, 0xe0, 0x00 }, { "Audio", 0x02, 0xe3, 0x1c }, { "SDP", 0x04, 0xe6, 0x2a }, { "Vendor", 0x10, 0xec, 0x54 } }; struct i2c_client *client = v4l2_get_subdevdata(sd); struct device *dev = &client->dev; union hdmi_infoframe frame; u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {}; int len, i; if (!(hdmi_read(sd, 0x05) & 0x80)) { v4l2_info(sd, "receive DVI-D signal, no infoframes\n"); return; } for (i = 0; i < ARRAY_SIZE(cri); i++) log_infoframe(sd, &cri[i]); for (i = 0; i < ARRAY_SIZE(adv7842_cri); i++) { len = adv7842_read_infoframe_buf(sd, i, buffer); if (len < 0) continue; if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, adv7842_cri[i].desc); else hdmi_infoframe_log(KERN_INFO, dev, &frame); } } #if 0 Loading Loading @@ -3263,6 +3273,41 @@ static int adv7842_subscribe_event(struct v4l2_subdev *sd, } } static ssize_t adv7842_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; if (!is_hdmi(sd)) return 0; 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; case V4L2_DEBUGFS_IF_HDMI: index = 3; break; default: return 0; } len = adv7842_read_infoframe_buf(sd, index, buf); if (len > 0) len = simple_read_from_buffer(ubuf, count, ppos, buf, len); return len < 0 ? 0 : len; } static int adv7842_registered(struct v4l2_subdev *sd) { struct adv7842_state *state = to_state(sd); Loading @@ -3270,8 +3315,15 @@ static int adv7842_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); } else { 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 | V4L2_DEBUGFS_IF_HDMI, sd, adv7842_debugfs_if_read); } return err; } Loading @@ -3280,6 +3332,10 @@ static void adv7842_unregistered(struct v4l2_subdev *sd) struct adv7842_state *state = to_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; } /* ----------------------------------------------------------------------- */ Loading