From 21c3cdc101e77e9f824650662d0beaecf542802f Mon Sep 17 00:00:00 2001
From: Suprith Malligere Shankaregowda <supgow@codeaurora.org>
Date: Sat, 7 Jul 2018 15:23:34 +0530
Subject: [PATCH] adv7481: Fix AVI infoframe read

Change the AVI infoframe read to check avi_info_raw bit in
hdmi lvl raw status register instead of new_avi_info_raw
in hdmi edg raw status register. This is required so as not
to miss AVI infoframes if we disconnect and reconnect the
HDMI cable or close and reopen the application. Also return
error if no AVI infoframe is found and change some error
logs to be more specific.

Change-Id: If30ba820d255149f1b54f422b8e075e634271aaf
Signed-off-by: Suprith Malligere Shankaregowda <supgow@codeaurora.org>
---
 drivers/media/i2c/adv7481.c     | 16 +++++++++-------
 drivers/media/i2c/adv7481_reg.h |  4 ++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/media/i2c/adv7481.c b/drivers/media/i2c/adv7481.c
index 713a47cfea7f..eb2b37ce1095 100644
--- a/drivers/media/i2c/adv7481.c
+++ b/drivers/media/i2c/adv7481.c
@@ -1134,11 +1134,12 @@ static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 	case VIDIOC_G_AVI_INFOFRAME: {
 		int int_raw = adv7481_rd_byte(&state->i2c_client,
 			state->i2c_io_addr,
-			IO_HDMI_EDG_RAW_STATUS_1_ADDR);
+			IO_HDMI_LVL_RAW_STATUS_1_ADDR);
 		adv7481_wr_byte(&state->i2c_client,
 			state->i2c_io_addr,
-			IO_HDMI_EDG_INT_CLEAR_1_ADDR, int_raw);
-		if (ADV_REG_GETFIELD(int_raw, IO_NEW_AVI_INFO_RAW)) {
+			IO_HDMI_LVL_INT_CLEAR_1_ADDR, int_raw);
+		pr_debug("%s: VIDIOC_G_AVI_INFOFRAME\n", __func__);
+		if (ADV_REG_GETFIELD(int_raw, IO_AVI_INFO_RAW)) {
 			inf_buffer[0] = adv7481_rd_byte(&state->i2c_client,
 				state->i2c_hdmi_inf_addr,
 				HDMI_REG_AVI_PACKET_ID_ADDR);
@@ -1154,13 +1155,13 @@ static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 				&inf_buffer[3],
 				INFOFRAME_DATA_SIZE);
 			if (ret) {
-				pr_err("%s:Error in VIDIOC_G_AVI_INFOFRAME\n",
+				pr_err("%s: Error in reading AVI Infoframe\n",
 						__func__);
 				return -EINVAL;
 			}
 			if (hdmi_infoframe_unpack(&hdmi_info_frame,
 					(void *)inf_buffer) < 0) {
-				pr_err("%s: infoframe unpack fail\n", __func__);
+				pr_err("%s: Infoframe unpack fail\n", __func__);
 				return -EINVAL;
 			}
 			hdmi_infoframe_log(KERN_ERR, dev, &hdmi_info_frame);
@@ -1173,12 +1174,13 @@ static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 			state->hdmi_avi_infoframe.video_code =
 				hdmi_info_frame.avi.video_code;
 		} else {
-			pr_err("%s: No new AVI Infoframe\n", __func__);
+			pr_err("%s: No AVI Infoframe\n", __func__);
+			return -EINVAL;
 		}
 		if (copy_to_user((void __user *)adv_arg.ptr,
 				(void *)&state->hdmi_avi_infoframe,
 				sizeof(struct avi_infoframe_params))) {
-			pr_err("%s: Failed to copy Infoframe\n", __func__);
+			pr_err("%s: Failed to copy AVI Infoframe\n", __func__);
 			return -EINVAL;
 		}
 		break;
diff --git a/drivers/media/i2c/adv7481_reg.h b/drivers/media/i2c/adv7481_reg.h
index 403e538b6127..e1984f17d125 100644
--- a/drivers/media/i2c/adv7481_reg.h
+++ b/drivers/media/i2c/adv7481_reg.h
@@ -73,6 +73,10 @@
 #define IO_CTRL_MASTER_PWDN_REG_VALUE           0x01
 
 /* Interrupts */
+#define IO_HDMI_LVL_RAW_STATUS_1_ADDR           0x67
+#define IO_AVI_INFO_RAW_BMSK                    0x0001
+#define IO_AVI_INFO_RAW_SHFT                    0
+
 #define IO_HDMI_LVL_INT_CLEAR_1_ADDR            0x69
 
 #define IO_HDMI_LVL_INT_MASKB_1_ADDR            0x6B