Commit d94a2a00 authored by Brigham Campbell's avatar Brigham Campbell Committed by Douglas Anderson
Browse files

drm: Create mipi_dsi_dual* macros



Create mipi_dsi_dual, mipi_dsi_dual_dcs_write_seq_multi, and
mipi_dsi_dual_generic_write_seq_multi macros for panels which are driven
by two parallel serial interfaces. This allows for the reduction of code
duplication in drivers for these panels.

Remove mipi_dsi_dual_dcs_write_seq_multi definition from
panel-novatek-nt36523.c to avoid the duplicate definition. Make novatek
driver pass mipi_dsi_context struct as a pointer.

Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: default avatarBrigham Campbell <me@brighamcampbell.com>
Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20250722015313.561966-2-me@brighamcampbell.com
parent 33f8f321
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -827,6 +827,30 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
}
EXPORT_SYMBOL(mipi_dsi_generic_write_multi);

/**
 * mipi_dsi_dual_generic_write_multi() - mipi_dsi_generic_write_multi() for
 * two dsi channels, one after the other
 * @ctx: Context for multiple DSI transactions
 * @dsi1: First dsi channel to write buffer to
 * @dsi2: Second dsi channel to write buffer to
 * @payload: Buffer containing the payload
 * @size: Size of payload buffer
 *
 * A wrapper around mipi_dsi_generic_write_multi() that allows the user to
 * conveniently write to two dsi channels, one after the other.
 */
void mipi_dsi_dual_generic_write_multi(struct mipi_dsi_multi_context *ctx,
				       struct mipi_dsi_device *dsi1,
				       struct mipi_dsi_device *dsi2,
				       const void *payload, size_t size)
{
	ctx->dsi = dsi1;
	mipi_dsi_generic_write_multi(ctx, payload, size);
	ctx->dsi = dsi2;
	mipi_dsi_generic_write_multi(ctx, payload, size);
}
EXPORT_SYMBOL(mipi_dsi_dual_generic_write_multi);

/**
 * mipi_dsi_generic_read() - receive data using a generic read packet
 * @dsi: DSI peripheral device
@@ -1006,6 +1030,30 @@ void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
}
EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);

/**
 * mipi_dsi_dual_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_multi() for
 * two dsi channels, one after the other
 * @ctx: Context for multiple DSI transactions
 * @dsi1: First dsi channel to write buffer to
 * @dsi2: Second dsi channel to write buffer to
 * @data: Buffer containing data to be transmitted
 * @len: Size of transmission buffer
 *
 * A wrapper around mipi_dsi_dcs_write_buffer_multi() that allows the user to
 * conveniently write to two dsi channels, one after the other.
 */
void mipi_dsi_dual_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
					  struct mipi_dsi_device *dsi1,
					  struct mipi_dsi_device *dsi2,
					  const void *data, size_t len)
{
	ctx->dsi = dsi1;
	mipi_dsi_dcs_write_buffer_multi(ctx, data, len);
	ctx->dsi = dsi2;
	mipi_dsi_dcs_write_buffer_multi(ctx, data, len);
}
EXPORT_SYMBOL(mipi_dsi_dual_dcs_write_buffer_multi);

