[PATCH 5/5] video: add support for MIPI DBI interface

John Watts contact at jookia.org
Fri Jun 14 14:18:45 CEST 2024


This interface supports sending MIPI commands over an SPI bus.
This driver only implements the Type C1 protocol for now.

Signed-off-by: John Watts <contact at jookia.org>
---
 drivers/video/Kconfig    |  6 ++++
 drivers/video/Makefile   |  1 +
 drivers/video/mipi_dbi.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
 include/mipi_dbi.h       | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 150 insertions(+)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7808ae7919..e9d069d440 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -157,6 +157,12 @@ config VIDEO_MIPI_DSI
 	  The MIPI Display Serial Interface (MIPI DSI) defines a high-speed
 	  serial interface between a host processor and a display module.
 
+config VIDEO_MIPI_DBI
+	bool "Support MIPI DBI interface"
+	help
+	  Support MIPI DBI interface for driving a MIPI compatible device
+	  over a SPI interface.
+
 config CONSOLE_NORMAL
 	bool "Support a simple text console"
 	default y
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index f3f70cd04a..ad77c60973 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o
 obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o
 obj-${CONFIG_VIDEO_MESON} += meson/
 obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o
+obj-${CONFIG_VIDEO_MIPI_DBI} += mipi_dbi.o
 obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o
 obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o
 obj-$(CONFIG_VIDEO_NX) += nexell_display.o videomodes.o nexell/
diff --git a/drivers/video/mipi_dbi.c b/drivers/video/mipi_dbi.c
new file mode 100644
index 0000000000..d7457bb6e2
--- /dev/null
+++ b/drivers/video/mipi_dbi.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MIPI DBI Bus support
+ *
+ * Copyright 2024 John Watts <contact at jookia.org>
+ */
+
+#include <mipi_dbi.h>
+
+int mipi_dbi_spi_init(struct spi_slave *slave, struct mipi_dbi *dbi,
+		      struct gpio_desc *dc)
+{
+	/* D/C GPIO isn't supported yet */
+	if (dc)
+		return -1;
+
+	dbi->spi = slave;
+
+	return 0;
+}
+
+int mipi_dbi_xfer(struct mipi_dbi *dbi, u8 data, int pos, int len)
+{
+	struct spi_slave *spi = dbi->spi;
+	bool is_data = (pos != 0);
+	int flags = 0;
+	u8 buf[2];
+
+	/* Mimic Linux's behaviour of pulling CS active each word */
+	flags |= SPI_XFER_ONCE;
+
+	buf[0] = (is_data ? 0x80 : 0x00) | (data >> 1);
+	buf[1] = ((data & 0x1) << 7);
+
+	return spi_xfer(spi, 9, &buf, NULL, flags);
+}
+
+int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, const u8 *data, size_t len)
+{
+	struct spi_slave *spi = dbi->spi;
+	int wordlen;
+	int retval = -1;
+
+	if (spi_claim_bus(spi))
+		return -1;
+
+	wordlen = spi_set_wordlen(spi, 9);
+	if (wordlen == -1)
+		goto done;
+
+	if (mipi_dbi_xfer(dbi, cmd, 0, len) != 0)
+		goto done;
+
+	for (int i = 1; i <= len; ++i) {
+		u8 dat = data[i - 1];
+
+		if (mipi_dbi_xfer(dbi, dat, i, len) != 0)
+			goto done;
+	}
+
+	retval = 0;
+
+done:
+	if (wordlen != -1)
+		spi_set_wordlen(spi, wordlen);
+
+	spi_release_bus(spi);
+
+	return retval;
+}
diff --git a/include/mipi_dbi.h b/include/mipi_dbi.h
new file mode 100644
index 0000000000..1c0c21ba81
--- /dev/null
+++ b/include/mipi_dbi.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * MIPI DBI Bus support
+ *
+ * Copyright 2024 John Watts <contact at jookia.org>
+ */
+#ifndef MIPI_DBI_H
+#define MIPI_DBI_H
+
+#include <asm/gpio.h>
+#include <mipi_display.h>
+#include <spi.h>
+
+/**
+ * struct mipi_dbi - MIPI DBI bus info
+ *
+ * This contains information about a MIPI DBI bus.
+ * Use mipi_dbi_spi_init to create and initialize this structure.
+ *
+ * @spi:	SPI slave this bus operates on.
+ */
+struct mipi_dbi {
+	struct spi_slave *spi;
+};
+
+/**
+ * mipi_dbi_spi_init - Creates a new MIPI DBI bus
+ *
+ * Creates and sets up a 'struct mipi_dbi' using the provided SPI slave
+ * and optional D/C GPIO.
+ *
+ * @slave:	SPI slave the bus is on
+ * @dbi:	Destination mipi_dbi structure to initialize
+ * @dc:		D/C GPIO (NULL if unused)
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int mipi_dbi_spi_init(struct spi_slave *slave, struct mipi_dbi *dbi,
+		      struct gpio_desc *dc);
+
+/**
+ * mipi_dbi_command_buf - Sends a command and data over the bus
+ *
+ * Sends a command and any optional data over a bus.
+ *
+ * @dbi:	MIPI DBI bus to use
+ * @cmd:	MIPI DBI command
+ * @data:	Command data (NULL if len is 0)
+ * @len:	Length of data in bytes
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, const u8 *data, size_t len);
+
+/**
+ * mipi_dbi_command - Sends a command and data sequence over the bus
+ *
+ * Sends a command and any optional data over a bus.
+ * The data is a variadic sequence.
+ *
+ * @dbi:	MIPI DBI bus to use
+ * @cmd:	MIPI DBI command
+ * @seq:	Command data bytes
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+#define mipi_dbi_command(dbi, cmd, seq...) \
+({ \
+	const u8 data[] = { seq }; \
+	mipi_dbi_command_buf(dbi, cmd, data, ARRAY_SIZE(data)); \
+})
+
+#endif /* MIPI_DBI_H */

-- 
2.45.2



More information about the U-Boot mailing list