All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: robh+dt@kernel.org, david@lechnology.com
Cc: devicetree@vger.kernel.org, linux-fbdev@vger.kernel.org,
	dave.stevenson@raspberrypi.com, linux-staging@lists.linux.dev,
	dri-devel@lists.freedesktop.org,
	"Noralf Trønnes" <noralf@tronnes.org>,
	maxime@cerno.tech
Subject: [PATCH 5/6] drm/mipi-dbi: Add device property functions
Date: Wed, 24 Nov 2021 16:07:56 +0100	[thread overview]
Message-ID: <20211124150757.17929-6-noralf@tronnes.org> (raw)
In-Reply-To: <20211124150757.17929-1-noralf@tronnes.org>

Add helper functions for configuring a MIPI DBI controller from device
properties.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/drm_mipi_dbi.c | 139 +++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dbi.h     |   3 +
 2 files changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 71b646c4131f..41362e1d4231 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -137,6 +137,24 @@ int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val)
 }
 EXPORT_SYMBOL(mipi_dbi_command_read);
 
+/**
+ * mipi_dbi_set_writeonly - Set the controller write only state
+ * @dbi: MIPI DBI structure
+ * @writeonly: If true the controller is not readable
+ *
+ * This function sets whether the controller can be read from or not (ie. MISO connected or not).
+ * It also checks the 'write-only' device property which overrides @writeonly.
+ * The controller is assumed to be readable by default.
+ */
+void mipi_dbi_set_writeonly(struct mipi_dbi *dbi, bool writeonly)
+{
+	struct device *dev = &dbi->spi->dev;
+
+	if (writeonly || device_property_present(dev, "write-only"))
+		dbi->read_commands = NULL;
+}
+EXPORT_SYMBOL(mipi_dbi_set_writeonly);
+
 /**
  * mipi_dbi_command_buf - MIPI DCS command with parameter(s) in an array
  * @dbi: MIPI DBI structure
@@ -186,6 +204,40 @@ int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
 }
 EXPORT_SYMBOL(mipi_dbi_command_stackbuf);
 
+/**
+ * mipi_dbi_command_from_property - MIPI DCS command with parameter(s) from a device property
+ * @dbi: MIPI DBI structure
+ * @cmd: Command
+ * @propname: Name of the device property
+ * @len: Data length
+ *
+ * This function will execute @cmd with parameters from @propname if it exist.
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_command_from_property(struct mipi_dbi *dbi, u8 cmd, const char *propname, size_t len)
+{
+	struct device *dev = &dbi->spi->dev;
+	u8 data[64];
+	int ret;
+
+	if (WARN_ON_ONCE(len > sizeof(data)))
+		return -EINVAL;
+
+	if (!device_property_present(dev, propname))
+		return 0;
+
+	ret = device_property_read_u8_array(dev, propname, data, len);
+	if (ret) {
+		dev_err(dev, "Failed to read property '%s', error=%d\n", propname, ret);
+		return ret;
+	}
+
+	return mipi_dbi_command_stackbuf(dbi, cmd, data, len);
+}
+EXPORT_SYMBOL(mipi_dbi_command_from_property);
+
 /**
  * mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary
  * @dst: The destination buffer
@@ -571,6 +623,93 @@ int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 }
 EXPORT_SYMBOL(mipi_dbi_dev_init);
 
+static int mipi_dbi_property_read_u32(struct device *dev, const char *propname,
+				      unsigned int *retval, bool required)
+{
+	u32 val32;
+	int ret;
+
+	if (!device_property_present(dev, propname)) {
+		if (required) {
+			dev_err(dev, "Missing required property '%s'\n", propname);
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	ret = device_property_read_u32(dev, propname, &val32);
+	if (ret) {
+		dev_err(dev, "Error reading property '%s', error=%d\n", propname, ret);
+		return ret;
+	}
+
+	*retval = val32;
+
+	return 0;
+}
+
+static void mipi_dbi_simple_mode(struct drm_display_mode *mode,
+				 unsigned int width, unsigned int height,
+				 unsigned int width_mm, unsigned int height_mm)
+{
+	struct drm_display_mode simple_mode = { DRM_SIMPLE_MODE(width, height, width_mm, height_mm) };
+
+	*mode = simple_mode;
+}
+
+/**
+ * mipi_dbi_read_device_properties - Read device properties
+ * @dbidev: MIPI DBI device structure
+ * @mode: Returned display mode
+ *
+ * This function reads device properties 'width', 'height', 'width_mm', 'height_mm'
+ * and returns them as a display mode in @mode.
+ * It also reads 'x-offset' and 'y-offset' whose values are set on @dbidev.
+ *
+ * The returned @mode can be passed on to mipi_dbi_dev_init().
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_read_device_properties(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode)
+{
+	unsigned int width, height, width_mm = 0, height_mm = 0;
+	struct device *dev = dbidev->drm.dev;
+	int ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "width", &width, true);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "height", &height, true);
+	if (ret)
+		return ret;
+
+	if (device_property_present(dev, "width_mm") || device_property_present(dev, "height_mm")) {
+		ret = mipi_dbi_property_read_u32(dev, "width_mm", &width_mm, true);
+		if (ret)
+			return ret;
+
+		ret = mipi_dbi_property_read_u32(dev, "height_mm", &height_mm, true);
+		if (ret)
+			return ret;
+	}
+
+	mipi_dbi_simple_mode(mode, width, height, width_mm, height_mm);
+
+	ret = mipi_dbi_property_read_u32(dev, "x-offset", &dbidev->left_offset, false);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "y-offset", &dbidev->top_offset, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dbi_read_device_properties);
+
 /**
  * mipi_dbi_hw_reset - Hardware reset of controller
  * @dbi: MIPI DBI structure
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 05e194958265..c75f760d6de5 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -147,6 +147,7 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 		      const struct drm_simple_display_pipe_funcs *funcs,
 		      const struct drm_display_mode *mode, unsigned int rotation);
+int mipi_dbi_read_device_properties(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode);
 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
 			  struct drm_plane_state *old_state);
 void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
@@ -163,9 +164,11 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
 			  u8 bpw, const void *buf, size_t len);
 
 int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val);
+void mipi_dbi_set_writeonly(struct mipi_dbi *dbi, bool writeonly);
 int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len);
 int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
 			      size_t len);
+int mipi_dbi_command_from_property(struct mipi_dbi *dbi, u8 cmd, const char *propname, size_t len);
 int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
 		      struct drm_rect *clip, bool swap);
 /**
-- 
2.33.0


WARNING: multiple messages have this Message-ID (diff)
From: "Noralf Trønnes" <noralf@tronnes.org>
To: robh+dt@kernel.org, david@lechnology.com
Cc: devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linux-fbdev@vger.kernel.org, linux-staging@lists.linux.dev,
	dave.stevenson@raspberrypi.com, maxime@cerno.tech,
	"Noralf Trønnes" <noralf@tronnes.org>
Subject: [PATCH 5/6] drm/mipi-dbi: Add device property functions
Date: Wed, 24 Nov 2021 16:07:56 +0100	[thread overview]
Message-ID: <20211124150757.17929-6-noralf@tronnes.org> (raw)
In-Reply-To: <20211124150757.17929-1-noralf@tronnes.org>

Add helper functions for configuring a MIPI DBI controller from device
properties.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/drm_mipi_dbi.c | 139 +++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dbi.h     |   3 +
 2 files changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 71b646c4131f..41362e1d4231 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -137,6 +137,24 @@ int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val)
 }
 EXPORT_SYMBOL(mipi_dbi_command_read);
 
+/**
+ * mipi_dbi_set_writeonly - Set the controller write only state
+ * @dbi: MIPI DBI structure
+ * @writeonly: If true the controller is not readable
+ *
+ * This function sets whether the controller can be read from or not (ie. MISO connected or not).
+ * It also checks the 'write-only' device property which overrides @writeonly.
+ * The controller is assumed to be readable by default.
+ */
+void mipi_dbi_set_writeonly(struct mipi_dbi *dbi, bool writeonly)
+{
+	struct device *dev = &dbi->spi->dev;
+
+	if (writeonly || device_property_present(dev, "write-only"))
+		dbi->read_commands = NULL;
+}
+EXPORT_SYMBOL(mipi_dbi_set_writeonly);
+
 /**
  * mipi_dbi_command_buf - MIPI DCS command with parameter(s) in an array
  * @dbi: MIPI DBI structure
@@ -186,6 +204,40 @@ int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
 }
 EXPORT_SYMBOL(mipi_dbi_command_stackbuf);
 
+/**
+ * mipi_dbi_command_from_property - MIPI DCS command with parameter(s) from a device property
+ * @dbi: MIPI DBI structure
+ * @cmd: Command
+ * @propname: Name of the device property
+ * @len: Data length
+ *
+ * This function will execute @cmd with parameters from @propname if it exist.
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_command_from_property(struct mipi_dbi *dbi, u8 cmd, const char *propname, size_t len)
+{
+	struct device *dev = &dbi->spi->dev;
+	u8 data[64];
+	int ret;
+
+	if (WARN_ON_ONCE(len > sizeof(data)))
+		return -EINVAL;
+
+	if (!device_property_present(dev, propname))
+		return 0;
+
+	ret = device_property_read_u8_array(dev, propname, data, len);
+	if (ret) {
+		dev_err(dev, "Failed to read property '%s', error=%d\n", propname, ret);
+		return ret;
+	}
+
+	return mipi_dbi_command_stackbuf(dbi, cmd, data, len);
+}
+EXPORT_SYMBOL(mipi_dbi_command_from_property);
+
 /**
  * mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary
  * @dst: The destination buffer
@@ -571,6 +623,93 @@ int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 }
 EXPORT_SYMBOL(mipi_dbi_dev_init);
 
+static int mipi_dbi_property_read_u32(struct device *dev, const char *propname,
+				      unsigned int *retval, bool required)
+{
+	u32 val32;
+	int ret;
+
+	if (!device_property_present(dev, propname)) {
+		if (required) {
+			dev_err(dev, "Missing required property '%s'\n", propname);
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	ret = device_property_read_u32(dev, propname, &val32);
+	if (ret) {
+		dev_err(dev, "Error reading property '%s', error=%d\n", propname, ret);
+		return ret;
+	}
+
+	*retval = val32;
+
+	return 0;
+}
+
+static void mipi_dbi_simple_mode(struct drm_display_mode *mode,
+				 unsigned int width, unsigned int height,
+				 unsigned int width_mm, unsigned int height_mm)
+{
+	struct drm_display_mode simple_mode = { DRM_SIMPLE_MODE(width, height, width_mm, height_mm) };
+
+	*mode = simple_mode;
+}
+
+/**
+ * mipi_dbi_read_device_properties - Read device properties
+ * @dbidev: MIPI DBI device structure
+ * @mode: Returned display mode
+ *
+ * This function reads device properties 'width', 'height', 'width_mm', 'height_mm'
+ * and returns them as a display mode in @mode.
+ * It also reads 'x-offset' and 'y-offset' whose values are set on @dbidev.
+ *
+ * The returned @mode can be passed on to mipi_dbi_dev_init().
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_read_device_properties(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode)
+{
+	unsigned int width, height, width_mm = 0, height_mm = 0;
+	struct device *dev = dbidev->drm.dev;
+	int ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "width", &width, true);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "height", &height, true);
+	if (ret)
+		return ret;
+
+	if (device_property_present(dev, "width_mm") || device_property_present(dev, "height_mm")) {
+		ret = mipi_dbi_property_read_u32(dev, "width_mm", &width_mm, true);
+		if (ret)
+			return ret;
+
+		ret = mipi_dbi_property_read_u32(dev, "height_mm", &height_mm, true);
+		if (ret)
+			return ret;
+	}
+
+	mipi_dbi_simple_mode(mode, width, height, width_mm, height_mm);
+
+	ret = mipi_dbi_property_read_u32(dev, "x-offset", &dbidev->left_offset, false);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_property_read_u32(dev, "y-offset", &dbidev->top_offset, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dbi_read_device_properties);
+
 /**
  * mipi_dbi_hw_reset - Hardware reset of controller
  * @dbi: MIPI DBI structure
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 05e194958265..c75f760d6de5 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -147,6 +147,7 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 		      const struct drm_simple_display_pipe_funcs *funcs,
 		      const struct drm_display_mode *mode, unsigned int rotation);
+int mipi_dbi_read_device_properties(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode);
 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
 			  struct drm_plane_state *old_state);
 void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
@@ -163,9 +164,11 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
 			  u8 bpw, const void *buf, size_t len);
 
 int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val);
+void mipi_dbi_set_writeonly(struct mipi_dbi *dbi, bool writeonly);
 int mipi_dbi_command_buf(struct mipi_dbi *dbi, u8 cmd, u8 *data, size_t len);
 int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data,
 			      size_t len);
+int mipi_dbi_command_from_property(struct mipi_dbi *dbi, u8 cmd, const char *propname, size_t len);
 int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
 		      struct drm_rect *clip, bool swap);
 /**
-- 
2.33.0


  parent reply	other threads:[~2021-11-24 15:08 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-24 15:07 [PATCH 0/6] drm/tiny/st7735r: Match up with staging/fbtft driver Noralf Trønnes
2021-11-24 15:07 ` Noralf Trønnes
2021-11-24 15:07 ` [PATCH 1/6] dt-bindings: display: sitronix, st7735r: Fix backlight in example Noralf Trønnes
2021-11-24 15:07   ` [PATCH 1/6] dt-bindings: display: sitronix,st7735r: " Noralf Trønnes
2021-12-01 21:57   ` Rob Herring
2021-12-01 21:57     ` Rob Herring
2021-12-06  8:53   ` Geert Uytterhoeven
2021-12-06  8:53     ` [PATCH 1/6] dt-bindings: display: sitronix, st7735r: " Geert Uytterhoeven
2021-12-06 15:18   ` David Lechner
2021-12-06 15:18     ` [PATCH 1/6] dt-bindings: display: sitronix,st7735r: " David Lechner
2021-11-24 15:07 ` [PATCH 2/6] dt-bindings: display: sitronix, st7735r: Make reset-gpios optional Noralf Trønnes
2021-11-24 15:07   ` [PATCH 2/6] dt-bindings: display: sitronix,st7735r: " Noralf Trønnes
2021-12-01 21:57   ` Rob Herring
2021-12-01 21:57     ` Rob Herring
2021-12-06 15:18   ` David Lechner
2021-12-06 15:18     ` David Lechner
2021-11-24 15:07 ` [PATCH 3/6] dt-bindings: display: sitronix, st7735r: Remove spi-max-frequency limit Noralf Trønnes
2021-11-24 15:07   ` [PATCH 3/6] dt-bindings: display: sitronix,st7735r: " Noralf Trønnes
2021-12-01 21:57   ` Rob Herring
2021-12-01 21:57     ` Rob Herring
2021-12-06 15:19   ` David Lechner
2021-12-06 15:19     ` David Lechner
2021-12-06 16:02     ` Noralf Trønnes
2021-12-06 16:02       ` Noralf Trønnes
2021-11-24 15:07 ` [PATCH 4/6] dt-bindings: display: sitronix, st7735r: Add initialization properties Noralf Trønnes
2021-11-24 15:07   ` [PATCH 4/6] dt-bindings: display: sitronix,st7735r: " Noralf Trønnes
2021-12-01 22:08   ` Rob Herring
2021-12-01 22:08     ` Rob Herring
2021-11-24 15:07 ` Noralf Trønnes [this message]
2021-11-24 15:07   ` [PATCH 5/6] drm/mipi-dbi: Add device property functions Noralf Trønnes
2021-11-24 15:07 ` [PATCH 6/6] drm: tiny: st7735r: Support DT initialization of controller Noralf Trønnes
2021-11-24 15:07   ` Noralf Trønnes
2021-11-24 22:03 ` [PATCH 0/6] drm/tiny/st7735r: Match up with staging/fbtft driver David Lechner
2021-11-24 22:03   ` David Lechner
2021-11-25 17:21   ` Noralf Trønnes
2021-11-25 17:21     ` Noralf Trønnes
2021-11-29  9:39   ` Maxime Ripard
2021-11-29  9:39     ` Maxime Ripard
2021-11-30  8:13     ` Geert Uytterhoeven
2021-11-30  8:13       ` Geert Uytterhoeven
2021-11-30  9:03       ` Maxime Ripard
2021-11-30  9:03         ` Maxime Ripard
2021-11-30 14:30     ` Noralf Trønnes
2021-11-30 14:30       ` Noralf Trønnes
2021-12-01 14:52       ` Maxime Ripard
2021-12-01 14:52         ` Maxime Ripard
2021-12-06 15:26         ` David Lechner
2021-12-06 15:26           ` David Lechner
2021-12-06 16:04           ` Noralf Trønnes
2021-12-06 16:04             ` Noralf Trønnes
2022-03-09 10:37 ` Noralf Trønnes
2022-03-09 10:37   ` Noralf Trønnes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211124150757.17929-6-noralf@tronnes.org \
    --to=noralf@tronnes.org \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=david@lechnology.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-staging@lists.linux.dev \
    --cc=maxime@cerno.tech \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.