// SPDX-License-Identifier: GPL-2.0
/*
 * Synaptics R63353 Controller driver
 *
 * Copyright (C) 2020 BSH Hausgerate GmbH
 */

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/media-bus-format.h>

#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>

#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
#include <drm/drm_panel.h>

#include <video/mipi_display.h>

#define R63353_INSTR(...) { \
		.len = sizeof((u8[]) {__VA_ARGS__}), \
		.data = (u8[]){__VA_ARGS__} \
	}

struct r63353_instr {
	size_t len;
	const u8 *data;
};

static const struct r63353_instr sharp_ls068b3sx02_init[] = {
	R63353_INSTR(0x51, 0xff),
	R63353_INSTR(0x53, 0x0c),
	R63353_INSTR(0x55, 0x00),
	R63353_INSTR(0x84, 0x00),
	R63353_INSTR(0x29),
};

struct r63353_desc {
	const char *name;
	const struct r63353_instr *init;
	const size_t init_length;
	const struct drm_display_mode *mode;
	u32 width_mm;
	u32 height_mm;
};

struct r63353_panel {
	struct drm_panel base;
	struct mipi_dsi_device *dsi;

	struct gpio_desc *reset_gpio;
	struct regulator *dvdd;
	struct regulator *avdd;

	struct r63353_desc *pdata;
};

static inline struct r63353_panel *to_r63353_panel(struct drm_panel *panel)
{
	return container_of(panel, struct r63353_panel, base);
}

static int r63353_panel_power_on(struct r63353_panel *rpanel)
{
	struct mipi_dsi_device *dsi = rpanel->dsi;
	struct device *dev = &dsi->dev;
	int ret;

	ret = regulator_enable(rpanel->avdd);
	if (ret) {
		dev_err(dev, "Failed to enable avdd regulator (%d)\n", ret);
		return ret;
	}

	usleep_range(15000, 25000);

	ret = regulator_enable(rpanel->dvdd);
	if (ret) {
		dev_err(dev, "Failed to enable dvdd regulator (%d)\n", ret);
		regulator_disable(rpanel->avdd);
		return ret;
	}

	usleep_range(300000, 350000);
	gpiod_set_value(rpanel->reset_gpio, 1);
	usleep_range(15000, 25000);

	return 0;
}

static int r63353_panel_power_off(struct r63353_panel *rpanel)
{
	gpiod_set_value(rpanel->reset_gpio, 0);
	regulator_disable(rpanel->dvdd);
	regulator_disable(rpanel->avdd);

	return 0;
}

static int r63353_panel_activate(struct r63353_panel *rpanel)
{
	struct mipi_dsi_device *dsi = rpanel->dsi;
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
	int i;

	mipi_dsi_dcs_soft_reset_multi(&dsi_ctx);

	mipi_dsi_usleep_range(&dsi_ctx, 15000, 17000);

	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);

	for (i = 0; i < rpanel->pdata->init_length; i++) {
		const struct r63353_instr *instr = &rpanel->pdata->init[i];

		mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, instr->data,
						instr->len);
	}

	mipi_dsi_msleep(&dsi_ctx, 120);

	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);

	mipi_dsi_usleep_range(&dsi_ctx, 5000, 10000);

	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);

	if (dsi_ctx.accum_err)
		gpiod_set_value(rpanel->reset_gpio, 0);

	return dsi_ctx.accum_err;
}

static int r63353_panel_prepare(struct drm_panel *panel)
{
	struct r63353_panel *rpanel = to_r63353_panel(panel);
	struct mipi_dsi_device *dsi = rpanel->dsi;
	struct device *dev = &dsi->dev;
	int ret;

	dev_dbg(dev, "Preparing\n");

	ret = r63353_panel_power_on(rpanel);
	if (ret)
		return ret;

	ret = r63353_panel_activate(rpanel);
	if (ret) {
		r63353_panel_power_off(rpanel);
		return ret;
	}

	dev_dbg(dev, "Prepared\n");
	return 0;
}

static void r63353_panel_deactivate(struct r63353_panel *rpanel)
{
	struct mipi_dsi_device *dsi = rpanel->dsi;
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };

	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);

	mipi_dsi_usleep_range(&dsi_ctx, 5000, 10000);

	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
}

static int r63353_panel_unprepare(struct drm_panel *panel)
{
	struct r63353_panel *rpanel = to_r63353_panel(panel);

	r63353_panel_deactivate(rpanel);
	r63353_panel_power_off(rpanel);

	return 0;
}

