/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <spi_qup.h>
#include <msm_panel.h>
#include <target/display.h>
#include <platform/gpio.h>

#define SUCCESS		0
#define FAIL		1

static struct qup_spi_dev *dev = NULL;

static int mdss_spi_write_cmd(const char *buf)
{
	int ret = 0;

	if (!dev) {
		dprintf(CRITICAL, "SPI has not been initialized\n");
		return -ENODEV;
	}

	dev->bytes_per_word = 1;
	dev->bit_shift_en = 1;

	gpio_set(spi_dc_gpio.pin_id, 0);
	ret = spi_qup_transfer(dev, buf, 1);
	gpio_set(spi_dc_gpio.pin_id, 2);
	if (ret)
		dprintf(CRITICAL, "Send SPI command to panel failed\n");

	return ret;
}

static int mdss_spi_write_data(const char *buf, size_t len)
{
	int ret = 0;

	if (!dev) {
		dprintf(CRITICAL, "SPI has not been initialized\n");
		return -ENODEV;
	}

	dev->bytes_per_word = 1;
	dev->bit_shift_en = 1;

	gpio_set(spi_dc_gpio.pin_id, 2);
	ret = spi_qup_transfer(dev, buf, len);
	if (ret)
		dprintf(CRITICAL, "Send SPI parameters to panel failed\n");

	return ret;
}

static int mdss_spi_write_frame(const char *buf, size_t len)
{
	int ret = 0;

	if (!dev) {
		dprintf(CRITICAL, "SPI has not been initialized\n");
		return -ENODEV;
	}

	dev->bytes_per_word = 2;
	dev->bit_shift_en = 1;
	dev->unpack_en = 0;

	gpio_set(spi_dc_gpio.pin_id, 2);
	ret = spi_qup_transfer(dev, buf, len);

	return ret;
}

static void spi_read_panel_data(unsigned char *buf,  int len)
{
	int ret = 0;

	if (!dev) {
		 dprintf(CRITICAL, "SPI has not been initialized\n");
		 return -ENODEV;
	}
	dev->bytes_per_word = 1;
	dev->bit_shift_en = 1;

	gpio_set(spi_dc_gpio.pin_id, 0);
	ret = spi_qup_transfer(dev, buf, len);
	gpio_set(spi_dc_gpio.pin_id, 2);

	if (ret)
		dprintf(CRITICAL, "Send SPI command to panel failed\n");

	return;
}

int mdss_spi_init(void)
{
	if (!dev) {
		dev = qup_blsp_spi_init(SPI_BLSP_ID, SPI_QUP_ID);
		if (!dev) {
			dprintf(CRITICAL, "Failed initializing SPI\n");
			return -ENODEV;
		}
	}

	gpio_tlmm_config(spi_dc_gpio.pin_id, 0, spi_dc_gpio.pin_direction,
			spi_dc_gpio.pin_pull, spi_dc_gpio.pin_strength,
			spi_dc_gpio.pin_state);
	return SUCCESS;
}

int mdss_spi_panel_init(struct msm_panel_info *pinfo)
{
	int cmd_count = 0;
	int ret = 0;

	while (cmd_count < pinfo->spi.num_of_panel_cmds) {
		if (pinfo->spi.panel_cmds[cmd_count].cmds_post_tg){
			cmd_count ++;
			continue;
		}

		mdss_spi_write_cmd(pinfo->spi.panel_cmds[cmd_count].payload);
		if (pinfo->spi.panel_cmds[cmd_count].size > 1)
			mdss_spi_write_data(
				pinfo->spi.panel_cmds[cmd_count].payload + 1,
				pinfo->spi.panel_cmds[cmd_count].size - 1);

		if (pinfo->spi.panel_cmds[cmd_count].wait)
			mdelay(pinfo->spi.panel_cmds[cmd_count].wait);

		cmd_count ++;
	}
	return SUCCESS;
}

int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb)
{
	int buf_size = 0;
	int ret = 0;

	buf_size =  fb->width * fb->height * (fb->bpp / 8);
	ret = mdss_spi_write_frame(fb->base, buf_size);
	if (ret)
		dprintf(CRITICAL, "Send SPI frame data to panel failed\n");

	return ret;
}

int mdss_spi_cmd_post_on(struct msm_panel_info *pinfo)
{
	int cmd_count = 0;
	char *payload;

	if (!dev) {
		dprintf(CRITICAL, "SPI has not been initialized\n");
		return -ENODEV;
	}

	while (cmd_count < pinfo->spi.num_of_panel_cmds) {
		if (pinfo->spi.panel_cmds[cmd_count].cmds_post_tg){
			payload = pinfo->spi.panel_cmds[cmd_count].payload;
			mdss_spi_write_cmd(payload);
			if (pinfo->spi.panel_cmds[cmd_count].size > 1)
				mdss_spi_write_data(payload + 1,
					pinfo->spi.panel_cmds[cmd_count].size
						- 1);

			if (pinfo->spi.panel_cmds[cmd_count].wait)
				mdelay(pinfo->spi.panel_cmds[cmd_count].wait);
		}

		cmd_count ++;
	}

	return SUCCESS;
}
