2023-08-10 15:42:14

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v2 1/3] dt-bindings: vendor-prefixes: add ShenZhen New Display Co.

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



2023-08-10 15:43:56

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v2 2/3] dt-bindings: display: panel: Add panels based on ILITEK ILI9806E

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


2023-08-10 15:48:26

by Luca Ceresoli

[permalink] [raw]
Subject: [PATCH v2 3/3] DRM: panel: add Ilitek ILI9806E driver

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


2023-08-10 16:49:28

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] dt-bindings: vendor-prefixes: add ShenZhen New Display Co.


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.


2023-08-10 16:49:43

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] dt-bindings: display: panel: Add panels based on ILITEK ILI9806E


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.


2023-08-10 19:26:46

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] dt-bindings: vendor-prefixes: add ShenZhen New Display Co.

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]>


Attachments:
(No filename) (301.00 B)
signature.asc (235.00 B)
Download all attachments

2023-08-10 22:03:58

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] dt-bindings: display: panel: Add panels based on ILITEK ILI9806E


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]>


2023-08-10 22:05:33

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] dt-bindings: vendor-prefixes: add ShenZhen New Display Co.


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]>