diff mbox series

[3/4] drm/tiny/mi0283qt: Move driver to panel-ilitek-ili9341

Message ID 20190801135249.28803-4-noralf@tronnes.org (mailing list archive)
State New, archived
Headers show
Series drm/mipi-dbi: Support panel drivers | expand

Commit Message

Noralf Trønnes Aug. 1, 2019, 1:52 p.m. UTC
The MI0283QT panels use a ILI9341 controller so it makes sense to merge
it with the other ili9341 code.

The DRM driver name is ABI, so that is retained.

Cc: David Lechner <david@lechnology.com>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 MAINTAINERS                                  |   9 +-
 drivers/gpu/drm/panel/Kconfig                |   1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 161 +++++++++-
 drivers/gpu/drm/tiny/Kconfig                 |  11 -
 drivers/gpu/drm/tiny/Makefile                |   1 -
 drivers/gpu/drm/tiny/mi0283qt.c              | 294 -------------------
 6 files changed, 161 insertions(+), 316 deletions(-)
 delete mode 100644 drivers/gpu/drm/tiny/mi0283qt.c

Comments

David Lechner Aug. 1, 2019, 7:13 p.m. UTC | #1
On 8/1/19 8:52 AM, Noralf Trønnes wrote:
> The MI0283QT panels use a ILI9341 controller so it makes sense to merge
> it with the other ili9341 code.
> 
> The DRM driver name is ABI, so that is retained.
> 
> Cc: David Lechner <david@lechnology.com>
> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
> ---

...

> @@ -216,6 +339,10 @@ static int ili9341_probe(struct spi_device *spi)
>   		return PTR_ERR(dc);
>   	}
>   
> +	ili->regulator = devm_regulator_get(dev, "power");
> +	if (IS_ERR(ili->regulator))
> +		return PTR_ERR(ili->regulator);
> +
>   	ili->backlight = devm_of_find_backlight(dev);
>   	if (IS_ERR(ili->backlight))
>   		return PTR_ERR(ili->backlight);
> @@ -230,7 +357,12 @@ static int ili9341_probe(struct spi_device *spi)
>   	ili->panel.dev = dev;
>   	ili->panel.funcs = ili->conf->funcs;
>   

Should probably add a comment here that this is for backwards
compatibility of the driver name so that no one is tempted to
to add more driver structs when adding new panels.

> -	return drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, &ili9341_drm_driver,
> +	if (ili->conf == &mi0283qt_data)
> +		driver = &mi0283qt_drm_driver;
> +	else
> +		driver = &ili9341_drm_driver;
> +
> +	return drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, driver,
>   					   ili->conf->mode, rotation);
>   }
>
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 66b3893a100f..cd7b8bdb3780 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5110,10 +5110,12 @@  F:	Documentation/devicetree/bindings/display/ilitek,ili9225.txt
 
 DRM DRIVER FOR ILITEK ILI9341 PANELS
 M:	David Lechner <david@lechnology.com>
+M:	Noralf Trønnes <noralf@tronnes.org>
 T:	git git://anongit.freedesktop.org/drm/drm-misc
 S:	Maintained
 F:	drivers/gpu/drm/panel/panel-ilitek-ili9341.c
 F:	Documentation/devicetree/bindings/display/ilitek,ili9341.txt
+F:	Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
 
 DRM DRIVER FOR HX8357D PANELS
 M:	Eric Anholt <eric@anholt.net>
@@ -5137,13 +5139,6 @@  M:	Dave Airlie <airlied@redhat.com>
 S:	Odd Fixes
 F:	drivers/gpu/drm/mgag200/
 
-DRM DRIVER FOR MI0283QT
-M:	Noralf Trønnes <noralf@tronnes.org>
-T:	git git://anongit.freedesktop.org/drm/drm-misc
-S:	Maintained
-F:	drivers/gpu/drm/tiny/mi0283qt.c
-F:	Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
-
 DRM DRIVER FOR MSM ADRENO GPU
 M:	Rob Clark <robdclark@gmail.com>
 M:	Sean Paul <sean@poorly.run>
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a24953ec2d40..fbb5a723eeb5 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -65,6 +65,7 @@  config DRM_PANEL_ILITEK_ILI9341
 	help
 	  DRM driver for the following Ilitek ILI9341 panels:
 	  * YX240QV29-T 2.4" 240x320 TFT (Adafruit 2.4")
