/*
 * Copyright (C) 2012 Samsung Electronics
 *
 * Author: Donghwa Lee <dh09.lee@samsung.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <asm/arch/mipi_dsim.h>

#include "exynos_mipi_dsi_lowlevel.h"
#include "exynos_mipi_dsi_common.h"

static void s6e8ax0_panel_cond(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x4c,
		0x6e, 0x10, 0x27, 0x7d, 0x3f, 0x10, 0x00, 0x00, 0x20,
		0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08,
		0x23, 0x23, 0xc0, 0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc3,
		0xff, 0xff, 0xc8
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_display_cond(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf2, 0x80, 0x03, 0x0d
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_gamma_cond(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	/* 7500K 2.2 Set : 30cd */
	const unsigned char data_to_send[] = {
		0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad,
		0xaf, 0xba, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1,
		0xdc, 0xc0, 0x00, 0x61, 0x00, 0x5a, 0x00, 0x74,
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_gamma_update(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xf7, 0x3);
}

static void s6e8ax0_etc_source_control(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf6, 0x00, 0x02, 0x00
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_etc_pentile_control(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
		0x00
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_etc_mipi_control1(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_etc_mipi_control2(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_etc_power_control(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_etc_mipi_control3(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xe3, 0x40);
}

static void s6e8ax0_etc_mipi_control4(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_elvss_set(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xb1, 0x04, 0x00
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
			(unsigned int)data_to_send,
			ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_display_on(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;

	ops->cmd_write(dsim_dev,
		MIPI_DSI_DCS_SHORT_WRITE, 0x29, 0x00);
}

static void s6e8ax0_sleep_out(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;

	ops->cmd_write(dsim_dev,
		MIPI_DSI_DCS_SHORT_WRITE, 0x11, 0x00);
}

static void s6e8ax0_apply_level1_key(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf0, 0x5a, 0x5a
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_apply_mtp_key(struct mipi_dsim_device *dsim_dev)
{
	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
	const unsigned char data_to_send[] = {
		0xf1, 0x5a, 0x5a
	};

	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
}

static void s6e8ax0_panel_init(struct mipi_dsim_device *dsim_dev)
{
	/*
	 * in case of setting gamma and panel condition at first,
	 * it shuold be setting like below.
	 * set_gamma() -> set_panel_condition()
	 */

	s6e8ax0_apply_level1_key(dsim_dev);
	s6e8ax0_apply_mtp_key(dsim_dev);

	s6e8ax0_sleep_out(dsim_dev);
	mdelay(5);
	s6e8ax0_panel_cond(dsim_dev);
	s6e8ax0_display_cond(dsim_dev);
	s6e8ax0_gamma_cond(dsim_dev);
	s6e8ax0_gamma_update(dsim_dev);

	s6e8ax0_etc_source_control(dsim_dev);
	s6e8ax0_elvss_set(dsim_dev);
	s6e8ax0_etc_pentile_control(dsim_dev);
	s6e8ax0_etc_mipi_control1(dsim_dev);
	s6e8ax0_etc_mipi_control2(dsim_dev);
	s6e8ax0_etc_power_control(dsim_dev);
	s6e8ax0_etc_mipi_control3(dsim_dev);
	s6e8ax0_etc_mipi_control4(dsim_dev);
}

static int s6e8ax0_panel_set(struct mipi_dsim_device *dsim_dev)
{
	s6e8ax0_panel_init(dsim_dev);

	return 0;
}

static void s6e8ax0_display_enable(struct mipi_dsim_device *dsim_dev)
{
	s6e8ax0_display_on(dsim_dev);
}

static struct mipi_dsim_lcd_driver s6e8ax0_dsim_ddi_driver = {
	.name = "s6e8ax0",
	.id = -1,

	.mipi_panel_init = s6e8ax0_panel_set,
	.mipi_display_on = s6e8ax0_display_enable,
};

void s6e8ax0_init(void)
{
	exynos_mipi_dsi_register_lcd_driver(&s6e8ax0_dsim_ddi_driver);
}
