On Tue, Nov 11, 2025 at 04:13:09PM +0530, Sudarshan Shetty wrote:
> This patch adds a DRM panel driver for Waveshare MIPI-DSI panels
> of various sizes (5.0", 5.5", 7.0", 8.0", and 10.1") with integrated
> touch functionality.
> 
> The driver provides:
>  - Initialization and reset sequencing
>  - MIPI-DSI command transfer for panel setup
>  - Backlight integration through the backlight class device
>  - Support for multiple panel variants via compatible strings
> 
> These panels are commonly used with Waveshare development kits
> and require proper power sequencing and regulator support.
> 
> Signed-off-by: Sudarshan Shetty <[email protected]>
> ---
>  arch/arm64/configs/defconfig                  |    1 +
>  drivers/gpu/drm/panel/Kconfig                 |   11 +
>  drivers/gpu/drm/panel/Makefile                |    1 +
>  .../gpu/drm/panel/panel-waveshare-dsi-v2.c    | 2687 +++++++++++++++++


This was sent to the internal ML, got negative feedback and still
reached the public ML. May I ask, WHY?


Anyway, you missed the bindings for the driver.

>  4 files changed, 2700 insertions(+)
>  create mode 100644 drivers/gpu/drm/panel/panel-waveshare-dsi-v2.c
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index a1e564024be2..178c8699f86c 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1823,4 +1823,5 @@ CONFIG_CORESIGHT_STM=m
>  CONFIG_CORESIGHT_CPU_DEBUG=m
>  CONFIG_CORESIGHT_CTI=m
>  CONFIG_MEMTEST=y
> +CONFIG_DRM_PANEL_WAVESHARE_TOUCHSCREEN_V2=y
>  CONFIG_REGULATOR_WAVESHARE_TOUCHSCREEN=y

Separate commit, the entry is out of place there is no reason to build
the driver into the kernel, etc.

> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 407c5f6a268b..b771817af8f8 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -1137,6 +1137,17 @@ config DRM_PANEL_VISIONOX_VTDR6130
>         Say Y here if you want to enable support for Visionox
>         VTDR6130 1080x2400 AMOLED DSI panel.
>  
> +config DRM_PANEL_WAVESHARE_TOUCHSCREEN_V2
> +     tristate "Waveshare touchscreen panels V2"
> +     depends on DRM_MIPI_DSI
> +     depends on I2C
> +     depends on BACKLIGHT_CLASS_DEVICE
> +     help
> +       Enable support for Waveshare DSI touchscreen panels,
> +       Say Y here if you want to enable support for the Waveshare
> +       DSI Touchscreens.  To compile this driver as a module,
> +       choose M here.
> +
>  config DRM_PANEL_WIDECHIPS_WS2401
>       tristate "Widechips WS2401 DPI panel driver"
>       depends on SPI && GPIOLIB
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index 3615a761b44f..3947e28addde 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -114,5 +114,6 @@ obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += 
> panel-visionox-rm69299.o
>  obj-$(CONFIG_DRM_PANEL_VISIONOX_RM692E5) += panel-visionox-rm692e5.o
>  obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o
>  obj-$(CONFIG_DRM_PANEL_VISIONOX_R66451) += panel-visionox-r66451.o
> +obj-$(CONFIG_DRM_PANEL_WAVESHARE_TOUCHSCREEN_V2) += panel-waveshare-dsi-v2.o
>  obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o
>  obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
> diff --git a/drivers/gpu/drm/panel/panel-waveshare-dsi-v2.c 
> b/drivers/gpu/drm/panel/panel-waveshare-dsi-v2.c
> new file mode 100644
> index 000000000000..7af11fdc026f
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-waveshare-dsi-v2.c
> @@ -0,0 +1,2687 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2024 Waveshare International Limited
> + *
> + * Based on panel-raspberrypi-touchscreen by Broadcom
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_panel.h>
> +
> +#include <video/mipi_display.h>
> +
> +struct ws_panel_desc {
> +     int (*init)(struct mipi_dsi_device *dsi);
> +     const struct drm_display_mode *mode;
> +     const unsigned long mode_flags;
> +     unsigned int lanes;
> +     enum mipi_dsi_pixel_format format;
> +};
> +
> +struct ws_panel {
> +     struct drm_panel panel;
> +     struct mipi_dsi_device *dsi;
> +     const struct ws_panel_desc *desc;
> +
> +     struct regulator *power;
> +     struct gpio_desc *reset;
> +     struct gpio_desc *iovcc;
> +     struct gpio_desc *avdd;

Don't use GPIOs for regulators. Use proper regulator framework devices.

> +
> +     enum drm_panel_orientation orientation;
> +};
> +
> +enum dsi_cmd_type {
> +     INIT_DCS_CMD,
> +     DELAY_CMD,
> +};

Unused

> +
> +struct panel_init_cmd {
> +     enum dsi_cmd_type type;
> +     size_t len;
> +     const char *data;
> +};

Unused

> +
> +static int ws_panel_12_3_a_4lane_init(struct mipi_dsi_device *dsi)
> +{
> +     struct mipi_dsi_multi_context ctx = { .dsi = dsi };
> +
> +     mipi_dsi_dcs_write_seq_multi(&ctx, 0xB9, 0x83, 0x10, 0x2E);

- Please don't group panels by vendor. Panel drivers are grouped by the
  controlling IC. In this driver you've tried to stuff together several
  panels with different controllers. Instead add these to the drivers
  with the corresponding controllers. Feel free to rework existing
  drivers in order to be able to do it.

- Also, lowercase the hex.

> +     mipi_dsi_dcs_write_seq_multi(&ctx, 0xBD, 0x00);
> +     mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);

exit_sleep_mode

> +     msleep(120);

Use a proper wrapper

> +     mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);

