[PATCH v4] drm/panel: db7430: Add driver for Samsung DB7430

Noralf Trønnes noralf at tronnes.org
Thu Jun 10 16:15:08 UTC 2021



Den 10.06.2021 15.25, skrev Linus Walleij:
> This adds a new driver for the Samsung DB7430 DPI display
> controller as controlled over SPI.
> 
> Right now the only panel product we know that is using this
> display controller is the LMS397KF04 but there may be more.
> 
> This is the first regular panel driver making use of the
> MIPI DBI helper library. The DBI "device" portions can not
> be used because that code assumes the use of a single
> regulator and specific timings around the reset pulse that
> do not match the DB7430 datasheet.
> 
> Cc: Noralf Trønnes <noralf at tronnes.org>
> Cc: Paul Cercueil <paul at crapouillou.net>
> Cc: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v3->v4:
> - Managed to make use of the in-kernel DBI support to
>   conjure and send 9bit DBI SPI messages.

When I moved the DBI code out of tinydrm I split it up into an interface
part and a framebuffer part so panel drivers could use the interface
part like you have done here.

> - This cuts out a bit of overhead.
> - Deeper integration with the DBI library is not done, as
>   assumes too much about the device, such as being used
>   as a stand-alone framebuffer (this device is not).

> diff --git a/drivers/gpu/drm/panel/panel-samsung-db7430.c b/drivers/gpu/drm/panel/panel-samsung-db7430.c
> new file mode 100644
> index 000000000000..c11b3da65896
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-samsung-db7430.c

> +/**
> + * struct db7430 - state container for a panel controlled by the DB7430
> + * controller
> + */
> +struct db7430 {
> +	/** @dev: the container device */
> +	struct device *dev;
> +	/** @dbi: the DBI bus abstraction handle */
> +	struct mipi_dbi dbi;
> +	/** @panel: the DRM panel instance for this device */
> +	struct drm_panel panel;
> +	/** @width: the width of this panel in mm */
> +	u32 width;
> +	/** @height: the height of this panel in mm */
> +	u32 height;
> +	/** @reset: reset GPIO line */
> +	struct gpio_desc *reset;

You can use dbi->reset.

> +	/** @regulators: VCCIO and VIO supply regulators */
> +	struct regulator_bulk_data regulators[2];
> +};

> +static int db7430_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct db7430 *db;
> +	int ret;
> +
> +	db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL);
> +	if (!db)
> +		return -ENOMEM;
> +	db->dev = dev;
> +
> +	/*
> +	 * VCI   is the analog voltage supply
> +	 * VCCIO is the digital I/O voltage supply
> +	 */
> +	db->regulators[0].supply = "vci";
> +	db->regulators[1].supply = "vccio";
> +	ret = devm_regulator_bulk_get(dev,
> +				      ARRAY_SIZE(db->regulators),
> +				      db->regulators);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to get regulators\n");
> +
> +	db->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> +	if (IS_ERR(db->reset)) {
> +		ret = PTR_ERR(db->reset);
> +		return dev_err_probe(dev, ret, "no RESET GPIO\n");
> +	}
> +
> +	spi->bits_per_word = 9;

Do you need to set this? The DBI helper sets it on the SPI transfer if
the SPI controller supports 9-bit or uses emulation code if not.

> +	/* Preserve e.g. SPI_3WIRE setting */
> +	spi->mode |= SPI_MODE_3;

You can use the DT properties 'spi-cpha' and 'spi-cpol' to set this.

> +	ret = spi_setup(spi);

So I don't think you need to call spi_setup() here.

This code as-is will fail on a SPI controller that doesn't support 9
bits per word, and the emulation code in the DBI helper won't be utilised.

With the comments considered:

Acked-by: Noralf Trønnes <noralf at tronnes.org>

Noralf.

> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "spi setup failed\n");
> +
> +	ret = mipi_dbi_spi_init(spi, &db->dbi, NULL);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "MIPI DBI init failed\n");
> +
> +	drm_panel_init(&db->panel, dev, &db7430_drm_funcs,
> +		       DRM_MODE_CONNECTOR_DPI);
> +
> +	/* FIXME: if no external backlight, use internal backlight */
> +	ret = drm_panel_of_backlight(&db->panel);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to add backlight\n");
> +
> +	spi_set_drvdata(spi, db);
> +
> +	drm_panel_add(&db->panel);
> +	dev_dbg(dev, "added panel\n");
> +
> +	return 0;
> +}


More information about the dri-devel mailing list