Commit 960dd616 authored by Thierry Reding's avatar Thierry Reding

drm/dsi: Make mipi_dsi_dcs_{read,write}() symmetrical

Currently the mipi_dsi_dcs_write() function requires the DCS command
byte to be embedded within the write buffer whereas mipi_dsi_dcs_read()
has a separate parameter. Make them more symmetrical by adding an extra
command parameter to mipi_dsi_dcs_write().

The S6E8AA0 driver relies on the old asymmetric API and there's concern
that moving to the new API may be less efficient. Provide a new function
with the old semantics for those cases and make the S6E8AA0 driver use
it instead.
Reviewed-by: default avatarSean Paul <seanpaul@chromium.org>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 9eb491f3
...@@ -333,13 +333,19 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, ...@@ -333,13 +333,19 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
EXPORT_SYMBOL(mipi_dsi_create_packet); EXPORT_SYMBOL(mipi_dsi_create_packet);
/** /**
* mipi_dsi_dcs_write - send DCS write command * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
* @dsi: DSI device * @dsi: DSI peripheral device
* @data: pointer to the command followed by parameters * @data: buffer containing data to be transmitted
* @len: length of @data * @len: size of transmission buffer
*
* This function will automatically choose the right data type depending on
* the command payload length.
*
* Return: The number of bytes successfully transmitted or a negative error
* code on failure.
*/ */
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
size_t len) const void *data, size_t len)
{ {
struct mipi_dsi_msg msg = { struct mipi_dsi_msg msg = {
.channel = dsi->channel, .channel = dsi->channel,
...@@ -350,12 +356,15 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, ...@@ -350,12 +356,15 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data,
switch (len) { switch (len) {
case 0: case 0:
return -EINVAL; return -EINVAL;
case 1: case 1:
msg.type = MIPI_DSI_DCS_SHORT_WRITE; msg.type = MIPI_DSI_DCS_SHORT_WRITE;
break; break;
case 2: case 2:
msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
break; break;
default: default:
msg.type = MIPI_DSI_DCS_LONG_WRITE; msg.type = MIPI_DSI_DCS_LONG_WRITE;
break; break;
...@@ -363,16 +372,60 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, ...@@ -363,16 +372,60 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data,
return mipi_dsi_device_transfer(dsi, &msg); return mipi_dsi_device_transfer(dsi, &msg);
} }
EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
/**
* mipi_dsi_dcs_write() - send DCS write command
* @dsi: DSI peripheral device
* @cmd: DCS command
* @data: buffer containing the command payload
* @len: command payload length
*
* This function will automatically choose the right data type depending on
* the command payload length.
*
* Return: The number of bytes successfully transmitted or a negative error
* code on failure.
*/
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
const void *data, size_t len)
{
ssize_t err;
size_t size;
u8 *tx;
if (len > 0) {
size = 1 + len;
tx = kmalloc(size, GFP_KERNEL);
if (!tx)
return -ENOMEM;
/* concatenate the DCS command byte and the payload */
tx[0] = cmd;
memcpy(&tx[1], data, len);
} else {
tx = &cmd;
size = 1;
}
err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
if (len > 0)
kfree(tx);
return err;
}
EXPORT_SYMBOL(mipi_dsi_dcs_write); EXPORT_SYMBOL(mipi_dsi_dcs_write);
/** /**
* mipi_dsi_dcs_read - send DCS read request command * mipi_dsi_dcs_read() - send DCS read request command
* @dsi: DSI device * @dsi: DSI peripheral device
* @cmd: DCS read command * @cmd: DCS command
* @data: pointer to read buffer * @data: buffer in which to receive data
* @len: length of @data * @len: size of receive buffer
* *
* Function returns number of read bytes or error code. * Return: The number of bytes read or a negative error code on failure.
*/ */
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
size_t len) size_t len)
......
...@@ -141,7 +141,7 @@ static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len) ...@@ -141,7 +141,7 @@ static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len)
if (ctx->error < 0) if (ctx->error < 0)
return; return;
ret = mipi_dsi_dcs_write(dsi, data, len); ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
if (ret < 0) { if (ret < 0) {
dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret,
(int)len, data); (int)len, data);
......
...@@ -153,8 +153,10 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) ...@@ -153,8 +153,10 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev)
int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_attach(struct mipi_dsi_device *dsi);
int mipi_dsi_detach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi);
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
size_t len); 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, ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
size_t len); size_t len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment