Dear Thierry,
I understand that your opinion is:
It is better to handle the error every time it is input to the
register, rather than error handling at once in the struct using
error. This not only makes the code easier to maintain, but also
reduces unnecessary computation.
So I modified the panel driver to code-by-code error handling.
If this is not your opinion, could you tell me what your opinion?
Best Regards,
Hoegeun
Changes for V11:
- Added the Reviewed-by: Javier Martinez Canillas <[email protected]>
(1/3, 3/3 patches)
- Checked for rebase 4.11 rc1.
Changes for V10:
- Fixed code-by-code error handling.
Changes for V9:
- Fixed the te-gpio to optional in bindings
Changes for V8:
- Applied below two patches: (drm/exynos)
: drm/exynos: mic: Add mode_set callback function
: drm/exynos: mic: Fix parse_dt function
- The dt-binding patch and driver patch were divided.
- Rebase these patches on samsung SoC tree[1] and tm2 touckey patch[2].
Change for V7:
- Fixed the mode_set callback function of mic device driver.
because the mic register is initialized when entering suspend
mode, so should set the reg value whenever pre_enable is
called.
Changes for V6:
- Fixed the parse_dt function of dsi device driver.
- Removed OF graph of panel in DT and DT binding document.
- Fixed the s6e3ha2 panel device driver.
- Fixed from number size to ARRAY_SIZE().
- Fixed error handling in mipi_dsi_dcs_* functions.
- Fixed the clock of display_mode.
- Removed unnecessary casting and error log.
Change for V5:
- The V5 has only one fix in V4 below.
- Removed the enable check of the mic driver in mode_set
callback, because mode_set should be performed every time.
Changes for V4:
- Removed display-timings in devicetree, the display-timings has
been fixed to be provided by the device driver.
- Added the mode_set callback function into exynos_drm_mic,
because the exynos_drm_mic driver can not parse a videomode
struct by removing the display-timings from the devicetree.
Changes for V3:
- In the DT binding document, made it clearly that the panel is a
child node of dsi.
- Fix reset-gpio active from high to low.
- Is the OF graph saying related to patch2?
Althogh the panel is a child of dsi, I think OF graph necessary.
because if a remote-endpoint is not specified, the dsi also
panel is not probed.
- The display-timings has been fixed to be provided by the device
driver. however, I think display-timings is necessary in dts.
because if dts does not have display-timings, dsi will not load.
Changes for V2:
- Fixed the samsung,s6e3ha2.txt DT document.
- Added active high or low after the description of the GPIOs.
- Removed the reg and added a description of the virtual
channel number of a DSI peripheral.
Depends on:
[1] https://git.kernel.org/cgit/linux/kernel/git/krzk/linux.git/ (for-next branch)
[2] https://patchwork.kernel.org/patch/9504131/
- ("arm64: dts: exynos: Add tm2 touchkey node")
Hoegeun Kwon (2):
dt-bindings: Add support for samsung s6e3ha2 panel binding
drm/panel: Add support for S6E3HA2 panel driver on TM2 board
Hyungwon Hwang (1):
arm64: dts: exynos: Add support for S6E3HA2 panel device on TM2 board
.../bindings/display/panel/samsung,s6e3ha2.txt | 28 +
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 12 +
drivers/gpu/drm/panel/Kconfig | 6 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 739 +++++++++++++++++++++
5 files changed, 786 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
--
1.9.1
This patch add support for MIPI-DSI based S6E3HA2 AMOLED panel
driver. This panel has 1440x2560 resolution in 5.7-inch physical
panel in the TM2 device.
Signed-off-by: Donghwa Lee <[email protected]>
Signed-off-by: Hyungwon Hwang <[email protected]>
Signed-off-by: Hoegeun Kwon <[email protected]>
Tested-by: Chanwoo Choi <[email protected]>
Reviewed-by: Andrzej Hajda <[email protected]>
---
drivers/gpu/drm/panel/Kconfig | 6 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 739 ++++++++++++++++++++++++++
3 files changed, 746 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 62aba97..d913c83 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -52,6 +52,12 @@ config DRM_PANEL_PANASONIC_VVX10F034N00
WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
Xperia Z2 tablets
+config DRM_PANEL_SAMSUNG_S6E3HA2
+ tristate "Samsung S6E3HA2 DSI video mode panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ select VIDEOMODE_HELPERS
+
config DRM_PANEL_SAMSUNG_S6E8AA0
tristate "Samsung S6E8AA0 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index a5c7ec0..1d483b0 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
new file mode 100644
index 0000000..4cc08d7
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
@@ -0,0 +1,739 @@
+/*
+ * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver.
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Donghwa Lee <[email protected]>
+ * Hyungwon Hwang <[email protected]>
+ * Hoegeun Kwon <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+#include <linux/backlight.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#define S6E3HA2_MIN_BRIGHTNESS 0
+#define S6E3HA2_MAX_BRIGHTNESS 100
+#define S6E3HA2_DEFAULT_BRIGHTNESS 80
+
+#define S6E3HA2_NUM_GAMMA_STEPS 46
+#define S6E3HA2_GAMMA_CMD_CNT 35
+#define S6E3HA2_VINT_STATUS_MAX 10
+
+static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = {
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83,
+ 0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c,
+ 0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84,
+ 0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a,
+ 0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a,
+ 0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a,
+ 0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85,
+ 0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b,
+ 0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b,
+ 0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89,
+ 0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c,
+ 0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88,
+ 0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a,
+ 0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b,
+ 0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c,
+ 0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c,
+ 0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
+ 0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
+ 0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b,
+ 0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
+ 0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e,
+ 0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e,
+ 0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d,
+ 0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
+ 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c,
+ 0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83,
+ 0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a,
+ 0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83,
+ 0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a,
+ 0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83,
+ 0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89,
+ 0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83,
+ 0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a,
+ 0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82,
+ 0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87,
+ 0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82,
+ 0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88,
+ 0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83,
+ 0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89,
+ 0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82,
+ 0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86,
+ 0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82,
+ 0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87,
+ 0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81,
+ 0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86,
+ 0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82,
+ 0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83,
+ 0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82,
+ 0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82,
+ 0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80,
+ 0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81,
+ 0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
+ 0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
+ 0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82,
+ 0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83,
+ 0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83,
+ 0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80,
+ 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81,
+ 0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81,
+ 0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83,
+ 0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80,
+ 0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80,
+ 0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80,
+ 0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d,
+ 0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80,
+ 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82,
+ 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80,
+ 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 },
+ { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00 }
+};
+
+unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = {
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c,
+ 0x1d, 0x1e, 0x1f, 0x20, 0x21
+};
+
+struct s6e3ha2 {
+ struct device *dev;
+ struct drm_panel panel;
+ struct backlight_device *bl_dev;
+
+ struct regulator_bulk_data supplies[2];
+ struct gpio_desc *reset_gpio;
+ struct gpio_desc *enable_gpio;
+};
+
+static int s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ return mipi_dsi_dcs_write_buffer(dsi, data, len);
+}
+
+#define s6e3ha2_dcs_write_seq_static(ctx, seq...) do { \
+ static const u8 d[] = { seq }; \
+ int ret; \
+ ret = s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d)); \
+ if (ret < 0) \
+ return ret; \
+} while (0)
+
+#define s6e3ha2_call_write_func(ret, func) do { \
+ ret = (func); \
+ if (ret < 0) \
+ return ret; \
+} while (0)
+
+static int s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
+ return 0;
+}
+
+static int s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5);
+ return 0;
+}
+
+static int s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
+ return 0;
+}
+
+static int s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5);
+ return 0;
+}
+
+static int s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67);
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09);
+ return 0;
+}
+
+static int s6e3ha2_freq_calibration(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c);
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39);
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0);
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20);
+ s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62, 0x40,
+ 0x80, 0xc0, 0x28, 0x28, 0x28, 0x28, 0x39, 0xc5);
+ return 0;
+}
+
+static int s6e3ha2_aor_control(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10);
+ return 0;
+}
+
+static int s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a);
+ return 0;
+}
+
+static int s6e3ha2_acl_off(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00);
+ return 0;
+}
+
+static int s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40);
+ return 0;
+}
+
+static int s6e3ha2_test_global(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07);
+ return 0;
+}
+
+static int s6e3ha2_test(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19);
+ return 0;
+}
+
+static int s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xbd, 0x33, 0x11, 0x02,
+ 0x16, 0x02, 0x16);
+ return 0;
+}
+
+static int s6e3ha2_pentile_control(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8);
+ return 0;
+}
+
+static int s6e3ha2_poc_global(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20);
+ return 0;
+}
+
+static int s6e3ha2_poc_setting(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08);
+ return 0;
+}
+
+static int s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51);
+ return 0;
+}
+
+static int s6e3ha2_err_fg_set(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44);
+ return 0;
+}
+
+static int s6e3ha2_hbm_off(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00);
+ return 0;
+}
+
+static int s6e3ha2_te_start_setting(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09);
+ return 0;
+}
+
+static int s6e3ha2_gamma_update(struct s6e3ha2 *ctx)
+{
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03);
+ ndelay(100); /* need for 100ns delay */
+ s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00);
+ return 0;
+}
+
+static int s6e3ha2_get_brightness(struct backlight_device *bl_dev)
+{
+ return bl_dev->props.brightness;
+}
+
+static int s6e3ha2_set_vint(struct s6e3ha2 *ctx)
+{
+ struct backlight_device *bl_dev = ctx->bl_dev;
+ unsigned int brightness = bl_dev->props.brightness;
+ unsigned char data[] = { 0xf4, 0x8b,
+ vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) /
+ S6E3HA2_MAX_BRIGHTNESS] };
+
+ return s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data));
+}
+
+static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness)
+{
+ return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) /
+ S6E3HA2_MAX_BRIGHTNESS;
+}
+
+static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness)
+{
+ struct backlight_device *bl_dev = ctx->bl_dev;
+ unsigned int index = s6e3ha2_get_brightness_index(brightness);
+ u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, };
+ int ret;
+
+ memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT);
+ s6e3ha2_call_write_func(ret,
+ s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data)));
+
+ s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
+ bl_dev->props.brightness = brightness;
+
+ return 0;
+}
+
+static int s6e3ha2_set_brightness(struct backlight_device *bl_dev)
+{
+ struct s6e3ha2 *ctx = bl_get_data(bl_dev);
+ unsigned int brightness = bl_dev->props.brightness;
+ int ret;
+
+ if (brightness < S6E3HA2_MIN_BRIGHTNESS ||
+ brightness > bl_dev->props.max_brightness) {
+ dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
+ return -EINVAL;
+ }
+
+ if (bl_dev->props.power > FB_BLANK_NORMAL)
+ return -EPERM;
+
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_update_gamma(ctx, brightness));
+ s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_set_vint(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
+
+ return 0;
+}
+
+static const struct backlight_ops s6e3ha2_bl_ops = {
+ .get_brightness = s6e3ha2_get_brightness,
+ .update_status = s6e3ha2_set_brightness,
+};
+
+static int s6e3ha2_panel_init(struct s6e3ha2 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ s6e3ha2_call_write_func(ret, mipi_dsi_dcs_exit_sleep_mode(dsi));
+ usleep_range(5000, 6000);
+
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_single_dsi_set(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_freq_calibration(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
+
+ return 0;
+}
+
+static int s6e3ha2_power_off(struct s6e3ha2 *ctx)
+{
+ return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+}
+
+static int s6e3ha2_disable(struct drm_panel *panel)
+{
+ struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ s6e3ha2_call_write_func(ret, mipi_dsi_dcs_enter_sleep_mode(dsi));
+ s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_off(dsi));
+
+ msleep(40);
+ ctx->bl_dev->props.power = FB_BLANK_NORMAL;
+
+ return 0;
+}
+
+static int s6e3ha2_unprepare(struct drm_panel *panel)
+{
+ struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
+
+ return s6e3ha2_power_off(ctx);
+}
+
+static int s6e3ha2_power_on(struct s6e3ha2 *ctx)
+{
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ msleep(120);
+
+ gpiod_set_value(ctx->enable_gpio, 0);
+ usleep_range(5000, 6000);
+ gpiod_set_value(ctx->enable_gpio, 1);
+
+ gpiod_set_value(ctx->reset_gpio, 1);
+ usleep_range(5000, 6000);
+ gpiod_set_value(ctx->reset_gpio, 0);
+ usleep_range(5000, 6000);
+
+ return 0;
+}
+static int s6e3ha2_prepare(struct drm_panel *panel)
+{
+ struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
+ int ret;
+
+ ret = s6e3ha2_power_on(ctx);
+ if (ret < 0)
+ return ret;
+
+ ret = s6e3ha2_panel_init(ctx);
+ if (ret < 0)
+ goto err;
+
+ ctx->bl_dev->props.power = FB_BLANK_NORMAL;
+
+ return 0;
+
+err:
+ s6e3ha2_power_off(ctx);
+ return ret;
+}
+
+static int s6e3ha2_enable(struct drm_panel *panel)
+{
+ struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ /* common setting */
+ s6e3ha2_call_write_func(ret,
+ mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK));
+
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_touch_hsync_on1(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_pentile_control(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_poc_global(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_poc_setting(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
+
+ /* pcd setting off for TB */
+ s6e3ha2_call_write_func(ret, s6e3ha2_pcd_set_off(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_err_fg_set(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_te_start_setting(ctx));
+
+ /* brightness setting */
+ s6e3ha2_call_write_func(ret, s6e3ha2_set_brightness(ctx->bl_dev));
+ s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_caps_elvss_set(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_acl_off(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_acl_off_opr(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_hbm_off(ctx));
+
+ /* elvss temp compensation */
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_global(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test(ctx));
+ s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
+
+ s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_on(dsi));
+ ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
+
+ return 0;
+}
+
+static const struct drm_display_mode default_mode = {
+ .clock = 222372,
+ .hdisplay = 1440,
+ .hsync_start = 1440 + 1,
+ .hsync_end = 1440 + 1 + 1,
+ .htotal = 1440 + 1 + 1 + 1,
+ .vdisplay = 2560,
+ .vsync_start = 2560 + 1,
+ .vsync_end = 2560 + 1 + 1,
+ .vtotal = 2560 + 1 + 1 + 15,
+ .vrefresh = 60,
+ .flags = 0,
+};
+
+static int s6e3ha2_get_modes(struct drm_panel *panel)
+{
+ struct drm_connector *connector = panel->connector;
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(panel->drm, &default_mode);
+ if (!mode) {
+ DRM_ERROR("failed to add mode %ux%ux@%u\n",
+ default_mode.hdisplay, default_mode.vdisplay,
+ default_mode.vrefresh);
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+ drm_mode_probed_add(connector, mode);
+
+ connector->display_info.width_mm = 71;
+ connector->display_info.height_mm = 125;
+
+ return 1;
+}
+
+static const struct drm_panel_funcs s6e3ha2_drm_funcs = {
+ .disable = s6e3ha2_disable,
+ .unprepare = s6e3ha2_unprepare,
+ .prepare = s6e3ha2_prepare,
+ .enable = s6e3ha2_enable,
+ .get_modes = s6e3ha2_get_modes,
+};
+
+static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct s6e3ha2 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ ctx->dev = dev;
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ ctx->supplies[0].supply = "vdd3";
+ ctx->supplies[1].supply = "vci";
+
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+ ctx->supplies);
+ if (ret < 0) {
+ dev_err(dev, "failed to get regulators: %d\n", ret);
+ return ret;
+ }
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->reset_gpio)) {
+ dev_err(dev, "cannot get reset-gpios %ld\n",
+ PTR_ERR(ctx->reset_gpio));
+ return PTR_ERR(ctx->reset_gpio);
+ }
+
+ ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->enable_gpio)) {
+ dev_err(dev, "cannot get enable-gpios %ld\n",
+ PTR_ERR(ctx->enable_gpio));
+ return PTR_ERR(ctx->enable_gpio);
+ }
+
+ ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx,
+ &s6e3ha2_bl_ops, NULL);
+ if (IS_ERR(ctx->bl_dev)) {
+ dev_err(dev, "failed to register backlight device\n");
+ return PTR_ERR(ctx->bl_dev);
+ }
+
+ ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS;
+ ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
+ ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
+
+ drm_panel_init(&ctx->panel);
+ ctx->panel.dev = dev;
+ ctx->panel.funcs = &s6e3ha2_drm_funcs;
+
+ ret = drm_panel_add(&ctx->panel);
+ if (ret < 0)
+ goto unregister_backlight;
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0)
+ goto remove_panel;
+
+ return ret;
+
+remove_panel:
+ drm_panel_remove(&ctx->panel);
+
+unregister_backlight:
+ backlight_device_unregister(ctx->bl_dev);
+
+ return ret;
+}
+
+static int s6e3ha2_remove(struct mipi_dsi_device *dsi)
+{
+ struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi);
+
+ mipi_dsi_detach(dsi);
+ drm_panel_remove(&ctx->panel);
+ backlight_device_unregister(ctx->bl_dev);
+
+ return 0;
+}
+
+static const struct of_device_id s6e3ha2_of_match[] = {
+ { .compatible = "samsung,s6e3ha2" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, s6e3ha2_of_match);
+
+static struct mipi_dsi_driver s6e3ha2_driver = {
+ .probe = s6e3ha2_probe,
+ .remove = s6e3ha2_remove,
+ .driver = {
+ .name = "panel-samsung-s6e3ha2",
+ .of_match_table = s6e3ha2_of_match,
+ },
+};
+module_mipi_dsi_driver(s6e3ha2_driver);
+
+MODULE_AUTHOR("Donghwa Lee <[email protected]>");
+MODULE_AUTHOR("Hyungwon Hwang <[email protected]>");
+MODULE_AUTHOR("Hoegeun Kwon <[email protected]>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
From: Hyungwon Hwang <[email protected]>
This patch add the panel device tree node for S6E3HA2 display
controller to TM2 dts.
Signed-off-by: Hyungwon Hwang <[email protected]>
Signed-off-by: Andrzej Hajda <[email protected]>
Signed-off-by: Chanwoo Choi <[email protected]>
Signed-off-by: Hoegeun Kwon <[email protected]>
Tested-by: Chanwoo Choi <[email protected]>
Reviewed-by: Javier Martinez Canillas <[email protected]>
---
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index dea0a6f..db3fed2 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -52,6 +52,18 @@
assigned-clock-rates = <250000000>, <400000000>;
};
+&dsi {
+ panel@0 {
+ compatible = "samsung,s6e3ha2";
+ reg = <0>;
+ vdd3-supply = <&ldo27_reg>;
+ vci-supply = <&ldo28_reg>;
+ reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+ te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
+ };
+};
+
&hsi2c_9 {
status = "okay";
--
1.9.1
The Samsung s6e3ha2 is a 5.7" 1440x2560 AMOLED panel connected
using MIPI-DSI interfaces.
Signed-off-by: Donghwa Lee <[email protected]>
Signed-off-by: Hyungwon Hwang <[email protected]>
Signed-off-by: Hoegeun Kwon <[email protected]>
Reviewed-by: Andrzej Hajda <[email protected]>
Reviewed-by: Javier Martinez Canillas <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
.../bindings/display/panel/samsung,s6e3ha2.txt | 28 ++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
new file mode 100644
index 0000000..18854f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
@@ -0,0 +1,28 @@
+Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel
+
+Required properties:
+ - compatible: "samsung,s6e3ha2"
+ - reg: the virtual channel number of a DSI peripheral
+ - vdd3-supply: I/O voltage supply
+ - vci-supply: voltage supply for analog circuits
+ - reset-gpios: a GPIO spec for the reset pin (active low)
+ - enable-gpios: a GPIO spec for the panel enable pin (active high)
+
+Optional properties:
+ - te-gpios: a GPIO spec for the tearing effect synchronization signal
+ gpio pin (active high)
+
+Example:
+&dsi {
+ ...
+
+ panel@0 {
+ compatible = "samsung,s6e3ha2";
+ reg = <0>;
+ vdd3-supply = <&ldo27_reg>;
+ vci-supply = <&ldo28_reg>;
+ reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+ te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
+ };
+};
--
1.9.1
On Wed, Mar 08, 2017 at 10:42:37AM +0900, Hoegeun Kwon wrote:
> From: Hyungwon Hwang <[email protected]>
>
> This patch add the panel device tree node for S6E3HA2 display
> controller to TM2 dts.
>
> Signed-off-by: Hyungwon Hwang <[email protected]>
> Signed-off-by: Andrzej Hajda <[email protected]>
> Signed-off-by: Chanwoo Choi <[email protected]>
> Signed-off-by: Hoegeun Kwon <[email protected]>
> Tested-by: Chanwoo Choi <[email protected]>
> Reviewed-by: Javier Martinez Canillas <[email protected]>
> ---
> arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
Thanks, applied.
Best regards,
Krzysztof
Dear Thierry,
I would like your review please.
I try to modify it to your advice.
Please let me know if you have any other advice.
Best regards,
Hoegeun
On 03/08/2017 10:42 AM, Hoegeun Kwon wrote:
> Dear Thierry,
>
> I understand that your opinion is:
> It is better to handle the error every time it is input to the
> register, rather than error handling at once in the struct using
> error. This not only makes the code easier to maintain, but also
> reduces unnecessary computation.
>
> So I modified the panel driver to code-by-code error handling.
> If this is not your opinion, could you tell me what your opinion?
>
> Best Regards,
> Hoegeun
>
> Changes for V11:
> - Added the Reviewed-by: Javier Martinez Canillas <[email protected]>
> (1/3, 3/3 patches)
> - Checked for rebase 4.11 rc1.
>
> Changes for V10:
> - Fixed code-by-code error handling.
>
> Changes for V9:
> - Fixed the te-gpio to optional in bindings
>
> Changes for V8:
> - Applied below two patches: (drm/exynos)
> : drm/exynos: mic: Add mode_set callback function
> : drm/exynos: mic: Fix parse_dt function
> - The dt-binding patch and driver patch were divided.
> - Rebase these patches on samsung SoC tree[1] and tm2 touckey patch[2].
>
> Change for V7:
> - Fixed the mode_set callback function of mic device driver.
> because the mic register is initialized when entering suspend
> mode, so should set the reg value whenever pre_enable is
> called.
>
> Changes for V6:
> - Fixed the parse_dt function of dsi device driver.
> - Removed OF graph of panel in DT and DT binding document.
> - Fixed the s6e3ha2 panel device driver.
> - Fixed from number size to ARRAY_SIZE().
> - Fixed error handling in mipi_dsi_dcs_* functions.
> - Fixed the clock of display_mode.
> - Removed unnecessary casting and error log.
>
> Change for V5:
> - The V5 has only one fix in V4 below.
> - Removed the enable check of the mic driver in mode_set
> callback, because mode_set should be performed every time.
>
> Changes for V4:
> - Removed display-timings in devicetree, the display-timings has
> been fixed to be provided by the device driver.
> - Added the mode_set callback function into exynos_drm_mic,
> because the exynos_drm_mic driver can not parse a videomode
> struct by removing the display-timings from the devicetree.
>
> Changes for V3:
> - In the DT binding document, made it clearly that the panel is a
> child node of dsi.
> - Fix reset-gpio active from high to low.
> - Is the OF graph saying related to patch2?
> Althogh the panel is a child of dsi, I think OF graph necessary.
> because if a remote-endpoint is not specified, the dsi also
> panel is not probed.
> - The display-timings has been fixed to be provided by the device
> driver. however, I think display-timings is necessary in dts.
> because if dts does not have display-timings, dsi will not load.
>
> Changes for V2:
> - Fixed the samsung,s6e3ha2.txt DT document.
> - Added active high or low after the description of the GPIOs.
> - Removed the reg and added a description of the virtual
> channel number of a DSI peripheral.
>
> Depends on:
> [1] https://git.kernel.org/cgit/linux/kernel/git/krzk/linux.git/ (for-next branch)
> [2] https://patchwork.kernel.org/patch/9504131/
> - ("arm64: dts: exynos: Add tm2 touchkey node")
>
> Hoegeun Kwon (2):
> dt-bindings: Add support for samsung s6e3ha2 panel binding
> drm/panel: Add support for S6E3HA2 panel driver on TM2 board
>
> Hyungwon Hwang (1):
> arm64: dts: exynos: Add support for S6E3HA2 panel device on TM2 board
>
> .../bindings/display/panel/samsung,s6e3ha2.txt | 28 +
> arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 12 +
> drivers/gpu/drm/panel/Kconfig | 6 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 739 +++++++++++++++++++++
> 5 files changed, 786 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
>
On Wed, Mar 08, 2017 at 10:42:36AM +0900, Hoegeun Kwon wrote:
> This patch add support for MIPI-DSI based S6E3HA2 AMOLED panel
> driver. This panel has 1440x2560 resolution in 5.7-inch physical
> panel in the TM2 device.
>
> Signed-off-by: Donghwa Lee <[email protected]>
> Signed-off-by: Hyungwon Hwang <[email protected]>
> Signed-off-by: Hoegeun Kwon <[email protected]>
> Tested-by: Chanwoo Choi <[email protected]>
> Reviewed-by: Andrzej Hajda <[email protected]>
> ---
> drivers/gpu/drm/panel/Kconfig | 6 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 739 ++++++++++++++++++++++++++
> 3 files changed, 746 insertions(+)
> create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
Applied, thanks.
Thierry
On Wed, Mar 08, 2017 at 10:42:35AM +0900, Hoegeun Kwon wrote:
> The Samsung s6e3ha2 is a 5.7" 1440x2560 AMOLED panel connected
> using MIPI-DSI interfaces.
>
> Signed-off-by: Donghwa Lee <[email protected]>
> Signed-off-by: Hyungwon Hwang <[email protected]>
> Signed-off-by: Hoegeun Kwon <[email protected]>
> Reviewed-by: Andrzej Hajda <[email protected]>
> Reviewed-by: Javier Martinez Canillas <[email protected]>
> Acked-by: Rob Herring <[email protected]>
> ---
> .../bindings/display/panel/samsung,s6e3ha2.txt | 28 ++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
Applied, thanks.
Thierry