0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/device.h>
0029 #include <linux/module.h>
0030 #include <linux/of_device.h>
0031 #include <linux/pm_runtime.h>
0032 #include <linux/slab.h>
0033
0034 #include <drm/display/drm_dsc.h>
0035 #include <drm/drm_mipi_dsi.h>
0036 #include <drm/drm_print.h>
0037
0038 #include <video/mipi_display.h>
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
0051 {
0052 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
0053
0054
0055 if (of_driver_match_device(dev, drv))
0056 return 1;
0057
0058
0059 if (!strcmp(dsi->name, drv->name))
0060 return 1;
0061
0062 return 0;
0063 }
0064
0065 static int mipi_dsi_uevent(struct device *dev, struct kobj_uevent_env *env)
0066 {
0067 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
0068 int err;
0069
0070 err = of_device_uevent_modalias(dev, env);
0071 if (err != -ENODEV)
0072 return err;
0073
0074 add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX,
0075 dsi->name);
0076
0077 return 0;
0078 }
0079
0080 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
0081 .runtime_suspend = pm_generic_runtime_suspend,
0082 .runtime_resume = pm_generic_runtime_resume,
0083 .suspend = pm_generic_suspend,
0084 .resume = pm_generic_resume,
0085 .freeze = pm_generic_freeze,
0086 .thaw = pm_generic_thaw,
0087 .poweroff = pm_generic_poweroff,
0088 .restore = pm_generic_restore,
0089 };
0090
0091 static struct bus_type mipi_dsi_bus_type = {
0092 .name = "mipi-dsi",
0093 .match = mipi_dsi_device_match,
0094 .uevent = mipi_dsi_uevent,
0095 .pm = &mipi_dsi_device_pm_ops,
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
0107 {
0108 struct device *dev;
0109
0110 dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
0111
0112 return dev ? to_mipi_dsi_device(dev) : NULL;
0113 }
0114 EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
0115
0116 static void mipi_dsi_dev_release(struct device *dev)
0117 {
0118 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
0119
0120 of_node_put(dev->of_node);
0121 kfree(dsi);
0122 }
0123
0124 static const struct device_type mipi_dsi_device_type = {
0125 .release = mipi_dsi_dev_release,
0126 };
0127
0128 static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
0129 {
0130 struct mipi_dsi_device *dsi;
0131
0132 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
0133 if (!dsi)
0134 return ERR_PTR(-ENOMEM);
0135
0136 dsi->host = host;
0137 dsi->dev.bus = &mipi_dsi_bus_type;
0138 dsi->dev.parent = host->dev;
0139 dsi->dev.type = &mipi_dsi_device_type;
0140
0141 device_initialize(&dsi->dev);
0142
0143 return dsi;
0144 }
0145
0146 static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
0147 {
0148 struct mipi_dsi_host *host = dsi->host;
0149
0150 dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), dsi->channel);
0151
0152 return device_add(&dsi->dev);
0153 }
0154
0155 #if IS_ENABLED(CONFIG_OF)
0156 static struct mipi_dsi_device *
0157 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
0158 {
0159 struct mipi_dsi_device_info info = { };
0160 int ret;
0161 u32 reg;
0162
0163 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
0164 drm_err(host, "modalias failure on %pOF\n", node);
0165 return ERR_PTR(-EINVAL);
0166 }
0167
0168 ret = of_property_read_u32(node, "reg", ®);
0169 if (ret) {
0170 drm_err(host, "device node %pOF has no valid reg property: %d\n",
0171 node, ret);
0172 return ERR_PTR(-EINVAL);
0173 }
0174
0175 info.channel = reg;
0176 info.node = of_node_get(node);
0177
0178 return mipi_dsi_device_register_full(host, &info);
0179 }
0180 #else
0181 static struct mipi_dsi_device *
0182 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
0183 {
0184 return ERR_PTR(-ENODEV);
0185 }
0186 #endif
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 struct mipi_dsi_device *
0201 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
0202 const struct mipi_dsi_device_info *info)
0203 {
0204 struct mipi_dsi_device *dsi;
0205 int ret;
0206
0207 if (!info) {
0208 drm_err(host, "invalid mipi_dsi_device_info pointer\n");
0209 return ERR_PTR(-EINVAL);
0210 }
0211
0212 if (info->channel > 3) {
0213 drm_err(host, "invalid virtual channel: %u\n", info->channel);
0214 return ERR_PTR(-EINVAL);
0215 }
0216
0217 dsi = mipi_dsi_device_alloc(host);
0218 if (IS_ERR(dsi)) {
0219 drm_err(host, "failed to allocate DSI device %ld\n",
0220 PTR_ERR(dsi));
0221 return dsi;
0222 }
0223
0224 dsi->dev.of_node = info->node;
0225 dsi->channel = info->channel;
0226 strlcpy(dsi->name, info->type, sizeof(dsi->name));
0227
0228 ret = mipi_dsi_device_add(dsi);
0229 if (ret) {
0230 drm_err(host, "failed to add DSI device %d\n", ret);
0231 kfree(dsi);
0232 return ERR_PTR(ret);
0233 }
0234
0235 return dsi;
0236 }
0237 EXPORT_SYMBOL(mipi_dsi_device_register_full);
0238
0239
0240
0241
0242
0243 void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
0244 {
0245 device_unregister(&dsi->dev);
0246 }
0247 EXPORT_SYMBOL(mipi_dsi_device_unregister);
0248
0249 static void devm_mipi_dsi_device_unregister(void *arg)
0250 {
0251 struct mipi_dsi_device *dsi = arg;
0252
0253 mipi_dsi_device_unregister(dsi);
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 struct mipi_dsi_device *
0274 devm_mipi_dsi_device_register_full(struct device *dev,
0275 struct mipi_dsi_host *host,
0276 const struct mipi_dsi_device_info *info)
0277 {
0278 struct mipi_dsi_device *dsi;
0279 int ret;
0280
0281 dsi = mipi_dsi_device_register_full(host, info);
0282 if (IS_ERR(dsi))
0283 return dsi;
0284
0285 ret = devm_add_action_or_reset(dev,
0286 devm_mipi_dsi_device_unregister,
0287 dsi);
0288 if (ret)
0289 return ERR_PTR(ret);
0290
0291 return dsi;
0292 }
0293 EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
0294
0295 static DEFINE_MUTEX(host_lock);
0296 static LIST_HEAD(host_list);
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
0308 {
0309 struct mipi_dsi_host *host;
0310
0311 mutex_lock(&host_lock);
0312
0313 list_for_each_entry(host, &host_list, list) {
0314 if (host->dev->of_node == node) {
0315 mutex_unlock(&host_lock);
0316 return host;
0317 }
0318 }
0319
0320 mutex_unlock(&host_lock);
0321
0322 return NULL;
0323 }
0324 EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
0325
0326 int mipi_dsi_host_register(struct mipi_dsi_host *host)
0327 {
0328 struct device_node *node;
0329
0330 for_each_available_child_of_node(host->dev->of_node, node) {
0331
0332 if (!of_find_property(node, "reg", NULL))
0333 continue;
0334 of_mipi_dsi_device_add(host, node);
0335 }
0336
0337 mutex_lock(&host_lock);
0338 list_add_tail(&host->list, &host_list);
0339 mutex_unlock(&host_lock);
0340
0341 return 0;
0342 }
0343 EXPORT_SYMBOL(mipi_dsi_host_register);
0344
0345 static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
0346 {
0347 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
0348
0349 mipi_dsi_device_unregister(dsi);
0350
0351 return 0;
0352 }
0353
0354 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
0355 {
0356 device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
0357
0358 mutex_lock(&host_lock);
0359 list_del_init(&host->list);
0360 mutex_unlock(&host_lock);
0361 }
0362 EXPORT_SYMBOL(mipi_dsi_host_unregister);
0363
0364
0365
0366
0367
0368 int mipi_dsi_attach(struct mipi_dsi_device *dsi)
0369 {
0370 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
0371
0372 if (!ops || !ops->attach)
0373 return -ENOSYS;
0374
0375 return ops->attach(dsi->host, dsi);
0376 }
0377 EXPORT_SYMBOL(mipi_dsi_attach);
0378
0379
0380
0381
0382
0383 int mipi_dsi_detach(struct mipi_dsi_device *dsi)
0384 {
0385 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
0386
0387 if (!ops || !ops->detach)
0388 return -ENOSYS;
0389
0390 return ops->detach(dsi->host, dsi);
0391 }
0392 EXPORT_SYMBOL(mipi_dsi_detach);
0393
0394 static void devm_mipi_dsi_detach(void *arg)
0395 {
0396 struct mipi_dsi_device *dsi = arg;
0397
0398 mipi_dsi_detach(dsi);
0399 }
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 int devm_mipi_dsi_attach(struct device *dev,
0413 struct mipi_dsi_device *dsi)
0414 {
0415 int ret;
0416
0417 ret = mipi_dsi_attach(dsi);
0418 if (ret)
0419 return ret;
0420
0421 ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
0422 if (ret)
0423 return ret;
0424
0425 return 0;
0426 }
0427 EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
0428
0429 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
0430 struct mipi_dsi_msg *msg)
0431 {
0432 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
0433
0434 if (!ops || !ops->transfer)
0435 return -ENOSYS;
0436
0437 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
0438 msg->flags |= MIPI_DSI_MSG_USE_LPM;
0439
0440 return ops->transfer(dsi->host, msg);
0441 }
0442
0443
0444
0445
0446
0447
0448
0449
0450 bool mipi_dsi_packet_format_is_short(u8 type)
0451 {
0452 switch (type) {
0453 case MIPI_DSI_V_SYNC_START:
0454 case MIPI_DSI_V_SYNC_END:
0455 case MIPI_DSI_H_SYNC_START:
0456 case MIPI_DSI_H_SYNC_END:
0457 case MIPI_DSI_COMPRESSION_MODE:
0458 case MIPI_DSI_END_OF_TRANSMISSION:
0459 case MIPI_DSI_COLOR_MODE_OFF:
0460 case MIPI_DSI_COLOR_MODE_ON:
0461 case MIPI_DSI_SHUTDOWN_PERIPHERAL:
0462 case MIPI_DSI_TURN_ON_PERIPHERAL:
0463 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
0464 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
0465 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
0466 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
0467 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
0468 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
0469 case MIPI_DSI_DCS_SHORT_WRITE:
0470 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
0471 case MIPI_DSI_DCS_READ:
0472 case MIPI_DSI_EXECUTE_QUEUE:
0473 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
0474 return true;
0475 }
0476
0477 return false;
0478 }
0479 EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
0480
0481
0482
0483
0484
0485
0486
0487
0488 bool mipi_dsi_packet_format_is_long(u8 type)
0489 {
0490 switch (type) {
0491 case MIPI_DSI_NULL_PACKET:
0492 case MIPI_DSI_BLANKING_PACKET:
0493 case MIPI_DSI_GENERIC_LONG_WRITE:
0494 case MIPI_DSI_DCS_LONG_WRITE:
0495 case MIPI_DSI_PICTURE_PARAMETER_SET:
0496 case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
0497 case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
0498 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
0499 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
0500 case MIPI_DSI_PACKED_PIXEL_STREAM_30:
0501 case MIPI_DSI_PACKED_PIXEL_STREAM_36:
0502 case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
0503 case MIPI_DSI_PACKED_PIXEL_STREAM_16:
0504 case MIPI_DSI_PACKED_PIXEL_STREAM_18:
0505 case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
0506 case MIPI_DSI_PACKED_PIXEL_STREAM_24:
0507 return true;
0508 }
0509
0510 return false;
0511 }
0512 EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
0523 const struct mipi_dsi_msg *msg)
0524 {
0525 if (!packet || !msg)
0526 return -EINVAL;
0527
0528
0529 if (!mipi_dsi_packet_format_is_short(msg->type) &&
0530 !mipi_dsi_packet_format_is_long(msg->type))
0531 return -EINVAL;
0532
0533 if (msg->channel > 3)
0534 return -EINVAL;
0535
0536 memset(packet, 0, sizeof(*packet));
0537 packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 if (mipi_dsi_packet_format_is_long(msg->type)) {
0549 packet->header[1] = (msg->tx_len >> 0) & 0xff;
0550 packet->header[2] = (msg->tx_len >> 8) & 0xff;
0551
0552 packet->payload_length = msg->tx_len;
0553 packet->payload = msg->tx_buf;
0554 } else {
0555 const u8 *tx = msg->tx_buf;
0556
0557 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
0558 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
0559 }
0560
0561 packet->size = sizeof(packet->header) + packet->payload_length;
0562
0563 return 0;
0564 }
0565 EXPORT_SYMBOL(mipi_dsi_create_packet);
0566
0567
0568
0569
0570
0571
0572
0573 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
0574 {
0575 struct mipi_dsi_msg msg = {
0576 .channel = dsi->channel,
0577 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
0578 .tx_buf = (u8 [2]) { 0, 0 },
0579 .tx_len = 2,
0580 };
0581 int ret = mipi_dsi_device_transfer(dsi, &msg);
0582
0583 return (ret < 0) ? ret : 0;
0584 }
0585 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
0586
0587
0588
0589
0590
0591
0592
0593 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
0594 {
0595 struct mipi_dsi_msg msg = {
0596 .channel = dsi->channel,
0597 .type = MIPI_DSI_TURN_ON_PERIPHERAL,
0598 .tx_buf = (u8 [2]) { 0, 0 },
0599 .tx_len = 2,
0600 };
0601 int ret = mipi_dsi_device_transfer(dsi, &msg);
0602
0603 return (ret < 0) ? ret : 0;
0604 }
0605 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
0617 u16 value)
0618 {
0619 u8 tx[2] = { value & 0xff, value >> 8 };
0620 struct mipi_dsi_msg msg = {
0621 .channel = dsi->channel,
0622 .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
0623 .tx_len = sizeof(tx),
0624 .tx_buf = tx,
0625 };
0626 int ret = mipi_dsi_device_transfer(dsi, &msg);
0627
0628 return (ret < 0) ? ret : 0;
0629 }
0630 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642 ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
0643 {
0644
0645 u8 tx[2] = { enable << 0, 0 };
0646 struct mipi_dsi_msg msg = {
0647 .channel = dsi->channel,
0648 .type = MIPI_DSI_COMPRESSION_MODE,
0649 .tx_len = sizeof(tx),
0650 .tx_buf = tx,
0651 };
0652 int ret = mipi_dsi_device_transfer(dsi, &msg);
0653
0654 return (ret < 0) ? ret : 0;
0655 }
0656 EXPORT_SYMBOL(mipi_dsi_compression_mode);
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
0668 const struct drm_dsc_picture_parameter_set *pps)
0669 {
0670 struct mipi_dsi_msg msg = {
0671 .channel = dsi->channel,
0672 .type = MIPI_DSI_PICTURE_PARAMETER_SET,
0673 .tx_len = sizeof(*pps),
0674 .tx_buf = pps,
0675 };
0676 int ret = mipi_dsi_device_transfer(dsi, &msg);
0677
0678 return (ret < 0) ? ret : 0;
0679 }
0680 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
0695 size_t size)
0696 {
0697 struct mipi_dsi_msg msg = {
0698 .channel = dsi->channel,
0699 .tx_buf = payload,
0700 .tx_len = size
0701 };
0702
0703 switch (size) {
0704 case 0:
0705 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
0706 break;
0707
0708 case 1:
0709 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
0710 break;
0711
0712 case 2:
0713 msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
0714 break;
0715
0716 default:
0717 msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
0718 break;
0719 }
0720
0721 return mipi_dsi_device_transfer(dsi, &msg);
0722 }
0723 EXPORT_SYMBOL(mipi_dsi_generic_write);
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
0740 size_t num_params, void *data, size_t size)
0741 {
0742 struct mipi_dsi_msg msg = {
0743 .channel = dsi->channel,
0744 .tx_len = num_params,
0745 .tx_buf = params,
0746 .rx_len = size,
0747 .rx_buf = data
0748 };
0749
0750 switch (num_params) {
0751 case 0:
0752 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
0753 break;
0754
0755 case 1:
0756 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
0757 break;
0758
0759 case 2:
0760 msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
0761 break;
0762
0763 default:
0764 return -EINVAL;
0765 }
0766
0767 return mipi_dsi_device_transfer(dsi, &msg);
0768 }
0769 EXPORT_SYMBOL(mipi_dsi_generic_read);
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
0784 const void *data, size_t len)
0785 {
0786 struct mipi_dsi_msg msg = {
0787 .channel = dsi->channel,
0788 .tx_buf = data,
0789 .tx_len = len
0790 };
0791
0792 switch (len) {
0793 case 0:
0794 return -EINVAL;
0795
0796 case 1:
0797 msg.type = MIPI_DSI_DCS_SHORT_WRITE;
0798 break;
0799
0800 case 2:
0801 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
0802 break;
0803
0804 default:
0805 msg.type = MIPI_DSI_DCS_LONG_WRITE;
0806 break;
0807 }
0808
0809 return mipi_dsi_device_transfer(dsi, &msg);
0810 }
0811 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
0827 const void *data, size_t len)
0828 {
0829 ssize_t err;
0830 size_t size;
0831 u8 stack_tx[8];
0832 u8 *tx;
0833
0834 size = 1 + len;
0835 if (len > ARRAY_SIZE(stack_tx) - 1) {
0836 tx = kmalloc(size, GFP_KERNEL);
0837 if (!tx)
0838 return -ENOMEM;
0839 } else {
0840 tx = stack_tx;
0841 }
0842
0843
0844 tx[0] = cmd;
0845 if (data)
0846 memcpy(&tx[1], data, len);
0847
0848 err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
0849
0850 if (tx != stack_tx)
0851 kfree(tx);
0852
0853 return err;
0854 }
0855 EXPORT_SYMBOL(mipi_dsi_dcs_write);
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
0867 size_t len)
0868 {
0869 struct mipi_dsi_msg msg = {
0870 .channel = dsi->channel,
0871 .type = MIPI_DSI_DCS_READ,
0872 .tx_buf = &cmd,
0873 .tx_len = 1,
0874 .rx_buf = data,
0875 .rx_len = len
0876 };
0877
0878 return mipi_dsi_device_transfer(dsi, &msg);
0879 }
0880 EXPORT_SYMBOL(mipi_dsi_dcs_read);
0881
0882
0883
0884
0885
0886
0887
0888 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
0889 {
0890 ssize_t err;
0891
0892 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
0893 if (err < 0)
0894 return err;
0895
0896 return 0;
0897 }
0898 EXPORT_SYMBOL(mipi_dsi_dcs_nop);
0899
0900
0901
0902
0903
0904
0905
0906 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
0907 {
0908 ssize_t err;
0909
0910 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
0911 if (err < 0)
0912 return err;
0913
0914 return 0;
0915 }
0916 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
0927 {
0928 ssize_t err;
0929
0930 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
0931 sizeof(*mode));
0932 if (err <= 0) {
0933 if (err == 0)
0934 err = -ENODATA;
0935
0936 return err;
0937 }
0938
0939 return 0;
0940 }
0941 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
0952 {
0953 ssize_t err;
0954
0955 err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
0956 sizeof(*format));
0957 if (err <= 0) {
0958 if (err == 0)
0959 err = -ENODATA;
0960
0961 return err;
0962 }
0963
0964 return 0;
0965 }
0966 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
0967
0968
0969
0970
0971
0972
0973
0974
0975 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
0976 {
0977 ssize_t err;
0978
0979 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
0980 if (err < 0)
0981 return err;
0982
0983 return 0;
0984 }
0985 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
0986
0987
0988
0989
0990
0991
0992
0993
0994 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
0995 {
0996 ssize_t err;
0997
0998 err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
0999 if (err < 0)
1000 return err;
1001
1002 return 0;
1003 }
1004 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
1005
1006
1007
1008
1009
1010
1011
1012
1013 int 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 }
1023 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
1024
1025
1026
1027
1028
1029
1030
1031
1032 int 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 }
1042 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053 int 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 }
1066 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 int 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 }
1090 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
1091
1092
1093
1094
1095
1096
1097
1098
1099 int 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 }
1109 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 int 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 }
1132 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142 int 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 }
1153 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163 int 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 }
1175 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185 int 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 }
1198 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness);
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 int 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 }
1224 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
1225
1226 static 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
1234 static 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
1242 static 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
1252
1253
1254
1255
1256
1257 int 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 }
1272 EXPORT_SYMBOL(mipi_dsi_driver_register_full);
1273
1274
1275
1276
1277
1278
1279
1280 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
1281 {
1282 driver_unregister(&drv->driver);
1283 }
1284 EXPORT_SYMBOL(mipi_dsi_driver_unregister);
1285
1286 static int __init mipi_dsi_bus_init(void)
1287 {
1288 return bus_register(&mipi_dsi_bus_type);
1289 }
1290 postcore_initcall(mipi_dsi_bus_init);
1291
1292 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
1293 MODULE_DESCRIPTION("MIPI DSI Bus");
1294 MODULE_LICENSE("GPL and additional rights");