From: Linus Walleij Date: Mon, 14 Jun 2021 18:11:35 +0000 (+0200) Subject: drm/panel: s6e63m0: Switch to DBI abstraction for SPI X-Git-Tag: v5.15~303^2~28^2~173 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c2a61865baa45b5d1dfc3e83da50bcd51d518786;p=platform%2Fkernel%2Flinux-starfive.git drm/panel: s6e63m0: Switch to DBI abstraction for SPI The SPI access to s6e63m0 is using the DBI protocol, so switch to using the elaborate DBI protocol implementation in the DRM DBI helper library. Acked-by: Noralf Trønnes Reviewed-by: Douglas Anderson Signed-off-by: Linus Walleij Link: https://patchwork.freedesktop.org/patch/msgid/20210614181135.1124445-2-linus.walleij@linaro.org --- diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 7c32b04..09acd18 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -388,6 +388,7 @@ config DRM_PANEL_SAMSUNG_S6E63M0_SPI depends on SPI depends on DRM_PANEL_SAMSUNG_S6E63M0 default DRM_PANEL_SAMSUNG_S6E63M0 + select DRM_MIPI_DBI help Say Y here if you want to be able to access the Samsung S6E63M0 panel using SPI. diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c index 07a48f62..e0b1a7e 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c @@ -16,7 +16,8 @@ #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) +static int s6e63m0_dsi_dcs_read(struct device *dev, void *trsp, + const u8 cmd, u8 *data) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); int ret; @@ -32,7 +33,8 @@ static int s6e63m0_dsi_dcs_read(struct device *dev, const u8 cmd, u8 *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, void *trsp, + const u8 *data, size_t len) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); const u8 *seqp = data; @@ -99,8 +101,8 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_read, s6e63m0_dsi_dcs_write, - true); + ret = s6e63m0_probe(dev, NULL, 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 326deb3..3669cc3 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c @@ -5,62 +5,38 @@ #include #include +#include #include #include "panel-samsung-s6e63m0.h" -#define DATA_MASK 0x100 +static const u8 s6e63m0_dbi_read_commands[] = { + MCS_READ_ID1, + MCS_READ_ID2, + MCS_READ_ID3, + 0, /* sentinel */ +}; -static int s6e63m0_spi_dcs_read(struct device *dev, const u8 cmd, u8 *data) +static int s6e63m0_spi_dcs_read(struct device *dev, void *trsp, + const u8 cmd, u8 *data) { - struct spi_device *spi = to_spi_device(dev); - u16 buf[1]; - u16 rbuf[1]; + struct mipi_dbi *dbi = trsp; int ret; - /* SPI buffers are always in CPU order */ - buf[0] = (u16)cmd; - ret = spi_write_then_read(spi, buf, 2, rbuf, 2); - dev_dbg(dev, "READ CMD: %04x RET: %04x\n", buf[0], rbuf[0]); - if (!ret) - /* These high 8 bits of the 9 contains the readout */ - *data = (rbuf[0] & 0x1ff) >> 1; + ret = mipi_dbi_command_read(dbi, cmd, data); + if (ret) + dev_err(dev, "error on DBI read command %02x\n", cmd); return ret; } -static int s6e63m0_spi_write_word(struct device *dev, u16 data) -{ - struct spi_device *spi = to_spi_device(dev); - - /* SPI buffers are always in CPU order */ - return spi_write(spi, &data, 2); -} - -static int s6e63m0_spi_dcs_write(struct device *dev, const u8 *data, size_t len) +static int s6e63m0_spi_dcs_write(struct device *dev, void *trsp, + const u8 *data, size_t len) { - int ret = 0; - - dev_dbg(dev, "SPI writing dcs seq: %*ph\n", (int)len, data); - - /* - * This sends 9 bits with the first bit (bit 8) set to 0 - * This indicates that this is a command. Anything after the - * command is data. - */ - ret = s6e63m0_spi_write_word(dev, *data); - - while (!ret && --len) { - ++data; - /* This sends 9 bits with the first bit (bit 8) set to 1 */ - ret = s6e63m0_spi_write_word(dev, *data | DATA_MASK); - } - - if (ret) { - dev_err(dev, "SPI error %d writing dcs seq: %*ph\n", ret, - (int)len, data); - } + struct mipi_dbi *dbi = trsp; + int ret; + ret = mipi_dbi_command_stackbuf(dbi, data[0], (data + 1), (len - 1)); usleep_range(300, 310); return ret; @@ -69,18 +45,21 @@ static int s6e63m0_spi_dcs_write(struct device *dev, const u8 *data, size_t len) static int s6e63m0_spi_probe(struct spi_device *spi) { struct device *dev = &spi->dev; + struct mipi_dbi *dbi; int ret; - spi->bits_per_word = 9; - /* Preserve e.g. SPI_3WIRE setting */ - spi->mode |= SPI_MODE_3; - ret = spi_setup(spi); - if (ret < 0) { - dev_err(dev, "spi setup failed.\n"); - return ret; - } - return s6e63m0_probe(dev, s6e63m0_spi_dcs_read, s6e63m0_spi_dcs_write, - false); + dbi = devm_kzalloc(dev, sizeof(*dbi), GFP_KERNEL); + if (!dbi) + return -ENOMEM; + + ret = mipi_dbi_spi_init(spi, dbi, NULL); + if (ret) + return dev_err_probe(dev, ret, "MIPI DBI init failed\n"); + /* Register our custom MCS read commands */ + dbi->read_commands = s6e63m0_dbi_read_commands; + + return s6e63m0_probe(dev, dbi, 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 603c5df..35d72ac 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c @@ -22,31 +22,6 @@ #include "panel-samsung-s6e63m0.h" -/* Manufacturer Command Set */ -#define MCS_ELVSS_ON 0xb1 -#define MCS_TEMP_SWIRE 0xb2 -#define MCS_PENTILE_1 0xb3 -#define MCS_PENTILE_2 0xb4 -#define MCS_GAMMA_DELTA_Y_RED 0xb5 -#define MCS_GAMMA_DELTA_X_RED 0xb6 -#define MCS_GAMMA_DELTA_Y_GREEN 0xb7 -#define MCS_GAMMA_DELTA_X_GREEN 0xb8 -#define MCS_GAMMA_DELTA_Y_BLUE 0xb9 -#define MCS_GAMMA_DELTA_X_BLUE 0xba -#define MCS_MIECTL1 0xc0 -#define MCS_BCMODE 0xc1 -#define MCS_ERROR_CHECK 0xd5 -#define MCS_READ_ID1 0xda -#define MCS_READ_ID2 0xdb -#define MCS_READ_ID3 0xdc -#define MCS_LEVEL_2_KEY 0xf0 -#define MCS_MTP_KEY 0xf1 -#define MCS_DISCTL 0xf2 -#define MCS_SRCCTL 0xf6 -#define MCS_IFCTL 0xf7 -#define MCS_PANELCTL 0xf8 -#define MCS_PGAMMACTL 0xfa - #define S6E63M0_LCD_ID_VALUE_M2 0xA4 #define S6E63M0_LCD_ID_VALUE_SM2 0xB4 #define S6E63M0_LCD_ID_VALUE_SM2_1 0xB6 @@ -283,8 +258,9 @@ static u8 const s6e63m0_elvss_per_gamma[NUM_GAMMA_LEVELS] = { 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); + void *transport_data; + int (*dcs_read)(struct device *dev, void *trsp, const u8 cmd, u8 *val); + int (*dcs_write)(struct device *dev, void *trsp, const u8 *data, size_t len); struct drm_panel panel; struct backlight_device *bl_dev; u8 lcd_type; @@ -340,7 +316,7 @@ 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); + ctx->error = ctx->dcs_read(ctx->dev, ctx->transport_data, cmd, data); } static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len) @@ -348,7 +324,7 @@ static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len) if (ctx->error < 0 || len == 0) return; - ctx->error = ctx->dcs_write(ctx->dev, data, len); + ctx->error = ctx->dcs_write(ctx->dev, ctx->transport_data, data, len); } #define s6e63m0_dcs_write_seq_static(ctx, seq ...) \ @@ -713,9 +689,9 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx, u32 max_brightness) return ret; } -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 s6e63m0_probe(struct device *dev, void *trsp, + int (*dcs_read)(struct device *dev, void *trsp, const u8 cmd, u8 *val), + int (*dcs_write)(struct device *dev, void *trsp, const u8 *data, size_t len), bool dsi_mode) { struct s6e63m0 *ctx; @@ -726,6 +702,7 @@ int s6e63m0_probe(struct device *dev, if (!ctx) return -ENOMEM; + ctx->transport_data = trsp; ctx->dsi_mode = dsi_mode; ctx->dcs_read = dcs_read; ctx->dcs_write = dcs_write; diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h index c669fec..306605e 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h @@ -3,9 +3,36 @@ #ifndef _PANEL_SAMSUNG_S6E63M0_H #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, +/* Manufacturer Command Set */ +#define MCS_ELVSS_ON 0xb1 +#define MCS_TEMP_SWIRE 0xb2 +#define MCS_PENTILE_1 0xb3 +#define MCS_PENTILE_2 0xb4 +#define MCS_GAMMA_DELTA_Y_RED 0xb5 +#define MCS_GAMMA_DELTA_X_RED 0xb6 +#define MCS_GAMMA_DELTA_Y_GREEN 0xb7 +#define MCS_GAMMA_DELTA_X_GREEN 0xb8 +#define MCS_GAMMA_DELTA_Y_BLUE 0xb9 +#define MCS_GAMMA_DELTA_X_BLUE 0xba +#define MCS_MIECTL1 0xc0 +#define MCS_BCMODE 0xc1 +#define MCS_ERROR_CHECK 0xd5 +#define MCS_READ_ID1 0xda +#define MCS_READ_ID2 0xdb +#define MCS_READ_ID3 0xdc +#define MCS_LEVEL_2_KEY 0xf0 +#define MCS_MTP_KEY 0xf1 +#define MCS_DISCTL 0xf2 +#define MCS_SRCCTL 0xf6 +#define MCS_IFCTL 0xf7 +#define MCS_PANELCTL 0xf8 +#define MCS_PGAMMACTL 0xfa + +int s6e63m0_probe(struct device *dev, void *trsp, + int (*dcs_read)(struct device *dev, void *trsp, + const u8 cmd, u8 *val), + int (*dcs_write)(struct device *dev, void *trsp, + const u8 *data, size_t len), bool dsi_mode); int s6e63m0_remove(struct device *dev);