aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2020-08-09 23:51:01 +0200
committerLinus Walleij <linus.walleij@linaro.org>2020-09-05 01:21:48 +0200
commitb7b23e4476872d80b7d70cd24e158a0505fdad5f (patch)
treecd7e72a8bdb2ed9bec4976e75692a0d90cb3cd4f /drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
parentdrm/managed: Cleanup of unused functions and polishing docs (diff)
downloadlinux-dev-b7b23e4476872d80b7d70cd24e158a0505fdad5f.tar.xz
linux-dev-b7b23e4476872d80b7d70cd24e158a0505fdad5f.zip
drm/panel: s6e63m0: Break out SPI transport
This panel can be accessed using both SPI and DSI. To make it possible to probe and use the device also from a DSI bus, first break out the SPI support to its own file. Since all the panel driver does is write DCS commands to the panel, we pass a DCS write function to probe() from each subdriver. We make the Kconfig entry for SPI mode default so all current users will continue to work. 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/384873/
Diffstat (limited to 'drivers/gpu/drm/panel/panel-samsung-s6e63m0.c')
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6e63m0.c79
1 files changed, 12 insertions, 67 deletions
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
index 2cc772fdc456..64d95201a7d4 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
@@ -16,10 +16,11 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
#include <video/mipi_display.h>
+#include "panel-samsung-s6e63m0.h"
+
/* Manufacturer Command Set */
#define MCS_ELVSS_ON 0xb1
#define MCS_MIECTL1 0xc0
@@ -33,8 +34,6 @@
#define NUM_GAMMA_LEVELS 11
#define GAMMA_TABLE_COUNT 23
-#define DATA_MASK 0x100
-
#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1)
/* array of gamma tables for gamma value 2.2 */
@@ -87,6 +86,7 @@ static u8 const s6e63m0_gamma_22[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = {
struct s6e63m0 {
struct device *dev;
+ int (*dcs_write)(struct device *dev, const u8 *data, size_t len);
struct drm_panel panel;
struct backlight_device *bl_dev;
@@ -134,42 +134,12 @@ static int s6e63m0_clear_error(struct s6e63m0 *ctx)
return ret;
}
-static int s6e63m0_spi_write_word(struct s6e63m0 *ctx, u16 data)
-{
- struct spi_device *spi = to_spi_device(ctx->dev);
- struct spi_transfer xfer = {
- .len = 2,
- .tx_buf = &data,
- };
- struct spi_message msg;
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
-
- return spi_sync(spi, &msg);
-}
-
static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len)
{
- int ret = 0;
-
if (ctx->error < 0 || len == 0)
return;
- dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data);
- ret = s6e63m0_spi_write_word(ctx, *data);
-
- while (!ret && --len) {
- ++data;
- ret = s6e63m0_spi_write_word(ctx, *data | DATA_MASK);
- }
-
- if (ret) {
- dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, (int)len, data);
- ctx->error = ret;
- }
-
- usleep_range(300, 310);
+ ctx->error = ctx->dcs_write(ctx->dev, data, len);
}
#define s6e63m0_dcs_write_seq_static(ctx, seq ...) \
@@ -429,9 +399,9 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx)
return ret;
}
-static int s6e63m0_probe(struct spi_device *spi)
+int s6e63m0_probe(struct device *dev,
+ int (*dcs_write)(struct device *dev, const u8 *data, size_t len))
{
- struct device *dev = &spi->dev;
struct s6e63m0 *ctx;
int ret;
@@ -439,7 +409,8 @@ static int s6e63m0_probe(struct spi_device *spi)
if (!ctx)
return -ENOMEM;
- spi_set_drvdata(spi, ctx);
+ ctx->dcs_write = dcs_write;
+ dev_set_drvdata(dev, ctx);
ctx->dev = dev;
ctx->enabled = false;
@@ -460,14 +431,6 @@ static int s6e63m0_probe(struct spi_device *spi)
return PTR_ERR(ctx->reset_gpio);
}
- spi->bits_per_word = 9;
- spi->mode = SPI_MODE_3;
- ret = spi_setup(spi);
- if (ret < 0) {
- dev_err(dev, "spi setup failed.\n");
- return ret;
- }
-
drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs,
DRM_MODE_CONNECTOR_DPI);
@@ -479,32 +442,14 @@ static int s6e63m0_probe(struct spi_device *spi)
return 0;
}
+EXPORT_SYMBOL_GPL(s6e63m0_probe);
-static int s6e63m0_remove(struct spi_device *spi)
+int s6e63m0_remove(struct device *dev)
{
- struct s6e63m0 *ctx = spi_get_drvdata(spi);
+ struct s6e63m0 *ctx = dev_get_drvdata(dev);
drm_panel_remove(&ctx->panel);
return 0;
}
-
-static const struct of_device_id s6e63m0_of_match[] = {
- { .compatible = "samsung,s6e63m0" },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, s6e63m0_of_match);
-
-static struct spi_driver s6e63m0_driver = {
- .probe = s6e63m0_probe,
- .remove = s6e63m0_remove,
- .driver = {
- .name = "panel-samsung-s6e63m0",
- .of_match_table = s6e63m0_of_match,
- },
-};
-module_spi_driver(s6e63m0_driver);
-
-MODULE_AUTHOR("Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>");
-MODULE_DESCRIPTION("s6e63m0 LCD Driver");
-MODULE_LICENSE("GPL v2");
+EXPORT_SYMBOL_GPL(s6e63m0_remove);