Skip to content

Instantly share code, notes, and snippets.

@ata2001
Last active January 15, 2018 15:13
Show Gist options
  • Save ata2001/4bfb6320aded76cdd21e9f798416b2f7 to your computer and use it in GitHub Desktop.
Save ata2001/4bfb6320aded76cdd21e9f798416b2f7 to your computer and use it in GitHub Desktop.
AUO Novatek 720p panel driver
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index d84a031f..5d970093 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -117,4 +117,13 @@ config DRM_PANEL_SITRONIX_ST7789V
Say Y here if you want to enable support for the Sitronix
ST7789V controller for 240x320 LCD panels
+config DRM_PANEL_AUO_NOVATEK_720P
+ tristate "AUO Novatek 720p panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to enable support for AUO 720p DSI panel
+ as found in some Sony XPERIA Z1 compact devices
+
endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 9f6610d0..a45c8d50 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
+obj-$(CONFIG_DRM_PANEL_AUO_NOVATEK_720P) += panel-auo-novatek-720p.o
diff --git a/drivers/gpu/drm/panel/panel-auo-novatek-720p.c b/drivers/gpu/drm/panel/panel-auo-novatek-720p.c
index e69de29b..53cc77db 100644
--- a/drivers/gpu/drm/panel/panel-auo-novatek-720p.c
+++ b/drivers/gpu/drm/panel/panel-auo-novatek-720p.c
@@ -0,0 +1,2318 @@
+/*
+ * Copyright (C) 2015 Red Hat
+ * Copyright (C) 2017 Attila Szollosi
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/backlight.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <video/mipi_display.h>
+
+struct auo_panel {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ struct backlight_device *backlight;
+ struct regulator *supply;
+ struct gpio_desc *reset_gpio;
+
+ bool prepared;
+ bool enabled;
+
+ const struct drm_display_mode *mode;
+};
+
+static inline struct auo_panel *to_auo_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct auo_panel, base);
+}
+
+static int auo_panel_cabc_early_init(struct auo_panel *auo)
+{
+ struct mipi_dsi_device *dsi = auo->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0xee }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x26, (u8[]){ 0x08 }, 1);
+ if (ret < 0)
+ return ret;
+ msleep(1);
+
+ ret = mipi_dsi_dcs_write(dsi, 0x26, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int auo_panel_init(struct auo_panel *auo)
+{
+ struct mipi_dsi_device *dsi = auo->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0xee }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x12, (u8[]){ 0x50 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x13, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x00, (u8[]){ 0x4a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x01, (u8[]){ 0x43 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x02, (u8[]){ 0x54 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x03, (u8[]){ 0x55 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x04, (u8[]){ 0x55 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x05, (u8[]){ 0x33 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x06, (u8[]){ 0x22 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x08, (u8[]){ 0x56 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x09, (u8[]){ 0x8f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0b, (u8[]){ 0x97 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0c, (u8[]){ 0x97 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0d, (u8[]){ 0x2f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0e, (u8[]){ 0x24 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x36, (u8[]){ 0x73 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0f, (u8[]){ 0x04 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x69, (u8[]){ 0x99 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6f, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x01, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x02, (u8[]){ 0x8d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x03, (u8[]){ 0x8d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x04, (u8[]){ 0x8d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x05, (u8[]){ 0x30 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x06, (u8[]){ 0x33 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x07, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x08, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x09, (u8[]){ 0x46 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0a, (u8[]){ 0x46 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0d, (u8[]){ 0x0b }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0e, (u8[]){ 0x1d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0f, (u8[]){ 0x08 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x10, (u8[]){ 0x53 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x11, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x12, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x14, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x15, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x16, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x17, (u8[]){ 0x04 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x19, (u8[]){ 0x7f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1a, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1b, (u8[]){ 0x0f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1c, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1d, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1e, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1f, (u8[]){ 0x07 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x20, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x21, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x22, (u8[]){ 0x55 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x23, (u8[]){ 0x4d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6c, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6d, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2d, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x83, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9e, (u8[]){ 0x58 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9f, (u8[]){ 0x58 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa0, (u8[]){ 0x41 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa2, (u8[]){ 0x10 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbb, (u8[]){ 0x0a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbc, (u8[]){ 0x0a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x28, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2f, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x32, (u8[]){ 0x08 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x33, (u8[]){ 0xb8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x36, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x37, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x43, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4b, (u8[]){ 0x21 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4c, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x50, (u8[]){ 0x21 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x51, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x58, (u8[]){ 0x21 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x59, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5d, (u8[]){ 0x21 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5e, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x75, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x76, (u8[]){ 0x59 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x77, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x78, (u8[]){ 0x61 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x79, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7a, (u8[]){ 0x72 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7b, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7c, (u8[]){ 0x81 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7d, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7e, (u8[]){ 0x90 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7f, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x80, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x81, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x82, (u8[]){ 0xab }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x83, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x84, (u8[]){ 0xb7 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x85, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x86, (u8[]){ 0xc2 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x87, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x88, (u8[]){ 0xe8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x89, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8a, (u8[]){ 0x0a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8b, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8c, (u8[]){ 0x40 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8d, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8e, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8f, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x90, (u8[]){ 0xb5 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x91, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x92, (u8[]){ 0x0d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x93, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x94, (u8[]){ 0x0f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x95, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x96, (u8[]){ 0x57 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x97, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x98, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x99, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9a, (u8[]){ 0xca }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9b, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9c, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9d, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9e, (u8[]){ 0x2c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9f, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa0, (u8[]){ 0x60 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa2, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa3, (u8[]){ 0x71 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa4, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa5, (u8[]){ 0x87 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa6, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa7, (u8[]){ 0xb8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xaa, (u8[]){ 0xc8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xab, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xac, (u8[]){ 0xd8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xad, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xae, (u8[]){ 0xe8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xaf, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb0, (u8[]){ 0xf8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb1, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb2, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb3, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb4, (u8[]){ 0x59 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb5, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb6, (u8[]){ 0x61 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb7, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb8, (u8[]){ 0x72 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb9, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xba, (u8[]){ 0x81 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbb, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbc, (u8[]){ 0x90 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbd, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbe, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbf, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc0, (u8[]){ 0xab }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc1, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc2, (u8[]){ 0xb7 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc3, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc4, (u8[]){ 0xc2 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc5, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc6, (u8[]){ 0xe8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc7, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc8, (u8[]){ 0x0a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc9, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xca, (u8[]){ 0x40 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcc, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcd, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xce, (u8[]){ 0xb5 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcf, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd0, (u8[]){ 0x0d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd1, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd2, (u8[]){ 0x0f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd3, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd4, (u8[]){ 0x57 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd5, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd6, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd7, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd8, (u8[]){ 0xca }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xda, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdb, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdc, (u8[]){ 0x2c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdd, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xde, (u8[]){ 0x60 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdf, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe0, (u8[]){ 0x71 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe1, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe2, (u8[]){ 0x87 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe3, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe4, (u8[]){ 0xb8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe5, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe6, (u8[]){ 0xc8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe7, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe8, (u8[]){ 0xd8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xea, (u8[]){ 0xe8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xeb, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xec, (u8[]){ 0xf8 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xed, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xee, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xef, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf0, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf1, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf2, (u8[]){ 0x76 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf3, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf4, (u8[]){ 0x85 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf5, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf6, (u8[]){ 0x92 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf7, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf8, (u8[]){ 0x9f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xf9, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfa, (u8[]){ 0xab }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x00, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x01, (u8[]){ 0xb6 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x02, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x03, (u8[]){ 0xc1 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x04, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x05, (u8[]){ 0xcb }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x06, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x07, (u8[]){ 0xef }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x08, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x09, (u8[]){ 0x0f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0a, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0b, (u8[]){ 0x43 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0c, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0d, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0e, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0f, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x10, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x11, (u8[]){ 0x0c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x12, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x13, (u8[]){ 0x0e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x14, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x15, (u8[]){ 0x56 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x16, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x17, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x18, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x19, (u8[]){ 0xca }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1a, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1b, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1c, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1d, (u8[]){ 0x2a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1e, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x1f, (u8[]){ 0x56 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x20, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x21, (u8[]){ 0x61 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x22, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x23, (u8[]){ 0x6f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x24, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x25, (u8[]){ 0x7d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x26, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x27, (u8[]){ 0x8d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x28, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x29, (u8[]){ 0x96 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2a, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2b, (u8[]){ 0xa2 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2d, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2f, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x30, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x31, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x32, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x33, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x34, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x35, (u8[]){ 0x76 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x36, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x37, (u8[]){ 0x85 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x38, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x39, (u8[]){ 0x92 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x3a, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x3b, (u8[]){ 0x9f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x3d, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x3f, (u8[]){ 0xab }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x40, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x41, (u8[]){ 0xb6 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x42, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x43, (u8[]){ 0xc1 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x44, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x45, (u8[]){ 0xcb }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x46, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x47, (u8[]){ 0xef }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x48, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x49, (u8[]){ 0x0f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4a, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4b, (u8[]){ 0x43 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4c, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4d, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4e, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x4f, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x50, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x51, (u8[]){ 0x0c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x52, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x53, (u8[]){ 0x0e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x54, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x55, (u8[]){ 0x56 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x56, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x58, (u8[]){ 0x9e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x59, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5a, (u8[]){ 0xca }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5b, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5c, (u8[]){ 0x05 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5d, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5e, (u8[]){ 0x2a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x5f, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x60, (u8[]){ 0x56 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x61, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x62, (u8[]){ 0x61 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x63, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x64, (u8[]){ 0x6f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x65, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x66, (u8[]){ 0x7d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x67, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x68, (u8[]){ 0x8d }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x69, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6a, (u8[]){ 0x96 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6b, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6c, (u8[]){ 0xa2 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6d, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6e, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x6f, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x70, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x71, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x72, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x73, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x74, (u8[]){ 0x0e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x75, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x76, (u8[]){ 0x26 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x77, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x78, (u8[]){ 0x3a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x79, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7a, (u8[]){ 0x4c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7b, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7c, (u8[]){ 0x5e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7d, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7e, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x7f, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x80, (u8[]){ 0x7b }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x81, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x82, (u8[]){ 0x88 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x83, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x84, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x85, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x86, (u8[]){ 0xdb }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x87, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x88, (u8[]){ 0x17 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x89, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8a, (u8[]){ 0x4a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8b, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8c, (u8[]){ 0x98 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8d, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8e, (u8[]){ 0xfc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x8f, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x90, (u8[]){ 0xfe }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x91, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x92, (u8[]){ 0x4a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x93, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x94, (u8[]){ 0x93 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x95, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x96, (u8[]){ 0xc0 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x97, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x98, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x99, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9a, (u8[]){ 0x2f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9b, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9c, (u8[]){ 0x85 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9d, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9e, (u8[]){ 0xcc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x9f, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa0, (u8[]){ 0xd4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa2, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa3, (u8[]){ 0xdc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa4, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa5, (u8[]){ 0xe4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa6, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa7, (u8[]){ 0xec }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xa9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xaa, (u8[]){ 0xf4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xab, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xac, (u8[]){ 0xfc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xad, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xae, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xaf, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb0, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb1, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb2, (u8[]){ 0x0e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb3, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb4, (u8[]){ 0x26 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb5, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb6, (u8[]){ 0x3a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb7, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb8, (u8[]){ 0x4c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xb9, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xba, (u8[]){ 0x5e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbb, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbc, (u8[]){ 0x6e }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbd, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbe, (u8[]){ 0x7b }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xbf, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc0, (u8[]){ 0x88 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc1, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc2, (u8[]){ 0xb4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc3, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc4, (u8[]){ 0xdb }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc5, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc6, (u8[]){ 0x17 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc7, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc8, (u8[]){ 0x4a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc9, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xca, (u8[]){ 0x98 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcc, (u8[]){ 0xfc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcd, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xce, (u8[]){ 0xfe }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xcf, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd0, (u8[]){ 0x4a }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd1, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd2, (u8[]){ 0x93 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd3, (u8[]){ 0x02 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd4, (u8[]){ 0xc0 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd5, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd6, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd7, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd8, (u8[]){ 0x2f }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xd9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xda, (u8[]){ 0x85 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdb, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdc, (u8[]){ 0xcc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdd, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xde, (u8[]){ 0xd4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xdf, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe0, (u8[]){ 0xdc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe1, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe2, (u8[]){ 0xe4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe3, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe4, (u8[]){ 0xec }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe5, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe6, (u8[]){ 0xf4 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe7, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe8, (u8[]){ 0xfc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xe9, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xea, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xc2, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x3b, (u8[]){ 0x03, 0x02, 0x03, 0x08, 0x04 }, 5);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xba, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0)
+ return ret;
+
+ msleep(50);
+
+ return 0;
+}
+
+static int auo_panel_cabc_early_on(struct auo_panel *auo)
+{
+ struct mipi_dsi_device *dsi = auo->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x04 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x2a, (u8[]){ 0x84 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x29, (u8[]){ 0x99 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x28, (u8[]){ 0x99 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x27, (u8[]){ 0x99 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x26, (u8[]){ 0xaa }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x25, (u8[]){ 0xbb }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x24, (u8[]){ 0xcc }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x23, (u8[]){ 0xdd }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x22, (u8[]){ 0xee }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x21, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x0a, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x32, (u8[]){ 0x64 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xfb, (u8[]){ 0x01 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x00 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x51, (u8[]){ 0xff }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x53, (u8[]){ 0x2c }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_write(dsi, 0x55, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int auo_panel_on(struct auo_panel *auo)
+{
+ struct mipi_dsi_device *dsi = auo->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0)
+ return ret;
+
+ msleep(40);
+
+ return 0;
+}
+
+static int auo_panel_off(struct auo_panel *auo)
+{
+ struct mipi_dsi_device *dsi = auo->dsi;
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_write(dsi, 0xff, (u8[]){ 0x10 }, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0)
+ return ret;
+
+ msleep(100);
+
+ return 0;
+}
+
+static int auo_panel_disable(struct drm_panel *panel)
+{
+ struct auo_panel *auo = to_auo_panel(panel);
+
+ if (!auo->enabled)
+ return 0;
+
+ DRM_DEBUG("disable\n");
+
+ if (auo->backlight) {
+ auo->backlight->props.power = FB_BLANK_POWERDOWN;
+ backlight_update_status(auo->backlight);
+ }
+
+ auo->enabled = false;
+
+ return 0;
+}
+
+static int auo_panel_unprepare(struct drm_panel *panel)
+{
+ struct auo_panel *auo = to_auo_panel(panel);
+ int ret;
+
+ if (!auo->prepared)
+ return 0;
+
+ DRM_DEBUG("unprepare\n");
+
+ ret = auo_panel_off(auo);
+ if (ret) {
+ dev_err(panel->dev, "failed to set panel off: %d\n", ret);
+ return ret;
+ }
+
+ regulator_disable(auo->supply);
+ if (auo->reset_gpio)
+ gpiod_set_value(auo->reset_gpio, 0);
+
+ auo->prepared = false;
+
+ return 0;
+}
+
+static int auo_panel_prepare(struct drm_panel *panel)
+{
+ struct auo_panel *auo = to_auo_panel(panel);
+ int ret;
+
+ if (auo->prepared)
+ return 0;
+
+ DRM_DEBUG("prepare\n");
+
+ if (auo->reset_gpio) {
+ gpiod_set_value(auo->reset_gpio, 0);
+ msleep(5);
+ }
+
+ ret = regulator_enable(auo->supply);
+ if (ret < 0)
+ return ret;
+
+ msleep(20);
+
+ if (auo->reset_gpio) {
+ gpiod_set_value(auo->reset_gpio, 1);
+ msleep(10);
+ }
+
+ msleep(150);
+
+ ret = auo_panel_cabc_early_init(auo);
+ if (ret) {
+ dev_err(panel->dev, "early init sequence failed: %d\n", ret);
+ goto poweroff;
+ }
+
+ ret = auo_panel_cabc_early_on(auo);
+ if (ret) {
+ dev_err(panel->dev, "early on sequence failed: %d\n", ret);
+ goto poweroff;
+ }
+
+ ret = auo_panel_init(auo);
+ if (ret) {
+ dev_err(panel->dev, "failed to init panel: %d\n", ret);
+ goto poweroff;
+ }
+
+ ret = auo_panel_on(auo);
+ if (ret) {
+ dev_err(panel->dev, "failed to set panel on: %d\n", ret);
+ goto poweroff;
+ }
+
+ auo->prepared = true;
+
+ return 0;
+
+poweroff:
+ regulator_disable(auo->supply);
+ if (auo->reset_gpio)
+ gpiod_set_value(auo->reset_gpio, 0);
+ return ret;
+}
+
+static int auo_panel_enable(struct drm_panel *panel)
+{
+ struct auo_panel *auo = to_auo_panel(panel);
+
+ if (auo->enabled)
+ return 0;
+
+ DRM_DEBUG("enable\n");
+
+ if (auo->backlight) {
+ auo->backlight->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(auo->backlight);
+ }
+
+ auo->enabled = true;
+
+ return 0;
+}
+
+static const struct drm_display_mode default_mode = {
+ .clock = 71331,
+ .hdisplay = 720,
+ .hsync_start = 720 + 136,
+ .hsync_end = 720 + 136 + 4,
+ .htotal = 720 + 136 + 4 + 4,
+ .vdisplay = 1280,
+ .vsync_start = 1280 + 94,
+ .vsync_end = 1280 + 94 + 1,
+ .vtotal = 1280 + 94 + 1 + 1,
+ .vrefresh = 60,
+};
+
+static int auo_panel_get_modes(struct drm_panel *panel)
+{
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(panel->drm, &default_mode);
+ if (!mode) {
+ dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
+ default_mode.hdisplay, default_mode.vdisplay,
+ default_mode.vrefresh);
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ drm_mode_probed_add(panel->connector, mode);
+
+ panel->connector->display_info.width_mm = 53;
+ panel->connector->display_info.height_mm = 94;
+
+ return 1;
+}
+
+static const struct drm_panel_funcs auo_panel_funcs = {
+ .disable = auo_panel_disable,
+ .unprepare = auo_panel_unprepare,
+ .prepare = auo_panel_prepare,
+ .enable = auo_panel_enable,
+ .get_modes = auo_panel_get_modes,
+};
+
+static const struct of_device_id auo_of_match[] = {
+ { .compatible = "auo,novatek-720p-vid", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, auo_of_match);
+
+static int auo_panel_add(struct auo_panel *auo)
+{
+ struct device *dev= &auo->dsi->dev;
+ struct device_node *np;
+ int ret;
+
+ auo->mode = &default_mode;
+
+ auo->supply = devm_regulator_get(dev, "power");
+ if (IS_ERR(auo->supply))
+ return PTR_ERR(auo->supply);
+
+ auo->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(auo->reset_gpio)) {
+ dev_err(dev, "cannot get reset-gpios %ld\n",
+ PTR_ERR(auo->reset_gpio));
+ auo->reset_gpio = NULL;
+ } else {
+ gpiod_direction_output(auo->reset_gpio, 0);
+ }
+
+ np = of_parse_phandle(dev->of_node, "backlight", 0);
+ if (np) {
+ auo->backlight = of_find_backlight_by_node(np);
+ of_node_put(np);
+
+ if (!auo->backlight)
+ return -EPROBE_DEFER;
+ }
+
+ drm_panel_init(&auo->base);
+ auo->base.funcs = &auo_panel_funcs;
+ auo->base.dev = &auo->dsi->dev;
+
+ ret = drm_panel_add(&auo->base);
+ if (ret < 0)
+ goto put_backlight;
+
+ return 0;
+
+ put_backlight:
+ if (auo->backlight)
+ put_device(&auo->backlight->dev);
+
+ return ret;
+}
+
+static void auo_panel_del(struct auo_panel *auo)
+{
+ if (auo->base.dev)
+ drm_panel_remove(&auo->base);
+
+ if (auo->backlight)
+ put_device(&auo->backlight->dev);
+}
+
+static int auo_panel_probe(struct mipi_dsi_device *dsi)
+{
+ struct auo_panel *auo;
+ int ret;
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+ MIPI_DSI_MODE_VIDEO_HSE |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS |
+ MIPI_DSI_MODE_EOT_PACKET;
+
+ auo = devm_kzalloc(&dsi->dev, sizeof(*auo), GFP_KERNEL);
+ if (!auo) {
+ return -ENOMEM;
+ }
+
+ mipi_dsi_set_drvdata(dsi, auo);
+
+ auo->dsi = dsi;
+
+ ret = auo_panel_add(auo);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return mipi_dsi_attach(dsi);
+}
+
+static int auo_panel_remove(struct mipi_dsi_device *dsi)
+{
+ struct auo_panel *auo = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = auo_panel_disable(&auo->base);
+ if (ret < 0)
+ dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
+
+ drm_panel_detach(&auo->base);
+ auo_panel_del(auo);
+
+ return 0;
+}
+
+static void auo_panel_shutdown(struct mipi_dsi_device *dsi)
+{
+ struct auo_panel *auo = mipi_dsi_get_drvdata(dsi);
+
+ auo_panel_disable(&auo->base);
+}
+
+static struct mipi_dsi_driver auo_panel_driver = {
+ .driver = {
+ .name = "panel-auo-novatek-720p",
+ .of_match_table = auo_of_match,
+ },
+ .probe = auo_panel_probe,
+ .remove = auo_panel_remove,
+ .shutdown = auo_panel_shutdown,
+};
+module_mipi_dsi_driver(auo_panel_driver);
+
+MODULE_AUTHOR("Attila Szollosi <ata2001@airmail.cc>");
+MODULE_DESCRIPTION("AUO Novatek 720p panel driver");
+MODULE_LICENSE("GPL v2");
@munjeni
Copy link

munjeni commented Jan 4, 2018

Hi, amazing work! If you are interesting I have got wifi on latest mainline kernel https://forum.xda-developers.com/showpost.php?p=74889673&postcount=6 and this finaly working with some small modification to device tree https://forum.xda-developers.com/showpost.php?p=74895925&postcount=7 , curently having some problems with wifi "can't pass authentification" when I trying to connect to AP network, client also can't connect to any AP. Did you got postmarketos working on Z1C? Can I get download link?

@mirh
Copy link

mirh commented Jan 4, 2018

There's is none 😆
Just sources :p
Let's say it's just a tad hard to understand how their build system works
https://github.com/postmarketOS/pmbootstrap/pull/100 and https://github.com/postmarketOS/pmbootstrap/pull/770 should pretty much interest you and give an idea

TL;DR they should check out this (LA.BR.1.3.3_rb2.14 based)
Funny how having sources "upstreamed" gave you more problems than it solved, lol.

EDIT: I fear gist doesn't notify you of comments.....
ping @ata2001

@munjeni
Copy link

munjeni commented Jan 5, 2018

#770 commit no, its old prima wlan which exist only on msm kernel, wcn36xx is on mainline kernel and that one is what I told about. I saw that python script for building PMO but I thinked maybe somebody have it allready compiled just for trying it with mainline kernel

@ata2001
Copy link
Author

ata2001 commented Jan 12, 2018

@munjeni amazing news!

Regarding display: I haven't been able to get anything on the screen yet. I'm going to publish the dt patches too, I might need some help debugging this driver.

BTW: I've sent a minimal dt without display and wifi to the linux mailing list: https://patchwork.kernel.org/patch/10089119/

You should join #postmarketos and ##linux-msm on freenode, we could continue this conversation there.

@munjeni
Copy link

munjeni commented Jan 13, 2018

Hey thanks! Amami is specific on mdss in comparation to Honami. For example this commit which I done munjeni/android_kernel_sony_msm8974@22c5690 fixes black screen on Amami. Problem was udelays on mdss clocks! Also there is two modes, video mode and command mode. If I remember corecly Amami on video mode have problem with hardware overlays and frezes in almost all like YouTube...etc, so with patch above Amami now use command mode and all things related to hardware overlays is working now. Amami have 3-4 diferent panels, so booth panels must be ported too! Your panel driver indeed not working, at least with dtb I used, I can't get right dsi base (https://forum.xda-developers.com/showpost.php?p=74910407&postcount=8) and realy have no idea what is need to get it working. But I am happy because I see somebody working on Amami, realy! :) If need I can post wifi part!

@ata2001
Copy link
Author

ata2001 commented Jan 13, 2018

@munjeni I have another Z1C with jdi panel, I'm using that for testing, this might not be updated by me until I replace the battery in my amami with auo panel.

Panel detection haven't yet been solved in mainline linux, but Bjorn Andersson and Rob Clark are working on it IIRC.

@mirh
Copy link

mirh commented Jan 13, 2018

wcn36xx is on mainline kernel and that one is what I told about.

Oh, speaking of the devil, look who had worked on what

@munjeni
Copy link

munjeni commented Jan 14, 2018

Hm I might think wcn36xx by wiki https://wireless.wiki.kernel.org/en/users/drivers/wcn36xx point to https://github.com/KrasnikovEugene/wcn36xx . I'm compared Krasnikov latest dev branch with mainline wcn36xx seems wcn36xx on mainline is much more updated

@munjeni
Copy link

munjeni commented Jan 14, 2018

@ata2001 I have jdi panel too

@mirh
Copy link

mirh commented Jan 15, 2018

Oh, cool. Kinda crazy he's almost unmentioned anywhere.
I have also found this very very random bug tracker with Mr. Importance involved then https://bugs.96boards.org/show_bug.cgi?id=631

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment