// 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->dsi->dev,
		       &osd101t2587_panel_funcs, DRM_MODE_CONNECTOR_DSI);

	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");
