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