1// SPDX-License-Identifier: GPL-2.0 2/* 3 * MIPI DSI Bus 4 * 5 * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. 6 * Copyright (C) 2019 STMicroelectronics - All Rights Reserved 7 * Andrzej Hajda <a.hajda@samsung.com> 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the 11 * "Software"), to deal in the Software without restriction, including 12 * without limitation the rights to use, copy, modify, merge, publish, 13 * distribute, sub license, and/or sell copies of the Software, and to 14 * permit persons to whom the Software is furnished to do so, subject to 15 * the following conditions: 16 * 17 * The above copyright notice and this permission notice (including the 18 * next paragraph) shall be included in all copies or substantial portions 19 * of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 24 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 25 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 26 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 27 * USE OR OTHER DEALINGS IN THE SOFTWARE. 28 * 29 * Mipi_dsi.c contains a set of dsi helpers. 30 * This file is inspired from the drm helper file drivers/gpu/drm/drm_mipi_dsi.c 31 * (kernel linux). 32 * 33 */ 34 35#include <common.h> 36#include <clk.h> 37#include <display.h> 38#include <dm.h> 39#include <mipi_display.h> 40#include <mipi_dsi.h> 41#include <dm/devres.h> 42 43/** 44 * DOC: dsi helpers 45 * 46 * These functions contain some common logic and helpers to deal with MIPI DSI 47 * peripherals. 48 * 49 * Helpers are provided for a number of standard MIPI DSI command as well as a 50 * subset of the MIPI DCS command set. 51 */ 52 53/** 54 * mipi_dsi_attach - attach a DSI device to its DSI host 55 * @dsi: DSI peripheral 56 */ 57int mipi_dsi_attach(struct mipi_dsi_device *dsi) 58{ 59 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 60 61 if (!ops || !ops->attach) 62 return -ENOSYS; 63 64 return ops->attach(dsi->host, dsi); 65} 66EXPORT_SYMBOL(mipi_dsi_attach); 67 68/** 69 * mipi_dsi_detach - detach a DSI device from its DSI host 70 * @dsi: DSI peripheral 71 */ 72int mipi_dsi_detach(struct mipi_dsi_device *dsi) 73{ 74 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 75 76 if (!ops || !ops->detach) 77 return -ENOSYS; 78 79 return ops->detach(dsi->host, dsi); 80} 81EXPORT_SYMBOL(mipi_dsi_detach); 82 83/** 84 * mipi_dsi_device_transfer - transfer message to a DSI device 85 * @dsi: DSI peripheral 86 * @msg: message 87 */ 88static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, 89 struct mipi_dsi_msg *msg) 90{ 91 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 92 93 if (!ops || !ops->transfer) 94 return -ENOSYS; 95 96 if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 97 msg->flags |= MIPI_DSI_MSG_USE_LPM; 98 99 return ops->transfer(dsi->host, msg); 100} 101 102/** 103 * mipi_dsi_packet_format_is_short - check if a packet is of the short format 104 * @type: MIPI DSI data type of the packet 105 * 106 * Return: true if the packet for the given data type is a short packet, false 107 * otherwise. 108 */ 109bool mipi_dsi_packet_format_is_short(u8 type) 110{ 111 switch (type) { 112 case MIPI_DSI_V_SYNC_START: 113 case MIPI_DSI_V_SYNC_END: 114 case MIPI_DSI_H_SYNC_START: 115 case MIPI_DSI_H_SYNC_END: 116 case MIPI_DSI_END_OF_TRANSMISSION: 117 case MIPI_DSI_COLOR_MODE_OFF: 118 case MIPI_DSI_COLOR_MODE_ON: 119 case MIPI_DSI_SHUTDOWN_PERIPHERAL: 120 case MIPI_DSI_TURN_ON_PERIPHERAL: 121 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 122 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 123 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 124 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 125 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 126 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 127 case MIPI_DSI_DCS_SHORT_WRITE: 128 case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 129 case MIPI_DSI_DCS_READ: 130 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: 131 return true; 132 } 133 134 return false; 135} 136EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); 137 138/** 139 * mipi_dsi_packet_format_is_long - check if a packet is of the long format 140 * @type: MIPI DSI data type of the packet 141 * 142 * Return: true if the packet for the given data type is a long packet, false 143 * otherwise. 144 */ 145bool mipi_dsi_packet_format_is_long(u8 type) 146{ 147 switch (type) { 148 case MIPI_DSI_NULL_PACKET: 149 case MIPI_DSI_BLANKING_PACKET: 150 case MIPI_DSI_GENERIC_LONG_WRITE: 151 case MIPI_DSI_DCS_LONG_WRITE: 152 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: 153 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: 154 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: 155 case MIPI_DSI_PACKED_PIXEL_STREAM_30: 156 case MIPI_DSI_PACKED_PIXEL_STREAM_36: 157 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: 158 case MIPI_DSI_PACKED_PIXEL_STREAM_16: 159 case MIPI_DSI_PACKED_PIXEL_STREAM_18: 160 case MIPI_DSI_PIXEL_STREAM_3BYTE_18: 161 case MIPI_DSI_PACKED_PIXEL_STREAM_24: 162 return true; 163 } 164 165 return false; 166} 167EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); 168 169/** 170 * mipi_dsi_create_packet - create a packet from a message according to the 171 * DSI protocol 172 * @packet: pointer to a DSI packet structure 173 * @msg: message to translate into a packet 174 * 175 * Return: 0 on success or a negative error code on failure. 176 */ 177int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 178 const struct mipi_dsi_msg *msg) 179{ 180 if (!packet || !msg) 181 return -EINVAL; 182 183 /* do some minimum sanity checking */ 184 if (!mipi_dsi_packet_format_is_short(msg->type) && 185 !mipi_dsi_packet_format_is_long(msg->type)) 186 return -EINVAL; 187 188 if (msg->channel > 3) 189 return -EINVAL; 190 191 memset(packet, 0, sizeof(*packet)); 192 packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); 193 194 /* TODO: compute ECC if hardware support is not available */ 195 196 /* 197 * Long write packets contain the word count in header bytes 1 and 2. 198 * The payload follows the header and is word count bytes long. 199 * 200 * Short write packets encode up to two parameters in header bytes 1 201 * and 2. 202 */ 203 if (mipi_dsi_packet_format_is_long(msg->type)) { 204 packet->header[1] = (msg->tx_len >> 0) & 0xff; 205 packet->header[2] = (msg->tx_len >> 8) & 0xff; 206 207 packet->payload_length = msg->tx_len; 208 packet->payload = msg->tx_buf; 209 } else { 210 const u8 *tx = msg->tx_buf; 211 212 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 213 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 214 } 215 216 packet->size = sizeof(packet->header) + packet->payload_length; 217 218 return 0; 219} 220EXPORT_SYMBOL(mipi_dsi_create_packet); 221 222/** 223 * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command 224 * @dsi: DSI peripheral device 225 * 226 * Return: 0 on success or a negative error code on failure. 227 */ 228int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) 229{ 230 struct mipi_dsi_msg msg = { 231 .channel = dsi->channel, 232 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, 233 .tx_buf = (u8 [2]) { 0, 0 }, 234 .tx_len = 2, 235 }; 236 int ret = mipi_dsi_device_transfer(dsi, &msg); 237 238 return (ret < 0) ? ret : 0; 239} 240EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); 241 242/** 243 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command 244 * @dsi: DSI peripheral device 245 * 246 * Return: 0 on success or a negative error code on failure. 247 */ 248int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) 249{ 250 struct mipi_dsi_msg msg = { 251 .channel = dsi->channel, 252 .type = MIPI_DSI_TURN_ON_PERIPHERAL, 253 .tx_buf = (u8 [2]) { 0, 0 }, 254 .tx_len = 2, 255 }; 256 int ret = mipi_dsi_device_transfer(dsi, &msg); 257 258 return (ret < 0) ? ret : 0; 259} 260EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); 261 262/* 263 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the 264 * the payload in a long packet transmitted from the peripheral back to the 265 * host processor 266 * @dsi: DSI peripheral device 267 * @value: the maximum size of the payload 268 * 269 * Return: 0 on success or a negative error code on failure. 270 */ 271int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 272 u16 value) 273{ 274 u8 tx[2] = { value & 0xff, value >> 8 }; 275 struct mipi_dsi_msg msg = { 276 .channel = dsi->channel, 277 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 278 .tx_len = sizeof(tx), 279 .tx_buf = tx, 280 }; 281 int ret = mipi_dsi_device_transfer(dsi, &msg); 282 283 return (ret < 0) ? ret : 0; 284} 285EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 286 287/** 288 * mipi_dsi_generic_write() - transmit data using a generic write packet 289 * @dsi: DSI peripheral device 290 * @payload: buffer containing the payload 291 * @size: size of payload buffer 292 * 293 * This function will automatically choose the right data type depending on 294 * the payload length. 295 * 296 * Return: The number of bytes transmitted on success or a negative error code 297 * on failure. 298 */ 299ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 300 size_t size) 301{ 302 struct mipi_dsi_msg msg = { 303 .channel = dsi->channel, 304 .tx_buf = payload, 305 .tx_len = size 306 }; 307 308 switch (size) { 309 case 0: 310 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 311 break; 312 313 case 1: 314 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 315 break; 316 317 case 2: 318 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 319 break; 320 321 default: 322 msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 323 break; 324 } 325 326 return mipi_dsi_device_transfer(dsi, &msg); 327} 328EXPORT_SYMBOL(mipi_dsi_generic_write); 329 330/** 331 * mipi_dsi_generic_read() - receive data using a generic read packet 332 * @dsi: DSI peripheral device 333 * @params: buffer containing the request parameters 334 * @num_params: number of request parameters 335 * @data: buffer in which to return the received data 336 * @size: size of receive buffer 337 * 338 * This function will automatically choose the right data type depending on 339 * the number of parameters passed in. 340 * 341 * Return: The number of bytes successfully read or a negative error code on 342 * failure. 343 */ 344ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 345 size_t num_params, void *data, size_t size) 346{ 347 struct mipi_dsi_msg msg = { 348 .channel = dsi->channel, 349 .tx_len = num_params, 350 .tx_buf = params, 351 .rx_len = size, 352 .rx_buf = data 353 }; 354 355 switch (num_params) { 356 case 0: 357 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 358 break; 359 360 case 1: 361 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 362 break; 363 364 case 2: 365 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 366 break; 367 368 default: 369 return -EINVAL; 370 } 371 372 return mipi_dsi_device_transfer(dsi, &msg); 373} 374EXPORT_SYMBOL(mipi_dsi_generic_read); 375 376/** 377 * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 378 * @dsi: DSI peripheral device 379 * @data: buffer containing data to be transmitted 380 * @len: size of transmission buffer 381 * 382 * This function will automatically choose the right data type depending on 383 * the command payload length. 384 * 385 * Return: The number of bytes successfully transmitted or a negative error 386 * code on failure. 387 */ 388ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 389 const void *data, size_t len) 390{ 391 struct mipi_dsi_msg msg = { 392 .channel = dsi->channel, 393 .tx_buf = data, 394 .tx_len = len 395 }; 396 397 switch (len) { 398 case 0: 399 return -EINVAL; 400 401 case 1: 402 msg.type = MIPI_DSI_DCS_SHORT_WRITE; 403 break; 404 405 case 2: 406 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 407 break; 408 409 default: 410 msg.type = MIPI_DSI_DCS_LONG_WRITE; 411 break; 412 } 413 414 return mipi_dsi_device_transfer(dsi, &msg); 415} 416EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 417 418/** 419 * mipi_dsi_dcs_write() - send DCS write command 420 * @dsi: DSI peripheral device 421 * @cmd: DCS command 422 * @data: buffer containing the command payload 423 * @len: command payload length 424 * 425 * This function will automatically choose the right data type depending on 426 * the command payload length. 427 * 428 * Return: The number of bytes successfully transmitted or a negative error 429 * code on failure. 430 */ 431ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 432 const void *data, size_t len) 433{ 434 ssize_t err; 435 size_t size; 436 u8 *tx; 437 438 if (len > 0) { 439 size = 1 + len; 440 441 tx = kmalloc(size, GFP_KERNEL); 442 if (!tx) 443 return -ENOMEM; 444 445 /* concatenate the DCS command byte and the payload */ 446 tx[0] = cmd; 447 memcpy(&tx[1], data, len); 448 } else { 449 tx = &cmd; 450 size = 1; 451 } 452 453 err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 454 455 if (len > 0) 456 kfree(tx); 457 458 return err; 459} 460EXPORT_SYMBOL(mipi_dsi_dcs_write); 461 462/** 463 * mipi_dsi_dcs_read() - send DCS read request command 464 * @dsi: DSI peripheral device 465 * @cmd: DCS command 466 * @data: buffer in which to receive data 467 * @len: size of receive buffer 468 * 469 * Return: The number of bytes read or a negative error code on failure. 470 */ 471ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 472 size_t len) 473{ 474 struct mipi_dsi_msg msg = { 475 .channel = dsi->channel, 476 .type = MIPI_DSI_DCS_READ, 477 .tx_buf = &cmd, 478 .tx_len = 1, 479 .rx_buf = data, 480 .rx_len = len 481 }; 482 483 return mipi_dsi_device_transfer(dsi, &msg); 484} 485EXPORT_SYMBOL(mipi_dsi_dcs_read); 486 487/** 488 * mipi_dsi_dcs_nop() - send DCS nop packet 489 * @dsi: DSI peripheral device 490 * 491 * Return: 0 on success or a negative error code on failure. 492 */ 493int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 494{ 495 ssize_t err; 496 497 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 498 if (err < 0) 499 return err; 500 501 return 0; 502} 503EXPORT_SYMBOL(mipi_dsi_dcs_nop); 504 505/** 506 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 507 * @dsi: DSI peripheral device 508 * 509 * Return: 0 on success or a negative error code on failure. 510 */ 511int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 512{ 513 ssize_t err; 514 515 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 516 if (err < 0) 517 return err; 518 519 return 0; 520} 521EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 522 523/** 524 * mipi_dsi_dcs_get_power_mode() - query the display module's current power 525 * mode 526 * @dsi: DSI peripheral device 527 * @mode: return location for the current power mode 528 * 529 * Return: 0 on success or a negative error code on failure. 530 */ 531int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 532{ 533 ssize_t err; 534 535 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 536 sizeof(*mode)); 537 if (err <= 0) { 538 if (err == 0) 539 err = -ENODATA; 540 541 return err; 542 } 543 544 return 0; 545} 546EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 547 548/** 549 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 550 * data used by the interface 551 * @dsi: DSI peripheral device 552 * @format: return location for the pixel format 553 * 554 * Return: 0 on success or a negative error code on failure. 555 */ 556int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 557{ 558 ssize_t err; 559 560 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 561 sizeof(*format)); 562 if (err <= 0) { 563 if (err == 0) 564 err = -ENODATA; 565 566 return err; 567 } 568 569 return 0; 570} 571EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 572 573/** 574 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 575 * display module except interface communication 576 * @dsi: DSI peripheral device 577 * 578 * Return: 0 on success or a negative error code on failure. 579 */ 580int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 581{ 582 ssize_t err; 583 584 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 585 if (err < 0) 586 return err; 587 588 return 0; 589} 590EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 591 592/** 593 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 594 * module 595 * @dsi: DSI peripheral device 596 * 597 * Return: 0 on success or a negative error code on failure. 598 */ 599int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 600{ 601 ssize_t err; 602 603 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 604 if (err < 0) 605 return err; 606 607 return 0; 608} 609EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 610 611/** 612 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 613 * display device 614 * @dsi: DSI peripheral device 615 * 616 * Return: 0 on success or a negative error code on failure. 617 */ 618int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 619{ 620 ssize_t err; 621 622 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 623 if (err < 0) 624 return err; 625 626 return 0; 627} 628EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 629 630/** 631 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 632 * display device 633 * @dsi: DSI peripheral device 634 * 635 * Return: 0 on success or a negative error code on failure 636 */ 637int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 638{ 639 ssize_t err; 640 641 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 642 if (err < 0) 643 return err; 644 645 return 0; 646} 647EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 648 649/** 650 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 651 * memory accessed by the host processor 652 * @dsi: DSI peripheral device 653 * @start: first column of frame memory 654 * @end: last column of frame memory 655 * 656 * Return: 0 on success or a negative error code on failure. 657 */ 658int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 659 u16 end) 660{ 661 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 662 ssize_t err; 663 664 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 665 sizeof(payload)); 666 if (err < 0) 667 return err; 668 669 return 0; 670} 671EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 672 673/** 674 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 675 * memory accessed by the host processor 676 * @dsi: DSI peripheral device 677 * @start: first page of frame memory 678 * @end: last page of frame memory 679 * 680 * Return: 0 on success or a negative error code on failure. 681 */ 682int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 683 u16 end) 684{ 685 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 686 ssize_t err; 687 688 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 689 sizeof(payload)); 690 if (err < 0) 691 return err; 692 693 return 0; 694} 695EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 696 697/** 698 * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect 699 * output signal on the TE signal line 700 * @dsi: DSI peripheral device 701 * 702 * Return: 0 on success or a negative error code on failure 703 */ 704int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) 705{ 706 ssize_t err; 707 708 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 709 if (err < 0) 710 return err; 711 712 return 0; 713} 714EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); 715 716/** 717 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 718 * output signal on the TE signal line. 719 * @dsi: DSI peripheral device 720 * @mode: the Tearing Effect Output Line mode 721 * 722 * Return: 0 on success or a negative error code on failure 723 */ 724int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 725 enum mipi_dsi_dcs_tear_mode mode) 726{ 727 u8 value = mode; 728 ssize_t err; 729 730 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 731 sizeof(value)); 732 if (err < 0) 733 return err; 734 735 return 0; 736} 737EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 738 739/** 740 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 741 * data used by the interface 742 * @dsi: DSI peripheral device 743 * @format: pixel format 744 * 745 * Return: 0 on success or a negative error code on failure. 746 */ 747int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 748{ 749 ssize_t err; 750 751 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 752 sizeof(format)); 753 if (err < 0) 754 return err; 755 756 return 0; 757} 758EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 759 760/** 761 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 762 * the Tearing Effect output signal of the display module 763 * @dsi: DSI peripheral device 764 * @scanline: scanline to use as trigger 765 * 766 * Return: 0 on success or a negative error code on failure 767 */ 768int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 769{ 770 u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, 771 scanline & 0xff }; 772 ssize_t err; 773 774 err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); 775 if (err < 0) 776 return err; 777 778 return 0; 779} 780EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 781 782/** 783 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 784 * display 785 * @dsi: DSI peripheral device 786 * @brightness: brightness value 787 * 788 * Return: 0 on success or a negative error code on failure. 789 */ 790int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 791 u16 brightness) 792{ 793 u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 794 ssize_t err; 795 796 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 797 payload, sizeof(payload)); 798 if (err < 0) 799 return err; 800 801 return 0; 802} 803EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 804 805/** 806 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 807 * of the display 808 * @dsi: DSI peripheral device 809 * @brightness: brightness value 810 * 811 * Return: 0 on success or a negative error code on failure. 812 */ 813int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 814 u16 *brightness) 815{ 816 ssize_t err; 817 818 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 819 brightness, sizeof(*brightness)); 820 if (err <= 0) { 821 if (err == 0) 822 err = -ENODATA; 823 824 return err; 825 } 826 827 return 0; 828} 829EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 830