Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] adv7604: log infoframes

Add support for logging the detected InfoFrames for the adv76xx. Helps in
debugging what is actually received on the HDMI link.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
516613c1 b4dbad8f

+63 -33
+1
drivers/media/i2c/Kconfig
··· 197 197 config VIDEO_ADV7604 198 198 tristate "Analog Devices ADV7604 decoder" 199 199 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && GPIOLIB 200 + select HDMI 200 201 ---help--- 201 202 Support for the Analog Devices ADV7604 video decoder. 202 203
+62 -33
drivers/media/i2c/adv7604.c
··· 29 29 30 30 #include <linux/delay.h> 31 31 #include <linux/gpio/consumer.h> 32 + #include <linux/hdmi.h> 32 33 #include <linux/i2c.h> 33 34 #include <linux/kernel.h> 34 35 #include <linux/module.h> ··· 94 93 bool rgb_out; 95 94 bool swap_cb_cr; 96 95 u8 op_format_sel; 96 + }; 97 + 98 + struct adv76xx_cfg_read_infoframe { 99 + const char *desc; 100 + u8 present_mask; 101 + u8 head_addr; 102 + u8 payload_addr; 97 103 }; 98 104 99 105 struct adv76xx_chip_info { ··· 2135 2127 2136 2128 /*********** avi info frame CEA-861-E **************/ 2137 2129 2138 - static void print_avi_infoframe(struct v4l2_subdev *sd) 2130 + static const struct adv76xx_cfg_read_infoframe adv76xx_cri[] = { 2131 + { "AVI", 0x01, 0xe0, 0x00 }, 2132 + { "Audio", 0x02, 0xe3, 0x1c }, 2133 + { "SDP", 0x04, 0xe6, 0x2a }, 2134 + { "Vendor", 0x10, 0xec, 0x54 } 2135 + }; 2136 + 2137 + static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index, 2138 + union hdmi_infoframe *frame) 2139 + { 2140 + uint8_t buffer[32]; 2141 + u8 len; 2142 + int i; 2143 + 2144 + if (!(io_read(sd, 0x60) & adv76xx_cri[index].present_mask)) { 2145 + v4l2_info(sd, "%s infoframe not received\n", 2146 + adv76xx_cri[index].desc); 2147 + return -ENOENT; 2148 + } 2149 + 2150 + for (i = 0; i < 3; i++) 2151 + buffer[i] = infoframe_read(sd, 2152 + adv76xx_cri[index].head_addr + i); 2153 + 2154 + len = buffer[2] + 1; 2155 + 2156 + if (len + 3 > sizeof(buffer)) { 2157 + v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, 2158 + adv76xx_cri[index].desc, len); 2159 + return -ENOENT; 2160 + } 2161 + 2162 + for (i = 0; i < len; i++) 2163 + buffer[i + 3] = infoframe_read(sd, 2164 + adv76xx_cri[index].payload_addr + i); 2165 + 2166 + if (hdmi_infoframe_unpack(frame, buffer) < 0) { 2167 + v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, 2168 + adv76xx_cri[index].desc); 2169 + return -ENOENT; 2170 + } 2171 + return 0; 2172 + } 2173 + 2174 + static void adv76xx_log_infoframes(struct v4l2_subdev *sd) 2139 2175 { 2140 2176 int i; 2141 - u8 buf[14]; 2142 - u8 avi_len; 2143 - u8 avi_ver; 2144 2177 2145 2178 if (!is_hdmi(sd)) { 2146 - v4l2_info(sd, "receive DVI-D signal (AVI infoframe not supported)\n"); 2147 - return; 2148 - } 2149 - if (!(io_read(sd, 0x60) & 0x01)) { 2150 - v4l2_info(sd, "AVI infoframe not received\n"); 2179 + v4l2_info(sd, "receive DVI-D signal, no infoframes\n"); 2151 2180 return; 2152 2181 } 2153 2182 2154 - if (io_read(sd, 0x83) & 0x01) { 2155 - v4l2_info(sd, "AVI infoframe checksum error has occurred earlier\n"); 2156 - io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */ 2157 - if (io_read(sd, 0x83) & 0x01) { 2158 - v4l2_info(sd, "AVI infoframe checksum error still present\n"); 2159 - io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */ 2160 - } 2183 + for (i = 0; i < ARRAY_SIZE(adv76xx_cri); i++) { 2184 + union hdmi_infoframe frame; 2185 + struct i2c_client *client = v4l2_get_subdevdata(sd); 2186 + 2187 + if (adv76xx_read_infoframe(sd, i, &frame)) 2188 + return; 2189 + hdmi_infoframe_log(KERN_INFO, &client->dev, &frame); 2161 2190 } 2162 - 2163 - avi_len = infoframe_read(sd, 0xe2); 2164 - avi_ver = infoframe_read(sd, 0xe1); 2165 - v4l2_info(sd, "AVI infoframe version %d (%d byte)\n", 2166 - avi_ver, avi_len); 2167 - 2168 - if (avi_ver != 0x02) 2169 - return; 2170 - 2171 - for (i = 0; i < 14; i++) 2172 - buf[i] = infoframe_read(sd, i); 2173 - 2174 - v4l2_info(sd, 2175 - "\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2176 - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], 2177 - buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); 2178 2191 } 2179 2192 2180 2193 static int adv76xx_log_status(struct v4l2_subdev *sd) ··· 2331 2302 2332 2303 v4l2_info(sd, "Deep color mode: %s\n", deep_color_mode_txt[(hdmi_read(sd, 0x0b) & 0x60) >> 5]); 2333 2304 2334 - print_avi_infoframe(sd); 2305 + adv76xx_log_infoframes(sd); 2335 2306 } 2336 2307 2337 2308 return 0;