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