// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
 *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
 */

#include <linux/backlight.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>

#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>

#include <video/mipi_display.h>

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

	struct backlight_device *backlight;
	struct regulator *supply;

	bool prepared;
	bool enabled;

	const struct drm_display_mode *default_mode;
};

static inline struct osd101t2587_panel *ti_osd_panel(struct drm_panel *panel)
{
	return container_of(panel, struct osd101t2587_panel, base);
}

static int osd101t2587_panel_disable(struct drm_panel *panel)
{
	struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
	int ret;

	if (!osd101t2587->enabled)
		return 0;

	backlight_disable(osd101t2587->backlight);

	ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);

	osd101t2587->enabled = false;

	return ret;
}

static int osd101t2587_panel_unprepare(struct drm_panel *panel)
{
	struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);

	if (!osd101t2587->prepared)
		return 0;

	regulator_disable(osd101t2587->supply);
	osd101t2587->prepared = false;

	return 0;
}

static int osd101t2587_panel_prepare(struct drm_panel *panel)
{
	struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
	int ret;

	if (osd101t2587->prepared)
		return 0;

	ret = regulator_enable(osd101t2587->supply);
	if (!ret)
		osd101t2587->prepared = true;

	return ret;
}

static int osd101t2587_panel_enable(struct drm_panel *panel)
{
	struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
	int ret;

	if (osd101t2587->enabled)
		return 0;

	ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
	if (ret)
		return ret;

	backlight_enable(osd101t2587->backlight);

	osd101t2587->enabled = true;

	return ret;
}

static const struct drm_display_mode default_mode_osd101t2587 = {
	.clock = 164400,
	.hdisplay = 1920,
	.hsync_start = 1920 + 152,
	.hsync_end = 1920 + 152 + 52,
	.htotal = 1920 + 152 + 52 + 20,
	.vdisplay = 1200,
	.vsync_start = 1200 + 24,
	.vsync_end = 1200 + 24 + 6,
	.vtotal = 1200 + 24 + 6 + 48,
	.vrefresh = 60,
	.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

static int osd101t2587_panel_get_modes(struct drm_panel *panel)
{
	struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
	struct drm_display_mode *mode;

	mode = drm_mode_duplicate(panel->drm, osd101t2587->default_mode);
	if (!mode) {
		dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
			osd101t2587->default_mode->hdisplay,
			osd101t2587->default_mode->vdisplay,
			osd101t2587->default_mode->vrefresh);
		return -ENOMEM;
	}

	drm_mode_set_name(mode);

	drm_mode_probed_add(panel->connector, mode);

	panel->connector->display_info.width_mm = 217;
	panel->connector->display_info.height_mm = 136;

	return 1;
}

static const struct drm_panel_funcs osd101t2587_panel_funcs = {
	.disable = osd101t2587_panel_disable,
	.unprepare = osd101t2587_panel_unprepare,
	.prepare = osd101t2587_panel_prepare,
	.enable = osd101t2587_panel_enable,
	.get_modes = osd101t2587_panel_get_modes,
};

static const struct of_device_id osd101t2587_of_match[] = {
	{
		.compatible = "osddisplays,osd101t2587-53ts",
		.data = &default_mode_osd101t2587,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, osd101t2587_of_match);

static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587)
{
	struct device *dev = &osd101t2587->dsi->dev;

	osd101t2587->supply = devm_regulator_get(dev, "power");
	if (IS_ERR(osd101t2587->supply))
		return PTR_ERR(osd101t2587->supply);

	osd101t2587->backlight = devm_of_find_backlight(dev);
	if (IS_ERR(osd101t2587->backlight))
		return PTR_ERR(osd101t2587->backlight);

	drm_panel_init(&osd101t2587->base);
	osd101t2587->base.funcs = &osd101t2587_panel_funcs;
	osd101t2587->base.dev = &osd101t2587->dsi->dev;

	return drm_panel_add(&osd101t2587->base);
}

static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi)
{
	struct osd101t2587_panel *osd101t2587;
	const struct of_device_id *id;
	int ret;

	id = of_match_node(osd101t2587_of_match, dsi->dev.of_node);
	if (!id)
		return -ENODEV;

	dsi->lanes = 4;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
			  MIPI_DSI_MODE_VIDEO_BURST |
			  MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
			  MIPI_DSI_MODE_EOT_PACKET;

	osd101t2587 = devm_kzalloc(&dsi->dev, sizeof(*osd101t2587), GFP_KERNEL);
	if (!osd101t2587)
		return -ENOMEM;

	mipi_dsi_set_drvdata(dsi, osd101t2587);

	osd101t2587->dsi = dsi;
	osd101t2587->default_mode = id->data;

	ret = osd101t2587_panel_add(osd101t2587);
	if (ret < 0)
		return ret;

	ret = mipi_dsi_attach(dsi);
	if (ret)
		drm_panel_remove(&osd101t2587->base);

	return ret;
}

static int osd101t2587_panel_remove(struct mipi_dsi_device *dsi)
{
	struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
	int ret;

	ret = osd101t2587_panel_disable(&osd101t2587->base);
	if (ret < 0)
		dev_warn(&dsi->dev, "failed to disable panel: %d\n", ret);

	osd101t2587_panel_unprepare(&osd101t2587->base);

	drm_panel_remove(&osd101t2587->base);

	ret = mipi_dsi_detach(dsi);
	if (ret < 0)
		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);

	return ret;
}

static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
{
	struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);

	osd101t2587_panel_disable(&osd101t2587->base);
	osd101t2587_panel_unprepare(&osd101t2587->base);
}

static struct mipi_dsi_driver osd101t2587_panel_driver = {
	.driver = {
		.name = "panel-osd-osd101t2587-53ts",
		.of_match_table = osd101t2587_of_match,
	},
	.probe = osd101t2587_panel_probe,
	.remove = osd101t2587_panel_remove,
	.shutdown = osd101t2587_panel_shutdown,
};
module_mipi_dsi_driver(osd101t2587_panel_driver);

MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_DESCRIPTION("OSD101T2587-53TS DSI panel");
MODULE_LICENSE("GPL v2");
