diff mbox series

[3/4] drm/panel: s6e63m0: Add reading functionality

Message ID 20200809215104.1830206-4-linus.walleij@linaro.org
State Accepted
Commit 91867ac7d6724c31f32c3a63e2bb5db978893eaf
Headers show
Series drm/panel: s6e63m0: Add DSI transport | expand

Commit Message

Linus Walleij Aug. 9, 2020, 9:51 p.m. UTC
This adds code to send read commands to read a single
byte from the display, in order to perform MTP ID
look-up of the mounted panel on the s6e63m0 controller.
This is needed for proper biasing on the DSI variants.

Cc: Stephan Gerhold <stephan@gerhold.net>
Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 19 ++++++++++++++++++-
 .../gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 14 +++++++++++++-
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 11 +++++++++++
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.h |  1 +
 4 files changed, 43 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c
index f4927a6ce26d..2ec9e7900791 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c
@@ -16,6 +16,22 @@ 
 #define MCS_GLOBAL_PARAM	0xb0
 #define S6E63M0_DSI_MAX_CHUNK	15 /* CMD + 15 bytes max */
 
+static int s6e63m0_dsi_dcs_read(struct device *dev, const u8 cmd, u8 *data)
+{
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+	int ret;
+
+	ret = mipi_dsi_dcs_read(dsi, cmd, data, 1);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "could not read DCS CMD %02x\n", cmd);
+		return ret;
+	}
+
+	DRM_DEV_INFO(dev, "DSI read CMD %02x = %02x\n", cmd, *data);
+
+	return 0;
+}
+
 static int s6e63m0_dsi_dcs_write(struct device *dev, const u8 *data, size_t len)
 {
 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
@@ -90,7 +106,8 @@  static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi)
 		MIPI_DSI_MODE_EOT_PACKET |
 		MIPI_DSI_MODE_VIDEO_BURST;
 
-	ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_write, true);
+	ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_read, s6e63m0_dsi_dcs_write,
+			    true);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
index 0587eac52f2a..3b1a2a3a44ea 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
@@ -11,6 +11,17 @@ 
 
 #define DATA_MASK	0x100
 
+static int s6e63m0_spi_dcs_read(struct device *dev, const u8 cmd, u8 *data)
+{
+	/*
+	 * FIXME: implement reading DCS commands over SPI so we can
+	 * properly identify which physical panel is connected.
+	 */
+	*data = 0;
+
+	return 0;
+}
+
 static int s6e63m0_spi_write_word(struct device *dev, u16 data)
 {
 	struct spi_device *spi = to_spi_device(dev);
@@ -60,7 +71,8 @@  static int s6e63m0_spi_probe(struct spi_device *spi)
 		DRM_DEV_ERROR(dev, "spi setup failed.\n");
 		return ret;
 	}
-	return s6e63m0_probe(dev, s6e63m0_spi_dcs_write, false);
+	return s6e63m0_probe(dev, s6e63m0_spi_dcs_read, s6e63m0_spi_dcs_write,
+			     false);
 }
 
 static int s6e63m0_spi_remove(struct spi_device *spi)
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
index c6d17e938955..b25021bdd724 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
@@ -87,6 +87,7 @@  static u8 const s6e63m0_gamma_22[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = {
 
 struct s6e63m0 {
 	struct device *dev;
+	int (*dcs_read)(struct device *dev, const u8 cmd, u8 *val);
 	int (*dcs_write)(struct device *dev, const u8 *data, size_t len);
 	struct drm_panel panel;
 	struct backlight_device *bl_dev;
@@ -136,6 +137,14 @@  static int s6e63m0_clear_error(struct s6e63m0 *ctx)
 	return ret;
 }
 
+static void s6e63m0_dcs_read(struct s6e63m0 *ctx, const u8 cmd, u8 *data)
+{
+	if (ctx->error < 0)
+		return;
+
+	ctx->error = ctx->dcs_read(ctx->dev, cmd, data);
+}
+
 static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len)
 {
 	if (ctx->error < 0 || len == 0)
@@ -403,6 +412,7 @@  static int s6e63m0_backlight_register(struct s6e63m0 *ctx)
 }
 
 int s6e63m0_probe(struct device *dev,
+		  int (*dcs_read)(struct device *dev, const u8 cmd, u8 *val),
 		  int (*dcs_write)(struct device *dev, const u8 *data, size_t len),
 		  bool dsi_mode)
 {
@@ -413,6 +423,7 @@  int s6e63m0_probe(struct device *dev,
 	if (!ctx)
 		return -ENOMEM;
 
+	ctx->dcs_read = dcs_read;
 	ctx->dcs_write = dcs_write;
 	dev_set_drvdata(dev, ctx);
 
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h
index 229e23b0c97a..c669fec91763 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h
@@ -4,6 +4,7 @@ 
 #define _PANEL_SAMSUNG_S6E63M0_H
 
 int s6e63m0_probe(struct device *dev,
+		  int (*dcs_read)(struct device *dev, const u8 cmd, u8 *val),
 		  int (*dcs_write)(struct device *dev, const u8 *data,
 				   size_t len),
 		  bool dsi_mode);