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 <video/mipi_display.h> 40 41 /** 42 * DOC: dsi helpers 43 * 44 * These functions contain some common logic and helpers to deal with MIPI DSI 45 * peripherals. 46 * 47 * Helpers are provided for a number of standard MIPI DSI command as well as a 48 * subset of the MIPI DCS command set. 49 */ 50 51 #ifdef notyet 52 53 static int mipi_dsi_device_match(struct device *dev, 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 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 drm_err(host, "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 drm_err(host, "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 drm_err(host, "invalid mipi_dsi_device_info pointer\n"); 212 return ERR_PTR(-EINVAL); 213 } 214 215 if (info->channel > 3) { 216 drm_err(host, "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 drm_err(host, "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 drm_err(host, "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 STUB(); 289 return ERR_PTR(-ENOSYS); 290 #ifdef notyet 291 ret = devm_add_action_or_reset(dev, 292 devm_mipi_dsi_device_unregister, 293 dsi); 294 if (ret) 295 return ERR_PTR(ret); 296 297 return dsi; 298 #endif 299 } 300 EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full); 301 302 static DEFINE_MUTEX(host_lock); 303 static DRM_LIST_HEAD(host_list); 304 305 /** 306 * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a 307 * device tree node 308 * @node: device tree node 309 * 310 * Returns: 311 * A pointer to the MIPI DSI host corresponding to @node or NULL if no 312 * such device exists (or has not been registered yet). 313 */ 314 struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node) 315 { 316 struct mipi_dsi_host *host; 317 318 mutex_lock(&host_lock); 319 320 list_for_each_entry(host, &host_list, list) { 321 if (host->dev->of_node == node) { 322 mutex_unlock(&host_lock); 323 return host; 324 } 325 } 326 327 mutex_unlock(&host_lock); 328 329 return NULL; 330 } 331 EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node); 332 333 int mipi_dsi_host_register(struct mipi_dsi_host *host) 334 { 335 struct device_node *node; 336 337 for_each_available_child_of_node(host->dev->of_node, node) { 338 /* skip nodes without reg property */ 339 if (!of_property_present(node, "reg")) 340 continue; 341 of_mipi_dsi_device_add(host, node); 342 } 343 344 mutex_lock(&host_lock); 345 list_add_tail(&host->list, &host_list); 346 mutex_unlock(&host_lock); 347 348 return 0; 349 } 350 EXPORT_SYMBOL(mipi_dsi_host_register); 351 352 static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) 353 { 354 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 355 356 if (dsi->attached) 357 mipi_dsi_detach(dsi); 358 mipi_dsi_device_unregister(dsi); 359 360 return 0; 361 } 362 363 void mipi_dsi_host_unregister(struct mipi_dsi_host *host) 364 { 365 device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); 366 367 mutex_lock(&host_lock); 368 list_del_init(&host->list); 369 mutex_unlock(&host_lock); 370 } 371 EXPORT_SYMBOL(mipi_dsi_host_unregister); 372 373 #endif 374 375 /** 376 * mipi_dsi_attach - attach a DSI device to its DSI host 377 * @dsi: DSI peripheral 378 */ 379 int mipi_dsi_attach(struct mipi_dsi_device *dsi) 380 { 381 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 382 int ret; 383 384 if (!ops || !ops->attach) 385 return -ENOSYS; 386 387 ret = ops->attach(dsi->host, dsi); 388 if (ret) 389 return ret; 390 391 dsi->attached = true; 392 393 return 0; 394 } 395 EXPORT_SYMBOL(mipi_dsi_attach); 396 397 /** 398 * mipi_dsi_detach - detach a DSI device from its DSI host 399 * @dsi: DSI peripheral 400 */ 401 int mipi_dsi_detach(struct mipi_dsi_device *dsi) 402 { 403 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 404 405 if (WARN_ON(!dsi->attached)) 406 return -EINVAL; 407 408 if (!ops || !ops->detach) 409 return -ENOSYS; 410 411 dsi->attached = false; 412 413 return ops->detach(dsi->host, dsi); 414 } 415 EXPORT_SYMBOL(mipi_dsi_detach); 416 417 static void devm_mipi_dsi_detach(void *arg) 418 { 419 struct mipi_dsi_device *dsi = arg; 420 421 mipi_dsi_detach(dsi); 422 } 423 424 /** 425 * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host 426 * @dev: device to tie the MIPI-DSI device attachment lifetime to 427 * @dsi: DSI peripheral 428 * 429 * This is the managed version of mipi_dsi_attach() which automatically 430 * calls mipi_dsi_detach() when @dev is unbound. 431 * 432 * Returns: 433 * 0 on success, a negative error code on failure. 434 */ 435 int devm_mipi_dsi_attach(struct device *dev, 436 struct mipi_dsi_device *dsi) 437 { 438 int ret; 439 440 ret = mipi_dsi_attach(dsi); 441 if (ret) 442 return ret; 443 444 STUB(); 445 return -ENOSYS; 446 #ifdef notyet 447 ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi); 448 if (ret) 449 return ret; 450 451 return 0; 452 #endif 453 } 454 EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach); 455 456 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, 457 struct mipi_dsi_msg *msg) 458 { 459 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 460 461 if (!ops || !ops->transfer) 462 return -ENOSYS; 463 464 if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 465 msg->flags |= MIPI_DSI_MSG_USE_LPM; 466 467 return ops->transfer(dsi->host, msg); 468 } 469 470 /** 471 * mipi_dsi_packet_format_is_short - check if a packet is of the short format 472 * @type: MIPI DSI data type of the packet 473 * 474 * Return: true if the packet for the given data type is a short packet, false 475 * otherwise. 476 */ 477 bool mipi_dsi_packet_format_is_short(u8 type) 478 { 479 switch (type) { 480 case MIPI_DSI_V_SYNC_START: 481 case MIPI_DSI_V_SYNC_END: 482 case MIPI_DSI_H_SYNC_START: 483 case MIPI_DSI_H_SYNC_END: 484 case MIPI_DSI_COMPRESSION_MODE: 485 case MIPI_DSI_END_OF_TRANSMISSION: 486 case MIPI_DSI_COLOR_MODE_OFF: 487 case MIPI_DSI_COLOR_MODE_ON: 488 case MIPI_DSI_SHUTDOWN_PERIPHERAL: 489 case MIPI_DSI_TURN_ON_PERIPHERAL: 490 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 491 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 492 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 493 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 494 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 495 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 496 case MIPI_DSI_DCS_SHORT_WRITE: 497 case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 498 case MIPI_DSI_DCS_READ: 499 case MIPI_DSI_EXECUTE_QUEUE: 500 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: 501 return true; 502 } 503 504 return false; 505 } 506 EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); 507 508 /** 509 * mipi_dsi_packet_format_is_long - check if a packet is of the long format 510 * @type: MIPI DSI data type of the packet 511 * 512 * Return: true if the packet for the given data type is a long packet, false 513 * otherwise. 514 */ 515 bool mipi_dsi_packet_format_is_long(u8 type) 516 { 517 switch (type) { 518 case MIPI_DSI_NULL_PACKET: 519 case MIPI_DSI_BLANKING_PACKET: 520 case MIPI_DSI_GENERIC_LONG_WRITE: 521 case MIPI_DSI_DCS_LONG_WRITE: 522 case MIPI_DSI_PICTURE_PARAMETER_SET: 523 case MIPI_DSI_COMPRESSED_PIXEL_STREAM: 524 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: 525 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: 526 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: 527 case MIPI_DSI_PACKED_PIXEL_STREAM_30: 528 case MIPI_DSI_PACKED_PIXEL_STREAM_36: 529 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: 530 case MIPI_DSI_PACKED_PIXEL_STREAM_16: 531 case MIPI_DSI_PACKED_PIXEL_STREAM_18: 532 case MIPI_DSI_PIXEL_STREAM_3BYTE_18: 533 case MIPI_DSI_PACKED_PIXEL_STREAM_24: 534 return true; 535 } 536 537 return false; 538 } 539 EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); 540 541 /** 542 * mipi_dsi_create_packet - create a packet from a message according to the 543 * DSI protocol 544 * @packet: pointer to a DSI packet structure 545 * @msg: message to translate into a packet 546 * 547 * Return: 0 on success or a negative error code on failure. 548 */ 549 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 550 const struct mipi_dsi_msg *msg) 551 { 552 if (!packet || !msg) 553 return -EINVAL; 554 555 /* do some minimum sanity checking */ 556 if (!mipi_dsi_packet_format_is_short(msg->type) && 557 !mipi_dsi_packet_format_is_long(msg->type)) 558 return -EINVAL; 559 560 if (msg->channel > 3) 561 return -EINVAL; 562 563 memset(packet, 0, sizeof(*packet)); 564 packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); 565 566 /* TODO: compute ECC if hardware support is not available */ 567 568 /* 569 * Long write packets contain the word count in header bytes 1 and 2. 570 * The payload follows the header and is word count bytes long. 571 * 572 * Short write packets encode up to two parameters in header bytes 1 573 * and 2. 574 */ 575 if (mipi_dsi_packet_format_is_long(msg->type)) { 576 packet->header[1] = (msg->tx_len >> 0) & 0xff; 577 packet->header[2] = (msg->tx_len >> 8) & 0xff; 578 579 packet->payload_length = msg->tx_len; 580 packet->payload = msg->tx_buf; 581 } else { 582 const u8 *tx = msg->tx_buf; 583 584 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 585 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 586 } 587 588 packet->size = sizeof(packet->header) + packet->payload_length; 589 590 return 0; 591 } 592 EXPORT_SYMBOL(mipi_dsi_create_packet); 593 594 /** 595 * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command 596 * @dsi: DSI peripheral device 597 * 598 * Return: 0 on success or a negative error code on failure. 599 */ 600 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) 601 { 602 struct mipi_dsi_msg msg = { 603 .channel = dsi->channel, 604 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, 605 .tx_buf = (u8 [2]) { 0, 0 }, 606 .tx_len = 2, 607 }; 608 int ret = mipi_dsi_device_transfer(dsi, &msg); 609 610 return (ret < 0) ? ret : 0; 611 } 612 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); 613 614 /** 615 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command 616 * @dsi: DSI peripheral device 617 * 618 * Return: 0 on success or a negative error code on failure. 619 */ 620 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) 621 { 622 struct mipi_dsi_msg msg = { 623 .channel = dsi->channel, 624 .type = MIPI_DSI_TURN_ON_PERIPHERAL, 625 .tx_buf = (u8 [2]) { 0, 0 }, 626 .tx_len = 2, 627 }; 628 int ret = mipi_dsi_device_transfer(dsi, &msg); 629 630 return (ret < 0) ? ret : 0; 631 } 632 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); 633 634 /* 635 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of 636 * the payload in a long packet transmitted from the peripheral back to the 637 * host processor 638 * @dsi: DSI peripheral device 639 * @value: the maximum size of the payload 640 * 641 * Return: 0 on success or a negative error code on failure. 642 */ 643 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 644 u16 value) 645 { 646 u8 tx[2] = { value & 0xff, value >> 8 }; 647 struct mipi_dsi_msg msg = { 648 .channel = dsi->channel, 649 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 650 .tx_len = sizeof(tx), 651 .tx_buf = tx, 652 }; 653 int ret = mipi_dsi_device_transfer(dsi, &msg); 654 655 return (ret < 0) ? ret : 0; 656 } 657 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 658 659 /** 660 * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral 661 * @dsi: DSI peripheral device 662 * @enable: Whether to enable or disable the DSC 663 * 664 * Enable or disable Display Stream Compression on the peripheral using the 665 * default Picture Parameter Set and VESA DSC 1.1 algorithm. 666 * 667 * Return: 0 on success or a negative error code on failure. 668 */ 669 int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) 670 { 671 /* Note: Needs updating for non-default PPS or algorithm */ 672 u8 tx[2] = { enable << 0, 0 }; 673 struct mipi_dsi_msg msg = { 674 .channel = dsi->channel, 675 .type = MIPI_DSI_COMPRESSION_MODE, 676 .tx_len = sizeof(tx), 677 .tx_buf = tx, 678 }; 679 int ret = mipi_dsi_device_transfer(dsi, &msg); 680 681 return (ret < 0) ? ret : 0; 682 } 683 EXPORT_SYMBOL(mipi_dsi_compression_mode); 684 685 /** 686 * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral 687 * @dsi: DSI peripheral device 688 * @pps: VESA DSC 1.1 Picture Parameter Set 689 * 690 * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. 691 * 692 * Return: 0 on success or a negative error code on failure. 693 */ 694 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, 695 const struct drm_dsc_picture_parameter_set *pps) 696 { 697 struct mipi_dsi_msg msg = { 698 .channel = dsi->channel, 699 .type = MIPI_DSI_PICTURE_PARAMETER_SET, 700 .tx_len = sizeof(*pps), 701 .tx_buf = pps, 702 }; 703 int ret = mipi_dsi_device_transfer(dsi, &msg); 704 705 return (ret < 0) ? ret : 0; 706 } 707 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set); 708 709 /** 710 * mipi_dsi_generic_write() - transmit data using a generic write packet 711 * @dsi: DSI peripheral device 712 * @payload: buffer containing the payload 713 * @size: size of payload buffer 714 * 715 * This function will automatically choose the right data type depending on 716 * the payload length. 717 * 718 * Return: The number of bytes transmitted on success or a negative error code 719 * on failure. 720 */ 721 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 722 size_t size) 723 { 724 struct mipi_dsi_msg msg = { 725 .channel = dsi->channel, 726 .tx_buf = payload, 727 .tx_len = size 728 }; 729 730 switch (size) { 731 case 0: 732 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 733 break; 734 735 case 1: 736 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 737 break; 738 739 case 2: 740 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 741 break; 742 743 default: 744 msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 745 break; 746 } 747 748 return mipi_dsi_device_transfer(dsi, &msg); 749 } 750 EXPORT_SYMBOL(mipi_dsi_generic_write); 751 752 /** 753 * mipi_dsi_generic_read() - receive data using a generic read packet 754 * @dsi: DSI peripheral device 755 * @params: buffer containing the request parameters 756 * @num_params: number of request parameters 757 * @data: buffer in which to return the received data 758 * @size: size of receive buffer 759 * 760 * This function will automatically choose the right data type depending on 761 * the number of parameters passed in. 762 * 763 * Return: The number of bytes successfully read or a negative error code on 764 * failure. 765 */ 766 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 767 size_t num_params, void *data, size_t size) 768 { 769 struct mipi_dsi_msg msg = { 770 .channel = dsi->channel, 771 .tx_len = num_params, 772 .tx_buf = params, 773 .rx_len = size, 774 .rx_buf = data 775 }; 776 777 switch (num_params) { 778 case 0: 779 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 780 break; 781 782 case 1: 783 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 784 break; 785 786 case 2: 787 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 788 break; 789 790 default: 791 return -EINVAL; 792 } 793 794 return mipi_dsi_device_transfer(dsi, &msg); 795 } 796 EXPORT_SYMBOL(mipi_dsi_generic_read); 797 798 /** 799 * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 800 * @dsi: DSI peripheral device 801 * @data: buffer containing data to be transmitted 802 * @len: size of transmission buffer 803 * 804 * This function will automatically choose the right data type depending on 805 * the command payload length. 806 * 807 * Return: The number of bytes successfully transmitted or a negative error 808 * code on failure. 809 */ 810 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 811 const void *data, size_t len) 812 { 813 struct mipi_dsi_msg msg = { 814 .channel = dsi->channel, 815 .tx_buf = data, 816 .tx_len = len 817 }; 818 819 switch (len) { 820 case 0: 821 return -EINVAL; 822 823 case 1: 824 msg.type = MIPI_DSI_DCS_SHORT_WRITE; 825 break; 826 827 case 2: 828 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 829 break; 830 831 default: 832 msg.type = MIPI_DSI_DCS_LONG_WRITE; 833 break; 834 } 835 836 return mipi_dsi_device_transfer(dsi, &msg); 837 } 838 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 839 840 /** 841 * mipi_dsi_dcs_write() - send DCS write command 842 * @dsi: DSI peripheral device 843 * @cmd: DCS command 844 * @data: buffer containing the command payload 845 * @len: command payload length 846 * 847 * This function will automatically choose the right data type depending on 848 * the command payload length. 849 * 850 * Return: The number of bytes successfully transmitted or a negative error 851 * code on failure. 852 */ 853 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 854 const void *data, size_t len) 855 { 856 ssize_t err; 857 size_t size; 858 u8 stack_tx[8]; 859 u8 *tx; 860 861 size = 1 + len; 862 if (len > ARRAY_SIZE(stack_tx) - 1) { 863 tx = kmalloc(size, GFP_KERNEL); 864 if (!tx) 865 return -ENOMEM; 866 } else { 867 tx = stack_tx; 868 } 869 870 /* concatenate the DCS command byte and the payload */ 871 tx[0] = cmd; 872 if (data) 873 memcpy(&tx[1], data, len); 874 875 err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 876 877 if (tx != stack_tx) 878 kfree(tx); 879 880 return err; 881 } 882 EXPORT_SYMBOL(mipi_dsi_dcs_write); 883 884 /** 885 * mipi_dsi_dcs_read() - send DCS read request command 886 * @dsi: DSI peripheral device 887 * @cmd: DCS command 888 * @data: buffer in which to receive data 889 * @len: size of receive buffer 890 * 891 * Return: The number of bytes read or a negative error code on failure. 892 */ 893 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 894 size_t len) 895 { 896 struct mipi_dsi_msg msg = { 897 .channel = dsi->channel, 898 .type = MIPI_DSI_DCS_READ, 899 .tx_buf = &cmd, 900 .tx_len = 1, 901 .rx_buf = data, 902 .rx_len = len 903 }; 904 905 return mipi_dsi_device_transfer(dsi, &msg); 906 } 907 EXPORT_SYMBOL(mipi_dsi_dcs_read); 908 909 /** 910 * mipi_dsi_dcs_nop() - send DCS nop packet 911 * @dsi: DSI peripheral device 912 * 913 * Return: 0 on success or a negative error code on failure. 914 */ 915 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 916 { 917 ssize_t err; 918 919 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 920 if (err < 0) 921 return err; 922 923 return 0; 924 } 925 EXPORT_SYMBOL(mipi_dsi_dcs_nop); 926 927 /** 928 * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 929 * @dsi: DSI peripheral device 930 * 931 * Return: 0 on success or a negative error code on failure. 932 */ 933 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 934 { 935 ssize_t err; 936 937 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 938 if (err < 0) 939 return err; 940 941 return 0; 942 } 943 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 944 945 /** 946 * mipi_dsi_dcs_get_power_mode() - query the display module's current power 947 * mode 948 * @dsi: DSI peripheral device 949 * @mode: return location for the current power mode 950 * 951 * Return: 0 on success or a negative error code on failure. 952 */ 953 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 954 { 955 ssize_t err; 956 957 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 958 sizeof(*mode)); 959 if (err <= 0) { 960 if (err == 0) 961 err = -ENODATA; 962 963 return err; 964 } 965 966 return 0; 967 } 968 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 969 970 /** 971 * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 972 * data used by the interface 973 * @dsi: DSI peripheral device 974 * @format: return location for the pixel format 975 * 976 * Return: 0 on success or a negative error code on failure. 977 */ 978 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 979 { 980 ssize_t err; 981 982 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 983 sizeof(*format)); 984 if (err <= 0) { 985 if (err == 0) 986 err = -ENODATA; 987 988 return err; 989 } 990 991 return 0; 992 } 993 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 994 995 /** 996 * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 997 * display module except interface communication 998 * @dsi: DSI peripheral device 999 * 1000 * Return: 0 on success or a negative error code on failure. 1001 */ 1002 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 1003 { 1004 ssize_t err; 1005 1006 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 1007 if (err < 0) 1008 return err; 1009 1010 return 0; 1011 } 1012 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 1013 1014 /** 1015 * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 1016 * module 1017 * @dsi: DSI peripheral device 1018 * 1019 * Return: 0 on success or a negative error code on failure. 1020 */ 1021 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 1022 { 1023 ssize_t err; 1024 1025 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 1026 if (err < 0) 1027 return err; 1028 1029 return 0; 1030 } 1031 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 1032 1033 /** 1034 * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 1035 * display device 1036 * @dsi: DSI peripheral device 1037 * 1038 * Return: 0 on success or a negative error code on failure. 1039 */ 1040 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 1041 { 1042 ssize_t err; 1043 1044 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 1045 if (err < 0) 1046 return err; 1047 1048 return 0; 1049 } 1050 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 1051 1052 /** 1053 * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 1054 * display device 1055 * @dsi: DSI peripheral device 1056 * 1057 * Return: 0 on success or a negative error code on failure 1058 */ 1059 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 1060 { 1061 ssize_t err; 1062 1063 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 1064 if (err < 0) 1065 return err; 1066 1067 return 0; 1068 } 1069 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 1070 1071 /** 1072 * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 1073 * memory accessed by the host processor 1074 * @dsi: DSI peripheral device 1075 * @start: first column of frame memory 1076 * @end: last column of frame memory 1077 * 1078 * Return: 0 on success or a negative error code on failure. 1079 */ 1080 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 1081 u16 end) 1082 { 1083 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1084 ssize_t err; 1085 1086 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 1087 sizeof(payload)); 1088 if (err < 0) 1089 return err; 1090 1091 return 0; 1092 } 1093 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 1094 1095 /** 1096 * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 1097 * memory accessed by the host processor 1098 * @dsi: DSI peripheral device 1099 * @start: first page of frame memory 1100 * @end: last page of frame memory 1101 * 1102 * Return: 0 on success or a negative error code on failure. 1103 */ 1104 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 1105 u16 end) 1106 { 1107 u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1108 ssize_t err; 1109 1110 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 1111 sizeof(payload)); 1112 if (err < 0) 1113 return err; 1114 1115 return 0; 1116 } 1117 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 1118 1119 /** 1120 * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect 1121 * output signal on the TE signal line 1122 * @dsi: DSI peripheral device 1123 * 1124 * Return: 0 on success or a negative error code on failure 1125 */ 1126 int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) 1127 { 1128 ssize_t err; 1129 1130 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 1131 if (err < 0) 1132 return err; 1133 1134 return 0; 1135 } 1136 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); 1137 1138 /** 1139 * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 1140 * output signal on the TE signal line. 1141 * @dsi: DSI peripheral device 1142 * @mode: the Tearing Effect Output Line mode 1143 * 1144 * Return: 0 on success or a negative error code on failure 1145 */ 1146 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 1147 enum mipi_dsi_dcs_tear_mode mode) 1148 { 1149 u8 value = mode; 1150 ssize_t err; 1151 1152 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 1153 sizeof(value)); 1154 if (err < 0) 1155 return err; 1156 1157 return 0; 1158 } 1159 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 1160 1161 /** 1162 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1163 * data used by the interface 1164 * @dsi: DSI peripheral device 1165 * @format: pixel format 1166 * 1167 * Return: 0 on success or a negative error code on failure. 1168 */ 1169 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 1170 { 1171 ssize_t err; 1172 1173 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 1174 sizeof(format)); 1175 if (err < 0) 1176 return err; 1177 1178 return 0; 1179 } 1180 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 1181 1182 #ifdef notyet 1183 1184 /** 1185 * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 1186 * the Tearing Effect output signal of the display module 1187 * @dsi: DSI peripheral device 1188 * @scanline: scanline to use as trigger 1189 * 1190 * Return: 0 on success or a negative error code on failure 1191 */ 1192 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1193 { 1194 u8 payload[2] = { scanline >> 8, scanline & 0xff }; 1195 ssize_t err; 1196 1197 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, 1198 sizeof(payload)); 1199 if (err < 0) 1200 return err; 1201 1202 return 0; 1203 } 1204 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 1205 1206 /** 1207 * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 1208 * display 1209 * @dsi: DSI peripheral device 1210 * @brightness: brightness value 1211 * 1212 * Return: 0 on success or a negative error code on failure. 1213 */ 1214 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 1215 u16 brightness) 1216 { 1217 u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 1218 ssize_t err; 1219 1220 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1221 payload, sizeof(payload)); 1222 if (err < 0) 1223 return err; 1224 1225 return 0; 1226 } 1227 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 1228 1229 /** 1230 * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 1231 * of the display 1232 * @dsi: DSI peripheral device 1233 * @brightness: brightness value 1234 * 1235 * Return: 0 on success or a negative error code on failure. 1236 */ 1237 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 1238 u16 *brightness) 1239 { 1240 ssize_t err; 1241 1242 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1243 brightness, sizeof(*brightness)); 1244 if (err <= 0) { 1245 if (err == 0) 1246 err = -ENODATA; 1247 1248 return err; 1249 } 1250 1251 return 0; 1252 } 1253 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 1254 1255 /** 1256 * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value 1257 * of the display 1258 * @dsi: DSI peripheral device 1259 * @brightness: brightness value 1260 * 1261 * Return: 0 on success or a negative error code on failure. 1262 */ 1263 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, 1264 u16 brightness) 1265 { 1266 u8 payload[2] = { brightness >> 8, brightness & 0xff }; 1267 ssize_t err; 1268 1269 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1270 payload, sizeof(payload)); 1271 if (err < 0) 1272 return err; 1273 1274 return 0; 1275 } 1276 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); 1277 1278 /** 1279 * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit 1280 * brightness value of the display 1281 * @dsi: DSI peripheral device 1282 * @brightness: brightness value 1283 * 1284 * Return: 0 on success or a negative error code on failure. 1285 */ 1286 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, 1287 u16 *brightness) 1288 { 1289 u8 brightness_be[2]; 1290 ssize_t err; 1291 1292 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1293 brightness_be, sizeof(brightness_be)); 1294 if (err <= 0) { 1295 if (err == 0) 1296 err = -ENODATA; 1297 1298 return err; 1299 } 1300 1301 *brightness = (brightness_be[0] << 8) | brightness_be[1]; 1302 1303 return 0; 1304 } 1305 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); 1306 1307 static int mipi_dsi_drv_probe(struct device *dev) 1308 { 1309 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1310 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1311 1312 return drv->probe(dsi); 1313 } 1314 1315 static int mipi_dsi_drv_remove(struct device *dev) 1316 { 1317 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1318 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1319 1320 drv->remove(dsi); 1321 1322 return 0; 1323 } 1324 1325 static void mipi_dsi_drv_shutdown(struct device *dev) 1326 { 1327 struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1328 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1329 1330 drv->shutdown(dsi); 1331 } 1332 1333 /** 1334 * mipi_dsi_driver_register_full() - register a driver for DSI devices 1335 * @drv: DSI driver structure 1336 * @owner: owner module 1337 * 1338 * Return: 0 on success or a negative error code on failure. 1339 */ 1340 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 1341 struct module *owner) 1342 { 1343 drv->driver.bus = &mipi_dsi_bus_type; 1344 drv->driver.owner = owner; 1345 1346 if (drv->probe) 1347 drv->driver.probe = mipi_dsi_drv_probe; 1348 if (drv->remove) 1349 drv->driver.remove = mipi_dsi_drv_remove; 1350 if (drv->shutdown) 1351 drv->driver.shutdown = mipi_dsi_drv_shutdown; 1352 1353 return driver_register(&drv->driver); 1354 } 1355 EXPORT_SYMBOL(mipi_dsi_driver_register_full); 1356 1357 /** 1358 * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 1359 * @drv: DSI driver structure 1360 * 1361 * Return: 0 on success or a negative error code on failure. 1362 */ 1363 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 1364 { 1365 driver_unregister(&drv->driver); 1366 } 1367 EXPORT_SYMBOL(mipi_dsi_driver_unregister); 1368 1369 static int __init mipi_dsi_bus_init(void) 1370 { 1371 return bus_register(&mipi_dsi_bus_type); 1372 } 1373 postcore_initcall(mipi_dsi_bus_init); 1374 1375 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>"); 1376 MODULE_DESCRIPTION("MIPI DSI Bus"); 1377 MODULE_LICENSE("GPL and additional rights"); 1378 1379 #endif 1380