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