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