+	  * Multi-Inno MI0283QT
 
 	  If M is selected the module will be called panel-ilitek-ili9341.
 
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
index f8df737018d3..f6082fa2a389 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -3,8 +3,6 @@ 
  * DRM driver for Ilitek ILI9341 panels
  *
  * Copyright 2018 David Lechner <david@lechnology.com>
- *
- * Based on mi0283qt.c:
  * Copyright 2016 Noralf Trønnes
  */
 
@@ -13,7 +11,9 @@ 
 #include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm.h>
 #include <linux/property.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
 #include <video/mipi_display.h>
@@ -22,6 +22,7 @@ 
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_mipi_dbi.h>
+#include <drm/drm_modeset_helper.h>
 #include <drm/drm_panel.h>
 
 #define ILI9341_FRMCTR1		0xb1
@@ -57,6 +58,7 @@  struct ili9341_config {
 struct ili9341 {
 	struct mipi_dbi_dev dbidev; /* This must be the first entry */
 	struct drm_panel panel;
+	struct regulator *regulator;
 	struct backlight_device *backlight;
 	const struct ili9341_config *conf;
 };
@@ -174,12 +176,133 @@  static const struct ili9341_config yx240qv29_data = {
 	.mode = &yx240qv29_mode,
 };
 
+static int mi0283qt_prepare(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+	struct mipi_dbi_dev *dbidev = &ili->dbidev;
+	struct mipi_dbi *dbi = &dbidev->dbi;
+	u8 addr_mode;
+	int ret;
+
+	if (ili->regulator)
+		regulator_enable(ili->regulator);
+
+	ret = mipi_dbi_poweron_conditional_reset(dbidev);
+	if (ret < 0) {
+		if (ili->regulator)
+			regulator_disable(ili->regulator);
+		return ret;
+	}
+	if (ret == 1)
+		goto out_enable;
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
+
+	mipi_dbi_command(dbi, ILI9341_PWCTRLB, 0x00, 0x83, 0x30);
+	mipi_dbi_command(dbi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
+	mipi_dbi_command(dbi, ILI9341_DTCTRLA, 0x85, 0x01, 0x79);
+	mipi_dbi_command(dbi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
+	mipi_dbi_command(dbi, ILI9341_PUMPCTRL, 0x20);
+	mipi_dbi_command(dbi, ILI9341_DTCTRLB, 0x00, 0x00);
+
+	/* Power Control */
+	mipi_dbi_command(dbi, ILI9341_PWCTRL1, 0x26);
+	mipi_dbi_command(dbi, ILI9341_PWCTRL2, 0x11);
+	/* VCOM */
+	mipi_dbi_command(dbi, ILI9341_VMCTRL1, 0x35, 0x3e);
+	mipi_dbi_command(dbi, ILI9341_VMCTRL2, 0xbe);
+
+	/* Memory Access Control */
+	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
+
+	/* Frame Rate */
+	mipi_dbi_command(dbi, ILI9341_FRMCTR1, 0x00, 0x1b);
+
+	/* Gamma */
+	mipi_dbi_command(dbi, ILI9341_EN3GAM, 0x08);
+	mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
+	mipi_dbi_command(dbi, ILI9341_PGAMCTRL,
+			 0x1f, 0x1a, 0x18, 0x0a, 0x0f, 0x06, 0x45, 0x87,
+			 0x32, 0x0a, 0x07, 0x02, 0x07, 0x05, 0x00);
+	mipi_dbi_command(dbi, ILI9341_NGAMCTRL,
+			 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3a, 0x78,
+			 0x4d, 0x05, 0x18, 0x0d, 0x38, 0x3a, 0x1f);
+
+	/* DDRAM */
+	mipi_dbi_command(dbi, ILI9341_ETMOD, 0x07);
+
+	/* Display */
+	mipi_dbi_command(dbi, ILI9341_DISCTRL, 0x0a, 0x82, 0x27, 0x00);
+	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(100);
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
+	msleep(100);
+
+out_enable:
+	/* The PiTFT (ili9340) has a hardware reset circuit that
+	 * resets only on power-on and not on each reboot through
+	 * a gpio like the rpi-display does.
+	 * As a result, we need to always apply the rotation value
+	 * regardless of the display "on/off" state.
+	 */
+	switch (dbidev->rotation) {
+	default:
+		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
+			    ILI9341_MADCTL_MX;
+		break;
+	case 90:
+		addr_mode = ILI9341_MADCTL_MY;
+		break;
+	case 180:
+		addr_mode = ILI9341_MADCTL_MV;
+		break;
+	case 270:
+		addr_mode = ILI9341_MADCTL_MX;
+		break;
+	}
+	addr_mode |= ILI9341_MADCTL_BGR;
+	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+
+	return 0;
+}
+
+static int mi0283qt_unprepare(struct drm_panel *panel)
+{
+	struct ili9341 *ili = panel_to_ili9341(panel);
+
+	if (ili->regulator)
+		regulator_disable(ili->regulator);
+
+	return 0;
+}
+
+static const struct drm_panel_funcs mi0283qt_drm_funcs = {
+	.prepare = mi0283qt_prepare,
+	.enable = ili9341_enable,
+	.disable = ili9341_disable,
+	.unprepare = mi0283qt_unprepare,
+};
+
+static const struct drm_display_mode mi0283qt_mode = {
+	DRM_SIMPLE_MODE(320, 240, 58, 43),
+};
+
+static const struct ili9341_config mi0283qt_data = {
+	.funcs = &mi0283qt_drm_funcs,
+	.mode = &mi0283qt_mode,
+};
+
+/* Legacy, DRM driver name is ABI */
+DEFINE_DRM_MIPI_DBI_PANEL_DRIVER(mi0283qt, "Multi-Inno MI0283QT", "20160614");
+
 DEFINE_DRM_MIPI_DBI_PANEL_DRIVER(ili9341, "Ilitek ILI9341", "20180514");
 
 static int ili9341_probe(struct spi_device *spi)
 {
 	const struct spi_device_id *spi_id;
 	struct device *dev = &spi->dev;
+	struct drm_driver *driver;
 	struct mipi_dbi *dbi;
 	struct gpio_desc *dc;
 	struct ili9341 *ili;
@@ -216,6 +339,10 @@  static int ili9341_probe(struct spi_device *spi)
 		return PTR_ERR(dc);
 	}
 
+	ili->regulator = devm_regulator_get(dev, "power");
+	if (IS_ERR(ili->regulator))
+		return PTR_ERR(ili->regulator);
+
 	ili->backlight = devm_of_find_backlight(dev);
 	if (IS_ERR(ili->backlight))
 		return PTR_ERR(ili->backlight);
@@ -230,7 +357,12 @@  static int ili9341_probe(struct spi_device *spi)
 	ili->panel.dev = dev;
 	ili->panel.funcs = ili->conf->funcs;
 
-	return drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, &ili9341_drm_driver,
+	if (ili->conf == &mi0283qt_data)
+		driver = &mi0283qt_drm_driver;
+	else
+		driver = &ili9341_drm_driver;
+
+	return drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, driver,
 					   ili->conf->mode, rotation);
 }
 
@@ -251,14 +383,36 @@  static void ili9341_shutdown(struct spi_device *spi)
 	drm_atomic_helper_shutdown(&ili->dbidev.drm);
 }
 
