/*
 * Copyright 2009-2015 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

/*!
 * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
 */

/*!
 * @file mxc_edid.c
 *
 * @brief MXC EDID driver
 *
 * @ingroup Framebuffer
 */

/*!
 * Include files
 */
#include <linux/i2c.h>
#include <linux/fb.h>
#include <video/mxc_edid.h>
#include "../edid.h"

#undef DEBUG  /* define this for verbose EDID parsing output */
#ifdef DEBUG
#define DPRINTK(fmt, args...) printk(fmt, ## args)
#else
#define DPRINTK(fmt, args...)
#endif

const struct fb_videomode mxc_cea_mode[64] = {
	/* #1: 640x480p@59.94/60Hz 4:3 */
	[1] = {
		NULL, 60, 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #2: 720x480p@59.94/60Hz 4:3 */
	[2] = {
		NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #3: 720x480p@59.94/60Hz 16:9 */
	[3] = {
		NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #4: 1280x720p@59.94/60Hz 16:9 */
	[4] = {
		NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
	},
	/* #5: 1920x1080i@59.94/60Hz 16:9 */
	[5] = {
		NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
	[6] = {
		NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
		FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
	[7] = {
		NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
		FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
	[8] = {
		NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
	[9] = {
		NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #14: 1440x480p@59.94/60Hz 4:3 */
	[14] = {
		NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #15: 1440x480p@59.94/60Hz 16:9 */
	[15] = {
		NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #16: 1920x1080p@60Hz 16:9 */
	[16] = {
		NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #17: 720x576pH@50Hz 4:3 */
	[17] = {
		NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #18: 720x576pH@50Hz 16:9 */
	[18] = {
		NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #19: 1280x720p@50Hz */
	[19] = {
		NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #20: 1920x1080i@50Hz */
	[20] = {
		NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #23: 720(1440)x288pH@50Hz 4:3 */
	[23] = {
		NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #24: 720(1440)x288pH@50Hz 16:9 */
	[24] = {
		NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #29: 720(1440)x576pH@50Hz 4:3 */
	[29] = {
		NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
	},
	/* #30: 720(1440)x576pH@50Hz 16:9 */
	[30] = {
		NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #31: 1920x1080p@50Hz */
	[31] = {
		NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #32: 1920x1080p@23.98/24Hz */
	[32] = {
		NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #33: 1920x1080p@25Hz */
	[33] = {
		NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #34: 1920x1080p@30Hz */
	[34] = {
		NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
	},
	/* #41: 1280x720p@100Hz 16:9 */
	[41] = {
		NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
	},
	/* #47: 1280x720p@119.88/120Hz 16:9 */
	[47] = {
		NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
	},
};

/*
 * We have a special version of fb_mode_is_equal that ignores
 * pixclock, since for many CEA modes, 2 frequencies are supported
 * e.g. 640x480 @ 60Hz or 59.94Hz
 */
int mxc_edid_fb_mode_is_equal(bool use_aspect,
			const struct fb_videomode *mode1,
			const struct fb_videomode *mode2)
{
	u32 mask;

	if (use_aspect)
		mask = ~0;
	else
		mask = ~FB_VMODE_ASPECT_MASK;

	return (mode1->xres         == mode2->xres &&
		mode1->yres         == mode2->yres &&
		mode1->hsync_len    == mode2->hsync_len &&
		mode1->vsync_len    == mode2->vsync_len &&
		mode1->left_margin  == mode2->left_margin &&
		mode1->right_margin == mode2->right_margin &&
		mode1->upper_margin == mode2->upper_margin &&
		mode1->lower_margin == mode2->lower_margin &&
		mode1->sync         == mode2->sync &&
		/* refresh check, 59.94Hz and 60Hz have the same parameter
		 * in struct of mxc_cea_mode */
		abs(mode1->refresh - mode2->refresh) <= 1 &&
		(mode1->vmode & mask) == (mode2->vmode & mask));
}

static void get_detailed_timing(unsigned char *block,
				struct fb_videomode *mode)
{
	mode->xres = H_ACTIVE;
	mode->yres = V_ACTIVE;
	mode->pixclock = PIXEL_CLOCK;
	mode->pixclock /= 1000;
	mode->pixclock = KHZ2PICOS(mode->pixclock);
	mode->right_margin = H_SYNC_OFFSET;
	mode->left_margin = (H_ACTIVE + H_BLANKING) -
		(H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
	mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
		V_SYNC_WIDTH;
	mode->lower_margin = V_SYNC_OFFSET;
	mode->hsync_len = H_SYNC_WIDTH;
	mode->vsync_len = V_SYNC_WIDTH;
	if (HSYNC_POSITIVE)
		mode->sync |= FB_SYNC_HOR_HIGH_ACT;
	if (VSYNC_POSITIVE)
		mode->sync |= FB_SYNC_VERT_HIGH_ACT;
	mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
				     (V_ACTIVE + V_BLANKING));
	if (INTERLACED) {
		mode->yres *= 2;
		mode->upper_margin *= 2;
		mode->lower_margin *= 2;
		mode->vsync_len *= 2;
		mode->vmode |= FB_VMODE_INTERLACED;
	}
	mode->flag = FB_MODE_IS_DETAILED;

	if ((H_SIZE / 16) == (V_SIZE / 9))
		mode->vmode |= FB_VMODE_ASPECT_16_9;
	else if ((H_SIZE / 4) == (V_SIZE / 3))
		mode->vmode |= FB_VMODE_ASPECT_4_3;
	else if ((mode->xres / 16) == (mode->yres / 9))
		mode->vmode |= FB_VMODE_ASPECT_16_9;
	else if ((mode->xres / 4) == (mode->yres / 3))
		mode->vmode |= FB_VMODE_ASPECT_4_3;

	if (mode->vmode & FB_VMODE_ASPECT_16_9)
		DPRINTK("Aspect ratio: 16:9\n");
	if (mode->vmode & FB_VMODE_ASPECT_4_3)
		DPRINTK("Aspect ratio: 4:3\n");
	DPRINTK("      %d MHz ",  PIXEL_CLOCK/1000000);
	DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
	       H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
	DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
	       V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
	DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
	       (VSYNC_POSITIVE) ? "+" : "-");
}

int mxc_edid_parse_ext_blk(unsigned char *edid,
		struct mxc_edid_cfg *cfg,
		struct fb_monspecs *specs)
{
	char detail_timing_desc_offset;
	struct fb_videomode *mode, *m;
	unsigned char index = 0x0;
	unsigned char *block;
	int i, num = 0, revision;

	if (edid[index++] != 0x2) /* only support cea ext block now */
		return 0;
	revision = edid[index++];
	DPRINTK("cea extent revision %d\n", revision);
	mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
	if (mode == NULL)
		return -1;

	detail_timing_desc_offset = edid[index++];

	if (revision >= 2) {
		cfg->cea_underscan = (edid[index] >> 7) & 0x1;
		cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
		cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
		cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;

		DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
		DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
		DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
		DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
	}

	if (revision >= 3) {
		/* short desc */
		DPRINTK("CEA Short desc timmings\n");
		index++;
		while (index < detail_timing_desc_offset) {
			unsigned char tagcode, blklen;

			tagcode = (edid[index] >> 5) & 0x7;
			blklen = (edid[index]) & 0x1f;

			DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);

			switch (tagcode) {
			case 0x2: /*Video data block*/
				{
					int cea_idx;
					i = 0;
					while (i < blklen) {
						index++;
						cea_idx = edid[index] & 0x7f;
						if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
								(mxc_cea_mode[cea_idx].xres)) {
							DPRINTK("Support CEA Format #%d\n", cea_idx);
							mode[num] = mxc_cea_mode[cea_idx];
							mode[num].flag |= FB_MODE_IS_STANDARD;
							num++;
						}
						i++;
					}
					break;
				}
			case 0x3: /*Vendor specific data*/
				{
					unsigned char IEEE_reg_iden[3];
					unsigned char deep_color;
					unsigned char latency_present;
					unsigned char I_latency_present;
					unsigned char hdmi_video_present;
					unsigned char hdmi_3d_present;
					unsigned char hdmi_3d_multi_present;
					unsigned char hdmi_vic_len;
					unsigned char hdmi_3d_len;
					unsigned char index_inc = 0;
					unsigned char vsd_end;

					vsd_end = index + blklen;

					IEEE_reg_iden[0] = edid[index+1];
					IEEE_reg_iden[1] = edid[index+2];
					IEEE_reg_iden[2] = edid[index+3];
					cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
					cfg->physical_address[1] = (edid[index+4] & 0x0f);
					cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
					cfg->physical_address[3] = (edid[index+5] & 0x0f);

					if ((IEEE_reg_iden[0] == 0x03) &&
							(IEEE_reg_iden[1] == 0x0c) &&
							(IEEE_reg_iden[2] == 0x00))
						cfg->hdmi_cap = 1;

					if (blklen > 5) {
						deep_color = edid[index+6];
						if (deep_color & 0x80)
							cfg->vsd_support_ai = true;
						if (deep_color & 0x40)
							cfg->vsd_dc_48bit = true;
						if (deep_color & 0x20)
							cfg->vsd_dc_36bit = true;
						if (deep_color & 0x10)
							cfg->vsd_dc_30bit = true;
						if (deep_color & 0x08)
							cfg->vsd_dc_y444 = true;
						if (deep_color & 0x01)
							cfg->vsd_dvi_dual = true;
					}

					DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
					DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
					DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
					DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
					DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
					DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
					DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);

					if (blklen > 6)
						cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
					DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);

					if (blklen > 7) {
						latency_present = edid[index+8] >> 7;
						I_latency_present =  (edid[index+8] & 0x40) >> 6;
						hdmi_video_present = (edid[index+8] & 0x20) >> 5;
						cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
						cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
						cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
						cfg->vsd_cnc0 = edid[index+8] & 0x1;

						DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
						DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
						DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
						DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
						DPRINTK("latency_present %d\n", latency_present);
						DPRINTK("I_latency_present %d\n", I_latency_present);
						DPRINTK("hdmi_video_present %d\n", hdmi_video_present);

					} else {
						index += blklen;
						break;
					}

					index += 9;

					/*latency present */
					if (latency_present) {
						cfg->vsd_video_latency = edid[index++];
						cfg->vsd_audio_latency = edid[index++];

						if (I_latency_present) {
							cfg->vsd_I_video_latency = edid[index++];
							cfg->vsd_I_audio_latency = edid[index++];
						} else {
							cfg->vsd_I_video_latency = cfg->vsd_video_latency;
							cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
						}

						DPRINTK("VSD latency video_latency  %d\n", cfg->vsd_video_latency);
						DPRINTK("VSD latency audio_latency  %d\n", cfg->vsd_audio_latency);
						DPRINTK("VSD latency I_video_latency  %d\n", cfg->vsd_I_video_latency);
						DPRINTK("VSD latency I_audio_latency  %d\n", cfg->vsd_I_audio_latency);
					}

					if (hdmi_video_present) {
						hdmi_3d_present = edid[index] >> 7;
						hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
						index++;
						hdmi_vic_len = (edid[index] & 0xe0) >> 5;
						hdmi_3d_len = edid[index] & 0x1f;
						index++;

						DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
						DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
						DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
						DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);

						if (hdmi_vic_len > 0) {
							for (i = 0; i < hdmi_vic_len; i++) {
								cfg->hdmi_vic[i] = edid[index++];
								DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
							}
						}

						if (hdmi_3d_len > 0) {
							if (hdmi_3d_present) {
								if (hdmi_3d_multi_present == 0x1) {
									cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
									index_inc = 2;
								} else if (hdmi_3d_multi_present == 0x2) {
									cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
									cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
									index_inc = 4;
								} else
									index_inc = 0;
							}

							DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
							DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);

							/* Read 2D vic 3D_struct */
							if ((hdmi_3d_len - index_inc) > 0) {
								DPRINTK("Support 3D video format\n");
								i = 0;
								while ((hdmi_3d_len - index_inc) > 0) {

									cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
									cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
									index_inc++;

									if (cfg->hdmi_3d_format[i].struct_3d ==  8) {
										cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
										index_inc++;
									} else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
										cfg->hdmi_3d_format[i].detail_3d = 0;
										index_inc++;
									}

									DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
											cfg->hdmi_3d_format[i].vic_order_2d,
											cfg->hdmi_3d_format[i].struct_3d,
											cfg->hdmi_3d_format[i].detail_3d);
									i++;
								}
							}
							index += index_inc;
						}
					}

					index = vsd_end;

					break;
				}
			case 0x1: /*Audio data block*/
				{
					u8 audio_format, max_ch, byte1, byte2, byte3;

					i = 0;
					cfg->max_channels = 0;
					cfg->sample_rates = 0;
					cfg->sample_sizes = 0;

					while (i < blklen) {
						byte1 = edid[index + 1];
						byte2 = edid[index + 2];
						byte3 = edid[index + 3];
						index += 3;
						i += 3;

						audio_format = byte1 >> 3;
						max_ch = (byte1 & 0x07) + 1;

						DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
						DPRINTK("Max Number of Channels  : %2d\n", max_ch);
						DPRINTK("Sample Rates            : %02x\n", byte2);

						/* ALSA can't specify specific compressed
						 * formats, so only care about PCM for now. */
						if (audio_format == AUDIO_CODING_TYPE_LPCM) {
							if (max_ch > cfg->max_channels)
								cfg->max_channels = max_ch;

							cfg->sample_rates |= byte2;
							cfg->sample_sizes |= byte3 & 0x7;
							DPRINTK("Sample Sizes            : %02x\n",
								byte3 & 0x7);
						}
					}
					break;
				}
			case 0x4: /*Speaker allocation block*/
				{
					i = 0;
					while (i < blklen) {
						cfg->speaker_alloc = edid[index + 1];
						index += 3;
						i += 3;
						DPRINTK("Speaker Alloc           : %02x\n", cfg->speaker_alloc);
					}
					break;
				}
			case 0x7: /*User extended block*/
			default:
				/* skip */
				DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
				index += blklen;
				break;
			}

			index++;
		}
	}

	/* long desc */
	DPRINTK("CEA long desc timmings\n");
	index = detail_timing_desc_offset;
	block = edid + index;
	while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
		if (!(block[0] == 0x00 && block[1] == 0x00)) {
			get_detailed_timing(block, &mode[num]);
			num++;
		}
		block += DETAILED_TIMING_DESCRIPTION_SIZE;
		index += DETAILED_TIMING_DESCRIPTION_SIZE;
	}

	if (!num) {
		kfree(mode);
		return 0;
	}

	m = kmalloc((num + specs->modedb_len) *
			sizeof(struct fb_videomode), GFP_KERNEL);
	if (!m) {
		kfree(mode);
		return 0;
	}

	if (specs->modedb_len) {
		memmove(m, specs->modedb,
			specs->modedb_len * sizeof(struct fb_videomode));
		kfree(specs->modedb);
	}
	memmove(m+specs->modedb_len, mode,
		num * sizeof(struct fb_videomode));
	kfree(mode);

	specs->modedb_len += num;
	specs->modedb = m;

	return 0;
}
EXPORT_SYMBOL(mxc_edid_parse_ext_blk);

static int mxc_edid_readblk(struct i2c_adapter *adp,
		unsigned short addr, unsigned char *edid)
{
	int ret = 0, extblknum = 0;
	unsigned char regaddr = 0x0;
	struct i2c_msg msg[2] = {
		{
		.addr	= addr,
		.flags	= 0,
		.len	= 1,
		.buf	= &regaddr,
		}, {
		.addr	= addr,
		.flags	= I2C_M_RD,
		.len	= EDID_LENGTH,
		.buf	= edid,
		},
	};

	ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
	if (ret != ARRAY_SIZE(msg)) {
		DPRINTK("unable to read EDID block\n");
		return -EIO;
	}

	if (edid[1] == 0x00)
		return -ENOENT;

	extblknum = edid[0x7E];

	if (extblknum) {
		regaddr = 128;
		msg[1].buf = edid + EDID_LENGTH;

		ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
		if (ret != ARRAY_SIZE(msg)) {
			DPRINTK("unable to read EDID ext block\n");
			return -EIO;
		}
	}

	return extblknum;
}

static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
			unsigned char *edid, int seg_num)
{
	int ret = 0;
	unsigned char segment = 0x1, regaddr = 0;
	struct i2c_msg msg[3] = {
		{
		.addr	= 0x30,
		.flags	= 0,
		.len	= 1,
		.buf	= &segment,
		}, {
		.addr	= addr,
		.flags	= 0,
		.len	= 1,
		.buf	= &regaddr,
		}, {
		.addr	= addr,
		.flags	= I2C_M_RD,
		.len	= EDID_LENGTH,
		.buf	= edid,
		},
	};

	ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
	if (ret != ARRAY_SIZE(msg)) {
		DPRINTK("unable to read EDID block\n");
		return -EIO;
	}

	if (seg_num == 2) {
		regaddr = 128;
		msg[2].buf = edid + EDID_LENGTH;

		ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
		if (ret != ARRAY_SIZE(msg)) {
			DPRINTK("unable to read EDID block\n");
			return -EIO;
		}
	}

	return ret;
}

int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
{
	int i;
	struct fb_videomode m;

	for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
		fb_var_to_videomode(&m, var);
		if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
			break;
	}

	if (i == ARRAY_SIZE(mxc_cea_mode))
		return 0;

	return i;
}
EXPORT_SYMBOL(mxc_edid_var_to_vic);

int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
{
	int i;
	bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);

	for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
		if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
			break;
	}

	if (i == ARRAY_SIZE(mxc_cea_mode))
		return 0;

	return i;
}
EXPORT_SYMBOL(mxc_edid_mode_to_vic);

/* make sure edid has 512 bytes*/
int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
	unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
{
	int ret = 0, extblknum;
	if (!adp || !edid || !cfg || !fbi)
		return -EINVAL;

	memset(edid, 0, EDID_LENGTH*4);
	memset(cfg, 0, sizeof(struct mxc_edid_cfg));

	extblknum = mxc_edid_readblk(adp, addr, edid);
	if (extblknum < 0)
		return extblknum;

	/* edid first block parsing */
	memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
	fb_edid_to_monspecs(edid, &fbi->monspecs);

	if (extblknum) {
		int i;

		/* FIXME: mxc_edid_readsegblk() won't read more than 2 blocks
		 * and the for-loop will read past the end of the buffer! :-( */
		if (extblknum > 3) {
			WARN_ON(true);
			return -EINVAL;
		}

		/* need read segment block? */
		if (extblknum > 1) {
			ret = mxc_edid_readsegblk(adp, addr,
				edid + EDID_LENGTH*2, extblknum - 1);
			if (ret < 0)
				return ret;
		}

		for (i = 1; i <= extblknum; i++)
			/* edid ext block parsing */
			mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
					cfg, &fbi->monspecs);
	}

	return 0;
}
EXPORT_SYMBOL(mxc_edid_read);

