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