/**
 * mipi_dsi_dcs_write() - send DCS write command
 * @dsi: DSI peripheral device
+398 −406

File changed.

Preview size limit exceeded, changes collapsed.

+95 −0
Original line number Diff line number Diff line
@@ -289,6 +289,10 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
				  const void *payload, size_t size);
void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
				  const void *payload, size_t size);
void mipi_dsi_dual_generic_write_multi(struct mipi_dsi_multi_context *ctx,
				       struct mipi_dsi_device *dsi1,
				       struct mipi_dsi_device *dsi2,
				       const void *payload, size_t size);
ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
			      size_t num_params, void *data, size_t size);
u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format);
@@ -329,6 +333,10 @@ int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
				     const void *data, size_t len);
void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
				     const void *data, size_t len);
void mipi_dsi_dual_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
					  struct mipi_dsi_device *dsi1,
					  struct mipi_dsi_device *dsi2,
					  const void *data, size_t len);
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,
@@ -431,6 +439,93 @@ void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx);
		mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
	} while (0)

/**
 * mipi_dsi_dual - send the same MIPI DSI command to two interfaces
 *
 * This macro will send the specified MIPI DSI command twice, once per each of
 * the two interfaces supplied. This is useful for reducing duplication of code
 * in panel drivers which use two parallel serial interfaces.
 *
 * Note that the _func parameter cannot accept a macro such as
 * mipi_dsi_generic_write_multi() or mipi_dsi_dcs_write_buffer_multi(). See
 * mipi_dsi_dual_generic_write_multi() and
 * mipi_dsi_dual_dcs_write_buffer_multi() instead.
 *
 * WARNING: This macro reuses the _func argument and the optional trailing
 * arguments twice each, which may cause unintended side effects. For example,
 * adding the postfix increment ++ operator to one of the arguments to be
 * passed to _func will cause the variable to be incremented twice instead of
 * once and the variable will be its original value + 1 when sent to _dsi2.
 *
 * @_func: MIPI DSI function to pass context and arguments into
 * @_ctx: Context for multiple DSI transactions
 * @_dsi1: First DSI interface to act as recipient of the MIPI DSI command
 * @_dsi2: Second DSI interface to act as recipient of the MIPI DSI command
 * @...: Arguments to pass to MIPI DSI function or macro
 */

#define mipi_dsi_dual(_func, _ctx, _dsi1, _dsi2, ...)		 \
	do {							 \
		struct mipi_dsi_multi_context *_ctxcpy = (_ctx); \
		_ctxcpy->dsi = (_dsi1);				 \
		(_func)(_ctxcpy, ##__VA_ARGS__);		 \
		_ctxcpy->dsi = (_dsi2);				 \
		(_func)(_ctxcpy, ##__VA_ARGS__);		 \
	} while (0)

/**
 * mipi_dsi_dual_generic_write_seq_multi - transmit data using a generic write
 * packet to two dsi interfaces, one after the other
 *
 * This macro will send the specified generic packet twice, once per each of
 * the two interfaces supplied. This is useful for reducing duplication of code
 * in panel drivers which use two parallel serial interfaces.
 *
 * Note that if an error occurs while transmitting the packet to the first DSI
 * interface, the packet will not be sent to the second DSI interface.
 *
 * This macro will print errors for you and error handling is optimized for
 * callers that call this multiple times in a row.
 *
 * @_ctx: Context for multiple DSI transactions
 * @_dsi1: First DSI interface to act as recipient of packet
 * @_dsi2: Second DSI interface to act as recipient of packet
 * @_seq: buffer containing the payload
 */
#define mipi_dsi_dual_generic_write_seq_multi(_ctx, _dsi1, _dsi2, _seq...) \
	do {								   \
		static const u8 d[] = { _seq };				   \
		mipi_dsi_dual_generic_write_multi(_ctx, _dsi1, _dsi2, d,   \
						  ARRAY_SIZE(d));	   \
	} while (0)

/**
 * mipi_dsi_dual_dcs_write_seq_multi - transmit a DCS command with payload to
 * two dsi interfaces, one after the other
 *
 * This macro will send the specified DCS command with payload twice, once per
 * each of the two interfaces supplied. This is useful for reducing duplication
 * of code in panel drivers which use two parallel serial interfaces.
 *
 * Note that if an error occurs while transmitting the payload to the first DSI
 * interface, the payload will not be sent to the second DSI interface.
 *
 * This macro will print errors for you and error handling is optimized for
 * callers that call this multiple times in a row.
 *
 * @_ctx: Context for multiple DSI transactions
 * @_dsi1: First DSI interface to act as recipient of packet
 * @_dsi2: Second DSI interface to act as recipient of packet
 * @_cmd: Command
 * @_seq: buffer containing the payload
 */
#define mipi_dsi_dual_dcs_write_seq_multi(_ctx, _dsi1, _dsi2, _cmd, _seq...) \
	do {								     \
		static const u8 d[] = { _cmd, _seq };			     \
		mipi_dsi_dual_dcs_write_buffer_multi(_ctx, _dsi1, _dsi2, d,  \
						     ARRAY_SIZE(d));	     \
	} while (0)

/**
 * struct mipi_dsi_driver - DSI driver
 * @driver: device driver model driver