static const struct drm_display_mode sharp_ls068b3sx02_timing = {
	.clock = 70000,
	.hdisplay = 640,
	.hsync_start = 640 + 35,
	.hsync_end = 640 + 35 + 2,
	.htotal = 640 + 35 + 2 + 150,
	.vdisplay = 1280,
	.vsync_start = 1280 + 2,
	.vsync_end = 1280 + 2 + 4,
	.vtotal = 1280 + 2 + 4 + 0,
};

static int r63353_panel_get_modes(struct drm_panel *panel,
				  struct drm_connector *connector)
{
	struct r63353_panel *rpanel = to_r63353_panel(panel);
	struct drm_display_mode *mode;
	static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;

	mode = drm_mode_duplicate(connector->dev, rpanel->pdata->mode);
	if (!mode)
		return -ENOMEM;

	drm_mode_set_name(mode);
	drm_mode_probed_add(connector, mode);

	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
	connector->display_info.width_mm = rpanel->pdata->width_mm;
	connector->display_info.height_mm = rpanel->pdata->height_mm;

	drm_display_info_set_bus_formats(&connector->display_info,
					 &bus_format, 1);

	return 1;
}

static const struct drm_panel_funcs r63353_panel_funcs = {
	.prepare = r63353_panel_prepare,
	.unprepare = r63353_panel_unprepare,
	.get_modes = r63353_panel_get_modes,
};

static int r63353_panel_probe(struct mipi_dsi_device *dsi)
{
	int ret = 0;
	struct device *dev = &dsi->dev;
	struct r63353_panel *panel;

	panel = devm_drm_panel_alloc(dev, struct r63353_panel, base,
				     &r63353_panel_funcs,
				     DRM_MODE_CONNECTOR_DSI);
	if (IS_ERR(panel))
		return PTR_ERR(panel);

	mipi_dsi_set_drvdata(dsi, panel);
	panel->dsi = dsi;
	panel->pdata = (struct r63353_desc *)of_device_get_match_data(dev);

	dev_info(dev, "Panel %s\n", panel->pdata->name);

	dsi->lanes = 2;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
			  MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM |
			  MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET;

	panel->dvdd = devm_regulator_get(dev, "dvdd");
	if (IS_ERR(panel->dvdd))
		return PTR_ERR(panel->dvdd);
	panel->avdd = devm_regulator_get(dev, "avdd");
	if (IS_ERR(panel->avdd))
		return PTR_ERR(panel->avdd);

	panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(panel->reset_gpio)) {
		dev_err(dev, "failed to get RESET GPIO\n");
		return PTR_ERR(panel->reset_gpio);
	}

	panel->base.prepare_prev_first = true;
	ret = drm_panel_of_backlight(&panel->base);
	if (ret)
		return ret;

	drm_panel_add(&panel->base);

	ret = mipi_dsi_attach(dsi);
	if (ret < 0) {
		dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
		drm_panel_remove(&panel->base);
		return ret;
	}

	return ret;
}

static void r63353_panel_remove(struct mipi_dsi_device *dsi)
{
	struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi);
	struct device *dev = &dsi->dev;
	int ret;

	ret = mipi_dsi_detach(dsi);
	if (ret < 0)
		dev_err(dev, "Failed to detach from host (%d)\n", ret);

	drm_panel_remove(&rpanel->base);
}

static void r63353_panel_shutdown(struct mipi_dsi_device *dsi)
{
	struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi);

	drm_panel_unprepare(&rpanel->base);
}

static const struct r63353_desc sharp_ls068b3sx02_data = {
	.name = "Sharp LS068B3SX02",
	.mode = &sharp_ls068b3sx02_timing,
	.init = sharp_ls068b3sx02_init,
	.init_length = ARRAY_SIZE(sharp_ls068b3sx02_init),
	.width_mm = 68,
	.height_mm = 159,
};

static const struct of_device_id r63353_of_match[] = {
	{ .compatible = "sharp,ls068b3sx02", .data = &sharp_ls068b3sx02_data },
	{ }
};

MODULE_DEVICE_TABLE(of, r63353_of_match);

static struct mipi_dsi_driver r63353_panel_driver = {
	.driver = {
		   .name = "r63353-dsi",
		   .of_match_table = r63353_of_match,
	},
	.probe = r63353_panel_probe,
	.remove = r63353_panel_remove,
	.shutdown = r63353_panel_shutdown,
};

module_mipi_dsi_driver(r63353_panel_driver);

MODULE_AUTHOR("Matthias Proske <Matthias.Proske@bshg.com>");
MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
MODULE_DESCRIPTION("Synaptics R63353 Controller Driver");
MODULE_LICENSE("GPL");
