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