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