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