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