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