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