ShenZhen New Display Co., Limited is the manufacturer of the
NDS040480800-V3 LCD panel according the datasheet.
Signed-off-by: Luca Ceresoli <[email protected]>
---
Changes in v2: none
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index af60bf1a6664..f73d6d4eabbe 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -929,6 +929,8 @@ patternProperties:
description: Netronix, Inc.
"^netxeon,.*":
description: Shenzhen Netxeon Technology CO., LTD
+ "^newdisplay,.*":
+ description: ShenZhen New Display Co., Limited
"^neweast,.*":
description: Guangdong Neweast Optoelectronics CO., LTD
"^newhaven,.*":
--
2.34.1
Add bindings for LCD panels based on the ILITEK ILI9806E RGB controller
connected over SPI and the "ShenZhen New Display Co NDS040480800-V3"
480x800 panel based on it.
Signed-off-by: Luca Ceresoli <[email protected]>
---
Changes in v2:
- remove T: line form MAINTAINERS entry
- reference spi-peripheral-props.yaml
- add 'maxItems: 1' to reg
- use unevaluatedProperties
- remove out of scope backlight node
---
.../display/panel/ilitek,ili9806e.yaml | 63 +++++++++++++++++++
MAINTAINERS | 5 ++
2 files changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
new file mode 100644
index 000000000000..83d177be4e7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/ilitek,ili9806e.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ilitek ILI9806E display panels
+
+maintainers:
+ - Luca Ceresoli <[email protected]>
+
+description:
+ This binding is for display panels using an Ilitek ILI9806E controller in
+ SPI mode.
+
+allOf:
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ # ShenZhen New Display Co 3.97" 480x800 RGB a-SI TFT LCD
+ - newdisplay,nds040480800-v3
+ - const: ilitek,ili9806e
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - port
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ display@0 {
+ compatible = "newdisplay,nds040480800-v3", "ilitek,ili9806e";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdgpios>;
+ reset-gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+ backlight = <&backlight>;
+
+ port {
+ ili9806e_in: endpoint {
+ remote-endpoint = <&lcdif_out>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 0f966f05fb0d..085e44a7b5e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6516,6 +6516,11 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/ilitek,ili9486.yaml
F: drivers/gpu/drm/tiny/ili9486.c
+DRM DRIVER FOR ILITEK ILI9806E PANELS
+M: Luca Ceresoli <[email protected]>
+S: Maintained
+F: Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
+
DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS
M: Jagan Teki <[email protected]>
S: Maintained
--
2.34.1
Add a driver for the ILITEK ILI9806E 480x864 RGB LCD controller connected
over SPI, and implement the ShenZhen New Display Co NDS040480800-V3 480x800
panel.
Signed-off-by: Luca Ceresoli <[email protected]>
---
Changes in v2:
- add ILI9806E_P1_DISCTRL1 bit description
---
MAINTAINERS | 1 +
drivers/gpu/drm/panel/Kconfig | 13 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-ilitek-ili9806e.c | 385 ++++++++++++++++++
4 files changed, 400 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9806e.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 085e44a7b5e1..602dc866c2e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6520,6 +6520,7 @@ DRM DRIVER FOR ILITEK ILI9806E PANELS
M: Luca Ceresoli <[email protected]>
S: Maintained
F: Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
+F: drivers/gpu/drm/panel/panel-ilitek-ili9806e.c
DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS
M: Jagan Teki <[email protected]>
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 203c0ef0bbfd..e3e89d86668a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -194,6 +194,19 @@ config DRM_PANEL_ILITEK_ILI9341
QVGA (240x320) RGB panels. support serial & parallel rgb
interface.
+config DRM_PANEL_ILITEK_ILI9806E
+ tristate "Ilitek ILI9806E panel"
+ depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
+ select VIDEOMODE_HELPERS
+ select DRM_MIPI_DBI
+ help
+ Say Y here if you want to enable support for LCD panels connected
+ over SPI and based on the Ilitek ILI9806E controller.
+
+ The ILI9806E is an LCD controller capable of driving 18-bit a-Si
+ TFT LCDs up to a resolution of 480x800.
+
config DRM_PANEL_ILITEK_ILI9881C
tristate "Ilitek ILI9881C-based panels"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 30cf553c8d1d..f465140ae7df 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d
obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9806E) += panel-ilitek-ili9806e.o
obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o
obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c
new file mode 100644
index 000000000000..ffc60d924e63
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Ilitek ILI9806E a-Si TFT LCD controller.
+ *
+ * Copyright (c) 2023 Delcon SRL
+ * Luca Ceresoli <[email protected]>
+ */
+
+#include <drm/drm_mipi_dbi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/media-bus-format.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+
+#include <video/mipi_display.h>
+
+#define ILI9806E_BUS_FORMAT MEDIA_BUS_FMT_RGB666_1X18
+
+// Page 1 registers
+#define ILI9806E_P1_IFMODE1 0x08 // Interface Mode Control 1
+#define IFMODE1_SEPT_SDIO BIT(3) // 1 = two data pins
+#define IFMODE1_SDO_STATUS BIT(4) // 0 = SDO has output enable
+#define ILI9806E_P1_DISCTRL1 0x20 // Display Function Control 1
+#define DISCTRL1_SYNC_MODE BIT(0) // RGB interface mode: 0 = DE mode, 1 = SYNC mode
+#define ILI9806E_P1_DISCTRL2 0x21 // Display Function Control 2
+#define DISCTRL2_EPL BIT(0) // DE polarity (1 = active high)
+#define DISCTRL2_DPL BIT(1) // PCLK polarity (1 = fetch on falling edge)
+#define DISCTRL2_HSPL BIT(2) // HS polarity (1 = active high)
+#define DISCTRL2_VSPL BIT(3) // VS polarity (1 = active high)
+#define ILI9806E_P1_RESCTRL 0x30 // Resolution Control
+#define RESCTRL_480x864 0x0
+#define RESCTRL_480x854 0x1
+#define RESCTRL_480x800 0x2
+#define RESCTRL_480x640 0x3
+#define RESCTRL_480x720 0x4
+#define ILI9806E_P1_INVTR 0x31 // Display Inversion Control
+#define INVTR_NLA_COLUMN 0x0
+#define INVTR_NLA_1DOT 0x1
+#define INVTR_NLA_2DOT 0x2
+#define INVTR_NLA_3DOT 0x3
+#define INVTR_NLA_4DOT 0x4
+#define ILI9806E_P1_PWCTRL1 0x40 // Power Control 1
+#define ILI9806E_P1_PWCTRL2 0x41 // Power Control 2
+#define ILI9806E_P1_PWCTRL3 0x42 // Power Control 3
+#define ILI9806E_P1_PWCTRL4 0x43 // Power Control 4
+#define ILI9806E_P1_PWCTRL5 0x44 // Power Control 5
+#define ILI9806E_P1_PWCTRL6 0x45 // Power Control 6
+#define ILI9806E_P1_PWCTRL7 0x46 // Power Control 7
+#define ILI9806E_P1_PWCTRL8 0x47 // Power Control 8
+#define ILI9806E_P1_PWCTRL9 0x50 // Power Control 9
+#define ILI9806E_P1_PWCTRL10 0x51 // Power Control 10
+#define ILI9806E_P1_VMCTRL1 0x52 // VCOM Control 1
+#define ILI9806E_P1_VMCTRL2 0x53 // VCOM Control 1
+#define ILI9806E_P1_SRCTADJ1 0x60 // Source Timing Adjust 1
+#define ILI9806E_P1_SRCTADJ2 0x61 // Source Timing Adjust 2
+#define ILI9806E_P1_SRCTADJ3 0x62 // Source Timing Adjust 3
+#define ILI9806E_P1_SRCTADJ4 0x63 // Source Timing Adjust 4
+#define ILI9806E_P1_P_GAMMA(n) (0xa0 + (n) - 1) // Positive Gamma Control 1~16
+#define ILI9806E_P1_N_GAMMA(n) (0xc0 + (n) - 1) // Negative Gamma Correction 1~16
+
+// Page 7 registers
+#define ILI9806E_P7_VGLREGEN 0x17 // VGL_REG EN
+#define ILI9806E_P7_0x02 0x02 // undocumented
+#define ILI9806E_P7_0xe1 0xe1 // undocumented
+
+// The page-switching register (valid for all pages)
+#define ILI9806E_Px_ENEXTC 0xff
+
+static const struct drm_display_mode nds040480800_v3_mode = {
+ .width_mm = 51,
+ .height_mm = 85,
+ .clock = 30000,
+ .hdisplay = 480,
+ .hsync_start = 480 + 25,
+ .hsync_end = 480 + 25 + 54,
+ .htotal = 480 + 25 + 54 + 25,
+ .vdisplay = 800,
+ .vsync_start = 800 + 25,
+ .vsync_end = 800 + 25 + 14,
+ .vtotal = 800 + 25 + 14 + 22,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER,
+};
+
+struct ili9806e {
+ struct mipi_dbi dbi;
+ struct drm_panel panel;
+};
+
+static inline struct ili9806e *panel_to_ili9806e(struct drm_panel *panel)
+{
+ return container_of(panel, struct ili9806e, panel);
+}
+
+static int ili9806e_switch_page(struct ili9806e *ctx, unsigned int page)
+{
+ return mipi_dbi_command(&ctx->dbi, ILI9806E_Px_ENEXTC, 0xff, 0x98, 0x06, 0x04, page);
+}
+
+static int ili9806e_unprepare(struct drm_panel *panel)
+{
+ struct ili9806e *ctx = panel_to_ili9806e(panel);
+ struct mipi_dbi *dbi = &ctx->dbi;
+
+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF, 0x00);
+ mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE, 0x00);
+
+ return 0;
+}
+
+static int ili9806e_prepare(struct drm_panel *panel)
+{
+ struct ili9806e *ctx = panel_to_ili9806e(panel);
+ struct mipi_dbi *dbi = &ctx->dbi;
+
+ /* Reset */
+
+ gpiod_set_value(ctx->dbi.reset, 1);
+ usleep_range(15, 50); // Min 10 us
+ gpiod_set_value(ctx->dbi.reset, 0);
+ msleep(125); // Min 5 ms in sleep in mode, 120 ms in sleep out mode
+
+ /* Init sequence */
+
+ ili9806e_switch_page(ctx, 1);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_IFMODE1, IFMODE1_SDO_STATUS);
+ mipi_dbi_command(dbi, ILI9806E_P1_DISCTRL2, DISCTRL2_EPL);
+ mipi_dbi_command(dbi, ILI9806E_P1_RESCTRL, RESCTRL_480x800);
+ mipi_dbi_command(dbi, ILI9806E_P1_INVTR, INVTR_NLA_COLUMN);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL1, 0x10);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL2, 0x55);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL3, 0x02);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL4, 0x09);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL5, 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL9, 0x78);
+ mipi_dbi_command(dbi, ILI9806E_P1_PWCTRL10, 0x78);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_VMCTRL1, 0x00);
+ mipi_dbi_command(dbi, ILI9806E_P1_VMCTRL2, 0x6d);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_SRCTADJ1, 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_SRCTADJ2, 0x00);
+ mipi_dbi_command(dbi, ILI9806E_P1_SRCTADJ3, 0x08);
+ mipi_dbi_command(dbi, ILI9806E_P1_SRCTADJ4, 0x00);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(1), 0x00);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(2), 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(3), 0x0c);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(4), 0x0b);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(5), 0x03);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(6), 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(7), 0x06);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(8), 0x04);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(9), 0x08);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(10), 0x0c);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(11), 0x13);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(12), 0x06);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(13), 0x0d);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(14), 0x19);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(15), 0x10);
+ mipi_dbi_command(dbi, ILI9806E_P1_P_GAMMA(16), 0x00);
+
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(1), 0x00);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(2), 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(3), 0x0c);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(4), 0x0b);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(5), 0x03);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(6), 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(7), 0x07);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(8), 0x04);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(9), 0x08);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(10), 0x0c);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(11), 0x13);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(12), 0x06);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(13), 0x0d);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(14), 0x18);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(15), 0x10);
+ mipi_dbi_command(dbi, ILI9806E_P1_N_GAMMA(16), 0x00);
+
+ ili9806e_switch_page(ctx, 6);
+
+ /* Registers in page 6 are not really documented except for the comments copied below */
+ mipi_dbi_command(dbi, 0x00, 0x20); // STV_A_Rise[10:8] | GIP_0_SET0
+ mipi_dbi_command(dbi, 0x01, 0x0a); // STV_A_Rise[7:0]
+ mipi_dbi_command(dbi, 0x02, 0x00); // GIP_0_SET1
+ mipi_dbi_command(dbi, 0x03, 0x00); // GIP_0_SET2
+ mipi_dbi_command(dbi, 0x04, 0x01); // GIP_0_SET3
+ mipi_dbi_command(dbi, 0x05, 0x01); // GIP_0_SET4
+ mipi_dbi_command(dbi, 0x06, 0x98); // CLK_A_Rise[10:8] | GIP_0_SET5
+ mipi_dbi_command(dbi, 0x07, 0x06); // CLK_A_Rise[7:0]
+ mipi_dbi_command(dbi, 0x08, 0x01); // GIP_0_SET6
+ mipi_dbi_command(dbi, 0x09, 0x80); // GIP_0_SET7
+ mipi_dbi_command(dbi, 0x0a, 0x00); // GIP_0_SET8
+ mipi_dbi_command(dbi, 0x0b, 0x00); // GIP_0_SET9
+ mipi_dbi_command(dbi, 0x0c, 0x01); // GIP_0_SET10
+ mipi_dbi_command(dbi, 0x0d, 0x01); // GIP_0_SET11
+ mipi_dbi_command(dbi, 0x0e, 0x00); // GIP_0_SET12
+ mipi_dbi_command(dbi, 0x0f, 0x00); // GIP_0_SET13
+ mipi_dbi_command(dbi, 0x10, 0xf0); // GIP_0_SET14
+ mipi_dbi_command(dbi, 0x11, 0xf4); // GIP_0_SET15
+ mipi_dbi_command(dbi, 0x12, 0x01); // GIP_0_SET16
+ mipi_dbi_command(dbi, 0x13, 0x00); // GIP_0_SET17
+ mipi_dbi_command(dbi, 0x14, 0x00); // GIP_0_SET18
+ mipi_dbi_command(dbi, 0x15, 0xc0); // GIP_0_SET19
+ mipi_dbi_command(dbi, 0x16, 0x08); // GIP_0_SET20
+ mipi_dbi_command(dbi, 0x17, 0x00); // GIP_0_SET21
+ mipi_dbi_command(dbi, 0x18, 0x00); // GIP_0_SET22
+ mipi_dbi_command(dbi, 0x19, 0x00); // GIP_0_SET23
+ mipi_dbi_command(dbi, 0x1a, 0x00); // GIP_0_SET24
+ mipi_dbi_command(dbi, 0x1b, 0x00); // GIP_0_SET25
+ mipi_dbi_command(dbi, 0x1c, 0x00); // GIP_0_SET26
+ mipi_dbi_command(dbi, 0x1d, 0x00); // GIP_0_SET27
+ mipi_dbi_command(dbi, 0x20, 0x01); // GIP_1_SET0
+ mipi_dbi_command(dbi, 0x21, 0x23); // GIP_1_SET1
+ mipi_dbi_command(dbi, 0x22, 0x45); // GIP_1_SET2
+ mipi_dbi_command(dbi, 0x23, 0x67); // GIP_1_SET3
+ mipi_dbi_command(dbi, 0x24, 0x01); // GIP_1_SET4
+ mipi_dbi_command(dbi, 0x25, 0x23); // GIP_1_SET5
+ mipi_dbi_command(dbi, 0x26, 0x45); // GIP_1_SET6
+ mipi_dbi_command(dbi, 0x27, 0x67); // GIP_1_SET7
+ mipi_dbi_command(dbi, 0x30, 0x11); // GIP_2_SET8
+ mipi_dbi_command(dbi, 0x31, 0x11); // GIP_2_SET9
+ mipi_dbi_command(dbi, 0x32, 0x00); // GIP_2_SET10
+ mipi_dbi_command(dbi, 0x33, 0xee); // GIP_2_SET11
+ mipi_dbi_command(dbi, 0x34, 0xff); // GIP_2_SET12
+ mipi_dbi_command(dbi, 0x35, 0xbb); // GIP_2_SET13
+ mipi_dbi_command(dbi, 0x36, 0xaa); // GIP_2_SET14
+ mipi_dbi_command(dbi, 0x37, 0xdd); // GIP_2_SET15
+ mipi_dbi_command(dbi, 0x38, 0xcc); // GIP_2_SET16
+ mipi_dbi_command(dbi, 0x39, 0x66); // GIP_2_SET17
+ mipi_dbi_command(dbi, 0x3a, 0x77); // GIP_2_SET18
+ mipi_dbi_command(dbi, 0x3b, 0x22); // GIP_2_SET19
+ mipi_dbi_command(dbi, 0x3c, 0x22); // GIP_2_SET20
+ mipi_dbi_command(dbi, 0x3d, 0x22); // GIP_2_SET21
+ mipi_dbi_command(dbi, 0x3e, 0x22); // GIP_2_SET22
+ mipi_dbi_command(dbi, 0x3f, 0x22); // GIP_2_SET23
+ mipi_dbi_command(dbi, 0x40, 0x22); // GIP_2_SET24
+ mipi_dbi_command(dbi, 0x52, 0x10); // undocumented
+ mipi_dbi_command(dbi, 0x53, 0x10); // GOUT_VGLO Control
+
+ ili9806e_switch_page(ctx, 7);
+
+ mipi_dbi_command(dbi, ILI9806E_P7_VGLREGEN, 0x22);
+ mipi_dbi_command(dbi, ILI9806E_P7_0x02, 0x77);
+ mipi_dbi_command(dbi, ILI9806E_P7_0xe1, 0x79);
+
+ ili9806e_switch_page(ctx, 0);
+
+ mipi_dbi_command(dbi, MIPI_DCS_SET_TEAR_ON);
+ mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
+
+ msleep(120);
+
+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
+
+ return 0;
+}
+
+static int ili9806e_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ const u32 bus_format = ILI9806E_BUS_FORMAT;
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(connector->dev, &nds040480800_v3_mode);
+ if (!mode)
+ return -ENOMEM;
+
+ drm_mode_set_name(mode);
+
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+ drm_display_info_set_bus_formats(&connector->display_info, &bus_format, 1);
+
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs ili9806e_drm_funcs = {
+ .unprepare = ili9806e_unprepare,
+ .prepare = ili9806e_prepare,
+ .get_modes = ili9806e_get_modes,
+};
+
+static int ili9806e_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct ili9806e *ctx;
+ int err;
+
+ ctx = devm_kzalloc(dev, sizeof(struct ili9806e), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ drm_panel_init(&ctx->panel, dev, &ili9806e_drm_funcs, DRM_MODE_CONNECTOR_DPI);
+
+ spi_set_drvdata(spi, ctx);
+
+ ctx->dbi.reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->dbi.reset))
+ return dev_err_probe(dev, PTR_ERR(ctx->dbi.reset), "cannot get reset-gpios\n");
+
+ err = drm_panel_of_backlight(&ctx->panel);
+ if (err)
+ return dev_err_probe(dev, err, "Failed to get backlight\n");
+
+ err = mipi_dbi_spi_init(spi, &ctx->dbi, NULL);
+ if (err)
+ return dev_err_probe(dev, err, "MIPI DBI init failed\n");
+
+ drm_panel_add(&ctx->panel);
+
+ return 0;
+}
+
+static void ili9806e_remove(struct spi_device *spi)
+{
+ struct ili9806e *ctx = spi_get_drvdata(spi);
+
+ drm_panel_remove(&ctx->panel);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ili9806e_suspend(struct device *dev)
+{
+ struct ili9806e *ctx = dev_get_drvdata(dev);
+ struct mipi_dbi *dbi = &ctx->dbi;
+
+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF, 0x00);
+ mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE, 0x00);
+
+ return 0;
+}
+
+static int ili9806e_resume(struct device *dev)
+{
+ struct ili9806e *ctx = dev_get_drvdata(dev);
+ struct mipi_dbi *dbi = &ctx->dbi;
+
+ mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE, 0x00);
+ msleep(120);
+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON, 0x00);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops ili9806e_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ili9806e_suspend, ili9806e_resume)
+};
+
+static const struct of_device_id ili9806e_of_match[] = {
+ { .compatible = "newdisplay,nds040480800-v3" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ili9806e_of_match);
+
+static const struct spi_device_id ili9806e_ids[] = {
+ { "nds040480800-v3", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(spi, ili9806e_ids);
+
+static struct spi_driver ili9806e_driver = {
+ .probe = ili9806e_probe,
+ .remove = ili9806e_remove,
+ .id_table = ili9806e_ids,
+ .driver = {
+ .name = "panel-ilitek-ili9806e",
+ .of_match_table = ili9806e_of_match,
+ .pm = &ili9806e_pm_ops,
+ },
+};
+module_spi_driver(ili9806e_driver);
+
+MODULE_AUTHOR("Luca Ceresoli <[email protected]>");
+MODULE_DESCRIPTION("Ilitek ILI9806E LCD Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
On Thu, 10 Aug 2023 16:41:14 +0200, Luca Ceresoli wrote:
> ShenZhen New Display Co., Limited is the manufacturer of the
> NDS040480800-V3 LCD panel according the datasheet.
>
> Signed-off-by: Luca Ceresoli <[email protected]>
>
> ---
>
> Changes in v2: none
> ---
> Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/[email protected]
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
On Thu, 10 Aug 2023 16:41:15 +0200, Luca Ceresoli wrote:
> Add bindings for LCD panels based on the ILITEK ILI9806E RGB controller
> connected over SPI and the "ShenZhen New Display Co NDS040480800-V3"
> 480x800 panel based on it.
>
> Signed-off-by: Luca Ceresoli <[email protected]>
>
> ---
>
> Changes in v2:
> - remove T: line form MAINTAINERS entry
> - reference spi-peripheral-props.yaml
> - add 'maxItems: 1' to reg
> - use unevaluatedProperties
> - remove out of scope backlight node
> ---
> .../display/panel/ilitek,ili9806e.yaml | 63 +++++++++++++++++++
> MAINTAINERS | 5 ++
> 2 files changed, 68 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/[email protected]
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
On Thu, Aug 10, 2023 at 04:41:14PM +0200, Luca Ceresoli wrote:
> ShenZhen New Display Co., Limited is the manufacturer of the
> NDS040480800-V3 LCD panel according the datasheet.
>
> Signed-off-by: Luca Ceresoli <[email protected]>
Acked-by: Conor Dooley <[email protected]>
On Thu, 10 Aug 2023 16:41:15 +0200, Luca Ceresoli wrote:
> Add bindings for LCD panels based on the ILITEK ILI9806E RGB controller
> connected over SPI and the "ShenZhen New Display Co NDS040480800-V3"
> 480x800 panel based on it.
>
> Signed-off-by: Luca Ceresoli <[email protected]>
>
> ---
>
> Changes in v2:
> - remove T: line form MAINTAINERS entry
> - reference spi-peripheral-props.yaml
> - add 'maxItems: 1' to reg
> - use unevaluatedProperties
> - remove out of scope backlight node
> ---
> .../display/panel/ilitek,ili9806e.yaml | 63 +++++++++++++++++++
> MAINTAINERS | 5 ++
> 2 files changed, 68 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9806e.yaml
>
Reviewed-by: Rob Herring <[email protected]>
On Thu, 10 Aug 2023 16:41:14 +0200, Luca Ceresoli wrote:
> ShenZhen New Display Co., Limited is the manufacturer of the
> NDS040480800-V3 LCD panel according the datasheet.
>
> Signed-off-by: Luca Ceresoli <[email protected]>
>
> ---
>
> Changes in v2: none
> ---
> Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
Acked-by: Rob Herring <[email protected]>