Add support for Visionox panel driver.
Changes in v1:
-Split out panel driver patch from dsi config changes(Rob Clark).
-Remove unrelated code(Stephen Boyd).
-Remove static arrays to make regulator setup open coded
in probe(Stephen Boyd).
-Remove pre-assigning variables(Stephen Boyd).
-Inline panel_add function into probe(Stephen Boyd).
-Use mipi_dsi_dcs_write directly(Rob Clark).
-Remove qcom_rm69299_1080p_panel_magic_cmds array(Rob Clark).
Changes in v2:
-Dropping redundant space in Kconfig(Sam Ravnborg).
-Changing structure for include files(Sam Ravnborg).
-Removing backlight related code and functions(Sam Ravnborg).
-Removing repeated printing of error message(Sam Ravnborg).
-Adding drm_connector as an argument for get_modes function.
Signed-off-by: Harigovindan P
---
drivers/gpu/drm/panel/Kconfig | 8 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-visionox-rm69299.c | 370 +
3 files changed, 379 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-visionox-rm69299.c
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index f152bc4..123481f 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -355,4 +355,12 @@ config DRM_PANEL_TRULY_NT35597_WQXGA
help
Say Y here if you want to enable support for Truly NT35597 WQXGA Dual
DSI
Video Mode panel
+
+config DRM_PANEL_VISIONOX_RM69299
+ tristate "Visionox RM69299"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ help
+ Say Y here if you want to enable support for Visionox
+ RM69299 DSI Video Mode panel.
endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index b6cd39f..6f1e4c6 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) +=
panel-tpo-td028ttec1.o
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
+obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c
b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
new file mode 100644
index 000..3fa1cb4
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+struct rm69299_config {
+ unsigned long width_mm;
+ unsigned long height_mm;
+ const char *panel_name;
+ u32 num_on_cmds;
+ const struct drm_display_mode *dm;
+};
+
+struct visionox_rm69299 {
+ struct device *dev;
+ struct drm_panel panel;
+
+ struct regulator_bulk_data supplies[2];
+
+ struct gpio_desc *reset_gpio;
+
+ struct mipi_dsi_device *dsi;
+ const struct rm69299_config *config;
+ bool prepared;
+ bool enabled;
+};
+
+static inline struct visionox_rm69299 *panel_to_ctx(struct drm_panel *panel)
+{
+ return container_of(panel, struct visionox_rm69299, panel);
+}
+
+static int visionox_35597_power_on(struct visionox_rm69299 *ctx)
+{
+ int ret;
+
+ ret = regulator_set_load(ctx->supplies[0].consumer, 32000);
+ if (ret)
+ return ret;
+
+ ret = regulator_set_load(ctx->supplies[1].consumer, 13200);
+ if (ret)
+ return ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ /*
+* Reset sequence of visionox panel requires the panel to be
+* out of reset for 10ms, followed by being held in reset
+* for 10ms and then out again
+*/
+ gpiod_set_value(ctx->reset_gpio, 1);
+ usleep_range(1, 2);
+ gpiod_set_value(ctx->reset_gpio, 0);
+ usleep_range(1, 2);
+ gpiod_set_value(ctx->reset_gpio, 1);
+ usleep_range(1, 2);
+
+ return 0;
+}
+
+static int visionox_rm69299_power_off(struct visionox_rm69299 *ctx)
+{
+ int ret;
+
+ gpiod_set_value(ctx->reset_gpio, 0);
+
+ ret = regulator_set_load(ctx->supplies[0].consumer, 80);
+
+ if (ret) {
+ DRM_DEV_ERROR(ctx->dev,
+ "regulator_set_load failed %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_set_load(ctx->supplies[1].consumer, 80);
+
+ if (ret) {
+ DRM_DEV_ERROR(ctx->dev,
+ "regulator_set_load failed %d\n", ret);
+ return ret;
+ }
+
+ ret =