Create mipi_dsi_dcs_read_multi(), which accepts a mipi_dsi_multi_context
struct for improved error handling and cleaner panel driver code.
Signed-off-by: Brigham Campbell <me@brighamcampbell.com>
---
drivers/gpu/drm/drm_mipi_dsi.c | 37 ++++++++++++++++++++++++++++++++++
include/drm/drm_mipi_dsi.h | 2 ++
2 files changed, 39 insertions(+)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index a00d76443128..227b28555174 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1075,6 +1075,43 @@ ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
}
EXPORT_SYMBOL(mipi_dsi_dcs_read);
+/**
+ * mipi_dsi_dcs_read_multi() - mipi_dsi_dcs_read() w/ accum_err
+ * @ctx: Context for multiple DSI transactions
+ * @cmd: DCS command
+ * @data: buffer in which to receive data
+ * @len: size of receive buffer
+ *
+ * Like mipi_dsi_dcs_read() but deals with errors in a way that makes it
+ * convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd,
+ void *data, size_t len)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .type = MIPI_DSI_DCS_READ,
+ .tx_buf = &cmd,
+ .tx_len = 1,
+ .rx_buf = data,
+ .rx_len = len
+ };
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_device_transfer(dsi, &msg);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "transferring dcs message %xh failed: %d\n", cmd,
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_read_multi);
+
/**
* mipi_dsi_dcs_nop() - send DCS nop packet
* @dsi: DSI peripheral device
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 369b0d8830c3..d17c00d299c8 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -333,6 +333,8 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
const void *data, size_t len);
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
size_t len);
+void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd,
+ void *data, size_t len);
int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode);
--
2.50.1
Hi, On Thu, Jul 24, 2025 at 1:23 PM Brigham Campbell <me@brighamcampbell.com> wrote: > > +void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd, > + void *data, size_t len) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi; > + struct device *dev = &dsi->dev; > + struct mipi_dsi_msg msg = { > + .channel = dsi->channel, > + .type = MIPI_DSI_DCS_READ, > + .tx_buf = &cmd, > + .tx_len = 1, > + .rx_buf = data, > + .rx_len = len > + }; > + ssize_t ret; > + > + if (ctx->accum_err) > + return; > + > + ret = mipi_dsi_device_transfer(dsi, &msg); > + if (ret < 0) { > + ctx->accum_err = ret; > + dev_err(dev, "transferring dcs message %xh failed: %d\n", cmd, Format code "%xh" is probably not exactly what you want. If the error code is 0x10 it will print 10h, which is not very standard. You probably copied it from the write routine which uses "%*ph". There the "h" means something. See Documentation/core-api/printk-formats.rst. Probably you want "%#x". I'd probably also say "dcs read with cmd" rather than "transferring dcs message".
On Fri Jul 25, 2025 at 3:16 PM MDT, Doug Anderson wrote: >> + dev_err(dev, "transferring dcs message %xh failed: %d\n", cmd, > > Format code "%xh" is probably not exactly what you want. If the error > code is 0x10 it will print 10h, which is not very standard. You > probably copied it from the write routine which uses "%*ph". There the > "h" means something. See Documentation/core-api/printk-formats.rst. > Probably you want "%#x". Ah yes, I had based this change off the "%*ph" format specifier and I had mistakenly assumed that the 'h' was a literal 'h'. I'll fix that in v2. > I'd probably also say "dcs read with cmd" rather than "transferring > dcs message". Yes, this sounds more accurate. I'll include this in v2 as well. Thanks for the review, Brigham
© 2016 - 2025 Red Hat, Inc.