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_nop() - send DCS nop packet 1101 * @dsi: DSI peripheral device 1102 * 1103 * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead. 1104 * 1105 * Return: 0 on success or a negative error code on failure. 1106 */ 1107 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 1108 { 1109 ssize_t err; 1110 1111 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 1112 if (err < 0) 1113 return err; 1114 1115 return 0; 1116 } 1117 EXPORT_SYMBOL(mipi_dsi_dcs_nop); 1118 1119 /** 1120 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 1121 * @dsi: DSI peripheral device 1122 * 1123 * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead. 1124 * 1125 * Return: 0 on success or a negative error code on failure. 1126 */ 1127 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 1128 { 1129 ssize_t err; 1130 1131 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 1132 if (err < 0) 1133 return err; 1134 1135 return 0; 1136 } 1137 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 1138 1139 /** 1140 * mipi_dsi_dcs_get_power_mode() - query the display module's current power 1141 * mode 1142 * @dsi: DSI peripheral device 1143 * @mode: return location for the current power mode 1144 * 1145 * Return: 0 on success or a negative error code on failure. 1146 */ 1147 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 1148 { 1149 ssize_t err; 1150 1151 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 1152 sizeof(*mode)); 1153 if (err <= 0) { 1154 if (err == 0) 1155 err = -ENODATA; 1156 1157 return err; 1158 } 1159 1160 return 0; 1161 } 1162 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 1163 1164 /** 1165 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 1166 * data used by the interface 1167 * @dsi: DSI peripheral device 1168 * @format: return location for the pixel format 1169 * 1170 * Return: 0 on success or a negative error code on failure. 1171 */ 1172 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 1173 { 1174 ssize_t err; 1175 1176 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 1177 sizeof(*format)); 1178 if (err <= 0) { 1179 if (err == 0) 1180 err = -ENODATA; 1181 1182 return err; 1183 } 1184 1185 return 0; 1186 } 1187 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 1188 1189 /** 1190 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 1191 * display module except interface communication 1192 * @dsi: DSI peripheral device 1193 * 1194 * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() instead. 1195 * 1196 * Return: 0 on success or a negative error code on failure. 1197 */ 1198 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 1199 { 1200 ssize_t err; 1201 1202 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 1203 if (err < 0) 1204 return err; 1205 1206 return 0; 1207 } 1208 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 1209 1210 /** 1211 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 1212 * module 1213 * @dsi: DSI peripheral device 1214 * 1215 * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() instead. 1216 * 1217 * Return: 0 on success or a negative error code on failure. 1218 */ 1219 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 1220 { 1221 ssize_t err; 1222 1223 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 1224 if (err < 0) 1225 return err; 1226 1227 return 0; 1228 } 1229 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 1230 1231 /** 1232 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 1233 * display device 1234 * @dsi: DSI peripheral device 1235 * 1236 * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() instead. 1237 * 1238 * Return: 0 on success or a negative error code on failure. 1239 */ 1240 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 1241 { 1242 ssize_t err; 1243 1244 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 1245 if (err < 0) 1246 return err; 1247 1248 return 0; 1249 } 1250 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 1251 1252 /** 1253 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 1254 * display device 1255 * @dsi: DSI peripheral device 1256 * 1257 * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() instead. 1258 * 1259 * Return: 0 on success or a negative error code on failure 1260 */ 1261 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 1262 { 1263 ssize_t err; 1264 1265 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 1266 if (err < 0) 1267 return err; 1268 1269 return 0; 1270 } 1271 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 1272 1273 /** 1274 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 1275 * memory accessed by the host processor 1276 * @dsi: DSI peripheral device 1277 * @start: first column of frame memory 1278 * @end: last column of frame memory 1279 * 1280 * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi() 1281 * instead. 1282 * 1283 * Return: 0 on success or a negative error code on failure. 1284 */ 1285 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 1286 u16 end) 1287 { 1288 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1289 ssize_t err; 1290 1291 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 1292 sizeof(payload)); 1293 if (err < 0) 1294 return err; 1295 1296 return 0; 1297 } 1298 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 1299 1300 /** 1301 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 1302 * memory accessed by the host processor 1303 * @dsi: DSI peripheral device 1304 * @start: first page of frame memory 1305 * @end: last page of frame memory 1306 * 1307 * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi() 1308 * instead. 1309 * 1310 * Return: 0 on success or a negative error code on failure. 1311 */ 1312 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 1313 u16 end) 1314 { 1315 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1316 ssize_t err; 1317 1318 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 1319 sizeof(payload)); 1320 if (err < 0) 1321 return err; 1322 1323 return 0; 1324 } 1325 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 1326 1327 /** 1328 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 1329 * output signal on the TE signal line. 1330 * @dsi: DSI peripheral device 1331 * @mode: the Tearing Effect Output Line mode 1332 * 1333 * This function is deprecated. Use mipi_dsi_dcs_set_tear_on_multi() instead. 1334 * 1335 * Return: 0 on success or a negative error code on failure 1336 */ 1337 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 1338 enum mipi_dsi_dcs_tear_mode mode) 1339 { 1340 u8 value = mode; 1341 ssize_t err; 1342 1343 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 1344 sizeof(value)); 1345 if (err < 0) 1346 return err; 1347 1348 return 0; 1349 } 1350 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 1351 1352 /** 1353 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1354 * data used by the interface 1355 * @dsi: DSI peripheral device 1356 * @format: pixel format 1357 * 1358 * This function is deprecated. Use mipi_dsi_dcs_set_pixel_format_multi() 1359 * instead. 1360 * 1361 * Return: 0 on success or a negative error code on failure. 1362 */ 1363 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 1364 { 1365 ssize_t err; 1366 1367 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 1368 sizeof(format)); 1369 if (err < 0) 1370 return err; 1371 1372 return 0; 1373 } 1374 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 1375 1376 /** 1377 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 1378 * the Tearing Effect output signal of the display module 1379 * @dsi: DSI peripheral device 1380 * @scanline: scanline to use as trigger 1381 * 1382 * This function is deprecated. Use mipi_dsi_dcs_set_tear_scanline_multi() 1383 * instead. 1384 * 1385 * Return: 0 on success or a negative error code on failure 1386 */ 1387 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1388 { 1389 u8 payload[2] = { scanline >> 8, scanline & 0xff }; 1390 ssize_t err; 1391 1392 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, 1393 sizeof(payload)); 1394 if (err < 0) 1395 return err; 1396 1397 return 0; 1398 } 1399 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 1400 1401 /** 1402 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 1403 * display 1404 * @dsi: DSI peripheral device 1405 * @brightness: brightness value 1406 * 1407 * This function is deprecated. Use mipi_dsi_dcs_set_display_brightness_multi() 1408 * instead. 1409 * 1410 * Return: 0 on success or a negative error code on failure. 1411 */ 1412 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 1413 u16 brightness) 1414 { 1415 u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 1416 ssize_t err; 1417 1418 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1419 payload, sizeof(payload)); 1420 if (err < 0) 1421 return err; 1422 1423 return 0; 1424 } 1425 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 1426 1427 /** 1428 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 1429 * of the display 1430 * @dsi: DSI peripheral device 1431 * @brightness: brightness value 1432 * 1433 * Return: 0 on success or a negative error code on failure. 1434 */ 1435 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 1436 u16 *brightness) 1437 { 1438 ssize_t err; 1439 1440 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1441 brightness, sizeof(*brightness)); 1442 if (err <= 0) { 1443 if (err == 0) 1444 err = -ENODATA; 1445 1446 return err; 1447 } 1448 1449 return 0; 1450 } 1451 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 1452 1453 /** 1454 * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value 1455 * of the display 1456 * @dsi: DSI peripheral device 1457 * @brightness: brightness value 1458 * 1459 * Return: 0 on success or a negative error code on failure. 1460 */ 1461 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, 1462 u16 brightness) 1463 { 1464 u8 payload[2] = { brightness >> 8, brightness & 0xff }; 1465 ssize_t err; 1466 1467 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1468 payload, sizeof(payload)); 1469 if (err < 0) 1470 return err; 1471 1472 return 0; 1473 } 1474 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); 1475 1476 /** 1477 * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit 1478 * brightness value of the display 1479 * @dsi: DSI peripheral device 1480 * @brightness: brightness value 1481 * 1482 * Return: 0 on success or a negative error code on failure. 1483 */ 1484 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, 1485 u16 *brightness) 1486 { 1487 u8 brightness_be[2]; 1488 ssize_t err; 1489 1490 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1491 brightness_be, sizeof(brightness_be)); 1492 if (err <= 0) { 1493 if (err == 0) 1494 err = -ENODATA; 1495 1496 return err; 1497 } 1498 1499 *brightness = (brightness_be[0] << 8) | brightness_be[1]; 1500 1501 return 0; 1502 } 1503 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); 1504 1505 /** 1506 * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral 1507 * @ctx: Context for multiple DSI transactions 1508 * @pps: VESA DSC 1.1 Picture Parameter Set 1509 * 1510 * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that 1511 * makes it convenient to make several calls in a row. 1512 */ 1513 void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, 1514 const struct drm_dsc_picture_parameter_set *pps) 1515 { 1516 struct mipi_dsi_device *dsi = ctx->dsi; 1517 struct device *dev = &dsi->dev; 1518 ssize_t ret; 1519 1520 if (ctx->accum_err) 1521 return; 1522 1523 ret = mipi_dsi_picture_parameter_set(dsi, pps); 1524 if (ret < 0) { 1525 ctx->accum_err = ret; 1526 dev_err(dev, "sending PPS failed: %d\n", 1527 ctx->accum_err); 1528 } 1529 } 1530 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi); 1531 1532 /** 1533 * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral 1534 * @ctx: Context for multiple DSI transactions 1535 * @enable: Whether to enable or disable the DSC 1536 * @algo: Selected compression algorithm 1537 * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries 1538 * 1539 * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that 1540 * makes it convenient to make several calls in a row. 1541 */ 1542 void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, 1543 bool enable, 1544 enum mipi_dsi_compression_algo algo, 1545 unsigned int pps_selector) 1546 { 1547 struct mipi_dsi_device *dsi = ctx->dsi; 1548 struct device *dev = &dsi->dev; 1549 ssize_t ret; 1550 1551 if (ctx->accum_err) 1552 return; 1553 1554 ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector); 1555 if (ret < 0) { 1556 ctx->accum_err = ret; 1557 dev_err(dev, "sending COMPRESSION_MODE failed: %d\n", 1558 ctx->accum_err); 1559 } 1560 } 1561 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); 1562 1563 /** 1564 * mipi_dsi_compression_mode_multi() - enable/disable DSC on the peripheral 1565 * @ctx: Context for multiple DSI transactions 1566 * @enable: Whether to enable or disable the DSC 1567 * 1568 * Enable or disable Display Stream Compression on the peripheral using the 1569 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 1570 */ 1571 void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, 1572 bool enable) 1573 { 1574 return mipi_dsi_compression_mode_ext_multi(ctx, enable, 1575 MIPI_DSI_COMPRESSION_DSC, 0); 1576 } 1577 EXPORT_SYMBOL(mipi_dsi_compression_mode_multi); 1578 1579 /** 1580 * mipi_dsi_dcs_nop_multi() - send DCS NOP packet 1581 * @ctx: Context for multiple DSI transactions 1582 * 1583 * Like mipi_dsi_dcs_nop() but deals with errors in a way that 1584 * makes it convenient to make several calls in a row. 1585 */ 1586 void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx) 1587 { 1588 struct mipi_dsi_device *dsi = ctx->dsi; 1589 struct device *dev = &dsi->dev; 1590 ssize_t ret; 1591 1592 if (ctx->accum_err) 1593 return; 1594 1595 ret = mipi_dsi_dcs_nop(dsi); 1596 if (ret < 0) { 1597 ctx->accum_err = ret; 1598 dev_err(dev, "sending DCS NOP failed: %d\n", 1599 ctx->accum_err); 1600 } 1601 } 1602 EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi); 1603 1604 /** 1605 * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet 1606 * @ctx: Context for multiple DSI transactions 1607 * 1608 * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that 1609 * makes it convenient to make several calls in a row. 1610 */ 1611 void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1612 { 1613 struct mipi_dsi_device *dsi = ctx->dsi; 1614 struct device *dev = &dsi->dev; 1615 ssize_t ret; 1616 1617 if (ctx->accum_err) 1618 return; 1619 1620 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 1621 if (ret < 0) { 1622 ctx->accum_err = ret; 1623 dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n", 1624 ctx->accum_err); 1625 } 1626 } 1627 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi); 1628 1629 /** 1630 * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet 1631 * @ctx: Context for multiple DSI transactions 1632 * 1633 * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that 1634 * makes it convenient to make several calls in a row. 1635 */ 1636 void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) 1637 { 1638 struct mipi_dsi_device *dsi = ctx->dsi; 1639 struct device *dev = &dsi->dev; 1640 ssize_t ret; 1641 1642 if (ctx->accum_err) 1643 return; 1644 1645 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 1646 if (ret < 0) { 1647 ctx->accum_err = ret; 1648 dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n", 1649 ctx->accum_err); 1650 } 1651 } 1652 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi); 1653 1654 /** 1655 * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet 1656 * @ctx: Context for multiple DSI transactions 1657 * 1658 * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that 1659 * makes it convenient to make several calls in a row. 1660 */ 1661 void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx) 1662 { 1663 struct mipi_dsi_device *dsi = ctx->dsi; 1664 struct device *dev = &dsi->dev; 1665 ssize_t ret; 1666 1667 if (ctx->accum_err) 1668 return; 1669 1670 ret = mipi_dsi_dcs_set_display_off(dsi); 1671 if (ret < 0) { 1672 ctx->accum_err = ret; 1673 dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n", 1674 ctx->accum_err); 1675 } 1676 } 1677 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi); 1678 1679 /** 1680 * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet 1681 * @ctx: Context for multiple DSI transactions 1682 * 1683 * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that 1684 * makes it convenient to make several calls in a row. 1685 */ 1686 void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx) 1687 { 1688 struct mipi_dsi_device *dsi = ctx->dsi; 1689 struct device *dev = &dsi->dev; 1690 ssize_t ret; 1691 1692 if (ctx->accum_err) 1693 return; 1694 1695 ret = mipi_dsi_dcs_set_display_on(dsi); 1696 if (ret < 0) { 1697 ctx->accum_err = ret; 1698 dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n", 1699 ctx->accum_err); 1700 } 1701 } 1702 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi); 1703 1704 /** 1705 * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet 1706 * @ctx: Context for multiple DSI transactions 1707 * @mode: the Tearing Effect Output Line mode 1708 * 1709 * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that 1710 * makes it convenient to make several calls in a row. 1711 */ 1712 void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, 1713 enum mipi_dsi_dcs_tear_mode mode) 1714 { 1715 struct mipi_dsi_device *dsi = ctx->dsi; 1716 struct device *dev = &dsi->dev; 1717 ssize_t ret; 1718 1719 if (ctx->accum_err) 1720 return; 1721 1722 ret = mipi_dsi_dcs_set_tear_on(dsi, mode); 1723 if (ret < 0) { 1724 ctx->accum_err = ret; 1725 dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n", 1726 ctx->accum_err); 1727 } 1728 } 1729 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi); 1730 1731 /** 1732 * mipi_dsi_turn_on_peripheral_multi() - sends a Turn On Peripheral command 1733 * @ctx: Context for multiple DSI transactions 1734 * 1735 * Like mipi_dsi_turn_on_peripheral() but deals with errors in a way that 1736 * makes it convenient to make several calls in a row. 1737 */ 1738 void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx) 1739 { 1740 struct mipi_dsi_device *dsi = ctx->dsi; 1741 struct device *dev = &dsi->dev; 1742 int ret; 1743 1744 if (ctx->accum_err) 1745 return; 1746 1747 ret = mipi_dsi_turn_on_peripheral(dsi); 1748 if (ret < 0) { 1749 ctx->accum_err = ret; 1750 dev_err(dev, "Failed to turn on peripheral: %d\n", 1751 ctx->accum_err); 1752 } 1753 } 1754 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi); 1755 1756 /** 1757 * mipi_dsi_dcs_set_tear_off_multi() - turn off the display module's Tearing Effect 1758 * output signal on the TE signal line 1759 * @ctx: Context for multiple DSI transactions 1760 */ 1761 void mipi_dsi_dcs_set_tear_off_multi(struct mipi_dsi_multi_context *ctx) 1762 { 1763 struct mipi_dsi_device *dsi = ctx->dsi; 1764 struct device *dev = &dsi->dev; 1765 ssize_t err; 1766 1767 if (ctx->accum_err) 1768 return; 1769 1770 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 1771 if (err < 0) { 1772 ctx->accum_err = err; 1773 dev_err(dev, "Failed to set tear off: %d\n", 1774 ctx->accum_err); 1775 } 1776 } 1777 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off_multi); 1778 1779 /** 1780 * mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module 1781 * @ctx: Context for multiple DSI transactions 1782 * 1783 * Like mipi_dsi_dcs_soft_reset() but deals with errors in a way that 1784 * makes it convenient to make several calls in a row. 1785 */ 1786 void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx) 1787 { 1788 struct mipi_dsi_device *dsi = ctx->dsi; 1789 struct device *dev = &dsi->dev; 1790 int ret; 1791 1792 if (ctx->accum_err) 1793 return; 1794 1795 ret = mipi_dsi_dcs_soft_reset(dsi); 1796 if (ret < 0) { 1797 ctx->accum_err = ret; 1798 dev_err(dev, "Failed to mipi_dsi_dcs_soft_reset: %d\n", 1799 ctx->accum_err); 1800 } 1801 } 1802 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset_multi); 1803 1804 /** 1805 * mipi_dsi_dcs_set_display_brightness_multi() - sets the brightness value of 1806 * the display 1807 * @ctx: Context for multiple DSI transactions 1808 * @brightness: brightness value 1809 * 1810 * Like mipi_dsi_dcs_set_display_brightness() but deals with errors in a way that 1811 * makes it convenient to make several calls in a row. 1812 */ 1813 void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx, 1814 u16 brightness) 1815 { 1816 struct mipi_dsi_device *dsi = ctx->dsi; 1817 struct device *dev = &dsi->dev; 1818 int ret; 1819 1820 if (ctx->accum_err) 1821 return; 1822 1823 ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness); 1824 if (ret < 0) { 1825 ctx->accum_err = ret; 1826 dev_err(dev, "Failed to write display brightness: %d\n", 1827 ctx->accum_err); 1828 } 1829 } 1830 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_multi); 1831 1832 /** 1833 * mipi_dsi_dcs_set_pixel_format_multi() - sets the pixel format for the RGB image 1834 * data used by the interface 1835 * @ctx: Context for multiple DSI transactions 1836 * @format: pixel format 1837 * 1838 * Like mipi_dsi_dcs_set_pixel_format() but deals with errors in a way that 1839 * makes it convenient to make several calls in a row. 1840 */ 1841 void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx, 1842 u8 format) 1843 { 1844 struct mipi_dsi_device *dsi = ctx->dsi; 1845 struct device *dev = &dsi->dev; 1846 int ret; 1847 1848 if (ctx->accum_err) 1849 return; 1850 1851 ret = mipi_dsi_dcs_set_pixel_format(dsi, format); 1852 if (ret < 0) { 1853 ctx->accum_err = ret; 1854 dev_err(dev, "Failed to set pixel format: %d\n", 1855 ctx->accum_err); 1856 } 1857 } 1858 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format_multi); 1859 1860 /** 1861 * mipi_dsi_dcs_set_column_address_multi() - define the column extent of the 1862 * frame memory accessed by the host processor 1863 * @ctx: Context for multiple DSI transactions 1864 * @start: first column of frame memory 1865 * @end: last column of frame memory 1866 * 1867 * Like mipi_dsi_dcs_set_column_address() but deals with errors in a way that 1868 * makes it convenient to make several calls in a row. 1869 */ 1870 void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx, 1871 u16 start, u16 end) 1872 { 1873 struct mipi_dsi_device *dsi = ctx->dsi; 1874 struct device *dev = &dsi->dev; 1875 int ret; 1876 1877 if (ctx->accum_err) 1878 return; 1879 1880 ret = mipi_dsi_dcs_set_column_address(dsi, start, end); 1881 if (ret < 0) { 1882 ctx->accum_err = ret; 1883 dev_err(dev, "Failed to set column address: %d\n", 1884 ctx->accum_err); 1885 } 1886 } 1887 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address_multi); 1888 1889 /** 1890 * mipi_dsi_dcs_set_page_address_multi() - define the page extent of the 1891 * frame memory accessed by the host processor 1892 * @ctx: Context for multiple DSI transactions 1893 * @start: first page of frame memory 1894 * @end: last page of frame memory 1895 * 1896 * Like mipi_dsi_dcs_set_page_address() but deals with errors in a way that 1897 * makes it convenient to make several calls in a row. 1898 */ 1899 void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx, 1900 u16 start, u16 end) 1901 { 1902 struct mipi_dsi_device *dsi = ctx->dsi; 1903 struct device *dev = &dsi->dev; 1904 int ret; 1905 1906 if (ctx->accum_err) 1907 return; 1908 1909 ret = mipi_dsi_dcs_set_page_address(dsi, start, end); 1910 if (ret < 0) { 1911 ctx->accum_err = ret; 1912 dev_err(dev, "Failed to set page address: %d\n", 1913 ctx->accum_err); 1914 } 1915 } 1916 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address_multi); 1917 1918 /** 1919 * mipi_dsi_dcs_set_tear_scanline_multi() - set the scanline to use as trigger for 1920 * the Tearing Effect output signal of the display module 1921 * @ctx: Context for multiple DSI transactions 1922 * @scanline: scanline to use as trigger 1923 * 1924 * Like mipi_dsi_dcs_set_tear_scanline() but deals with errors in a way that 1925 * makes it convenient to make several calls in a row. 1926 */ 1927 void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx, 1928 u16 scanline) 1929 { 1930 struct mipi_dsi_device *dsi = ctx->dsi; 1931 struct device *dev = &dsi->dev; 1932 int ret; 1933 1934 if (ctx->accum_err) 1935 return; 1936 1937 ret = mipi_dsi_dcs_set_tear_scanline(dsi, scanline); 1938 if (ret < 0) { 1939 ctx->accum_err = ret; 1940 dev_err(dev, "Failed to set tear scanline: %d\n", 1941 ctx->accum_err); 1942 } 1943 } 1944 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline_multi); 1945 1946 static int mipi_dsi_drv_probe(struct device *dev) 1947 { 1948 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1949 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1950 1951 return drv->probe(dsi); 1952 } 1953 1954 static int mipi_dsi_drv_remove(struct device *dev) 1955 { 1956 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1957 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1958 1959 drv->remove(dsi); 1960 1961 return 0; 1962 } 1963 1964 static void mipi_dsi_drv_shutdown(struct device *dev) 1965 { 1966 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1967 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1968 1969 drv->shutdown(dsi); 1970 } 1971 1972 /** 1973 * mipi_dsi_driver_register_full() - register a driver for DSI devices 1974 * @drv: DSI driver structure 1975 * @owner: owner module 1976 * 1977 * Return: 0 on success or a negative error code on failure. 1978 */ 1979 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 1980 struct module *owner) 1981 { 1982 drv->driver.bus = &mipi_dsi_bus_type; 1983 drv->driver.owner = owner; 1984 1985 if (drv->probe) 1986 drv->driver.probe = mipi_dsi_drv_probe; 1987 if (drv->remove) 1988 drv->driver.remove = mipi_dsi_drv_remove; 1989 if (drv->shutdown) 1990 drv->driver.shutdown = mipi_dsi_drv_shutdown; 1991 1992 return driver_register(&drv->driver); 1993 } 1994 EXPORT_SYMBOL(mipi_dsi_driver_register_full); 1995 1996 /** 1997 * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 1998 * @drv: DSI driver structure 1999 * 2000 * Return: 0 on success or a negative error code on failure. 2001 */ 2002 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 2003 { 2004 driver_unregister(&drv->driver); 2005 } 2006 EXPORT_SYMBOL(mipi_dsi_driver_unregister); 2007 2008 static int __init mipi_dsi_bus_init(void) 2009 { 2010 return bus_register(&mipi_dsi_bus_type); 2011 } 2012 postcore_initcall(mipi_dsi_bus_init); 2013 2014 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>"); 2015 MODULE_DESCRIPTION("MIPI DSI Bus"); 2016 MODULE_LICENSE("GPL and additional rights"); 2017