]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/drm_mipi_dsi.c
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
[karo-tx-linux.git] / drivers / gpu / drm / drm_mipi_dsi.c
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", &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");