1 /* 2 * MIPI DSI Bus 3 * 4 * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. 5 * Andrzej Hajda <a.hajda@samsung.com> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25 * USE OR OTHER DEALINGS IN THE SOFTWARE. 26 */ 27 28 #include <linux/device.h> 29 #include <linux/export.h> 30 #include <linux/module.h> 31 #include <linux/of.h> 32 #include <linux/of_device.h> 33 #include <linux/pm_runtime.h> 34 #include <linux/slab.h> 35 36 #include <drm/display/drm_dsc.h> 37 #include <drm/drm_mipi_dsi.h> 38 #include <drm/drm_print.h> 39 40 #include <linux/media-bus-format.h> 41 42 #include <video/mipi_display.h> 43 44 /** 45 * DOC: dsi helpers 46 * 47 * These functions contain some common logic and helpers to deal with MIPI DSI 48 * peripherals. 49 * 50 * Helpers are provided for a number of standard MIPI DSI command as well as a 51 * subset of the MIPI DCS command set. 52 */ 53 54 static int mipi_dsi_device_match(struct device *dev, const struct device_driver *drv) 55 { 56 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 57 58 /* attempt OF style match */ 59 if (of_driver_match_device(dev, drv)) 60 return 1; 61 62 /* compare DSI device and driver names */ 63 if (!strcmp(dsi->name, drv->name)) 64 return 1; 65 66 return 0; 67 } 68 69 static int mipi_dsi_uevent(const struct device *dev, struct kobj_uevent_env *env) 70 { 71 const struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 72 int err; 73 74 err = of_device_uevent_modalias(dev, env); 75 if (err != -ENODEV) 76 return err; 77 78 add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX, 79 dsi->name); 80 81 return 0; 82 } 83 84 static const struct dev_pm_ops mipi_dsi_device_pm_ops = { 85 .runtime_suspend = pm_generic_runtime_suspend, 86 .runtime_resume = pm_generic_runtime_resume, 87 .suspend = pm_generic_suspend, 88 .resume = pm_generic_resume, 89 .freeze = pm_generic_freeze, 90 .thaw = pm_generic_thaw, 91 .poweroff = pm_generic_poweroff, 92 .restore = pm_generic_restore, 93 }; 94 95 const struct bus_type mipi_dsi_bus_type = { 96 .name = "mipi-dsi", 97 .match = mipi_dsi_device_match, 98 .uevent = mipi_dsi_uevent, 99 .pm = &mipi_dsi_device_pm_ops, 100 }; 101 EXPORT_SYMBOL_GPL(mipi_dsi_bus_type); 102 103 /** 104 * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a 105 * device tree node 106 * @np: device tree node 107 * 108 * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no 109 * such device exists (or has not been registered yet). 110 */ 111 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np) 112 { 113 struct device *dev; 114 115 dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np); 116 117 return dev ? to_mipi_dsi_device(dev) : NULL; 118 } 119 EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node); 120 121 static void mipi_dsi_dev_release(struct device *dev) 122 { 123 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 124 125 of_node_put(dev->of_node); 126 kfree(dsi); 127 } 128 129 static const struct device_type mipi_dsi_device_type = { 130 .release = mipi_dsi_dev_release, 131 }; 132 133 static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host) 134 { 135 struct mipi_dsi_device *dsi; 136 137 dsi = kzalloc_obj(*dsi); 138 if (!dsi) 139 return ERR_PTR(-ENOMEM); 140 141 dsi->host = host; 142 dsi->dev.bus = &mipi_dsi_bus_type; 143 dsi->dev.parent = host->dev; 144 dsi->dev.type = &mipi_dsi_device_type; 145 146 device_initialize(&dsi->dev); 147 148 return dsi; 149 } 150 151 static int mipi_dsi_device_add(struct mipi_dsi_device *dsi) 152 { 153 struct mipi_dsi_host *host = dsi->host; 154 155 dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), dsi->channel); 156 157 return device_add(&dsi->dev); 158 } 159 160 #if IS_ENABLED(CONFIG_OF) 161 static struct mipi_dsi_device * 162 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) 163 { 164 struct mipi_dsi_device_info info = { }; 165 int ret; 166 u32 reg; 167 168 if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { 169 dev_err(host->dev, "modalias failure on %pOF\n", node); 170 return ERR_PTR(-EINVAL); 171 } 172 173 ret = of_property_read_u32(node, "reg", ®); 174 if (ret) { 175 dev_err(host->dev, "device node %pOF has no valid reg property: %d\n", 176 node, ret); 177 return ERR_PTR(-EINVAL); 178 } 179 180 info.channel = reg; 181 info.node = of_node_get(node); 182 183 return mipi_dsi_device_register_full(host, &info); 184 } 185 #else 186 static struct mipi_dsi_device * 187 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) 188 { 189 return ERR_PTR(-ENODEV); 190 } 191 #endif 192 193 /** 194 * mipi_dsi_device_register_full - create a MIPI DSI device 195 * @host: DSI host to which this device is connected 196 * @info: pointer to template containing DSI device information 197 * 198 * Create a MIPI DSI device by using the device information provided by 199 * mipi_dsi_device_info template 200 * 201 * Returns: 202 * A pointer to the newly created MIPI DSI device, or, a pointer encoded 203 * with an error 204 */ 205 struct mipi_dsi_device * 206 mipi_dsi_device_register_full(struct mipi_dsi_host *host, 207 const struct mipi_dsi_device_info *info) 208 { 209 struct mipi_dsi_device *dsi; 210 int ret; 211 212 if (!info) { 213 dev_err(host->dev, "invalid mipi_dsi_device_info pointer\n"); 214 return ERR_PTR(-EINVAL); 215 } 216 217 if (info->channel > 3) { 218 dev_err(host->dev, "invalid virtual channel: %u\n", info->channel); 219 return ERR_PTR(-EINVAL); 220 } 221 222 dsi = mipi_dsi_device_alloc(host); 223 if (IS_ERR(dsi)) { 224 dev_err(host->dev, "failed to allocate DSI device %ld\n", 225 PTR_ERR(dsi)); 226 return dsi; 227 } 228 229 device_set_node(&dsi->dev, of_fwnode_handle(info->node)); 230 dsi->channel = info->channel; 231 strscpy(dsi->name, info->type, sizeof(dsi->name)); 232 233 ret = mipi_dsi_device_add(dsi); 234 if (ret) { 235 dev_err(host->dev, "failed to add DSI device %d\n", ret); 236 kfree(dsi); 237 return ERR_PTR(ret); 238 } 239 240 return dsi; 241 } 242 EXPORT_SYMBOL(mipi_dsi_device_register_full); 243 244 /** 245 * mipi_dsi_device_unregister - unregister MIPI DSI device 246 * @dsi: DSI peripheral device 247 */ 248 void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi) 249 { 250 device_unregister(&dsi->dev); 251 } 252 EXPORT_SYMBOL(mipi_dsi_device_unregister); 253 254 static void devm_mipi_dsi_device_unregister(void *arg) 255 { 256 struct mipi_dsi_device *dsi = arg; 257 258 mipi_dsi_device_unregister(dsi); 259 } 260 261 /** 262 * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device 263 * @dev: device to tie the MIPI-DSI device lifetime to 264 * @host: DSI host to which this device is connected 265 * @info: pointer to template containing DSI device information 266 * 267 * Create a MIPI DSI device by using the device information provided by 268 * mipi_dsi_device_info template 269 * 270 * This is the managed version of mipi_dsi_device_register_full() which 271 * automatically calls mipi_dsi_device_unregister() when @dev is 272 * unbound. 273 * 274 * Returns: 275 * A pointer to the newly created MIPI DSI device, or, a pointer encoded 276 * with an error 277 */ 278 struct mipi_dsi_device * 279 devm_mipi_dsi_device_register_full(struct device *dev, 280 struct mipi_dsi_host *host, 281 const struct mipi_dsi_device_info *info) 282 { 283 struct mipi_dsi_device *dsi; 284 int ret; 285 286 dsi = mipi_dsi_device_register_full(host, info); 287 if (IS_ERR(dsi)) 288 return dsi; 289 290 ret = devm_add_action_or_reset(dev, 291 devm_mipi_dsi_device_unregister, 292 dsi); 293 if (ret) 294 return ERR_PTR(ret); 295 296 return dsi; 297 } 298 EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full); 299 300 static DEFINE_MUTEX(host_lock); 301 static LIST_HEAD(host_list); 302 303 /** 304 * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a 305 * device tree node 306 * @node: device tree node 307 * 308 * Returns: 309 * A pointer to the MIPI DSI host corresponding to @node or NULL if no 310 * such device exists (or has not been registered yet). 311 */ 312 struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node) 313 { 314 struct mipi_dsi_host *host; 315 316 mutex_lock(&host_lock); 317 318 list_for_each_entry(host, &host_list, list) { 319 if (host->dev->of_node == node) { 320 mutex_unlock(&host_lock); 321 return host; 322 } 323 } 324 325 mutex_unlock(&host_lock); 326 327 return NULL; 328 } 329 EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node); 330 331 int mipi_dsi_host_register(struct mipi_dsi_host *host) 332 { 333 struct device_node *node; 334 335 for_each_available_child_of_node(host->dev->of_node, node) { 336 /* skip nodes without reg property */ 337 if (!of_property_present(node, "reg")) 338 continue; 339 of_mipi_dsi_device_add(host, node); 340 } 341 342 mutex_lock(&host_lock); 343 list_add_tail(&host->list, &host_list); 344 mutex_unlock(&host_lock); 345 346 return 0; 347 } 348 EXPORT_SYMBOL(mipi_dsi_host_register); 349 350 static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) 351 { 352 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 353 354 if (dsi->attached) 355 mipi_dsi_detach(dsi); 356 mipi_dsi_device_unregister(dsi); 357 358 return 0; 359 } 360 361 void mipi_dsi_host_unregister(struct mipi_dsi_host *host) 362 { 363 device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); 364 365 mutex_lock(&host_lock); 366 list_del_init(&host->list); 367 mutex_unlock(&host_lock); 368 } 369 EXPORT_SYMBOL(mipi_dsi_host_unregister); 370 371 /** 372 * mipi_dsi_attach - attach a DSI device to its DSI host 373 * @dsi: DSI peripheral 374 */ 375 int mipi_dsi_attach(struct mipi_dsi_device *dsi) 376 { 377 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 378 int ret; 379 380 if (!ops || !ops->attach) 381 return -ENOSYS; 382 383 ret = ops->attach(dsi->host, dsi); 384 if (ret) 385 return ret; 386 387 dsi->attached = true; 388 389 return 0; 390 } 391 EXPORT_SYMBOL(mipi_dsi_attach); 392 393 /** 394 * mipi_dsi_detach - detach a DSI device from its DSI host 395 * @dsi: DSI peripheral 396 */ 397 int mipi_dsi_detach(struct mipi_dsi_device *dsi) 398 { 399 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 400 401 if (WARN_ON(!dsi->attached)) 402 return -EINVAL; 403 404 if (!ops || !ops->detach) 405 return -ENOSYS; 406 407 dsi->attached = false; 408 409 return ops->detach(dsi->host, dsi); 410 } 411 EXPORT_SYMBOL(mipi_dsi_detach); 412 413 static void devm_mipi_dsi_detach(void *arg) 414 { 415 struct mipi_dsi_device *dsi = arg; 416 417 mipi_dsi_detach(dsi); 418 } 419 420 /** 421 * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host 422 * @dev: device to tie the MIPI-DSI device attachment lifetime to 423 * @dsi: DSI peripheral 424 * 425 * This is the managed version of mipi_dsi_attach() which automatically 426 * calls mipi_dsi_detach() when @dev is unbound. 427 * 428 * Returns: 429 * 0 on success, a negative error code on failure. 430 */ 431 int devm_mipi_dsi_attach(struct device *dev, 432 struct mipi_dsi_device *dsi) 433 { 434 int ret; 435 436 ret = mipi_dsi_attach(dsi); 437 if (ret) 438 return ret; 439 440 ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi); 441 if (ret) 442 return ret; 443 444 return 0; 445 } 446 EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach); 447 448 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, 449 struct mipi_dsi_msg *msg) 450 { 451 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 452 453 if (!ops || !ops->transfer) 454 return -ENOSYS; 455 456 if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 457 msg->flags |= MIPI_DSI_MSG_USE_LPM; 458 459 return ops->transfer(dsi->host, msg); 460 } 461 462 /** 463 * mipi_dsi_packet_format_is_short - check if a packet is of the short format 464 * @type: MIPI DSI data type of the packet 465 * 466 * Return: true if the packet for the given data type is a short packet, false 467 * otherwise. 468 */ 469 bool mipi_dsi_packet_format_is_short(u8 type) 470 { 471 switch (type) { 472 case MIPI_DSI_V_SYNC_START: 473 case MIPI_DSI_V_SYNC_END: 474 case MIPI_DSI_H_SYNC_START: 475 case MIPI_DSI_H_SYNC_END: 476 case MIPI_DSI_COMPRESSION_MODE: 477 case MIPI_DSI_END_OF_TRANSMISSION: 478 case MIPI_DSI_COLOR_MODE_OFF: 479 case MIPI_DSI_COLOR_MODE_ON: 480 case MIPI_DSI_SHUTDOWN_PERIPHERAL: 481 case MIPI_DSI_TURN_ON_PERIPHERAL: 482 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 483 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 484 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 485 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 486 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 487 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 488 case MIPI_DSI_DCS_SHORT_WRITE: 489 case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 490 case MIPI_DSI_DCS_READ: 491 case MIPI_DSI_EXECUTE_QUEUE: 492 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: 493 return true; 494 } 495 496 return false; 497 } 498 EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); 499 500 /** 501 * mipi_dsi_packet_format_is_long - check if a packet is of the long format 502 * @type: MIPI DSI data type of the packet 503 * 504 * Return: true if the packet for the given data type is a long packet, false 505 * otherwise. 506 */ 507 bool mipi_dsi_packet_format_is_long(u8 type) 508 { 509 switch (type) { 510 case MIPI_DSI_NULL_PACKET: 511 case MIPI_DSI_BLANKING_PACKET: 512 case MIPI_DSI_GENERIC_LONG_WRITE: 513 case MIPI_DSI_DCS_LONG_WRITE: 514 case MIPI_DSI_PICTURE_PARAMETER_SET: 515 case MIPI_DSI_COMPRESSED_PIXEL_STREAM: 516 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: 517 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: 518 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: 519 case MIPI_DSI_PACKED_PIXEL_STREAM_30: 520 case MIPI_DSI_PACKED_PIXEL_STREAM_36: 521 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: 522 case MIPI_DSI_PACKED_PIXEL_STREAM_16: 523 case MIPI_DSI_PACKED_PIXEL_STREAM_18: 524 case MIPI_DSI_PIXEL_STREAM_3BYTE_18: 525 case MIPI_DSI_PACKED_PIXEL_STREAM_24: 526 return true; 527 } 528 529 return false; 530 } 531 EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); 532 533 /** 534 * mipi_dsi_create_packet - create a packet from a message according to the 535 * DSI protocol 536 * @packet: pointer to a DSI packet structure 537 * @msg: message to translate into a packet 538 * 539 * Return: 0 on success or a negative error code on failure. 540 */ 541 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 542 const struct mipi_dsi_msg *msg) 543 { 544 if (!packet || !msg) 545 return -EINVAL; 546 547 /* do some minimum sanity checking */ 548 if (!mipi_dsi_packet_format_is_short(msg->type) && 549 !mipi_dsi_packet_format_is_long(msg->type)) 550 return -EINVAL; 551 552 if (msg->channel > 3) 553 return -EINVAL; 554 555 memset(packet, 0, sizeof(*packet)); 556 packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); 557 558 /* TODO: compute ECC if hardware support is not available */ 559 560 /* 561 * Long write packets contain the word count in header bytes 1 and 2. 562 * The payload follows the header and is word count bytes long. 563 * 564 * Short write packets encode up to two parameters in header bytes 1 565 * and 2. 566 */ 567 if (mipi_dsi_packet_format_is_long(msg->type)) { 568 packet->header[1] = (msg->tx_len >> 0) & 0xff; 569 packet->header[2] = (msg->tx_len >> 8) & 0xff; 570 571 packet->payload_length = msg->tx_len; 572 packet->payload = msg->tx_buf; 573 } else { 574 const u8 *tx = msg->tx_buf; 575 576 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 577 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 578 } 579 580 packet->size = sizeof(packet->header) + packet->payload_length; 581 582 return 0; 583 } 584 EXPORT_SYMBOL(mipi_dsi_create_packet); 585 586 /** 587 * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command 588 * @dsi: DSI peripheral device 589 * 590 * This function is deprecated. Use mipi_dsi_shutdown_peripheral_multi() 591 * instead. 592 * 593 * Return: 0 on success or a negative error code on failure. 594 */ 595 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) 596 { 597 struct mipi_dsi_msg msg = { 598 .channel = dsi->channel, 599 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, 600 .tx_buf = (u8 [2]) { 0, 0 }, 601 .tx_len = 2, 602 }; 603 int ret = mipi_dsi_device_transfer(dsi, &msg); 604 605 return (ret < 0) ? ret : 0; 606 } 607 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); 608 609 /** 610 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command 611 * @dsi: DSI peripheral device 612 * 613 * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() instead. 614 * 615 * Return: 0 on success or a negative error code on failure. 616 */ 617 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) 618 { 619 struct mipi_dsi_msg msg = { 620 .channel = dsi->channel, 621 .type = MIPI_DSI_TURN_ON_PERIPHERAL, 622 .tx_buf = (u8 [2]) { 0, 0 }, 623 .tx_len = 2, 624 }; 625 int ret = mipi_dsi_device_transfer(dsi, &msg); 626 627 return (ret < 0) ? ret : 0; 628 } 629 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); 630 631 /* 632 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of 633 * the payload in a long packet transmitted from the peripheral back to the 634 * host processor 635 * @dsi: DSI peripheral device 636 * @value: the maximum size of the payload 637 * 638 * Return: 0 on success or a negative error code on failure. 639 */ 640 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 641 u16 value) 642 { 643 u8 tx[2] = { value & 0xff, value >> 8 }; 644 struct mipi_dsi_msg msg = { 645 .channel = dsi->channel, 646 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 647 .tx_len = sizeof(tx), 648 .tx_buf = tx, 649 }; 650 int ret = mipi_dsi_device_transfer(dsi, &msg); 651 652 return (ret < 0) ? ret : 0; 653 } 654 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 655 656 /** 657 * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral 658 * @dsi: DSI peripheral device 659 * @enable: Whether to enable or disable the DSC 660 * @algo: Selected compression algorithm 661 * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries 662 * 663 * Enable or disable Display Stream Compression on the peripheral. 664 * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() instead. 665 * 666 * Return: 0 on success or a negative error code on failure. 667 */ 668 int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, 669 enum mipi_dsi_compression_algo algo, 670 unsigned int pps_selector) 671 { 672 u8 tx[2] = { }; 673 struct mipi_dsi_msg msg = { 674 .channel = dsi->channel, 675 .type = MIPI_DSI_COMPRESSION_MODE, 676 .tx_len = sizeof(tx), 677 .tx_buf = tx, 678 }; 679 int ret; 680 681 if (algo > 3 || pps_selector > 3) 682 return -EINVAL; 683 684 tx[0] = (enable << 0) | 685 (algo << 1) | 686 (pps_selector << 4); 687 688 ret = mipi_dsi_device_transfer(dsi, &msg); 689 690 return (ret < 0) ? ret : 0; 691 } 692 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext); 693 694 /** 695 * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral 696 * @dsi: DSI peripheral device 697 * @enable: Whether to enable or disable the DSC 698 * 699 * Enable or disable Display Stream Compression on the peripheral using the 700 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 701 * 702 * Return: 0 on success or a negative error code on failure. 703 */ 704 int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) 705 { 706 return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0); 707 } 708 EXPORT_SYMBOL(mipi_dsi_compression_mode); 709 710 /** 711 * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral 712 * @dsi: DSI peripheral device 713 * @pps: VESA DSC 1.1 Picture Parameter Set 714 * 715 * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. 716 * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() instead. 717 * 718 * Return: 0 on success or a negative error code on failure. 719 */ 720 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, 721 const struct drm_dsc_picture_parameter_set *pps) 722 { 723 struct mipi_dsi_msg msg = { 724 .channel = dsi->channel, 725 .type = MIPI_DSI_PICTURE_PARAMETER_SET, 726 .tx_len = sizeof(*pps), 727 .tx_buf = pps, 728 }; 729 int ret = mipi_dsi_device_transfer(dsi, &msg); 730 731 return (ret < 0) ? ret : 0; 732 } 733 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set); 734 735 /** 736 * mipi_dsi_generic_write() - transmit data using a generic write packet 737 * @dsi: DSI peripheral device 738 * @payload: buffer containing the payload 739 * @size: size of payload buffer 740 * 741 * This function will automatically choose the right data type depending on 742 * the payload length. 743 * 744 * Return: The number of bytes transmitted on success or a negative error code 745 * on failure. 746 */ 747 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 748 size_t size) 749 { 750 struct mipi_dsi_msg msg = { 751 .channel = dsi->channel, 752 .tx_buf = payload, 753 .tx_len = size 754 }; 755 756 switch (size) { 757 case 0: 758 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 759 break; 760 761 case 1: 762 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 763 break; 764 765 case 2: 766 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 767 break; 768 769 default: 770 msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 771 break; 772 } 773 774 return mipi_dsi_device_transfer(dsi, &msg); 775 } 776 EXPORT_SYMBOL(mipi_dsi_generic_write); 777 778 /** 779 * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write() w/ accum_err 780 * @ctx: Context for multiple DSI transactions 781 * @payload: buffer containing the payload 782 * @size: size of payload buffer 783 * 784 * A wrapper around mipi_dsi_generic_write() that deals with errors in a way 785 * that makes it convenient to make several calls in a row. 786 */ 787 void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, 788 const void *payload, size_t size) 789 { 790 struct mipi_dsi_device *dsi = ctx->dsi; 791 struct device *dev = &dsi->dev; 792 ssize_t ret; 793 794 if (ctx->accum_err) 795 return; 796 797 ret = mipi_dsi_generic_write(dsi, payload, size); 798 if (ret < 0) { 799 ctx->accum_err = ret; 800 dev_err(dev, "sending generic data %*ph failed: %d\n", 801 (int)size, payload, ctx->accum_err); 802 } 803 } 804 EXPORT_SYMBOL(mipi_dsi_generic_write_multi); 805 806 /** 807 * mipi_dsi_dual_generic_write_multi() - mipi_dsi_generic_write_multi() for 808 * two dsi channels, one after the other 809 * @ctx: Context for multiple DSI transactions 810 * @dsi1: First dsi channel to write buffer to 811 * @dsi2: Second dsi channel to write buffer to 812 * @payload: Buffer containing the payload 813 * @size: Size of payload buffer 814 * 815 * A wrapper around mipi_dsi_generic_write_multi() that allows the user to 816 * conveniently write to two dsi channels, one after the other. 817 */ 818 void mipi_dsi_dual_generic_write_multi(struct mipi_dsi_multi_context *ctx, 819 struct mipi_dsi_device *dsi1, 820 struct mipi_dsi_device *dsi2, 821 const void *payload, size_t size) 822 { 823 ctx->dsi = dsi1; 824 mipi_dsi_generic_write_multi(ctx, payload, size); 825 ctx->dsi = dsi2; 826 mipi_dsi_generic_write_multi(ctx, payload, size); 827 } 828 EXPORT_SYMBOL(mipi_dsi_dual_generic_write_multi); 829 830 /** 831 * mipi_dsi_generic_read() - receive data using a generic read packet 832 * @dsi: DSI peripheral device 833 * @params: buffer containing the request parameters 834 * @num_params: number of request parameters 835 * @data: buffer in which to return the received data 836 * @size: size of receive buffer 837 * 838 * This function will automatically choose the right data type depending on 839 * the number of parameters passed in. 840 * 841 * Return: The number of bytes successfully read or a negative error code on 842 * failure. 843 */ 844 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 845 size_t num_params, void *data, size_t size) 846 { 847 struct mipi_dsi_msg msg = { 848 .channel = dsi->channel, 849 .tx_len = num_params, 850 .tx_buf = params, 851 .rx_len = size, 852 .rx_buf = data 853 }; 854 855 switch (num_params) { 856 case 0: 857 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 858 break; 859 860 case 1: 861 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 862 break; 863 864 case 2: 865 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 866 break; 867 868 default: 869 return -EINVAL; 870 } 871 872 return mipi_dsi_device_transfer(dsi, &msg); 873 } 874 EXPORT_SYMBOL(mipi_dsi_generic_read); 875 876 /** 877 * drm_mipi_dsi_get_input_bus_fmt() - Get the required MEDIA_BUS_FMT_* based 878 * input pixel format for a given DSI output 879 * pixel format 880 * @dsi_format: pixel format that a DSI host needs to output 881 * 882 * Various DSI hosts can use this function during their 883 * &drm_bridge_funcs.atomic_get_input_bus_fmts operation to ascertain 884 * the MEDIA_BUS_FMT_* pixel format required as input. 885 * 886 * RETURNS: 887 * a 32-bit MEDIA_BUS_FMT_* value on success or 0 in case of failure. 888 */ 889 u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format) 890 { 891 switch (dsi_format) { 892 case MIPI_DSI_FMT_RGB888: 893 return MEDIA_BUS_FMT_RGB888_1X24; 894 895 case MIPI_DSI_FMT_RGB666: 896 return MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 897 898 case MIPI_DSI_FMT_RGB666_PACKED: 899 return MEDIA_BUS_FMT_RGB666_1X18; 900 901 case MIPI_DSI_FMT_RGB565: 902 return MEDIA_BUS_FMT_RGB565_1X16; 903 904 default: 905 /* Unsupported DSI Format */ 906 return 0; 907 } 908 } 909 EXPORT_SYMBOL(drm_mipi_dsi_get_input_bus_fmt); 910 911 /** 912 * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 913 * @dsi: DSI peripheral device 914 * @data: buffer containing data to be transmitted 915 * @len: size of transmission buffer 916 * 917 * This function will automatically choose the right data type depending on 918 * the command payload length. 919 * 920 * Return: The number of bytes successfully transmitted or a negative error 921 * code on failure. 922 */ 923 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 924 const void *data, size_t len) 925 { 926 struct mipi_dsi_msg msg = { 927 .channel = dsi->channel, 928 .tx_buf = data, 929 .tx_len = len 930 }; 931 932 switch (len) { 933 case 0: 934 return -EINVAL; 935 936 case 1: 937 msg.type = MIPI_DSI_DCS_SHORT_WRITE; 938 break; 939 940 case 2: 941 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 942 break; 943 944 default: 945 msg.type = MIPI_DSI_DCS_LONG_WRITE; 946 break; 947 } 948 949 return mipi_dsi_device_transfer(dsi, &msg); 950 } 951 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 952 953 /** 954 * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log 955 * @dsi: DSI peripheral device 956 * @data: buffer containing data to be transmitted 957 * @len: size of transmission buffer 958 * 959 * Like mipi_dsi_dcs_write_buffer() but includes a dev_err() 960 * call for you and returns 0 upon success, not the number of bytes sent. 961 * 962 * Return: 0 on success or a negative error code on failure. 963 */ 964 int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, 965 const void *data, size_t len) 966 { 967 struct device *dev = &dsi->dev; 968 ssize_t ret; 969 970 ret = mipi_dsi_dcs_write_buffer(dsi, data, len); 971 if (ret < 0) { 972 dev_err(dev, "sending dcs data %*ph failed: %zd\n", 973 (int)len, data, ret); 974 return ret; 975 } 976 977 return 0; 978 } 979 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty); 980 981 /** 982 * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err 983 * @ctx: Context for multiple DSI transactions 984 * @data: buffer containing data to be transmitted 985 * @len: size of transmission buffer 986 * 987 * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that 988 * makes it convenient to make several calls in a row. 989 */ 990 void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, 991 const void *data, size_t len) 992 { 993 struct mipi_dsi_device *dsi = ctx->dsi; 994 struct device *dev = &dsi->dev; 995 ssize_t ret; 996 997 if (ctx->accum_err) 998 return; 999 1000 ret = mipi_dsi_dcs_write_buffer(dsi, data, len); 1001 if (ret < 0) { 1002 ctx->accum_err = ret; 1003 dev_err(dev, "sending dcs data %*ph failed: %d\n", 1004 (int)len, data, ctx->accum_err); 1005 } 1006 } 1007 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi); 1008 1009 /** 1010 * mipi_dsi_dual_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_multi() for 1011 * two dsi channels, one after the other 1012 * @ctx: Context for multiple DSI transactions 1013 * @dsi1: First dsi channel to write buffer to 1014 * @dsi2: Second dsi channel to write buffer to 1015 * @data: Buffer containing data to be transmitted 1016 * @len: Size of transmission buffer 1017 * 1018 * A wrapper around mipi_dsi_dcs_write_buffer_multi() that allows the user to 1019 * conveniently write to two dsi channels, one after the other. 1020 */ 1021 void mipi_dsi_dual_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, 1022 struct mipi_dsi_device *dsi1, 1023 struct mipi_dsi_device *dsi2, 1024 const void *data, size_t len) 1025 { 1026 ctx->dsi = dsi1; 1027 mipi_dsi_dcs_write_buffer_multi(ctx, data, len); 1028 ctx->dsi = dsi2; 1029 mipi_dsi_dcs_write_buffer_multi(ctx, data, len); 1030 } 1031 EXPORT_SYMBOL(mipi_dsi_dual_dcs_write_buffer_multi); 1032 1033 /** 1034 * mipi_dsi_dcs_write() - send DCS write command 1035 * @dsi: DSI peripheral device 1036 * @cmd: DCS command 1037 * @data: buffer containing the command payload 1038 * @len: command payload length 1039 * 1040 * This function will automatically choose the right data type depending on 1041 * the command payload length. 1042 * 1043 * Return: The number of bytes successfully transmitted or a negative error 1044 * code on failure. 1045 */ 1046 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 1047 const void *data, size_t len) 1048 { 1049 ssize_t err; 1050 size_t size; 1051 u8 stack_tx[8]; 1052 u8 *tx; 1053 1054 size = 1 + len; 1055 if (len > ARRAY_SIZE(stack_tx) - 1) { 1056 tx = kmalloc(size, GFP_KERNEL); 1057 if (!tx) 1058 return -ENOMEM; 1059 } else { 1060 tx = stack_tx; 1061 } 1062 1063 /* concatenate the DCS command byte and the payload */ 1064 tx[0] = cmd; 1065 if (data) 1066 memcpy(&tx[1], data, len); 1067 1068 err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 1069 1070 if (tx != stack_tx) 1071 kfree(tx); 1072 1073 return err; 1074 } 1075 EXPORT_SYMBOL(mipi_dsi_dcs_write); 1076 1077 /** 1078 * mipi_dsi_dcs_read() - send DCS read request command 1079 * @dsi: DSI peripheral device 1080 * @cmd: DCS command 1081 * @data: buffer in which to receive data 1082 * @len: size of receive buffer 1083 * 1084 * Return: The number of bytes read or a negative error code on failure. 1085 */ 1086 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 1087 size_t len) 1088 { 1089 struct mipi_dsi_msg msg = { 1090 .channel = dsi->channel, 1091 .type = MIPI_DSI_DCS_READ, 1092 .tx_buf = &cmd, 1093 .tx_len = 1, 1094 .rx_buf = data, 1095 .rx_len = len 1096 }; 1097 1098 return mipi_dsi_device_transfer(dsi, &msg); 1099 } 1100 EXPORT_SYMBOL(mipi_dsi_dcs_read); 1101 1102 /** 1103 * mipi_dsi_dcs_read_multi() - mipi_dsi_dcs_read() w/ accum_err 1104 * @ctx: Context for multiple DSI transactions 1105 * @cmd: DCS command 1106 * @data: buffer in which to receive data 1107 * @len: size of receive buffer 1108 * 1109 * Like mipi_dsi_dcs_read() but deals with errors in a way that makes it 1110 * convenient to make several calls in a row. 1111 */ 1112 void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd, 1113 void *data, size_t len) 1114 { 1115 struct mipi_dsi_device *dsi = ctx->dsi; 1116 struct device *dev = &dsi->dev; 1117 struct mipi_dsi_msg msg = { 1118 .channel = dsi->channel, 1119 .type = MIPI_DSI_DCS_READ, 1120 .tx_buf = &cmd, 1121 .tx_len = 1, 1122 .rx_buf = data, 1123 .rx_len = len 1124 }; 1125 ssize_t ret; 1126 1127 if (ctx->accum_err) 1128 return; 1129 1130 ret = mipi_dsi_device_transfer(dsi, &msg); 1131 if (ret < 0) { 1132 ctx->accum_err = ret; 1133 dev_err(dev, "dcs read with command %#x failed: %d\n", cmd, 1134 ctx->accum_err); 1135 } 1136 } 1137 EXPORT_SYMBOL(mipi_dsi_dcs_read_multi); 1138 1139 /** 1140 * mipi_dsi_dcs_nop() - send DCS nop packet 1141 * @dsi: DSI peripheral device 1142 * 1143 * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead. 1144 * 1145 * Return: 0 on success or a negative error code on failure. 1146 */ 1147 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 1148 { 1149 ssize_t err; 1150 1151 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 1152 if (err < 0) 1153 return err; 1154 1155 return 0; 1156 } 1157 EXPORT_SYMBOL(mipi_dsi_dcs_nop); 1158 1159 /** 1160 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 1161 * @dsi: DSI peripheral device 1162 * 1163 * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead. 1164 * 1165 * Return: 0 on success or a negative error code on failure. 1166 */ 1167 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 1168 { 1169 ssize_t err; 1170 1171 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 1172 if (err < 0) 1173 return err; 1174 1175 return 0; 1176 } 1177 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 1178 1179 /** 1180 * mipi_dsi_dcs_get_power_mode() - query the display module's current power 1181 * mode 1182 * @dsi: DSI peripheral device 1183 * @mode: return location for the current power mode 1184 * 1185 * Return: 0 on success or a negative error code on failure. 1186 */ 1187 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 1188 { 1189 ssize_t err; 1190 1191 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 1192 sizeof(*mode)); 1193 if (err <= 0) { 1194 if (err == 0) 1195 err = -ENODATA; 1196 1197 return err; 1198 } 1199 1200 return 0; 1201 } 1202 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 1203 1204 /** 1205 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 1206 * data used by the interface 1207 * @dsi: DSI peripheral device 1208 * @format: return location for the pixel format 1209 * 1210 * Return: 0 on success or a negative error code on failure. 1211 */ 1212 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 1213 { 1214 ssize_t err; 1215 1216 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 1217 sizeof(*format)); 1218 if (err <= 0) { 1219 if (err == 0) 1220 err = -ENODATA; 1221 1222 return err; 1223 } 1224 1225 return 0; 1226 } 1227 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 1228 1229 /** 1230 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 1231 * display module except interface communication 1232 * @dsi: DSI peripheral device 1233 * 1234 * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() instead. 1235 * 1236 * Return: 0 on success or a negative error code on failure. 1237 */ 1238 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 1239 { 1240 ssize_t err; 1241 1242 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 1243 if (err < 0) 1244 return err; 1245 1246 return 0; 1247 } 1248 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 1249 1250 /** 1251 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 1252 * module 1253 * @dsi: DSI peripheral device 1254 * 1255 * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() instead. 1256 * 1257 * Return: 0 on success or a negative error code on failure. 1258 */ 1259 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 1260 { 1261 ssize_t err; 1262 1263 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 1264 if (err < 0) 1265 return err; 1266 1267 return 0; 1268 } 1269 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 1270 1271 /** 1272 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 1273 * display device 1274 * @dsi: DSI peripheral device 1275 * 1276 * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() instead. 1277 * 1278 * Return: 0 on success or a negative error code on failure. 1279 */ 1280 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 1281 { 1282 ssize_t err; 1283 1284 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 1285 if (err < 0) 1286 return err; 1287 1288 return 0; 1289 } 1290 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 1291 1292 /** 1293 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 1294 * display device 1295 * @dsi: DSI peripheral device 1296 * 1297 * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() instead. 1298 * 1299 * Return: 0 on success or a negative error code on failure 1300 */ 1301 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 1302 { 1303 ssize_t err; 1304 1305 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 1306 if (err < 0) 1307 return err; 1308 1309 return 0; 1310 } 1311 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 1312 1313 /** 1314 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 1315 * memory accessed by the host processor 1316 * @dsi: DSI peripheral device 1317 * @start: first column of frame memory 1318 * @end: last column of frame memory 1319 * 1320 * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi() 1321 * instead. 1322 * 1323 * Return: 0 on success or a negative error code on failure. 1324 */ 1325 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 1326 u16 end) 1327 { 1328 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1329 ssize_t err; 1330 1331 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 1332 sizeof(payload)); 1333 if (err < 0) 1334 return err; 1335 1336 return 0; 1337 } 1338 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 1339 1340 /** 1341 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 1342 * memory accessed by the host processor 1343 * @dsi: DSI peripheral device 1344 * @start: first page of frame memory 1345 * @end: last page of frame memory 1346 * 1347 * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi() 1348 * instead. 1349 * 1350 * Return: 0 on success or a negative error code on failure. 1351 */ 1352 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 1353 u16 end) 1354 { 1355 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1356 ssize_t err; 1357 1358 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 1359 sizeof(payload)); 1360 if (err < 0) 1361 return err; 1362 1363 return 0; 1364 } 1365 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 1366 1367 /** 1368 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 1369 * output signal on the TE signal line. 1370 * @dsi: DSI peripheral device 1371 * @mode: the Tearing Effect Output Line mode 1372 * 1373 * This function is deprecated. Use mipi_dsi_dcs_set_tear_on_multi() instead. 1374 * 1375 * Return: 0 on success or a negative error code on failure 1376 */ 1377 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 1378 enum mipi_dsi_dcs_tear_mode mode) 1379 { 1380 u8 value = mode; 1381 ssize_t err; 1382 1383 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 1384 sizeof(value)); 1385 if (err < 0) 1386 return err; 1387 1388 return 0; 1389 } 1390 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 1391 1392 /** 1393 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1394 * data used by the interface 1395 * @dsi: DSI peripheral device 1396 * @format: pixel format 1397 * 1398 * This function is deprecated. Use mipi_dsi_dcs_set_pixel_format_multi() 1399 * instead. 1400 * 1401 * Return: 0 on success or a negative error code on failure. 1402 */ 1403 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 1404 { 1405 ssize_t err; 1406 1407 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 1408 sizeof(format)); 1409 if (err < 0) 1410 return err; 1411 1412 return 0; 1413 } 1414 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 1415 1416 /** 1417 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 1418 * the Tearing Effect output signal of the display module 1419 * @dsi: DSI peripheral device 1420 * @scanline: scanline to use as trigger 1421 * 1422 * This function is deprecated. Use mipi_dsi_dcs_set_tear_scanline_multi() 1423 * instead. 1424 * 1425 * Return: 0 on success or a negative error code on failure 1426 */ 1427 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1428 { 1429 u8 payload[2] = { scanline >> 8, scanline & 0xff }; 1430 ssize_t err; 1431 1432 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, 1433 sizeof(payload)); 1434 if (err < 0) 1435 return err; 1436 1437 return 0; 1438 } 1439 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 1440 1441 /** 1442 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 1443 * display 1444 * @dsi: DSI peripheral device 1445 * @brightness: brightness value 1446 * 1447 * This function is deprecated. Use mipi_dsi_dcs_set_display_brightness_multi() 1448 * instead. 1449 * 1450 * Return: 0 on success or a negative error code on failure. 1451 */ 1452 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 1453 u16 brightness) 1454 { 1455 u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 1456 ssize_t err; 1457 1458 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1459 payload, sizeof(payload)); 1460 if (err < 0) 1461 return err; 1462 1463 return 0; 1464 } 1465 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 1466 1467 /** 1468 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 1469 * of the display 1470 * @dsi: DSI peripheral device 1471 * @brightness: brightness value 1472 * 1473 * Return: 0 on success or a negative error code on failure. 1474 */ 1475 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 1476 u16 *brightness) 1477 { 1478 ssize_t err; 1479 1480 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1481 brightness, sizeof(*brightness)); 1482 if (err <= 0) { 1483 if (err == 0) 1484 err = -ENODATA; 1485 1486 return err; 1487 } 1488 1489 return 0; 1490 } 1491 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 1492 1493 /** 1494 * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value 1495 * of the display 1496 * @dsi: DSI peripheral device 1497 * @brightness: brightness value 1498 * 1499 * Return: 0 on success or a negative error code on failure. 1500 */ 1501 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, 1502 u16 brightness) 1503 { 1504 u8 payload[2] = { brightness >> 8, brightness & 0xff }; 1505 ssize_t err; 1506 1507 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1508 payload, sizeof(payload)); 1509 if (err < 0) 1510 return err; 1511 1512 return 0; 1513 } 1514 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); 1515 1516 /** 1517 * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit 1518 * brightness value of the display 1519 * @dsi: DSI peripheral device 1520 * @brightness: brightness value 1521 * 1522 * Return: 0 on success or a negative error code on failure. 1523 */ 1524 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, 1525 u16 *brightness) 1526 { 1527 u8 brightness_be[2]; 1528 ssize_t err; 1529 1530 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1531 brightness_be, sizeof(brightness_be)); 1532 if (err <= 0) { 1533 if (err == 0) 1534 err = -ENODATA; 1535 1536 return err; 1537 } 1538 1539 *brightness = (brightness_be[0] << 8) | brightness_be[1]; 1540 1541 return 0; 1542 } 1543 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); 1544 1545 /** 1546 * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral 1547 * @ctx: Context for multiple DSI transactions 1548 * @pps: VESA DSC 1.1 Picture Parameter Set 1549 * 1550 * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that 1551 * makes it convenient to make several calls in a row. 1552 */ 1553 void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, 1554 const struct drm_dsc_picture_parameter_set *pps) 1555 { 1556 struct mipi_dsi_device *dsi = ctx->dsi; 1557 struct device *dev = &dsi->dev; 1558 ssize_t ret; 1559 1560 if (ctx->accum_err) 1561 return; 1562 1563 ret = mipi_dsi_picture_parameter_set(dsi, pps); 1564 if (ret < 0) { 1565 ctx->accum_err = ret; 1566 dev_err(dev, "sending PPS failed: %d\n", 1567 ctx->accum_err); 1568 } 1569 } 1570 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi); 1571 1572 /** 1573 * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral 1574 * @ctx: Context for multiple DSI transactions 1575 * @enable: Whether to enable or disable the DSC 1576 * @algo: Selected compression algorithm 1577 * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries 1578 * 1579 * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that 1580 * makes it convenient to make several calls in a row. 1581 */ 1582 void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, 1583 bool enable, 1584 enum mipi_dsi_compression_algo algo, 1585 unsigned int pps_selector) 1586 { 1587 struct mipi_dsi_device *dsi = ctx->dsi; 1588 struct device *dev = &dsi->dev; 1589 ssize_t ret; 1590 1591 if (ctx->accum_err) 1592 return; 1593 1594 ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector); 1595 if (ret < 0) { 1596 ctx->accum_err = ret; 1597 dev_err(dev, "sending COMPRESSION_MODE failed: %d\n", 1598 ctx->accum_err); 1599 } 1600 } 1601 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); 1602 1603 /** 1604 * mipi_dsi_compression_mode_multi() - enable/disable DSC on the peripheral 1605 * @ctx: Context for multiple DSI transactions 1606 * @enable: Whether to enable or disable the DSC 1607 * 1608 * Enable or disable Display Stream Compression on the peripheral using the 1609 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 1610 */ 1611 void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, 1612 bool enable) 1613 { 1614 return mipi_dsi_compression_mode_ext_multi(ctx, enable, 1615 MIPI_DSI_COMPRESSION_DSC, 0); 1616 } 1617 EXPORT_SYMBOL(mipi_dsi_compression_mode_multi); 1618 1619 /** 1620 * mipi_dsi_dcs_nop_multi() - send DCS NOP packet 1621 * @ctx: Context for multiple DSI transactions 1622 * 1623 * Like mipi_dsi_dcs_nop() but deals with errors in a way that 1624 * makes it convenient to make several calls in a row. 1625 */ 1626 void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx) 1627 { 1628 struct mipi_dsi_device *dsi = ctx->dsi; 1629 struct device *dev = &dsi->dev; 1630 ssize_t ret; 1631 1632 if (ctx->accum_err) 1633 return; 1634 1635 ret = mipi_dsi_dcs_nop(dsi); 1636 if (ret < 0) { 1637 ctx->accum_err = ret; 1638 dev_err(dev, "sending DCS NOP failed: %d\n", 1639 ctx->accum_err); 1640 } 1641 } 1642 EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi); 1643 1644 /** 1645 * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet 1646 * @ctx: Context for multiple DSI transactions 1647 * 1648 * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that 1649 * makes it convenient to make several calls in a row. 1650 */ 1651 void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1652 { 1653 struct mipi_dsi_device *dsi = ctx->dsi; 1654 struct device *dev = &dsi->dev; 1655 ssize_t ret; 1656 1657 if (ctx->accum_err) 1658 return; 1659 1660 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 1661 if (ret < 0) { 1662 ctx->accum_err = ret; 1663 dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n", 1664 ctx->accum_err); 1665 } 1666 } 1667 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi); 1668 1669 /** 1670 * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet 1671 * @ctx: Context for multiple DSI transactions 1672 * 1673 * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that 1674 * makes it convenient to make several calls in a row. 1675 */ 1676 void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1677 { 1678 struct mipi_dsi_device *dsi = ctx->dsi; 1679 struct device *dev = &dsi->dev; 1680 ssize_t ret; 1681 1682 if (ctx->accum_err) 1683 return; 1684 1685 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 1686 if (ret < 0) { 1687 ctx->accum_err = ret; 1688 dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n", 1689 ctx->accum_err); 1690 } 1691 } 1692 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi); 1693 1694 /** 1695 * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet 1696 * @ctx: Context for multiple DSI transactions 1697 * 1698 * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that 1699 * makes it convenient to make several calls in a row. 1700 */ 1701 void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx) 1702 { 1703 struct mipi_dsi_device *dsi = ctx->dsi; 1704 struct device *dev = &dsi->dev; 1705 ssize_t ret; 1706 1707 if (ctx->accum_err) 1708 return; 1709 1710 ret = mipi_dsi_dcs_set_display_off(dsi); 1711 if (ret < 0) { 1712 ctx->accum_err = ret; 1713 dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n", 1714 ctx->accum_err); 1715 } 1716 } 1717 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi); 1718 1719 /** 1720 * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet 1721 * @ctx: Context for multiple DSI transactions 1722 * 1723 * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that 1724 * makes it convenient to make several calls in a row. 1725 */ 1726 void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx) 1727 { 1728 struct mipi_dsi_device *dsi = ctx->dsi; 1729 struct device *dev = &dsi->dev; 1730 ssize_t ret; 1731 1732 if (ctx->accum_err) 1733 return; 1734 1735 ret = mipi_dsi_dcs_set_display_on(dsi); 1736 if (ret < 0) { 1737 ctx->accum_err = ret; 1738 dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n", 1739 ctx->accum_err); 1740 } 1741 } 1742 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi); 1743 1744 /** 1745 * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet 1746 * @ctx: Context for multiple DSI transactions 1747 * @mode: the Tearing Effect Output Line mode 1748 * 1749 * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that 1750 * makes it convenient to make several calls in a row. 1751 */ 1752 void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, 1753 enum mipi_dsi_dcs_tear_mode mode) 1754 { 1755 struct mipi_dsi_device *dsi = ctx->dsi; 1756 struct device *dev = &dsi->dev; 1757 ssize_t ret; 1758 1759 if (ctx->accum_err) 1760 return; 1761 1762 ret = mipi_dsi_dcs_set_tear_on(dsi, mode); 1763 if (ret < 0) { 1764 ctx->accum_err = ret; 1765 dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n", 1766 ctx->accum_err); 1767 } 1768 } 1769 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi); 1770 1771 /** 1772 * mipi_dsi_turn_on_peripheral_multi() - sends a Turn On Peripheral command 1773 * @ctx: Context for multiple DSI transactions 1774 * 1775 * Like mipi_dsi_turn_on_peripheral() but deals with errors in a way that 1776 * makes it convenient to make several calls in a row. 1777 */ 1778 void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx) 1779 { 1780 struct mipi_dsi_device *dsi = ctx->dsi; 1781 struct device *dev = &dsi->dev; 1782 int ret; 1783 1784 if (ctx->accum_err) 1785 return; 1786 1787 ret = mipi_dsi_turn_on_peripheral(dsi); 1788 if (ret < 0) { 1789 ctx->accum_err = ret; 1790 dev_err(dev, "Failed to turn on peripheral: %d\n", 1791 ctx->accum_err); 1792 } 1793 } 1794 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi); 1795 1796 /** 1797 * mipi_dsi_dcs_set_tear_off_multi() - turn off the display module's Tearing Effect 1798 * output signal on the TE signal line 1799 * @ctx: Context for multiple DSI transactions 1800 */ 1801 void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx) 1802 { 1803 struct mipi_dsi_device *dsi = ctx->dsi; 1804 struct device *dev = &dsi->dev; 1805 ssize_t err; 1806 1807 if (ctx->accum_err) 1808 return; 1809 1810 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 1811 if (err < 0) { 1812 ctx->accum_err = err; 1813 dev_err(dev, "Failed to set tear off: %d\n", 1814 ctx->accum_err); 1815 } 1816 } 1817 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off_multi); 1818 1819 /** 1820 * mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module 1821 * @ctx: Context for multiple DSI transactions 1822 * 1823 * Like mipi_dsi_dcs_soft_reset() but deals with errors in a way that 1824 * makes it convenient to make several calls in a row. 1825 */ 1826 void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx) 1827 { 1828 struct mipi_dsi_device *dsi = ctx->dsi; 1829 struct device *dev = &dsi->dev; 1830 int ret; 1831 1832 if (ctx->accum_err) 1833 return; 1834 1835 ret = mipi_dsi_dcs_soft_reset(dsi); 1836 if (ret < 0) { 1837 ctx->accum_err = ret; 1838 dev_err(dev, "Failed to mipi_dsi_dcs_soft_reset: %d\n", 1839 ctx->accum_err); 1840 } 1841 } 1842 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset_multi); 1843 1844 /** 1845 * mipi_dsi_dcs_set_display_brightness_multi() - sets the brightness value of 1846 * the display 1847 * @ctx: Context for multiple DSI transactions 1848 * @brightness: brightness value 1849 * 1850 * Like mipi_dsi_dcs_set_display_brightness() but deals with errors in a way that 1851 * makes it convenient to make several calls in a row. 1852 */ 1853 void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx, 1854 u16 brightness) 1855 { 1856 struct mipi_dsi_device *dsi = ctx->dsi; 1857 struct device *dev = &dsi->dev; 1858 int ret; 1859 1860 if (ctx->accum_err) 1861 return; 1862 1863 ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness); 1864 if (ret < 0) { 1865 ctx->accum_err = ret; 1866 dev_err(dev, "Failed to write display brightness: %d\n", 1867 ctx->accum_err); 1868 } 1869 } 1870 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_multi); 1871 1872 /** 1873 * mipi_dsi_dcs_set_pixel_format_multi() - sets the pixel format for the RGB image 1874 * data used by the interface 1875 * @ctx: Context for multiple DSI transactions 1876 * @format: pixel format 1877 * 1878 * Like mipi_dsi_dcs_set_pixel_format() but deals with errors in a way that 1879 * makes it convenient to make several calls in a row. 1880 */ 1881 void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx, 1882 u8 format) 1883 { 1884 struct mipi_dsi_device *dsi = ctx->dsi; 1885 struct device *dev = &dsi->dev; 1886 int ret; 1887 1888 if (ctx->accum_err) 1889 return; 1890 1891 ret = mipi_dsi_dcs_set_pixel_format(dsi, format); 1892 if (ret < 0) { 1893 ctx->accum_err = ret; 1894 dev_err(dev, "Failed to set pixel format: %d\n", 1895 ctx->accum_err); 1896 } 1897 } 1898 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format_multi); 1899 1900 /** 1901 * mipi_dsi_dcs_set_column_address_multi() - define the column extent of the 1902 * frame memory accessed by the host processor 1903 * @ctx: Context for multiple DSI transactions 1904 * @start: first column of frame memory 1905 * @end: last column of frame memory 1906 * 1907 * Like mipi_dsi_dcs_set_column_address() but deals with errors in a way that 1908 * makes it convenient to make several calls in a row. 1909 */ 1910 void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx, 1911 u16 start, u16 end) 1912 { 1913 struct mipi_dsi_device *dsi = ctx->dsi; 1914 struct device *dev = &dsi->dev; 1915 int ret; 1916 1917 if (ctx->accum_err) 1918 return; 1919 1920 ret = mipi_dsi_dcs_set_column_address(dsi, start, end); 1921 if (ret < 0) { 1922 ctx->accum_err = ret; 1923 dev_err(dev, "Failed to set column address: %d\n", 1924 ctx->accum_err); 1925 } 1926 } 1927 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address_multi); 1928 1929 /** 1930 * mipi_dsi_dcs_set_page_address_multi() - define the page extent of the 1931 * frame memory accessed by the host processor 1932 * @ctx: Context for multiple DSI transactions 1933 * @start: first page of frame memory 1934 * @end: last page of frame memory 1935 * 1936 * Like mipi_dsi_dcs_set_page_address() but deals with errors in a way that 1937 * makes it convenient to make several calls in a row. 1938 */ 1939 void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx, 1940 u16 start, u16 end) 1941 { 1942 struct mipi_dsi_device *dsi = ctx->dsi; 1943 struct device *dev = &dsi->dev; 1944 int ret; 1945 1946 if (ctx->accum_err) 1947 return; 1948 1949 ret = mipi_dsi_dcs_set_page_address(dsi, start, end); 1950 if (ret < 0) { 1951 ctx->accum_err = ret; 1952 dev_err(dev, "Failed to set page address: %d\n", 1953 ctx->accum_err); 1954 } 1955 } 1956 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address_multi); 1957 1958 /** 1959 * mipi_dsi_dcs_set_tear_scanline_multi() - set the scanline to use as trigger for 1960 * the Tearing Effect output signal of the display module 1961 * @ctx: Context for multiple DSI transactions 1962 * @scanline: scanline to use as trigger 1963 * 1964 * Like mipi_dsi_dcs_set_tear_scanline() but deals with errors in a way that 1965 * makes it convenient to make several calls in a row. 1966 */ 1967 void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx, 1968 u16 scanline) 1969 { 1970 struct mipi_dsi_device *dsi = ctx->dsi; 1971 struct device *dev = &dsi->dev; 1972 int ret; 1973 1974 if (ctx->accum_err) 1975 return; 1976 1977 ret = mipi_dsi_dcs_set_tear_scanline(dsi, scanline); 1978 if (ret < 0) { 1979 ctx->accum_err = ret; 1980 dev_err(dev, "Failed to set tear scanline: %d\n", 1981 ctx->accum_err); 1982 } 1983 } 1984 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline_multi); 1985 1986 /** 1987 * mipi_dsi_shutdown_peripheral_multi() - sends a Shutdown Peripheral command 1988 * @ctx: Context for multiple DSI transactions 1989 * 1990 * Like mipi_dsi_shutdown_peripheral() but deals with errors in a way that 1991 * makes it convenient to make several calls in a row. 1992 */ 1993 void mipi_dsi_shutdown_peripheral_multi(struct mipi_dsi_multi_context *ctx) 1994 { 1995 struct mipi_dsi_device *dsi = ctx->dsi; 1996 struct device *dev = &dsi->dev; 1997 int ret; 1998 1999 if (ctx->accum_err) 2000 return; 2001 2002 ret = mipi_dsi_shutdown_peripheral(dsi); 2003 if (ret < 0) { 2004 ctx->accum_err = ret; 2005 dev_err(dev, "Failed to shutdown peripheral: %d\n", 2006 ctx->accum_err); 2007 } 2008 } 2009 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral_multi); 2010 2011 static int mipi_dsi_drv_probe(struct device *dev) 2012 { 2013 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 2014 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 2015 2016 return drv->probe(dsi); 2017 } 2018 2019 static int mipi_dsi_drv_remove(struct device *dev) 2020 { 2021 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 2022 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 2023 2024 drv->remove(dsi); 2025 2026 return 0; 2027 } 2028 2029 static void mipi_dsi_drv_shutdown(struct device *dev) 2030 { 2031 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 2032 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 2033 2034 drv->shutdown(dsi); 2035 } 2036 2037 /** 2038 * mipi_dsi_driver_register_full() - register a driver for DSI devices 2039 * @drv: DSI driver structure 2040 * @owner: owner module 2041 * 2042 * Return: 0 on success or a negative error code on failure. 2043 */ 2044 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 2045 struct module *owner) 2046 { 2047 drv->driver.bus = &mipi_dsi_bus_type; 2048 drv->driver.owner = owner; 2049 2050 if (drv->probe) 2051 drv->driver.probe = mipi_dsi_drv_probe; 2052 if (drv->remove) 2053 drv->driver.remove = mipi_dsi_drv_remove; 2054 if (drv->shutdown) 2055 drv->driver.shutdown = mipi_dsi_drv_shutdown; 2056 2057 return driver_register(&drv->driver); 2058 } 2059 EXPORT_SYMBOL(mipi_dsi_driver_register_full); 2060 2061 /** 2062 * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 2063 * @drv: DSI driver structure 2064 * 2065 * Return: 0 on success or a negative error code on failure. 2066 */ 2067 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 2068 { 2069 driver_unregister(&drv->driver); 2070 } 2071 EXPORT_SYMBOL(mipi_dsi_driver_unregister); 2072 2073 static int __init mipi_dsi_bus_init(void) 2074 { 2075 return bus_register(&mipi_dsi_bus_type); 2076 } 2077 postcore_initcall(mipi_dsi_bus_init); 2078 2079 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>"); 2080 MODULE_DESCRIPTION("MIPI DSI Bus"); 2081 MODULE_LICENSE("GPL and additional rights"); 2082