Commit 91867ac7 authored by Linus Walleij's avatar Linus Walleij

drm/panel: s6e63m0: Add reading functionality

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarStephan Gerhold <stephan@gerhold.net>
Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
Acked-by: default avatarPaul Cercueil <paul@crapouillou.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20200809215104.1830206-4-linus.walleij@linaro.org
parent 435e06c0
...@@ -16,6 +16,22 @@ ...@@ -16,6 +16,22 @@
#define MCS_GLOBAL_PARAM 0xb0 #define MCS_GLOBAL_PARAM 0xb0
#define S6E63M0_DSI_MAX_CHUNK 15 /* CMD + 15 bytes max */ #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) 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); struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
...@@ -90,7 +106,8 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi) ...@@ -90,7 +106,8 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi)
MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_EOT_PACKET |
MIPI_DSI_MODE_VIDEO_BURST; 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) if (ret)
return ret; return ret;
......
...@@ -11,6 +11,17 @@ ...@@ -11,6 +11,17 @@
#define DATA_MASK 0x100 #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) static int s6e63m0_spi_write_word(struct device *dev, u16 data)
{ {
struct spi_device *spi = to_spi_device(dev); struct spi_device *spi = to_spi_device(dev);
...@@ -60,7 +71,8 @@ static int s6e63m0_spi_probe(struct spi_device *spi) ...@@ -60,7 +71,8 @@ static int s6e63m0_spi_probe(struct spi_device *spi)
DRM_DEV_ERROR(dev, "spi setup failed.\n"); DRM_DEV_ERROR(dev, "spi setup failed.\n");
return ret; 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) static int s6e63m0_spi_remove(struct spi_device *spi)
......
...@@ -86,6 +86,7 @@ static u8 const s6e63m0_gamma_22[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = { ...@@ -86,6 +86,7 @@ static u8 const s6e63m0_gamma_22[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = {
struct s6e63m0 { struct s6e63m0 {
struct device *dev; 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); int (*dcs_write)(struct device *dev, const u8 *data, size_t len);
struct drm_panel panel; struct drm_panel panel;
struct backlight_device *bl_dev; struct backlight_device *bl_dev;
...@@ -134,6 +135,14 @@ static int s6e63m0_clear_error(struct s6e63m0 *ctx) ...@@ -134,6 +135,14 @@ static int s6e63m0_clear_error(struct s6e63m0 *ctx)
return ret; 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) static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len)
{ {
if (ctx->error < 0 || len == 0) if (ctx->error < 0 || len == 0)
...@@ -400,6 +409,7 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx) ...@@ -400,6 +409,7 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx)
} }
int s6e63m0_probe(struct device *dev, 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), int (*dcs_write)(struct device *dev, const u8 *data, size_t len),
bool dsi_mode) bool dsi_mode)
{ {
...@@ -410,6 +420,7 @@ int s6e63m0_probe(struct device *dev, ...@@ -410,6 +420,7 @@ int s6e63m0_probe(struct device *dev,
if (!ctx) if (!ctx)
return -ENOMEM; return -ENOMEM;
ctx->dcs_read = dcs_read;
ctx->dcs_write = dcs_write; ctx->dcs_write = dcs_write;
dev_set_drvdata(dev, ctx); dev_set_drvdata(dev, ctx);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#define _PANEL_SAMSUNG_S6E63M0_H #define _PANEL_SAMSUNG_S6E63M0_H
int s6e63m0_probe(struct device *dev, 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, int (*dcs_write)(struct device *dev, const u8 *data,
size_t len), size_t len),
bool dsi_mode); bool dsi_mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment