xref: /linux/drivers/gpu/drm/drm_mipi_dsi.c (revision 906fd46a65383cd639e5eec72a047efc33045d86)
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 <linux/device.h>
29 #include <linux/module.h>
30 #include <linux/of.h>
31 #include <linux/of_device.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/slab.h>
34 
35 #include <drm/display/drm_dsc.h>
36 #include <drm/drm_mipi_dsi.h>
37 #include <drm/drm_print.h>
38 
39 #include <video/mipi_display.h>
40 
41 /**
42  * DOC: dsi helpers
43  *
44  * These functions contain some common logic and helpers to deal with MIPI DSI
45  * peripherals.
46  *
47  * Helpers are provided for a number of standard MIPI DSI command as well as a
48  * subset of the MIPI DCS command set.
49  */
50 
51 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
52 {
53 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
54 
55 	/* attempt OF style match */
56 	if (of_driver_match_device(dev, drv))
57 		return 1;
58 
59 	/* compare DSI device and driver names */
60 	if (!strcmp(dsi->name, drv->name))
61 		return 1;
62 
63 	return 0;
64 }
65 
66 static int mipi_dsi_uevent(const struct device *dev, struct kobj_uevent_env *env)
67 {
68 	const struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
69 	int err;
70 
71 	err = of_device_uevent_modalias(dev, env);
72 	if (err != -ENODEV)
73 		return err;
74 
75 	add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX,
76 		       dsi->name);
77 
78 	return 0;
79 }
80 
81 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
82 	.runtime_suspend = pm_generic_runtime_suspend,
83 	.runtime_resume = pm_generic_runtime_resume,
84 	.suspend = pm_generic_suspend,
85 	.resume = pm_generic_resume,
86 	.freeze = pm_generic_freeze,
87 	.thaw = pm_generic_thaw,
88 	.poweroff = pm_generic_poweroff,
89 	.restore = pm_generic_restore,
90 };
91 
92 static const struct bus_type mipi_dsi_bus_type = {
93 	.name = "mipi-dsi",
94 	.match = mipi_dsi_device_match,
95 	.uevent = mipi_dsi_uevent,
96 	.pm = &mipi_dsi_device_pm_ops,
97 };
98 
99 /**
100  * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
101  *    device tree node
102  * @np: device tree node
103  *
104  * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
105  *    such device exists (or has not been registered yet).
106  */
107 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
108 {
109 	struct device *dev;
110 
111 	dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
112 
113 	return dev ? to_mipi_dsi_device(dev) : NULL;
114 }
115 EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
116 
117 static void mipi_dsi_dev_release(struct device *dev)
118 {
119 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
120 
121 	of_node_put(dev->of_node);
122 	kfree(dsi);
123 }
124 
125 static const struct device_type mipi_dsi_device_type = {
126 	.release = mipi_dsi_dev_release,
127 };
128 
129 static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
130 {
131 	struct mipi_dsi_device *dsi;
132 
133 	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
134 	if (!dsi)
135 		return ERR_PTR(-ENOMEM);
136 
137 	dsi->host = host;
138 	dsi->dev.bus = &mipi_dsi_bus_type;
139 	dsi->dev.parent = host->dev;
140 	dsi->dev.type = &mipi_dsi_device_type;
141 
142 	device_initialize(&dsi->dev);
143 
144 	return dsi;
145 }
146 
147 static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
148 {
149 	struct mipi_dsi_host *host = dsi->host;
150 
151 	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
152 
153 	return device_add(&dsi->dev);
154 }
155 
156 #if IS_ENABLED(CONFIG_OF)
157 static struct mipi_dsi_device *
158 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
159 {
160 	struct mipi_dsi_device_info info = { };
161 	int ret;
162 	u32 reg;
163 
164 	if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
165 		drm_err(host, "modalias failure on %pOF\n", node);
166 		return ERR_PTR(-EINVAL);
167 	}
168 
169 	ret = of_property_read_u32(node, "reg", &reg);
170 	if (ret) {
171 		drm_err(host, "device node %pOF has no valid reg property: %d\n",
172 			node, ret);
173 		return ERR_PTR(-EINVAL);
174 	}
175 
176 	info.channel = reg;
177 	info.node = of_node_get(node);
178 
179 	return mipi_dsi_device_register_full(host, &info);
180 }
181 #else
182 static struct mipi_dsi_device *
183 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
184 {
185 	return ERR_PTR(-ENODEV);
186 }
187 #endif
188 
189 /**
190  * mipi_dsi_device_register_full - create a MIPI DSI device
191  * @host: DSI host to which this device is connected
192  * @info: pointer to template containing DSI device information
193  *
194  * Create a MIPI DSI device by using the device information provided by
195  * mipi_dsi_device_info template
196  *
197  * Returns:
198  * A pointer to the newly created MIPI DSI device, or, a pointer encoded
199  * with an error
200  */
201 struct mipi_dsi_device *
202 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
203 			      const struct mipi_dsi_device_info *info)
204 {
205 	struct mipi_dsi_device *dsi;
206 	int ret;
207 
208 	if (!info) {
209 		drm_err(host, "invalid mipi_dsi_device_info pointer\n");
210 		return ERR_PTR(-EINVAL);
211 	}
212 
213 	if (info->channel > 3) {
214 		drm_err(host, "invalid virtual channel: %u\n", info->channel);
215 		return ERR_PTR(-EINVAL);
216 	}
217 
218 	dsi = mipi_dsi_device_alloc(host);
219 	if (IS_ERR(dsi)) {
220 		drm_err(host, "failed to allocate DSI device %ld\n",
221 			PTR_ERR(dsi));
222 		return dsi;
223 	}
224 
225 	device_set_node(&dsi->dev, of_fwnode_handle(info->node));
226 	dsi->channel = info->channel;
227 	strscpy(dsi->name, info->type, sizeof(dsi->name));
228 
229 	ret = mipi_dsi_device_add(dsi);
230 	if (ret) {
231 		drm_err(host, "failed to add DSI device %d\n", ret);
232 		kfree(dsi);
233 		return ERR_PTR(ret);
234 	}
235 
236 	return dsi;
237 }
238 EXPORT_SYMBOL(mipi_dsi_device_register_full);
239 
240 /**
241  * mipi_dsi_device_unregister - unregister MIPI DSI device
242  * @dsi: DSI peripheral device
243  */
244 void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
245 {
246 	device_unregister(&dsi->dev);
247 }
248 EXPORT_SYMBOL(mipi_dsi_device_unregister);
249 
250 static void devm_mipi_dsi_device_unregister(void *arg)
251 {
252 	struct mipi_dsi_device *dsi = arg;
253 
254 	mipi_dsi_device_unregister(dsi);
255 }
256 
257 /**
258  * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
259  * @dev: device to tie the MIPI-DSI device lifetime to
260  * @host: DSI host to which this device is connected
261  * @info: pointer to template containing DSI device information
262  *
263  * Create a MIPI DSI device by using the device information provided by
264  * mipi_dsi_device_info template
265  *
266  * This is the managed version of mipi_dsi_device_register_full() which
267  * automatically calls mipi_dsi_device_unregister() when @dev is
268  * unbound.
269  *
270  * Returns:
271  * A pointer to the newly created MIPI DSI device, or, a pointer encoded
272  * with an error
273  */
274 struct mipi_dsi_device *
275 devm_mipi_dsi_device_register_full(struct device *dev,
276 				   struct mipi_dsi_host *host,
277 				   const struct mipi_dsi_device_info *info)
278 {
279 	struct mipi_dsi_device *dsi;
280 	int ret;
281 
282 	dsi = mipi_dsi_device_register_full(host, info);
283 	if (IS_ERR(dsi))
284 		return dsi;
285 
286 	ret = devm_add_action_or_reset(dev,
287 				       devm_mipi_dsi_device_unregister,
288 				       dsi);
289 	if (ret)
290 		return ERR_PTR(ret);
291 
292 	return dsi;
293 }
294 EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
295 
296 static DEFINE_MUTEX(host_lock);
297 static LIST_HEAD(host_list);
298 
299 /**
300  * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
301  *				     device tree node
302  * @node: device tree node
303  *
304  * Returns:
305  * A pointer to the MIPI DSI host corresponding to @node or NULL if no
306  * such device exists (or has not been registered yet).
307  */
308 struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
309 {
310 	struct mipi_dsi_host *host;
311 
312 	mutex_lock(&host_lock);
313 
314 	list_for_each_entry(host, &host_list, list) {
315 		if (host->dev->of_node == node) {
316 			mutex_unlock(&host_lock);
317 			return host;
318 		}
319 	}
320 
321 	mutex_unlock(&host_lock);
322 
323 	return NULL;
324 }
325 EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
326 
327 int mipi_dsi_host_register(struct mipi_dsi_host *host)
328 {
329 	struct device_node *node;
330 
331 	for_each_available_child_of_node(host->dev->of_node, node) {
332 		/* skip nodes without reg property */
333 		if (!of_property_present(node, "reg"))
334 			continue;
335 		of_mipi_dsi_device_add(host, node);
336 	}
337 
338 	mutex_lock(&host_lock);
339 	list_add_tail(&host->list, &host_list);
340 	mutex_unlock(&host_lock);
341 
342 	return 0;
343 }
344 EXPORT_SYMBOL(mipi_dsi_host_register);
345 
346 static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
347 {
348 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
349 
350 	if (dsi->attached)
351 		mipi_dsi_detach(dsi);
352 	mipi_dsi_device_unregister(dsi);
353 
354 	return 0;
355 }
356 
357 void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
358 {
359 	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
360 
361 	mutex_lock(&host_lock);
362 	list_del_init(&host->list);
363 	mutex_unlock(&host_lock);
364 }
365 EXPORT_SYMBOL(mipi_dsi_host_unregister);
366 
367 /**
368  * mipi_dsi_attach - attach a DSI device to its DSI host
369  * @dsi: DSI peripheral
370  */
371 int mipi_dsi_attach(struct mipi_dsi_device *dsi)
372 {
373 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
374 	int ret;
375 
376 	if (!ops || !ops->attach)
377 		return -ENOSYS;
378 
379 	ret = ops->attach(dsi->host, dsi);
380 	if (ret)
381 		return ret;
382 
383 	dsi->attached = true;
384 
385 	return 0;
386 }
387 EXPORT_SYMBOL(mipi_dsi_attach);
388 
389 /**
390  * mipi_dsi_detach - detach a DSI device from its DSI host
391  * @dsi: DSI peripheral
392  */
393 int mipi_dsi_detach(struct mipi_dsi_device *dsi)
394 {
395 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
396 
397 	if (WARN_ON(!dsi->attached))
398 		return -EINVAL;
399 
400 	if (!ops || !ops->detach)
401 		return -ENOSYS;
402 
403 	dsi->attached = false;
404 
405 	return ops->detach(dsi->host, dsi);
406 }
407 EXPORT_SYMBOL(mipi_dsi_detach);
408 
409 static void devm_mipi_dsi_detach(void *arg)
410 {
411 	struct mipi_dsi_device *dsi = arg;
412 
413 	mipi_dsi_detach(dsi);
414 }
415 
416 /**
417  * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
418  * @dev: device to tie the MIPI-DSI device attachment lifetime to
419  * @dsi: DSI peripheral
420  *
421  * This is the managed version of mipi_dsi_attach() which automatically
422  * calls mipi_dsi_detach() when @dev is unbound.
423  *
424  * Returns:
425  * 0 on success, a negative error code on failure.
426  */
427 int devm_mipi_dsi_attach(struct device *dev,
428 			 struct mipi_dsi_device *dsi)
429 {
430 	int ret;
431 
432 	ret = mipi_dsi_attach(dsi);
433 	if (ret)
434 		return ret;
435 
436 	ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
437 	if (ret)
438 		return ret;
439 
440 	return 0;
441 }
442 EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
443 
444 static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
445 					struct mipi_dsi_msg *msg)
446 {
447 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
448 
449 	if (!ops || !ops->transfer)
450 		return -ENOSYS;
451 
452 	if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
453 		msg->flags |= MIPI_DSI_MSG_USE_LPM;
454 
455 	return ops->transfer(dsi->host, msg);
456 }
457 
458 /**
459  * mipi_dsi_packet_format_is_short - check if a packet is of the short format
460  * @type: MIPI DSI data type of the packet
461  *
462  * Return: true if the packet for the given data type is a short packet, false
463  * otherwise.
464  */
465 bool mipi_dsi_packet_format_is_short(u8 type)
466 {
467 	switch (type) {
468 	case MIPI_DSI_V_SYNC_START:
469 	case MIPI_DSI_V_SYNC_END:
470 	case MIPI_DSI_H_SYNC_START:
471 	case MIPI_DSI_H_SYNC_END:
472 	case MIPI_DSI_COMPRESSION_MODE:
473 	case MIPI_DSI_END_OF_TRANSMISSION:
474 	case MIPI_DSI_COLOR_MODE_OFF:
475 	case MIPI_DSI_COLOR_MODE_ON:
476 	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
477 	case MIPI_DSI_TURN_ON_PERIPHERAL:
478 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
479 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
480 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
481 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
482 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
483 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
484 	case MIPI_DSI_DCS_SHORT_WRITE:
485 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
486 	case MIPI_DSI_DCS_READ:
487 	case MIPI_DSI_EXECUTE_QUEUE:
488 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
489 		return true;
490 	}
491 
492 	return false;
493 }
494 EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
495 
496 /**
497  * mipi_dsi_packet_format_is_long - check if a packet is of the long format
498  * @type: MIPI DSI data type of the packet
499  *
500  * Return: true if the packet for the given data type is a long packet, false
501  * otherwise.
502  */
503 bool mipi_dsi_packet_format_is_long(u8 type)
504 {
505 	switch (type) {
506 	case MIPI_DSI_NULL_PACKET:
507 	case MIPI_DSI_BLANKING_PACKET:
508 	case MIPI_DSI_GENERIC_LONG_WRITE:
509 	case MIPI_DSI_DCS_LONG_WRITE:
510 	case MIPI_DSI_PICTURE_PARAMETER_SET:
511 	case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
512 	case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
513 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
514 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
515 	case MIPI_DSI_PACKED_PIXEL_STREAM_30:
516 	case MIPI_DSI_PACKED_PIXEL_STREAM_36:
517 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
518 	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
519 	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
520 	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
521 	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
522 		return true;
523 	}
524 
525 	return false;
526 }
527 EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
528 
529 /**
530  * mipi_dsi_create_packet - create a packet from a message according to the
531  *     DSI protocol
532  * @packet: pointer to a DSI packet structure
533  * @msg: message to translate into a packet
534  *
535  * Return: 0 on success or a negative error code on failure.
536  */
537 int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
538 			   const struct mipi_dsi_msg *msg)
539 {
540 	if (!packet || !msg)
541 		return -EINVAL;
542 
543 	/* do some minimum sanity checking */
544 	if (!mipi_dsi_packet_format_is_short(msg->type) &&
545 	    !mipi_dsi_packet_format_is_long(msg->type))
546 		return -EINVAL;
547 
548 	if (msg->channel > 3)
549 		return -EINVAL;
550 
551 	memset(packet, 0, sizeof(*packet));
552 	packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
553 
554 	/* TODO: compute ECC if hardware support is not available */
555 
556 	/*
557 	 * Long write packets contain the word count in header bytes 1 and 2.
558 	 * The payload follows the header and is word count bytes long.
559 	 *
560 	 * Short write packets encode up to two parameters in header bytes 1
561 	 * and 2.
562 	 */
563 	if (mipi_dsi_packet_format_is_long(msg->type)) {
564 		packet->header[1] = (msg->tx_len >> 0) & 0xff;
565 		packet->header[2] = (msg->tx_len >> 8) & 0xff;
566 
567 		packet->payload_length = msg->tx_len;
568 		packet->payload = msg->tx_buf;
569 	} else {
570 		const u8 *tx = msg->tx_buf;
571 
572 		packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
573 		packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
574 	}
575 
576 	packet->size = sizeof(packet->header) + packet->payload_length;
577 
578 	return 0;
579 }
580 EXPORT_SYMBOL(mipi_dsi_create_packet);
581 
582 /**
583  * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
584  * @dsi: DSI peripheral device
585  *
586  * Return: 0 on success or a negative error code on failure.
587  */
588 int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
589 {
590 	struct mipi_dsi_msg msg = {
591 		.channel = dsi->channel,
592 		.type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
593 		.tx_buf = (u8 [2]) { 0, 0 },
594 		.tx_len = 2,
595 	};
596 	int ret = mipi_dsi_device_transfer(dsi, &msg);
597 
598 	return (ret < 0) ? ret : 0;
599 }
600 EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
601 
602 /**
603  * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
604  * @dsi: DSI peripheral device
605  *
606  * Return: 0 on success or a negative error code on failure.
607  */
608 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
609 {
610 	struct mipi_dsi_msg msg = {
611 		.channel = dsi->channel,
612 		.type = MIPI_DSI_TURN_ON_PERIPHERAL,
613 		.tx_buf = (u8 [2]) { 0, 0 },
614 		.tx_len = 2,
615 	};
616 	int ret = mipi_dsi_device_transfer(dsi, &msg);
617 
618 	return (ret < 0) ? ret : 0;
619 }
620 EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
621 
622 /*
623  * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of
624  *    the payload in a long packet transmitted from the peripheral back to the
625  *    host processor
626  * @dsi: DSI peripheral device
627  * @value: the maximum size of the payload
628  *
629  * Return: 0 on success or a negative error code on failure.
630  */
631 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
632 					    u16 value)
633 {
634 	u8 tx[2] = { value & 0xff, value >> 8 };
635 	struct mipi_dsi_msg msg = {
636 		.channel = dsi->channel,
637 		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
638 		.tx_len = sizeof(tx),
639 		.tx_buf = tx,
640 	};
641 	int ret = mipi_dsi_device_transfer(dsi, &msg);
642 
643 	return (ret < 0) ? ret : 0;
644 }
645 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
646 
647 /**
648  * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral
649  * @dsi: DSI peripheral device
650  * @enable: Whether to enable or disable the DSC
651  * @algo: Selected compression algorithm
652  * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
653  *
654  * Enable or disable Display Stream Compression on the peripheral.
655  *
656  * Return: 0 on success or a negative error code on failure.
657  */
658 int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
659 				  enum mipi_dsi_compression_algo algo,
660 				  unsigned int pps_selector)
661 {
662 	u8 tx[2] = { };
663 	struct mipi_dsi_msg msg = {
664 		.channel = dsi->channel,
665 		.type = MIPI_DSI_COMPRESSION_MODE,
666 		.tx_len = sizeof(tx),
667 		.tx_buf = tx,
668 	};
669 	int ret;
670 
671 	if (algo > 3 || pps_selector > 3)
672 		return -EINVAL;
673 
674 	tx[0] = (enable << 0) |
675 		(algo << 1) |
676 		(pps_selector << 4);
677 
678 	ret = mipi_dsi_device_transfer(dsi, &msg);
679 
680 	return (ret < 0) ? ret : 0;
681 }
682 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext);
683 
684 /**
685  * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
686  * @dsi: DSI peripheral device
687  * @enable: Whether to enable or disable the DSC
688  *
689  * Enable or disable Display Stream Compression on the peripheral using the
690  * default Picture Parameter Set and VESA DSC 1.1 algorithm.
691  *
692  * Return: 0 on success or a negative error code on failure.
693  */
694 int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
695 {
696 	return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0);
697 }
698 EXPORT_SYMBOL(mipi_dsi_compression_mode);
699 
700 /**
701  * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
702  * @dsi: DSI peripheral device
703  * @pps: VESA DSC 1.1 Picture Parameter Set
704  *
705  * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
706  *
707  * Return: 0 on success or a negative error code on failure.
708  */
709 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
710 				   const struct drm_dsc_picture_parameter_set *pps)
711 {
712 	struct mipi_dsi_msg msg = {
713 		.channel = dsi->channel,
714 		.type = MIPI_DSI_PICTURE_PARAMETER_SET,
715 		.tx_len = sizeof(*pps),
716 		.tx_buf = pps,
717 	};
718 	int ret = mipi_dsi_device_transfer(dsi, &msg);
719 
720 	return (ret < 0) ? ret : 0;
721 }
722 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
723 
724 /**
725  * mipi_dsi_generic_write() - transmit data using a generic write packet
726  * @dsi: DSI peripheral device
727  * @payload: buffer containing the payload
728  * @size: size of payload buffer
729  *
730  * This function will automatically choose the right data type depending on
731  * the payload length.
732  *
733  * Return: The number of bytes transmitted on success or a negative error code
734  * on failure.
735  */
736 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
737 			       size_t size)
738 {
739 	struct mipi_dsi_msg msg = {
740 		.channel = dsi->channel,
741 		.tx_buf = payload,
742 		.tx_len = size
743 	};
744 
745 	switch (size) {
746 	case 0:
747 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
748 		break;
749 
750 	case 1:
751 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
752 		break;
753 
754 	case 2:
755 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
756 		break;
757 
758 	default:
759 		msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
760 		break;
761 	}
762 
763 	return mipi_dsi_device_transfer(dsi, &msg);
764 }
765 EXPORT_SYMBOL(mipi_dsi_generic_write);
766 
767 /**
768  * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
769  * @dsi: DSI peripheral device
770  * @payload: buffer containing the payload
771  * @size: size of payload buffer
772  *
773  * Like mipi_dsi_generic_write() but includes a dev_err()
774  * call for you and returns 0 upon success, not the number of bytes sent.
775  *
776  * Return: 0 on success or a negative error code on failure.
777  */
778 int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
779 				  const void *payload, size_t size)
780 {
781 	struct device *dev = &dsi->dev;
782 	ssize_t ret;
783 
784 	ret = mipi_dsi_generic_write(dsi, payload, size);
785 	if (ret < 0) {
786 		dev_err(dev, "sending generic data %*ph failed: %zd\n",
787 			(int)size, payload, ret);
788 		return ret;
789 	}
790 
791 	return 0;
792 }
793 EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
794 
795 /**
796  * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err
797  * @ctx: Context for multiple DSI transactions
798  * @payload: buffer containing the payload
799  * @size: size of payload buffer
800  *
801  * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
802  * makes it convenient to make several calls in a row.
803  */
804 void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
805 				  const void *payload, size_t size)
806 {
807 	struct mipi_dsi_device *dsi = ctx->dsi;
808 	struct device *dev = &dsi->dev;
809 	ssize_t ret;
810 
811 	if (ctx->accum_err)
812 		return;
813 
814 	ret = mipi_dsi_generic_write(dsi, payload, size);
815 	if (ret < 0) {
816 		ctx->accum_err = ret;
817 		dev_err(dev, "sending generic data %*ph failed: %d\n",
818 			(int)size, payload, ctx->accum_err);
819 	}
820 }
821 EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
822 
823 /**
824  * mipi_dsi_generic_read() - receive data using a generic read packet
825  * @dsi: DSI peripheral device
826  * @params: buffer containing the request parameters
827  * @num_params: number of request parameters
828  * @data: buffer in which to return the received data
829  * @size: size of receive buffer
830  *
831  * This function will automatically choose the right data type depending on
832  * the number of parameters passed in.
833  *
834  * Return: The number of bytes successfully read or a negative error code on
835  * failure.
836  */
837 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
838 			      size_t num_params, void *data, size_t size)
839 {
840 	struct mipi_dsi_msg msg = {
841 		.channel = dsi->channel,
842 		.tx_len = num_params,
843 		.tx_buf = params,
844 		.rx_len = size,
845 		.rx_buf = data
846 	};
847 
848 	switch (num_params) {
849 	case 0:
850 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
851 		break;
852 
853 	case 1:
854 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
855 		break;
856 
857 	case 2:
858 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
859 		break;
860 
861 	default:
862 		return -EINVAL;
863 	}
864 
865 	return mipi_dsi_device_transfer(dsi, &msg);
866 }
867 EXPORT_SYMBOL(mipi_dsi_generic_read);
868 
869 /**
870  * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
871  * @dsi: DSI peripheral device
872  * @data: buffer containing data to be transmitted
873  * @len: size of transmission buffer
874  *
875  * This function will automatically choose the right data type depending on
876  * the command payload length.
877  *
878  * Return: The number of bytes successfully transmitted or a negative error
879  * code on failure.
880  */
881 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
882 				  const void *data, size_t len)
883 {
884 	struct mipi_dsi_msg msg = {
885 		.channel = dsi->channel,
886 		.tx_buf = data,
887 		.tx_len = len
888 	};
889 
890 	switch (len) {
891 	case 0:
892 		return -EINVAL;
893 
894 	case 1:
895 		msg.type = MIPI_DSI_DCS_SHORT_WRITE;
896 		break;
897 
898 	case 2:
899 		msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
900 		break;
901 
902 	default:
903 		msg.type = MIPI_DSI_DCS_LONG_WRITE;
904 		break;
905 	}
906 
907 	return mipi_dsi_device_transfer(dsi, &msg);
908 }
909 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
910 
911 /**
912  * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log
913  * @dsi: DSI peripheral device
914  * @data: buffer containing data to be transmitted
915  * @len: size of transmission buffer
916  *
917  * Like mipi_dsi_dcs_write_buffer() but includes a dev_err()
918  * call for you and returns 0 upon success, not the number of bytes sent.
919  *
920  * Return: 0 on success or a negative error code on failure.
921  */
922 int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
923 				     const void *data, size_t len)
924 {
925 	struct device *dev = &dsi->dev;
926 	ssize_t ret;
927 
928 	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
929 	if (ret < 0) {
930 		dev_err(dev, "sending dcs data %*ph failed: %zd\n",
931 			(int)len, data, ret);
932 		return ret;
933 	}
934 
935 	return 0;
936 }
937 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
938 
939 /**
940  * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err
941  * @ctx: Context for multiple DSI transactions
942  * @data: buffer containing data to be transmitted
943  * @len: size of transmission buffer
944  *
945  * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
946  * makes it convenient to make several calls in a row.
947  */
948 void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
949 				     const void *data, size_t len)
950 {
951 	struct mipi_dsi_device *dsi = ctx->dsi;
952 	struct device *dev = &dsi->dev;
953 	ssize_t ret;
954 
955 	if (ctx->accum_err)
956 		return;
957 
958 	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
959 	if (ret < 0) {
960 		ctx->accum_err = ret;
961 		dev_err(dev, "sending dcs data %*ph failed: %d\n",
962 			(int)len, data, ctx->accum_err);
963 	}
964 }
965 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
966 
967 /**
968  * mipi_dsi_dcs_write() - send DCS write command
969  * @dsi: DSI peripheral device
970  * @cmd: DCS command
971  * @data: buffer containing the command payload
972  * @len: command payload length
973  *
974  * This function will automatically choose the right data type depending on
975  * the command payload length.
976  *
977  * Return: The number of bytes successfully transmitted or a negative error
978  * code on failure.
979  */
980 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
981 			   const void *data, size_t len)
982 {
983 	ssize_t err;
984 	size_t size;
985 	u8 stack_tx[8];
986 	u8 *tx;
987 
988 	size = 1 + len;
989 	if (len > ARRAY_SIZE(stack_tx) - 1) {
990 		tx = kmalloc(size, GFP_KERNEL);
991 		if (!tx)
992 			return -ENOMEM;
993 	} else {
994 		tx = stack_tx;
995 	}
996 
997 	/* concatenate the DCS command byte and the payload */
998 	tx[0] = cmd;
999 	if (data)
1000 		memcpy(&tx[1], data, len);
1001 
1002 	err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
1003 
1004 	if (tx != stack_tx)
1005 		kfree(tx);
1006 
1007 	return err;
1008 }
1009 EXPORT_SYMBOL(mipi_dsi_dcs_write);
1010 
1011 /**
1012  * mipi_dsi_dcs_read() - send DCS read request command
1013  * @dsi: DSI peripheral device
1014  * @cmd: DCS command
1015  * @data: buffer in which to receive data
1016  * @len: size of receive buffer
1017  *
1018  * Return: The number of bytes read or a negative error code on failure.
1019  */
1020 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
1021 			  size_t len)
1022 {
1023 	struct mipi_dsi_msg msg = {
1024 		.channel = dsi->channel,
1025 		.type = MIPI_DSI_DCS_READ,
1026 		.tx_buf = &cmd,
1027 		.tx_len = 1,
1028 		.rx_buf = data,
1029 		.rx_len = len
1030 	};
1031 
1032 	return mipi_dsi_device_transfer(dsi, &msg);
1033 }
1034 EXPORT_SYMBOL(mipi_dsi_dcs_read);
1035 
1036 /**
1037  * mipi_dsi_dcs_nop() - send DCS nop packet
1038  * @dsi: DSI peripheral device
1039  *
1040  * Return: 0 on success or a negative error code on failure.
1041  */
1042 int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
1043 {
1044 	ssize_t err;
1045 
1046 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
1047 	if (err < 0)
1048 		return err;
1049 
1050 	return 0;
1051 }
1052 EXPORT_SYMBOL(mipi_dsi_dcs_nop);
1053 
1054 /**
1055  * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
1056  * @dsi: DSI peripheral device
1057  *
1058  * Return: 0 on success or a negative error code on failure.
1059  */
1060 int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
1061 {
1062 	ssize_t err;
1063 
1064 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
1065 	if (err < 0)
1066 		return err;
1067 
1068 	return 0;
1069 }
1070 EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
1071 
1072 /**
1073  * mipi_dsi_dcs_get_power_mode() - query the display module's current power
1074  *    mode
1075  * @dsi: DSI peripheral device
1076  * @mode: return location for the current power mode
1077  *
1078  * Return: 0 on success or a negative error code on failure.
1079  */
1080 int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
1081 {
1082 	ssize_t err;
1083 
1084 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
1085 				sizeof(*mode));
1086 	if (err <= 0) {
1087 		if (err == 0)
1088 			err = -ENODATA;
1089 
1090 		return err;
1091 	}
1092 
1093 	return 0;
1094 }
1095 EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
1096 
1097 /**
1098  * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
1099  *    data used by the interface
1100  * @dsi: DSI peripheral device
1101  * @format: return location for the pixel format
1102  *
1103  * Return: 0 on success or a negative error code on failure.
1104  */
1105 int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
1106 {
1107 	ssize_t err;
1108 
1109 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
1110 				sizeof(*format));
1111 	if (err <= 0) {
1112 		if (err == 0)
1113 			err = -ENODATA;
1114 
1115 		return err;
1116 	}
1117 
1118 	return 0;
1119 }
1120 EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
1121 
1122 /**
1123  * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
1124  *    display module except interface communication
1125  * @dsi: DSI peripheral device
1126  *
1127  * Return: 0 on success or a negative error code on failure.
1128  */
1129 int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
1130 {
1131 	ssize_t err;
1132 
1133 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
1134 	if (err < 0)
1135 		return err;
1136 
1137 	return 0;
1138 }
1139 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
1140 
1141 /**
1142  * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
1143  *    module
1144  * @dsi: DSI peripheral device
1145  *
1146  * Return: 0 on success or a negative error code on failure.
1147  */
1148 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
1149 {
1150 	ssize_t err;
1151 
1152 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
1153 	if (err < 0)
1154 		return err;
1155 
1156 	return 0;
1157 }
1158 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
1159 
1160 /**
1161  * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
1162  *    display device
1163  * @dsi: DSI peripheral device
1164  *
1165  * Return: 0 on success or a negative error code on failure.
1166  */
1167 int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
1168 {
1169 	ssize_t err;
1170 
1171 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
1172 	if (err < 0)
1173 		return err;
1174 
1175 	return 0;
1176 }
1177 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
1178 
1179 /**
1180  * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
1181  *    display device
1182  * @dsi: DSI peripheral device
1183  *
1184  * Return: 0 on success or a negative error code on failure
1185  */
1186 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
1187 {
1188 	ssize_t err;
1189 
1190 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
1191 	if (err < 0)
1192 		return err;
1193 
1194 	return 0;
1195 }
1196 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
1197 
1198 /**
1199  * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
1200  *    memory accessed by the host processor
1201  * @dsi: DSI peripheral device
1202  * @start: first column of frame memory
1203  * @end: last column of frame memory
1204  *
1205  * Return: 0 on success or a negative error code on failure.
1206  */
1207 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
1208 				    u16 end)
1209 {
1210 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1211 	ssize_t err;
1212 
1213 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
1214 				 sizeof(payload));
1215 	if (err < 0)
1216 		return err;
1217 
1218 	return 0;
1219 }
1220 EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
1221 
1222 /**
1223  * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
1224  *    memory accessed by the host processor
1225  * @dsi: DSI peripheral device
1226  * @start: first page of frame memory
1227  * @end: last page of frame memory
1228  *
1229  * Return: 0 on success or a negative error code on failure.
1230  */
1231 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
1232 				  u16 end)
1233 {
1234 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1235 	ssize_t err;
1236 
1237 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
1238 				 sizeof(payload));
1239 	if (err < 0)
1240 		return err;
1241 
1242 	return 0;
1243 }
1244 EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
1245 
1246 /**
1247  * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
1248  *    output signal on the TE signal line
1249  * @dsi: DSI peripheral device
1250  *
1251  * Return: 0 on success or a negative error code on failure
1252  */
1253 int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
1254 {
1255 	ssize_t err;
1256 
1257 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
1258 	if (err < 0)
1259 		return err;
1260 
1261 	return 0;
1262 }
1263 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
1264 
1265 /**
1266  * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
1267  *    output signal on the TE signal line.
1268  * @dsi: DSI peripheral device
1269  * @mode: the Tearing Effect Output Line mode
1270  *
1271  * Return: 0 on success or a negative error code on failure
1272  */
1273 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
1274 			     enum mipi_dsi_dcs_tear_mode mode)
1275 {
1276 	u8 value = mode;
1277 	ssize_t err;
1278 
1279 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
1280 				 sizeof(value));
1281 	if (err < 0)
1282 		return err;
1283 
1284 	return 0;
1285 }
1286 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
1287 
1288 /**
1289  * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
1290  *    data used by the interface
1291  * @dsi: DSI peripheral device
1292  * @format: pixel format
1293  *
1294  * Return: 0 on success or a negative error code on failure.
1295  */
1296 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
1297 {
1298 	ssize_t err;
1299 
1300 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
1301 				 sizeof(format));
1302 	if (err < 0)
1303 		return err;
1304 
1305 	return 0;
1306 }
1307 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
1308 
1309 /**
1310  * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
1311  *    the Tearing Effect output signal of the display module
1312  * @dsi: DSI peripheral device
1313  * @scanline: scanline to use as trigger
1314  *
1315  * Return: 0 on success or a negative error code on failure
1316  */
1317 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
1318 {
1319 	u8 payload[2] = { scanline >> 8, scanline & 0xff };
1320 	ssize_t err;
1321 
1322 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload,
1323 				 sizeof(payload));
1324 	if (err < 0)
1325 		return err;
1326 
1327 	return 0;
1328 }
1329 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
1330 
1331 /**
1332  * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
1333  *    display
1334  * @dsi: DSI peripheral device
1335  * @brightness: brightness value
1336  *
1337  * Return: 0 on success or a negative error code on failure.
1338  */
1339 int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
1340 					u16 brightness)
1341 {
1342 	u8 payload[2] = { brightness & 0xff, brightness >> 8 };
1343 	ssize_t err;
1344 
1345 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1346 				 payload, sizeof(payload));
1347 	if (err < 0)
1348 		return err;
1349 
1350 	return 0;
1351 }
1352 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness);
1353 
1354 /**
1355  * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
1356  *    of the display
1357  * @dsi: DSI peripheral device
1358  * @brightness: brightness value
1359  *
1360  * Return: 0 on success or a negative error code on failure.
1361  */
1362 int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
1363 					u16 *brightness)
1364 {
1365 	ssize_t err;
1366 
1367 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1368 				brightness, sizeof(*brightness));
1369 	if (err <= 0) {
1370 		if (err == 0)
1371 			err = -ENODATA;
1372 
1373 		return err;
1374 	}
1375 
1376 	return 0;
1377 }
1378 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
1379 
1380 /**
1381  * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
1382  *    of the display
1383  * @dsi: DSI peripheral device
1384  * @brightness: brightness value
1385  *
1386  * Return: 0 on success or a negative error code on failure.
1387  */
1388 int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
1389 					     u16 brightness)
1390 {
1391 	u8 payload[2] = { brightness >> 8, brightness & 0xff };
1392 	ssize_t err;
1393 
1394 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1395 				 payload, sizeof(payload));
1396 	if (err < 0)
1397 		return err;
1398 
1399 	return 0;
1400 }
1401 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
1402 
1403 /**
1404  * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
1405  *    brightness value of the display
1406  * @dsi: DSI peripheral device
1407  * @brightness: brightness value
1408  *
1409  * Return: 0 on success or a negative error code on failure.
1410  */
1411 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
1412 					     u16 *brightness)
1413 {
1414 	u8 brightness_be[2];
1415 	ssize_t err;
1416 
1417 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1418 				brightness_be, sizeof(brightness_be));
1419 	if (err <= 0) {
1420 		if (err == 0)
1421 			err = -ENODATA;
1422 
1423 		return err;
1424 	}
1425 
1426 	*brightness = (brightness_be[0] << 8) | brightness_be[1];
1427 
1428 	return 0;
1429 }
1430 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
1431 
1432 /**
1433  * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
1434  * @ctx: Context for multiple DSI transactions
1435  * @pps: VESA DSC 1.1 Picture Parameter Set
1436  *
1437  * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
1438  * makes it convenient to make several calls in a row.
1439  */
1440 void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
1441 				   const struct drm_dsc_picture_parameter_set *pps)
1442 {
1443 	struct mipi_dsi_device *dsi = ctx->dsi;
1444 	struct device *dev = &dsi->dev;
1445 	ssize_t ret;
1446 
1447 	if (ctx->accum_err)
1448 		return;
1449 
1450 	ret = mipi_dsi_picture_parameter_set(dsi, pps);
1451 	if (ret < 0) {
1452 		ctx->accum_err = ret;
1453 		dev_err(dev, "sending PPS failed: %d\n",
1454 			ctx->accum_err);
1455 	}
1456 }
1457 EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
1458 
1459 /**
1460  * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
1461  * @ctx: Context for multiple DSI transactions
1462  * @enable: Whether to enable or disable the DSC
1463  * @algo: Selected compression algorithm
1464  * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
1465  *
1466  * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
1467  * makes it convenient to make several calls in a row.
1468  */
1469 void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
1470 					 bool enable,
1471 					 enum mipi_dsi_compression_algo algo,
1472 					 unsigned int pps_selector)
1473 {
1474 	struct mipi_dsi_device *dsi = ctx->dsi;
1475 	struct device *dev = &dsi->dev;
1476 	ssize_t ret;
1477 
1478 	if (ctx->accum_err)
1479 		return;
1480 
1481 	ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
1482 	if (ret < 0) {
1483 		ctx->accum_err = ret;
1484 		dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
1485 			ctx->accum_err);
1486 	}
1487 }
1488 EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
1489 
1490 /**
1491  * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
1492  * @ctx: Context for multiple DSI transactions
1493  *
1494  * Like mipi_dsi_dcs_nop() but deals with errors in a way that
1495  * makes it convenient to make several calls in a row.
1496  */
1497 void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
1498 {
1499 	struct mipi_dsi_device *dsi = ctx->dsi;
1500 	struct device *dev = &dsi->dev;
1501 	ssize_t ret;
1502 
1503 	if (ctx->accum_err)
1504 		return;
1505 
1506 	ret = mipi_dsi_dcs_nop(dsi);
1507 	if (ret < 0) {
1508 		ctx->accum_err = ret;
1509 		dev_err(dev, "sending DCS NOP failed: %d\n",
1510 			ctx->accum_err);
1511 	}
1512 }
1513 EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
1514 
1515 /**
1516  * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
1517  * @ctx: Context for multiple DSI transactions
1518  *
1519  * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
1520  * makes it convenient to make several calls in a row.
1521  */
1522 void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
1523 {
1524 	struct mipi_dsi_device *dsi = ctx->dsi;
1525 	struct device *dev = &dsi->dev;
1526 	ssize_t ret;
1527 
1528 	if (ctx->accum_err)
1529 		return;
1530 
1531 	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
1532 	if (ret < 0) {
1533 		ctx->accum_err = ret;
1534 		dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
1535 			ctx->accum_err);
1536 	}
1537 }
1538 EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
1539 
1540 /**
1541  * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
1542  * @ctx: Context for multiple DSI transactions
1543  *
1544  * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
1545  * makes it convenient to make several calls in a row.
1546  */
1547 void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
1548 {
1549 	struct mipi_dsi_device *dsi = ctx->dsi;
1550 	struct device *dev = &dsi->dev;
1551 	ssize_t ret;
1552 
1553 	if (ctx->accum_err)
1554 		return;
1555 
1556 	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
1557 	if (ret < 0) {
1558 		ctx->accum_err = ret;
1559 		dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
1560 			ctx->accum_err);
1561 	}
1562 }
1563 EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
1564 
1565 /**
1566  * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
1567  * @ctx: Context for multiple DSI transactions
1568  *
1569  * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
1570  * makes it convenient to make several calls in a row.
1571  */
1572 void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
1573 {
1574 	struct mipi_dsi_device *dsi = ctx->dsi;
1575 	struct device *dev = &dsi->dev;
1576 	ssize_t ret;
1577 
1578 	if (ctx->accum_err)
1579 		return;
1580 
1581 	ret = mipi_dsi_dcs_set_display_off(dsi);
1582 	if (ret < 0) {
1583 		ctx->accum_err = ret;
1584 		dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
1585 			ctx->accum_err);
1586 	}
1587 }
1588 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
1589 
1590 /**
1591  * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
1592  * @ctx: Context for multiple DSI transactions
1593  *
1594  * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
1595  * makes it convenient to make several calls in a row.
1596  */
1597 void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
1598 {
1599 	struct mipi_dsi_device *dsi = ctx->dsi;
1600 	struct device *dev = &dsi->dev;
1601 	ssize_t ret;
1602 
1603 	if (ctx->accum_err)
1604 		return;
1605 
1606 	ret = mipi_dsi_dcs_set_display_on(dsi);
1607 	if (ret < 0) {
1608 		ctx->accum_err = ret;
1609 		dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
1610 			ctx->accum_err);
1611 	}
1612 }
1613 EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
1614 
1615 /**
1616  * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
1617  * @ctx: Context for multiple DSI transactions
1618  * @mode: the Tearing Effect Output Line mode
1619  *
1620  * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
1621  * makes it convenient to make several calls in a row.
1622  */
1623 void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
1624 				    enum mipi_dsi_dcs_tear_mode mode)
1625 {
1626 	struct mipi_dsi_device *dsi = ctx->dsi;
1627 	struct device *dev = &dsi->dev;
1628 	ssize_t ret;
1629 
1630 	if (ctx->accum_err)
1631 		return;
1632 
1633 	ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
1634 	if (ret < 0) {
1635 		ctx->accum_err = ret;
1636 		dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
1637 			ctx->accum_err);
1638 	}
1639 }
1640 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
1641 
1642 static int mipi_dsi_drv_probe(struct device *dev)
1643 {
1644 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1645 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1646 
1647 	return drv->probe(dsi);
1648 }
1649 
1650 static int mipi_dsi_drv_remove(struct device *dev)
1651 {
1652 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1653 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1654 
1655 	drv->remove(dsi);
1656 
1657 	return 0;
1658 }
1659 
1660 static void mipi_dsi_drv_shutdown(struct device *dev)
1661 {
1662 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1663 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1664 
1665 	drv->shutdown(dsi);
1666 }
1667 
1668 /**
1669  * mipi_dsi_driver_register_full() - register a driver for DSI devices
1670  * @drv: DSI driver structure
1671  * @owner: owner module
1672  *
1673  * Return: 0 on success or a negative error code on failure.
1674  */
1675 int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
1676 				  struct module *owner)
1677 {
1678 	drv->driver.bus = &mipi_dsi_bus_type;
1679 	drv->driver.owner = owner;
1680 
1681 	if (drv->probe)
1682 		drv->driver.probe = mipi_dsi_drv_probe;
1683 	if (drv->remove)
1684 		drv->driver.remove = mipi_dsi_drv_remove;
1685 	if (drv->shutdown)
1686 		drv->driver.shutdown = mipi_dsi_drv_shutdown;
1687 
1688 	return driver_register(&drv->driver);
1689 }
1690 EXPORT_SYMBOL(mipi_dsi_driver_register_full);
1691 
1692 /**
1693  * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
1694  * @drv: DSI driver structure
1695  *
1696  * Return: 0 on success or a negative error code on failure.
1697  */
1698 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
1699 {
1700 	driver_unregister(&drv->driver);
1701 }
1702 EXPORT_SYMBOL(mipi_dsi_driver_unregister);
1703 
1704 static int __init mipi_dsi_bus_init(void)
1705 {
1706 	return bus_register(&mipi_dsi_bus_type);
1707 }
1708 postcore_initcall(mipi_dsi_bus_init);
1709 
1710 MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
1711 MODULE_DESCRIPTION("MIPI DSI Bus");
1712 MODULE_LICENSE("GPL and additional rights");
1713