Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: Add MIPI read_multi func and two write macros

Create mipi_dsi_dcs_read_multi(), which accepts a mipi_dsi_multi_context
struct for improved error handling and cleaner panel driver code.

Create mipi_dsi_dcs_write_var_seq_multi() and
mipi_dsi_generic_write_var_seq_multi() macros which allow MIPI panel
drivers to write non-constant data to display controllers.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Brigham Campbell <me@brighamcampbell.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20250731032343.1258366-3-me@brighamcampbell.com

authored by

Brigham Campbell and committed by
Douglas Anderson
ffc23a20 00708510

+72
+37
drivers/gpu/drm/drm_mipi_dsi.c
··· 1097 1097 EXPORT_SYMBOL(mipi_dsi_dcs_read); 1098 1098 1099 1099 /** 1100 + * mipi_dsi_dcs_read_multi() - mipi_dsi_dcs_read() w/ accum_err 1101 + * @ctx: Context for multiple DSI transactions 1102 + * @cmd: DCS command 1103 + * @data: buffer in which to receive data 1104 + * @len: size of receive buffer 1105 + * 1106 + * Like mipi_dsi_dcs_read() but deals with errors in a way that makes it 1107 + * convenient to make several calls in a row. 1108 + */ 1109 + void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd, 1110 + void *data, size_t len) 1111 + { 1112 + struct mipi_dsi_device *dsi = ctx->dsi; 1113 + struct device *dev = &dsi->dev; 1114 + struct mipi_dsi_msg msg = { 1115 + .channel = dsi->channel, 1116 + .type = MIPI_DSI_DCS_READ, 1117 + .tx_buf = &cmd, 1118 + .tx_len = 1, 1119 + .rx_buf = data, 1120 + .rx_len = len 1121 + }; 1122 + ssize_t ret; 1123 + 1124 + if (ctx->accum_err) 1125 + return; 1126 + 1127 + ret = mipi_dsi_device_transfer(dsi, &msg); 1128 + if (ret < 0) { 1129 + ctx->accum_err = ret; 1130 + dev_err(dev, "dcs read with command %#x failed: %d\n", cmd, 1131 + ctx->accum_err); 1132 + } 1133 + } 1134 + EXPORT_SYMBOL(mipi_dsi_dcs_read_multi); 1135 + 1136 + /** 1100 1137 * mipi_dsi_dcs_nop() - send DCS nop packet 1101 1138 * @dsi: DSI peripheral device 1102 1139 *
+35
include/drm/drm_mipi_dsi.h
··· 342 342 const void *data, size_t len); 343 343 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 344 344 size_t len); 345 + void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd, 346 + void *data, size_t len); 345 347 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); 346 348 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); 347 349 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); ··· 406 404 } while (0) 407 405 408 406 /** 407 + * mipi_dsi_generic_write_var_seq_multi - transmit non-constant data using a 408 + * generic write packet 409 + * 410 + * This macro will print errors for you and error handling is optimized for 411 + * callers that call this multiple times in a row. 412 + * 413 + * @ctx: Context for multiple DSI transactions 414 + * @seq: buffer containing the payload 415 + */ 416 + #define mipi_dsi_generic_write_var_seq_multi(ctx, seq...) \ 417 + do { \ 418 + const u8 d[] = { seq }; \ 419 + mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \ 420 + } while (0) 421 + 422 + /** 409 423 * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload 410 424 * 411 425 * This macro will print errors for you and error handling is optimized for ··· 435 417 do { \ 436 418 static const u8 d[] = { cmd, seq }; \ 437 419 mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \ 420 + } while (0) 421 + 422 + /** 423 + * mipi_dsi_dcs_write_var_seq_multi - transmit a DCS command with non-constant 424 + * payload 425 + * 426 + * This macro will print errors for you and error handling is optimized for 427 + * callers that call this multiple times in a row. 428 + * 429 + * @ctx: Context for multiple DSI transactions 430 + * @cmd: Command 431 + * @seq: buffer containing data to be transmitted 432 + */ 433 + #define mipi_dsi_dcs_write_var_seq_multi(ctx, cmd, seq...) \ 434 + do { \ 435 + const u8 d[] = { cmd, seq }; \ 436 + mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \ 438 437 } while (0) 439 438 440 439 /**