OSDN Git Service

drm/panel: s6e63m0: Add reading functionality
authorLinus Walleij <linus.walleij@linaro.org>
Sun, 9 Aug 2020 21:51:03 +0000 (23:51 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 4 Sep 2020 23:24:26 +0000 (01:24 +0200)
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.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Stephan Gerhold <stephan@gerhold.net>
Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
Acked-by: Paul Cercueil <paul@crapouillou.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20200809215104.1830206-4-linus.walleij@linaro.org
drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c
drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
drivers/gpu/drm/panel/panel-samsung-s6e63m0.h

index f4927a6..2ec9e79 100644 (file)
 #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;
 
index 0587eac..3b1a2a3 100644 (file)
 
 #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)
index 260c516..c53706e 100644 (file)
@@ -86,6 +86,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;
@@ -134,6 +135,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)
@@ -400,6 +409,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)
 {
@@ -410,6 +420,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);
 
index 229e23b..c669fec 100644 (file)
@@ -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);