+static int __maybe_unused ili9341_pm_suspend(struct device *dev)
+{
+	struct ili9341 *ili = dev_get_drvdata(dev);
+
+	return drm_mode_config_helper_suspend(&ili->dbidev.drm);
+}
+
+static int __maybe_unused ili9341_pm_resume(struct device *dev)
+{
+	struct ili9341 *ili = dev_get_drvdata(dev);
+
+	drm_mode_config_helper_resume(&ili->dbidev.drm);
+
+	return 0;
+}
+
+static const struct dev_pm_ops ili9341_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ili9341_pm_suspend, ili9341_pm_resume)
+};
+
 static const struct of_device_id ili9341_of_match[] = {
 	{ .compatible = "adafruit,yx240qv29", .data = &yx240qv29_data },
+	{ .compatible = "multi-inno,mi0283qt", .data = &mi0283qt_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, ili9341_of_match);
 
 static const struct spi_device_id ili9341_id[] = {
 	{ "yx240qv29", (unsigned long)&yx240qv29_data },
+	{ "mi0283qt", (unsigned long)&mi0283qt_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(spi, ili9341_id);
@@ -267,6 +421,7 @@  static struct spi_driver ili9341_spi_driver = {
 	.driver = {
 		.name = "panel-ilitek-ili9341",
 		.of_match_table = ili9341_of_match,
+		.pm = &ili9341_pm_ops,
 	},
 	.id_table = ili9341_id,
 	.probe = ili9341_probe,
diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
index 3e63e93fbeac..4fae3e50147d 100644
--- a/drivers/gpu/drm/tiny/Kconfig
+++ b/drivers/gpu/drm/tiny/Kconfig
@@ -34,17 +34,6 @@  config TINYDRM_ILI9225
 
 	  If M is selected the module will be called ili9225.
 
-config TINYDRM_MI0283QT
-	tristate "DRM support for MI0283QT"
-	depends on DRM && SPI
-	select DRM_KMS_HELPER
-	select DRM_KMS_CMA_HELPER
-	select DRM_MIPI_DBI
-	select BACKLIGHT_CLASS_DEVICE
-	help
-	  DRM driver for the Multi-Inno MI0283QT display panel
-	  If M is selected the module will be called mi0283qt.
-
 config TINYDRM_REPAPER
 	tristate "DRM support for Pervasive Displays RePaper panels (V231)"
 	depends on DRM && SPI
diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile
index c140962f5c7e..05029c4b1916 100644
--- a/drivers/gpu/drm/tiny/Makefile
+++ b/drivers/gpu/drm/tiny/Makefile
@@ -3,7 +3,6 @@ 
 obj-$(CONFIG_DRM_GM12U320)		+= gm12u320.o
 obj-$(CONFIG_TINYDRM_HX8357D)		+= hx8357d.o
 obj-$(CONFIG_TINYDRM_ILI9225)		+= ili9225.o
-obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
 obj-$(CONFIG_TINYDRM_REPAPER)		+= repaper.o
 obj-$(CONFIG_TINYDRM_ST7586)		+= st7586.o
 obj-$(CONFIG_TINYDRM_ST7735R)		+= st7735r.o
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
deleted file mode 100644
index e2cfd9a17143..000000000000
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ /dev/null
@@ -1,294 +0,0 @@ 
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * DRM driver for Multi-Inno MI0283QT panels
- *
- * Copyright 2016 Noralf Trønnes
- */
-
-#include <linux/backlight.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/module.h>
-#include <linux/property.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_drv.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_mipi_dbi.h>
-#include <drm/drm_modeset_helper.h>
-#include <video/mipi_display.h>
-
-#define ILI9341_FRMCTR1		0xb1
-#define ILI9341_DISCTRL		0xb6
-#define ILI9341_ETMOD		0xb7
-
-#define ILI9341_PWCTRL1		0xc0
-#define ILI9341_PWCTRL2		0xc1
-#define ILI9341_VMCTRL1		0xc5
-#define ILI9341_VMCTRL2		0xc7
-#define ILI9341_PWCTRLA		0xcb
-#define ILI9341_PWCTRLB		0xcf
-
-#define ILI9341_PGAMCTRL	0xe0
-#define ILI9341_NGAMCTRL	0xe1
-#define ILI9341_DTCTRLA		0xe8
-#define ILI9341_DTCTRLB		0xea
-#define ILI9341_PWRSEQ		0xed
-
-#define ILI9341_EN3GAM		0xf2
-#define ILI9341_PUMPCTRL	0xf7
-
-#define ILI9341_MADCTL_BGR	BIT(3)
-#define ILI9341_MADCTL_MV	BIT(5)
-#define ILI9341_MADCTL_MX	BIT(6)
-#define ILI9341_MADCTL_MY	BIT(7)
-
-static void mi0283qt_enable(struct drm_simple_display_pipe *pipe,
-			    struct drm_crtc_state *crtc_state,
-			    struct drm_plane_state *plane_state)
-{
-	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
-	struct mipi_dbi *dbi = &dbidev->dbi;
-	u8 addr_mode;
-	int ret, idx;
-
-	if (!drm_dev_enter(pipe->crtc.dev, &idx))
-		return;
-
-	DRM_DEBUG_KMS("\n");
-
-	ret = mipi_dbi_poweron_conditional_reset(dbidev);
-	if (ret < 0)
-		goto out_exit;
-	if (ret == 1)
-		goto out_enable;
-
-	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
-
-	mipi_dbi_command(dbi, ILI9341_PWCTRLB, 0x00, 0x83, 0x30);
-	mipi_dbi_command(dbi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
-	mipi_dbi_command(dbi, ILI9341_DTCTRLA, 0x85, 0x01, 0x79);
-	mipi_dbi_command(dbi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
-	mipi_dbi_command(dbi, ILI9341_PUMPCTRL, 0x20);
-	mipi_dbi_command(dbi, ILI9341_DTCTRLB, 0x00, 0x00);
-
-	/* Power Control */
-	mipi_dbi_command(dbi, ILI9341_PWCTRL1, 0x26);
-	mipi_dbi_command(dbi, ILI9341_PWCTRL2, 0x11);
-	/* VCOM */
-	mipi_dbi_command(dbi, ILI9341_VMCTRL1, 0x35, 0x3e);
-	mipi_dbi_command(dbi, ILI9341_VMCTRL2, 0xbe);
-
-	/* Memory Access Control */
-	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
-
-	/* Frame Rate */
-	mipi_dbi_command(dbi, ILI9341_FRMCTR1, 0x00, 0x1b);
-
-	/* Gamma */
-	mipi_dbi_command(dbi, ILI9341_EN3GAM, 0x08);
-	mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
-	mipi_dbi_command(dbi, ILI9341_PGAMCTRL,
-		       0x1f, 0x1a, 0x18, 0x0a, 0x0f, 0x06, 0x45, 0x87,
-		       0x32, 0x0a, 0x07, 0x02, 0x07, 0x05, 0x00);
-	mipi_dbi_command(dbi, ILI9341_NGAMCTRL,
-		       0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3a, 0x78,
-		       0x4d, 0x05, 0x18, 0x0d, 0x38, 0x3a, 0x1f);
-
-	/* DDRAM */
-	mipi_dbi_command(dbi, ILI9341_ETMOD, 0x07);
-
-	/* Display */
-	mipi_dbi_command(dbi, ILI9341_DISCTRL, 0x0a, 0x82, 0x27, 0x00);
-	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
-	msleep(100);
-
-	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
-	msleep(100);
-
-out_enable:
-	/* The PiTFT (ili9340) has a hardware reset circuit that
-	 * resets only on power-on and not on each reboot through
-	 * a gpio like the rpi-display does.
-	 * As a result, we need to always apply the rotation value
-	 * regardless of the display "on/off" state.
-	 */
-	switch (dbidev->rotation) {
-	default:
-		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
-			    ILI9341_MADCTL_MX;
-		break;
-	case 90:
-		addr_mode = ILI9341_MADCTL_MY;
-		break;
-	case 180:
-		addr_mode = ILI9341_MADCTL_MV;
-		break;
-	case 270:
-		addr_mode = ILI9341_MADCTL_MX;
-		break;
-	}
-	addr_mode |= ILI9341_MADCTL_BGR;
-	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
-out_exit:
-	drm_dev_exit(idx);
-}
-
-static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = {
-	.enable = mi0283qt_enable,
-	.disable = mipi_dbi_pipe_disable,
-	.update = mipi_dbi_pipe_update,
-	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
-};
-
-static const struct drm_display_mode mi0283qt_mode = {
-	DRM_SIMPLE_MODE(320, 240, 58, 43),
-};
-
-DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
-
-static struct drm_driver mi0283qt_driver = {
-	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-	.fops			= &mi0283qt_fops,
-	.release		= mipi_dbi_release,
-	DRM_GEM_CMA_VMAP_DRIVER_OPS,
-	.debugfs_init		= mipi_dbi_debugfs_init,
-	.name			= "mi0283qt",
-	.desc			= "Multi-Inno MI0283QT",
-	.date			= "20160614",
-	.major			= 1,
-	.minor			= 0,
-};
-
-static const struct of_device_id mi0283qt_of_match[] = {
-	{ .compatible = "multi-inno,mi0283qt" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, mi0283qt_of_match);
-
-static const struct spi_device_id mi0283qt_id[] = {
-	{ "mi0283qt", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(spi, mi0283qt_id);
-
-static int mi0283qt_probe(struct spi_device *spi)
-{
-	struct device *dev = &spi->dev;
-	struct mipi_dbi_dev *dbidev;
-	struct drm_device *drm;
-	struct mipi_dbi *dbi;
-	struct gpio_desc *dc;
-	u32 rotation = 0;
-	int ret;
-
-	dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL);
-	if (!dbidev)
-		return -ENOMEM;
-
-	dbi = &dbidev->dbi;
-	drm = &dbidev->drm;
-	ret = devm_drm_dev_init(dev, drm, &mi0283qt_driver);
-	if (ret) {
-		kfree(dbidev);
-		return ret;
-	}
-
-	drm_mode_config_init(drm);
-
-	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-	if (IS_ERR(dbi->reset)) {
-		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
-		return PTR_ERR(dbi->reset);
-	}
-
-	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
-	if (IS_ERR(dc)) {
-		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
-		return PTR_ERR(dc);
-	}
-
-	dbidev->regulator = devm_regulator_get(dev, "power");
-	if (IS_ERR(dbidev->regulator))
-		return PTR_ERR(dbidev->regulator);
-
-	dbidev->backlight = devm_of_find_backlight(dev);
-	if (IS_ERR(dbidev->backlight))
-		return PTR_ERR(dbidev->backlight);
-
-	device_property_read_u32(dev, "rotation", &rotation);
-
-	ret = mipi_dbi_spi_init(spi, dbi, dc);
-	if (ret)
-		return ret;
-
-	ret = mipi_dbi_dev_init(dbidev, &mi0283qt_pipe_funcs, &mi0283qt_mode, rotation);
-	if (ret)
-		return ret;
-
-	drm_mode_config_reset(drm);
-
-	ret = drm_dev_register(drm, 0);
-	if (ret)
-		return ret;
-
-	spi_set_drvdata(spi, drm);
-
-	drm_fbdev_generic_setup(drm, 0);
-
-	return 0;
-}
-
-static int mi0283qt_remove(struct spi_device *spi)
-{
-	struct drm_device *drm = spi_get_drvdata(spi);
-
-	drm_dev_unplug(drm);
-	drm_atomic_helper_shutdown(drm);
-
-	return 0;
-}
-
-static void mi0283qt_shutdown(struct spi_device *spi)
-{
-	drm_atomic_helper_shutdown(spi_get_drvdata(spi));
-}
-
-static int __maybe_unused mi0283qt_pm_suspend(struct device *dev)
-{
-	return drm_mode_config_helper_suspend(dev_get_drvdata(dev));
-}
-
-static int __maybe_unused mi0283qt_pm_resume(struct device *dev)
-{
-	drm_mode_config_helper_resume(dev_get_drvdata(dev));
-
-	return 0;
-}
-
-static const struct dev_pm_ops mi0283qt_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mi0283qt_pm_suspend, mi0283qt_pm_resume)
-};
-
-static struct spi_driver mi0283qt_spi_driver = {
-	.driver = {
-		.name = "mi0283qt",
-		.owner = THIS_MODULE,
-		.of_match_table = mi0283qt_of_match,
-		.pm = &mi0283qt_pm_ops,
-	},
-	.id_table = mi0283qt_id,
-	.probe = mi0283qt_probe,
-	.remove = mi0283qt_remove,
-	.shutdown = mi0283qt_shutdown,
-};
-module_spi_driver(mi0283qt_spi_driver);
-
-MODULE_DESCRIPTION("Multi-Inno MI0283QT DRM driver");
-MODULE_AUTHOR("Noralf Trønnes");
-MODULE_LICENSE("GPL");