diff options
| author | Thierry Reding <treding@nvidia.com> | 2014-07-21 09:47:10 -0400 |
|---|---|---|
| committer | Thierry Reding <treding@nvidia.com> | 2014-11-13 07:55:36 -0500 |
| commit | 960dd616f61c8482b3f9d01fa6623576fb74503c (patch) | |
| tree | d62b57a143804dc3404ad57f8ecd767d6f5202b3 | |
| parent | 9eb491f3eed26eb7edf4bf4b1a549895fb3301ea (diff) | |
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: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
| -rw-r--r-- | drivers/gpu/drm/drm_mipi_dsi.c | 77 | ||||
| -rw-r--r-- | drivers/gpu/drm/panel/panel-s6e8aa0.c | 2 | ||||
| -rw-r--r-- | include/drm/drm_mipi_dsi.h | 6 |
3 files changed, 70 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 0cc030a09c56..388c3ab02500 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c | |||
| @@ -333,13 +333,19 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, | |||
| 333 | EXPORT_SYMBOL(mipi_dsi_create_packet); | 333 | EXPORT_SYMBOL(mipi_dsi_create_packet); |
| 334 | 334 | ||
| 335 | /** | 335 | /** |
| 336 | * mipi_dsi_dcs_write - send DCS write command | 336 | * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload |
| 337 | * @dsi: DSI device | 337 | * @dsi: DSI peripheral device |
| 338 | * @data: pointer to the command followed by parameters | 338 | * @data: buffer containing data to be transmitted |
| 339 | * @len: length of @data | 339 | * @len: size of transmission buffer |
| 340 | * | ||
| 341 | * This function will automatically choose the right data type depending on | ||
| 342 | * the command payload length. | ||
| 343 | * | ||
| 344 | * Return: The number of bytes successfully transmitted or a negative error | ||
| 345 | * code on failure. | ||
| 340 | */ | 346 | */ |
| 341 | ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, | 347 | ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, |
| 342 | size_t len) | 348 | const void *data, size_t len) |
| 343 | { | 349 | { |
| 344 | struct mipi_dsi_msg msg = { | 350 | struct mipi_dsi_msg msg = { |
| 345 | .channel = dsi->channel, | 351 | .channel = dsi->channel, |
| @@ -350,12 +356,15 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, | |||
| 350 | switch (len) { | 356 | switch (len) { |
| 351 | case 0: | 357 | case 0: |
| 352 | return -EINVAL; | 358 | return -EINVAL; |
| 359 | |||
| 353 | case 1: | 360 | case 1: |
| 354 | msg.type = MIPI_DSI_DCS_SHORT_WRITE; | 361 | msg.type = MIPI_DSI_DCS_SHORT_WRITE; |
| 355 | break; | 362 | break; |
| 363 | |||
| 356 | case 2: | 364 | case 2: |
| 357 | msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; | 365 | msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; |
| 358 | break; | 366 | break; |
| 367 | |||
| 359 | default: | 368 | default: |
| 360 | msg.type = MIPI_DSI_DCS_LONG_WRITE; | 369 | msg.type = MIPI_DSI_DCS_LONG_WRITE; |
| 361 | break; | 370 | break; |
| @@ -363,16 +372,60 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, | |||
| 363 | 372 | ||
| 364 | return mipi_dsi_device_transfer(dsi, &msg); | 373 | return mipi_dsi_device_transfer(dsi, &msg); |
| 365 | } | 374 | } |
| 375 | EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); | ||
| 376 | |||
| 377 | /** | ||
| 378 | * mipi_dsi_dcs_write() - send DCS write command | ||
| 379 | * @dsi: DSI peripheral device | ||
| 380 | * @cmd: DCS command | ||
| 381 | * @data: buffer containing the command payload | ||
| 382 | * @len: command payload length | ||
| 383 | * | ||
| 384 | * This function will automatically choose the right data type depending on | ||
| 385 | * the command payload length. | ||
| 386 | * | ||
| 387 | * Return: The number of bytes successfully transmitted or a negative error | ||
| 388 | * code on failure. | ||
| 389 | */ | ||
| 390 | ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, | ||
| 391 | const void *data, size_t len) | ||
| 392 | { | ||
| 393 | ssize_t err; | ||
| 394 | size_t size; | ||
| 395 | u8 *tx; | ||
| 396 | |||
| 397 | if (len > 0) { | ||
| 398 | size = 1 + len; | ||
| 399 | |||
| 400 | tx = kmalloc(size, GFP_KERNEL); | ||
| 401 | if (!tx) | ||
| 402 | return -ENOMEM; | ||
| 403 | |||
| 404 | /* concatenate the DCS command byte and the payload */ | ||
| 405 | tx[0] = cmd; | ||
| 406 | memcpy(&tx[1], data, len); | ||
| 407 | } else { | ||
| 408 | tx = &cmd; | ||
| 409 | size = 1; | ||
| 410 | } | ||
| 411 | |||
| 412 | err = mipi_dsi_dcs_write_buffer(dsi, tx, size); | ||
| 413 | |||
| 414 | if (len > 0) | ||
| 415 | kfree(tx); | ||
| 416 | |||
| 417 | return err; | ||
| 418 | } | ||
| 366 | EXPORT_SYMBOL(mipi_dsi_dcs_write); | 419 | EXPORT_SYMBOL(mipi_dsi_dcs_write); |
| 367 | 420 | ||
| 368 | /** | 421 | /** |
| 369 | * mipi_dsi_dcs_read - send DCS read request command | 422 | * mipi_dsi_dcs_read() - send DCS read request command |
| 370 | * @dsi: DSI device | 423 | * @dsi: DSI peripheral device |
| 371 | * @cmd: DCS read command | 424 | * @cmd: DCS command |
| 372 | * @data: pointer to read buffer | 425 | * @data: buffer in which to receive data |
| 373 | * @len: length of @data | 426 | * @len: size of receive buffer |
| 374 | * | 427 | * |
| 375 | * Function returns number of read bytes or error code. | 428 | * Return: The number of bytes read or a negative error code on failure. |
| 376 | */ | 429 | */ |
| 377 | ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, | 430 | ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, |
| 378 | size_t len) | 431 | size_t len) |
diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c index 96f4476609b0..17bc7991344d 100644 --- a/drivers/gpu/drm/panel/panel-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c | |||
| @@ -141,7 +141,7 @@ static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len) | |||
| 141 | if (ctx->error < 0) | 141 | if (ctx->error < 0) |
| 142 | return; | 142 | return; |
| 143 | 143 | ||
| 144 | ret = mipi_dsi_dcs_write(dsi, data, len); | 144 | ret = mipi_dsi_dcs_write_buffer(dsi, data, len); |
| 145 | if (ret < 0) { | 145 | if (ret < 0) { |
| 146 | dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, | 146 | dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, |
| 147 | (int)len, data); | 147 | (int)len, data); |
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 6e3e3aadd2d7..44cece97f333 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h | |||
| @@ -153,8 +153,10 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) | |||
| 153 | 153 | ||
| 154 | int mipi_dsi_attach(struct mipi_dsi_device *dsi); | 154 | int mipi_dsi_attach(struct mipi_dsi_device *dsi); |
| 155 | int mipi_dsi_detach(struct mipi_dsi_device *dsi); | 155 | int mipi_dsi_detach(struct mipi_dsi_device *dsi); |
| 156 | ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, | 156 | ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, |
| 157 | size_t len); | 157 | const void *data, size_t len); |
| 158 | ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, | ||
| 159 | const void *data, size_t len); | ||
| 158 | ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, | 160 | ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, |
| 159 | size_t len); | 161 | size_t len); |
| 160 | 162 | ||