set_display_on

> +     msleep(20);
> +
> +     return 0;

Return error code.

> +};
> +
> +static int ws_panel_10_1_a_4lane_init(struct mipi_dsi_device *dsi)
> +{
> +     struct mipi_dsi_multi_context ctx = { .dsi = dsi };
> +
> +     mipi_dsi_dcs_write_seq_multi(&ctx, 0xE0, 0x00);

As you can see, it's a completely different init sequence.

> +
> +static int ws_panel_prepare(struct drm_panel *panel)
> +{
> +     struct ws_panel *ctx = panel_to_ws(panel);
> +     int ret;
> +
> +     if (ctx->iovcc) {
> +             gpiod_set_value_cansleep(ctx->iovcc, 1);
> +             msleep(20);
> +     }
> +
> +     if (ctx->avdd) {
> +             gpiod_set_value_cansleep(ctx->avdd, 1);
> +             msleep(20);
> +     }

Yuck

> +
> +     if (ctx->reset) {
> +             gpiod_set_value_cansleep(ctx->reset, 0);
> +             msleep(60);
> +             gpiod_set_value_cansleep(ctx->reset, 1);
> +             msleep(60);
> +     }
> +
> +     ret = ctx->desc->init(ctx->dsi);
> +     if (ret < 0)
> +             dev_err(panel->dev, "failed to init panel: %d\n", ret);
> +
> +     return 0;
> +}
> +
> +static int ws_panel_unprepare(struct drm_panel *panel)
> +{
> +     struct ws_panel *ctx = panel_to_ws(panel);
> +
> +     mipi_dsi_dcs_set_display_off(ctx->dsi);
> +     mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
> +
> +     if (ctx->reset) {
> +             gpiod_set_value_cansleep(ctx->reset, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->avdd) {
> +             gpiod_set_value_cansleep(ctx->avdd, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->iovcc) {
> +             gpiod_set_value_cansleep(ctx->iovcc, 0);
> +             msleep(5);
> +     }
> +
> +     return 0;
> +}
> +
> +static const struct drm_display_mode ws_panel_12_3_a_4lane_mode = {
> +     .clock = 95000,

My preference is to define mode.clock clearly as (720 + 10 + 10 + 12)
* (1920 + 64 + 18 + 4) * 63 / 1000 (why 63 though?)

> +     .hdisplay = 720,
> +     .hsync_start = 720 + 10,
> +     .hsync_end = 720 + 10 + 10,
> +     .htotal = 720 + 10 + 10 + 12,
> +     .vdisplay = 1920,
> +     .vsync_start = 1920 + 64,
> +     .vsync_end = 1920 + 64 + 18,
> +     .vtotal = 1920 + 64 + 18 + 4,
> +     .width_mm = 109,
> +     .height_mm = 292,
> +};
> +
> +static const struct drm_display_mode ws_panel_10_1_a_mode = {
> +     .clock = 70000,
> +     .hdisplay = 800,
> +     .hsync_start = 800 + 40,
> +     .hsync_end = 800 + 40 + 20,
> +     .htotal = 800 + 40 + 20 + 20,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 20,
> +     .vsync_end = 1280 + 20 + 20,
> +     .vtotal = 1280 + 20 + 20 + 4,
> +     .width_mm = 135,
> +     .height_mm = 216,
> +};
> +
> +static const struct drm_display_mode ws_panel_10_1_b_4lane_mode = {
> +     .clock = 66000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 60,
> +     .hsync_end = 720 + 60 + 60,
> +     .htotal = 720 + 60 + 60 + 4,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 16,
> +     .vsync_end = 1280 + 16 + 12,
> +     .vtotal = 1280 + 16 + 12 + 4,
> +     .width_mm = 125,
> +     .height_mm = 222,
> +};
> +
> +static const struct drm_display_mode ws_panel_10_1_b_mode = {
> +     .clock = 69000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 50,
> +     .hsync_end = 720 + 50 + 50,
> +     .htotal = 720 + 50 + 50 + 50,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 26,
> +     .vsync_end = 1280 + 26 + 12,
> +     .vtotal = 1280 + 26 + 12 + 4,
> +     .width_mm = 125,
> +     .height_mm = 222,
> +};
> +
> +static const struct drm_display_mode ws_panel_9_b_4lane_mode = {
> +     .clock = 66000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 60,
> +     .hsync_end = 720 + 60 + 60,
> +     .htotal = 720 + 60 + 60 + 4,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 16,
> +     .vsync_end = 1280 + 16 + 12,
> +     .vtotal = 1280 + 16 + 12 + 4,
> +     .width_mm = 114,
> +     .height_mm = 196,
> +};
> +
> +static const struct drm_display_mode ws_panel_9_b_mode = {
> +     .clock = 69000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 50,
> +     .hsync_end = 720 + 50 + 50,
> +     .htotal = 720 + 50 + 50 + 50,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 26,
> +     .vsync_end = 1280 + 26 + 12,
> +     .vtotal = 1280 + 26 + 12 + 4,
> +     .width_mm = 114,
> +     .height_mm = 196,
> +};
> +
> +static const struct drm_display_mode ws_panel_8_8_a_mode = {
> +     .clock = 75000,
> +     .hdisplay = 480,
> +     .hsync_start = 480 + 50,
> +     .hsync_end = 480 + 50 + 50,
> +     .htotal = 480 + 50 + 50 + 50,
> +     .vdisplay = 1920,
> +     .vsync_start = 1920 + 20,
> +     .vsync_end = 1920 + 20 + 20,
> +     .vtotal = 1920 + 20 + 20 + 20,
> +     .width_mm = 68,
> +     .height_mm = 219,
> +};
> +
> +static const struct drm_display_mode ws_panel_8_a_mode = {
> +     .clock = 70000,
> +     .hdisplay = 800,
> +     .hsync_start = 800 + 40,
> +     .hsync_end = 800 + 40 + 20,
> +     .htotal = 800 + 40 + 20 + 20,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 30,
> +     .vsync_end = 1280 + 30 + 12,
> +     .vtotal = 1280 + 30 + 12 + 4,
> +     .width_mm = 107,
> +     .height_mm = 172,
> +};
> +
> +static const struct drm_display_mode ws_panel_7_a_mode = {
> +     .clock = 83333,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 120,
> +     .hsync_end = 720 + 120 + 100,
> +     .htotal = 720 + 120 + 100 + 100,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 10,
> +     .vsync_end = 1280 + 10 + 10,
> +     .vtotal = 1280 + 10 + 10 + 10,
> +     .width_mm = 85,
> +     .height_mm = 154,
> +};
> +
> +static const struct drm_display_mode ws_panel_5_5_a_mode = {
> +     .clock = 65000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 50,
> +     .hsync_end = 720 + 50 + 50,
> +     .htotal = 720 + 50 + 50 + 10,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 15,
> +     .vsync_end = 1280 + 15 + 12,
> +     .vtotal = 1280 + 15 + 12 + 4,
> +     .width_mm = 62,
> +     .height_mm = 110,
> +};
> +
> +static const struct drm_display_mode ws_panel_5_a_mode = {
> +     .clock = 70000,
> +     .hdisplay = 720,
> +     .hsync_start = 720 + 40,
> +     .hsync_end = 720 + 40 + 20,
> +     .htotal = 720 + 40 + 20 + 20,
> +     .vdisplay = 1280,
> +     .vsync_start = 1280 + 30,
> +     .vsync_end = 1280 + 30 + 10,
> +     .vtotal = 1280 + 30 + 10 + 4,
> +     .width_mm = 62,
> +     .height_mm = 110,
> +};
> +
> +static const struct drm_display_mode ws_panel_4_c_mode = {
> +     .clock       = 36500,
> +     .hdisplay    = 720,
> +     .hsync_start = 720 + 40,
> +     .hsync_end   = 720 + 40 + 20,
> +     .htotal      = 720 + 40 + 20 + 20,
> +     .vdisplay    = 720,
> +     .vsync_start = 720 + 24,
> +     .vsync_end   = 720 + 24 + 4,
> +     .vtotal      = 720 + 24 + 4 + 12,
> +     .width_mm        = 88,
> +     .height_mm       = 88,
> +};
> +
> +static const struct drm_display_mode ws_panel_3_4_c_mode = {
> +     .clock       = 44300,
> +     .hdisplay    = 800,
> +     .hsync_start = 800 + 40,
> +     .hsync_end   = 800 + 40 + 20,
> +     .htotal      = 800 + 40 + 20 + 20,
> +     .vdisplay    = 800,
> +     .vsync_start = 800 + 24,
> +     .vsync_end   = 800 + 24 + 4,
> +     .vtotal      = 800 + 24 + 4 + 12,
> +     .width_mm        = 88,
> +     .height_mm       = 88,
> +};
> +
> +static int ws_panel_get_modes(struct drm_panel *panel,
> +                           struct drm_connector *connector)
> +{
> +     struct ws_panel *ctx = panel_to_ws(panel);
> +     struct drm_display_mode *mode;
> +
> +     mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
> +     if (!mode) {
> +             dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",
> +                     ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
> +                     drm_mode_vrefresh(ctx->desc->mode));
> +             return -ENOMEM;
> +     }
> +
> +     drm_mode_set_name(mode);
> +
> +     mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> +     drm_mode_probed_add(connector, mode);
> +
> +     connector->display_info.width_mm = mode->width_mm;
> +     connector->display_info.height_mm = mode->height_mm;

drm_connector_helper_get_modes_fixed()

> +
> +     drm_connector_set_panel_orientation(connector, ctx->orientation);
> +
> +     return 1;
> +}
> +
> +static enum drm_panel_orientation
> +ws_panel_get_orientation(struct drm_panel *panel)
> +{
> +     struct ws_panel *ctx = panel_to_ws(panel);
> +
> +     return ctx->orientation;
> +}
> +
> +static const struct drm_panel_funcs ws_panel_funcs = {
> +     .prepare = ws_panel_prepare,
> +     .unprepare = ws_panel_unprepare,
> +     .get_modes = ws_panel_get_modes,
> +     .get_orientation = ws_panel_get_orientation,
> +};
> +
> +static int ws_panel_dsi_probe(struct mipi_dsi_device *dsi)
> +{
> +     struct ws_panel *ctx;
> +     int ret;
> +
> +     dev_info(&dsi->dev, "dsi panel: %s\n",
> +              (char *)of_get_property(
> +                      dsi->dev.of_node, "compatible", NULL));
> +
> +     ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL);
> +     if (!ctx)
> +             return -ENOMEM;
> +     mipi_dsi_set_drvdata(dsi, ctx);
> +     ctx->dsi = dsi;
> +     ctx->desc = of_device_get_match_data(&dsi->dev);
> +
> +     ctx->panel.prepare_prev_first = true;
> +     drm_panel_init(&ctx->panel, &dsi->dev, &ws_panel_funcs,
> +                    DRM_MODE_CONNECTOR_DSI);
> +
> +     ctx->reset = devm_gpiod_get_optional(
> +                     &dsi->dev, "reset", GPIOD_OUT_LOW);
> +     if (IS_ERR(ctx->reset))
> +             return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset),
> +                                  "Couldn't get our reset GPIO\n");
> +
> +     ctx->iovcc = devm_gpiod_get_optional(
> +                     &dsi->dev, "iovcc", GPIOD_OUT_LOW);
> +     if (IS_ERR(ctx->iovcc))
> +             return dev_err_probe(&dsi->dev, PTR_ERR(ctx->iovcc),
> +                                     "Couldn't get our iovcc GPIO\n");
> +
> +     ctx->avdd = devm_gpiod_get_optional(&dsi->dev, "avdd", GPIOD_OUT_LOW);
> +     if (IS_ERR(ctx->avdd))
> +             return dev_err_probe(&dsi->dev, PTR_ERR(ctx->avdd),
> +                                     "Couldn't get our avdd GPIO\n");
> +
> +     ret = of_drm_get_panel_orientation(
> +                     dsi->dev.of_node, &ctx->orientation);
> +     if (ret) {
> +             dev_err(&dsi->dev, "%pOF: failed to get orientation: %d\n",
> +                     dsi->dev.of_node, ret);
> +             return ret;
> +     }
> +
> +     ret = drm_panel_of_backlight(&ctx->panel);
> +     if (ret)
> +             return ret;
> +
> +     drm_panel_add(&ctx->panel);
> +
> +     dsi->mode_flags = ctx->desc->mode_flags;
> +     dsi->format = ctx->desc->format;
> +     dsi->lanes = ctx->desc->lanes;
> +     dev_info(&dsi->dev, "lanes: %d\n", dsi->lanes);
> +
> +     ret = mipi_dsi_attach(dsi);
> +     if (ret)
> +             drm_panel_remove(&ctx->panel);
> +
> +     return ret;
> +}
> +
> +static void ws_panel_dsi_remove(struct mipi_dsi_device *dsi)
> +{
> +     struct ws_panel *ctx = mipi_dsi_get_drvdata(dsi);
> +
> +     mipi_dsi_detach(dsi);
> +     drm_panel_remove(&ctx->panel);
> +     if (ctx->reset) {
> +             gpiod_set_value_cansleep(ctx->reset, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->avdd) {
> +             gpiod_set_value_cansleep(ctx->avdd, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->iovcc) {
> +             gpiod_set_value_cansleep(ctx->iovcc, 0);
> +             msleep(5);
> +     }
> +}
> +
> +static void ws_panel_dsi_shutdown(struct mipi_dsi_device *dsi)
> +{
> +     struct ws_panel *ctx = mipi_dsi_get_drvdata(dsi);
> +
> +     if (ctx->reset) {
> +             dev_info(&dsi->dev, "shutdown\n");
> +             gpiod_set_value_cansleep(ctx->reset, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->avdd) {
> +             gpiod_set_value_cansleep(ctx->avdd, 0);
> +             msleep(5);
> +     }
> +
> +     if (ctx->iovcc) {
> +             gpiod_set_value_cansleep(ctx->iovcc, 0);
> +             msleep(5);
> +     }
> +}
> +
> +static const struct ws_panel_desc ws_panel_12_3_inch_a_4lane_desc = {
> +     .init = ws_panel_12_3_a_4lane_init,
> +     .mode = &ws_panel_12_3_a_4lane_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 4,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_10_1_inch_a_4lane_desc = {
> +     .init = ws_panel_10_1_a_4lane_init,
> +     .mode = &ws_panel_10_1_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 4,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_10_1_inch_a_desc = {
> +     .init = ws_panel_10_1_a_init,
> +     .mode = &ws_panel_10_1_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_10_1_inch_b_4lane_desc = {
> +     .init = ws_panel_10_1_b_4lane_init,
> +     .mode = &ws_panel_10_1_b_4lane_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 4,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_10_1_inch_b_desc = {
> +     .init = ws_panel_10_1_b_init,
> +     .mode = &ws_panel_10_1_b_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_9_inch_b_4lane_desc = {
> +     .init = ws_panel_10_1_b_4lane_init,
> +     .mode = &ws_panel_9_b_4lane_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 4,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_9_inch_b_desc = {
> +     .init = ws_panel_10_1_b_init,
> +     .mode = &ws_panel_9_b_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_8_8_inch_a_desc = {
> +     .init = ws_panel_8_8_a_init,
> +     .mode = &ws_panel_8_8_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_8_inch_a_4lane_desc = {
> +     .init = ws_panel_8_a_4lane_init,
> +     .mode = &ws_panel_8_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 4,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_8_inch_a_desc = {
> +     .init = ws_panel_8_a_init,
> +     .mode = &ws_panel_8_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_7_inch_a_desc = {
> +     .init = ws_panel_7_a_init,
> +     .mode = &ws_panel_7_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_5_5_inch_a_desc = {
> +     .init = ws_panel_5_5_a_init,
> +     .mode = &ws_panel_5_5_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_5_inch_a_desc = {
> +     .init = ws_panel_5_a_init,
> +     .mode = &ws_panel_5_a_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_4_inch_c_desc = {
> +     .init = ws_panel_4_c_init,
> +     .mode = &ws_panel_4_c_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct ws_panel_desc ws_panel_3_4_inch_c_desc = {
> +     .init = ws_panel_3_4_c_init,
> +     .mode = &ws_panel_3_4_c_mode,
> +     .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
> +                   MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
> +     .lanes = 2,
> +     .format = MIPI_DSI_FMT_RGB888,
> +};
> +
> +static const struct of_device_id ws_panel_of_match[] = {
> +     { .compatible = "waveshare,12.3-dsi-touch-a,4lane",
> +       &ws_panel_12_3_inch_a_4lane_desc },
> +     { .compatible = "waveshare,10.1-dsi-touch-a-4lane",
> +       &ws_panel_10_1_inch_a_4lane_desc },
> +     { .compatible = "waveshare,10.1-dsi-touch-a",

Is it the same panel but connected differently? Or are those two
different panels?

The same question applies to several other panels here.

> +       &ws_panel_10_1_inch_a_desc },
> +     { .compatible = "waveshare,10.1-dsi-touch-b,4lane",
> +       &ws_panel_10_1_inch_b_4lane_desc },
> +     { .compatible = "waveshare,10.1-dsi-touch-b",
> +       &ws_panel_10_1_inch_b_desc },
> +     { .compatible = "waveshare,9.0-dsi-touch-b,4lane",
> +       &ws_panel_9_inch_b_4lane_desc },
> +     { .compatible = "waveshare,9.0-dsi-touch-b",
> +       &ws_panel_9_inch_b_desc },
> +     { .compatible = "waveshare,8.8-dsi-touch-a",
> +       &ws_panel_8_8_inch_a_desc },
> +     { .compatible = "waveshare,8.0-dsi-touch-a-4lane",
> +       &ws_panel_8_inch_a_4lane_desc },
> +     { .compatible = "waveshare,8.0-dsi-touch-a", &ws_panel_8_inch_a_desc },
> +     { .compatible = "waveshare,7.0-dsi-touch-a", &ws_panel_7_inch_a_desc },
> +     { .compatible = "waveshare,7.0-dsi-touch-b", &ws_panel_7_inch_a_desc },
> +     { .compatible = "waveshare,5.5-dsi-touch-a",
> +       &ws_panel_5_5_inch_a_desc },
> +     { .compatible = "waveshare,5.0-dsi-touch-a", &ws_panel_5_inch_a_desc },
> +     { .compatible = "waveshare,4.0-dsi-touch-c", &ws_panel_4_inch_c_desc },
> +     { .compatible = "waveshare,3.4-dsi-touch-c",
> +             &ws_panel_3_4_inch_c_desc },
> +     {}
> +};
> +MODULE_DEVICE_TABLE(of, ws_panel_of_match);
> +
> +static struct mipi_dsi_driver ws_panel_dsi_driver = {
> +     .probe          = ws_panel_dsi_probe,
> +     .remove         = ws_panel_dsi_remove,
> +     .shutdown       = ws_panel_dsi_shutdown,
> +     .driver = {
> +             .name           = "waveshare-dsi",
> +             .of_match_table = ws_panel_of_match,
> +     },
> +};
> +module_mipi_dsi_driver(ws_panel_dsi_driver);
> +
> +MODULE_AUTHOR("Waveshare Team <[email protected]>");
> +MODULE_DESCRIPTION("Waveshare DSI panel driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

Reply via email to