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(sizeof(*dsi), GFP_KERNEL); 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 * Return: 0 on success or a negative error code on failure. 591 */ 592 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) 593 { 594 struct mipi_dsi_msg msg = { 595 .channel = dsi->channel, 596 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, 597 .tx_buf = (u8 [2]) { 0, 0 }, 598 .tx_len = 2, 599 }; 600 int ret = mipi_dsi_device_transfer(dsi, &msg); 601 602 return (ret < 0) ? ret : 0; 603 } 604 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); 605 606 /** 607 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command 608 * @dsi: DSI peripheral device 609 * 610 * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() instead. 611 * 612 * Return: 0 on success or a negative error code on failure. 613 */ 614 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) 615 { 616 struct mipi_dsi_msg msg = { 617 .channel = dsi->channel, 618 .type = MIPI_DSI_TURN_ON_PERIPHERAL, 619 .tx_buf = (u8 [2]) { 0, 0 }, 620 .tx_len = 2, 621 }; 622 int ret = mipi_dsi_device_transfer(dsi, &msg); 623 624 return (ret < 0) ? ret : 0; 625 } 626 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); 627 628 /* 629 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of 630 * the payload in a long packet transmitted from the peripheral back to the 631 * host processor 632 * @dsi: DSI peripheral device 633 * @value: the maximum size of the payload 634 * 635 * Return: 0 on success or a negative error code on failure. 636 */ 637 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 638 u16 value) 639 { 640 u8 tx[2] = { value & 0xff, value >> 8 }; 641 struct mipi_dsi_msg msg = { 642 .channel = dsi->channel, 643 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 644 .tx_len = sizeof(tx), 645 .tx_buf = tx, 646 }; 647 int ret = mipi_dsi_device_transfer(dsi, &msg); 648 649 return (ret < 0) ? ret : 0; 650 } 651 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 652 653 /** 654 * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral 655 * @dsi: DSI peripheral device 656 * @enable: Whether to enable or disable the DSC 657 * @algo: Selected compression algorithm 658 * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries 659 * 660 * Enable or disable Display Stream Compression on the peripheral. 661 * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() instead. 662 * 663 * Return: 0 on success or a negative error code on failure. 664 */ 665 int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, 666 enum mipi_dsi_compression_algo algo, 667 unsigned int pps_selector) 668 { 669 u8 tx[2] = { }; 670 struct mipi_dsi_msg msg = { 671 .channel = dsi->channel, 672 .type = MIPI_DSI_COMPRESSION_MODE, 673 .tx_len = sizeof(tx), 674 .tx_buf = tx, 675 }; 676 int ret; 677 678 if (algo > 3 || pps_selector > 3) 679 return -EINVAL; 680 681 tx[0] = (enable << 0) | 682 (algo << 1) | 683 (pps_selector << 4); 684 685 ret = mipi_dsi_device_transfer(dsi, &msg); 686 687 return (ret < 0) ? ret : 0; 688 } 689 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext); 690 691 /** 692 * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral 693 * @dsi: DSI peripheral device 694 * @enable: Whether to enable or disable the DSC 695 * 696 * Enable or disable Display Stream Compression on the peripheral using the 697 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 698 * 699 * Return: 0 on success or a negative error code on failure. 700 */ 701 int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) 702 { 703 return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0); 704 } 705 EXPORT_SYMBOL(mipi_dsi_compression_mode); 706 707 /** 708 * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral 709 * @dsi: DSI peripheral device 710 * @pps: VESA DSC 1.1 Picture Parameter Set 711 * 712 * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. 713 * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() instead. 714 * 715 * Return: 0 on success or a negative error code on failure. 716 */ 717 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, 718 const struct drm_dsc_picture_parameter_set *pps) 719 { 720 struct mipi_dsi_msg msg = { 721 .channel = dsi->channel, 722 .type = MIPI_DSI_PICTURE_PARAMETER_SET, 723 .tx_len = sizeof(*pps), 724 .tx_buf = pps, 725 }; 726 int ret = mipi_dsi_device_transfer(dsi, &msg); 727 728 return (ret < 0) ? ret : 0; 729 } 730 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set); 731 732 /** 733 * mipi_dsi_generic_write() - transmit data using a generic write packet 734 * @dsi: DSI peripheral device 735 * @payload: buffer containing the payload 736 * @size: size of payload buffer 737 * 738 * This function will automatically choose the right data type depending on 739 * the payload length. 740 * 741 * Return: The number of bytes transmitted on success or a negative error code 742 * on failure. 743 */ 744 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 745 size_t size) 746 { 747 struct mipi_dsi_msg msg = { 748 .channel = dsi->channel, 749 .tx_buf = payload, 750 .tx_len = size 751 }; 752 753 switch (size) { 754 case 0: 755 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 756 break; 757 758 case 1: 759 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 760 break; 761 762 case 2: 763 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 764 break; 765 766 default: 767 msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 768 break; 769 } 770 771 return mipi_dsi_device_transfer(dsi, &msg); 772 } 773 EXPORT_SYMBOL(mipi_dsi_generic_write); 774 775 /** 776 * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write() w/ accum_err 777 * @ctx: Context for multiple DSI transactions 778 * @payload: buffer containing the payload 779 * @size: size of payload buffer 780 * 781 * A wrapper around mipi_dsi_generic_write() that deals with errors in a way 782 * that makes it convenient to make several calls in a row. 783 */ 784 void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, 785 const void *payload, size_t size) 786 { 787 struct mipi_dsi_device *dsi = ctx->dsi; 788 struct device *dev = &dsi->dev; 789 ssize_t ret; 790 791 if (ctx->accum_err) 792 return; 793 794 ret = mipi_dsi_generic_write(dsi, payload, size); 795 if (ret < 0) { 796 ctx->accum_err = ret; 797 dev_err(dev, "sending generic data %*ph failed: %d\n", 798 (int)size, payload, ctx->accum_err); 799 } 800 } 801 EXPORT_SYMBOL(mipi_dsi_generic_write_multi); 802 803 /** 804 * mipi_dsi_dual_generic_write_multi() - mipi_dsi_generic_write_multi() for 805 * two dsi channels, one after the other 806 * @ctx: Context for multiple DSI transactions 807 * @dsi1: First dsi channel to write buffer to 808 * @dsi2: Second dsi channel to write buffer to 809 * @payload: Buffer containing the payload 810 * @size: Size of payload buffer 811 * 812 * A wrapper around mipi_dsi_generic_write_multi() that allows the user to 813 * conveniently write to two dsi channels, one after the other. 814 */ 815 void mipi_dsi_dual_generic_write_multi(struct mipi_dsi_multi_context *ctx, 816 struct mipi_dsi_device *dsi1, 817 struct mipi_dsi_device *dsi2, 818 const void *payload, size_t size) 819 { 820 ctx->dsi = dsi1; 821 mipi_dsi_generic_write_multi(ctx, payload, size); 822 ctx->dsi = dsi2; 823 mipi_dsi_generic_write_multi(ctx, payload, size); 824 } 825 EXPORT_SYMBOL(mipi_dsi_dual_generic_write_multi); 826 827 /** 828 * mipi_dsi_generic_read() - receive data using a generic read packet 829 * @dsi: DSI peripheral device 830 * @params: buffer containing the request parameters 831 * @num_params: number of request parameters 832 * @data: buffer in which to return the received data 833 * @size: size of receive buffer 834 * 835 * This function will automatically choose the right data type depending on 836 * the number of parameters passed in. 837 * 838 * Return: The number of bytes successfully read or a negative error code on 839 * failure. 840 */ 841 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 842 size_t num_params, void *data, size_t size) 843 { 844 struct mipi_dsi_msg msg = { 845 .channel = dsi->channel, 846 .tx_len = num_params, 847 .tx_buf = params, 848 .rx_len = size, 849 .rx_buf = data 850 }; 851 852 switch (num_params) { 853 case 0: 854 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 855 break; 856 857 case 1: 858 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 859 break; 860 861 case 2: 862 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 863 break; 864 865 default: 866 return -EINVAL; 867 } 868 869 return mipi_dsi_device_transfer(dsi, &msg); 870 } 871 EXPORT_SYMBOL(mipi_dsi_generic_read); 872 873 /** 874 * drm_mipi_dsi_get_input_bus_fmt() - Get the required MEDIA_BUS_FMT_* based 875 * input pixel format for a given DSI output 876 * pixel format 877 * @dsi_format: pixel format that a DSI host needs to output 878 * 879 * Various DSI hosts can use this function during their 880 * &drm_bridge_funcs.atomic_get_input_bus_fmts operation to ascertain 881 * the MEDIA_BUS_FMT_* pixel format required as input. 882 * 883 * RETURNS: 884 * a 32-bit MEDIA_BUS_FMT_* value on success or 0 in case of failure. 885 */ 886 u32 drm_mipi_dsi_get_input_bus_fmt(enum mipi_dsi_pixel_format dsi_format) 887 { 888 switch (dsi_format) { 889 case MIPI_DSI_FMT_RGB888: 890 return MEDIA_BUS_FMT_RGB888_1X24; 891 892 case MIPI_DSI_FMT_RGB666: 893 return MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 894 895 case MIPI_DSI_FMT_RGB666_PACKED: 896 return MEDIA_BUS_FMT_RGB666_1X18; 897 898 case MIPI_DSI_FMT_RGB565: 899 return MEDIA_BUS_FMT_RGB565_1X16; 900 901 default: 902 /* Unsupported DSI Format */ 903 return 0; 904 } 905 } 906 EXPORT_SYMBOL(drm_mipi_dsi_get_input_bus_fmt); 907 908 /** 909 * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 910 * @dsi: DSI peripheral device 911 * @data: buffer containing data to be transmitted 912 * @len: size of transmission buffer 913 * 914 * This function will automatically choose the right data type depending on 915 * the command payload length. 916 * 917 * Return: The number of bytes successfully transmitted or a negative error 918 * code on failure. 919 */ 920 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 921 const void *data, size_t len) 922 { 923 struct mipi_dsi_msg msg = { 924 .channel = dsi->channel, 925 .tx_buf = data, 926 .tx_len = len 927 }; 928 929 switch (len) { 930 case 0: 931 return -EINVAL; 932 933 case 1: 934 msg.type = MIPI_DSI_DCS_SHORT_WRITE; 935 break; 936 937 case 2: 938 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 939 break; 940 941 default: 942 msg.type = MIPI_DSI_DCS_LONG_WRITE; 943 break; 944 } 945 946 return mipi_dsi_device_transfer(dsi, &msg); 947 } 948 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 949 950 /** 951 * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log 952 * @dsi: DSI peripheral device 953 * @data: buffer containing data to be transmitted 954 * @len: size of transmission buffer 955 * 956 * Like mipi_dsi_dcs_write_buffer() but includes a dev_err() 957 * call for you and returns 0 upon success, not the number of bytes sent. 958 * 959 * Return: 0 on success or a negative error code on failure. 960 */ 961 int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, 962 const void *data, size_t len) 963 { 964 struct device *dev = &dsi->dev; 965 ssize_t ret; 966 967 ret = mipi_dsi_dcs_write_buffer(dsi, data, len); 968 if (ret < 0) { 969 dev_err(dev, "sending dcs data %*ph failed: %zd\n", 970 (int)len, data, ret); 971 return ret; 972 } 973 974 return 0; 975 } 976 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty); 977 978 /** 979 * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err 980 * @ctx: Context for multiple DSI transactions 981 * @data: buffer containing data to be transmitted 982 * @len: size of transmission buffer 983 * 984 * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that 985 * makes it convenient to make several calls in a row. 986 */ 987 void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, 988 const void *data, size_t len) 989 { 990 struct mipi_dsi_device *dsi = ctx->dsi; 991 struct device *dev = &dsi->dev; 992 ssize_t ret; 993 994 if (ctx->accum_err) 995 return; 996 997 ret = mipi_dsi_dcs_write_buffer(dsi, data, len); 998 if (ret < 0) { 999 ctx->accum_err = ret; 1000 dev_err(dev, "sending dcs data %*ph failed: %d\n", 1001 (int)len, data, ctx->accum_err); 1002 } 1003 } 1004 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi); 1005 1006 /** 1007 * mipi_dsi_dual_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_multi() for 1008 * two dsi channels, one after the other 1009 * @ctx: Context for multiple DSI transactions 1010 * @dsi1: First dsi channel to write buffer to 1011 * @dsi2: Second dsi channel to write buffer to 1012 * @data: Buffer containing data to be transmitted 1013 * @len: Size of transmission buffer 1014 * 1015 * A wrapper around mipi_dsi_dcs_write_buffer_multi() that allows the user to 1016 * conveniently write to two dsi channels, one after the other. 1017 */ 1018 void mipi_dsi_dual_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, 1019 struct mipi_dsi_device *dsi1, 1020 struct mipi_dsi_device *dsi2, 1021 const void *data, size_t len) 1022 { 1023 ctx->dsi = dsi1; 1024 mipi_dsi_dcs_write_buffer_multi(ctx, data, len); 1025 ctx->dsi = dsi2; 1026 mipi_dsi_dcs_write_buffer_multi(ctx, data, len); 1027 } 1028 EXPORT_SYMBOL(mipi_dsi_dual_dcs_write_buffer_multi); 1029 1030 /** 1031 * mipi_dsi_dcs_write() - send DCS write command 1032 * @dsi: DSI peripheral device 1033 * @cmd: DCS command 1034 * @data: buffer containing the command payload 1035 * @len: command payload length 1036 * 1037 * This function will automatically choose the right data type depending on 1038 * the command payload length. 1039 * 1040 * Return: The number of bytes successfully transmitted or a negative error 1041 * code on failure. 1042 */ 1043 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 1044 const void *data, size_t len) 1045 { 1046 ssize_t err; 1047 size_t size; 1048 u8 stack_tx[8]; 1049 u8 *tx; 1050 1051 size = 1 + len; 1052 if (len > ARRAY_SIZE(stack_tx) - 1) { 1053 tx = kmalloc(size, GFP_KERNEL); 1054 if (!tx) 1055 return -ENOMEM; 1056 } else { 1057 tx = stack_tx; 1058 } 1059 1060 /* concatenate the DCS command byte and the payload */ 1061 tx[0] = cmd; 1062 if (data) 1063 memcpy(&tx[1], data, len); 1064 1065 err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 1066 1067 if (tx != stack_tx) 1068 kfree(tx); 1069 1070 return err; 1071 } 1072 EXPORT_SYMBOL(mipi_dsi_dcs_write); 1073 1074 /** 1075 * mipi_dsi_dcs_read() - send DCS read request command 1076 * @dsi: DSI peripheral device 1077 * @cmd: DCS command 1078 * @data: buffer in which to receive data 1079 * @len: size of receive buffer 1080 * 1081 * Return: The number of bytes read or a negative error code on failure. 1082 */ 1083 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 1084 size_t len) 1085 { 1086 struct mipi_dsi_msg msg = { 1087 .channel = dsi->channel, 1088 .type = MIPI_DSI_DCS_READ, 1089 .tx_buf = &cmd, 1090 .tx_len = 1, 1091 .rx_buf = data, 1092 .rx_len = len 1093 }; 1094 1095 return mipi_dsi_device_transfer(dsi, &msg); 1096 } 1097 EXPORT_SYMBOL(mipi_dsi_dcs_read); 1098 1099 /** 1100 * mipi_dsi_dcs_read_multi() - mipi_dsi_dcs_read() w/ accum_err 1101 * @ctx: Context for multiple DSI transactions 1102 * @cmd: DCS command 1103 * @data: buffer in which to receive data 1104 * @len: size of receive buffer 1105 * 1106 * Like mipi_dsi_dcs_read() but deals with errors in a way that makes it 1107 * convenient to make several calls in a row. 1108 */ 1109 void mipi_dsi_dcs_read_multi(struct mipi_dsi_multi_context *ctx, u8 cmd, 1110 void *data, size_t len) 1111 { 1112 struct mipi_dsi_device *dsi = ctx->dsi; 1113 struct device *dev = &dsi->dev; 1114 struct mipi_dsi_msg msg = { 1115 .channel = dsi->channel, 1116 .type = MIPI_DSI_DCS_READ, 1117 .tx_buf = &cmd, 1118 .tx_len = 1, 1119 .rx_buf = data, 1120 .rx_len = len 1121 }; 1122 ssize_t ret; 1123 1124 if (ctx->accum_err) 1125 return; 1126 1127 ret = mipi_dsi_device_transfer(dsi, &msg); 1128 if (ret < 0) { 1129 ctx->accum_err = ret; 1130 dev_err(dev, "dcs read with command %#x failed: %d\n", cmd, 1131 ctx->accum_err); 1132 } 1133 } 1134 EXPORT_SYMBOL(mipi_dsi_dcs_read_multi); 1135 1136 /** 1137 * mipi_dsi_dcs_nop() - send DCS nop packet 1138 * @dsi: DSI peripheral device 1139 * 1140 * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead. 1141 * 1142 * Return: 0 on success or a negative error code on failure. 1143 */ 1144 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 1145 { 1146 ssize_t err; 1147 1148 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 1149 if (err < 0) 1150 return err; 1151 1152 return 0; 1153 } 1154 EXPORT_SYMBOL(mipi_dsi_dcs_nop); 1155 1156 /** 1157 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 1158 * @dsi: DSI peripheral device 1159 * 1160 * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead. 1161 * 1162 * Return: 0 on success or a negative error code on failure. 1163 */ 1164 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 1165 { 1166 ssize_t err; 1167 1168 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 1169 if (err < 0) 1170 return err; 1171 1172 return 0; 1173 } 1174 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 1175 1176 /** 1177 * mipi_dsi_dcs_get_power_mode() - query the display module's current power 1178 * mode 1179 * @dsi: DSI peripheral device 1180 * @mode: return location for the current power mode 1181 * 1182 * Return: 0 on success or a negative error code on failure. 1183 */ 1184 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 1185 { 1186 ssize_t err; 1187 1188 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 1189 sizeof(*mode)); 1190 if (err <= 0) { 1191 if (err == 0) 1192 err = -ENODATA; 1193 1194 return err; 1195 } 1196 1197 return 0; 1198 } 1199 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 1200 1201 /** 1202 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 1203 * data used by the interface 1204 * @dsi: DSI peripheral device 1205 * @format: return location for the pixel format 1206 * 1207 * Return: 0 on success or a negative error code on failure. 1208 */ 1209 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 1210 { 1211 ssize_t err; 1212 1213 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 1214 sizeof(*format)); 1215 if (err <= 0) { 1216 if (err == 0) 1217 err = -ENODATA; 1218 1219 return err; 1220 } 1221 1222 return 0; 1223 } 1224 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 1225 1226 /** 1227 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 1228 * display module except interface communication 1229 * @dsi: DSI peripheral device 1230 * 1231 * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() instead. 1232 * 1233 * Return: 0 on success or a negative error code on failure. 1234 */ 1235 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 1236 { 1237 ssize_t err; 1238 1239 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 1240 if (err < 0) 1241 return err; 1242 1243 return 0; 1244 } 1245 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 1246 1247 /** 1248 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 1249 * module 1250 * @dsi: DSI peripheral device 1251 * 1252 * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() instead. 1253 * 1254 * Return: 0 on success or a negative error code on failure. 1255 */ 1256 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 1257 { 1258 ssize_t err; 1259 1260 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 1261 if (err < 0) 1262 return err; 1263 1264 return 0; 1265 } 1266 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 1267 1268 /** 1269 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 1270 * display device 1271 * @dsi: DSI peripheral device 1272 * 1273 * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() instead. 1274 * 1275 * Return: 0 on success or a negative error code on failure. 1276 */ 1277 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 1278 { 1279 ssize_t err; 1280 1281 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 1282 if (err < 0) 1283 return err; 1284 1285 return 0; 1286 } 1287 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 1288 1289 /** 1290 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 1291 * display device 1292 * @dsi: DSI peripheral device 1293 * 1294 * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() instead. 1295 * 1296 * Return: 0 on success or a negative error code on failure 1297 */ 1298 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 1299 { 1300 ssize_t err; 1301 1302 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 1303 if (err < 0) 1304 return err; 1305 1306 return 0; 1307 } 1308 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 1309 1310 /** 1311 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 1312 * memory accessed by the host processor 1313 * @dsi: DSI peripheral device 1314 * @start: first column of frame memory 1315 * @end: last column of frame memory 1316 * 1317 * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi() 1318 * instead. 1319 * 1320 * Return: 0 on success or a negative error code on failure. 1321 */ 1322 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 1323 u16 end) 1324 { 1325 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1326 ssize_t err; 1327 1328 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 1329 sizeof(payload)); 1330 if (err < 0) 1331 return err; 1332 1333 return 0; 1334 } 1335 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 1336 1337 /** 1338 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 1339 * memory accessed by the host processor 1340 * @dsi: DSI peripheral device 1341 * @start: first page of frame memory 1342 * @end: last page of frame memory 1343 * 1344 * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi() 1345 * instead. 1346 * 1347 * Return: 0 on success or a negative error code on failure. 1348 */ 1349 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 1350 u16 end) 1351 { 1352 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1353 ssize_t err; 1354 1355 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 1356 sizeof(payload)); 1357 if (err < 0) 1358 return err; 1359 1360 return 0; 1361 } 1362 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 1363 1364 /** 1365 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 1366 * output signal on the TE signal line. 1367 * @dsi: DSI peripheral device 1368 * @mode: the Tearing Effect Output Line mode 1369 * 1370 * This function is deprecated. Use mipi_dsi_dcs_set_tear_on_multi() instead. 1371 * 1372 * Return: 0 on success or a negative error code on failure 1373 */ 1374 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 1375 enum mipi_dsi_dcs_tear_mode mode) 1376 { 1377 u8 value = mode; 1378 ssize_t err; 1379 1380 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 1381 sizeof(value)); 1382 if (err < 0) 1383 return err; 1384 1385 return 0; 1386 } 1387 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 1388 1389 /** 1390 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1391 * data used by the interface 1392 * @dsi: DSI peripheral device 1393 * @format: pixel format 1394 * 1395 * This function is deprecated. Use mipi_dsi_dcs_set_pixel_format_multi() 1396 * instead. 1397 * 1398 * Return: 0 on success or a negative error code on failure. 1399 */ 1400 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 1401 { 1402 ssize_t err; 1403 1404 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 1405 sizeof(format)); 1406 if (err < 0) 1407 return err; 1408 1409 return 0; 1410 } 1411 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 1412 1413 /** 1414 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 1415 * the Tearing Effect output signal of the display module 1416 * @dsi: DSI peripheral device 1417 * @scanline: scanline to use as trigger 1418 * 1419 * This function is deprecated. Use mipi_dsi_dcs_set_tear_scanline_multi() 1420 * instead. 1421 * 1422 * Return: 0 on success or a negative error code on failure 1423 */ 1424 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1425 { 1426 u8 payload[2] = { scanline >> 8, scanline & 0xff }; 1427 ssize_t err; 1428 1429 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, 1430 sizeof(payload)); 1431 if (err < 0) 1432 return err; 1433 1434 return 0; 1435 } 1436 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 1437 1438 /** 1439 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 1440 * display 1441 * @dsi: DSI peripheral device 1442 * @brightness: brightness value 1443 * 1444 * This function is deprecated. Use mipi_dsi_dcs_set_display_brightness_multi() 1445 * instead. 1446 * 1447 * Return: 0 on success or a negative error code on failure. 1448 */ 1449 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 1450 u16 brightness) 1451 { 1452 u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 1453 ssize_t err; 1454 1455 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1456 payload, sizeof(payload)); 1457 if (err < 0) 1458 return err; 1459 1460 return 0; 1461 } 1462 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 1463 1464 /** 1465 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 1466 * of the display 1467 * @dsi: DSI peripheral device 1468 * @brightness: brightness value 1469 * 1470 * Return: 0 on success or a negative error code on failure. 1471 */ 1472 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 1473 u16 *brightness) 1474 { 1475 ssize_t err; 1476 1477 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1478 brightness, sizeof(*brightness)); 1479 if (err <= 0) { 1480 if (err == 0) 1481 err = -ENODATA; 1482 1483 return err; 1484 } 1485 1486 return 0; 1487 } 1488 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 1489 1490 /** 1491 * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value 1492 * of the display 1493 * @dsi: DSI peripheral device 1494 * @brightness: brightness value 1495 * 1496 * Return: 0 on success or a negative error code on failure. 1497 */ 1498 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, 1499 u16 brightness) 1500 { 1501 u8 payload[2] = { brightness >> 8, brightness & 0xff }; 1502 ssize_t err; 1503 1504 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1505 payload, sizeof(payload)); 1506 if (err < 0) 1507 return err; 1508 1509 return 0; 1510 } 1511 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); 1512 1513 /** 1514 * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit 1515 * brightness value of the display 1516 * @dsi: DSI peripheral device 1517 * @brightness: brightness value 1518 * 1519 * Return: 0 on success or a negative error code on failure. 1520 */ 1521 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, 1522 u16 *brightness) 1523 { 1524 u8 brightness_be[2]; 1525 ssize_t err; 1526 1527 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1528 brightness_be, sizeof(brightness_be)); 1529 if (err <= 0) { 1530 if (err == 0) 1531 err = -ENODATA; 1532 1533 return err; 1534 } 1535 1536 *brightness = (brightness_be[0] << 8) | brightness_be[1]; 1537 1538 return 0; 1539 } 1540 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); 1541 1542 /** 1543 * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral 1544 * @ctx: Context for multiple DSI transactions 1545 * @pps: VESA DSC 1.1 Picture Parameter Set 1546 * 1547 * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that 1548 * makes it convenient to make several calls in a row. 1549 */ 1550 void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, 1551 const struct drm_dsc_picture_parameter_set *pps) 1552 { 1553 struct mipi_dsi_device *dsi = ctx->dsi; 1554 struct device *dev = &dsi->dev; 1555 ssize_t ret; 1556 1557 if (ctx->accum_err) 1558 return; 1559 1560 ret = mipi_dsi_picture_parameter_set(dsi, pps); 1561 if (ret < 0) { 1562 ctx->accum_err = ret; 1563 dev_err(dev, "sending PPS failed: %d\n", 1564 ctx->accum_err); 1565 } 1566 } 1567 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi); 1568 1569 /** 1570 * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral 1571 * @ctx: Context for multiple DSI transactions 1572 * @enable: Whether to enable or disable the DSC 1573 * @algo: Selected compression algorithm 1574 * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries 1575 * 1576 * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that 1577 * makes it convenient to make several calls in a row. 1578 */ 1579 void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, 1580 bool enable, 1581 enum mipi_dsi_compression_algo algo, 1582 unsigned int pps_selector) 1583 { 1584 struct mipi_dsi_device *dsi = ctx->dsi; 1585 struct device *dev = &dsi->dev; 1586 ssize_t ret; 1587 1588 if (ctx->accum_err) 1589 return; 1590 1591 ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector); 1592 if (ret < 0) { 1593 ctx->accum_err = ret; 1594 dev_err(dev, "sending COMPRESSION_MODE failed: %d\n", 1595 ctx->accum_err); 1596 } 1597 } 1598 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); 1599 1600 /** 1601 * mipi_dsi_compression_mode_multi() - enable/disable DSC on the peripheral 1602 * @ctx: Context for multiple DSI transactions 1603 * @enable: Whether to enable or disable the DSC 1604 * 1605 * Enable or disable Display Stream Compression on the peripheral using the 1606 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 1607 */ 1608 void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, 1609 bool enable) 1610 { 1611 return mipi_dsi_compression_mode_ext_multi(ctx, enable, 1612 MIPI_DSI_COMPRESSION_DSC, 0); 1613 } 1614 EXPORT_SYMBOL(mipi_dsi_compression_mode_multi); 1615 1616 /** 1617 * mipi_dsi_dcs_nop_multi() - send DCS NOP packet 1618 * @ctx: Context for multiple DSI transactions 1619 * 1620 * Like mipi_dsi_dcs_nop() but deals with errors in a way that 1621 * makes it convenient to make several calls in a row. 1622 */ 1623 void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx) 1624 { 1625 struct mipi_dsi_device *dsi = ctx->dsi; 1626 struct device *dev = &dsi->dev; 1627 ssize_t ret; 1628 1629 if (ctx->accum_err) 1630 return; 1631 1632 ret = mipi_dsi_dcs_nop(dsi); 1633 if (ret < 0) { 1634 ctx->accum_err = ret; 1635 dev_err(dev, "sending DCS NOP failed: %d\n", 1636 ctx->accum_err); 1637 } 1638 } 1639 EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi); 1640 1641 /** 1642 * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet 1643 * @ctx: Context for multiple DSI transactions 1644 * 1645 * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that 1646 * makes it convenient to make several calls in a row. 1647 */ 1648 void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1649 { 1650 struct mipi_dsi_device *dsi = ctx->dsi; 1651 struct device *dev = &dsi->dev; 1652 ssize_t ret; 1653 1654 if (ctx->accum_err) 1655 return; 1656 1657 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 1658 if (ret < 0) { 1659 ctx->accum_err = ret; 1660 dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n", 1661 ctx->accum_err); 1662 } 1663 } 1664 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi); 1665 1666 /** 1667 * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet 1668 * @ctx: Context for multiple DSI transactions 1669 * 1670 * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that 1671 * makes it convenient to make several calls in a row. 1672 */ 1673 void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1674 { 1675 struct mipi_dsi_device *dsi = ctx->dsi; 1676 struct device *dev = &dsi->dev; 1677 ssize_t ret; 1678 1679 if (ctx->accum_err) 1680 return; 1681 1682 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 1683 if (ret < 0) { 1684 ctx->accum_err = ret; 1685 dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n", 1686 ctx->accum_err); 1687 } 1688 } 1689 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi); 1690 1691 /** 1692 * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet 1693 * @ctx: Context for multiple DSI transactions 1694 * 1695 * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that 1696 * makes it convenient to make several calls in a row. 1697 */ 1698 void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx) 1699 { 1700 struct mipi_dsi_device *dsi = ctx->dsi; 1701 struct device *dev = &dsi->dev; 1702 ssize_t ret; 1703 1704 if (ctx->accum_err) 1705 return; 1706 1707 ret = mipi_dsi_dcs_set_display_off(dsi); 1708 if (ret < 0) { 1709 ctx->accum_err = ret; 1710 dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n", 1711 ctx->accum_err); 1712 } 1713 } 1714 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi); 1715 1716 /** 1717 * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet 1718 * @ctx: Context for multiple DSI transactions 1719 * 1720 * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that 1721 * makes it convenient to make several calls in a row. 1722 */ 1723 void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx) 1724 { 1725 struct mipi_dsi_device *dsi = ctx->dsi; 1726 struct device *dev = &dsi->dev; 1727 ssize_t ret; 1728 1729 if (ctx->accum_err) 1730 return; 1731 1732 ret = mipi_dsi_dcs_set_display_on(dsi); 1733 if (ret < 0) { 1734 ctx->accum_err = ret; 1735 dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n", 1736 ctx->accum_err); 1737 } 1738 } 1739 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi); 1740 1741 /** 1742 * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet 1743 * @ctx: Context for multiple DSI transactions 1744 * @mode: the Tearing Effect Output Line mode 1745 * 1746 * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that 1747 * makes it convenient to make several calls in a row. 1748 */ 1749 void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, 1750 enum mipi_dsi_dcs_tear_mode mode) 1751 { 1752 struct mipi_dsi_device *dsi = ctx->dsi; 1753 struct device *dev = &dsi->dev; 1754 ssize_t ret; 1755 1756 if (ctx->accum_err) 1757 return; 1758 1759 ret = mipi_dsi_dcs_set_tear_on(dsi, mode); 1760 if (ret < 0) { 1761 ctx->accum_err = ret; 1762 dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n", 1763 ctx->accum_err); 1764 } 1765 } 1766 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi); 1767 1768 /** 1769 * mipi_dsi_turn_on_peripheral_multi() - sends a Turn On Peripheral command 1770 * @ctx: Context for multiple DSI transactions 1771 * 1772 * Like mipi_dsi_turn_on_peripheral() but deals with errors in a way that 1773 * makes it convenient to make several calls in a row. 1774 */ 1775 void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx) 1776 { 1777 struct mipi_dsi_device *dsi = ctx->dsi; 1778 struct device *dev = &dsi->dev; 1779 int ret; 1780 1781 if (ctx->accum_err) 1782 return; 1783 1784 ret = mipi_dsi_turn_on_peripheral(dsi); 1785 if (ret < 0) { 1786 ctx->accum_err = ret; 1787 dev_err(dev, "Failed to turn on peripheral: %d\n", 1788 ctx->accum_err); 1789 } 1790 } 1791 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi); 1792 1793 /** 1794 * mipi_dsi_dcs_set_tear_off_multi() - turn off the display module's Tearing Effect 1795 * output signal on the TE signal line 1796 * @ctx: Context for multiple DSI transactions 1797 */ 1798 void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx) 1799 { 1800 struct mipi_dsi_device *dsi = ctx->dsi; 1801 struct device *dev = &dsi->dev; 1802 ssize_t err; 1803 1804 if (ctx->accum_err) 1805 return; 1806 1807 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 1808 if (err < 0) { 1809 ctx->accum_err = err; 1810 dev_err(dev, "Failed to set tear off: %d\n", 1811 ctx->accum_err); 1812 } 1813 } 1814 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off_multi); 1815 1816 /** 1817 * mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module 1818 * @ctx: Context for multiple DSI transactions 1819 * 1820 * Like mipi_dsi_dcs_soft_reset() but deals with errors in a way that 1821 * makes it convenient to make several calls in a row. 1822 */ 1823 void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx) 1824 { 1825 struct mipi_dsi_device *dsi = ctx->dsi; 1826 struct device *dev = &dsi->dev; 1827 int ret; 1828 1829 if (ctx->accum_err) 1830 return; 1831 1832 ret = mipi_dsi_dcs_soft_reset(dsi); 1833 if (ret < 0) { 1834 ctx->accum_err = ret; 1835 dev_err(dev, "Failed to mipi_dsi_dcs_soft_reset: %d\n", 1836 ctx->accum_err); 1837 } 1838 } 1839 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset_multi); 1840 1841 /** 1842 * mipi_dsi_dcs_set_display_brightness_multi() - sets the brightness value of 1843 * the display 1844 * @ctx: Context for multiple DSI transactions 1845 * @brightness: brightness value 1846 * 1847 * Like mipi_dsi_dcs_set_display_brightness() but deals with errors in a way that 1848 * makes it convenient to make several calls in a row. 1849 */ 1850 void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx, 1851 u16 brightness) 1852 { 1853 struct mipi_dsi_device *dsi = ctx->dsi; 1854 struct device *dev = &dsi->dev; 1855 int ret; 1856 1857 if (ctx->accum_err) 1858 return; 1859 1860 ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness); 1861 if (ret < 0) { 1862 ctx->accum_err = ret; 1863 dev_err(dev, "Failed to write display brightness: %d\n", 1864 ctx->accum_err); 1865 } 1866 } 1867 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_multi); 1868 1869 /** 1870 * mipi_dsi_dcs_set_pixel_format_multi() - sets the pixel format for the RGB image 1871 * data used by the interface 1872 * @ctx: Context for multiple DSI transactions 1873 * @format: pixel format 1874 * 1875 * Like mipi_dsi_dcs_set_pixel_format() but deals with errors in a way that 1876 * makes it convenient to make several calls in a row. 1877 */ 1878 void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx, 1879 u8 format) 1880 { 1881 struct mipi_dsi_device *dsi = ctx->dsi; 1882 struct device *dev = &dsi->dev; 1883 int ret; 1884 1885 if (ctx->accum_err) 1886 return; 1887 1888 ret = mipi_dsi_dcs_set_pixel_format(dsi, format); 1889 if (ret < 0) { 1890 ctx->accum_err = ret; 1891 dev_err(dev, "Failed to set pixel format: %d\n", 1892 ctx->accum_err); 1893 } 1894 } 1895 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format_multi); 1896 1897 /** 1898 * mipi_dsi_dcs_set_column_address_multi() - define the column extent of the 1899 * frame memory accessed by the host processor 1900 * @ctx: Context for multiple DSI transactions 1901 * @start: first column of frame memory 1902 * @end: last column of frame memory 1903 * 1904 * Like mipi_dsi_dcs_set_column_address() but deals with errors in a way that 1905 * makes it convenient to make several calls in a row. 1906 */ 1907 void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx, 1908 u16 start, u16 end) 1909 { 1910 struct mipi_dsi_device *dsi = ctx->dsi; 1911 struct device *dev = &dsi->dev; 1912 int ret; 1913 1914 if (ctx->accum_err) 1915 return; 1916 1917 ret = mipi_dsi_dcs_set_column_address(dsi, start, end); 1918 if (ret < 0) { 1919 ctx->accum_err = ret; 1920 dev_err(dev, "Failed to set column address: %d\n", 1921 ctx->accum_err); 1922 } 1923 } 1924 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address_multi); 1925 1926 /** 1927 * mipi_dsi_dcs_set_page_address_multi() - define the page extent of the 1928 * frame memory accessed by the host processor 1929 * @ctx: Context for multiple DSI transactions 1930 * @start: first page of frame memory 1931 * @end: last page of frame memory 1932 * 1933 * Like mipi_dsi_dcs_set_page_address() but deals with errors in a way that 1934 * makes it convenient to make several calls in a row. 1935 */ 1936 void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx, 1937 u16 start, u16 end) 1938 { 1939 struct mipi_dsi_device *dsi = ctx->dsi; 1940 struct device *dev = &dsi->dev; 1941 int ret; 1942 1943 if (ctx->accum_err) 1944 return; 1945 1946 ret = mipi_dsi_dcs_set_page_address(dsi, start, end); 1947 if (ret < 0) { 1948 ctx->accum_err = ret; 1949 dev_err(dev, "Failed to set page address: %d\n", 1950 ctx->accum_err); 1951 } 1952 } 1953 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address_multi); 1954 1955 /** 1956 * mipi_dsi_dcs_set_tear_scanline_multi() - set the scanline to use as trigger for 1957 * the Tearing Effect output signal of the display module 1958 * @ctx: Context for multiple DSI transactions 1959 * @scanline: scanline to use as trigger 1960 * 1961 * Like mipi_dsi_dcs_set_tear_scanline() but deals with errors in a way that 1962 * makes it convenient to make several calls in a row. 1963 */ 1964 void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx, 1965 u16 scanline) 1966 { 1967 struct mipi_dsi_device *dsi = ctx->dsi; 1968 struct device *dev = &dsi->dev; 1969 int ret; 1970 1971 if (ctx->accum_err) 1972 return; 1973 1974 ret = mipi_dsi_dcs_set_tear_scanline(dsi, scanline); 1975 if (ret < 0) { 1976 ctx->accum_err = ret; 1977 dev_err(dev, "Failed to set tear scanline: %d\n", 1978 ctx->accum_err); 1979 } 1980 } 1981 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline_multi); 1982 1983 static int mipi_dsi_drv_probe(struct device *dev) 1984 { 1985 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1986 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1987 1988 return drv->probe(dsi); 1989 } 1990 1991 static int mipi_dsi_drv_remove(struct device *dev) 1992 { 1993 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1994 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1995 1996 drv->remove(dsi); 1997 1998 return 0; 1999 } 2000 2001 static void mipi_dsi_drv_shutdown(struct device *dev) 2002 { 2003 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 2004 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 2005 2006 drv->shutdown(dsi); 2007 } 2008 2009 /** 2010 * mipi_dsi_driver_register_full() - register a driver for DSI devices 2011 * @drv: DSI driver structure 2012 * @owner: owner module 2013 * 2014 * Return: 0 on success or a negative error code on failure. 2015 */ 2016 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 2017 struct module *owner) 2018 { 2019 drv->driver.bus = &mipi_dsi_bus_type; 2020 drv->driver.owner = owner; 2021 2022 if (drv->probe) 2023 drv->driver.probe = mipi_dsi_drv_probe; 2024 if (drv->remove) 2025 drv->driver.remove = mipi_dsi_drv_remove; 2026 if (drv->shutdown) 2027 drv->driver.shutdown = mipi_dsi_drv_shutdown; 2028 2029 return driver_register(&drv->driver); 2030 } 2031 EXPORT_SYMBOL(mipi_dsi_driver_register_full); 2032 2033 /** 2034 * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 2035 * @drv: DSI driver structure 2036 * 2037 * Return: 0 on success or a negative error code on failure. 2038 */ 2039 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 2040 { 2041 driver_unregister(&drv->driver); 2042 } 2043 EXPORT_SYMBOL(mipi_dsi_driver_unregister); 2044 2045 static int __init mipi_dsi_bus_init(void) 2046 { 2047 return bus_register(&mipi_dsi_bus_type); 2048 } 2049 postcore_initcall(mipi_dsi_bus_init); 2050 2051 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>"); 2052 MODULE_DESCRIPTION("MIPI DSI Bus"); 2053 MODULE_LICENSE("GPL and additional rights"); 2054