diff options
Diffstat (limited to 'drivers/gpu/drm/panel')
| -rw-r--r-- | drivers/gpu/drm/panel/Kconfig | 59 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/Makefile | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-edp.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 1327 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 69 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-lg-ld070wx3.c | 184 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-newvision-nv3052c.c | 408 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-ronbo-rb070d30.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-samsung-s6e3fc2x01.c | 385 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-samsung-sofef00.c | 105 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c | 225 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-simple.c | 127 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-synaptics-tddi.c | 277 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-visionox-rm69299.c | 71 |
15 files changed, 2412 insertions, 868 deletions
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 407c5f6a268b..76f6af819037 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -408,6 +408,19 @@ config DRM_PANEL_LG_LB035Q02 (found on the Gumstix Overo Palo35 board). To compile this driver as a module, choose M here. +config DRM_PANEL_LG_LD070WX3 + tristate "LG LD070WX3 MIPI DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for the LD070WX3 MIPI DSI + panel found in the NVIDIA Tegra Note 7 tablet. + + To compile this driver as a module, choose M here: the module will + be called panel-lg-ld070wx3. + config DRM_PANEL_LG_LG4573 tristate "LG4573 RGB/SPI panel" depends on OF && SPI @@ -801,6 +814,19 @@ config DRM_PANEL_SAMSUNG_S6D7AA0 select DRM_MIPI_DSI select VIDEOMODE_HELPERS +config DRM_PANEL_SAMSUNG_S6E3FC2X01 + tristate "Samsung S6E3FC2X01 DSI panel controller" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y or M here if you want to enable support for the + Samsung S6E3FC2 DDIC and connected MIPI DSI panel. + Currently supported panels: + + Samsung AMS641RW (found in the OnePlus 6T smartphone) + config DRM_PANEL_SAMSUNG_S6E3HA2 tristate "Samsung S6E3HA2 DSI video mode panel" depends on OF @@ -868,16 +894,17 @@ config DRM_PANEL_SAMSUNG_S6E8AA5X01_AMS561RA01 DSI protocol with 4 lanes. config DRM_PANEL_SAMSUNG_SOFEF00 - tristate "Samsung sofef00/s6e3fc2x01 OnePlus 6/6T DSI cmd mode panels" + tristate "Samsung SOFEF00 DSI panel controller" depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE select VIDEOMODE_HELPERS help Say Y or M here if you want to enable support for the Samsung AMOLED - command mode panels found in the OnePlus 6/6T smartphones. + panel SOFEF00 DDIC and connected panel. + Currently supported panels: - The panels are 2280x1080@60Hz and 2340x1080@60Hz respectively + Samsung AMS628NW01 (found in OnePlus 6, 1080x2280@60Hz) config DRM_PANEL_SEIKO_43WVF1G tristate "Seiko 43WVF1G panel" @@ -888,6 +915,21 @@ config DRM_PANEL_SEIKO_43WVF1G Say Y here if you want to enable support for the Seiko 43WVF1G controller for 800x480 LCD panels +config DRM_PANEL_SHARP_LQ079L1SX01 + tristate "Sharp LQ079L1SX01 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for Sharp LQ079L1SX01 + TFT-LCD modules. The panel has a 2560x1600 resolution and uses + 24 bit RGB per pixel. It provides a dual MIPI DSI interface to + the host. + + To compile this driver as a module, choose M here: the module + will be called panel-sharp-lq079l1sx01. + config DRM_PANEL_SHARP_LQ101R1SX01 tristate "Sharp LQ101R1SX01 panel" depends on OF @@ -1045,6 +1087,17 @@ config DRM_PANEL_SYNAPTICS_R63353 Say Y if you want to enable support for panels based on the Synaptics R63353 controller. +config DRM_PANEL_SYNAPTICS_TDDI + tristate "Synaptics TDDI display panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for the Synaptics TDDI display + panels. There are multiple MIPI DSI panels manufactured under the TDDI + namesake, with varying resolutions and data lanes. They also have a + built-in LED backlight and a touch controller. + config DRM_PANEL_TDO_TL070WSH30 tristate "TDO TL070WSH30 DSI panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 3615a761b44f..b9562a6fdcb3 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o obj-$(CONFIG_DRM_PANEL_LINCOLNTECH_LCD197) += panel-lincolntech-lcd197.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o +obj-$(CONFIG_DRM_PANEL_LG_LD070WX3) += panel-lg-ld070wx3.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o @@ -79,6 +80,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7) += panel-samsung-s6e3fa7.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FC2X01) += panel-samsung-s6e3fc2x01.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA8) += panel-samsung-s6e3ha8.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o @@ -91,6 +93,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA5X01_AMS561RA01) += panel-samsung-s6e8aa5x01-ams561ra01.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_SOFEF00) += panel-samsung-sofef00.o obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o +obj-$(CONFIG_DRM_PANEL_SHARP_LQ079L1SX01) += panel-sharp-lq079l1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o @@ -100,6 +103,7 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o obj-$(CONFIG_DRM_PANEL_SUMMIT) += panel-summit.o obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63353) += panel-synaptics-r63353.o +obj-$(CONFIG_DRM_PANEL_SYNAPTICS_TDDI) += panel-synaptics-tddi.o obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 62435e3cd9f4..415b894890ad 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1888,6 +1888,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x203d, &delay_200_500_e50, "B140HTN02.0"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0x205c, &delay_200_500_e50, "B116XAN02.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x208d, &delay_200_500_e50, "B140HTN02.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x239b, &delay_200_500_e50, "B116XAN06.1"), @@ -1909,6 +1910,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0x8bba, &delay_200_500_e50, "B140UAN08.5"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xa199, &delay_200_500_e50, "B116XAN06.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xa7b3, &delay_200_500_e50, "B140UAN04.4"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0xb7a9, &delay_200_500_e50, "B140HAK03.3"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xc4b4, &delay_200_500_e50, "B116XAT04.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xc9a8, &delay_200_500_e50, "B140QAN08.H"), EDP_PANEL_ENTRY('A', 'U', 'O', 0xcdba, &delay_200_500_e50, "B140UAX01.2"), @@ -1963,6 +1965,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a3e, &delay_200_500_e80_d50, "NV116WHM-N49"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a6a, &delay_200_500_e80, "NV140WUM-N44"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a84, &delay_200_500_e50, "NV133WUM-T01"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ac5, &delay_200_500_e50, "NV116WHM-N4C"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ae8, &delay_200_500_e50_p2e80, "NV140WUM-N41"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b09, &delay_200_500_e50_po2e200, "NV140FHM-NZ"), @@ -1974,6 +1977,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('B', 'O', 'E', 0x0c20, &delay_200_500_e80, "NT140FHM-N47"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0c93, &delay_200_500_e200, "Unknown"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cb6, &delay_200_500_e200, "NT116WHM-N44"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cf2, &delay_200_500_e200, "NV156FHM-N4S"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cf6, &delay_200_500_e200, "NV140WUM-N64"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0cfa, &delay_200_500_e50, "NV116WHM-A4D"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0d45, &delay_200_500_e80, "NV116WHM-N4B"), @@ -2007,10 +2011,12 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'M', 'N', 0x1441, &delay_200_500_e80_d50, "N140JCA-ELK"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x144f, &delay_200_500_e80_d50, "N140HGA-EA1"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1468, &delay_200_500_e80, "N140HGA-EA1"), + EDP_PANEL_ENTRY('C', 'M', 'N', 0x148f, &delay_200_500_e80, "N140HCA-EAC"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14a8, &delay_200_500_e80, "N140JCA-ELP"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d4, &delay_200_500_e80_d50, "N140HCA-EAC"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d6, &delay_200_500_e80_d50, "N140BGA-EA4"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14e5, &delay_200_500_e80_d50, "N140HGA-EA1"), + EDP_PANEL_ENTRY('C', 'M', 'N', 0x1565, &delay_200_500_e80, "N156HCA-EAB"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x162b, &delay_200_500_e80_d50, "N160JCE-ELL"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x7402, &delay_200_500_e200_d50, "N116BCA-EAK"), @@ -2022,10 +2028,12 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'S', 'W', 0x1104, &delay_200_500_e50_d100, "MNB601LS1-4"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x143f, &delay_200_500_e50, "MNE007QS3-6"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1448, &delay_200_500_e50, "MNE007QS3-7"), + EDP_PANEL_ENTRY('C', 'S', 'W', 0x144b, &delay_200_500_e80, "MNE001BS1-4"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1457, &delay_80_500_e80_p2e200, "MNE007QS3-8"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1462, &delay_200_500_e50, "MNE007QS5-2"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x1468, &delay_200_500_e50, "MNE007QB2-2"), EDP_PANEL_ENTRY('C', 'S', 'W', 0x146e, &delay_80_500_e50_d50, "MNE007QB3-1"), + EDP_PANEL_ENTRY('C', 'S', 'W', 0x1519, &delay_200_500_e80_d50, "MNF601BS1-3"), EDP_PANEL_ENTRY('E', 'T', 'C', 0x0000, &delay_50_500_e200_d200_po2e335, "LP079QX1-SP0V"), @@ -2046,6 +2054,8 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('K', 'D', 'B', 0x1212, &delay_200_500_e50, "KD116N0930A16"), EDP_PANEL_ENTRY('K', 'D', 'B', 0x1707, &delay_200_150_e50, "KD116N2130B12"), + EDP_PANEL_ENTRY('K', 'D', 'C', 0x0110, &delay_200_500_e50, "KD116N3730A07"), + EDP_PANEL_ENTRY('K', 'D', 'C', 0x0397, &delay_200_500_e50, "KD116N3730A12"), EDP_PANEL_ENTRY('K', 'D', 'C', 0x044f, &delay_200_500_e50, "KD116N9-30NH-F3"), EDP_PANEL_ENTRY('K', 'D', 'C', 0x05f1, &delay_200_500_e80_d50, "KD116N5-30NV-G7"), EDP_PANEL_ENTRY('K', 'D', 'C', 0x0809, &delay_200_500_e50, "KD116N2930A15"), diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index ad4993b2f92a..947b47841b01 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -100,7 +100,7 @@ static const struct ili9881c_instr lhr050h41_init[] = { ILI9881C_COMMAND_INSTR(0x13, 0x00), ILI9881C_COMMAND_INSTR(0x14, 0x00), ILI9881C_COMMAND_INSTR(0x15, 0x00), - ILI9881C_COMMAND_INSTR(0x16, 0x0C), + ILI9881C_COMMAND_INSTR(0x16, 0x0c), ILI9881C_COMMAND_INSTR(0x17, 0x00), ILI9881C_COMMAND_INSTR(0x18, 0x00), ILI9881C_COMMAND_INSTR(0x19, 0x00), @@ -108,7 +108,7 @@ static const struct ili9881c_instr lhr050h41_init[] = { ILI9881C_COMMAND_INSTR(0x1b, 0x00), ILI9881C_COMMAND_INSTR(0x1c, 0x00), ILI9881C_COMMAND_INSTR(0x1d, 0x00), - ILI9881C_COMMAND_INSTR(0x1e, 0xC0), + ILI9881C_COMMAND_INSTR(0x1e, 0xc0), ILI9881C_COMMAND_INSTR(0x1f, 0x80), ILI9881C_COMMAND_INSTR(0x20, 0x04), ILI9881C_COMMAND_INSTR(0x21, 0x01), @@ -134,7 +134,7 @@ static const struct ili9881c_instr lhr050h41_init[] = { ILI9881C_COMMAND_INSTR(0x35, 0x00), ILI9881C_COMMAND_INSTR(0x36, 0x00), ILI9881C_COMMAND_INSTR(0x37, 0x00), - ILI9881C_COMMAND_INSTR(0x38, 0x3C), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), ILI9881C_COMMAND_INSTR(0x39, 0x00), ILI9881C_COMMAND_INSTR(0x3a, 0x00), ILI9881C_COMMAND_INSTR(0x3b, 0x00), @@ -173,11 +173,11 @@ static const struct ili9881c_instr lhr050h41_init[] = { ILI9881C_COMMAND_INSTR(0x67, 0x02), ILI9881C_COMMAND_INSTR(0x68, 0x02), ILI9881C_COMMAND_INSTR(0x69, 0x02), - ILI9881C_COMMAND_INSTR(0x6a, 0x0C), + ILI9881C_COMMAND_INSTR(0x6a, 0x0c), ILI9881C_COMMAND_INSTR(0x6b, 0x02), - ILI9881C_COMMAND_INSTR(0x6c, 0x0F), - ILI9881C_COMMAND_INSTR(0x6d, 0x0E), - ILI9881C_COMMAND_INSTR(0x6e, 0x0D), + ILI9881C_COMMAND_INSTR(0x6c, 0x0f), + ILI9881C_COMMAND_INSTR(0x6d, 0x0e), + ILI9881C_COMMAND_INSTR(0x6e, 0x0d), ILI9881C_COMMAND_INSTR(0x6f, 0x06), ILI9881C_COMMAND_INSTR(0x70, 0x07), ILI9881C_COMMAND_INSTR(0x71, 0x02), @@ -195,74 +195,74 @@ static const struct ili9881c_instr lhr050h41_init[] = { ILI9881C_COMMAND_INSTR(0x7d, 0x02), ILI9881C_COMMAND_INSTR(0x7e, 0x02), ILI9881C_COMMAND_INSTR(0x7f, 0x02), - ILI9881C_COMMAND_INSTR(0x80, 0x0C), + ILI9881C_COMMAND_INSTR(0x80, 0x0c), ILI9881C_COMMAND_INSTR(0x81, 0x02), - ILI9881C_COMMAND_INSTR(0x82, 0x0F), - ILI9881C_COMMAND_INSTR(0x83, 0x0E), - ILI9881C_COMMAND_INSTR(0x84, 0x0D), + ILI9881C_COMMAND_INSTR(0x82, 0x0f), + ILI9881C_COMMAND_INSTR(0x83, 0x0e), + ILI9881C_COMMAND_INSTR(0x84, 0x0d), ILI9881C_COMMAND_INSTR(0x85, 0x06), ILI9881C_COMMAND_INSTR(0x86, 0x07), ILI9881C_COMMAND_INSTR(0x87, 0x02), ILI9881C_COMMAND_INSTR(0x88, 0x02), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), - ILI9881C_COMMAND_INSTR(0x6C, 0x15), - ILI9881C_COMMAND_INSTR(0x6E, 0x22), - ILI9881C_COMMAND_INSTR(0x6F, 0x33), - ILI9881C_COMMAND_INSTR(0x3A, 0xA4), - ILI9881C_COMMAND_INSTR(0x8D, 0x0D), - ILI9881C_COMMAND_INSTR(0x87, 0xBA), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x22), + ILI9881C_COMMAND_INSTR(0x6f, 0x33), + ILI9881C_COMMAND_INSTR(0x3a, 0xa4), + ILI9881C_COMMAND_INSTR(0x8d, 0x0d), + ILI9881C_COMMAND_INSTR(0x87, 0xba), ILI9881C_COMMAND_INSTR(0x26, 0x76), - ILI9881C_COMMAND_INSTR(0xB2, 0xD1), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), ILI9881C_SWITCH_PAGE_INSTR(1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), - ILI9881C_COMMAND_INSTR(0x53, 0xDC), - ILI9881C_COMMAND_INSTR(0x55, 0xA7), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x53, 0xdc), + ILI9881C_COMMAND_INSTR(0x55, 0xa7), ILI9881C_COMMAND_INSTR(0x50, 0x78), ILI9881C_COMMAND_INSTR(0x51, 0x78), ILI9881C_COMMAND_INSTR(0x31, 0x02), ILI9881C_COMMAND_INSTR(0x60, 0x14), - ILI9881C_COMMAND_INSTR(0xA0, 0x2A), - ILI9881C_COMMAND_INSTR(0xA1, 0x39), - ILI9881C_COMMAND_INSTR(0xA2, 0x46), - ILI9881C_COMMAND_INSTR(0xA3, 0x0e), - ILI9881C_COMMAND_INSTR(0xA4, 0x12), - ILI9881C_COMMAND_INSTR(0xA5, 0x25), - ILI9881C_COMMAND_INSTR(0xA6, 0x19), - ILI9881C_COMMAND_INSTR(0xA7, 0x1d), - ILI9881C_COMMAND_INSTR(0xA8, 0xa6), - ILI9881C_COMMAND_INSTR(0xA9, 0x1C), - ILI9881C_COMMAND_INSTR(0xAA, 0x29), - ILI9881C_COMMAND_INSTR(0xAB, 0x85), - ILI9881C_COMMAND_INSTR(0xAC, 0x1C), - ILI9881C_COMMAND_INSTR(0xAD, 0x1B), - ILI9881C_COMMAND_INSTR(0xAE, 0x51), - ILI9881C_COMMAND_INSTR(0xAF, 0x22), - ILI9881C_COMMAND_INSTR(0xB0, 0x2d), - ILI9881C_COMMAND_INSTR(0xB1, 0x4f), - ILI9881C_COMMAND_INSTR(0xB2, 0x59), - ILI9881C_COMMAND_INSTR(0xB3, 0x3F), - ILI9881C_COMMAND_INSTR(0xC0, 0x2A), - ILI9881C_COMMAND_INSTR(0xC1, 0x3a), - ILI9881C_COMMAND_INSTR(0xC2, 0x45), - ILI9881C_COMMAND_INSTR(0xC3, 0x0e), - ILI9881C_COMMAND_INSTR(0xC4, 0x11), - ILI9881C_COMMAND_INSTR(0xC5, 0x24), - ILI9881C_COMMAND_INSTR(0xC6, 0x1a), - ILI9881C_COMMAND_INSTR(0xC7, 0x1c), - ILI9881C_COMMAND_INSTR(0xC8, 0xaa), - ILI9881C_COMMAND_INSTR(0xC9, 0x1C), - ILI9881C_COMMAND_INSTR(0xCA, 0x29), - ILI9881C_COMMAND_INSTR(0xCB, 0x96), - ILI9881C_COMMAND_INSTR(0xCC, 0x1C), - ILI9881C_COMMAND_INSTR(0xCD, 0x1B), - ILI9881C_COMMAND_INSTR(0xCE, 0x51), - ILI9881C_COMMAND_INSTR(0xCF, 0x22), - ILI9881C_COMMAND_INSTR(0xD0, 0x2b), - ILI9881C_COMMAND_INSTR(0xD1, 0x4b), - ILI9881C_COMMAND_INSTR(0xD2, 0x59), - ILI9881C_COMMAND_INSTR(0xD3, 0x3F), + ILI9881C_COMMAND_INSTR(0xa0, 0x2a), + ILI9881C_COMMAND_INSTR(0xa1, 0x39), + ILI9881C_COMMAND_INSTR(0xa2, 0x46), + ILI9881C_COMMAND_INSTR(0xa3, 0x0e), + ILI9881C_COMMAND_INSTR(0xa4, 0x12), + ILI9881C_COMMAND_INSTR(0xa5, 0x25), + ILI9881C_COMMAND_INSTR(0xa6, 0x19), + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), + ILI9881C_COMMAND_INSTR(0xa8, 0xa6), + ILI9881C_COMMAND_INSTR(0xa9, 0x1c), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x85), + ILI9881C_COMMAND_INSTR(0xac, 0x1c), + ILI9881C_COMMAND_INSTR(0xad, 0x1b), + ILI9881C_COMMAND_INSTR(0xae, 0x51), + ILI9881C_COMMAND_INSTR(0xaf, 0x22), + ILI9881C_COMMAND_INSTR(0xb0, 0x2d), + ILI9881C_COMMAND_INSTR(0xb1, 0x4f), + ILI9881C_COMMAND_INSTR(0xb2, 0x59), + ILI9881C_COMMAND_INSTR(0xb3, 0x3f), + ILI9881C_COMMAND_INSTR(0xc0, 0x2a), + ILI9881C_COMMAND_INSTR(0xc1, 0x3a), + ILI9881C_COMMAND_INSTR(0xc2, 0x45), + ILI9881C_COMMAND_INSTR(0xc3, 0x0e), + ILI9881C_COMMAND_INSTR(0xc4, 0x11), + ILI9881C_COMMAND_INSTR(0xc5, 0x24), + ILI9881C_COMMAND_INSTR(0xc6, 0x1a), + ILI9881C_COMMAND_INSTR(0xc7, 0x1c), + ILI9881C_COMMAND_INSTR(0xc8, 0xaa), + ILI9881C_COMMAND_INSTR(0xc9, 0x1c), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x96), + ILI9881C_COMMAND_INSTR(0xcc, 0x1c), + ILI9881C_COMMAND_INSTR(0xcd, 0x1b), + ILI9881C_COMMAND_INSTR(0xce, 0x51), + ILI9881C_COMMAND_INSTR(0xcf, 0x22), + ILI9881C_COMMAND_INSTR(0xd0, 0x2b), + ILI9881C_COMMAND_INSTR(0xd1, 0x4b), + ILI9881C_COMMAND_INSTR(0xd2, 0x59), + ILI9881C_COMMAND_INSTR(0xd3, 0x3f), }; static const struct ili9881c_instr k101_im2byl02_init[] = { @@ -276,12 +276,12 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x07, 0x00), ILI9881C_COMMAND_INSTR(0x08, 0x00), ILI9881C_COMMAND_INSTR(0x09, 0x00), - ILI9881C_COMMAND_INSTR(0x0A, 0x01), - ILI9881C_COMMAND_INSTR(0x0B, 0x01), - ILI9881C_COMMAND_INSTR(0x0C, 0x00), - ILI9881C_COMMAND_INSTR(0x0D, 0x01), - ILI9881C_COMMAND_INSTR(0x0E, 0x01), - ILI9881C_COMMAND_INSTR(0x0F, 0x00), + ILI9881C_COMMAND_INSTR(0x0a, 0x01), + ILI9881C_COMMAND_INSTR(0x0b, 0x01), + ILI9881C_COMMAND_INSTR(0x0c, 0x00), + ILI9881C_COMMAND_INSTR(0x0d, 0x01), + ILI9881C_COMMAND_INSTR(0x0e, 0x01), + ILI9881C_COMMAND_INSTR(0x0f, 0x00), ILI9881C_COMMAND_INSTR(0x10, 0x00), ILI9881C_COMMAND_INSTR(0x11, 0x00), ILI9881C_COMMAND_INSTR(0x12, 0x00), @@ -292,12 +292,12 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x17, 0x00), ILI9881C_COMMAND_INSTR(0x18, 0x00), ILI9881C_COMMAND_INSTR(0x19, 0x00), - ILI9881C_COMMAND_INSTR(0x1A, 0x00), - ILI9881C_COMMAND_INSTR(0x1B, 0x00), - ILI9881C_COMMAND_INSTR(0x1C, 0x00), - ILI9881C_COMMAND_INSTR(0x1D, 0x00), - ILI9881C_COMMAND_INSTR(0x1E, 0x40), - ILI9881C_COMMAND_INSTR(0x1F, 0xC0), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0x40), + ILI9881C_COMMAND_INSTR(0x1f, 0xc0), ILI9881C_COMMAND_INSTR(0x20, 0x06), ILI9881C_COMMAND_INSTR(0x21, 0x01), ILI9881C_COMMAND_INSTR(0x22, 0x06), @@ -306,14 +306,14 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x25, 0x88), ILI9881C_COMMAND_INSTR(0x26, 0x00), ILI9881C_COMMAND_INSTR(0x27, 0x00), - ILI9881C_COMMAND_INSTR(0x28, 0x3B), + ILI9881C_COMMAND_INSTR(0x28, 0x3b), ILI9881C_COMMAND_INSTR(0x29, 0x03), - ILI9881C_COMMAND_INSTR(0x2A, 0x00), - ILI9881C_COMMAND_INSTR(0x2B, 0x00), - ILI9881C_COMMAND_INSTR(0x2C, 0x00), - ILI9881C_COMMAND_INSTR(0x2D, 0x00), - ILI9881C_COMMAND_INSTR(0x2E, 0x00), - ILI9881C_COMMAND_INSTR(0x2F, 0x00), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), ILI9881C_COMMAND_INSTR(0x30, 0x00), ILI9881C_COMMAND_INSTR(0x31, 0x00), ILI9881C_COMMAND_INSTR(0x32, 0x00), @@ -324,12 +324,12 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x37, 0x00), ILI9881C_COMMAND_INSTR(0x38, 0x00), ILI9881C_COMMAND_INSTR(0x39, 0x00), - ILI9881C_COMMAND_INSTR(0x3A, 0x00), - ILI9881C_COMMAND_INSTR(0x3B, 0x00), - ILI9881C_COMMAND_INSTR(0x3C, 0x00), - ILI9881C_COMMAND_INSTR(0x3D, 0x00), - ILI9881C_COMMAND_INSTR(0x3E, 0x00), - ILI9881C_COMMAND_INSTR(0x3F, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x00), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), ILI9881C_COMMAND_INSTR(0x40, 0x00), ILI9881C_COMMAND_INSTR(0x41, 0x00), ILI9881C_COMMAND_INSTR(0x42, 0x00), @@ -340,17 +340,17 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x52, 0x45), ILI9881C_COMMAND_INSTR(0x53, 0x67), ILI9881C_COMMAND_INSTR(0x54, 0x89), - ILI9881C_COMMAND_INSTR(0x55, 0xAB), + ILI9881C_COMMAND_INSTR(0x55, 0xab), ILI9881C_COMMAND_INSTR(0x56, 0x01), ILI9881C_COMMAND_INSTR(0x57, 0x23), ILI9881C_COMMAND_INSTR(0x58, 0x45), ILI9881C_COMMAND_INSTR(0x59, 0x67), - ILI9881C_COMMAND_INSTR(0x5A, 0x89), - ILI9881C_COMMAND_INSTR(0x5B, 0xAB), - ILI9881C_COMMAND_INSTR(0x5C, 0xCD), - ILI9881C_COMMAND_INSTR(0x5D, 0xEF), - ILI9881C_COMMAND_INSTR(0x5E, 0x00), - ILI9881C_COMMAND_INSTR(0x5F, 0x01), + ILI9881C_COMMAND_INSTR(0x5a, 0x89), + ILI9881C_COMMAND_INSTR(0x5b, 0xab), + ILI9881C_COMMAND_INSTR(0x5c, 0xcd), + ILI9881C_COMMAND_INSTR(0x5d, 0xef), + ILI9881C_COMMAND_INSTR(0x5e, 0x00), + ILI9881C_COMMAND_INSTR(0x5f, 0x01), ILI9881C_COMMAND_INSTR(0x60, 0x01), ILI9881C_COMMAND_INSTR(0x61, 0x06), ILI9881C_COMMAND_INSTR(0x62, 0x06), @@ -361,101 +361,101 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0x67, 0x02), ILI9881C_COMMAND_INSTR(0x68, 0x02), ILI9881C_COMMAND_INSTR(0x69, 0x05), - ILI9881C_COMMAND_INSTR(0x6A, 0x05), - ILI9881C_COMMAND_INSTR(0x6B, 0x02), - ILI9881C_COMMAND_INSTR(0x6C, 0x0D), - ILI9881C_COMMAND_INSTR(0x6D, 0x0D), - ILI9881C_COMMAND_INSTR(0x6E, 0x0C), - ILI9881C_COMMAND_INSTR(0x6F, 0x0C), - ILI9881C_COMMAND_INSTR(0x70, 0x0F), - ILI9881C_COMMAND_INSTR(0x71, 0x0F), - ILI9881C_COMMAND_INSTR(0x72, 0x0E), - ILI9881C_COMMAND_INSTR(0x73, 0x0E), + ILI9881C_COMMAND_INSTR(0x6a, 0x05), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x0d), + ILI9881C_COMMAND_INSTR(0x6d, 0x0d), + ILI9881C_COMMAND_INSTR(0x6e, 0x0c), + ILI9881C_COMMAND_INSTR(0x6f, 0x0c), + ILI9881C_COMMAND_INSTR(0x70, 0x0f), + ILI9881C_COMMAND_INSTR(0x71, 0x0f), + ILI9881C_COMMAND_INSTR(0x72, 0x0e), + ILI9881C_COMMAND_INSTR(0x73, 0x0e), ILI9881C_COMMAND_INSTR(0x74, 0x02), ILI9881C_COMMAND_INSTR(0x75, 0x01), ILI9881C_COMMAND_INSTR(0x76, 0x01), ILI9881C_COMMAND_INSTR(0x77, 0x06), ILI9881C_COMMAND_INSTR(0x78, 0x06), ILI9881C_COMMAND_INSTR(0x79, 0x07), - ILI9881C_COMMAND_INSTR(0x7A, 0x07), - ILI9881C_COMMAND_INSTR(0x7B, 0x00), - ILI9881C_COMMAND_INSTR(0x7C, 0x00), - ILI9881C_COMMAND_INSTR(0x7D, 0x02), - ILI9881C_COMMAND_INSTR(0x7E, 0x02), - ILI9881C_COMMAND_INSTR(0x7F, 0x05), + ILI9881C_COMMAND_INSTR(0x7a, 0x07), + ILI9881C_COMMAND_INSTR(0x7b, 0x00), + ILI9881C_COMMAND_INSTR(0x7c, 0x00), + ILI9881C_COMMAND_INSTR(0x7d, 0x02), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x05), ILI9881C_COMMAND_INSTR(0x80, 0x05), ILI9881C_COMMAND_INSTR(0x81, 0x02), - ILI9881C_COMMAND_INSTR(0x82, 0x0D), - ILI9881C_COMMAND_INSTR(0x83, 0x0D), - ILI9881C_COMMAND_INSTR(0x84, 0x0C), - ILI9881C_COMMAND_INSTR(0x85, 0x0C), - ILI9881C_COMMAND_INSTR(0x86, 0x0F), - ILI9881C_COMMAND_INSTR(0x87, 0x0F), - ILI9881C_COMMAND_INSTR(0x88, 0x0E), - ILI9881C_COMMAND_INSTR(0x89, 0x0E), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x82, 0x0d), + ILI9881C_COMMAND_INSTR(0x83, 0x0d), + ILI9881C_COMMAND_INSTR(0x84, 0x0c), + ILI9881C_COMMAND_INSTR(0x85, 0x0c), + ILI9881C_COMMAND_INSTR(0x86, 0x0f), + ILI9881C_COMMAND_INSTR(0x87, 0x0f), + ILI9881C_COMMAND_INSTR(0x88, 0x0e), + ILI9881C_COMMAND_INSTR(0x89, 0x0e), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), - ILI9881C_COMMAND_INSTR(0x3B, 0xC0), /* ILI4003D sel */ - ILI9881C_COMMAND_INSTR(0x6C, 0x15), /* Set VCORE voltage = 1.5V */ - ILI9881C_COMMAND_INSTR(0x6E, 0x2A), /* di_pwr_reg=0 for power mode 2A, VGH clamp 18V */ - ILI9881C_COMMAND_INSTR(0x6F, 0x33), /* pumping ratio VGH=5x VGL=-3x */ - ILI9881C_COMMAND_INSTR(0x8D, 0x1B), /* VGL clamp -10V */ - ILI9881C_COMMAND_INSTR(0x87, 0xBA), /* ESD */ - ILI9881C_COMMAND_INSTR(0x3A, 0x24), /* POWER SAVING */ + ILI9881C_COMMAND_INSTR(0x3b, 0xc0), /* ILI4003D sel */ + ILI9881C_COMMAND_INSTR(0x6c, 0x15), /* Set VCORE voltage = 1.5V */ + ILI9881C_COMMAND_INSTR(0x6e, 0x2a), /* di_pwr_reg=0 for power mode 2A, VGH clamp 18V */ + ILI9881C_COMMAND_INSTR(0x6f, 0x33), /* pumping ratio VGH=5x VGL=-3x */ + ILI9881C_COMMAND_INSTR(0x8d, 0x1b), /* VGL clamp -10V */ + ILI9881C_COMMAND_INSTR(0x87, 0xba), /* ESD */ + ILI9881C_COMMAND_INSTR(0x3a, 0x24), /* POWER SAVING */ ILI9881C_COMMAND_INSTR(0x26, 0x76), - ILI9881C_COMMAND_INSTR(0xB2, 0xD1), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), ILI9881C_SWITCH_PAGE_INSTR(1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), /* BGR, SS */ + ILI9881C_COMMAND_INSTR(0x22, 0x0a), /* BGR, SS */ ILI9881C_COMMAND_INSTR(0x31, 0x00), /* Zigzag type3 inversion */ ILI9881C_COMMAND_INSTR(0x40, 0x53), /* ILI4003D sel */ ILI9881C_COMMAND_INSTR(0x43, 0x66), - ILI9881C_COMMAND_INSTR(0x53, 0x4C), + ILI9881C_COMMAND_INSTR(0x53, 0x4c), ILI9881C_COMMAND_INSTR(0x50, 0x87), ILI9881C_COMMAND_INSTR(0x51, 0x82), ILI9881C_COMMAND_INSTR(0x60, 0x15), ILI9881C_COMMAND_INSTR(0x61, 0x01), - ILI9881C_COMMAND_INSTR(0x62, 0x0C), + ILI9881C_COMMAND_INSTR(0x62, 0x0c), ILI9881C_COMMAND_INSTR(0x63, 0x00), - ILI9881C_COMMAND_INSTR(0xA0, 0x00), - ILI9881C_COMMAND_INSTR(0xA1, 0x13), /* VP251 */ - ILI9881C_COMMAND_INSTR(0xA2, 0x23), /* VP247 */ - ILI9881C_COMMAND_INSTR(0xA3, 0x14), /* VP243 */ - ILI9881C_COMMAND_INSTR(0xA4, 0x16), /* VP239 */ - ILI9881C_COMMAND_INSTR(0xA5, 0x29), /* VP231 */ - ILI9881C_COMMAND_INSTR(0xA6, 0x1E), /* VP219 */ - ILI9881C_COMMAND_INSTR(0xA7, 0x1D), /* VP203 */ - ILI9881C_COMMAND_INSTR(0xA8, 0x86), /* VP175 */ - ILI9881C_COMMAND_INSTR(0xA9, 0x1E), /* VP144 */ - ILI9881C_COMMAND_INSTR(0xAA, 0x29), /* VP111 */ - ILI9881C_COMMAND_INSTR(0xAB, 0x74), /* VP80 */ - ILI9881C_COMMAND_INSTR(0xAC, 0x19), /* VP52 */ - ILI9881C_COMMAND_INSTR(0xAD, 0x17), /* VP36 */ - ILI9881C_COMMAND_INSTR(0xAE, 0x4B), /* VP24 */ - ILI9881C_COMMAND_INSTR(0xAF, 0x20), /* VP16 */ - ILI9881C_COMMAND_INSTR(0xB0, 0x26), /* VP12 */ - ILI9881C_COMMAND_INSTR(0xB1, 0x4C), /* VP8 */ - ILI9881C_COMMAND_INSTR(0xB2, 0x5D), /* VP4 */ - ILI9881C_COMMAND_INSTR(0xB3, 0x3F), /* VP0 */ - ILI9881C_COMMAND_INSTR(0xC0, 0x00), /* VN255 GAMMA N */ - ILI9881C_COMMAND_INSTR(0xC1, 0x13), /* VN251 */ - ILI9881C_COMMAND_INSTR(0xC2, 0x23), /* VN247 */ - ILI9881C_COMMAND_INSTR(0xC3, 0x14), /* VN243 */ - ILI9881C_COMMAND_INSTR(0xC4, 0x16), /* VN239 */ - ILI9881C_COMMAND_INSTR(0xC5, 0x29), /* VN231 */ - ILI9881C_COMMAND_INSTR(0xC6, 0x1E), /* VN219 */ - ILI9881C_COMMAND_INSTR(0xC7, 0x1D), /* VN203 */ - ILI9881C_COMMAND_INSTR(0xC8, 0x86), /* VN175 */ - ILI9881C_COMMAND_INSTR(0xC9, 0x1E), /* VN144 */ - ILI9881C_COMMAND_INSTR(0xCA, 0x29), /* VN111 */ - ILI9881C_COMMAND_INSTR(0xCB, 0x74), /* VN80 */ - ILI9881C_COMMAND_INSTR(0xCC, 0x19), /* VN52 */ - ILI9881C_COMMAND_INSTR(0xCD, 0x17), /* VN36 */ - ILI9881C_COMMAND_INSTR(0xCE, 0x4B), /* VN24 */ - ILI9881C_COMMAND_INSTR(0xCF, 0x20), /* VN16 */ - ILI9881C_COMMAND_INSTR(0xD0, 0x26), /* VN12 */ - ILI9881C_COMMAND_INSTR(0xD1, 0x4C), /* VN8 */ - ILI9881C_COMMAND_INSTR(0xD2, 0x5D), /* VN4 */ - ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */ + ILI9881C_COMMAND_INSTR(0xa0, 0x00), + ILI9881C_COMMAND_INSTR(0xa1, 0x13), /* VP251 */ + ILI9881C_COMMAND_INSTR(0xa2, 0x23), /* VP247 */ + ILI9881C_COMMAND_INSTR(0xa3, 0x14), /* VP243 */ + ILI9881C_COMMAND_INSTR(0xa4, 0x16), /* VP239 */ + ILI9881C_COMMAND_INSTR(0xa5, 0x29), /* VP231 */ + ILI9881C_COMMAND_INSTR(0xa6, 0x1e), /* VP219 */ + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), /* VP203 */ + ILI9881C_COMMAND_INSTR(0xa8, 0x86), /* VP175 */ + ILI9881C_COMMAND_INSTR(0xa9, 0x1e), /* VP144 */ + ILI9881C_COMMAND_INSTR(0xaa, 0x29), /* VP111 */ + ILI9881C_COMMAND_INSTR(0xab, 0x74), /* VP80 */ + ILI9881C_COMMAND_INSTR(0xac, 0x19), /* VP52 */ + ILI9881C_COMMAND_INSTR(0xad, 0x17), /* VP36 */ + ILI9881C_COMMAND_INSTR(0xae, 0x4b), /* VP24 */ + ILI9881C_COMMAND_INSTR(0xaf, 0x20), /* VP16 */ + ILI9881C_COMMAND_INSTR(0xb0, 0x26), /* VP12 */ + ILI9881C_COMMAND_INSTR(0xb1, 0x4c), /* VP8 */ + ILI9881C_COMMAND_INSTR(0xb2, 0x5d), /* VP4 */ + ILI9881C_COMMAND_INSTR(0xb3, 0x3f), /* VP0 */ + ILI9881C_COMMAND_INSTR(0xc0, 0x00), /* VN255 GAMMA N */ + ILI9881C_COMMAND_INSTR(0xc1, 0x13), /* VN251 */ + ILI9881C_COMMAND_INSTR(0xc2, 0x23), /* VN247 */ + ILI9881C_COMMAND_INSTR(0xc3, 0x14), /* VN243 */ + ILI9881C_COMMAND_INSTR(0xc4, 0x16), /* VN239 */ + ILI9881C_COMMAND_INSTR(0xc5, 0x29), /* VN231 */ + ILI9881C_COMMAND_INSTR(0xc6, 0x1e), /* VN219 */ + ILI9881C_COMMAND_INSTR(0xc7, 0x1d), /* VN203 */ + ILI9881C_COMMAND_INSTR(0xc8, 0x86), /* VN175 */ + ILI9881C_COMMAND_INSTR(0xc9, 0x1e), /* VN144 */ + ILI9881C_COMMAND_INSTR(0xca, 0x29), /* VN111 */ + ILI9881C_COMMAND_INSTR(0xcb, 0x74), /* VN80 */ + ILI9881C_COMMAND_INSTR(0xcc, 0x19), /* VN52 */ + ILI9881C_COMMAND_INSTR(0xcd, 0x17), /* VN36 */ + ILI9881C_COMMAND_INSTR(0xce, 0x4b), /* VN24 */ + ILI9881C_COMMAND_INSTR(0xcf, 0x20), /* VN16 */ + ILI9881C_COMMAND_INSTR(0xd0, 0x26), /* VN12 */ + ILI9881C_COMMAND_INSTR(0xd1, 0x4c), /* VN8 */ + ILI9881C_COMMAND_INSTR(0xd2, 0x5d), /* VN4 */ + ILI9881C_COMMAND_INSTR(0xd3, 0x3f), /* VN0 */ }; static const struct ili9881c_instr kd050hdfia020_init[] = { @@ -517,7 +517,7 @@ static const struct ili9881c_instr kd050hdfia020_init[] = { ILI9881C_COMMAND_INSTR(0x35, 0x00), ILI9881C_COMMAND_INSTR(0x36, 0x00), ILI9881C_COMMAND_INSTR(0x37, 0x00), - ILI9881C_COMMAND_INSTR(0x38, 0x3C), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), ILI9881C_COMMAND_INSTR(0x39, 0x00), ILI9881C_COMMAND_INSTR(0x3a, 0x40), ILI9881C_COMMAND_INSTR(0x3b, 0x40), @@ -549,10 +549,10 @@ static const struct ili9881c_instr kd050hdfia020_init[] = { ILI9881C_COMMAND_INSTR(0x60, 0x00), ILI9881C_COMMAND_INSTR(0x61, 0x15), ILI9881C_COMMAND_INSTR(0x62, 0x14), - ILI9881C_COMMAND_INSTR(0x63, 0x0E), - ILI9881C_COMMAND_INSTR(0x64, 0x0F), - ILI9881C_COMMAND_INSTR(0x65, 0x0C), - ILI9881C_COMMAND_INSTR(0x66, 0x0D), + ILI9881C_COMMAND_INSTR(0x63, 0x0e), + ILI9881C_COMMAND_INSTR(0x64, 0x0f), + ILI9881C_COMMAND_INSTR(0x65, 0x0c), + ILI9881C_COMMAND_INSTR(0x66, 0x0d), ILI9881C_COMMAND_INSTR(0x67, 0x06), ILI9881C_COMMAND_INSTR(0x68, 0x02), ILI9881C_COMMAND_INSTR(0x69, 0x07), @@ -571,10 +571,10 @@ static const struct ili9881c_instr kd050hdfia020_init[] = { ILI9881C_COMMAND_INSTR(0x76, 0x00), ILI9881C_COMMAND_INSTR(0x77, 0x14), ILI9881C_COMMAND_INSTR(0x78, 0x15), - ILI9881C_COMMAND_INSTR(0x79, 0x0E), - ILI9881C_COMMAND_INSTR(0x7a, 0x0F), - ILI9881C_COMMAND_INSTR(0x7b, 0x0C), - ILI9881C_COMMAND_INSTR(0x7c, 0x0D), + ILI9881C_COMMAND_INSTR(0x79, 0x0e), + ILI9881C_COMMAND_INSTR(0x7a, 0x0f), + ILI9881C_COMMAND_INSTR(0x7b, 0x0c), + ILI9881C_COMMAND_INSTR(0x7c, 0x0d), ILI9881C_COMMAND_INSTR(0x7d, 0x06), ILI9881C_COMMAND_INSTR(0x7e, 0x02), ILI9881C_COMMAND_INSTR(0x7f, 0x07), @@ -587,71 +587,71 @@ static const struct ili9881c_instr kd050hdfia020_init[] = { ILI9881C_COMMAND_INSTR(0x87, 0x02), ILI9881C_COMMAND_INSTR(0x88, 0x02), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(0x4), - ILI9881C_COMMAND_INSTR(0x6C, 0x15), - ILI9881C_COMMAND_INSTR(0x6E, 0x2A), - ILI9881C_COMMAND_INSTR(0x6F, 0x33), - ILI9881C_COMMAND_INSTR(0x3A, 0x94), - ILI9881C_COMMAND_INSTR(0x8D, 0x15), - ILI9881C_COMMAND_INSTR(0x87, 0xBA), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x2a), + ILI9881C_COMMAND_INSTR(0x6f, 0x33), + ILI9881C_COMMAND_INSTR(0x3a, 0x94), + ILI9881C_COMMAND_INSTR(0x8d, 0x15), + ILI9881C_COMMAND_INSTR(0x87, 0xba), ILI9881C_COMMAND_INSTR(0x26, 0x76), - ILI9881C_COMMAND_INSTR(0xB2, 0xD1), - ILI9881C_COMMAND_INSTR(0xB5, 0x06), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), + ILI9881C_COMMAND_INSTR(0xb5, 0x06), ILI9881C_SWITCH_PAGE_INSTR(0x1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), ILI9881C_COMMAND_INSTR(0x31, 0x00), ILI9881C_COMMAND_INSTR(0x53, 0x90), - ILI9881C_COMMAND_INSTR(0x55, 0xA2), - ILI9881C_COMMAND_INSTR(0x50, 0xB7), - ILI9881C_COMMAND_INSTR(0x51, 0xB7), + ILI9881C_COMMAND_INSTR(0x55, 0xa2), + ILI9881C_COMMAND_INSTR(0x50, 0xb7), + ILI9881C_COMMAND_INSTR(0x51, 0xb7), ILI9881C_COMMAND_INSTR(0x60, 0x22), ILI9881C_COMMAND_INSTR(0x61, 0x00), ILI9881C_COMMAND_INSTR(0x62, 0x19), ILI9881C_COMMAND_INSTR(0x63, 0x10), - ILI9881C_COMMAND_INSTR(0xA0, 0x08), - ILI9881C_COMMAND_INSTR(0xA1, 0x1A), - ILI9881C_COMMAND_INSTR(0xA2, 0x27), - ILI9881C_COMMAND_INSTR(0xA3, 0x15), - ILI9881C_COMMAND_INSTR(0xA4, 0x17), - ILI9881C_COMMAND_INSTR(0xA5, 0x2A), - ILI9881C_COMMAND_INSTR(0xA6, 0x1E), - ILI9881C_COMMAND_INSTR(0xA7, 0x1F), - ILI9881C_COMMAND_INSTR(0xA8, 0x8B), - ILI9881C_COMMAND_INSTR(0xA9, 0x1B), - ILI9881C_COMMAND_INSTR(0xAA, 0x27), - ILI9881C_COMMAND_INSTR(0xAB, 0x78), - ILI9881C_COMMAND_INSTR(0xAC, 0x18), - ILI9881C_COMMAND_INSTR(0xAD, 0x18), - ILI9881C_COMMAND_INSTR(0xAE, 0x4C), - ILI9881C_COMMAND_INSTR(0xAF, 0x21), - ILI9881C_COMMAND_INSTR(0xB0, 0x27), - ILI9881C_COMMAND_INSTR(0xB1, 0x54), - ILI9881C_COMMAND_INSTR(0xB2, 0x67), - ILI9881C_COMMAND_INSTR(0xB3, 0x39), - ILI9881C_COMMAND_INSTR(0xC0, 0x08), - ILI9881C_COMMAND_INSTR(0xC1, 0x1A), - ILI9881C_COMMAND_INSTR(0xC2, 0x27), - ILI9881C_COMMAND_INSTR(0xC3, 0x15), - ILI9881C_COMMAND_INSTR(0xC4, 0x17), - ILI9881C_COMMAND_INSTR(0xC5, 0x2A), - ILI9881C_COMMAND_INSTR(0xC6, 0x1E), - ILI9881C_COMMAND_INSTR(0xC7, 0x1F), - ILI9881C_COMMAND_INSTR(0xC8, 0x8B), - ILI9881C_COMMAND_INSTR(0xC9, 0x1B), - ILI9881C_COMMAND_INSTR(0xCA, 0x27), - ILI9881C_COMMAND_INSTR(0xCB, 0x78), - ILI9881C_COMMAND_INSTR(0xCC, 0x18), - ILI9881C_COMMAND_INSTR(0xCD, 0x18), - ILI9881C_COMMAND_INSTR(0xCE, 0x4C), - ILI9881C_COMMAND_INSTR(0xCF, 0x21), - ILI9881C_COMMAND_INSTR(0xD0, 0x27), - ILI9881C_COMMAND_INSTR(0xD1, 0x54), - ILI9881C_COMMAND_INSTR(0xD2, 0x67), - ILI9881C_COMMAND_INSTR(0xD3, 0x39), + ILI9881C_COMMAND_INSTR(0xa0, 0x08), + ILI9881C_COMMAND_INSTR(0xa1, 0x1a), + ILI9881C_COMMAND_INSTR(0xa2, 0x27), + ILI9881C_COMMAND_INSTR(0xa3, 0x15), + ILI9881C_COMMAND_INSTR(0xa4, 0x17), + ILI9881C_COMMAND_INSTR(0xa5, 0x2a), + ILI9881C_COMMAND_INSTR(0xa6, 0x1e), + ILI9881C_COMMAND_INSTR(0xa7, 0x1f), + ILI9881C_COMMAND_INSTR(0xa8, 0x8b), + ILI9881C_COMMAND_INSTR(0xa9, 0x1b), + ILI9881C_COMMAND_INSTR(0xaa, 0x27), + ILI9881C_COMMAND_INSTR(0xab, 0x78), + ILI9881C_COMMAND_INSTR(0xac, 0x18), + ILI9881C_COMMAND_INSTR(0xad, 0x18), + ILI9881C_COMMAND_INSTR(0xae, 0x4c), + ILI9881C_COMMAND_INSTR(0xaf, 0x21), + ILI9881C_COMMAND_INSTR(0xb0, 0x27), + ILI9881C_COMMAND_INSTR(0xb1, 0x54), + ILI9881C_COMMAND_INSTR(0xb2, 0x67), + ILI9881C_COMMAND_INSTR(0xb3, 0x39), + ILI9881C_COMMAND_INSTR(0xc0, 0x08), + ILI9881C_COMMAND_INSTR(0xc1, 0x1a), + ILI9881C_COMMAND_INSTR(0xc2, 0x27), + ILI9881C_COMMAND_INSTR(0xc3, 0x15), + ILI9881C_COMMAND_INSTR(0xc4, 0x17), + ILI9881C_COMMAND_INSTR(0xc5, 0x2a), + ILI9881C_COMMAND_INSTR(0xc6, 0x1e), + ILI9881C_COMMAND_INSTR(0xc7, 0x1f), + ILI9881C_COMMAND_INSTR(0xc8, 0x8b), + ILI9881C_COMMAND_INSTR(0xc9, 0x1b), + ILI9881C_COMMAND_INSTR(0xca, 0x27), + ILI9881C_COMMAND_INSTR(0xcb, 0x78), + ILI9881C_COMMAND_INSTR(0xcc, 0x18), + ILI9881C_COMMAND_INSTR(0xcd, 0x18), + ILI9881C_COMMAND_INSTR(0xce, 0x4c), + ILI9881C_COMMAND_INSTR(0xcf, 0x21), + ILI9881C_COMMAND_INSTR(0xd0, 0x27), + ILI9881C_COMMAND_INSTR(0xd1, 0x54), + ILI9881C_COMMAND_INSTR(0xd2, 0x67), + ILI9881C_COMMAND_INSTR(0xd3, 0x39), ILI9881C_SWITCH_PAGE_INSTR(0), ILI9881C_COMMAND_INSTR(0x35, 0x00), - ILI9881C_COMMAND_INSTR(0x3A, 0x7), + ILI9881C_COMMAND_INSTR(0x3a, 0x7), }; static const struct ili9881c_instr tl050hdv35_init[] = { @@ -696,7 +696,7 @@ static const struct ili9881c_instr tl050hdv35_init[] = { ILI9881C_COMMAND_INSTR(0x35, 0x00), ILI9881C_COMMAND_INSTR(0x36, 0x00), ILI9881C_COMMAND_INSTR(0x37, 0x00), - ILI9881C_COMMAND_INSTR(0x38, 0x3C), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), ILI9881C_COMMAND_INSTR(0x39, 0x00), ILI9881C_COMMAND_INSTR(0x3a, 0x40), ILI9881C_COMMAND_INSTR(0x3b, 0x40), @@ -750,7 +750,7 @@ static const struct ili9881c_instr tl050hdv35_init[] = { ILI9881C_COMMAND_INSTR(0x7f, 0x07), ILI9881C_COMMAND_INSTR(0x88, 0x02), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), ILI9881C_COMMAND_INSTR(0x38, 0x01), ILI9881C_COMMAND_INSTR(0x39, 0x00), @@ -820,6 +820,204 @@ static const struct ili9881c_instr tl050hdv35_init[] = { ILI9881C_COMMAND_INSTR(0xd3, 0x39), }; +static const struct ili9881c_instr w552946aaa_init[] = { + ILI9881C_SWITCH_PAGE_INSTR(3), + ILI9881C_COMMAND_INSTR(0x01, 0x00), + ILI9881C_COMMAND_INSTR(0x02, 0x00), + ILI9881C_COMMAND_INSTR(0x03, 0x53), + ILI9881C_COMMAND_INSTR(0x04, 0x53), + ILI9881C_COMMAND_INSTR(0x05, 0x13), + ILI9881C_COMMAND_INSTR(0x06, 0x04), + ILI9881C_COMMAND_INSTR(0x07, 0x02), + ILI9881C_COMMAND_INSTR(0x08, 0x02), + ILI9881C_COMMAND_INSTR(0x09, 0x00), + ILI9881C_COMMAND_INSTR(0x0a, 0x00), + ILI9881C_COMMAND_INSTR(0x0b, 0x00), + ILI9881C_COMMAND_INSTR(0x0c, 0x00), + ILI9881C_COMMAND_INSTR(0x0d, 0x00), + ILI9881C_COMMAND_INSTR(0x0e, 0x00), + ILI9881C_COMMAND_INSTR(0x0f, 0x00), + ILI9881C_COMMAND_INSTR(0x10, 0x00), + ILI9881C_COMMAND_INSTR(0x11, 0x00), + ILI9881C_COMMAND_INSTR(0x12, 0x00), + ILI9881C_COMMAND_INSTR(0x13, 0x00), + ILI9881C_COMMAND_INSTR(0x14, 0x00), + ILI9881C_COMMAND_INSTR(0x15, 0x08), + ILI9881C_COMMAND_INSTR(0x16, 0x10), + ILI9881C_COMMAND_INSTR(0x17, 0x00), + ILI9881C_COMMAND_INSTR(0x18, 0x08), + ILI9881C_COMMAND_INSTR(0x19, 0x00), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0xc0), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), + ILI9881C_COMMAND_INSTR(0x20, 0x02), + ILI9881C_COMMAND_INSTR(0x21, 0x09), + ILI9881C_COMMAND_INSTR(0x22, 0x00), + ILI9881C_COMMAND_INSTR(0x23, 0x00), + ILI9881C_COMMAND_INSTR(0x24, 0x00), + ILI9881C_COMMAND_INSTR(0x25, 0x00), + ILI9881C_COMMAND_INSTR(0x26, 0x00), + ILI9881C_COMMAND_INSTR(0x27, 0x00), + ILI9881C_COMMAND_INSTR(0x28, 0x55), + ILI9881C_COMMAND_INSTR(0x29, 0x03), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), + ILI9881C_COMMAND_INSTR(0x30, 0x00), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x32, 0x00), + ILI9881C_COMMAND_INSTR(0x33, 0x00), + ILI9881C_COMMAND_INSTR(0x34, 0x04), + ILI9881C_COMMAND_INSTR(0x35, 0x05), + ILI9881C_COMMAND_INSTR(0x36, 0x05), + ILI9881C_COMMAND_INSTR(0x37, 0x00), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), + ILI9881C_COMMAND_INSTR(0x39, 0x35), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x40), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x00), + ILI9881C_COMMAND_INSTR(0x41, 0x88), + ILI9881C_COMMAND_INSTR(0x42, 0x00), + ILI9881C_COMMAND_INSTR(0x43, 0x00), + ILI9881C_COMMAND_INSTR(0x44, 0x1f), + ILI9881C_COMMAND_INSTR(0x50, 0x01), + ILI9881C_COMMAND_INSTR(0x51, 0x23), + ILI9881C_COMMAND_INSTR(0x52, 0x45), + ILI9881C_COMMAND_INSTR(0x53, 0x67), + ILI9881C_COMMAND_INSTR(0x54, 0x89), + ILI9881C_COMMAND_INSTR(0x55, 0xab), + ILI9881C_COMMAND_INSTR(0x56, 0x01), + ILI9881C_COMMAND_INSTR(0x57, 0x23), + ILI9881C_COMMAND_INSTR(0x58, 0x45), + ILI9881C_COMMAND_INSTR(0x59, 0x67), + ILI9881C_COMMAND_INSTR(0x5a, 0x89), + ILI9881C_COMMAND_INSTR(0x5b, 0xab), + ILI9881C_COMMAND_INSTR(0x5c, 0xcd), + ILI9881C_COMMAND_INSTR(0x5d, 0xef), + ILI9881C_COMMAND_INSTR(0x5e, 0x03), + ILI9881C_COMMAND_INSTR(0x5f, 0x14), + ILI9881C_COMMAND_INSTR(0x60, 0x15), + ILI9881C_COMMAND_INSTR(0x61, 0x0c), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x0e), + ILI9881C_COMMAND_INSTR(0x64, 0x0f), + ILI9881C_COMMAND_INSTR(0x65, 0x10), + ILI9881C_COMMAND_INSTR(0x66, 0x11), + ILI9881C_COMMAND_INSTR(0x67, 0x08), + ILI9881C_COMMAND_INSTR(0x68, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x0a), + ILI9881C_COMMAND_INSTR(0x6a, 0x02), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x02), + ILI9881C_COMMAND_INSTR(0x6d, 0x02), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), + ILI9881C_COMMAND_INSTR(0x70, 0x02), + ILI9881C_COMMAND_INSTR(0x71, 0x02), + ILI9881C_COMMAND_INSTR(0x72, 0x06), + ILI9881C_COMMAND_INSTR(0x73, 0x02), + ILI9881C_COMMAND_INSTR(0x74, 0x02), + ILI9881C_COMMAND_INSTR(0x75, 0x14), + ILI9881C_COMMAND_INSTR(0x76, 0x15), + ILI9881C_COMMAND_INSTR(0x77, 0x0f), + ILI9881C_COMMAND_INSTR(0x78, 0x0e), + ILI9881C_COMMAND_INSTR(0x79, 0x0d), + ILI9881C_COMMAND_INSTR(0x7a, 0x0c), + ILI9881C_COMMAND_INSTR(0x7b, 0x11), + ILI9881C_COMMAND_INSTR(0x7c, 0x10), + ILI9881C_COMMAND_INSTR(0x7d, 0x06), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x0a), + ILI9881C_COMMAND_INSTR(0x80, 0x02), + ILI9881C_COMMAND_INSTR(0x81, 0x02), + ILI9881C_COMMAND_INSTR(0x82, 0x02), + ILI9881C_COMMAND_INSTR(0x83, 0x02), + ILI9881C_COMMAND_INSTR(0x84, 0x02), + ILI9881C_COMMAND_INSTR(0x85, 0x02), + ILI9881C_COMMAND_INSTR(0x86, 0x02), + ILI9881C_COMMAND_INSTR(0x87, 0x02), + ILI9881C_COMMAND_INSTR(0x88, 0x08), + ILI9881C_COMMAND_INSTR(0x89, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), + ILI9881C_SWITCH_PAGE_INSTR(4), + ILI9881C_COMMAND_INSTR(0x00, 0x80), + ILI9881C_COMMAND_INSTR(0x70, 0x00), + ILI9881C_COMMAND_INSTR(0x71, 0x00), + ILI9881C_COMMAND_INSTR(0x66, 0xfe), + ILI9881C_COMMAND_INSTR(0x82, 0x15), + ILI9881C_COMMAND_INSTR(0x84, 0x15), + ILI9881C_COMMAND_INSTR(0x85, 0x15), + ILI9881C_COMMAND_INSTR(0x3a, 0x24), + ILI9881C_COMMAND_INSTR(0x32, 0xac), + ILI9881C_COMMAND_INSTR(0x8c, 0x80), + ILI9881C_COMMAND_INSTR(0x3c, 0xf5), + ILI9881C_COMMAND_INSTR(0x88, 0x33), + ILI9881C_SWITCH_PAGE_INSTR(1), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x53, 0x78), + ILI9881C_COMMAND_INSTR(0x55, 0x7b), + ILI9881C_COMMAND_INSTR(0x60, 0x20), + ILI9881C_COMMAND_INSTR(0x61, 0x00), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x00), + ILI9881C_COMMAND_INSTR(0xa0, 0x00), + ILI9881C_COMMAND_INSTR(0xa1, 0x10), + ILI9881C_COMMAND_INSTR(0xa2, 0x1c), + ILI9881C_COMMAND_INSTR(0xa3, 0x13), + ILI9881C_COMMAND_INSTR(0xa4, 0x15), + ILI9881C_COMMAND_INSTR(0xa5, 0x26), + ILI9881C_COMMAND_INSTR(0xa6, 0x1a), + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), + ILI9881C_COMMAND_INSTR(0xa8, 0x67), + ILI9881C_COMMAND_INSTR(0xa9, 0x1c), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x5b), + ILI9881C_COMMAND_INSTR(0xac, 0x26), + ILI9881C_COMMAND_INSTR(0xad, 0x28), + ILI9881C_COMMAND_INSTR(0xae, 0x5c), + ILI9881C_COMMAND_INSTR(0xaf, 0x30), + ILI9881C_COMMAND_INSTR(0xb0, 0x31), + ILI9881C_COMMAND_INSTR(0xb1, 0x32), + ILI9881C_COMMAND_INSTR(0xb2, 0x00), + ILI9881C_COMMAND_INSTR(0xb1, 0x2e), + ILI9881C_COMMAND_INSTR(0xb2, 0x32), + ILI9881C_COMMAND_INSTR(0xb3, 0x00), + ILI9881C_COMMAND_INSTR(0xb6, 0x02), + ILI9881C_COMMAND_INSTR(0xb7, 0x03), + ILI9881C_COMMAND_INSTR(0xc0, 0x00), + ILI9881C_COMMAND_INSTR(0xc1, 0x10), + ILI9881C_COMMAND_INSTR(0xc2, 0x1c), + ILI9881C_COMMAND_INSTR(0xc3, 0x13), + ILI9881C_COMMAND_INSTR(0xc4, 0x15), + ILI9881C_COMMAND_INSTR(0xc5, 0x26), + ILI9881C_COMMAND_INSTR(0xc6, 0x1a), + ILI9881C_COMMAND_INSTR(0xc7, 0x1d), + ILI9881C_COMMAND_INSTR(0xc8, 0x67), + ILI9881C_COMMAND_INSTR(0xc9, 0x1c), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x5b), + ILI9881C_COMMAND_INSTR(0xcc, 0x26), + ILI9881C_COMMAND_INSTR(0xcd, 0x28), + ILI9881C_COMMAND_INSTR(0xce, 0x5c), + ILI9881C_COMMAND_INSTR(0xcf, 0x30), + ILI9881C_COMMAND_INSTR(0xd0, 0x31), + ILI9881C_COMMAND_INSTR(0xd1, 0x2e), + ILI9881C_COMMAND_INSTR(0xd2, 0x32), + ILI9881C_COMMAND_INSTR(0xd3, 0x00), + ILI9881C_SWITCH_PAGE_INSTR(0), +}; + static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_SWITCH_PAGE_INSTR(3), ILI9881C_COMMAND_INSTR(0x01, 0x00), @@ -831,12 +1029,12 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x07, 0x02), ILI9881C_COMMAND_INSTR(0x08, 0x02), ILI9881C_COMMAND_INSTR(0x09, 0x00), - ILI9881C_COMMAND_INSTR(0x0A, 0x00), - ILI9881C_COMMAND_INSTR(0x0B, 0x00), - ILI9881C_COMMAND_INSTR(0x0C, 0x00), - ILI9881C_COMMAND_INSTR(0x0D, 0x00), - ILI9881C_COMMAND_INSTR(0x0E, 0x00), - ILI9881C_COMMAND_INSTR(0x0F, 0x00), + ILI9881C_COMMAND_INSTR(0x0a, 0x00), + ILI9881C_COMMAND_INSTR(0x0b, 0x00), + ILI9881C_COMMAND_INSTR(0x0c, 0x00), + ILI9881C_COMMAND_INSTR(0x0d, 0x00), + ILI9881C_COMMAND_INSTR(0x0e, 0x00), + ILI9881C_COMMAND_INSTR(0x0f, 0x00), ILI9881C_COMMAND_INSTR(0x10, 0x00), ILI9881C_COMMAND_INSTR(0x11, 0x00), @@ -848,12 +1046,12 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x17, 0x00), ILI9881C_COMMAND_INSTR(0x18, 0x08), ILI9881C_COMMAND_INSTR(0x19, 0x00), - ILI9881C_COMMAND_INSTR(0x1A, 0x00), - ILI9881C_COMMAND_INSTR(0x1B, 0x00), - ILI9881C_COMMAND_INSTR(0x1C, 0x00), - ILI9881C_COMMAND_INSTR(0x1D, 0x00), - ILI9881C_COMMAND_INSTR(0x1E, 0xC0), - ILI9881C_COMMAND_INSTR(0x1F, 0x80), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0xc0), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), ILI9881C_COMMAND_INSTR(0x20, 0x02), ILI9881C_COMMAND_INSTR(0x21, 0x09), @@ -865,12 +1063,12 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x27, 0x00), ILI9881C_COMMAND_INSTR(0x28, 0x55), ILI9881C_COMMAND_INSTR(0x29, 0x03), - ILI9881C_COMMAND_INSTR(0x2A, 0x00), - ILI9881C_COMMAND_INSTR(0x2B, 0x00), - ILI9881C_COMMAND_INSTR(0x2C, 0x00), - ILI9881C_COMMAND_INSTR(0x2D, 0x00), - ILI9881C_COMMAND_INSTR(0x2E, 0x00), - ILI9881C_COMMAND_INSTR(0x2F, 0x00), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), ILI9881C_COMMAND_INSTR(0x30, 0x00), ILI9881C_COMMAND_INSTR(0x31, 0x00), @@ -880,54 +1078,54 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x35, 0x05), ILI9881C_COMMAND_INSTR(0x36, 0x05), ILI9881C_COMMAND_INSTR(0x37, 0x00), - ILI9881C_COMMAND_INSTR(0x38, 0x3C), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), ILI9881C_COMMAND_INSTR(0x39, 0x35), - ILI9881C_COMMAND_INSTR(0x3A, 0x00), - ILI9881C_COMMAND_INSTR(0x3B, 0x40), - ILI9881C_COMMAND_INSTR(0x3C, 0x00), - ILI9881C_COMMAND_INSTR(0x3D, 0x00), - ILI9881C_COMMAND_INSTR(0x3E, 0x00), - ILI9881C_COMMAND_INSTR(0x3F, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x40), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), ILI9881C_COMMAND_INSTR(0x40, 0x00), ILI9881C_COMMAND_INSTR(0x41, 0x88), ILI9881C_COMMAND_INSTR(0x42, 0x00), ILI9881C_COMMAND_INSTR(0x43, 0x00), - ILI9881C_COMMAND_INSTR(0x44, 0x1F), + ILI9881C_COMMAND_INSTR(0x44, 0x1f), ILI9881C_COMMAND_INSTR(0x50, 0x01), ILI9881C_COMMAND_INSTR(0x51, 0x23), ILI9881C_COMMAND_INSTR(0x52, 0x45), ILI9881C_COMMAND_INSTR(0x53, 0x67), ILI9881C_COMMAND_INSTR(0x54, 0x89), - ILI9881C_COMMAND_INSTR(0x55, 0xaB), + ILI9881C_COMMAND_INSTR(0x55, 0xab), ILI9881C_COMMAND_INSTR(0x56, 0x01), ILI9881C_COMMAND_INSTR(0x57, 0x23), ILI9881C_COMMAND_INSTR(0x58, 0x45), ILI9881C_COMMAND_INSTR(0x59, 0x67), - ILI9881C_COMMAND_INSTR(0x5A, 0x89), - ILI9881C_COMMAND_INSTR(0x5B, 0xAB), - ILI9881C_COMMAND_INSTR(0x5C, 0xCD), - ILI9881C_COMMAND_INSTR(0x5D, 0xEF), - ILI9881C_COMMAND_INSTR(0x5E, 0x03), - ILI9881C_COMMAND_INSTR(0x5F, 0x14), + ILI9881C_COMMAND_INSTR(0x5a, 0x89), + ILI9881C_COMMAND_INSTR(0x5b, 0xab), + ILI9881C_COMMAND_INSTR(0x5c, 0xcd), + ILI9881C_COMMAND_INSTR(0x5d, 0xef), + ILI9881C_COMMAND_INSTR(0x5e, 0x03), + ILI9881C_COMMAND_INSTR(0x5f, 0x14), ILI9881C_COMMAND_INSTR(0x60, 0x15), - ILI9881C_COMMAND_INSTR(0x61, 0x0C), - ILI9881C_COMMAND_INSTR(0x62, 0x0D), - ILI9881C_COMMAND_INSTR(0x63, 0x0E), - ILI9881C_COMMAND_INSTR(0x64, 0x0F), + ILI9881C_COMMAND_INSTR(0x61, 0x0c), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x0e), + ILI9881C_COMMAND_INSTR(0x64, 0x0f), ILI9881C_COMMAND_INSTR(0x65, 0x10), ILI9881C_COMMAND_INSTR(0x66, 0x11), ILI9881C_COMMAND_INSTR(0x67, 0x08), ILI9881C_COMMAND_INSTR(0x68, 0x02), - ILI9881C_COMMAND_INSTR(0x69, 0x0A), - ILI9881C_COMMAND_INSTR(0x6A, 0x02), - ILI9881C_COMMAND_INSTR(0x6B, 0x02), - ILI9881C_COMMAND_INSTR(0x6C, 0x02), - ILI9881C_COMMAND_INSTR(0x6D, 0x02), - ILI9881C_COMMAND_INSTR(0x6E, 0x02), - ILI9881C_COMMAND_INSTR(0x6F, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x0a), + ILI9881C_COMMAND_INSTR(0x6a, 0x02), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x02), + ILI9881C_COMMAND_INSTR(0x6d, 0x02), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), ILI9881C_COMMAND_INSTR(0x70, 0x02), ILI9881C_COMMAND_INSTR(0x71, 0x02), @@ -936,15 +1134,15 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x74, 0x02), ILI9881C_COMMAND_INSTR(0x75, 0x14), ILI9881C_COMMAND_INSTR(0x76, 0x15), - ILI9881C_COMMAND_INSTR(0x77, 0x0F), - ILI9881C_COMMAND_INSTR(0x78, 0x0E), - ILI9881C_COMMAND_INSTR(0x79, 0x0D), - ILI9881C_COMMAND_INSTR(0x7A, 0x0C), - ILI9881C_COMMAND_INSTR(0x7B, 0x11), - ILI9881C_COMMAND_INSTR(0x7C, 0x10), - ILI9881C_COMMAND_INSTR(0x7D, 0x06), - ILI9881C_COMMAND_INSTR(0x7E, 0x02), - ILI9881C_COMMAND_INSTR(0x7F, 0x0A), + ILI9881C_COMMAND_INSTR(0x77, 0x0f), + ILI9881C_COMMAND_INSTR(0x78, 0x0e), + ILI9881C_COMMAND_INSTR(0x79, 0x0d), + ILI9881C_COMMAND_INSTR(0x7a, 0x0c), + ILI9881C_COMMAND_INSTR(0x7b, 0x11), + ILI9881C_COMMAND_INSTR(0x7c, 0x10), + ILI9881C_COMMAND_INSTR(0x7d, 0x06), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x0a), ILI9881C_COMMAND_INSTR(0x80, 0x02), ILI9881C_COMMAND_INSTR(0x81, 0x02), @@ -956,74 +1154,74 @@ static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_COMMAND_INSTR(0x87, 0x02), ILI9881C_COMMAND_INSTR(0x88, 0x08), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), ILI9881C_COMMAND_INSTR(0x00, 0x80), ILI9881C_COMMAND_INSTR(0x70, 0x00), ILI9881C_COMMAND_INSTR(0x71, 0x00), - ILI9881C_COMMAND_INSTR(0x66, 0xFE), + ILI9881C_COMMAND_INSTR(0x66, 0xfe), ILI9881C_COMMAND_INSTR(0x82, 0x15), ILI9881C_COMMAND_INSTR(0x84, 0x15), ILI9881C_COMMAND_INSTR(0x85, 0x15), ILI9881C_COMMAND_INSTR(0x3a, 0x24), - ILI9881C_COMMAND_INSTR(0x32, 0xAC), - ILI9881C_COMMAND_INSTR(0x8C, 0x80), - ILI9881C_COMMAND_INSTR(0x3C, 0xF5), + ILI9881C_COMMAND_INSTR(0x32, 0xac), + ILI9881C_COMMAND_INSTR(0x8c, 0x80), + ILI9881C_COMMAND_INSTR(0x3c, 0xf5), ILI9881C_COMMAND_INSTR(0x88, 0x33), ILI9881C_SWITCH_PAGE_INSTR(1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), ILI9881C_COMMAND_INSTR(0x31, 0x00), ILI9881C_COMMAND_INSTR(0x53, 0x78), - ILI9881C_COMMAND_INSTR(0x50, 0x5B), - ILI9881C_COMMAND_INSTR(0x51, 0x5B), + ILI9881C_COMMAND_INSTR(0x50, 0x5b), + ILI9881C_COMMAND_INSTR(0x51, 0x5b), ILI9881C_COMMAND_INSTR(0x60, 0x20), ILI9881C_COMMAND_INSTR(0x61, 0x00), - ILI9881C_COMMAND_INSTR(0x62, 0x0D), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), ILI9881C_COMMAND_INSTR(0x63, 0x00), - ILI9881C_COMMAND_INSTR(0xA0, 0x00), - ILI9881C_COMMAND_INSTR(0xA1, 0x10), - ILI9881C_COMMAND_INSTR(0xA2, 0x1C), - ILI9881C_COMMAND_INSTR(0xA3, 0x13), - ILI9881C_COMMAND_INSTR(0xA4, 0x15), - ILI9881C_COMMAND_INSTR(0xA5, 0x26), - ILI9881C_COMMAND_INSTR(0xA6, 0x1A), - ILI9881C_COMMAND_INSTR(0xA7, 0x1D), - ILI9881C_COMMAND_INSTR(0xA8, 0x67), - ILI9881C_COMMAND_INSTR(0xA9, 0x1C), - ILI9881C_COMMAND_INSTR(0xAA, 0x29), - ILI9881C_COMMAND_INSTR(0xAB, 0x5B), - ILI9881C_COMMAND_INSTR(0xAC, 0x26), - ILI9881C_COMMAND_INSTR(0xAD, 0x28), - ILI9881C_COMMAND_INSTR(0xAE, 0x5C), - ILI9881C_COMMAND_INSTR(0xAF, 0x30), - ILI9881C_COMMAND_INSTR(0xB0, 0x31), - ILI9881C_COMMAND_INSTR(0xB1, 0x2E), - ILI9881C_COMMAND_INSTR(0xB2, 0x32), - ILI9881C_COMMAND_INSTR(0xB3, 0x00), - - ILI9881C_COMMAND_INSTR(0xC0, 0x00), - ILI9881C_COMMAND_INSTR(0xC1, 0x10), - ILI9881C_COMMAND_INSTR(0xC2, 0x1C), - ILI9881C_COMMAND_INSTR(0xC3, 0x13), - ILI9881C_COMMAND_INSTR(0xC4, 0x15), - ILI9881C_COMMAND_INSTR(0xC5, 0x26), - ILI9881C_COMMAND_INSTR(0xC6, 0x1A), - ILI9881C_COMMAND_INSTR(0xC7, 0x1D), - ILI9881C_COMMAND_INSTR(0xC8, 0x67), - ILI9881C_COMMAND_INSTR(0xC9, 0x1C), - ILI9881C_COMMAND_INSTR(0xCA, 0x29), - ILI9881C_COMMAND_INSTR(0xCB, 0x5B), - ILI9881C_COMMAND_INSTR(0xCC, 0x26), - ILI9881C_COMMAND_INSTR(0xCD, 0x28), - ILI9881C_COMMAND_INSTR(0xCE, 0x5C), - ILI9881C_COMMAND_INSTR(0xCF, 0x30), - ILI9881C_COMMAND_INSTR(0xD0, 0x31), - ILI9881C_COMMAND_INSTR(0xD1, 0x2E), - ILI9881C_COMMAND_INSTR(0xD2, 0x32), - ILI9881C_COMMAND_INSTR(0xD3, 0x00), + ILI9881C_COMMAND_INSTR(0xa0, 0x00), + ILI9881C_COMMAND_INSTR(0xa1, 0x10), + ILI9881C_COMMAND_INSTR(0xa2, 0x1c), + ILI9881C_COMMAND_INSTR(0xa3, 0x13), + ILI9881C_COMMAND_INSTR(0xa4, 0x15), + ILI9881C_COMMAND_INSTR(0xa5, 0x26), + ILI9881C_COMMAND_INSTR(0xa6, 0x1a), + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), + ILI9881C_COMMAND_INSTR(0xa8, 0x67), + ILI9881C_COMMAND_INSTR(0xa9, 0x1c), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x5b), + ILI9881C_COMMAND_INSTR(0xac, 0x26), + ILI9881C_COMMAND_INSTR(0xad, 0x28), + ILI9881C_COMMAND_INSTR(0xae, 0x5c), + ILI9881C_COMMAND_INSTR(0xaf, 0x30), + ILI9881C_COMMAND_INSTR(0xb0, 0x31), + ILI9881C_COMMAND_INSTR(0xb1, 0x2e), + ILI9881C_COMMAND_INSTR(0xb2, 0x32), + ILI9881C_COMMAND_INSTR(0xb3, 0x00), + + ILI9881C_COMMAND_INSTR(0xc0, 0x00), + ILI9881C_COMMAND_INSTR(0xc1, 0x10), + ILI9881C_COMMAND_INSTR(0xc2, 0x1c), + ILI9881C_COMMAND_INSTR(0xc3, 0x13), + ILI9881C_COMMAND_INSTR(0xc4, 0x15), + ILI9881C_COMMAND_INSTR(0xc5, 0x26), + ILI9881C_COMMAND_INSTR(0xc6, 0x1a), + ILI9881C_COMMAND_INSTR(0xc7, 0x1d), + ILI9881C_COMMAND_INSTR(0xc8, 0x67), + ILI9881C_COMMAND_INSTR(0xc9, 0x1c), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x5b), + ILI9881C_COMMAND_INSTR(0xcc, 0x26), + ILI9881C_COMMAND_INSTR(0xcd, 0x28), + ILI9881C_COMMAND_INSTR(0xce, 0x5c), + ILI9881C_COMMAND_INSTR(0xcf, 0x30), + ILI9881C_COMMAND_INSTR(0xd0, 0x31), + ILI9881C_COMMAND_INSTR(0xd1, 0x2e), + ILI9881C_COMMAND_INSTR(0xd2, 0x32), + ILI9881C_COMMAND_INSTR(0xd3, 0x00), ILI9881C_SWITCH_PAGE_INSTR(0), }; @@ -1032,10 +1230,10 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(0x01, 0x00), ILI9881C_COMMAND_INSTR(0x02, 0x00), ILI9881C_COMMAND_INSTR(0x03, 0x73), - ILI9881C_COMMAND_INSTR(0x04, 0xD3), + ILI9881C_COMMAND_INSTR(0x04, 0xd3), ILI9881C_COMMAND_INSTR(0x05, 0x00), - ILI9881C_COMMAND_INSTR(0x06, 0x0A), - ILI9881C_COMMAND_INSTR(0x07, 0x0E), + ILI9881C_COMMAND_INSTR(0x06, 0x0a), + ILI9881C_COMMAND_INSTR(0x07, 0x0e), ILI9881C_COMMAND_INSTR(0x08, 0x00), ILI9881C_COMMAND_INSTR(0x09, 0x01), ILI9881C_COMMAND_INSTR(0x0a, 0x01), @@ -1117,10 +1315,10 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(0x5f, 0x02), ILI9881C_COMMAND_INSTR(0x60, 0x00), ILI9881C_COMMAND_INSTR(0x61, 0x01), - ILI9881C_COMMAND_INSTR(0x62, 0x0D), - ILI9881C_COMMAND_INSTR(0x63, 0x0C), - ILI9881C_COMMAND_INSTR(0x64, 0x0F), - ILI9881C_COMMAND_INSTR(0x65, 0x0E), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x0c), + ILI9881C_COMMAND_INSTR(0x64, 0x0f), + ILI9881C_COMMAND_INSTR(0x65, 0x0e), ILI9881C_COMMAND_INSTR(0x66, 0x06), ILI9881C_COMMAND_INSTR(0x67, 0x07), ILI9881C_COMMAND_INSTR(0x68, 0x02), @@ -1139,10 +1337,10 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(0x75, 0x02), ILI9881C_COMMAND_INSTR(0x76, 0x00), ILI9881C_COMMAND_INSTR(0x77, 0x01), - ILI9881C_COMMAND_INSTR(0x78, 0x0D), - ILI9881C_COMMAND_INSTR(0x79, 0x0C), - ILI9881C_COMMAND_INSTR(0x7a, 0x0F), - ILI9881C_COMMAND_INSTR(0x7b, 0x0E), + ILI9881C_COMMAND_INSTR(0x78, 0x0d), + ILI9881C_COMMAND_INSTR(0x79, 0x0c), + ILI9881C_COMMAND_INSTR(0x7a, 0x0f), + ILI9881C_COMMAND_INSTR(0x7b, 0x0e), ILI9881C_COMMAND_INSTR(0x7c, 0x06), ILI9881C_COMMAND_INSTR(0x7d, 0x07), ILI9881C_COMMAND_INSTR(0x7e, 0x02), @@ -1157,7 +1355,7 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(0x87, 0x02), ILI9881C_COMMAND_INSTR(0x88, 0x02), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), ILI9881C_COMMAND_INSTR(0x6c, 0x15), @@ -1170,60 +1368,248 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(0xb2, 0xd1), ILI9881C_SWITCH_PAGE_INSTR(1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), - ILI9881C_COMMAND_INSTR(0x31, 0x0B), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x31, 0x0b), ILI9881C_COMMAND_INSTR(0x50, 0xa5), ILI9881C_COMMAND_INSTR(0x51, 0xa0), ILI9881C_COMMAND_INSTR(0x53, 0x70), - ILI9881C_COMMAND_INSTR(0x55, 0x7A), + ILI9881C_COMMAND_INSTR(0x55, 0x7a), ILI9881C_COMMAND_INSTR(0x60, 0x14), - ILI9881C_COMMAND_INSTR(0xA0, 0x00), - ILI9881C_COMMAND_INSTR(0xA1, 0x53), - ILI9881C_COMMAND_INSTR(0xA2, 0x50), - ILI9881C_COMMAND_INSTR(0xA3, 0x20), - ILI9881C_COMMAND_INSTR(0xA4, 0x27), - ILI9881C_COMMAND_INSTR(0xA5, 0x33), - ILI9881C_COMMAND_INSTR(0xA6, 0x25), - ILI9881C_COMMAND_INSTR(0xA7, 0x25), - ILI9881C_COMMAND_INSTR(0xA8, 0xD4), - ILI9881C_COMMAND_INSTR(0xA9, 0x1A), - ILI9881C_COMMAND_INSTR(0xAA, 0x2B), - ILI9881C_COMMAND_INSTR(0xAB, 0xB5), - ILI9881C_COMMAND_INSTR(0xAC, 0x19), - ILI9881C_COMMAND_INSTR(0xAD, 0x18), - ILI9881C_COMMAND_INSTR(0xAE, 0x53), - ILI9881C_COMMAND_INSTR(0xAF, 0x1A), - ILI9881C_COMMAND_INSTR(0xB0, 0x25), - ILI9881C_COMMAND_INSTR(0xB1, 0x62), - ILI9881C_COMMAND_INSTR(0xB2, 0x6A), - ILI9881C_COMMAND_INSTR(0xB3, 0x31), - - ILI9881C_COMMAND_INSTR(0xC0, 0x00), - ILI9881C_COMMAND_INSTR(0xC1, 0x53), - ILI9881C_COMMAND_INSTR(0xC2, 0x50), - ILI9881C_COMMAND_INSTR(0xC3, 0x20), - ILI9881C_COMMAND_INSTR(0xC4, 0x27), - ILI9881C_COMMAND_INSTR(0xC5, 0x33), - ILI9881C_COMMAND_INSTR(0xC6, 0x25), - ILI9881C_COMMAND_INSTR(0xC7, 0x25), - ILI9881C_COMMAND_INSTR(0xC8, 0xD4), - ILI9881C_COMMAND_INSTR(0xC9, 0x1A), - ILI9881C_COMMAND_INSTR(0xCA, 0x2B), - ILI9881C_COMMAND_INSTR(0xCB, 0xB5), - ILI9881C_COMMAND_INSTR(0xCC, 0x19), - ILI9881C_COMMAND_INSTR(0xCD, 0x18), - ILI9881C_COMMAND_INSTR(0xCE, 0x53), - ILI9881C_COMMAND_INSTR(0xCF, 0x1A), - ILI9881C_COMMAND_INSTR(0xD0, 0x25), - ILI9881C_COMMAND_INSTR(0xD1, 0x62), - ILI9881C_COMMAND_INSTR(0xD2, 0x6A), - ILI9881C_COMMAND_INSTR(0xD3, 0x31), + ILI9881C_COMMAND_INSTR(0xa0, 0x00), + ILI9881C_COMMAND_INSTR(0xa1, 0x53), + ILI9881C_COMMAND_INSTR(0xa2, 0x50), + ILI9881C_COMMAND_INSTR(0xa3, 0x20), + ILI9881C_COMMAND_INSTR(0xa4, 0x27), + ILI9881C_COMMAND_INSTR(0xa5, 0x33), + ILI9881C_COMMAND_INSTR(0xa6, 0x25), + ILI9881C_COMMAND_INSTR(0xa7, 0x25), + ILI9881C_COMMAND_INSTR(0xa8, 0xd4), + ILI9881C_COMMAND_INSTR(0xa9, 0x1a), + ILI9881C_COMMAND_INSTR(0xaa, 0x2b), + ILI9881C_COMMAND_INSTR(0xab, 0xb5), + ILI9881C_COMMAND_INSTR(0xac, 0x19), + ILI9881C_COMMAND_INSTR(0xad, 0x18), + ILI9881C_COMMAND_INSTR(0xae, 0x53), + ILI9881C_COMMAND_INSTR(0xaf, 0x1a), + ILI9881C_COMMAND_INSTR(0xb0, 0x25), + ILI9881C_COMMAND_INSTR(0xb1, 0x62), + ILI9881C_COMMAND_INSTR(0xb2, 0x6a), + ILI9881C_COMMAND_INSTR(0xb3, 0x31), + + ILI9881C_COMMAND_INSTR(0xc0, 0x00), + ILI9881C_COMMAND_INSTR(0xc1, 0x53), + ILI9881C_COMMAND_INSTR(0xc2, 0x50), + ILI9881C_COMMAND_INSTR(0xc3, 0x20), + ILI9881C_COMMAND_INSTR(0xc4, 0x27), + ILI9881C_COMMAND_INSTR(0xc5, 0x33), + ILI9881C_COMMAND_INSTR(0xc6, 0x25), + ILI9881C_COMMAND_INSTR(0xc7, 0x25), + ILI9881C_COMMAND_INSTR(0xc8, 0xd4), + ILI9881C_COMMAND_INSTR(0xc9, 0x1a), + ILI9881C_COMMAND_INSTR(0xca, 0x2b), + ILI9881C_COMMAND_INSTR(0xcb, 0xb5), + ILI9881C_COMMAND_INSTR(0xcc, 0x19), + ILI9881C_COMMAND_INSTR(0xcd, 0x18), + ILI9881C_COMMAND_INSTR(0xce, 0x53), + ILI9881C_COMMAND_INSTR(0xcf, 0x1a), + ILI9881C_COMMAND_INSTR(0xd0, 0x25), + ILI9881C_COMMAND_INSTR(0xd1, 0x62), + ILI9881C_COMMAND_INSTR(0xd2, 0x6a), + ILI9881C_COMMAND_INSTR(0xd3, 0x31), ILI9881C_SWITCH_PAGE_INSTR(0), ILI9881C_COMMAND_INSTR(MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c), ILI9881C_COMMAND_INSTR(MIPI_DCS_WRITE_POWER_SAVE, 0x00), }; +static const struct ili9881c_instr rpi_5inch_init[] = { + ILI9881C_SWITCH_PAGE_INSTR(3), + ILI9881C_COMMAND_INSTR(0x01, 0x00), + ILI9881C_COMMAND_INSTR(0x02, 0x00), + ILI9881C_COMMAND_INSTR(0x03, 0x73), + ILI9881C_COMMAND_INSTR(0x04, 0x73), + ILI9881C_COMMAND_INSTR(0x05, 0x00), + ILI9881C_COMMAND_INSTR(0x06, 0x06), + ILI9881C_COMMAND_INSTR(0x07, 0x02), + ILI9881C_COMMAND_INSTR(0x08, 0x00), + ILI9881C_COMMAND_INSTR(0x09, 0x01), + ILI9881C_COMMAND_INSTR(0x0a, 0x01), + ILI9881C_COMMAND_INSTR(0x0b, 0x01), + ILI9881C_COMMAND_INSTR(0x0c, 0x01), + ILI9881C_COMMAND_INSTR(0x0d, 0x01), + ILI9881C_COMMAND_INSTR(0x0e, 0x01), + ILI9881C_COMMAND_INSTR(0x0f, 0x01), + ILI9881C_COMMAND_INSTR(0x10, 0x01), + ILI9881C_COMMAND_INSTR(0x11, 0x00), + ILI9881C_COMMAND_INSTR(0x12, 0x00), + ILI9881C_COMMAND_INSTR(0x13, 0x01), + ILI9881C_COMMAND_INSTR(0x14, 0x00), + ILI9881C_COMMAND_INSTR(0x15, 0x00), + ILI9881C_COMMAND_INSTR(0x16, 0x00), + ILI9881C_COMMAND_INSTR(0x17, 0x00), + ILI9881C_COMMAND_INSTR(0x18, 0x00), + ILI9881C_COMMAND_INSTR(0x19, 0x00), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0xc0), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), + ILI9881C_COMMAND_INSTR(0x20, 0x04), + ILI9881C_COMMAND_INSTR(0x21, 0x03), + ILI9881C_COMMAND_INSTR(0x22, 0x00), + ILI9881C_COMMAND_INSTR(0x23, 0x00), + ILI9881C_COMMAND_INSTR(0x24, 0x00), + ILI9881C_COMMAND_INSTR(0x25, 0x00), + ILI9881C_COMMAND_INSTR(0x26, 0x00), + ILI9881C_COMMAND_INSTR(0x27, 0x00), + ILI9881C_COMMAND_INSTR(0x28, 0x33), + ILI9881C_COMMAND_INSTR(0x29, 0x03), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), + ILI9881C_COMMAND_INSTR(0x30, 0x00), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x32, 0x00), + ILI9881C_COMMAND_INSTR(0x33, 0x00), + ILI9881C_COMMAND_INSTR(0x34, 0x03), + ILI9881C_COMMAND_INSTR(0x35, 0x00), + ILI9881C_COMMAND_INSTR(0x36, 0x03), + ILI9881C_COMMAND_INSTR(0x37, 0x00), + ILI9881C_COMMAND_INSTR(0x38, 0x00), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x00), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x00), + ILI9881C_COMMAND_INSTR(0x41, 0x00), + ILI9881C_COMMAND_INSTR(0x42, 0x00), + ILI9881C_COMMAND_INSTR(0x43, 0x00), + ILI9881C_COMMAND_INSTR(0x44, 0x00), + ILI9881C_COMMAND_INSTR(0x50, 0x01), + ILI9881C_COMMAND_INSTR(0x51, 0x23), + ILI9881C_COMMAND_INSTR(0x52, 0x45), + ILI9881C_COMMAND_INSTR(0x53, 0x67), + ILI9881C_COMMAND_INSTR(0x54, 0x89), + ILI9881C_COMMAND_INSTR(0x55, 0xab), + ILI9881C_COMMAND_INSTR(0x56, 0x01), + ILI9881C_COMMAND_INSTR(0x57, 0x23), + ILI9881C_COMMAND_INSTR(0x58, 0x45), + ILI9881C_COMMAND_INSTR(0x59, 0x67), + ILI9881C_COMMAND_INSTR(0x5a, 0x89), + ILI9881C_COMMAND_INSTR(0x5b, 0xab), + ILI9881C_COMMAND_INSTR(0x5c, 0xcd), + ILI9881C_COMMAND_INSTR(0x5d, 0xef), + ILI9881C_COMMAND_INSTR(0x5e, 0x10), + ILI9881C_COMMAND_INSTR(0x5f, 0x09), + ILI9881C_COMMAND_INSTR(0x60, 0x08), + ILI9881C_COMMAND_INSTR(0x61, 0x0f), + ILI9881C_COMMAND_INSTR(0x62, 0x0e), + ILI9881C_COMMAND_INSTR(0x63, 0x0d), + ILI9881C_COMMAND_INSTR(0x64, 0x0c), + ILI9881C_COMMAND_INSTR(0x65, 0x02), + ILI9881C_COMMAND_INSTR(0x66, 0x02), + ILI9881C_COMMAND_INSTR(0x67, 0x02), + ILI9881C_COMMAND_INSTR(0x68, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x02), + ILI9881C_COMMAND_INSTR(0x6a, 0x02), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x02), + ILI9881C_COMMAND_INSTR(0x6d, 0x02), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), + ILI9881C_COMMAND_INSTR(0x70, 0x02), + ILI9881C_COMMAND_INSTR(0x71, 0x06), + ILI9881C_COMMAND_INSTR(0x72, 0x07), + ILI9881C_COMMAND_INSTR(0x73, 0x02), + ILI9881C_COMMAND_INSTR(0x74, 0x02), + ILI9881C_COMMAND_INSTR(0x75, 0x06), + ILI9881C_COMMAND_INSTR(0x76, 0x07), + ILI9881C_COMMAND_INSTR(0x77, 0x0e), + ILI9881C_COMMAND_INSTR(0x78, 0x0f), + ILI9881C_COMMAND_INSTR(0x79, 0x0c), + ILI9881C_COMMAND_INSTR(0x7a, 0x0d), + ILI9881C_COMMAND_INSTR(0x7b, 0x02), + ILI9881C_COMMAND_INSTR(0x7c, 0x02), + ILI9881C_COMMAND_INSTR(0x7d, 0x02), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x02), + ILI9881C_COMMAND_INSTR(0x80, 0x02), + ILI9881C_COMMAND_INSTR(0x81, 0x02), + ILI9881C_COMMAND_INSTR(0x82, 0x02), + ILI9881C_COMMAND_INSTR(0x83, 0x02), + ILI9881C_COMMAND_INSTR(0x84, 0x02), + ILI9881C_COMMAND_INSTR(0x85, 0x02), + ILI9881C_COMMAND_INSTR(0x86, 0x02), + ILI9881C_COMMAND_INSTR(0x87, 0x09), + ILI9881C_COMMAND_INSTR(0x88, 0x08), + ILI9881C_COMMAND_INSTR(0x89, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), + ILI9881C_SWITCH_PAGE_INSTR(4), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x2a), + ILI9881C_COMMAND_INSTR(0x6f, 0x57), + ILI9881C_COMMAND_INSTR(0x3a, 0xa4), + ILI9881C_COMMAND_INSTR(0x8d, 0x1a), + ILI9881C_COMMAND_INSTR(0x87, 0xba), + ILI9881C_COMMAND_INSTR(0x26, 0x76), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), + ILI9881C_SWITCH_PAGE_INSTR(1), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x53, 0x35), + ILI9881C_COMMAND_INSTR(0x55, 0x50), + ILI9881C_COMMAND_INSTR(0x50, 0xaf), + ILI9881C_COMMAND_INSTR(0x51, 0xaf), + ILI9881C_COMMAND_INSTR(0x60, 0x14), + ILI9881C_COMMAND_INSTR(0xa0, 0x08), + ILI9881C_COMMAND_INSTR(0xa1, 0x1d), + ILI9881C_COMMAND_INSTR(0xa2, 0x2c), + ILI9881C_COMMAND_INSTR(0xa3, 0x14), + ILI9881C_COMMAND_INSTR(0xa4, 0x19), + ILI9881C_COMMAND_INSTR(0xa5, 0x2e), + ILI9881C_COMMAND_INSTR(0xa6, 0x22), + ILI9881C_COMMAND_INSTR(0xa7, 0x23), + ILI9881C_COMMAND_INSTR(0xa8, 0x97), + ILI9881C_COMMAND_INSTR(0xa9, 0x1e), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x7b), + ILI9881C_COMMAND_INSTR(0xac, 0x18), + ILI9881C_COMMAND_INSTR(0xad, 0x17), + ILI9881C_COMMAND_INSTR(0xae, 0x4b), + ILI9881C_COMMAND_INSTR(0xaf, 0x1f), + ILI9881C_COMMAND_INSTR(0xb0, 0x27), + ILI9881C_COMMAND_INSTR(0xb1, 0x52), + ILI9881C_COMMAND_INSTR(0xb2, 0x63), + ILI9881C_COMMAND_INSTR(0xb3, 0x39), + ILI9881C_COMMAND_INSTR(0xc0, 0x08), + ILI9881C_COMMAND_INSTR(0xc1, 0x1d), + ILI9881C_COMMAND_INSTR(0xc2, 0x2c), + ILI9881C_COMMAND_INSTR(0xc3, 0x14), + ILI9881C_COMMAND_INSTR(0xc4, 0x19), + ILI9881C_COMMAND_INSTR(0xc5, 0x2e), + ILI9881C_COMMAND_INSTR(0xc6, 0x22), + ILI9881C_COMMAND_INSTR(0xc7, 0x23), + ILI9881C_COMMAND_INSTR(0xc8, 0x97), + ILI9881C_COMMAND_INSTR(0xc9, 0x1e), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x7b), + ILI9881C_COMMAND_INSTR(0xcc, 0x18), + ILI9881C_COMMAND_INSTR(0xcd, 0x17), + ILI9881C_COMMAND_INSTR(0xce, 0x4b), + ILI9881C_COMMAND_INSTR(0xcf, 0x1f), + ILI9881C_COMMAND_INSTR(0xd0, 0x27), + ILI9881C_COMMAND_INSTR(0xd1, 0x52), + ILI9881C_COMMAND_INSTR(0xd2, 0x63), + ILI9881C_COMMAND_INSTR(0xd3, 0x39), +}; + static const struct ili9881c_instr rpi_7inch_init[] = { ILI9881C_SWITCH_PAGE_INSTR(3), ILI9881C_COMMAND_INSTR(0x01, 0x00), @@ -1352,22 +1738,22 @@ static const struct ili9881c_instr rpi_7inch_init[] = { ILI9881C_COMMAND_INSTR(0x87, 0x02), ILI9881C_COMMAND_INSTR(0x88, 0x02), ILI9881C_COMMAND_INSTR(0x89, 0x02), - ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_COMMAND_INSTR(0x8a, 0x02), ILI9881C_SWITCH_PAGE_INSTR(4), - ILI9881C_COMMAND_INSTR(0x6C, 0x15), - ILI9881C_COMMAND_INSTR(0x6E, 0x2A), - ILI9881C_COMMAND_INSTR(0x6F, 0x33), - ILI9881C_COMMAND_INSTR(0x3B, 0x98), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x2a), + ILI9881C_COMMAND_INSTR(0x6f, 0x33), + ILI9881C_COMMAND_INSTR(0x3b, 0x98), ILI9881C_COMMAND_INSTR(0x3a, 0x94), - ILI9881C_COMMAND_INSTR(0x8D, 0x14), - ILI9881C_COMMAND_INSTR(0x87, 0xBA), + ILI9881C_COMMAND_INSTR(0x8d, 0x14), + ILI9881C_COMMAND_INSTR(0x87, 0xba), ILI9881C_COMMAND_INSTR(0x26, 0x76), - ILI9881C_COMMAND_INSTR(0xB2, 0xD1), - ILI9881C_COMMAND_INSTR(0xB5, 0x06), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), + ILI9881C_COMMAND_INSTR(0xb5, 0x06), ILI9881C_COMMAND_INSTR(0x38, 0x01), ILI9881C_COMMAND_INSTR(0x39, 0x00), ILI9881C_SWITCH_PAGE_INSTR(1), - ILI9881C_COMMAND_INSTR(0x22, 0x0A), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), ILI9881C_COMMAND_INSTR(0x31, 0x00), ILI9881C_COMMAND_INSTR(0x53, 0x7d), ILI9881C_COMMAND_INSTR(0x55, 0x8f), @@ -1375,46 +1761,46 @@ static const struct ili9881c_instr rpi_7inch_init[] = { ILI9881C_COMMAND_INSTR(0x50, 0x96), ILI9881C_COMMAND_INSTR(0x51, 0x96), ILI9881C_COMMAND_INSTR(0x60, 0x23), - ILI9881C_COMMAND_INSTR(0xA0, 0x08), - ILI9881C_COMMAND_INSTR(0xA1, 0x1d), - ILI9881C_COMMAND_INSTR(0xA2, 0x2a), - ILI9881C_COMMAND_INSTR(0xA3, 0x10), - ILI9881C_COMMAND_INSTR(0xA4, 0x15), - ILI9881C_COMMAND_INSTR(0xA5, 0x28), - ILI9881C_COMMAND_INSTR(0xA6, 0x1c), - ILI9881C_COMMAND_INSTR(0xA7, 0x1d), - ILI9881C_COMMAND_INSTR(0xA8, 0x7e), - ILI9881C_COMMAND_INSTR(0xA9, 0x1d), - ILI9881C_COMMAND_INSTR(0xAA, 0x29), - ILI9881C_COMMAND_INSTR(0xAB, 0x6b), - ILI9881C_COMMAND_INSTR(0xAC, 0x1a), - ILI9881C_COMMAND_INSTR(0xAD, 0x18), - ILI9881C_COMMAND_INSTR(0xAE, 0x4b), - ILI9881C_COMMAND_INSTR(0xAF, 0x20), - ILI9881C_COMMAND_INSTR(0xB0, 0x27), - ILI9881C_COMMAND_INSTR(0xB1, 0x50), - ILI9881C_COMMAND_INSTR(0xB2, 0x64), - ILI9881C_COMMAND_INSTR(0xB3, 0x39), - ILI9881C_COMMAND_INSTR(0xC0, 0x08), - ILI9881C_COMMAND_INSTR(0xC1, 0x1d), - ILI9881C_COMMAND_INSTR(0xC2, 0x2a), - ILI9881C_COMMAND_INSTR(0xC3, 0x10), - ILI9881C_COMMAND_INSTR(0xC4, 0x15), - ILI9881C_COMMAND_INSTR(0xC5, 0x28), - ILI9881C_COMMAND_INSTR(0xC6, 0x1c), - ILI9881C_COMMAND_INSTR(0xC7, 0x1d), - ILI9881C_COMMAND_INSTR(0xC8, 0x7e), - ILI9881C_COMMAND_INSTR(0xC9, 0x1d), - ILI9881C_COMMAND_INSTR(0xCA, 0x29), - ILI9881C_COMMAND_INSTR(0xCB, 0x6b), - ILI9881C_COMMAND_INSTR(0xCC, 0x1a), - ILI9881C_COMMAND_INSTR(0xCD, 0x18), - ILI9881C_COMMAND_INSTR(0xCE, 0x4b), - ILI9881C_COMMAND_INSTR(0xCF, 0x20), - ILI9881C_COMMAND_INSTR(0xD0, 0x27), - ILI9881C_COMMAND_INSTR(0xD1, 0x50), - ILI9881C_COMMAND_INSTR(0xD2, 0x64), - ILI9881C_COMMAND_INSTR(0xD3, 0x39), + ILI9881C_COMMAND_INSTR(0xa0, 0x08), + ILI9881C_COMMAND_INSTR(0xa1, 0x1d), + ILI9881C_COMMAND_INSTR(0xa2, 0x2a), + ILI9881C_COMMAND_INSTR(0xa3, 0x10), + ILI9881C_COMMAND_INSTR(0xa4, 0x15), + ILI9881C_COMMAND_INSTR(0xa5, 0x28), + ILI9881C_COMMAND_INSTR(0xa6, 0x1c), + ILI9881C_COMMAND_INSTR(0xa7, 0x1d), + ILI9881C_COMMAND_INSTR(0xa8, 0x7e), + ILI9881C_COMMAND_INSTR(0xa9, 0x1d), + ILI9881C_COMMAND_INSTR(0xaa, 0x29), + ILI9881C_COMMAND_INSTR(0xab, 0x6b), + ILI9881C_COMMAND_INSTR(0xac, 0x1a), + ILI9881C_COMMAND_INSTR(0xad, 0x18), + ILI9881C_COMMAND_INSTR(0xae, 0x4b), + ILI9881C_COMMAND_INSTR(0xaf, 0x20), + ILI9881C_COMMAND_INSTR(0xb0, 0x27), + ILI9881C_COMMAND_INSTR(0xb1, 0x50), + ILI9881C_COMMAND_INSTR(0xb2, 0x64), + ILI9881C_COMMAND_INSTR(0xb3, 0x39), + ILI9881C_COMMAND_INSTR(0xc0, 0x08), + ILI9881C_COMMAND_INSTR(0xc1, 0x1d), + ILI9881C_COMMAND_INSTR(0xc2, 0x2a), + ILI9881C_COMMAND_INSTR(0xc3, 0x10), + ILI9881C_COMMAND_INSTR(0xc4, 0x15), + ILI9881C_COMMAND_INSTR(0xc5, 0x28), + ILI9881C_COMMAND_INSTR(0xc6, 0x1c), + ILI9881C_COMMAND_INSTR(0xc7, 0x1d), + ILI9881C_COMMAND_INSTR(0xc8, 0x7e), + ILI9881C_COMMAND_INSTR(0xc9, 0x1d), + ILI9881C_COMMAND_INSTR(0xca, 0x29), + ILI9881C_COMMAND_INSTR(0xcb, 0x6b), + ILI9881C_COMMAND_INSTR(0xcc, 0x1a), + ILI9881C_COMMAND_INSTR(0xcd, 0x18), + ILI9881C_COMMAND_INSTR(0xce, 0x4b), + ILI9881C_COMMAND_INSTR(0xcf, 0x20), + ILI9881C_COMMAND_INSTR(0xd0, 0x27), + ILI9881C_COMMAND_INSTR(0xd1, 0x50), + ILI9881C_COMMAND_INSTR(0xd2, 0x64), + ILI9881C_COMMAND_INSTR(0xd3, 0x39), }; static const struct ili9881c_instr bsd1218_a101kl68_init[] = { @@ -1772,6 +2158,23 @@ static const struct drm_display_mode tl050hdv35_default_mode = { .height_mm = 110, }; +static const struct drm_display_mode w552946aaa_default_mode = { + .clock = 65000, + + .hdisplay = 720, + .hsync_start = 720 + 52, + .hsync_end = 720 + 52 + 8, + .htotal = 720 + 52 + 8 + 48, + + .vdisplay = 1280, + .vsync_start = 1280 + 16, + .vsync_end = 1280 + 16 + 6, + .vtotal = 1280 + 16 + 6 + 15, + + .width_mm = 68, + .height_mm = 121, +}; + static const struct drm_display_mode w552946aba_default_mode = { .clock = 64000, @@ -1806,6 +2209,23 @@ static const struct drm_display_mode am8001280g_default_mode = { .height_mm = 151, }; +static const struct drm_display_mode rpi_5inch_default_mode = { + .clock = 83333, + + .hdisplay = 720, + .hsync_start = 720 + 110, + .hsync_end = 720 + 110 + 12, + .htotal = 720 + 110 + 12 + 95, + + .vdisplay = 1280, + .vsync_start = 1280 + 100, + .vsync_end = 1280 + 100 + 2, + .vtotal = 1280 + 100 + 2 + 100, + + .width_mm = 62, + .height_mm = 110, +}; + static const struct drm_display_mode rpi_7inch_default_mode = { .clock = 83330, @@ -1983,6 +2403,15 @@ static const struct ili9881c_desc tl050hdv35_desc = { .default_address_mode = 0x03, }; +static const struct ili9881c_desc w552946aaa_desc = { + .init = w552946aaa_init, + .init_length = ARRAY_SIZE(w552946aaa_init), + .mode = &w552946aaa_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET, + .lanes = 2, +}; + static const struct ili9881c_desc w552946aba_desc = { .init = w552946ab_init, .init_length = ARRAY_SIZE(w552946ab_init), @@ -2000,6 +2429,14 @@ static const struct ili9881c_desc am8001280g_desc = { MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM, }; +static const struct ili9881c_desc rpi_5inch_desc = { + .init = rpi_5inch_init, + .init_length = ARRAY_SIZE(rpi_5inch_init), + .mode = &rpi_5inch_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM, + .lanes = 2, +}; + static const struct ili9881c_desc rpi_7inch_desc = { .init = rpi_7inch_init, .init_length = ARRAY_SIZE(rpi_7inch_init), @@ -2023,8 +2460,10 @@ static const struct of_device_id ili9881c_of_match[] = { { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc }, { .compatible = "startek,kd050hdfia020", .data = &kd050hdfia020_desc }, { .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc }, + { .compatible = "wanchanglong,w552946aaa", .data = &w552946aaa_desc }, { .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc }, { .compatible = "ampire,am8001280g", .data = &am8001280g_desc }, + { .compatible = "raspberrypi,dsi-5inch", &rpi_5inch_desc }, { .compatible = "raspberrypi,dsi-7inch", &rpi_7inch_desc }, { } }; diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c index 85c7059be214..c52f20863fc7 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c @@ -61,6 +61,13 @@ struct ili9882t { mipi_dsi_dcs_write_seq_multi(ctx, ILI9882T_DCS_SWITCH_PAGE, \ 0x98, 0x82, (page)) +/* IL79900A-specific commands, add new commands as you decode them */ +#define IL79900A_DCS_SWITCH_PAGE 0xFF + +#define il79900a_switch_page(ctx, page) \ + mipi_dsi_dcs_write_seq_multi(ctx, IL79900A_DCS_SWITCH_PAGE, \ + 0x5a, 0xa5, (page)) + static int starry_ili9882t_init(struct ili9882t *ili) { struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; @@ -413,6 +420,38 @@ static int starry_ili9882t_init(struct ili9882t *ili) return ctx.accum_err; }; +static int tianma_il79900a_init(struct ili9882t *ili) +{ + struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; + + mipi_dsi_usleep_range(&ctx, 5000, 5100); + + il79900a_switch_page(&ctx, 0x06); + mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x62); + + il79900a_switch_page(&ctx, 0x02); + mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x20); + mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00); + mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40); + + il79900a_switch_page(&ctx, 0x07); + mipi_dsi_dcs_write_seq_multi(&ctx, 0X29, 0x00); + + il79900a_switch_page(&ctx, 0x06); + mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22); + + il79900a_switch_page(&ctx, 0x00); + mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); + + mipi_dsi_msleep(&ctx, 120); + + mipi_dsi_dcs_set_display_on_multi(&ctx); + + mipi_dsi_msleep(&ctx, 80); + + return 0; +}; + static inline struct ili9882t *to_ili9882t(struct drm_panel *panel) { return container_of(panel, struct ili9882t, base); @@ -529,6 +568,19 @@ static const struct drm_display_mode starry_ili9882t_default_mode = { .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, }; +static const struct drm_display_mode tianma_il79900a_default_mode = { + .clock = 264355, + .hdisplay = 1600, + .hsync_start = 1600 + 20, + .hsync_end = 1600 + 20 + 4, + .htotal = 1600 + 20 + 4 + 20, + .vdisplay = 2560, + .vsync_start = 2560 + 82, + .vsync_end = 2560 + 82 + 2, + .vtotal = 2560 + 82 + 2 + 36, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + static const struct panel_desc starry_ili9882t_desc = { .modes = &starry_ili9882t_default_mode, .bpc = 8, @@ -543,6 +595,20 @@ static const struct panel_desc starry_ili9882t_desc = { .init = starry_ili9882t_init, }; +static const struct panel_desc tianma_tl121bvms07_desc = { + .modes = &tianma_il79900a_default_mode, + .bpc = 8, + .size = { + .width_mm = 163, + .height_mm = 260, + }, + .lanes = 3, + .format = MIPI_DSI_FMT_RGB888, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, + .init = tianma_il79900a_init, +}; + static int ili9882t_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -680,6 +746,9 @@ static const struct of_device_id ili9882t_of_match[] = { { .compatible = "starry,ili9882t", .data = &starry_ili9882t_desc }, + { .compatible = "tianma,tl121bvms07-00", + .data = &tianma_tl121bvms07_desc + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ili9882t_of_match); diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 5c2530598ddb..aa05316dc57b 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -1132,22 +1132,19 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) dsi->lanes = desc->lanes; jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(jadard->reset)) { - DRM_DEV_ERROR(&dsi->dev, "failed to get our reset GPIO\n"); - return PTR_ERR(jadard->reset); - } + if (IS_ERR(jadard->reset)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->reset), + "failed to get our reset GPIO\n"); jadard->vdd = devm_regulator_get(dev, "vdd"); - if (IS_ERR(jadard->vdd)) { - DRM_DEV_ERROR(&dsi->dev, "failed to get vdd regulator\n"); - return PTR_ERR(jadard->vdd); - } + if (IS_ERR(jadard->vdd)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vdd), + "failed to get vdd regulator\n"); jadard->vccio = devm_regulator_get(dev, "vccio"); - if (IS_ERR(jadard->vccio)) { - DRM_DEV_ERROR(&dsi->dev, "failed to get vccio regulator\n"); - return PTR_ERR(jadard->vccio); - } + if (IS_ERR(jadard->vccio)) + return dev_err_probe(&dsi->dev, PTR_ERR(jadard->vccio), + "failed to get vccio regulator\n"); ret = of_drm_get_panel_orientation(dev->of_node, &jadard->orientation); if (ret < 0) diff --git a/drivers/gpu/drm/panel/panel-lg-ld070wx3.c b/drivers/gpu/drm/panel/panel-lg-ld070wx3.c new file mode 100644 index 000000000000..00cbfc5518a5 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-lg-ld070wx3.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <linux/array_size.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +static const struct regulator_bulk_data lg_ld070wx3_supplies[] = { + { .supply = "vdd" }, { .supply = "vcc" }, +}; + +struct lg_ld070wx3 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator_bulk_data *supplies; +}; + +static inline struct lg_ld070wx3 *to_lg_ld070wx3(struct drm_panel *panel) +{ + return container_of(panel, struct lg_ld070wx3, panel); +} + +static int lg_ld070wx3_prepare(struct drm_panel *panel) +{ + struct lg_ld070wx3 *priv = to_lg_ld070wx3(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + struct device *dev = panel->dev; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(lg_ld070wx3_supplies), priv->supplies); + if (ret < 0) { + dev_err(dev, "failed to enable power supplies: %d\n", ret); + return ret; + } + + /* + * According to spec delay between enabling supply is 0, + * for regulators to reach required voltage ~5ms needed. + * MIPI interface signal for setup requires additional + * 110ms which in total results in 115ms. + */ + mdelay(115); + + mipi_dsi_dcs_soft_reset_multi(&ctx); + mipi_dsi_msleep(&ctx, 20); + + /* Differential input impedance selection */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x0b); + + /* Enter test mode 1 and 2*/ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0xea); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x5f); + + /* Increased MIPI CLK driving ability */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x68); + + /* Exit test mode 1 and 2 */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0x00); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x00); + + return ctx.accum_err; +} + +static int lg_ld070wx3_unprepare(struct drm_panel *panel) +{ + struct lg_ld070wx3 *priv = to_lg_ld070wx3(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + + mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); + + msleep(50); + + regulator_bulk_disable(ARRAY_SIZE(lg_ld070wx3_supplies), priv->supplies); + + /* power supply must be off for at least 1s after panel disable */ + msleep(1000); + + return 0; +} + +static const struct drm_display_mode lg_ld070wx3_mode = { + .clock = (800 + 32 + 48 + 8) * (1280 + 5 + 3 + 1) * 60 / 1000, + .hdisplay = 800, + .hsync_start = 800 + 32, + .hsync_end = 800 + 32 + 48, + .htotal = 800 + 32 + 48 + 8, + .vdisplay = 1280, + .vsync_start = 1280 + 5, + .vsync_end = 1280 + 5 + 3, + .vtotal = 1280 + 5 + 3 + 1, + .width_mm = 94, + .height_mm = 151, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static int lg_ld070wx3_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &lg_ld070wx3_mode); +} + +static const struct drm_panel_funcs lg_ld070wx3_panel_funcs = { + .prepare = lg_ld070wx3_prepare, + .unprepare = lg_ld070wx3_unprepare, + .get_modes = lg_ld070wx3_get_modes, +}; + +static int lg_ld070wx3_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct lg_ld070wx3 *priv; + int ret; + + priv = devm_drm_panel_alloc(dev, struct lg_ld070wx3, panel, + &lg_ld070wx3_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(lg_ld070wx3_supplies), + lg_ld070wx3_supplies, &priv->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get supplies\n"); + + priv->dsi = dsi; + mipi_dsi_set_drvdata(dsi, priv); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + + ret = drm_panel_of_backlight(&priv->panel); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get backlight\n"); + + drm_panel_add(&priv->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&priv->panel); + return dev_err_probe(dev, ret, "failed to attach to DSI host\n"); + } + + return 0; +} + +static void lg_ld070wx3_remove(struct mipi_dsi_device *dsi) +{ + struct lg_ld070wx3 *priv = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&priv->panel); +} + +static const struct of_device_id lg_ld070wx3_of_match[] = { + { .compatible = "lg,ld070wx3-sl01" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lg_ld070wx3_of_match); + +static struct mipi_dsi_driver lg_ld070wx3_driver = { + .driver = { + .name = "panel-lg-ld070wx3", + .of_match_table = lg_ld070wx3_of_match, + }, + .probe = lg_ld070wx3_probe, + .remove = lg_ld070wx3_remove, +}; +module_mipi_dsi_driver(lg_ld070wx3_driver); + +MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); +MODULE_DESCRIPTION("LG LD070WX3-SL01 DSI panel driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index 0db9cadd868e..18130bc14201 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -43,59 +43,12 @@ struct nv3052c { struct gpio_desc *reset_gpio; }; -static const struct nv3052c_reg ltk035c5444t_panel_regs[] = { - // EXTC Command set enable, select page 1 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 }, - // Mostly unknown registers - { 0xe3, 0x00 }, - { 0x40, 0x00 }, - { 0x03, 0x40 }, - { 0x04, 0x00 }, - { 0x05, 0x03 }, - { 0x08, 0x00 }, - { 0x09, 0x07 }, - { 0x0a, 0x01 }, - { 0x0b, 0x32 }, - { 0x0c, 0x32 }, - { 0x0d, 0x0b }, - { 0x0e, 0x00 }, - { 0x23, 0xa0 }, - { 0x24, 0x0c }, - { 0x25, 0x06 }, - { 0x26, 0x14 }, - { 0x27, 0x14 }, - { 0x38, 0xcc }, // VCOM_ADJ1 - { 0x39, 0xd7 }, // VCOM_ADJ2 - { 0x3a, 0x4a }, // VCOM_ADJ3 - { 0x28, 0x40 }, - { 0x29, 0x01 }, - { 0x2a, 0xdf }, - { 0x49, 0x3c }, - { 0x91, 0x77 }, // EXTPW_CTRL2 - { 0x92, 0x77 }, // EXTPW_CTRL3 - { 0xa0, 0x55 }, - { 0xa1, 0x50 }, - { 0xa4, 0x9c }, - { 0xa7, 0x02 }, - { 0xa8, 0x01 }, - { 0xa9, 0x01 }, - { 0xaa, 0xfc }, - { 0xab, 0x28 }, - { 0xac, 0x06 }, - { 0xad, 0x06 }, - { 0xae, 0x06 }, - { 0xaf, 0x03 }, - { 0xb0, 0x08 }, - { 0xb1, 0x26 }, - { 0xb2, 0x28 }, - { 0xb3, 0x28 }, - { 0xb4, 0x33 }, - { 0xb5, 0x08 }, - { 0xb6, 0x26 }, - { 0xb7, 0x08 }, - { 0xb8, 0x26 }, - { 0xf0, 0x00 }, - { 0xf6, 0xc0 }, +/* + * Common initialization registers for all currently + * supported displays. Mostly seem to be related + * to Gamma correction curves and output pad mappings. + */ +static const struct nv3052c_reg common_init_regs[] = { // EXTC Command set enable, select page 2 { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, // Set gray scale voltage to adjust gamma @@ -215,7 +168,7 @@ static const struct nv3052c_reg ltk035c5444t_panel_regs[] = { { 0xa0, 0x01 }, // PANELU2D33 // EXTC Command set enable, select page 2 { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, - // Unknown registers + // Page 2 register values (0x01..0x10) are same for nv3051d and nv3052c { 0x01, 0x01 }, { 0x02, 0xda }, { 0x03, 0xba }, @@ -236,6 +189,62 @@ static const struct nv3052c_reg ltk035c5444t_panel_regs[] = { { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, // Display Access Control { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 + +}; + +static const struct nv3052c_reg ltk035c5444t_panel_regs[] = { + // EXTC Command set enable, select page 1 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 }, + // Mostly unknown registers + { 0xe3, 0x00 }, + { 0x40, 0x00 }, + { 0x03, 0x40 }, + { 0x04, 0x00 }, + { 0x05, 0x03 }, + { 0x08, 0x00 }, + { 0x09, 0x07 }, + { 0x0a, 0x01 }, + { 0x0b, 0x32 }, + { 0x0c, 0x32 }, + { 0x0d, 0x0b }, + { 0x0e, 0x00 }, + { 0x23, 0xa0 }, + { 0x24, 0x0c }, + { 0x25, 0x06 }, + { 0x26, 0x14 }, + { 0x27, 0x14 }, + { 0x38, 0xcc }, // VCOM_ADJ1 + { 0x39, 0xd7 }, // VCOM_ADJ2 + { 0x3a, 0x4a }, // VCOM_ADJ3 + { 0x28, 0x40 }, + { 0x29, 0x01 }, + { 0x2a, 0xdf }, + { 0x49, 0x3c }, + { 0x91, 0x77 }, // EXTPW_CTRL2 + { 0x92, 0x77 }, // EXTPW_CTRL3 + { 0xa0, 0x55 }, + { 0xa1, 0x50 }, + { 0xa4, 0x9c }, + { 0xa7, 0x02 }, + { 0xa8, 0x01 }, + { 0xa9, 0x01 }, + { 0xaa, 0xfc }, + { 0xab, 0x28 }, + { 0xac, 0x06 }, + { 0xad, 0x06 }, + { 0xae, 0x06 }, + { 0xaf, 0x03 }, + { 0xb0, 0x08 }, + { 0xb1, 0x26 }, + { 0xb2, 0x28 }, + { 0xb3, 0x28 }, + { 0xb4, 0x33 }, + { 0xb5, 0x08 }, + { 0xb6, 0x26 }, + { 0xb7, 0x08 }, + { 0xb8, 0x26 }, + { 0xf0, 0x00 }, + { 0xf6, 0xc0 }, }; static const struct nv3052c_reg fs035vg158_panel_regs[] = { @@ -291,146 +300,6 @@ static const struct nv3052c_reg fs035vg158_panel_regs[] = { { 0xb8, 0x26 }, { 0xf0, 0x00 }, { 0xf6, 0xc0 }, - // EXTC Command set enable, select page 0 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, - // Set gray scale voltage to adjust gamma - { 0xb0, 0x0b }, // PGAMVR0 - { 0xb1, 0x16 }, // PGAMVR1 - { 0xb2, 0x17 }, // PGAMVR2 - { 0xb3, 0x2c }, // PGAMVR3 - { 0xb4, 0x32 }, // PGAMVR4 - { 0xb5, 0x3b }, // PGAMVR5 - { 0xb6, 0x29 }, // PGAMPR0 - { 0xb7, 0x40 }, // PGAMPR1 - { 0xb8, 0x0d }, // PGAMPK0 - { 0xb9, 0x05 }, // PGAMPK1 - { 0xba, 0x12 }, // PGAMPK2 - { 0xbb, 0x10 }, // PGAMPK3 - { 0xbc, 0x12 }, // PGAMPK4 - { 0xbd, 0x15 }, // PGAMPK5 - { 0xbe, 0x19 }, // PGAMPK6 - { 0xbf, 0x0e }, // PGAMPK7 - { 0xc0, 0x16 }, // PGAMPK8 - { 0xc1, 0x0a }, // PGAMPK9 - // Set gray scale voltage to adjust gamma - { 0xd0, 0x0c }, // NGAMVR0 - { 0xd1, 0x17 }, // NGAMVR0 - { 0xd2, 0x14 }, // NGAMVR1 - { 0xd3, 0x2e }, // NGAMVR2 - { 0xd4, 0x32 }, // NGAMVR3 - { 0xd5, 0x3c }, // NGAMVR4 - { 0xd6, 0x22 }, // NGAMPR0 - { 0xd7, 0x3d }, // NGAMPR1 - { 0xd8, 0x0d }, // NGAMPK0 - { 0xd9, 0x07 }, // NGAMPK1 - { 0xda, 0x13 }, // NGAMPK2 - { 0xdb, 0x13 }, // NGAMPK3 - { 0xdc, 0x11 }, // NGAMPK4 - { 0xdd, 0x15 }, // NGAMPK5 - { 0xde, 0x19 }, // NGAMPK6 - { 0xdf, 0x10 }, // NGAMPK7 - { 0xe0, 0x17 }, // NGAMPK8 - { 0xe1, 0x0a }, // NGAMPK9 - // EXTC Command set enable, select page 3 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 }, - // Set various timing settings - { 0x00, 0x2a }, // GIP_VST_1 - { 0x01, 0x2a }, // GIP_VST_2 - { 0x02, 0x2a }, // GIP_VST_3 - { 0x03, 0x2a }, // GIP_VST_4 - { 0x04, 0x61 }, // GIP_VST_5 - { 0x05, 0x80 }, // GIP_VST_6 - { 0x06, 0xc7 }, // GIP_VST_7 - { 0x07, 0x01 }, // GIP_VST_8 - { 0x08, 0x03 }, // GIP_VST_9 - { 0x09, 0x04 }, // GIP_VST_10 - { 0x70, 0x22 }, // GIP_ECLK1 - { 0x71, 0x80 }, // GIP_ECLK2 - { 0x30, 0x2a }, // GIP_CLK_1 - { 0x31, 0x2a }, // GIP_CLK_2 - { 0x32, 0x2a }, // GIP_CLK_3 - { 0x33, 0x2a }, // GIP_CLK_4 - { 0x34, 0x61 }, // GIP_CLK_5 - { 0x35, 0xc5 }, // GIP_CLK_6 - { 0x36, 0x80 }, // GIP_CLK_7 - { 0x37, 0x23 }, // GIP_CLK_8 - { 0x40, 0x03 }, // GIP_CLKA_1 - { 0x41, 0x04 }, // GIP_CLKA_2 - { 0x42, 0x05 }, // GIP_CLKA_3 - { 0x43, 0x06 }, // GIP_CLKA_4 - { 0x44, 0x11 }, // GIP_CLKA_5 - { 0x45, 0xe8 }, // GIP_CLKA_6 - { 0x46, 0xe9 }, // GIP_CLKA_7 - { 0x47, 0x11 }, // GIP_CLKA_8 - { 0x48, 0xea }, // GIP_CLKA_9 - { 0x49, 0xeb }, // GIP_CLKA_10 - { 0x50, 0x07 }, // GIP_CLKB_1 - { 0x51, 0x08 }, // GIP_CLKB_2 - { 0x52, 0x09 }, // GIP_CLKB_3 - { 0x53, 0x0a }, // GIP_CLKB_4 - { 0x54, 0x11 }, // GIP_CLKB_5 - { 0x55, 0xec }, // GIP_CLKB_6 - { 0x56, 0xed }, // GIP_CLKB_7 - { 0x57, 0x11 }, // GIP_CLKB_8 - { 0x58, 0xef }, // GIP_CLKB_9 - { 0x59, 0xf0 }, // GIP_CLKB_10 - // Map internal GOA signals to GOA output pad - { 0xb1, 0x01 }, // PANELD2U2 - { 0xb4, 0x15 }, // PANELD2U5 - { 0xb5, 0x16 }, // PANELD2U6 - { 0xb6, 0x09 }, // PANELD2U7 - { 0xb7, 0x0f }, // PANELD2U8 - { 0xb8, 0x0d }, // PANELD2U9 - { 0xb9, 0x0b }, // PANELD2U10 - { 0xba, 0x00 }, // PANELD2U11 - { 0xc7, 0x02 }, // PANELD2U24 - { 0xca, 0x17 }, // PANELD2U27 - { 0xcb, 0x18 }, // PANELD2U28 - { 0xcc, 0x0a }, // PANELD2U29 - { 0xcd, 0x10 }, // PANELD2U30 - { 0xce, 0x0e }, // PANELD2U31 - { 0xcf, 0x0c }, // PANELD2U32 - { 0xd0, 0x00 }, // PANELD2U33 - // Map internal GOA signals to GOA output pad - { 0x81, 0x00 }, // PANELU2D2 - { 0x84, 0x15 }, // PANELU2D5 - { 0x85, 0x16 }, // PANELU2D6 - { 0x86, 0x10 }, // PANELU2D7 - { 0x87, 0x0a }, // PANELU2D8 - { 0x88, 0x0c }, // PANELU2D9 - { 0x89, 0x0e }, // PANELU2D10 - { 0x8a, 0x02 }, // PANELU2D11 - { 0x97, 0x00 }, // PANELU2D24 - { 0x9a, 0x17 }, // PANELU2D27 - { 0x9b, 0x18 }, // PANELU2D28 - { 0x9c, 0x0f }, // PANELU2D29 - { 0x9d, 0x09 }, // PANELU2D30 - { 0x9e, 0x0b }, // PANELU2D31 - { 0x9f, 0x0d }, // PANELU2D32 - { 0xa0, 0x01 }, // PANELU2D33 - // EXTC Command set enable, select page 2 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, - // Unknown registers - { 0x01, 0x01 }, - { 0x02, 0xda }, - { 0x03, 0xba }, - { 0x04, 0xa8 }, - { 0x05, 0x9a }, - { 0x06, 0x70 }, - { 0x07, 0xff }, - { 0x08, 0x91 }, - { 0x09, 0x90 }, - { 0x0a, 0xff }, - { 0x0b, 0x8f }, - { 0x0c, 0x60 }, - { 0x0d, 0x58 }, - { 0x0e, 0x48 }, - { 0x0f, 0x38 }, - { 0x10, 0x2b }, - // EXTC Command set enable, select page 0 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, - // Display Access Control - { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 }; @@ -487,146 +356,6 @@ static const struct nv3052c_reg wl_355608_a8_panel_regs[] = { { 0xb8, 0x26 }, { 0xf0, 0x00 }, { 0xf6, 0xc0 }, - // EXTC Command set enable, select page 2 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, - // Set gray scale voltage to adjust gamma - { 0xb0, 0x0b }, // PGAMVR0 - { 0xb1, 0x16 }, // PGAMVR1 - { 0xb2, 0x17 }, // PGAMVR2 - { 0xb3, 0x2c }, // PGAMVR3 - { 0xb4, 0x32 }, // PGAMVR4 - { 0xb5, 0x3b }, // PGAMVR5 - { 0xb6, 0x29 }, // PGAMPR0 - { 0xb7, 0x40 }, // PGAMPR1 - { 0xb8, 0x0d }, // PGAMPK0 - { 0xb9, 0x05 }, // PGAMPK1 - { 0xba, 0x12 }, // PGAMPK2 - { 0xbb, 0x10 }, // PGAMPK3 - { 0xbc, 0x12 }, // PGAMPK4 - { 0xbd, 0x15 }, // PGAMPK5 - { 0xbe, 0x19 }, // PGAMPK6 - { 0xbf, 0x0e }, // PGAMPK7 - { 0xc0, 0x16 }, // PGAMPK8 - { 0xc1, 0x0a }, // PGAMPK9 - // Set gray scale voltage to adjust gamma - { 0xd0, 0x0c }, // NGAMVR0 - { 0xd1, 0x17 }, // NGAMVR0 - { 0xd2, 0x14 }, // NGAMVR1 - { 0xd3, 0x2e }, // NGAMVR2 - { 0xd4, 0x32 }, // NGAMVR3 - { 0xd5, 0x3c }, // NGAMVR4 - { 0xd6, 0x22 }, // NGAMPR0 - { 0xd7, 0x3d }, // NGAMPR1 - { 0xd8, 0x0d }, // NGAMPK0 - { 0xd9, 0x07 }, // NGAMPK1 - { 0xda, 0x13 }, // NGAMPK2 - { 0xdb, 0x13 }, // NGAMPK3 - { 0xdc, 0x11 }, // NGAMPK4 - { 0xdd, 0x15 }, // NGAMPK5 - { 0xde, 0x19 }, // NGAMPK6 - { 0xdf, 0x10 }, // NGAMPK7 - { 0xe0, 0x17 }, // NGAMPK8 - { 0xe1, 0x0a }, // NGAMPK9 - // EXTC Command set enable, select page 3 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 }, - // Set various timing settings - { 0x00, 0x2a }, // GIP_VST_1 - { 0x01, 0x2a }, // GIP_VST_2 - { 0x02, 0x2a }, // GIP_VST_3 - { 0x03, 0x2a }, // GIP_VST_4 - { 0x04, 0x61 }, // GIP_VST_5 - { 0x05, 0x80 }, // GIP_VST_6 - { 0x06, 0xc7 }, // GIP_VST_7 - { 0x07, 0x01 }, // GIP_VST_8 - { 0x08, 0x03 }, // GIP_VST_9 - { 0x09, 0x04 }, // GIP_VST_10 - { 0x70, 0x22 }, // GIP_ECLK1 - { 0x71, 0x80 }, // GIP_ECLK2 - { 0x30, 0x2a }, // GIP_CLK_1 - { 0x31, 0x2a }, // GIP_CLK_2 - { 0x32, 0x2a }, // GIP_CLK_3 - { 0x33, 0x2a }, // GIP_CLK_4 - { 0x34, 0x61 }, // GIP_CLK_5 - { 0x35, 0xc5 }, // GIP_CLK_6 - { 0x36, 0x80 }, // GIP_CLK_7 - { 0x37, 0x23 }, // GIP_CLK_8 - { 0x40, 0x03 }, // GIP_CLKA_1 - { 0x41, 0x04 }, // GIP_CLKA_2 - { 0x42, 0x05 }, // GIP_CLKA_3 - { 0x43, 0x06 }, // GIP_CLKA_4 - { 0x44, 0x11 }, // GIP_CLKA_5 - { 0x45, 0xe8 }, // GIP_CLKA_6 - { 0x46, 0xe9 }, // GIP_CLKA_7 - { 0x47, 0x11 }, // GIP_CLKA_8 - { 0x48, 0xea }, // GIP_CLKA_9 - { 0x49, 0xeb }, // GIP_CLKA_10 - { 0x50, 0x07 }, // GIP_CLKB_1 - { 0x51, 0x08 }, // GIP_CLKB_2 - { 0x52, 0x09 }, // GIP_CLKB_3 - { 0x53, 0x0a }, // GIP_CLKB_4 - { 0x54, 0x11 }, // GIP_CLKB_5 - { 0x55, 0xec }, // GIP_CLKB_6 - { 0x56, 0xed }, // GIP_CLKB_7 - { 0x57, 0x11 }, // GIP_CLKB_8 - { 0x58, 0xef }, // GIP_CLKB_9 - { 0x59, 0xf0 }, // GIP_CLKB_10 - // Map internal GOA signals to GOA output pad - { 0xb1, 0x01 }, // PANELD2U2 - { 0xb4, 0x15 }, // PANELD2U5 - { 0xb5, 0x16 }, // PANELD2U6 - { 0xb6, 0x09 }, // PANELD2U7 - { 0xb7, 0x0f }, // PANELD2U8 - { 0xb8, 0x0d }, // PANELD2U9 - { 0xb9, 0x0b }, // PANELD2U10 - { 0xba, 0x00 }, // PANELD2U11 - { 0xc7, 0x02 }, // PANELD2U24 - { 0xca, 0x17 }, // PANELD2U27 - { 0xcb, 0x18 }, // PANELD2U28 - { 0xcc, 0x0a }, // PANELD2U29 - { 0xcd, 0x10 }, // PANELD2U30 - { 0xce, 0x0e }, // PANELD2U31 - { 0xcf, 0x0c }, // PANELD2U32 - { 0xd0, 0x00 }, // PANELD2U33 - // Map internal GOA signals to GOA output pad - { 0x81, 0x00 }, // PANELU2D2 - { 0x84, 0x15 }, // PANELU2D5 - { 0x85, 0x16 }, // PANELU2D6 - { 0x86, 0x10 }, // PANELU2D7 - { 0x87, 0x0a }, // PANELU2D8 - { 0x88, 0x0c }, // PANELU2D9 - { 0x89, 0x0e }, // PANELU2D10 - { 0x8a, 0x02 }, // PANELU2D11 - { 0x97, 0x00 }, // PANELU2D24 - { 0x9a, 0x17 }, // PANELU2D27 - { 0x9b, 0x18 }, // PANELU2D28 - { 0x9c, 0x0f }, // PANELU2D29 - { 0x9d, 0x09 }, // PANELU2D30 - { 0x9e, 0x0b }, // PANELU2D31 - { 0x9f, 0x0d }, // PANELU2D32 - { 0xa0, 0x01 }, // PANELU2D33 - // EXTC Command set enable, select page 2 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, - // Unknown registers - { 0x01, 0x01 }, - { 0x02, 0xda }, - { 0x03, 0xba }, - { 0x04, 0xa8 }, - { 0x05, 0x9a }, - { 0x06, 0x70 }, - { 0x07, 0xff }, - { 0x08, 0x91 }, - { 0x09, 0x90 }, - { 0x0a, 0xff }, - { 0x0b, 0x8f }, - { 0x0c, 0x60 }, - { 0x0d, 0x58 }, - { 0x0e, 0x48 }, - { 0x0f, 0x38 }, - { 0x10, 0x2b }, - // EXTC Command set enable, select page 0 - { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, - // Display Access Control - { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 }; static inline struct nv3052c *to_nv3052c(struct drm_panel *panel) @@ -655,6 +384,7 @@ static int nv3052c_prepare(struct drm_panel *panel) gpiod_set_value_cansleep(priv->reset_gpio, 0); usleep_range(5000, 20000); + /* Apply panel-specific initialization registers */ for (i = 0; i < panel_regs_len; i++) { err = mipi_dbi_command(dbi, panel_regs[i].cmd, panel_regs[i].val); @@ -665,6 +395,16 @@ static int nv3052c_prepare(struct drm_panel *panel) } } + /* Apply common initialization registers */ + for (i = 0; i < ARRAY_SIZE(common_init_regs); i++) { + err = mipi_dbi_command(dbi, common_init_regs[i].cmd, + common_init_regs[i].val); + if (err) { + dev_err(priv->dev, "Unable to set register: %d\n", err); + goto err_disable_regulator; + } + } + err = mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); if (err) { dev_err(priv->dev, "Unable to exit sleep mode: %d\n", err); diff --git a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c index ad35d0fb0a16..c3fbc459c7e0 100644 --- a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c +++ b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c @@ -54,9 +54,9 @@ static int rb070d30_panel_prepare(struct drm_panel *panel) } msleep(20); - gpiod_set_value(ctx->gpios.power, 1); + gpiod_set_value_cansleep(ctx->gpios.power, 1); msleep(20); - gpiod_set_value(ctx->gpios.reset, 1); + gpiod_set_value_cansleep(ctx->gpios.reset, 1); msleep(20); return 0; } @@ -65,8 +65,8 @@ static int rb070d30_panel_unprepare(struct drm_panel *panel) { struct rb070d30_panel *ctx = panel_to_rb070d30_panel(panel); - gpiod_set_value(ctx->gpios.reset, 0); - gpiod_set_value(ctx->gpios.power, 0); + gpiod_set_value_cansleep(ctx->gpios.reset, 0); + gpiod_set_value_cansleep(ctx->gpios.power, 0); regulator_disable(ctx->supply); return 0; diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fc2x01.c b/drivers/gpu/drm/panel/panel-samsung-s6e3fc2x01.c new file mode 100644 index 000000000000..e63080204af7 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fc2x01.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Nia Espera <a5b6@riseup.net> + * Copyright (c) 2025 David Heidelberg <david@ixit.cz> + */ + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/regulator/consumer.h> +#include <linux/swab.h> +#include <linux/backlight.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +#define MCS_ELVSS_ON 0xb1 + +struct samsung_s6e3fc2x01 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; +}; + +static const struct regulator_bulk_data s6e3fc2x01_supplies[] = { + { .supply = "vddio" }, + { .supply = "vci" }, + { .supply = "poc" }, +}; + +static inline +struct samsung_s6e3fc2x01 *to_samsung_s6e3fc2x01(struct drm_panel *panel) +{ + return container_of(panel, struct samsung_s6e3fc2x01, panel); +} + +#define s6e3fc2x01_test_key_on_lvl1(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0xa5, 0xa5) +#define s6e3fc2x01_test_key_off_lvl1(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0x5a, 0x5a) +#define s6e3fc2x01_test_key_on_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a) +#define s6e3fc2x01_test_key_off_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5) +#define s6e3fc2x01_test_key_on_lvl3(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0x5a, 0x5a) +#define s6e3fc2x01_test_key_off_lvl3(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0xa5, 0xa5) + +static void s6e3fc2x01_reset(struct samsung_s6e3fc2x01 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(5000, 6000); +} + +static int s6e3fc2x01_on(struct samsung_s6e3fc2x01 *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + s6e3fc2x01_test_key_on_lvl1(&dsi_ctx); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0x0a); + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + s6e3fc2x01_test_key_off_lvl1(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xcd, 0x01); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + mipi_dsi_usleep_range(&dsi_ctx, 15000, 16000); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0x0f); + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + s6e3fc2x01_test_key_on_lvl1(&dsi_ctx); + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + s6e3fc2x01_test_key_off_lvl1(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xeb, 0x17, + 0x41, 0x92, + 0x0e, 0x10, + 0x82, 0x5a); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + /* Column & Page Address Setting */ + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x0437); + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0923); + + /* Horizontal & Vertical sync Setting */ + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x09); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe8, 0x10, 0x30); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl3(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe3, 0x88); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x07); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xed, 0x67); + s6e3fc2x01_test_key_off_lvl3(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x07); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb7, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb7, 0x12); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ELVSS_ON, 0x00, 0x01); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb3, 0x00, 0xc1); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0x78); + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x90); + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ELVSS_ON, 0xc6, 0x00, 0x00, + 0x21, 0xed, 0x02, 0x08, 0x06, 0xc1, 0x27, + 0xfc, 0xdc, 0xe4, 0x00, 0xd9, 0xe6, 0xe7, + 0x00, 0xfc, 0xff, 0xea); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ELVSS_ON, 0x00, 0x00); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + return dsi_ctx.accum_err; +} + +static int s6e3fc2x01_enable(struct drm_panel *panel) +{ + struct samsung_s6e3fc2x01 *ctx = to_samsung_s6e3fc2x01(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + s6e3fc2x01_test_key_on_lvl1(&dsi_ctx); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + s6e3fc2x01_test_key_off_lvl1(&dsi_ctx); + + return dsi_ctx.accum_err; +} + +static int s6e3fc2x01_off(struct samsung_s6e3fc2x01 *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + s6e3fc2x01_test_key_on_lvl1(&dsi_ctx); + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + + mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_usleep_range(&dsi_ctx, 16000, 17000); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x50); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb9, 0x82); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + mipi_dsi_usleep_range(&dsi_ctx, 16000, 17000); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + + s6e3fc2x01_test_key_off_lvl1(&dsi_ctx); + + s6e3fc2x01_test_key_on_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x01); + s6e3fc2x01_test_key_off_lvl2(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 160); + + return dsi_ctx.accum_err; +} + +static int s6e3fc2x01_disable(struct drm_panel *panel) +{ + struct samsung_s6e3fc2x01 *ctx = to_samsung_s6e3fc2x01(panel); + + s6e3fc2x01_off(ctx); + + return 0; +} + +static int s6e3fc2x01_prepare(struct drm_panel *panel) +{ + struct samsung_s6e3fc2x01 *ctx = to_samsung_s6e3fc2x01(panel); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(s6e3fc2x01_supplies), ctx->supplies); + if (ret < 0) + return ret; + + s6e3fc2x01_reset(ctx); + + ret = s6e3fc2x01_on(ctx); + if (ret < 0) { + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(s6e3fc2x01_supplies), ctx->supplies); + return ret; + } + + return 0; +} + +static int s6e3fc2x01_unprepare(struct drm_panel *panel) +{ + struct samsung_s6e3fc2x01 *ctx = to_samsung_s6e3fc2x01(panel); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(s6e3fc2x01_supplies), ctx->supplies); + + return 0; +} + +static const struct drm_display_mode ams641rw_mode = { + .clock = (1080 + 72 + 16 + 36) * (2340 + 32 + 4 + 18) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 72, + .hsync_end = 1080 + 72 + 16, + .htotal = 1080 + 72 + 16 + 36, + .vdisplay = 2340, + .vsync_start = 2340 + 32, + .vsync_end = 2340 + 32 + 4, + .vtotal = 2340 + 32 + 4 + 18, + .width_mm = 68, + .height_mm = 145, +}; + +static int s6e3fc2x01_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &ams641rw_mode); +} + +static const struct drm_panel_funcs samsung_s6e3fc2x01_panel_funcs = { + .prepare = s6e3fc2x01_prepare, + .enable = s6e3fc2x01_enable, + .disable = s6e3fc2x01_disable, + .unprepare = s6e3fc2x01_unprepare, + .get_modes = s6e3fc2x01_get_modes, +}; + +static int s6e3fc2x01_panel_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int err; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + err = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (err < 0) + return err; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops s6e3fc2x01_panel_bl_ops = { + .update_status = s6e3fc2x01_panel_bl_update_status, +}; + +static struct backlight_device * +s6e3fc2x01_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_PLATFORM, + .brightness = 512, + .max_brightness = 1023, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &s6e3fc2x01_panel_bl_ops, &props); +} + +static int s6e3fc2x01_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct samsung_s6e3fc2x01 *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct samsung_s6e3fc2x01, panel, + &samsung_s6e3fc2x01_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = devm_regulator_bulk_get_const(dev, + ARRAY_SIZE(s6e3fc2x01_supplies), + s6e3fc2x01_supplies, + &ctx->supplies); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + + /* keep the display on for flicker-free experience */ + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = s6e3fc2x01_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); + return ret; + } + + return 0; +} + +static void s6e3fc2x01_remove(struct mipi_dsi_device *dsi) +{ + struct samsung_s6e3fc2x01 *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id s6e3fc2x01_of_match[] = { + { .compatible = "samsung,s6e3fc2x01-ams641rw", .data = &ams641rw_mode }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, s6e3fc2x01_of_match); + +static struct mipi_dsi_driver s6e3fc2x01_driver = { + .probe = s6e3fc2x01_probe, + .remove = s6e3fc2x01_remove, + .driver = { + .name = "panel-samsung-s6e3fc2x01", + .of_match_table = s6e3fc2x01_of_match, + }, +}; +module_mipi_dsi_driver(s6e3fc2x01_driver); + +MODULE_AUTHOR("David Heidelberg <david@ixit.cz>"); +MODULE_DESCRIPTION("DRM driver for Samsung S6E3FC2X01 DDIC"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c index 064258217d50..e00a497a7c96 100644 --- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c +++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c @@ -16,20 +16,32 @@ #include <drm/drm_mipi_dsi.h> #include <drm/drm_modes.h> #include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> struct sofef00_panel { struct drm_panel panel; struct mipi_dsi_device *dsi; - struct regulator *supply; + struct regulator_bulk_data *supplies; struct gpio_desc *reset_gpio; }; +static const struct regulator_bulk_data sofef00_supplies[] = { + { .supply = "vddio" }, + { .supply = "vci" }, + { .supply = "poc" }, +}; + static inline struct sofef00_panel *to_sofef00_panel(struct drm_panel *panel) { return container_of(panel, struct sofef00_panel, panel); } +#define sofef00_test_key_on_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a) +#define sofef00_test_key_off_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5) + static void sofef00_panel_reset(struct sofef00_panel *ctx) { gpiod_set_value_cansleep(ctx->reset_gpio, 0); @@ -50,18 +62,26 @@ static int sofef00_panel_on(struct sofef00_panel *ctx) mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000); - mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a); - + sofef00_test_key_on_lvl2(&dsi_ctx); mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + sofef00_test_key_off_lvl2(&dsi_ctx); - mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5); - mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a); + sofef00_test_key_on_lvl2(&dsi_ctx); mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x07); mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb6, 0x12); - mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5); + sofef00_test_key_off_lvl2(&dsi_ctx); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + return dsi_ctx.accum_err; +} + +static int sofef00_enable(struct drm_panel *panel) +{ + struct sofef00_panel *ctx = to_sofef00_panel(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); return dsi_ctx.accum_err; @@ -72,8 +92,6 @@ static int sofef00_panel_off(struct sofef00_panel *ctx) struct mipi_dsi_device *dsi = ctx->dsi; struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; - mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); mipi_dsi_msleep(&dsi_ctx, 40); @@ -86,70 +104,70 @@ static int sofef00_panel_off(struct sofef00_panel *ctx) static int sofef00_panel_prepare(struct drm_panel *panel) { struct sofef00_panel *ctx = to_sofef00_panel(panel); - struct device *dev = &ctx->dsi->dev; int ret; - ret = regulator_enable(ctx->supply); - if (ret < 0) { - dev_err(dev, "Failed to enable regulator: %d\n", ret); + ret = regulator_bulk_enable(ARRAY_SIZE(sofef00_supplies), ctx->supplies); + if (ret < 0) return ret; - } sofef00_panel_reset(ctx); ret = sofef00_panel_on(ctx); if (ret < 0) { gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(sofef00_supplies), ctx->supplies); return ret; } return 0; } -static int sofef00_panel_unprepare(struct drm_panel *panel) +static int sofef00_disable(struct drm_panel *panel) { struct sofef00_panel *ctx = to_sofef00_panel(panel); sofef00_panel_off(ctx); - regulator_disable(ctx->supply); return 0; } -static const struct drm_display_mode enchilada_panel_mode = { +static int sofef00_panel_unprepare(struct drm_panel *panel) +{ + struct sofef00_panel *ctx = to_sofef00_panel(panel); + + regulator_bulk_disable(ARRAY_SIZE(sofef00_supplies), ctx->supplies); + + return 0; +} + +static const struct drm_display_mode ams628nw01_panel_mode = { .clock = (1080 + 112 + 16 + 36) * (2280 + 36 + 8 + 12) * 60 / 1000, + .hdisplay = 1080, .hsync_start = 1080 + 112, .hsync_end = 1080 + 112 + 16, .htotal = 1080 + 112 + 16 + 36, + .vdisplay = 2280, .vsync_start = 2280 + 36, .vsync_end = 2280 + 36 + 8, .vtotal = 2280 + 36 + 8 + 12, + .width_mm = 68, .height_mm = 145, + + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, }; static int sofef00_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(connector->dev, &enchilada_panel_mode); - if (!mode) - return -ENOMEM; - - drm_mode_set_name(mode); - - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - drm_mode_probed_add(connector, mode); - - return 1; + return drm_connector_helper_get_modes_fixed(connector, &ams628nw01_panel_mode); } static const struct drm_panel_funcs sofef00_panel_panel_funcs = { .prepare = sofef00_panel_prepare, + .enable = sofef00_enable, + .disable = sofef00_disable, .unprepare = sofef00_panel_unprepare, .get_modes = sofef00_panel_get_modes, }; @@ -160,10 +178,14 @@ static int sofef00_panel_bl_update_status(struct backlight_device *bl) int err; u16 brightness = (u16)backlight_get_brightness(bl); + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + err = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); if (err < 0) return err; + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + return 0; } @@ -177,7 +199,7 @@ sofef00_create_backlight(struct mipi_dsi_device *dsi) struct device *dev = &dsi->dev; const struct backlight_properties props = { .type = BACKLIGHT_PLATFORM, - .brightness = 1023, + .brightness = 512, .max_brightness = 1023, }; @@ -197,10 +219,12 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) if (IS_ERR(ctx)) return PTR_ERR(ctx); - ctx->supply = devm_regulator_get(dev, "vddio"); - if (IS_ERR(ctx->supply)) - return dev_err_probe(dev, PTR_ERR(ctx->supply), - "Failed to get vddio regulator\n"); + ret = devm_regulator_bulk_get_const(dev, + ARRAY_SIZE(sofef00_supplies), + sofef00_supplies, + &ctx->supplies); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ctx->reset_gpio)) @@ -212,6 +236,10 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + ctx->panel.prepare_prev_first = true; ctx->panel.backlight = sofef00_create_backlight(dsi); if (IS_ERR(ctx->panel.backlight)) @@ -243,7 +271,8 @@ static void sofef00_panel_remove(struct mipi_dsi_device *dsi) } static const struct of_device_id sofef00_panel_of_match[] = { - { .compatible = "samsung,sofef00" }, + { .compatible = "samsung,sofef00" }, /* legacy */ + { .compatible = "samsung,sofef00-ams628nw01" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sofef00_panel_of_match); @@ -252,7 +281,7 @@ static struct mipi_dsi_driver sofef00_panel_driver = { .probe = sofef00_panel_probe, .remove = sofef00_panel_remove, .driver = { - .name = "panel-oneplus6", + .name = "panel-samsung-sofef00", .of_match_table = sofef00_panel_of_match, }, }; @@ -260,5 +289,5 @@ static struct mipi_dsi_driver sofef00_panel_driver = { module_mipi_dsi_driver(sofef00_panel_driver); MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>"); -MODULE_DESCRIPTION("DRM driver for Samsung AMOLED DSI panels found in OnePlus 6/6T phones"); +MODULE_DESCRIPTION("DRM driver for Samsung SOFEF00 DDIC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c new file mode 100644 index 000000000000..8c00fde1c4a9 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016 XiaoMi, Inc. + * Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_connector.h> +#include <drm/drm_crtc.h> +#include <drm/drm_device.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +static const struct regulator_bulk_data sharp_supplies[] = { + { .supply = "avdd" }, { .supply = "vddio" }, + { .supply = "vsp" }, { .supply = "vsn" }, +}; + +struct sharp_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi[2]; + + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; + + const struct drm_display_mode *mode; +}; + +static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel) +{ + return container_of(panel, struct sharp_panel, panel); +} + +static void sharp_panel_reset(struct sharp_panel *sharp) +{ + gpiod_set_value_cansleep(sharp->reset_gpio, 1); + usleep_range(2000, 3000); + gpiod_set_value_cansleep(sharp->reset_gpio, 0); + usleep_range(2000, 3000); +} + +static int sharp_panel_prepare(struct drm_panel *panel) +{ + struct sharp_panel *sharp = to_sharp_panel(panel); + struct device *dev = panel->dev; + struct mipi_dsi_device *dsi0 = sharp->dsi[0]; + struct mipi_dsi_device *dsi1 = sharp->dsi[1]; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL }; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(sharp_supplies), sharp->supplies); + if (ret) { + dev_err(dev, "error enabling regulators (%d)\n", ret); + return ret; + } + + msleep(24); + + if (sharp->reset_gpio) + sharp_panel_reset(sharp); + + msleep(32); + + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_EXIT_SLEEP_MODE); + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, + MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff); + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, + MIPI_DCS_WRITE_POWER_SAVE, 0x01); + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, + MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c); + + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_ON); + + return 0; +} + +static int sharp_panel_unprepare(struct drm_panel *panel) +{ + struct sharp_panel *sharp = to_sharp_panel(panel); + struct mipi_dsi_device *dsi0 = sharp->dsi[0]; + struct mipi_dsi_device *dsi1 = sharp->dsi[1]; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL }; + + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_OFF); + mipi_dsi_msleep(&dsi_ctx, 100); + mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_ENTER_SLEEP_MODE); + mipi_dsi_msleep(&dsi_ctx, 150); + + if (sharp->reset_gpio) + gpiod_set_value_cansleep(sharp->reset_gpio, 1); + + return regulator_bulk_disable(ARRAY_SIZE(sharp_supplies), sharp->supplies); +} + +static const struct drm_display_mode default_mode = { + .clock = (1536 + 136 + 28 + 28) * (2048 + 14 + 8 + 2) * 60 / 1000, + .hdisplay = 1536, + .hsync_start = 1536 + 136, + .hsync_end = 1536 + 136 + 28, + .htotal = 1536 + 136 + 28 + 28, + .vdisplay = 2048, + .vsync_start = 2048 + 14, + .vsync_end = 2048 + 14 + 8, + .vtotal = 2048 + 14 + 8 + 2, + .width_mm = 120, + .height_mm = 160, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static int sharp_panel_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &default_mode); +} + +static const struct drm_panel_funcs sharp_panel_funcs = { + .unprepare = sharp_panel_unprepare, + .prepare = sharp_panel_prepare, + .get_modes = sharp_panel_get_modes, +}; + +static int sharp_panel_probe(struct mipi_dsi_device *dsi) +{ + const struct mipi_dsi_device_info info = { "sharp-link1", 0, NULL }; + struct device *dev = &dsi->dev; + struct device_node *dsi_r; + struct mipi_dsi_host *dsi_r_host; + struct sharp_panel *sharp; + int i, ret; + + sharp = devm_drm_panel_alloc(dev, struct sharp_panel, panel, + &sharp_panel_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(sharp)) + return PTR_ERR(sharp); + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(sharp_supplies), + sharp_supplies, &sharp->supplies); + if (ret) + return dev_err_probe(dev, ret, "failed to get supplies\n"); + + sharp->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(sharp->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(sharp->reset_gpio), + "failed to get reset GPIO\n"); + + /* Panel is always connected to two DSI hosts, DSI0 is left, DSI1 is right */ + dsi_r = of_graph_get_remote_node(dsi->dev.of_node, 1, -1); + if (!dsi_r) + return dev_err_probe(dev, -ENODEV, "failed to find second DSI host node\n"); + + dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r); + of_node_put(dsi_r); + if (!dsi_r_host) + return dev_err_probe(dev, -EPROBE_DEFER, "cannot get secondary DSI host\n"); + + sharp->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi_r_host, &info); + if (IS_ERR(sharp->dsi[1])) + return dev_err_probe(dev, PTR_ERR(sharp->dsi[1]), + "second link registration failed\n"); + + sharp->dsi[0] = dsi; + mipi_dsi_set_drvdata(dsi, sharp); + + ret = drm_panel_of_backlight(&sharp->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + drm_panel_add(&sharp->panel); + + for (i = 0; i < ARRAY_SIZE(sharp->dsi); i++) { + if (!sharp->dsi[i]) + continue; + + sharp->dsi[i]->lanes = 4; + sharp->dsi[i]->format = MIPI_DSI_FMT_RGB888; + sharp->dsi[i]->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + + ret = devm_mipi_dsi_attach(dev, sharp->dsi[i]); + if (ret < 0) { + drm_panel_remove(&sharp->panel); + return dev_err_probe(dev, ret, "failed to attach to DSI%d\n", i); + } + } + + return 0; +} + +static void sharp_panel_remove(struct mipi_dsi_device *dsi) +{ + struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&sharp->panel); +} + +static const struct of_device_id sharp_of_match[] = { + { .compatible = "sharp,lq079l1sx01" }, + { } +}; +MODULE_DEVICE_TABLE(of, sharp_of_match); + +static struct mipi_dsi_driver sharp_panel_driver = { + .driver = { + .name = "panel-sharp-lq079l1sx01", + .of_match_table = sharp_of_match, + }, + .probe = sharp_panel_probe, + .remove = sharp_panel_remove, +}; +module_mipi_dsi_driver(sharp_panel_driver); + +MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); +MODULE_DESCRIPTION("Sharp LQ079L1SX01 panel driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 0019de93be1b..b26b682826bc 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2889,6 +2889,38 @@ static const struct panel_desc innolux_zj070na_01p = { }, }; +static const struct display_timing jutouch_jt101tm023_timing = { + .pixelclock = { 66300000, 72400000, 78900000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 12, 72, 132 }, + .hback_porch = { 88, 88, 88 }, + .hsync_len = { 10, 10, 48 }, + .vactive = { 800, 800, 800 }, + .vfront_porch = { 1, 15, 49 }, + .vback_porch = { 23, 23, 23 }, + .vsync_len = { 5, 6, 13 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH, +}; + +static const struct panel_desc jutouch_jt101tm023 = { + .timings = &jutouch_jt101tm023_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 217, + .height = 136, + }, + .delay = { + .enable = 50, + .disable = 50, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + + static const struct display_timing koe_tx14d24vm1bpa_timing = { .pixelclock = { 5580000, 5850000, 6200000 }, .hactive = { 320, 320, 320 }, @@ -4074,6 +4106,30 @@ static const struct panel_desc qishenglong_gopher2b_lcd = { .connector_type = DRM_MODE_CONNECTOR_DPI, }; +static const struct display_timing raystar_rff500f_awh_dnn_timing = { + .pixelclock = { 23000000, 25000000, 27000000 }, + .hactive = { 800, 800, 800 }, + .hback_porch = { 4, 8, 48 }, + .hfront_porch = { 4, 8, 48 }, + .hsync_len = { 2, 4, 8 }, + .vactive = { 480, 480, 480 }, + .vback_porch = { 4, 8, 12 }, + .vfront_porch = { 4, 8, 12 }, + .vsync_len = { 2, 4, 8 }, +}; + +static const struct panel_desc raystar_rff500f_awh_dnn = { + .timings = &raystar_rff500f_awh_dnn_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 108, + .height = 65, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing rocktech_rk043fn48h_timing = { .pixelclock = { 6000000, 9000000, 12000000 }, .hactive = { 480, 480, 480 }, @@ -4191,6 +4247,37 @@ static const struct panel_desc samsung_ltl101al01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing samsung_ltl106al01_timing = { + .pixelclock = { 71980000, 71980000, 71980000 }, + .hactive = { 1366, 1366, 1366 }, + .hfront_porch = { 56, 56, 56 }, + .hback_porch = { 106, 106, 106 }, + .hsync_len = { 14, 14, 14 }, + .vactive = { 768, 768, 768 }, + .vfront_porch = { 3, 3, 3 }, + .vback_porch = { 6, 6, 6 }, + .vsync_len = { 1, 1, 1 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, +}; + +static const struct panel_desc samsung_ltl106al01 = { + .timings = &samsung_ltl106al01_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 235, + .height = 132, + }, + .delay = { + .prepare = 5, + .enable = 10, + .disable = 10, + .unprepare = 5, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode samsung_ltn101nt05_mode = { .clock = 54030, .hdisplay = 1024, @@ -5209,6 +5296,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "innolux,zj070na-01p", .data = &innolux_zj070na_01p, }, { + .compatible = "jutouch,jt101tm023", + .data = &jutouch_jt101tm023, + }, { .compatible = "koe,tx14d24vm1bpa", .data = &koe_tx14d24vm1bpa, }, { @@ -5344,6 +5434,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "qishenglong,gopher2b-lcd", .data = &qishenglong_gopher2b_lcd, }, { + .compatible = "raystar,rff500f-awh-dnn", + .data = &raystar_rff500f_awh_dnn, + }, { .compatible = "rocktech,rk043fn48h", .data = &rocktech_rk043fn48h, }, { @@ -5356,6 +5449,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "samsung,ltl101al01", .data = &samsung_ltl101al01, }, { + .compatible = "samsung,ltl106al01", + .data = &samsung_ltl106al01, + }, { .compatible = "samsung,ltn101nt05", .data = &samsung_ltn101nt05, }, { @@ -5565,34 +5661,6 @@ static const struct panel_desc_dsi boe_tv080wum_nl0 = { .lanes = 4, }; -static const struct drm_display_mode lg_ld070wx3_sl01_mode = { - .clock = 71000, - .hdisplay = 800, - .hsync_start = 800 + 32, - .hsync_end = 800 + 32 + 1, - .htotal = 800 + 32 + 1 + 57, - .vdisplay = 1280, - .vsync_start = 1280 + 28, - .vsync_end = 1280 + 28 + 1, - .vtotal = 1280 + 28 + 1 + 14, -}; - -static const struct panel_desc_dsi lg_ld070wx3_sl01 = { - .desc = { - .modes = &lg_ld070wx3_sl01_mode, - .num_modes = 1, - .bpc = 8, - .size = { - .width = 94, - .height = 151, - }, - .connector_type = DRM_MODE_CONNECTOR_DSI, - }, - .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS, - .format = MIPI_DSI_FMT_RGB888, - .lanes = 4, -}; - static const struct drm_display_mode lg_lh500wx1_sd03_mode = { .clock = 67000, .hdisplay = 720, @@ -5717,9 +5785,6 @@ static const struct of_device_id dsi_of_match[] = { .compatible = "boe,tv080wum-nl0", .data = &boe_tv080wum_nl0 }, { - .compatible = "lg,ld070wx3-sl01", - .data = &lg_ld070wx3_sl01 - }, { .compatible = "lg,lh500wx1-sd03", .data = &lg_lh500wx1_sd03 }, { diff --git a/drivers/gpu/drm/panel/panel-synaptics-tddi.c b/drivers/gpu/drm/panel/panel-synaptics-tddi.c new file mode 100644 index 000000000000..0aea1854710e --- /dev/null +++ b/drivers/gpu/drm/panel/panel-synaptics-tddi.c @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Synaptics TDDI display panel driver. + * + * Copyright (C) 2025 Kaustabh Chakraborty <kauschluss@disroot.org> + */ + +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +struct tddi_panel_data { + u8 lanes; + /* wait timings for panel enable */ + u8 delay_ms_sleep_exit; + u8 delay_ms_display_on; + /* wait timings for panel disable */ + u8 delay_ms_display_off; + u8 delay_ms_sleep_enter; +}; + +struct tddi_ctx { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct drm_display_mode mode; + struct backlight_device *backlight; + const struct tddi_panel_data *data; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + struct gpio_desc *backlight_gpio; +}; + +static const struct regulator_bulk_data tddi_supplies[] = { + { .supply = "vio" }, + { .supply = "vsn" }, + { .supply = "vsp" }, +}; + +static inline struct tddi_ctx *to_tddi_ctx(struct drm_panel *panel) +{ + return container_of(panel, struct tddi_ctx, panel); +} + +static int tddi_update_status(struct backlight_device *backlight) +{ + struct tddi_ctx *ctx = bl_get_data(backlight); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + u8 brightness = backlight_get_brightness(backlight); + + if (!ctx->panel.enabled) + return 0; + + mipi_dsi_dcs_set_display_brightness_multi(&dsi, brightness); + + return dsi.accum_err; +} + +static int tddi_prepare(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(tddi_supplies), ctx->supplies); + if (ret < 0) { + dev_err(dev, "failed to enable regulators: %d\n", ret); + return ret; + } + + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); + + gpiod_set_value_cansleep(ctx->backlight_gpio, 0); + usleep_range(5000, 6000); + + return 0; +} + +static int tddi_unprepare(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + + gpiod_set_value_cansleep(ctx->backlight_gpio, 1); + usleep_range(5000, 6000); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + + regulator_bulk_disable(ARRAY_SIZE(tddi_supplies), ctx->supplies); + + return 0; +} + +static int tddi_enable(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + u8 brightness = ctx->backlight->props.brightness; + + mipi_dsi_dcs_write_seq_multi(&dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x0c); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_sleep_exit); + + /* sync the panel with the backlight's brightness level */ + mipi_dsi_dcs_set_display_brightness_multi(&dsi, brightness); + + mipi_dsi_dcs_set_display_on_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_display_on); + + return dsi.accum_err; +}; + +static int tddi_disable(struct drm_panel *panel) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_display_off); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi); + mipi_dsi_msleep(&dsi, ctx->data->delay_ms_sleep_enter); + + return dsi.accum_err; +} + +static int tddi_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct tddi_ctx *ctx = to_tddi_ctx(panel); + + return drm_connector_helper_get_modes_fixed(connector, &ctx->mode); +} + +static const struct backlight_ops tddi_bl_ops = { + .update_status = tddi_update_status, +}; + +static const struct backlight_properties tddi_bl_props = { + .type = BACKLIGHT_PLATFORM, + .brightness = 255, + .max_brightness = 255, +}; + +static const struct drm_panel_funcs tddi_drm_panel_funcs = { + .prepare = tddi_prepare, + .unprepare = tddi_unprepare, + .enable = tddi_enable, + .disable = tddi_disable, + .get_modes = tddi_get_modes, +}; + +static int tddi_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct tddi_ctx *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct tddi_ctx, panel, + &tddi_drm_panel_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ctx->data = of_device_get_match_data(dev); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(tddi_supplies), + tddi_supplies, &ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get regulators\n"); + + ctx->backlight_gpio = devm_gpiod_get_optional(dev, "backlight", GPIOD_ASIS); + if (IS_ERR(ctx->backlight_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->backlight_gpio), + "failed to get backlight-gpios\n"); + + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "failed to get reset-gpios\n"); + + ret = of_get_drm_panel_display_mode(dev->of_node, &ctx->mode, NULL); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get panel timings\n"); + + ctx->backlight = devm_backlight_device_register(dev, dev_name(dev), dev, + ctx, &tddi_bl_ops, + &tddi_bl_props); + if (IS_ERR(ctx->backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->backlight), + "failed to register backlight device"); + + dsi->lanes = ctx->data->lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_VIDEO_NO_HFP; + + ctx->panel.prepare_prev_first = true; + drm_panel_add(&ctx->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "failed to attach to DSI host\n"); + } + + return 0; +} + +static void tddi_remove(struct mipi_dsi_device *dsi) +{ + struct tddi_ctx *ctx = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&ctx->panel); +} + +static const struct tddi_panel_data td4101_panel_data = { + .lanes = 2, + /* wait timings for panel enable */ + .delay_ms_sleep_exit = 100, + .delay_ms_display_on = 0, + /* wait timings for panel disable */ + .delay_ms_display_off = 20, + .delay_ms_sleep_enter = 90, +}; + +static const struct tddi_panel_data td4300_panel_data = { + .lanes = 4, + /* wait timings for panel enable */ + .delay_ms_sleep_exit = 100, + .delay_ms_display_on = 0, + /* wait timings for panel disable */ + .delay_ms_display_off = 0, + .delay_ms_sleep_enter = 0, +}; + +static const struct of_device_id tddi_of_device_id[] = { + { + .compatible = "syna,td4101-panel", + .data = &td4101_panel_data, + }, { + .compatible = "syna,td4300-panel", + .data = &td4300_panel_data, + }, { } +}; +MODULE_DEVICE_TABLE(of, tddi_of_device_id); + +static struct mipi_dsi_driver tddi_dsi_driver = { + .probe = tddi_probe, + .remove = tddi_remove, + .driver = { + .name = "panel-synaptics-tddi", + .of_match_table = tddi_of_device_id, + }, +}; +module_mipi_dsi_driver(tddi_dsi_driver); + +MODULE_AUTHOR("Kaustabh Chakraborty <kauschluss@disroot.org>"); +MODULE_DESCRIPTION("Synaptics TDDI Display Panel Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c index 909c280eab1f..e5e688cf98fd 100644 --- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -3,6 +3,7 @@ * Copyright (c) 2019, The Linux Foundation. All rights reserved. */ +#include <linux/backlight.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/property.h> @@ -20,6 +21,8 @@ struct visionox_rm69299_panel_desc { const struct drm_display_mode *mode; const u8 *init_seq; unsigned int init_seq_len; + int max_brightness; + int initial_brightness; }; struct visionox_rm69299 { @@ -192,7 +195,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) struct visionox_rm69299 *ctx = panel_to_ctx(panel); struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; - ctx->dsi->mode_flags = 0; + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); @@ -247,7 +250,7 @@ static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = { }; static const struct drm_display_mode visionox_rm69299_1080x2160_60hz = { - .clock = 158695, + .clock = (2160 + 8 + 4 + 4) * (1080 + 26 + 2 + 36) * 60 / 1000, .hdisplay = 1080, .hsync_start = 1080 + 26, .hsync_end = 1080 + 26 + 2, @@ -285,6 +288,63 @@ static const struct drm_panel_funcs visionox_rm69299_drm_funcs = { .get_modes = visionox_rm69299_get_modes, }; +static int visionox_rm69299_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return brightness; +} + +static int visionox_rm69299_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops visionox_rm69299_bl_ops = { + .update_status = visionox_rm69299_bl_update_status, + .get_brightness = visionox_rm69299_bl_get_brightness, +}; + +static struct backlight_device * +visionox_rm69299_create_backlight(struct visionox_rm69299 *ctx) +{ + struct device *dev = &ctx->dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = ctx->desc->initial_brightness, + .max_brightness = ctx->desc->max_brightness, + }; + + if (!ctx->desc->max_brightness) + return 0; + + return devm_backlight_device_register(dev, dev_name(dev), dev, ctx->dsi, + &visionox_rm69299_bl_ops, + &props); +} + static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) { struct device *dev = &dsi->dev; @@ -316,6 +376,11 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) return PTR_ERR(ctx->reset_gpio); } + ctx->panel.backlight = visionox_rm69299_create_backlight(ctx); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + drm_panel_add(&ctx->panel); dsi->lanes = 4; @@ -353,6 +418,8 @@ const struct visionox_rm69299_panel_desc visionox_rm69299_shift_desc = { .mode = &visionox_rm69299_1080x2160_60hz, .init_seq = (const u8 *)visionox_rm69299_1080x2160_60hz_init_seq, .init_seq_len = ARRAY_SIZE(visionox_rm69299_1080x2160_60hz_init_seq), + .max_brightness = 255, + .initial_brightness = 50, }; static const struct of_device_id visionox_rm69299_of_match[] = { |
